on-demand release 3.8dev+
[moodle.git] / blocks / tests / externallib_test.php
CommitLineData
8446ba36
JL
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
27defined('MOODLE_INTERNAL') || die();
28
29global $CFG;
30
31require_once($CFG->dirroot . '/webservice/tests/helpers.php');
0f8b2604 32require_once($CFG->dirroot . '/my/lib.php');
8446ba36
JL
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 */
43class 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
1ce19cc3 115 $CFG->defaultblocks_override = 'search_forums,course_list:calendar_upcoming,recent_activity';
8446ba36
JL
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
1ce19cc3
AB
129 // Expect 4 default blocks.
130 $this->assertCount(4, $result['blocks']);
8446ba36 131
1ce19cc3 132 $expectedblocks = array('navigation', 'settings', 'search_forums', 'course_list',
8446ba36
JL
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
cde3dc05
JL
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 $configdata = (object) [
181 'title' => $title,
182 'text' => [
183 'itemid' => 0,
184 'text' => $body,
185 'format' => $bodyformat,
186 ],
187 ];
188 $block->instance_config_save((object) $configdata);
189 $filename = 'img.png';
190 $filerecord = array(
191 'contextid' => context_block::instance($block->instance->id)->id,
192 'component' => 'block_html',
193 'filearea' => 'content',
194 'itemid' => 0,
195 'filepath' => '/',
196 'filename' => $filename,
197 );
198 // Create an area to upload the file.
199 $fs = get_file_storage();
200 // Create a file from the string that we made earlier.
201 $file = $fs->create_file_from_string($filerecord, 'some fake content (should be an image).');
202
203 // Check for the new block.
204 $result = core_block_external::get_course_blocks($course->id, true);
205 // We need to execute the return values cleaning process to simulate the web service server.
206 $result = external_api::clean_returnvalue(core_block_external::get_course_blocks_returns(), $result);
207
208 // Expect the new block.
209 $this->assertCount(1, $result['blocks']);
210 $this->assertEquals($title, $result['blocks'][0]['contents']['title']);
211 $this->assertEquals($body, $result['blocks'][0]['contents']['content']);
212 $this->assertEquals(FORMAT_HTML, $result['blocks'][0]['contents']['contentformat']); // Format change for external.
213 $this->assertEquals('', $result['blocks'][0]['contents']['footer']);
214 $this->assertCount(1, $result['blocks'][0]['contents']['files']);
215 $this->assertEquals($newblock, $result['blocks'][0]['name']);
c9acdfb6
JL
216 $configcounts = 0;
217 foreach ($result['blocks'][0]['configs'] as $config) {
218 if ($config['type'] = 'plugin' && $config['name'] == 'allowcssclasses' && $config['value'] == 0) {
219 $configcounts++;
220 } else if ($config['type'] = 'instance' && $config['name'] == 'text' && $config['value'] == $body) {
221 $configcounts++;
222 } else if ($config['type'] = 'instance' && $config['name'] == 'title' && $config['value'] == $title) {
223 $configcounts++;
224 } else if ($config['type'] = 'instance' && $config['name'] == 'format' && $config['value'] == 0) {
225 $configcounts++;
226 }
227 }
228 $this->assertEquals(4, $configcounts);
cde3dc05
JL
229 }
230
0f8b2604
JL
231 /**
232 * Test user get default dashboard blocks.
233 */
234 public function test_get_dashboard_blocks_default_dashboard() {
235 global $PAGE, $DB;
236 $this->resetAfterTest(true);
237
238 $user = $this->getDataGenerator()->create_user();
239 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set.
240
c9acdfb6
JL
241 // Force a setting change to check the returned blocks settings.
242 set_config('displaycategories', 0, 'block_recentlyaccessedcourses');
243
0f8b2604
JL
244 // Get the expected default blocks.
245 $alldefaultblocksordered = $DB->get_records_menu('block_instances',
246 array('pagetypepattern' => 'my-index'), 'defaultregion, defaultweight ASC', 'id, blockname');
247
248 $this->setUser($user);
249
250 // Check for the default blocks.
251 $result = core_block_external::get_dashboard_blocks($user->id);
252 // We need to execute the return values cleaning process to simulate the web service server.
253 $result = external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result);
254 // Expect all blogs except learning plans one (no learning plans to show).
255 $this->assertCount(count($alldefaultblocksordered) - 1, $result['blocks']);
256 $returnedblocks = array();
257 foreach ($result['blocks'] as $block) {
258 // Check all the returned blocks are in the expected blocks array.
259 $this->assertContains($block['name'], $alldefaultblocksordered);
260 $returnedblocks[] = $block['name'];
c9acdfb6
JL
261 // Check the configuration returned for this default block.
262 if ($block['name'] == 'recentlyaccessedcourses') {
263 $this->assertEquals('displaycategories', $block['configs'][0]['name']);
264 $this->assertEquals(0, $block['configs'][0]['value']);
265 $this->assertEquals('plugin', $block['configs'][0]['type']);
266 }
0f8b2604
JL
267 }
268 // Remove lp block.
269 array_shift($alldefaultblocksordered);
270 // Check that we received the blocks in the expected order.
271 $this->assertEquals(array_values($alldefaultblocksordered), $returnedblocks);
272 }
273
274 /**
275 * Test user get default dashboard blocks including a sticky block.
276 */
277 public function test_get_dashboard_blocks_default_dashboard_including_sticky_block() {
278 global $PAGE, $DB;
279 $this->resetAfterTest(true);
280
281 $user = $this->getDataGenerator()->create_user();
282 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set.
283
284 // Get the expected default blocks.
285 $alldefaultblocks = $DB->get_records_menu('block_instances', array('pagetypepattern' => 'my-index'), '', 'id, blockname');
286
287 // Now, add a sticky block.
288 $page = new moodle_page();
289 $page->set_context(context_system::instance());
290 $page->set_pagetype('my-index');
291 $page->set_url(new moodle_url('/'));
292 $page->blocks->add_region('side-pre');
293 $page->blocks->load_blocks();
294 $page->blocks->add_block('myprofile', 'side-pre', 0, true, '*');
295
296 $this->setUser($user);
297
298 // Check for the default blocks plus the sticky.
299 $result = core_block_external::get_dashboard_blocks($user->id);
300 // We need to execute the return values cleaning process to simulate the web service server.
301 $result = external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result);
302 // Expect all blogs plus sticky one except learning plans one (no learning plans to show).
303 $this->assertCount(count($alldefaultblocks), $result['blocks']);
304 $found = false;
305 foreach ($result['blocks'] as $block) {
306 if ($block['name'] == 'myprofile') {
307 $this->assertEquals('side-pre', $block['region']);
308 $found = true;
309 continue;
310 }
311 // Check that the block is in the expected blocks array.
312 $this->assertContains($block['name'], $alldefaultblocks);
313 }
314 $this->assertTrue($found);
315 }
316
317 /**
318 * Test admin get user's custom dashboard blocks.
319 */
320 public function test_get_dashboard_blocks_custom_user_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 // Get the expected default blocks.
328 $alldefaultblocks = $DB->get_records_menu('block_instances', array('pagetypepattern' => 'my-index'), '', 'id, blockname');
329
330 // Add a custom block.
331 $page = new moodle_page();
332 $page->set_context(context_user::instance($user->id));
333 $page->set_pagelayout('mydashboard');
334 $page->set_pagetype('my-index');
335 $page->blocks->add_region('content');
336 $currentpage = my_get_page($user->id, MY_PAGE_PRIVATE);
337 $page->set_subpage($currentpage->id);
338 $page->blocks->load_blocks();
339 $page->blocks->add_block('myprofile', 'content', 0, false);
340
341 $this->setAdminUser();
342
343 // Check for the new block as admin for a user.
344 $result = core_block_external::get_dashboard_blocks($user->id);
345 // We need to execute the return values cleaning process to simulate the web service server.
346 $result = external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result);
347 // Expect all default blogs plys the one we added except learning plans one (no learning plans to show).
348 $this->assertCount(count($alldefaultblocks), $result['blocks']);
349 $found = false;
350 foreach ($result['blocks'] as $block) {
351 if ($block['name'] == 'myprofile') {
352 $this->assertEquals('content', $block['region']);
353 $found = true;
354 continue;
355 }
356 // Check that the block is in the expected blocks array.
357 $this->assertContains($block['name'], $alldefaultblocks);
358 }
359 $this->assertTrue($found);
360 }
361
362 /**
363 * Test user tries to get other user blocks not having permission.
364 */
365 public function test_get_dashboard_blocks_other_user_missing_permissions() {
366 $this->resetAfterTest(true);
367
368 $user1 = $this->getDataGenerator()->create_user();
369 $user2 = $this->getDataGenerator()->create_user();
370
371 $this->setUser($user1);
372
373 $this->expectException('moodle_exception');
374 core_block_external::get_dashboard_blocks($user2->id);
375 }
8446ba36 376}