Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace core_block;
18
 
19
use core_block_external;
20
use externallib_advanced_testcase;
21
 
22
defined('MOODLE_INTERNAL') || die();
23
 
24
global $CFG;
25
 
26
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
27
require_once($CFG->dirroot . '/my/lib.php');
28
 
29
/**
30
 * External block functions unit tests
31
 *
32
 * @package    core_block
33
 * @category   external
34
 * @copyright  2015 Juan Leyva <juan@moodle.com>
35
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36
 * @since      Moodle 3.0
37
 */
1441 ariadna 38
final class externallib_test extends externallib_advanced_testcase {
1 efrain 39
 
40
    /**
41
     * Test get_course_blocks
42
     */
11 efrain 43
    public function test_get_course_blocks(): void {
1 efrain 44
        global $DB, $FULLME;
45
 
46
        $this->resetAfterTest(true);
1441 ariadna 47
        $this->setAdminUser();
1 efrain 48
 
49
        $user = $this->getDataGenerator()->create_user();
50
        $course = $this->getDataGenerator()->create_course();
51
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
52
        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
53
 
54
        $page = new \moodle_page();
55
        $page->set_context(\context_course::instance($course->id));
56
        $page->set_pagelayout('course');
57
        $course->format = course_get_format($course)->get_format();
58
        $page->set_pagetype('course-view-' . $course->format);
59
        $page->blocks->load_blocks();
60
        $newblock = 'calendar_upcoming';
61
        $page->blocks->add_block_at_end_of_default_region($newblock);
62
        $this->setUser($user);
63
 
64
        // Check for the new block.
65
        $result = core_block_external::get_course_blocks($course->id);
66
        // We need to execute the return values cleaning process to simulate the web service server.
67
        $result = \core_external\external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result);
68
 
69
        // Expect the new block.
70
        $this->assertCount(1, $result['blocks']);
71
        $this->assertEquals($newblock, $result['blocks'][0]['name']);
72
    }
73
 
74
    /**
75
     * Test get_course_blocks on site home
76
     */
11 efrain 77
    public function test_get_course_blocks_site_home(): void {
1 efrain 78
        global $DB, $FULLME;
79
 
80
        $this->resetAfterTest(true);
1441 ariadna 81
        $this->setAdminUser();
1 efrain 82
 
83
        $user = $this->getDataGenerator()->create_user();
84
 
85
        $page = new \moodle_page();
86
        $page->set_context(\context_course::instance(SITEID));
87
        $page->set_pagelayout('frontpage');
88
        $page->set_pagetype('site-index');
89
        $page->blocks->load_blocks();
90
        $newblock = 'calendar_upcoming';
91
        $page->blocks->add_block_at_end_of_default_region($newblock);
92
        $this->setUser($user);
93
 
94
        // Check for the new block.
95
        $result = core_block_external::get_course_blocks(SITEID);
96
        // We need to execute the return values cleaning process to simulate the web service server.
97
        $result = \core_external\external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result);
98
 
99
        // Expect the new block.
100
        $this->assertCount(1, $result['blocks']);
101
        $this->assertEquals($newblock, $result['blocks'][0]['name']);
102
    }
103
 
104
    /**
105
     * Test get_course_blocks
106
     */
11 efrain 107
    public function test_get_course_blocks_overrides(): void {
1 efrain 108
        global $DB, $CFG, $FULLME;
109
 
110
        $this->resetAfterTest(true);
111
 
112
        $CFG->defaultblocks_override = 'search_forums,course_list:calendar_upcoming,recent_activity';
113
 
114
        $user = $this->getDataGenerator()->create_user();
115
        $course = $this->getDataGenerator()->create_course();
116
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
117
        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
118
 
119
        $this->setUser($user);
120
 
121
        // Try default blocks.
122
        $result = core_block_external::get_course_blocks($course->id);
123
        // We need to execute the return values cleaning process to simulate the web service server.
124
        $result = \core_external\external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result);
125
 
126
        // Expect 4 default blocks.
127
        $this->assertCount(4, $result['blocks']);
128
 
129
        $expectedblocks = array('navigation', 'settings', 'search_forums', 'course_list',
130
                                'calendar_upcoming', 'recent_activity');
131
        foreach ($result['blocks'] as $block) {
132
            if (!in_array($block['name'], $expectedblocks)) {
133
                $this->fail("Unexpected block found: " . $block['name']);
134
            }
135
        }
136
 
137
    }
138
 
139
    /**
140
     * Test get_course_blocks contents
141
     */
