Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
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 /** 18 * External block functions unit tests 19 * 20 * @package core_block 21 * @category external 22 * @copyright 2017 Juan Leyva <juan@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 * @since Moodle 3.3 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 global $CFG; 30 31 require_once($CFG->dirroot . '/webservice/tests/helpers.php'); 32 require_once($CFG->dirroot . '/my/lib.php'); 33 34 /** 35 * External block functions unit tests 36 * 37 * @package core_block 38 * @category external 39 * @copyright 2015 Juan Leyva <juan@moodle.com> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 * @since Moodle 3.0 42 */ 43 class core_block_externallib_testcase extends externallib_advanced_testcase { 44 45 /** 46 * Test get_course_blocks 47 */ 48 public function test_get_course_blocks() { 49 global $DB, $FULLME; 50 51 $this->resetAfterTest(true); 52 53 $user = $this->getDataGenerator()->create_user(); 54 $course = $this->getDataGenerator()->create_course(); 55 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 56 $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); 57 58 $page = new moodle_page(); 59 $page->set_context(context_course::instance($course->id)); 60 $page->set_pagelayout('course'); 61 $course->format = course_get_format($course)->get_format(); 62 $page->set_pagetype('course-view-' . $course->format); 63 $page->blocks->load_blocks(); 64 $newblock = 'calendar_upcoming'; 65 $page->blocks->add_block_at_end_of_default_region($newblock); 66 $this->setUser($user); 67 68 // Check for the new block. 69 $result = core_block_external::get_course_blocks($course->id); 70 // We need to execute the return values cleaning process to simulate the web service server. 71 $result = external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result); 72 73 // Expect the new block. 74 $this->assertCount(1, $result['blocks']); 75 $this->assertEquals($newblock, $result['blocks'][0]['name']); 76 } 77 78 /** 79 * Test get_course_blocks on site home 80 */ 81 public function test_get_course_blocks_site_home() { 82 global $DB, $FULLME; 83 84 $this->resetAfterTest(true); 85 86 $user = $this->getDataGenerator()->create_user(); 87 88 $page = new moodle_page(); 89 $page->set_context(context_course::instance(SITEID)); 90 $page->set_pagelayout('frontpage'); 91 $page->set_pagetype('site-index'); 92 $page->blocks->load_blocks(); 93 $newblock = 'calendar_upcoming'; 94 $page->blocks->add_block_at_end_of_default_region($newblock); 95 $this->setUser($user); 96 97 // Check for the new block. 98 $result = core_block_external::get_course_blocks(SITEID); 99 // We need to execute the return values cleaning process to simulate the web service server. 100 $result = external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result); 101 102 // Expect the new block. 103 $this->assertCount(1, $result['blocks']); 104 $this->assertEquals($newblock, $result['blocks'][0]['name']); 105 } 106 107 /** 108 * Test get_course_blocks 109 */ 110 public function test_get_course_blocks_overrides() { 111 global $DB, $CFG, $FULLME; 112 113 $this->resetAfterTest(true); 114 115 $CFG->defaultblocks_override = 'search_forums,course_list:calendar_upcoming,recent_activity'; 116 117 $user = $this->getDataGenerator()->create_user(); 118 $course = $this->getDataGenerator()->create_course(); 119 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 120 $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); 121 122 $this->setUser($user); 123 124 // Try default blocks. 125 $result = core_block_external::get_course_blocks($course->id); 126 // We need to execute the return values cleaning process to simulate the web service server. 127 $result = external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result); 128 129 // Expect 4 default blocks. 130 $this->assertCount(4, $result['blocks']); 131 132 $expectedblocks = array('navigation', 'settings', 'search_forums', 'course_list', 133 'calendar_upcoming', 'recent_activity'); 134 foreach ($result['blocks'] as $block) { 135 if (!in_array($block['name'], $expectedblocks)) { 136 $this->fail("Unexpected block found: " . $block['name']); 137 } 138 } 139 140 } 141 142 /** 143 * Test get_course_blocks contents 144 */ 145 public function test_get_course_blocks_contents() { 146 global $DB, $FULLME; 147 148 $this->resetAfterTest(true); 149 150 $user = $this->getDataGenerator()->create_user(); 151 $course = $this->getDataGenerator()->create_course(); 152 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 153 $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); 154 $coursecontext = context_course::instance($course->id); 155 156 // Create a HTML block. 157 $title = 'Some course info'; 158 $body = 'Some course info<br /><p>Some contents</p>'; 159 $bodyformat = FORMAT_MOODLE; 160 $page = new moodle_page(); 161 $page->set_context($coursecontext); 162 $page->set_pagelayout('course'); 163 $course->format = course_get_format($course)->get_format(); 164 $page->set_pagetype('course-view-' . $course->format); 165 $page->blocks->load_blocks(); 166 $newblock = 'html'; 167 $page->blocks->add_block_at_end_of_default_region($newblock); 168 169 $this->setUser($user); 170 // Re-create the page. 171 $page = new moodle_page(); 172 $page->set_context($coursecontext); 173 $page->set_pagelayout('course'); 174 $course->format = course_get_format($course)->get_format(); 175 $page->set_pagetype('course-view-' . $course->format); 176 $page->blocks->load_blocks(); 177 $blocks = $page->blocks->get_blocks_for_region($page->blocks->get_default_region()); 178 $block = end($blocks); 179 $block = block_instance('html', $block->instance); 180 $nonscalar = [ 181 'something' => true, 182 ]; 183 $configdata = (object) [ 184 'title' => $title, 185 'text' => [ 186 'itemid' => 0, 187 'text' => $body, 188 'format' => $bodyformat, 189 ], 190 'nonscalar' => $nonscalar 191 ]; 192 $block->instance_config_save((object) $configdata); 193 $filename = 'img.png'; 194 $filerecord = array( 195 'contextid' => context_block::instance($block->instance->id)->id, 196 'component' => 'block_html', 197 'filearea' => 'content', 198 'itemid' => 0, 199 'filepath' => '/', 200 'filename' => $filename, 201 ); 202 // Create an area to upload the file. 203 $fs = get_file_storage(); 204 // Create a file from the string that we made earlier. 205 $file = $fs->create_file_from_string($filerecord, 'some fake content (should be an image).'); 206 207 // Check for the new block. 208 $result = core_block_external::get_course_blocks($course->id, true); 209 // We need to execute the return values cleaning process to simulate the web service server. 210 $result = external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result); 211 212 // Expect the new block. 213 $this->assertCount(1, $result['blocks']); 214 $this->assertEquals($title, $result['blocks'][0]['contents']['title']); 215 $this->assertEquals($body, $result['blocks'][0]['contents']['content']); 216 $this->assertEquals(FORMAT_HTML, $result['blocks'][0]['contents']['contentformat']); // Format change for external. 217 $this->assertEquals('', $result['blocks'][0]['contents']['footer']); 218 $this->assertCount(1, $result['blocks'][0]['contents']['files']); 219 $this->assertEquals($newblock, $result['blocks'][0]['name']); 220 $configcounts = 0; 221 foreach ($result['blocks'][0]['configs'] as $config) { 222 if ($config['type'] = 'plugin' && $config['name'] == 'allowcssclasses' && $config['value'] == json_encode('0')) { 223 $configcounts++; 224 } else if ($config['type'] = 'instance' && $config['name'] == 'text' && $config['value'] == json_encode($body)) { 225 $configcounts++; 226 } else if ($config['type'] = 'instance' && $config['name'] == 'title' && $config['value'] == json_encode($title)) { 227 $configcounts++; 228 } else if ($config['type'] = 'instance' && $config['name'] == 'format' && $config['value'] == json_encode('0')) { 229 $configcounts++; 230 } else if ($config['type'] = 'instance' && $config['name'] == 'nonscalar' && 231 $config['value'] == json_encode($nonscalar)) { 232 $configcounts++; 233 } 234 } 235 $this->assertEquals(5, $configcounts); 236 } 237 238 /** 239 * Test get_course_blocks contents with mathjax. 240 */ 241 public function test_get_course_blocks_contents_with_mathjax() { 242 global $DB, $CFG; 243 244 require_once($CFG->dirroot . '/lib/externallib.php'); 245 246 $this->resetAfterTest(true); 247 248 // Enable MathJax filter in content and headings. 249 $this->configure_filters([ 250 ['name' => 'mathjaxloader', 'state' => TEXTFILTER_ON, 'move' => -1, 'applytostrings' => true], 251 ]); 252 253 // Create a few stuff to test with. 254 $user = $this->getDataGenerator()->create_user(); 255 $course = $this->getDataGenerator()->create_course(); 256 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 257 $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); 258 $coursecontext = context_course::instance($course->id); 259 260 // Create a HTML block. 261 $title = 'My block $$(a+b)=2$$'; 262 $body = 'My block contents $$(a+b)=2$$'; 263 $bodyformat = FORMAT_MOODLE; 264 $page = new moodle_page(); 265 $page->set_context($coursecontext); 266 $page->set_pagelayout('course'); 267 $course->format = course_get_format($course)->get_format(); 268 $page->set_pagetype('course-view-' . $course->format); 269 $page->blocks->load_blocks(); 270 $newblock = 'html'; 271 $page->blocks->add_block_at_end_of_default_region($newblock); 272 273 $this->setUser($user); 274 // Re-create the page. 275 $page = new moodle_page(); 276 $page->set_context($coursecontext); 277 $page->set_pagelayout('course'); 278 $course->format = course_get_format($course)->get_format(); 279 $page->set_pagetype('course-view-' . $course->format); 280 $page->blocks->load_blocks(); 281 $blocks = $page->blocks->get_blocks_for_region($page->blocks->get_default_region()); 282 $block = end($blocks); 283 $block = block_instance('html', $block->instance); 284 $nonscalar = [ 285 'something' => true, 286 ]; 287 $configdata = (object) [ 288 'title' => $title, 289 'text' => [ 290 'itemid' => 0, 291 'text' => $body, 292 'format' => $bodyformat, 293 ], 294 'nonscalar' => $nonscalar 295 ]; 296 $block->instance_config_save((object) $configdata); 297 298 // Check for the new block. 299 $result = core_block_external::get_course_blocks($course->id, true); 300 $result = external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result); 301 302 // Format the original data. 303 $sitecontext = context_system::instance(); 304 $title = external_format_string($title, $coursecontext->id); 305 list($body, $bodyformat) = external_format_text($body, $bodyformat, $coursecontext->id, 'block_html', 'content'); 306 307 // Check that the block data is formatted. 308 $this->assertCount(1, $result['blocks']); 309 $this->assertStringContainsString('<span class="filter_mathjaxloader_equation">', 310 $result['blocks'][0]['contents']['title']); 311 $this->assertStringContainsString('<span class="filter_mathjaxloader_equation">', 312 $result['blocks'][0]['contents']['content']); 313 $this->assertEquals($title, $result['blocks'][0]['contents']['title']); 314 $this->assertEquals($body, $result['blocks'][0]['contents']['content']); 315 } 316 317 /** 318 * Test user get default dashboard blocks. 319 */ 320 public function test_get_dashboard_blocks_default_dashboard() { 321 global $PAGE, $DB; 322 $this->resetAfterTest(true); 323 324 $user = $this->getDataGenerator()->create_user(); 325 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set. 326 327 // Force a setting change to check the returned blocks settings. 328 set_config('displaycategories', 0, 'block_recentlyaccessedcourses'); 329 330 // Get the expected default blocks. 331 $alldefaultblocksordered = $DB->get_records_menu('block_instances', 332 array('pagetypepattern' => 'my-index'), 'defaultregion, defaultweight ASC', 'id, blockname'); 333 334 $this->setUser($user); 335 336 // Check for the default blocks. 337 $result = core_block_external::get_dashboard_blocks($user->id); 338 // We need to execute the return values cleaning process to simulate the web service server. 339 $result = external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result); 340 // Expect all blogs except learning plans one (no learning plans to show). 341 $this->assertCount(count($alldefaultblocksordered) - 1, $result['blocks']); 342 $returnedblocks = array(); 343 foreach ($result['blocks'] as $block) { 344 // Check all the returned blocks are in the expected blocks array. 345 $this->assertContains($block['name'], $alldefaultblocksordered); 346 $returnedblocks[] = $block['name']; 347 // Check the configuration returned for this default block. 348 if ($block['name'] == 'recentlyaccessedcourses') { 349 // Convert config to associative array to avoid DB sorting randomness. 350 $config = array_column($block['configs'], null, 'name'); 351 $this->assertArrayHasKey('displaycategories', $config); 352 $this->assertEquals(json_encode('0'), $config['displaycategories']['value']); 353 $this->assertEquals('plugin', $config['displaycategories']['type']); 354 } 355 } 356 // Remove lp block. 357 array_shift($alldefaultblocksordered); 358 // Check that we received the blocks in the expected order. 359 $this->assertEquals(array_values($alldefaultblocksordered), $returnedblocks); 360 } 361 362 /** 363 * Test user get default dashboard blocks including a sticky block. 364 */ 365 public function test_get_dashboard_blocks_default_dashboard_including_sticky_block() { 366 global $PAGE, $DB; 367 $this->resetAfterTest(true); 368 369 $user = $this->getDataGenerator()->create_user(); 370 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set. 371 372 // Get the expected default blocks. 373 $alldefaultblocks = $DB->get_records_menu('block_instances', array('pagetypepattern' => 'my-index'), '', 'id, blockname'); 374 375 // Now, add a sticky block. 376 $page = new moodle_page(); 377 $page->set_context(context_system::instance()); 378 $page->set_pagetype('my-index'); 379 $page->set_url(new moodle_url('/')); 380 $page->blocks->add_region('side-pre'); 381 $page->blocks->load_blocks(); 382 $page->blocks->add_block('myprofile', 'side-pre', 0, true, '*'); 383 384 $this->setUser($user); 385 386 // Check for the default blocks plus the sticky. 387 $result = core_block_external::get_dashboard_blocks($user->id); 388 // We need to execute the return values cleaning process to simulate the web service server. 389 $result = external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result); 390 // Expect all blogs plus sticky one except learning plans one (no learning plans to show). 391 $this->assertCount(count($alldefaultblocks), $result['blocks']); 392 $found = false; 393 foreach ($result['blocks'] as $block) { 394 if ($block['name'] == 'myprofile') { 395 $this->assertEquals('side-pre', $block['region']); 396 $found = true; 397 continue; 398 } 399 // Check that the block is in the expected blocks array. 400 $this->assertContains($block['name'], $alldefaultblocks); 401 } 402 $this->assertTrue($found); 403 } 404 405 /** 406 * Test admin get user's custom dashboard blocks. 407 */ 408 public function test_get_dashboard_blocks_custom_user_dashboard() { 409 global $PAGE, $DB; 410 $this->resetAfterTest(true); 411 412 $user = $this->getDataGenerator()->create_user(); 413 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set. 414 415 // Get the expected default blocks. 416 $alldefaultblocks = $DB->get_records_menu('block_instances', array('pagetypepattern' => 'my-index'), '', 'id, blockname'); 417 418 // Add a custom block. 419 $page = new moodle_page(); 420 $page->set_context(context_user::instance($user->id)); 421 $page->set_pagelayout('mydashboard'); 422 $page->set_pagetype('my-index'); 423 $page->blocks->add_region('content'); 424 $currentpage = my_get_page($user->id, MY_PAGE_PRIVATE); 425 $page->set_subpage($currentpage->id); 426 $page->blocks->load_blocks(); 427 $page->blocks->add_block('myprofile', 'content', 0, false); 428 429 $this->setAdminUser(); 430 431 // Check for the new block as admin for a user. 432 $result = core_block_external::get_dashboard_blocks($user->id); 433 // We need to execute the return values cleaning process to simulate the web service server. 434 $result = external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result); 435 // Expect all default blogs plys the one we added except learning plans one (no learning plans to show). 436 $this->assertCount(count($alldefaultblocks), $result['blocks']); 437 $found = false; 438 foreach ($result['blocks'] as $block) { 439 if ($block['name'] == 'myprofile') { 440 $this->assertEquals('content', $block['region']); 441 $found = true; 442 continue; 443 } 444 // Check that the block is in the expected blocks array. 445 $this->assertContains($block['name'], $alldefaultblocks); 446 } 447 $this->assertTrue($found); 448 } 449 450 /** 451 * Test user tries to get other user blocks not having permission. 452 */ 453 public function test_get_dashboard_blocks_other_user_missing_permissions() { 454 $this->resetAfterTest(true); 455 456 $user1 = $this->getDataGenerator()->create_user(); 457 $user2 = $this->getDataGenerator()->create_user(); 458 459 $this->setUser($user1); 460 461 $this->expectException('moodle_exception'); 462 core_block_external::get_dashboard_blocks($user2->id); 463 } 464 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body