Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
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 */ 43 public function test_get_course_blocks() { 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 = \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 */ 76 public function test_get_course_blocks_site_home() { 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 = \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 */ 105 public function test_get_course_blocks_overrides() { 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 = \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 */ 140 public function test_get_course_blocks_contents() { 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 = \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 */ 236 public function test_get_course_blocks_contents_with_mathjax() { 237 global $DB, $CFG; 238 239 require_once($CFG->dirroot . '/lib/externallib.php'); 240 241 $this->resetAfterTest(true); 242 243 // Enable MathJax filter in content and headings. 244 $this->configure_filters([ 245 ['name' => 'mathjaxloader', 'state' => TEXTFILTER_ON, 'move' => -1, 'applytostrings' => true], 246 ]); 247 248 // Create a few stuff to test with. 249 $user = $this->getDataGenerator()->create_user(); 250 $course = $this->getDataGenerator()->create_course(); 251 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 252 $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); 253 $coursecontext = \context_course::instance($course->id); 254 255 // Create a HTML block. 256 $title = 'My block $$(a+b)=2$$'; 257 $body = 'My block contents $$(a+b)=2$$'; 258 $bodyformat = FORMAT_MOODLE; 259 $page = new \moodle_page(); 260 $page->set_context($coursecontext); 261 $page->set_pagelayout('course'); 262 $course->format = course_get_format($course)->get_format(); 263 $page->set_pagetype('course-view-' . $course->format); 264 $page->blocks->load_blocks(); 265 $newblock = 'html'; 266 $page->blocks->add_block_at_end_of_default_region($newblock); 267 268 $this->setUser($user); 269 // Re-create the page. 270 $page = new \moodle_page(); 271 $page->set_context($coursecontext); 272 $page->set_pagelayout('course'); 273 $course->format = course_get_format($course)->get_format(); 274 $page->set_pagetype('course-view-' . $course->format); 275 $page->blocks->load_blocks(); 276 $blocks = $page->blocks->get_blocks_for_region($page->blocks->get_default_region()); 277 $block = end($blocks); 278 $block = block_instance('html', $block->instance); 279 $nonscalar = [ 280 'something' => true, 281 ]; 282 $configdata = (object) [ 283 'title' => $title, 284 'text' => [ 285 'itemid' => 0, 286 'text' => $body, 287 'format' => $bodyformat, 288 ], 289 'nonscalar' => $nonscalar 290 ]; 291 $block->instance_config_save((object) $configdata); 292 293 // Check for the new block. 294 $result = core_block_external::get_course_blocks($course->id, true); 295 $result = \external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result); 296 297 // Format the original data. 298 $sitecontext = \context_system::instance(); 299 $title = external_format_string($title, $coursecontext->id); 300 list($body, $bodyformat) = external_format_text($body, $bodyformat, $coursecontext->id, 'block_html', 'content'); 301 302 // Check that the block data is formatted. 303 $this->assertCount(1, $result['blocks']); 304 $this->assertStringContainsString('<span class="filter_mathjaxloader_equation">', 305 $result['blocks'][0]['contents']['title']); 306 $this->assertStringContainsString('<span class="filter_mathjaxloader_equation">', 307 $result['blocks'][0]['contents']['content']); 308 $this->assertEquals($title, $result['blocks'][0]['contents']['title']); 309 $this->assertEquals($body, $result['blocks'][0]['contents']['content']); 310 } 311 312 /** 313 * Test user get default dashboard blocks. 314 */ 315 public function test_get_dashboard_blocks_default_dashboard() { 316 global $PAGE, $DB; 317 $this->resetAfterTest(true); 318 319 $user = $this->getDataGenerator()->create_user(); 320 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set. 321 322 // Force a setting change to check the returned blocks settings. 323 set_config('displaycategories', 0, 'block_recentlyaccessedcourses'); 324 325 // Get the expected default blocks. 326 $alldefaultblocksordered = $DB->get_records_menu('block_instances', 327 array('pagetypepattern' => 'my-index'), 'defaultregion, defaultweight ASC', 'id, blockname'); 328 329 $this->setUser($user); 330 331 // Check for the default blocks. 332 $result = core_block_external::get_dashboard_blocks($user->id); 333 // We need to execute the return values cleaning process to simulate the web service server. 334 $result = \external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result); 335 // Expect all blogs except learning plans one (no learning plans to show). 336 $this->assertCount(count($alldefaultblocksordered) - 1, $result['blocks']); 337 $returnedblocks = array(); 338 foreach ($result['blocks'] as $block) { 339 // Check all the returned blocks are in the expected blocks array. 340 $this->assertContains($block['name'], $alldefaultblocksordered); 341 $returnedblocks[] = $block['name']; 342 // Check the configuration returned for this default block. 343 if ($block['name'] == 'recentlyaccessedcourses') { 344 // Convert config to associative array to avoid DB sorting randomness. 345 $config = array_column($block['configs'], null, 'name'); 346 $this->assertArrayHasKey('displaycategories', $config); 347 $this->assertEquals(json_encode('0'), $config['displaycategories']['value']); 348 $this->assertEquals('plugin', $config['displaycategories']['type']); 349 } 350 } 351 // Remove lp block. 352 array_shift($alldefaultblocksordered); 353 // Check that we received the blocks in the expected order. 354 $this->assertEquals(array_values($alldefaultblocksordered), $returnedblocks); 355 } 356 357 /** 358 * Test user get default dashboard blocks including a sticky block. 359 */ 360 public function test_get_dashboard_blocks_default_dashboard_including_sticky_block() { 361 global $PAGE, $DB; 362 $this->resetAfterTest(true); 363 364 $user = $this->getDataGenerator()->create_user(); 365 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set. 366 367 // Get the expected default blocks. 368 $alldefaultblocks = $DB->get_records_menu('block_instances', array('pagetypepattern' => 'my-index'), '', 'id, blockname'); 369 370 // Now, add a sticky block. 371 $page = new \moodle_page(); 372 $page->set_context(\context_system::instance()); 373 $page->set_pagetype('my-index'); 374 $page->set_url(new \moodle_url('/')); 375 $page->blocks->add_region('side-pre'); 376 $page->blocks->load_blocks(); 377 $page->blocks->add_block('myprofile', 'side-pre', 0, true, '*'); 378 379 $this->setUser($user); 380 381 // Check for the default blocks plus the sticky. 382 $result = core_block_external::get_dashboard_blocks($user->id); 383 // We need to execute the return values cleaning process to simulate the web service server. 384 $result = \external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result); 385 // Expect all blogs plus sticky one except learning plans one (no learning plans to show). 386 $this->assertCount(count($alldefaultblocks), $result['blocks']); 387 $found = false; 388 foreach ($result['blocks'] as $block) { 389 if ($block['name'] == 'myprofile') { 390 $this->assertEquals('side-pre', $block['region']); 391 $found = true; 392 continue; 393 } 394 // Check that the block is in the expected blocks array. 395 $this->assertContains($block['name'], $alldefaultblocks); 396 } 397 $this->assertTrue($found); 398 } 399 400 /** 401 * Test admin get user's custom dashboard blocks. 402 */ 403 public function test_get_dashboard_blocks_custom_user_dashboard() { 404 global $PAGE, $DB; 405 $this->resetAfterTest(true); 406 407 $user = $this->getDataGenerator()->create_user(); 408 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set. 409 410 // Get the expected default blocks. 411 $alldefaultblocks = $DB->get_records_menu('block_instances', array('pagetypepattern' => 'my-index'), '', 'id, blockname'); 412 413 // Add a custom block. 414 $page = new \moodle_page(); 415 $page->set_context(\context_user::instance($user->id)); 416 $page->set_pagelayout('mydashboard'); 417 $page->set_pagetype('my-index'); 418 $page->blocks->add_region('content'); 419 $currentpage = my_get_page($user->id, MY_PAGE_PRIVATE); 420 $page->set_subpage($currentpage->id); 421 $page->blocks->load_blocks(); 422 $page->blocks->add_block('myprofile', 'content', 0, false); 423 424 $this->setAdminUser(); 425 426 // Check for the new block as admin for a user. 427 $result = core_block_external::get_dashboard_blocks($user->id); 428 // We need to execute the return values cleaning process to simulate the web service server. 429 $result = \external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result); 430 // Expect all default blogs plys the one we added except learning plans one (no learning plans to show). 431 $this->assertCount(count($alldefaultblocks), $result['blocks']); 432 $found = false; 433 foreach ($result['blocks'] as $block) { 434 if ($block['name'] == 'myprofile') { 435 $this->assertEquals('content', $block['region']); 436 $found = true; 437 continue; 438 } 439 // Check that the block is in the expected blocks array. 440 $this->assertContains($block['name'], $alldefaultblocks); 441 } 442 $this->assertTrue($found); 443 } 444 445 /** 446 * Test user tries to get other user blocks not having permission. 447 */ 448 public function test_get_dashboard_blocks_other_user_missing_permissions() { 449 $this->resetAfterTest(true); 450 451 $user1 = $this->getDataGenerator()->create_user(); 452 $user2 = $this->getDataGenerator()->create_user(); 453 454 $this->setUser($user1); 455 456 $this->expectException('moodle_exception'); 457 core_block_external::get_dashboard_blocks($user2->id); 458 } 459 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body