11 efrain 142
    public function test_get_course_blocks_contents(): void {
1 efrain 143
        global $DB, $FULLME;
144
 
145
        $this->resetAfterTest(true);
1441 ariadna 146
        $this->setAdminUser();
1 efrain 147
 
148
        $user = $this->getDataGenerator()->create_user();
149
        $course = $this->getDataGenerator()->create_course();
150
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
151
        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
152
        $coursecontext = \context_course::instance($course->id);
153
 
154
        // Create a HTML block.
155
        $title = 'Some course info';
156
        $body = 'Some course info<br /><p>Some contents</p>';
157
        $bodyformat = FORMAT_MOODLE;
158
        $page = new \moodle_page();
159
        $page->set_context($coursecontext);
160
        $page->set_pagelayout('course');
161
        $course->format = course_get_format($course)->get_format();
162
        $page->set_pagetype('course-view-' . $course->format);
163
        $page->blocks->load_blocks();
164
        $newblock = 'html';
165
        $page->blocks->add_block_at_end_of_default_region($newblock);
166
 
167
        $this->setUser($user);
168
        // Re-create the page.
169
        $page = new \moodle_page();
170
        $page->set_context($coursecontext);
171
        $page->set_pagelayout('course');
172
        $course->format = course_get_format($course)->get_format();
173
        $page->set_pagetype('course-view-' . $course->format);
174
        $page->blocks->load_blocks();
175
        $blocks = $page->blocks->get_blocks_for_region($page->blocks->get_default_region());
176
        $block = end($blocks);
177
        $block = block_instance('html', $block->instance);
178
        $nonscalar = [
179
            'something' => true,
180
        ];
181
        $configdata = (object) [
182
            'title' => $title,
183
            'text' => [
184
                'itemid' => 0,
185
                'text' => $body,
186
                'format' => $bodyformat,
187
            ],
188
            'nonscalar' => $nonscalar
189
        ];
190
        $block->instance_config_save((object) $configdata);
191
        $filename = 'img.png';
192
        $filerecord = array(
193
            'contextid' => \context_block::instance($block->instance->id)->id,
194
            'component' => 'block_html',
195
            'filearea' => 'content',
196
            'itemid' => 0,
197
            'filepath' => '/',
198
            'filename' => $filename,
199
        );
200
        // Create an area to upload the file.
201
        $fs = get_file_storage();
202
        // Create a file from the string that we made earlier.
203
        $file = $fs->create_file_from_string($filerecord, 'some fake content (should be an image).');
204
 
205
        // Check for the new block.
206
        $result = core_block_external::get_course_blocks($course->id, true);
207
        // We need to execute the return values cleaning process to simulate the web service server.
208
        $result = \core_external\external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result);
209
 
210
        // Expect the new block.
211
        $this->assertCount(1, $result['blocks']);
212
        $this->assertEquals($title, $result['blocks'][0]['contents']['title']);
213
        $this->assertEquals($body, $result['blocks'][0]['contents']['content']);
214
        $this->assertEquals(FORMAT_HTML, $result['blocks'][0]['contents']['contentformat']);    // Format change for external.
215
        $this->assertEquals('', $result['blocks'][0]['contents']['footer']);
216
        $this->assertCount(1, $result['blocks'][0]['contents']['files']);
217
        $this->assertEquals($newblock, $result['blocks'][0]['name']);
218
        $configcounts = 0;
219
        foreach ($result['blocks'][0]['configs'] as $config) {
220
            if ($config['type'] = 'plugin' && $config['name'] == 'allowcssclasses' && $config['value'] == json_encode('0')) {
221
                $configcounts++;
222
            } else if ($config['type'] = 'instance' && $config['name'] == 'text' && $config['value'] == json_encode($body)) {
223
                $configcounts++;
224
            } else if ($config['type'] = 'instance' && $config['name'] == 'title' && $config['value'] == json_encode($title)) {
225
                $configcounts++;
226
            } else if ($config['type'] = 'instance' && $config['name'] == 'format' && $config['value'] == json_encode('0')) {
227
                $configcounts++;
228
            } else if ($config['type'] = 'instance' && $config['name'] == 'nonscalar' &&
229
                    $config['value'] == json_encode($nonscalar)) {
230
                $configcounts++;
231
            }
232
        }
233
        $this->assertEquals(5, $configcounts);
234
    }
235
 
236
    /**
237
     * Test get_course_blocks contents with mathjax.
238
     */
