Proyectos de Subversion Moodle

Rev

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