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']);
216 }
217
0f8b2604
JL
218 /**
219 * Test user get default dashboard blocks.
220 */
221 public function test_get_dashboard_blocks_default_dashboard() {
222 global $PAGE, $DB;
223 $this->resetAfterTest(true);
224
225 $user = $this->getDataGenerator()->create_user();
226 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set.
227
228 // Get the expected default blocks.
229 $alldefaultblocksordered = $DB->get_records_menu('block_instances',
230 array('pagetypepattern' => 'my-index'), 'defaultregion, defaultweight ASC', 'id, blockname');
231
232 $this->setUser($user);
233
234 // Check for the default blocks.
235 $result = core_block_external::get_dashboard_blocks($user->id);
236 // We need to execute the return values cleaning process to simulate the web service server.
237 $result = external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result);
238 // Expect all blogs except learning plans one (no learning plans to show).
239 $this->assertCount(count($alldefaultblocksordered) - 1, $result['blocks']);
240 $returnedblocks = array();
241 foreach ($result['blocks'] as $block) {
242 // Check all the returned blocks are in the expected blocks array.
243 $this->assertContains($block['name'], $alldefaultblocksordered);
244 $returnedblocks[] = $block['name'];
245 }
246 // Remove lp block.
247 array_shift($alldefaultblocksordered);
248 // Check that we received the blocks in the expected order.
249 $this->assertEquals(array_values($alldefaultblocksordered), $returnedblocks);
250 }
251
252 /**
253 * Test user get default dashboard blocks including a sticky block.
254 */
255 public function test_get_dashboard_blocks_default_dashboard_including_sticky_block() {
256 global $PAGE, $DB;
257 $this->resetAfterTest(true);
258
259 $user = $this->getDataGenerator()->create_user();
260 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set.
261
262 // Get the expected default blocks.
263 $alldefaultblocks = $DB->get_records_menu('block_instances', array('pagetypepattern' => 'my-index'), '', 'id, blockname');
264
265 // Now, add a sticky block.
266 $page = new moodle_page();
267 $page->set_context(context_system::instance());
268 $page->set_pagetype('my-index');
269 $page->set_url(new moodle_url('/'));
270 $page->blocks->add_region('side-pre');
271 $page->blocks->load_blocks();
272 $page->blocks->add_block('myprofile', 'side-pre', 0, true, '*');
273
274 $this->setUser($user);
275
276 // Check for the default blocks plus the sticky.
277 $result = core_block_external::get_dashboard_blocks($user->id);
278 // We need to execute the return values cleaning process to simulate the web service server.
279 $result = external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result);
280 // Expect all blogs plus sticky one except learning plans one (no learning plans to show).
281 $this->assertCount(count($alldefaultblocks), $result['blocks']);
282 $found = false;
283 foreach ($result['blocks'] as $block) {
284 if ($block['name'] == 'myprofile') {
285 $this->assertEquals('side-pre', $block['region']);
286 $found = true;
287 continue;
288 }
289 // Check that the block is in the expected blocks array.
290 $this->assertContains($block['name'], $alldefaultblocks);
291 }
292 $this->assertTrue($found);
293 }
294
295 /**
296 * Test admin get user's custom dashboard blocks.
297 */
298 public function test_get_dashboard_blocks_custom_user_dashboard() {
299 global $PAGE, $DB;
300 $this->resetAfterTest(true);
301
302 $user = $this->getDataGenerator()->create_user();
303 $PAGE->set_url('/my/index.php'); // Need this because some internal API calls require the $PAGE url to be set.
304
305 // Get the expected default blocks.
306 $alldefaultblocks = $DB->get_records_menu('block_instances', array('pagetypepattern' => 'my-index'), '', 'id, blockname');
307
308 // Add a custom block.
309 $page = new moodle_page();
310 $page->set_context(context_user::instance($user->id));
311 $page->set_pagelayout('mydashboard');
312 $page->set_pagetype('my-index');
313 $page->blocks->add_region('content');
314 $currentpage = my_get_page($user->id, MY_PAGE_PRIVATE);
315 $page->set_subpage($currentpage->id);
316 $page->blocks->load_blocks();
317 $page->blocks->add_block('myprofile', 'content', 0, false);
318
319 $this->setAdminUser();
320
321 // Check for the new block as admin for a user.
322 $result = core_block_external::get_dashboard_blocks($user->id);
323 // We need to execute the return values cleaning process to simulate the web service server.
324 $result = external_api::clean_returnvalue(core_block_external::get_dashboard_blocks_returns(), $result);
325 // Expect all default blogs plys the one we added except learning plans one (no learning plans to show).
326 $this->assertCount(count($alldefaultblocks), $result['blocks']);
327 $found = false;
328 foreach ($result['blocks'] as $block) {
329 if ($block['name'] == 'myprofile') {
330 $this->assertEquals('content', $block['region']);
331 $found = true;
332 continue;
333 }
334 // Check that the block is in the expected blocks array.
335 $this->assertContains($block['name'], $alldefaultblocks);
336 }
337 $this->assertTrue($found);
338 }
339
340 /**
341 * Test user tries to get other user blocks not having permission.
342 */
343 public function test_get_dashboard_blocks_other_user_missing_permissions() {
344 $this->resetAfterTest(true);
345
346 $user1 = $this->getDataGenerator()->create_user();
347 $user2 = $this->getDataGenerator()->create_user();
348
349 $this->setUser($user1);
350
351 $this->expectException('moodle_exception');
352 core_block_external::get_dashboard_blocks($user2->id);
353 }
8446ba36 354}