11 efrain 239
    public function test_get_course_blocks_contents_with_mathjax(): void {
1 efrain 240
        global $DB, $CFG;
241
 
242
        $this->resetAfterTest(true);
1441 ariadna 243
        $this->setAdminUser();
1 efrain 244
 
245
        // Enable MathJax filter in content and headings.
246
        $this->configure_filters([
247
            ['name' => 'mathjaxloader', 'state' => TEXTFILTER_ON, 'move' => -1, 'applytostrings' => true],
248
        ]);
249
 
250
        // Create a few stuff to test with.
251
        $user = $this->getDataGenerator()->create_user();
252
        $course = $this->getDataGenerator()->create_course();
253
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
254
        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
255
        $coursecontext = \context_course::instance($course->id);
256
 
257
        // Create a HTML block.
258
        $title = 'My block $$(a+b)=2$$';
259
        $body = 'My block contents $$(a+b)=2$$';
260
        $bodyformat = FORMAT_MOODLE;
261
        $page = new \moodle_page();
262
        $page->set_context($coursecontext);
263
        $page->set_pagelayout('course');
264
        $course->format = course_get_format($course)->get_format();
265
        $page->set_pagetype('course-view-' . $course->format);
266
        $page->blocks->load_blocks();
267
        $newblock = 'html';
268
        $page->blocks->add_block_at_end_of_default_region($newblock);
269
 
270
        $this->setUser($user);
271
        // Re-create the page.
272
        $page = new \moodle_page();
273
        $page->set_context($coursecontext);
274
        $page->set_pagelayout('course');
275
        $course->format = course_get_format($course)->get_format();
276
        $page->set_pagetype('course-view-' . $course->format);
277
        $page->blocks->load_blocks();
278
        $blocks = $page->blocks->get_blocks_for_region($page->blocks->get_default_region());
279
        $block = end($blocks);
280
        $block = block_instance('html', $block->instance);
281
        $nonscalar = [
282
            'something' => true,
283
        ];
284
        $configdata = (object) [
285
            'title' => $title,
286
            'text' => [
287
                'itemid' => 0,
288
                'text' => $body,
289
                'format' => $bodyformat,
290
            ],
291
            'nonscalar' => $nonscalar
292
        ];
293
        $block->instance_config_save((object) $configdata);
294
 
295
        // Check for the new block.
296
        $result = core_block_external::get_course_blocks($course->id, true);
297
        $result = \core_external\external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result);
298
 
299
        // Format the original data.
300
        $sitecontext = \context_system::instance();
301
        $title = \core_external\util::format_string($title, $coursecontext->id);
302
        list($body, $bodyformat) = \core_external\util::format_text($body, $bodyformat, $coursecontext, 'block_html', 'content');
303
 
304
        // Check that the block data is formatted.
305
        $this->assertCount(1, $result['blocks']);
306
        $this->assertStringContainsString('<span class="filter_mathjaxloader_equation">',
307
                $result['blocks'][0]['contents']['title']);
308
        $this->assertStringContainsString('<span class="filter_mathjaxloader_equation">',
309
                $result['blocks'][0]['contents']['content']);
310
        $this->assertEquals($title, $result['blocks'][0]['contents']['title']);
311
        $this->assertEquals($body, $result['blocks'][0]['contents']['content']);
312
    }
313
 
314
    /**
315
     * Test user get default dashboard blocks.
316
     */
11 efrain 317
    public function test_get_dashboard_blocks_default_dashboard(): void {
1 efrain 318
        global $PAGE, $DB;
319
        $this->resetAfterTest(true);
320
 
321
        $user = $this->getDataGenerator()->create_user();
322
        $PAGE->set_url('/my/index.php');    // Need this because some internal API calls require the $PAGE url to be set.
323
 
324
        // Force a setting change to check the returned blocks settings.
325
        set_config('displaycategories', 0, 'block_myoverview');
326
 
327
        $systempage = $DB->get_record('my_pages', array('userid' => null, 'name' => MY_PAGE_DEFAULT, 'private' => true));
328
        // Get the expected default blocks.
329
        $alldefaultblocksordered = $DB->get_records_menu(
330
            'block_instances',
331
            array('pagetypepattern' => 'my-index', 'subpagepattern' => $systempage->id),
332
            'defaultregion, defaultweight ASC',
333
            'id, blockname'
334
        );
335
 
336
        $this->setUser($user);
337
 
338
        // Check for the default blocks.
339
        $result = core_block_external::get_dashboard_blocks($user->id);
340
        // We need to execute the return values cleaning process to simulate the web service server.
341
        $result = \core_external\external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result);
342
        // Expect all default blocks defined in blocks_add_default_system_blocks().
343
        $this->assertCount(count($alldefaultblocksordered), $result['blocks']);
344
        $returnedblocks = array();
345
        foreach ($result['blocks'] as $block) {
346
            // Check all the returned blocks are in the expected blocks array.
347
            $this->assertContains($block['name'], $alldefaultblocksordered);
348
            $returnedblocks[] = $block['name'];
349
            // Check the configuration returned for this default block.
350
            if ($block['name'] == 'myoverview') {
351
                // Convert config to associative array to avoid DB sorting randomness.
352
                $config = array_column($block['configs'], null, 'name');
353
                $this->assertArrayHasKey('displaycategories', $config);
354
                $this->assertEquals(json_encode('0'), $config['displaycategories']['value']);
355
                $this->assertEquals('plugin', $config['displaycategories']['type']);
356
            }
357
        }
358
 
359
        // Check that we received the blocks in the expected order.
360
        $this->assertEquals(array_values($alldefaultblocksordered), $returnedblocks);
361
    }
362
 
363
    /**
364
     * Test user get default dashboard blocks including a sticky block.
365
     */
11 efrain 366
    public function test_get_dashboard_blocks_default_dashboard_including_sticky_block(): void {
1 efrain 367
        global $PAGE, $DB;
368
        $this->resetAfterTest(true);
1441 ariadna 369
        $this->setAdminUser();
1 efrain 370
 
371
        $user = $this->getDataGenerator()->create_user();
372
        $PAGE->set_url('/my/index.php');    // Need this because some internal API calls require the $PAGE url to be set.
373
 
374
        $systempage = $DB->get_record('my_pages', array('userid' => null, 'name' => MY_PAGE_DEFAULT, 'private' => true));
375
        // Get the expected default blocks.
376
        $alldefaultblocks = $DB->get_records_menu(
377
            'block_instances', array('pagetypepattern' => 'my-index', 'subpagepattern' => $systempage->id),
378
            '',
379
            'id, blockname'
380
        );
381
 
382
        // Now, add a sticky block.
383
        $page = new \moodle_page();
384
        $page->set_context(\context_system::instance());
385
        $page->set_pagetype('my-index');
386
        $page->set_url(new \moodle_url('/'));
387
        $page->blocks->add_region('side-pre');
388
        $page->blocks->load_blocks();
389
        $page->blocks->add_block('myprofile', 'side-pre', 0, true, '*');
390
 
391
        $this->setUser($user);
392
 
393
        // Check for the default blocks plus the sticky.
394
        $result = core_block_external::get_dashboard_blocks($user->id);
395
        // We need to execute the return values cleaning process to simulate the web service server.
396
        $result = \core_external\external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result);
397
        // Expect all default blocks defined in blocks_add_default_system_blocks() plus sticky one.
398
        $this->assertCount(count($alldefaultblocks) + 1, $result['blocks']);
399
        $found = false;
400
        foreach ($result['blocks'] as $block) {
401
            if ($block['name'] == 'myprofile') {
402
                $this->assertEquals('side-pre', $block['region']);
403
                $found = true;
404
                continue;
405
            }
406
            // Check that the block is in the expected blocks array.
407
            $this->assertContains($block['name'], $alldefaultblocks);
408
        }
409
        $this->assertTrue($found);
410
    }
411
 
412
    /**
413
     * Test admin get user's custom dashboard blocks.
414
     */
11 efrain 415
    public function test_get_dashboard_blocks_custom_user_dashboard(): void {
1 efrain 416
        global $PAGE, $DB;
417
        $this->resetAfterTest(true);
1441 ariadna 418
        $this->setAdminUser();
1 efrain 419
 
420
        $user = $this->getDataGenerator()->create_user();
421
        $PAGE->set_url('/my/index.php');    // Need this because some internal API calls require the $PAGE url to be set.
422
 
423
        $systempage = $DB->get_record('my_pages', array('userid' => null, 'name' => MY_PAGE_DEFAULT, 'private' => true));
424
        // Get the expected default blocks.
425
        $alldefaultblocks = $DB->get_records_menu(
426
            'block_instances',
427
            array('pagetypepattern' => 'my-index', 'subpagepattern' => $systempage->id),
428
            '',
429
            'id, blockname'
430
        );
431
 
432
        // Add a custom block.
433
        $page = new \moodle_page();
434
        $page->set_context(\context_user::instance($user->id));
435
        $page->set_pagelayout('mydashboard');
436
        $page->set_pagetype('my-index');
437
        $page->blocks->add_region('content');
438
        $currentpage = my_get_page($user->id, MY_PAGE_PRIVATE);
439
        $page->set_subpage($currentpage->id);
440
        $page->blocks->load_blocks();
441
        $page->blocks->add_block('myprofile', 'content', 0, false);
442
 
443
        $this->setAdminUser();
444
 
445
        // Check for the new block as admin for a user.
446
        $result = core_block_external::get_dashboard_blocks($user->id);
447
        // We need to execute the return values cleaning process to simulate the web service server.
448
        $result = \core_external\external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result);
449
        // Expect all default blocks defined in blocks_add_default_system_blocks() plus the one we added.
450
        $this->assertCount(count($alldefaultblocks) + 1, $result['blocks']);
451
        $found = false;
452
        foreach ($result['blocks'] as $block) {
453
            if ($block['name'] == 'myprofile') {
454
                $this->assertEquals('content', $block['region']);
455
                $found = true;
456
                continue;
457
            }
458
            // Check that the block is in the expected blocks array.
459
            $this->assertContains($block['name'], $alldefaultblocks);
460
        }
461
        $this->assertTrue($found);
462
    }
463
 
464
    /**
465
     * Test user tries to get other user blocks not having permission.
466
     */
11 efrain 467
    public function test_get_dashboard_blocks_other_user_missing_permissions(): void {
1 efrain 468
        $this->resetAfterTest(true);
469
 
470
        $user1 = $this->getDataGenerator()->create_user();
471
        $user2 = $this->getDataGenerator()->create_user();
472
 
473
        $this->setUser($user1);
474
 
475
        $this->expectException('moodle_exception');
476
        core_block_external::get_dashboard_blocks($user2->id);
477
    }
478
 
479
    /**
480
     * Test user get default dashboard blocks for my courses page.
481
     */
11 efrain 482
    public function test_get_dashboard_blocks_my_courses(): void {
1 efrain 483
        global $PAGE, $DB;
484
        $this->resetAfterTest(true);
485
 
486
        $user = $this->getDataGenerator()->create_user();
487
        $PAGE->set_url('/my/index.php');    // Need this because some internal API calls require the $PAGE url to be set.
488
 
489
        // Force a setting change to check the returned blocks settings.
490
        set_config('displaycategories', 0, 'block_myoverview');
491
 
492
        $systempage = $DB->get_record('my_pages', ['userid' => null, 'name' => MY_PAGE_COURSES, 'private' => false]);
493
        // Get the expected default blocks.
494
        $alldefaultblocksordered = $DB->get_records_menu(
495
            'block_instances',
496
            ['pagetypepattern' => 'my-index', 'subpagepattern' => $systempage->id],
497
            'defaultregion, defaultweight ASC',
498
            'id, blockname'
499
        );
500
 
501
        $this->setUser($user);
502
 
503
        // Check for the default blocks.
504
        $result = core_block_external::get_dashboard_blocks($user->id, false, MY_PAGE_COURSES);
505
        // We need to execute the return values cleaning process to simulate the web service server.
506
        $result = \core_external\external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result);
507
        // Expect all default blocks defined in blocks_add_default_system_blocks().
508
        $this->assertCount(count($alldefaultblocksordered), $result['blocks']);
509
        $returnedblocks = [];
510
        foreach ($result['blocks'] as $block) {
511
            // Check all the returned blocks are in the expected blocks array.
512
            $this->assertContains($block['name'], $alldefaultblocksordered);
513
            $returnedblocks[] = $block['name'];
514
            // Check the configuration returned for this default block.
515
            if ($block['name'] == 'myoverview') {
516
                // Convert config to associative array to avoid DB sorting randomness.
517
                $config = array_column($block['configs'], null, 'name');
518
                $this->assertArrayHasKey('displaycategories', $config);
519
                $this->assertEquals(json_encode('0'), $config['displaycategories']['value']);
520
                $this->assertEquals('plugin', $config['displaycategories']['type']);
521
            }
522
        }
523
 
524
        // Check that we received the blocks in the expected order.
525
        $this->assertEquals(array_values($alldefaultblocksordered), $returnedblocks);
526
    }
527
 
528
    /**
529
     * Test user passing the wrong page type and getting an exception.
530
     */
11 efrain 531
    public function test_get_dashboard_blocks_incorrect_page(): void {
1 efrain 532
        global $PAGE;
533
        $this->resetAfterTest(true);
534
 
535
        $user = $this->getDataGenerator()->create_user();
536
        $PAGE->set_url('/my/index.php');    // Need this because some internal API calls require the $PAGE url to be set.
537
 
538
        $this->setUser($user);
539
 
540
        $this->expectException('moodle_exception');
541
        // Check for the default blocks with a fake page, no need to assign as it'll throw.
542
        core_block_external::get_dashboard_blocks($user->id, false, 'fakepage');
543
 
544
    }
545
}