Commit | Line | Data |
---|---|---|
2a7a0216 JM |
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 course functions unit tests | |
19 | * | |
20 | * @package core_course | |
21 | * @category external | |
22 | * @copyright 2012 Jerome Mouneyrac | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
25 | ||
26 | defined('MOODLE_INTERNAL') || die(); | |
27 | ||
28 | global $CFG; | |
29 | ||
30 | require_once($CFG->dirroot . '/webservice/tests/helpers.php'); | |
31 | ||
32 | /** | |
33 | * External course functions unit tests | |
34 | * | |
35 | * @package core_course | |
36 | * @category external | |
37 | * @copyright 2012 Jerome Mouneyrac | |
38 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
39 | */ | |
8252b7c2 | 40 | class core_course_externallib_testcase extends externallib_advanced_testcase { |
2a7a0216 JM |
41 | |
42 | /** | |
43 | * Tests set up | |
44 | */ | |
45 | protected function setUp() { | |
46 | global $CFG; | |
47 | require_once($CFG->dirroot . '/course/externallib.php'); | |
48 | } | |
49 | ||
50 | /** | |
51 | * Test create_categories | |
52 | */ | |
53 | public function test_create_categories() { | |
54 | ||
55 | global $DB; | |
56 | ||
57 | $this->resetAfterTest(true); | |
58 | ||
59 | // Set the required capabilities by the external function | |
60 | $contextid = context_system::instance()->id; | |
61 | $roleid = $this->assignUserCapability('moodle/category:manage', $contextid); | |
62 | ||
63 | // Create base categories. | |
64 | $category1 = new stdClass(); | |
65 | $category1->name = 'Root Test Category 1'; | |
66 | $category2 = new stdClass(); | |
67 | $category2->name = 'Root Test Category 2'; | |
68 | $category2->idnumber = 'rootcattest2'; | |
69 | $category2->desc = 'Description for root test category 1'; | |
644fcbb6 | 70 | $category2->theme = 'bootstrapbase'; |
2a7a0216 JM |
71 | $categories = array( |
72 | array('name' => $category1->name, 'parent' => 0), | |
73 | array('name' => $category2->name, 'parent' => 0, 'idnumber' => $category2->idnumber, | |
74 | 'description' => $category2->desc, 'theme' => $category2->theme) | |
75 | ); | |
76 | ||
77 | $createdcats = core_course_external::create_categories($categories); | |
78 | ||
fb695f6e JM |
79 | // We need to execute the return values cleaning process to simulate the web service server. |
80 | $createdcats = external_api::clean_returnvalue(core_course_external::create_categories_returns(), $createdcats); | |
81 | ||
2a7a0216 JM |
82 | // Initially confirm that base data was inserted correctly. |
83 | $this->assertEquals($category1->name, $createdcats[0]['name']); | |
84 | $this->assertEquals($category2->name, $createdcats[1]['name']); | |
85 | ||
86 | // Save the ids. | |
87 | $category1->id = $createdcats[0]['id']; | |
88 | $category2->id = $createdcats[1]['id']; | |
89 | ||
90 | // Create on sub category. | |
91 | $category3 = new stdClass(); | |
92 | $category3->name = 'Sub Root Test Category 3'; | |
93 | $subcategories = array( | |
94 | array('name' => $category3->name, 'parent' => $category1->id) | |
95 | ); | |
96 | ||
97 | $createdsubcats = core_course_external::create_categories($subcategories); | |
98 | ||
fb695f6e JM |
99 | // We need to execute the return values cleaning process to simulate the web service server. |
100 | $createdsubcats = external_api::clean_returnvalue(core_course_external::create_categories_returns(), $createdsubcats); | |
101 | ||
2a7a0216 JM |
102 | // Confirm that sub categories were inserted correctly. |
103 | $this->assertEquals($category3->name, $createdsubcats[0]['name']); | |
104 | ||
105 | // Save the ids. | |
106 | $category3->id = $createdsubcats[0]['id']; | |
107 | ||
108 | // Calling the ws function should provide a new sortorder to give category1, | |
109 | // category2, category3. New course categories are ordered by id not name. | |
110 | $category1 = $DB->get_record('course_categories', array('id' => $category1->id)); | |
111 | $category2 = $DB->get_record('course_categories', array('id' => $category2->id)); | |
112 | $category3 = $DB->get_record('course_categories', array('id' => $category3->id)); | |
113 | ||
db1eed70 MG |
114 | // sortorder sequence (and sortorder) must be: |
115 | // category 1 | |
116 | // category 3 | |
117 | // category 2 | |
118 | $this->assertGreaterThan($category1->sortorder, $category3->sortorder); | |
119 | $this->assertGreaterThan($category3->sortorder, $category2->sortorder); | |
2a7a0216 JM |
120 | |
121 | // Call without required capability | |
122 | $this->unassignUserCapability('moodle/category:manage', $contextid, $roleid); | |
52f3e060 | 123 | $this->expectException('required_capability_exception'); |
2a7a0216 JM |
124 | $createdsubcats = core_course_external::create_categories($subcategories); |
125 | ||
126 | } | |
127 | ||
128 | /** | |
129 | * Test delete categories | |
130 | */ | |
131 | public function test_delete_categories() { | |
132 | global $DB; | |
133 | ||
134 | $this->resetAfterTest(true); | |
135 | ||
136 | // Set the required capabilities by the external function | |
137 | $contextid = context_system::instance()->id; | |
138 | $roleid = $this->assignUserCapability('moodle/category:manage', $contextid); | |
139 | ||
140 | $category1 = self::getDataGenerator()->create_category(); | |
141 | $category2 = self::getDataGenerator()->create_category( | |
142 | array('parent' => $category1->id)); | |
143 | $category3 = self::getDataGenerator()->create_category(); | |
144 | $category4 = self::getDataGenerator()->create_category( | |
145 | array('parent' => $category3->id)); | |
146 | $category5 = self::getDataGenerator()->create_category( | |
147 | array('parent' => $category4->id)); | |
148 | ||
149 | //delete category 1 and 2 + delete category 4, category 5 moved under category 3 | |
150 | core_course_external::delete_categories(array( | |
151 | array('id' => $category1->id, 'recursive' => 1), | |
152 | array('id' => $category4->id) | |
153 | )); | |
154 | ||
155 | //check $category 1 and 2 are deleted | |
156 | $notdeletedcount = $DB->count_records_select('course_categories', | |
157 | 'id IN ( ' . $category1->id . ',' . $category2->id . ',' . $category4->id . ')'); | |
158 | $this->assertEquals(0, $notdeletedcount); | |
159 | ||
160 | //check that $category5 as $category3 for parent | |
161 | $dbcategory5 = $DB->get_record('course_categories', array('id' => $category5->id)); | |
162 | $this->assertEquals($dbcategory5->path, $category3->path . '/' . $category5->id); | |
163 | ||
164 | // Call without required capability | |
165 | $this->unassignUserCapability('moodle/category:manage', $contextid, $roleid); | |
52f3e060 | 166 | $this->expectException('required_capability_exception'); |
2a7a0216 JM |
167 | $createdsubcats = core_course_external::delete_categories( |
168 | array(array('id' => $category3->id))); | |
169 | } | |
170 | ||
171 | /** | |
172 | * Test get categories | |
173 | */ | |
174 | public function test_get_categories() { | |
175 | global $DB; | |
176 | ||
177 | $this->resetAfterTest(true); | |
7d6c58bc JM |
178 | |
179 | $generatedcats = array(); | |
2a7a0216 JM |
180 | $category1data['idnumber'] = 'idnumbercat1'; |
181 | $category1data['name'] = 'Category 1 for PHPunit test'; | |
182 | $category1data['description'] = 'Category 1 description'; | |
183 | $category1data['descriptionformat'] = FORMAT_MOODLE; | |
184 | $category1 = self::getDataGenerator()->create_category($category1data); | |
7d6c58bc | 185 | $generatedcats[$category1->id] = $category1; |
2a7a0216 JM |
186 | $category2 = self::getDataGenerator()->create_category( |
187 | array('parent' => $category1->id)); | |
7d6c58bc | 188 | $generatedcats[$category2->id] = $category2; |
2a7a0216 JM |
189 | $category6 = self::getDataGenerator()->create_category( |
190 | array('parent' => $category1->id, 'visible' => 0)); | |
7d6c58bc | 191 | $generatedcats[$category6->id] = $category6; |
2a7a0216 | 192 | $category3 = self::getDataGenerator()->create_category(); |
7d6c58bc | 193 | $generatedcats[$category3->id] = $category3; |
2a7a0216 JM |
194 | $category4 = self::getDataGenerator()->create_category( |
195 | array('parent' => $category3->id)); | |
7d6c58bc | 196 | $generatedcats[$category4->id] = $category4; |
2a7a0216 JM |
197 | $category5 = self::getDataGenerator()->create_category( |
198 | array('parent' => $category4->id)); | |
7d6c58bc | 199 | $generatedcats[$category5->id] = $category5; |
2a7a0216 JM |
200 | |
201 | // Set the required capabilities by the external function. | |
202 | $context = context_system::instance(); | |
203 | $roleid = $this->assignUserCapability('moodle/category:manage', $context->id); | |
204 | ||
205 | // Retrieve category1 + sub-categories except not visible ones | |
206 | $categories = core_course_external::get_categories(array( | |
207 | array('key' => 'id', 'value' => $category1->id), | |
208 | array('key' => 'visible', 'value' => 1)), 1); | |
209 | ||
fb695f6e JM |
210 | // We need to execute the return values cleaning process to simulate the web service server. |
211 | $categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories); | |
212 | ||
2a7a0216 JM |
213 | // Check we retrieve the good total number of categories. |
214 | $this->assertEquals(2, count($categories)); | |
215 | ||
216 | // Check the return values | |
7d6c58bc JM |
217 | foreach ($categories as $category) { |
218 | $generatedcat = $generatedcats[$category['id']]; | |
219 | $this->assertEquals($category['idnumber'], $generatedcat->idnumber); | |
220 | $this->assertEquals($category['name'], $generatedcat->name); | |
46be1d58 MG |
221 | // Description was converted to the HTML format. |
222 | $this->assertEquals($category['description'], format_text($generatedcat->description, FORMAT_MOODLE, array('para' => false))); | |
7d6c58bc JM |
223 | $this->assertEquals($category['descriptionformat'], FORMAT_HTML); |
224 | } | |
2a7a0216 | 225 | |
c1da311a JL |
226 | // Check categories by ids. |
227 | $ids = implode(',', array_keys($generatedcats)); | |
228 | $categories = core_course_external::get_categories(array( | |
229 | array('key' => 'ids', 'value' => $ids)), 0); | |
230 | ||
231 | // We need to execute the return values cleaning process to simulate the web service server. | |
232 | $categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories); | |
233 | ||
234 | // Check we retrieve the good total number of categories. | |
235 | $this->assertEquals(6, count($categories)); | |
236 | // Check ids. | |
237 | $returnedids = []; | |
238 | foreach ($categories as $category) { | |
239 | $returnedids[] = $category['id']; | |
240 | } | |
241 | // Sort the arrays upon comparision. | |
242 | $this->assertEquals(array_keys($generatedcats), $returnedids, '', 0.0, 10, true); | |
243 | ||
2a7a0216 JM |
244 | // Check different params. |
245 | $categories = core_course_external::get_categories(array( | |
246 | array('key' => 'id', 'value' => $category1->id), | |
c1da311a | 247 | array('key' => 'ids', 'value' => $category1->id), |
2a7a0216 JM |
248 | array('key' => 'idnumber', 'value' => $category1->idnumber), |
249 | array('key' => 'visible', 'value' => 1)), 0); | |
fb695f6e JM |
250 | |
251 | // We need to execute the return values cleaning process to simulate the web service server. | |
252 | $categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories); | |
253 | ||
2a7a0216 JM |
254 | $this->assertEquals(1, count($categories)); |
255 | ||
b8b1be15 JL |
256 | // Same query, but forcing a parameters clean. |
257 | $categories = core_course_external::get_categories(array( | |
258 | array('key' => 'id', 'value' => "$category1->id"), | |
259 | array('key' => 'idnumber', 'value' => $category1->idnumber), | |
260 | array('key' => 'name', 'value' => $category1->name . "<br/>"), | |
261 | array('key' => 'visible', 'value' => '1')), 0); | |
262 | $categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories); | |
263 | ||
264 | $this->assertEquals(1, count($categories)); | |
265 | ||
2a7a0216 JM |
266 | // Retrieve categories from parent. |
267 | $categories = core_course_external::get_categories(array( | |
268 | array('key' => 'parent', 'value' => $category3->id)), 1); | |
bdf9f4d4 JL |
269 | $categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories); |
270 | ||
2a7a0216 JM |
271 | $this->assertEquals(2, count($categories)); |
272 | ||
273 | // Retrieve all categories. | |
274 | $categories = core_course_external::get_categories(); | |
fb695f6e JM |
275 | |
276 | // We need to execute the return values cleaning process to simulate the web service server. | |
277 | $categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories); | |
278 | ||
2a7a0216 JM |
279 | $this->assertEquals($DB->count_records('course_categories'), count($categories)); |
280 | ||
281 | // Call without required capability (it will fail cause of the search on idnumber). | |
282 | $this->unassignUserCapability('moodle/category:manage', $context->id, $roleid); | |
52f3e060 | 283 | $this->expectException('moodle_exception'); |
2a7a0216 JM |
284 | $categories = core_course_external::get_categories(array( |
285 | array('key' => 'id', 'value' => $category1->id), | |
286 | array('key' => 'idnumber', 'value' => $category1->idnumber), | |
287 | array('key' => 'visible', 'value' => 1)), 0); | |
288 | } | |
289 | ||
290 | /** | |
291 | * Test update_categories | |
292 | */ | |
293 | public function test_update_categories() { | |
294 | global $DB; | |
295 | ||
296 | $this->resetAfterTest(true); | |
297 | ||
298 | // Set the required capabilities by the external function | |
299 | $contextid = context_system::instance()->id; | |
300 | $roleid = $this->assignUserCapability('moodle/category:manage', $contextid); | |
301 | ||
302 | // Create base categories. | |
303 | $category1data['idnumber'] = 'idnumbercat1'; | |
304 | $category1data['name'] = 'Category 1 for PHPunit test'; | |
305 | $category1data['description'] = 'Category 1 description'; | |
306 | $category1data['descriptionformat'] = FORMAT_MOODLE; | |
307 | $category1 = self::getDataGenerator()->create_category($category1data); | |
308 | $category2 = self::getDataGenerator()->create_category( | |
309 | array('parent' => $category1->id)); | |
310 | $category3 = self::getDataGenerator()->create_category(); | |
311 | $category4 = self::getDataGenerator()->create_category( | |
312 | array('parent' => $category3->id)); | |
313 | $category5 = self::getDataGenerator()->create_category( | |
314 | array('parent' => $category4->id)); | |
315 | ||
316 | // We update all category1 attribut. | |
317 | // Then we move cat4 and cat5 parent: cat3 => cat1 | |
318 | $categories = array( | |
319 | array('id' => $category1->id, | |
320 | 'name' => $category1->name . '_updated', | |
321 | 'idnumber' => $category1->idnumber . '_updated', | |
322 | 'description' => $category1->description . '_updated', | |
323 | 'descriptionformat' => FORMAT_HTML, | |
324 | 'theme' => $category1->theme), | |
325 | array('id' => $category4->id, 'parent' => $category1->id)); | |
326 | ||
327 | core_course_external::update_categories($categories); | |
328 | ||
329 | // Check the values were updated. | |
330 | $dbcategories = $DB->get_records_select('course_categories', | |
331 | 'id IN (' . $category1->id . ',' . $category2->id . ',' . $category2->id | |
332 | . ',' . $category3->id . ',' . $category4->id . ',' . $category5->id .')'); | |
333 | $this->assertEquals($category1->name . '_updated', | |
334 | $dbcategories[$category1->id]->name); | |
335 | $this->assertEquals($category1->idnumber . '_updated', | |
336 | $dbcategories[$category1->id]->idnumber); | |
337 | $this->assertEquals($category1->description . '_updated', | |
338 | $dbcategories[$category1->id]->description); | |
339 | $this->assertEquals(FORMAT_HTML, $dbcategories[$category1->id]->descriptionformat); | |
340 | ||
341 | // Check that category4 and category5 have been properly moved. | |
342 | $this->assertEquals('/' . $category1->id . '/' . $category4->id, | |
343 | $dbcategories[$category4->id]->path); | |
344 | $this->assertEquals('/' . $category1->id . '/' . $category4->id . '/' . $category5->id, | |
345 | $dbcategories[$category5->id]->path); | |
346 | ||
347 | // Call without required capability. | |
348 | $this->unassignUserCapability('moodle/category:manage', $contextid, $roleid); | |
52f3e060 | 349 | $this->expectException('required_capability_exception'); |
2a7a0216 JM |
350 | core_course_external::update_categories($categories); |
351 | } | |
352 | ||
353 | /** | |
354 | * Test create_courses | |
355 | */ | |
356 | public function test_create_courses() { | |
357 | global $DB; | |
358 | ||
359 | $this->resetAfterTest(true); | |
360 | ||
821676f5 JM |
361 | // Enable course completion. |
362 | set_config('enablecompletion', 1); | |
141e7d87 DP |
363 | // Enable course themes. |
364 | set_config('allowcoursethemes', 1); | |
821676f5 | 365 | |
2a7a0216 JM |
366 | // Set the required capabilities by the external function |
367 | $contextid = context_system::instance()->id; | |
368 | $roleid = $this->assignUserCapability('moodle/course:create', $contextid); | |
369 | $this->assignUserCapability('moodle/course:visibility', $contextid, $roleid); | |
370 | ||
371 | $category = self::getDataGenerator()->create_category(); | |
372 | ||
373 | // Create base categories. | |
374 | $course1['fullname'] = 'Test course 1'; | |
375 | $course1['shortname'] = 'Testcourse1'; | |
376 | $course1['categoryid'] = $category->id; | |
377 | $course2['fullname'] = 'Test course 2'; | |
378 | $course2['shortname'] = 'Testcourse2'; | |
379 | $course2['categoryid'] = $category->id; | |
380 | $course2['idnumber'] = 'testcourse2idnumber'; | |
381 | $course2['summary'] = 'Description for course 2'; | |
382 | $course2['summaryformat'] = FORMAT_MOODLE; | |
383 | $course2['format'] = 'weeks'; | |
384 | $course2['showgrades'] = 1; | |
385 | $course2['newsitems'] = 3; | |
4491273b | 386 | $course2['startdate'] = 1420092000; // 01/01/2015 |
2a7a0216 JM |
387 | $course2['numsections'] = 4; |
388 | $course2['maxbytes'] = 100000; | |
389 | $course2['showreports'] = 1; | |
390 | $course2['visible'] = 0; | |
391 | $course2['hiddensections'] = 0; | |
392 | $course2['groupmode'] = 0; | |
393 | $course2['groupmodeforce'] = 0; | |
394 | $course2['defaultgroupingid'] = 0; | |
395 | $course2['enablecompletion'] = 1; | |
2a7a0216 JM |
396 | $course2['completionnotify'] = 1; |
397 | $course2['lang'] = 'en'; | |
644fcbb6 | 398 | $course2['forcetheme'] = 'bootstrapbase'; |
0e984d98 MG |
399 | $course3['fullname'] = 'Test course 3'; |
400 | $course3['shortname'] = 'Testcourse3'; | |
401 | $course3['categoryid'] = $category->id; | |
402 | $course3['format'] = 'topics'; | |
403 | $course3options = array('numsections' => 8, | |
404 | 'hiddensections' => 1, | |
405 | 'coursedisplay' => 1); | |
8d8d4da4 | 406 | $course3['courseformatoptions'] = array(); |
0e984d98 | 407 | foreach ($course3options as $key => $value) { |
8d8d4da4 | 408 | $course3['courseformatoptions'][] = array('name' => $key, 'value' => $value); |
0e984d98 | 409 | } |
821676f5 | 410 | $courses = array($course1, $course2, $course3); |
2a7a0216 JM |
411 | |
412 | $createdcourses = core_course_external::create_courses($courses); | |
413 | ||
fb695f6e JM |
414 | // We need to execute the return values cleaning process to simulate the web service server. |
415 | $createdcourses = external_api::clean_returnvalue(core_course_external::create_courses_returns(), $createdcourses); | |
416 | ||
2a7a0216 | 417 | // Check that right number of courses were created. |
821676f5 | 418 | $this->assertEquals(3, count($createdcourses)); |
2a7a0216 JM |
419 | |
420 | // Check that the courses were correctly created. | |
421 | foreach ($createdcourses as $createdcourse) { | |
850acb35 | 422 | $courseinfo = course_get_format($createdcourse['id'])->get_course(); |
2a7a0216 JM |
423 | |
424 | if ($createdcourse['shortname'] == $course2['shortname']) { | |
850acb35 MG |
425 | $this->assertEquals($courseinfo->fullname, $course2['fullname']); |
426 | $this->assertEquals($courseinfo->shortname, $course2['shortname']); | |
427 | $this->assertEquals($courseinfo->category, $course2['categoryid']); | |
428 | $this->assertEquals($courseinfo->idnumber, $course2['idnumber']); | |
429 | $this->assertEquals($courseinfo->summary, $course2['summary']); | |
430 | $this->assertEquals($courseinfo->summaryformat, $course2['summaryformat']); | |
431 | $this->assertEquals($courseinfo->format, $course2['format']); | |
432 | $this->assertEquals($courseinfo->showgrades, $course2['showgrades']); | |
433 | $this->assertEquals($courseinfo->newsitems, $course2['newsitems']); | |
434 | $this->assertEquals($courseinfo->startdate, $course2['startdate']); | |
435 | $this->assertEquals($courseinfo->numsections, $course2['numsections']); | |
436 | $this->assertEquals($courseinfo->maxbytes, $course2['maxbytes']); | |
437 | $this->assertEquals($courseinfo->showreports, $course2['showreports']); | |
438 | $this->assertEquals($courseinfo->visible, $course2['visible']); | |
439 | $this->assertEquals($courseinfo->hiddensections, $course2['hiddensections']); | |
440 | $this->assertEquals($courseinfo->groupmode, $course2['groupmode']); | |
441 | $this->assertEquals($courseinfo->groupmodeforce, $course2['groupmodeforce']); | |
442 | $this->assertEquals($courseinfo->defaultgroupingid, $course2['defaultgroupingid']); | |
443 | $this->assertEquals($courseinfo->completionnotify, $course2['completionnotify']); | |
444 | $this->assertEquals($courseinfo->lang, $course2['lang']); | |
141e7d87 | 445 | $this->assertEquals($courseinfo->theme, $course2['forcetheme']); |
2a7a0216 | 446 | |
821676f5 JM |
447 | // We enabled completion at the beginning of the test. |
448 | $this->assertEquals($courseinfo->enablecompletion, $course2['enablecompletion']); | |
2a7a0216 JM |
449 | |
450 | } else if ($createdcourse['shortname'] == $course1['shortname']) { | |
451 | $courseconfig = get_config('moodlecourse'); | |
850acb35 MG |
452 | $this->assertEquals($courseinfo->fullname, $course1['fullname']); |
453 | $this->assertEquals($courseinfo->shortname, $course1['shortname']); | |
454 | $this->assertEquals($courseinfo->category, $course1['categoryid']); | |
455 | $this->assertEquals($courseinfo->summaryformat, FORMAT_HTML); | |
456 | $this->assertEquals($courseinfo->format, $courseconfig->format); | |
457 | $this->assertEquals($courseinfo->showgrades, $courseconfig->showgrades); | |
458 | $this->assertEquals($courseinfo->newsitems, $courseconfig->newsitems); | |
459 | $this->assertEquals($courseinfo->maxbytes, $courseconfig->maxbytes); | |
460 | $this->assertEquals($courseinfo->showreports, $courseconfig->showreports); | |
461 | $this->assertEquals($courseinfo->groupmode, $courseconfig->groupmode); | |
462 | $this->assertEquals($courseinfo->groupmodeforce, $courseconfig->groupmodeforce); | |
463 | $this->assertEquals($courseinfo->defaultgroupingid, 0); | |
0e984d98 | 464 | } else if ($createdcourse['shortname'] == $course3['shortname']) { |
850acb35 MG |
465 | $this->assertEquals($courseinfo->fullname, $course3['fullname']); |
466 | $this->assertEquals($courseinfo->shortname, $course3['shortname']); | |
467 | $this->assertEquals($courseinfo->category, $course3['categoryid']); | |
468 | $this->assertEquals($courseinfo->format, $course3['format']); | |
469 | $this->assertEquals($courseinfo->hiddensections, $course3options['hiddensections']); | |
470 | $this->assertEquals($courseinfo->numsections, $course3options['numsections']); | |
471 | $this->assertEquals($courseinfo->coursedisplay, $course3options['coursedisplay']); | |
2a7a0216 JM |
472 | } else { |
473 | throw moodle_exception('Unexpected shortname'); | |
474 | } | |
475 | } | |
476 | ||
477 | // Call without required capability | |
478 | $this->unassignUserCapability('moodle/course:create', $contextid, $roleid); | |
52f3e060 | 479 | $this->expectException('required_capability_exception'); |
2a7a0216 JM |
480 | $createdsubcats = core_course_external::create_courses($courses); |
481 | } | |
482 | ||
483 | /** | |
484 | * Test delete_courses | |
485 | */ | |
486 | public function test_delete_courses() { | |
487 | global $DB, $USER; | |
488 | ||
489 | $this->resetAfterTest(true); | |
490 | ||
491 | // Admin can delete a course. | |
492 | $this->setAdminUser(); | |
493 | // Validate_context() will fail as the email is not set by $this->setAdminUser(). | |
0fe86bbd | 494 | $USER->email = 'emailtopass@example.com'; |
2a7a0216 JM |
495 | |
496 | $course1 = self::getDataGenerator()->create_course(); | |
497 | $course2 = self::getDataGenerator()->create_course(); | |
498 | $course3 = self::getDataGenerator()->create_course(); | |
499 | ||
500 | // Delete courses. | |
70f37963 JH |
501 | $result = core_course_external::delete_courses(array($course1->id, $course2->id)); |
502 | $result = external_api::clean_returnvalue(core_course_external::delete_courses_returns(), $result); | |
503 | // Check for 0 warnings. | |
504 | $this->assertEquals(0, count($result['warnings'])); | |
2a7a0216 JM |
505 | |
506 | // Check $course 1 and 2 are deleted. | |
507 | $notdeletedcount = $DB->count_records_select('course', | |
508 | 'id IN ( ' . $course1->id . ',' . $course2->id . ')'); | |
509 | $this->assertEquals(0, $notdeletedcount); | |
510 | ||
70f37963 JH |
511 | // Try to delete non-existent course. |
512 | $result = core_course_external::delete_courses(array($course1->id)); | |
513 | $result = external_api::clean_returnvalue(core_course_external::delete_courses_returns(), $result); | |
514 | // Check for 1 warnings. | |
515 | $this->assertEquals(1, count($result['warnings'])); | |
516 | ||
517 | // Try to delete Frontpage course. | |
518 | $result = core_course_external::delete_courses(array(0)); | |
519 | $result = external_api::clean_returnvalue(core_course_external::delete_courses_returns(), $result); | |
520 | // Check for 1 warnings. | |
521 | $this->assertEquals(1, count($result['warnings'])); | |
522 | ||
523 | // Fail when the user has access to course (enrolled) but does not have permission or is not admin. | |
524 | $student1 = self::getDataGenerator()->create_user(); | |
525 | $studentrole = $DB->get_record('role', array('shortname' => 'student')); | |
526 | $this->getDataGenerator()->enrol_user($student1->id, | |
527 | $course3->id, | |
528 | $studentrole->id); | |
529 | $this->setUser($student1); | |
530 | $result = core_course_external::delete_courses(array($course3->id)); | |
531 | $result = external_api::clean_returnvalue(core_course_external::delete_courses_returns(), $result); | |
532 | // Check for 1 warnings. | |
533 | $this->assertEquals(1, count($result['warnings'])); | |
534 | ||
2a7a0216 JM |
535 | // Fail when the user is not allow to access the course (enrolled) or is not admin. |
536 | $this->setGuestUser(); | |
52f3e060 | 537 | $this->expectException('require_login_exception'); |
70f37963 JH |
538 | |
539 | $result = core_course_external::delete_courses(array($course3->id)); | |
540 | $result = external_api::clean_returnvalue(core_course_external::delete_courses_returns(), $result); | |
2a7a0216 JM |
541 | } |
542 | ||
543 | /** | |
544 | * Test get_courses | |
545 | */ | |
546 | public function test_get_courses () { | |
547 | global $DB; | |
548 | ||
549 | $this->resetAfterTest(true); | |
550 | ||
7d6c58bc | 551 | $generatedcourses = array(); |
2a7a0216 | 552 | $coursedata['idnumber'] = 'idnumbercourse1'; |
d889b587 JL |
553 | // Adding tags here to check that format_string is applied. |
554 | $coursedata['fullname'] = '<b>Course 1 for PHPunit test</b>'; | |
555 | $coursedata['shortname'] = '<b>Course 1 for PHPunit test</b>'; | |
2a7a0216 JM |
556 | $coursedata['summary'] = 'Course 1 description'; |
557 | $coursedata['summaryformat'] = FORMAT_MOODLE; | |
558 | $course1 = self::getDataGenerator()->create_course($coursedata); | |
7d6c58bc | 559 | $generatedcourses[$course1->id] = $course1; |
2a7a0216 | 560 | $course2 = self::getDataGenerator()->create_course(); |
7d6c58bc | 561 | $generatedcourses[$course2->id] = $course2; |
0e984d98 | 562 | $course3 = self::getDataGenerator()->create_course(array('format' => 'topics')); |
7d6c58bc | 563 | $generatedcourses[$course3->id] = $course3; |
2a7a0216 JM |
564 | |
565 | // Set the required capabilities by the external function. | |
566 | $context = context_system::instance(); | |
567 | $roleid = $this->assignUserCapability('moodle/course:view', $context->id); | |
568 | $this->assignUserCapability('moodle/course:update', | |
569 | context_course::instance($course1->id)->id, $roleid); | |
570 | $this->assignUserCapability('moodle/course:update', | |
571 | context_course::instance($course2->id)->id, $roleid); | |
572 | $this->assignUserCapability('moodle/course:update', | |
573 | context_course::instance($course3->id)->id, $roleid); | |
574 | ||
575 | $courses = core_course_external::get_courses(array('ids' => | |
576 | array($course1->id, $course2->id))); | |
577 | ||
fb695f6e JM |
578 | // We need to execute the return values cleaning process to simulate the web service server. |
579 | $courses = external_api::clean_returnvalue(core_course_external::get_courses_returns(), $courses); | |
580 | ||
2a7a0216 JM |
581 | // Check we retrieve the good total number of categories. |
582 | $this->assertEquals(2, count($courses)); | |
583 | ||
7d6c58bc | 584 | foreach ($courses as $course) { |
d889b587 | 585 | $coursecontext = context_course::instance($course['id']); |
7d6c58bc JM |
586 | $dbcourse = $generatedcourses[$course['id']]; |
587 | $this->assertEquals($course['idnumber'], $dbcourse->idnumber); | |
d889b587 JL |
588 | $this->assertEquals($course['fullname'], external_format_string($dbcourse->fullname, $coursecontext->id)); |
589 | $this->assertEquals($course['displayname'], external_format_string(get_course_display_name_for_list($dbcourse), | |
590 | $coursecontext->id)); | |
46be1d58 MG |
591 | // Summary was converted to the HTML format. |
592 | $this->assertEquals($course['summary'], format_text($dbcourse->summary, FORMAT_MOODLE, array('para' => false))); | |
7d6c58bc | 593 | $this->assertEquals($course['summaryformat'], FORMAT_HTML); |
d889b587 | 594 | $this->assertEquals($course['shortname'], external_format_string($dbcourse->shortname, $coursecontext->id)); |
7d6c58bc JM |
595 | $this->assertEquals($course['categoryid'], $dbcourse->category); |
596 | $this->assertEquals($course['format'], $dbcourse->format); | |
597 | $this->assertEquals($course['showgrades'], $dbcourse->showgrades); | |
598 | $this->assertEquals($course['newsitems'], $dbcourse->newsitems); | |
599 | $this->assertEquals($course['startdate'], $dbcourse->startdate); | |
600 | $this->assertEquals($course['numsections'], $dbcourse->numsections); | |
601 | $this->assertEquals($course['maxbytes'], $dbcourse->maxbytes); | |
602 | $this->assertEquals($course['showreports'], $dbcourse->showreports); | |
603 | $this->assertEquals($course['visible'], $dbcourse->visible); | |
604 | $this->assertEquals($course['hiddensections'], $dbcourse->hiddensections); | |
605 | $this->assertEquals($course['groupmode'], $dbcourse->groupmode); | |
606 | $this->assertEquals($course['groupmodeforce'], $dbcourse->groupmodeforce); | |
607 | $this->assertEquals($course['defaultgroupingid'], $dbcourse->defaultgroupingid); | |
608 | $this->assertEquals($course['completionnotify'], $dbcourse->completionnotify); | |
609 | $this->assertEquals($course['lang'], $dbcourse->lang); | |
610 | $this->assertEquals($course['forcetheme'], $dbcourse->theme); | |
7d6c58bc | 611 | $this->assertEquals($course['enablecompletion'], $dbcourse->enablecompletion); |
0e984d98 | 612 | if ($dbcourse->format === 'topics') { |
8d8d4da4 MG |
613 | $this->assertEquals($course['courseformatoptions'], array( |
614 | array('name' => 'numsections', 'value' => $dbcourse->numsections), | |
615 | array('name' => 'hiddensections', 'value' => $dbcourse->hiddensections), | |
616 | array('name' => 'coursedisplay', 'value' => $dbcourse->coursedisplay), | |
0e984d98 MG |
617 | )); |
618 | } | |
7d6c58bc | 619 | } |
2a7a0216 JM |
620 | |
621 | // Get all courses in the DB | |
622 | $courses = core_course_external::get_courses(array()); | |
fb695f6e JM |
623 | |
624 | // We need to execute the return values cleaning process to simulate the web service server. | |
625 | $courses = external_api::clean_returnvalue(core_course_external::get_courses_returns(), $courses); | |
626 | ||
2a7a0216 JM |
627 | $this->assertEquals($DB->count_records('course'), count($courses)); |
628 | } | |
629 | ||
740c354f JL |
630 | /** |
631 | * Test search_courses | |
632 | */ | |
633 | public function test_search_courses () { | |
634 | ||
74fa9f76 | 635 | global $DB; |
740c354f JL |
636 | |
637 | $this->resetAfterTest(true); | |
638 | $this->setAdminUser(); | |
639 | $generatedcourses = array(); | |
640 | $coursedata1['fullname'] = 'FIRST COURSE'; | |
641 | $course1 = self::getDataGenerator()->create_course($coursedata1); | |
642 | $coursedata2['fullname'] = 'SECOND COURSE'; | |
643 | $course2 = self::getDataGenerator()->create_course($coursedata2); | |
644 | // Search by name. | |
645 | $results = core_course_external::search_courses('search', 'FIRST'); | |
646 | $results = external_api::clean_returnvalue(core_course_external::search_courses_returns(), $results); | |
647 | $this->assertEquals($coursedata1['fullname'], $results['courses'][0]['fullname']); | |
648 | $this->assertCount(1, $results['courses']); | |
649 | ||
650 | // Create the forum. | |
651 | $record = new stdClass(); | |
652 | $record->introformat = FORMAT_HTML; | |
653 | $record->course = $course2->id; | |
654 | // Set Aggregate type = Average of ratings. | |
655 | $forum = self::getDataGenerator()->create_module('forum', $record); | |
656 | ||
657 | // Search by module. | |
658 | $results = core_course_external::search_courses('modulelist', 'forum'); | |
659 | $results = external_api::clean_returnvalue(core_course_external::search_courses_returns(), $results); | |
660 | $this->assertEquals(1, $results['total']); | |
661 | ||
662 | // Enable coursetag option. | |
663 | set_config('block_tags_showcoursetags', true); | |
664 | // Add tag 'TAG-LABEL ON SECOND COURSE' to Course2. | |
74fa9f76 MG |
665 | core_tag_tag::set_item_tags('core', 'course', $course2->id, context_course::instance($course2->id), |
666 | array('TAG-LABEL ON SECOND COURSE')); | |
667 | $taginstance = $DB->get_record('tag_instance', | |
668 | array('itemtype' => 'course', 'itemid' => $course2->id), '*', MUST_EXIST); | |
740c354f JL |
669 | // Search by tagid. |
670 | $results = core_course_external::search_courses('tagid', $taginstance->tagid); | |
671 | $results = external_api::clean_returnvalue(core_course_external::search_courses_returns(), $results); | |
672 | $this->assertEquals($coursedata2['fullname'], $results['courses'][0]['fullname']); | |
673 | ||
674 | // Search by block (use news_items default block). | |
675 | $blockid = $DB->get_field('block', 'id', array('name' => 'news_items')); | |
676 | $results = core_course_external::search_courses('blocklist', $blockid); | |
677 | $results = external_api::clean_returnvalue(core_course_external::search_courses_returns(), $results); | |
678 | $this->assertEquals(2, $results['total']); | |
679 | ||
680 | // Now as a normal user. | |
681 | $user = self::getDataGenerator()->create_user(); | |
935ee1c6 EM |
682 | |
683 | // Add a 3rd, hidden, course we shouldn't see, even when enrolled as student. | |
684 | $coursedata3['fullname'] = 'HIDDEN COURSE'; | |
685 | $coursedata3['visible'] = 0; | |
686 | $course3 = self::getDataGenerator()->create_course($coursedata3); | |
687 | $this->getDataGenerator()->enrol_user($user->id, $course3->id, 'student'); | |
688 | ||
689 | $this->getDataGenerator()->enrol_user($user->id, $course2->id, 'student'); | |
740c354f JL |
690 | $this->setUser($user); |
691 | ||
692 | $results = core_course_external::search_courses('search', 'FIRST'); | |
693 | $results = external_api::clean_returnvalue(core_course_external::search_courses_returns(), $results); | |
694 | $this->assertCount(1, $results['courses']); | |
695 | $this->assertEquals(1, $results['total']); | |
696 | $this->assertEquals($coursedata1['fullname'], $results['courses'][0]['fullname']); | |
697 | ||
935ee1c6 EM |
698 | // Check that we can see both without the limit to enrolled setting. |
699 | $results = core_course_external::search_courses('search', 'COURSE', 0, 0, array(), 0); | |
700 | $results = external_api::clean_returnvalue(core_course_external::search_courses_returns(), $results); | |
701 | $this->assertCount(2, $results['courses']); | |
702 | $this->assertEquals(2, $results['total']); | |
703 | ||
704 | // Check that we only see our enrolled course when limiting. | |
705 | $results = core_course_external::search_courses('search', 'COURSE', 0, 0, array(), 1); | |
706 | $results = external_api::clean_returnvalue(core_course_external::search_courses_returns(), $results); | |
707 | $this->assertCount(1, $results['courses']); | |
708 | $this->assertEquals(1, $results['total']); | |
709 | $this->assertEquals($coursedata2['fullname'], $results['courses'][0]['fullname']); | |
710 | ||
740c354f | 711 | // Search by block (use news_items default block). Should fail (only admins allowed). |
52f3e060 | 712 | $this->expectException('required_capability_exception'); |
740c354f JL |
713 | $results = core_course_external::search_courses('blocklist', $blockid); |
714 | ||
715 | } | |
716 | ||
2a7a0216 | 717 | /** |
8a5346a7 JL |
718 | * Create a course with contents |
719 | * @return array A list with the course object and course modules objects | |
2a7a0216 | 720 | */ |
8a5346a7 | 721 | private function prepare_get_course_contents_test() { |
6a1131e2 | 722 | global $DB; |
2a7a0216 | 723 | $course = self::getDataGenerator()->create_course(); |
487bc1b6 JM |
724 | $forumdescription = 'This is the forum description'; |
725 | $forum = $this->getDataGenerator()->create_module('forum', | |
8a5346a7 | 726 | array('course' => $course->id, 'intro' => $forumdescription), |
487bc1b6 | 727 | array('showdescription' => true)); |
2a7a0216 | 728 | $forumcm = get_coursemodule_from_id('forum', $forum->cmid); |
8a5346a7 | 729 | $data = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id)); |
2a7a0216 | 730 | $datacm = get_coursemodule_from_instance('page', $data->id); |
8a5346a7 | 731 | $page = $this->getDataGenerator()->create_module('page', array('course' => $course->id)); |
2a7a0216 | 732 | $pagecm = get_coursemodule_from_instance('page', $page->id); |
487bc1b6 JM |
733 | $labeldescription = 'This is a very long label to test if more than 50 characters are returned. |
734 | So bla bla bla bla <b>bold bold bold</b> bla bla bla bla.'; | |
735 | $label = $this->getDataGenerator()->create_module('label', array('course' => $course->id, | |
736 | 'intro' => $labeldescription)); | |
737 | $labelcm = get_coursemodule_from_instance('label', $label->id); | |
e13c152e | 738 | $url = $this->getDataGenerator()->create_module('url', array('course' => $course->id, |
8a5346a7 JL |
739 | 'name' => 'URL: % & $ ../', 'section' => 2)); |
740 | $urlcm = get_coursemodule_from_instance('url', $url->id); | |
2a7a0216 JM |
741 | |
742 | // Set the required capabilities by the external function. | |
743 | $context = context_course::instance($course->id); | |
744 | $roleid = $this->assignUserCapability('moodle/course:view', $context->id); | |
745 | $this->assignUserCapability('moodle/course:update', $context->id, $roleid); | |
12306a9f | 746 | $this->assignUserCapability('mod/data:view', $context->id, $roleid); |
2a7a0216 | 747 | |
6a1131e2 JL |
748 | $conditions = array('course' => $course->id, 'section' => 2); |
749 | $DB->set_field('course_sections', 'summary', 'Text with iframe <iframe src="https://moodle.org"></iframe>', $conditions); | |
750 | rebuild_course_cache($course->id, true); | |
751 | ||
8a5346a7 JL |
752 | return array($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm); |
753 | } | |
754 | ||
755 | /** | |
756 | * Test get_course_contents | |
757 | */ | |
758 | public function test_get_course_contents() { | |
759 | $this->resetAfterTest(true); | |
2a7a0216 | 760 | |
8a5346a7 JL |
761 | list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test(); |
762 | ||
763 | $sections = core_course_external::get_course_contents($course->id, array()); | |
fb695f6e | 764 | // We need to execute the return values cleaning process to simulate the web service server. |
487bc1b6 JM |
765 | $sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections); |
766 | ||
767 | // Check that forum and label descriptions are correctly returned. | |
8a5346a7 JL |
768 | $firstsection = array_shift($sections); |
769 | $lastsection = array_pop($sections); | |
770 | ||
487bc1b6 JM |
771 | $modinfo = get_fast_modinfo($course); |
772 | $testexecuted = 0; | |
8a5346a7 | 773 | foreach ($firstsection['modules'] as $module) { |
487bc1b6 JM |
774 | if ($module['id'] == $forumcm->id and $module['modname'] == 'forum') { |
775 | $cm = $modinfo->cms[$forumcm->id]; | |
73ee2fda | 776 | $formattedtext = format_text($cm->content, FORMAT_HTML, |
487bc1b6 JM |
777 | array('noclean' => true, 'para' => false, 'filter' => false)); |
778 | $this->assertEquals($formattedtext, $module['description']); | |
ca4154ce | 779 | $this->assertEquals($forumcm->instance, $module['instance']); |
487bc1b6 JM |
780 | $testexecuted = $testexecuted + 1; |
781 | } else if ($module['id'] == $labelcm->id and $module['modname'] == 'label') { | |
782 | $cm = $modinfo->cms[$labelcm->id]; | |
73ee2fda | 783 | $formattedtext = format_text($cm->content, FORMAT_HTML, |
487bc1b6 JM |
784 | array('noclean' => true, 'para' => false, 'filter' => false)); |
785 | $this->assertEquals($formattedtext, $module['description']); | |
ca4154ce | 786 | $this->assertEquals($labelcm->instance, $module['instance']); |
487bc1b6 JM |
787 | $testexecuted = $testexecuted + 1; |
788 | } | |
789 | } | |
790 | $this->assertEquals(2, $testexecuted); | |
9df9f1f0 | 791 | $this->assertEquals(0, $firstsection['section']); |
fb695f6e | 792 | |
8a5346a7 JL |
793 | // Check that the only return section has the 5 created modules. |
794 | $this->assertCount(4, $firstsection['modules']); | |
795 | $this->assertCount(1, $lastsection['modules']); | |
9df9f1f0 | 796 | $this->assertEquals(2, $lastsection['section']); |
6a1131e2 JL |
797 | $this->assertContains('<iframe', $lastsection['summary']); |
798 | $this->assertContains('</iframe>', $lastsection['summary']); | |
8a5346a7 JL |
799 | |
800 | try { | |
801 | $sections = core_course_external::get_course_contents($course->id, | |
802 | array(array("name" => "invalid", "value" => 1))); | |
803 | $this->fail('Exception expected due to invalid option.'); | |
804 | } catch (moodle_exception $e) { | |
805 | $this->assertEquals('errorinvalidparam', $e->errorcode); | |
806 | } | |
807 | } | |
808 | ||
809 | ||
810 | /** | |
811 | * Test get_course_contents excluding modules | |
812 | */ | |
813 | public function test_get_course_contents_excluding_modules() { | |
814 | $this->resetAfterTest(true); | |
815 | ||
816 | list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test(); | |
817 | ||
818 | // Test exclude modules. | |
819 | $sections = core_course_external::get_course_contents($course->id, array(array("name" => "excludemodules", "value" => 1))); | |
820 | ||
821 | // We need to execute the return values cleaning process to simulate the web service server. | |
822 | $sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections); | |
823 | ||
824 | $firstsection = array_shift($sections); | |
825 | $lastsection = array_pop($sections); | |
826 | ||
827 | $this->assertEmpty($firstsection['modules']); | |
828 | $this->assertEmpty($lastsection['modules']); | |
829 | } | |
830 | ||
831 | /** | |
832 | * Test get_course_contents excluding contents | |
833 | */ | |
834 | public function test_get_course_contents_excluding_contents() { | |
835 | $this->resetAfterTest(true); | |
836 | ||
837 | list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test(); | |
838 | ||
839 | // Test exclude modules. | |
840 | $sections = core_course_external::get_course_contents($course->id, array(array("name" => "excludecontents", "value" => 1))); | |
841 | ||
842 | // We need to execute the return values cleaning process to simulate the web service server. | |
843 | $sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections); | |
844 | ||
845 | foreach ($sections as $section) { | |
846 | foreach ($section['modules'] as $module) { | |
847 | // Only resources return contents. | |
848 | if (isset($module['contents'])) { | |
849 | $this->assertEmpty($module['contents']); | |
850 | } | |
851 | } | |
852 | } | |
853 | } | |
854 | ||
855 | /** | |
856 | * Test get_course_contents filtering by section number | |
857 | */ | |
858 | public function test_get_course_contents_section_number() { | |
859 | $this->resetAfterTest(true); | |
860 | ||
861 | list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test(); | |
862 | ||
863 | // Test exclude modules. | |
864 | $sections = core_course_external::get_course_contents($course->id, array(array("name" => "sectionnumber", "value" => 0))); | |
865 | ||
866 | // We need to execute the return values cleaning process to simulate the web service server. | |
867 | $sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections); | |
868 | ||
869 | $this->assertCount(1, $sections); | |
870 | $this->assertCount(4, $sections[0]['modules']); | |
871 | } | |
872 | ||
873 | /** | |
874 | * Test get_course_contents filtering by cmid | |
875 | */ | |
876 | public function test_get_course_contents_cmid() { | |
877 | $this->resetAfterTest(true); | |
878 | ||
879 | list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test(); | |
880 | ||
881 | // Test exclude modules. | |
882 | $sections = core_course_external::get_course_contents($course->id, array(array("name" => "cmid", "value" => $forumcm->id))); | |
883 | ||
884 | // We need to execute the return values cleaning process to simulate the web service server. | |
885 | $sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections); | |
886 | ||
887 | $this->assertCount(2, $sections); | |
888 | $this->assertCount(1, $sections[0]['modules']); | |
889 | $this->assertEquals($forumcm->id, $sections[0]['modules'][0]["id"]); | |
890 | } | |
891 | ||
892 | ||
893 | /** | |
894 | * Test get_course_contents filtering by cmid and section | |
895 | */ | |
896 | public function test_get_course_contents_section_cmid() { | |
897 | $this->resetAfterTest(true); | |
898 | ||
899 | list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test(); | |
900 | ||
901 | // Test exclude modules. | |
902 | $sections = core_course_external::get_course_contents($course->id, array( | |
903 | array("name" => "cmid", "value" => $forumcm->id), | |
904 | array("name" => "sectionnumber", "value" => 0) | |
905 | )); | |
906 | ||
907 | // We need to execute the return values cleaning process to simulate the web service server. | |
908 | $sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections); | |
909 | ||
910 | $this->assertCount(1, $sections); | |
911 | $this->assertCount(1, $sections[0]['modules']); | |
912 | $this->assertEquals($forumcm->id, $sections[0]['modules'][0]["id"]); | |
913 | } | |
914 | ||
915 | /** | |
916 | * Test get_course_contents filtering by modname | |
917 | */ | |
918 | public function test_get_course_contents_modname() { | |
919 | $this->resetAfterTest(true); | |
920 | ||
921 | list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test(); | |
922 | ||
923 | // Test exclude modules. | |
924 | $sections = core_course_external::get_course_contents($course->id, array(array("name" => "modname", "value" => "forum"))); | |
925 | ||
926 | // We need to execute the return values cleaning process to simulate the web service server. | |
927 | $sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections); | |
928 | ||
929 | $this->assertCount(2, $sections); | |
930 | $this->assertCount(1, $sections[0]['modules']); | |
931 | $this->assertEquals($forumcm->id, $sections[0]['modules'][0]["id"]); | |
932 | } | |
933 | ||
934 | /** | |
935 | * Test get_course_contents filtering by modname | |
936 | */ | |
937 | public function test_get_course_contents_modid() { | |
938 | $this->resetAfterTest(true); | |
939 | ||
940 | list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test(); | |
941 | ||
942 | // Test exclude modules. | |
943 | $sections = core_course_external::get_course_contents($course->id, array( | |
944 | array("name" => "modname", "value" => "page"), | |
945 | array("name" => "modid", "value" => $pagecm->instance), | |
946 | )); | |
947 | ||
948 | // We need to execute the return values cleaning process to simulate the web service server. | |
949 | $sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections); | |
950 | ||
951 | $this->assertCount(2, $sections); | |
952 | $this->assertCount(1, $sections[0]['modules']); | |
953 | $this->assertEquals("page", $sections[0]['modules'][0]["modname"]); | |
954 | $this->assertEquals($pagecm->instance, $sections[0]['modules'][0]["instance"]); | |
2a7a0216 JM |
955 | } |
956 | ||
957 | /** | |
958 | * Test duplicate_course | |
959 | */ | |
960 | public function test_duplicate_course() { | |
961 | $this->resetAfterTest(true); | |
962 | ||
963 | // Create one course with three modules. | |
964 | $course = self::getDataGenerator()->create_course(); | |
965 | $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); | |
966 | $forumcm = get_coursemodule_from_id('forum', $forum->cmid); | |
967 | $forumcontext = context_module::instance($forum->cmid); | |
968 | $data = $this->getDataGenerator()->create_module('data', array('assessed'=>1, 'scale'=>100, 'course'=>$course->id)); | |
969 | $datacontext = context_module::instance($data->cmid); | |
970 | $datacm = get_coursemodule_from_instance('page', $data->id); | |
971 | $page = $this->getDataGenerator()->create_module('page', array('course'=>$course->id)); | |
972 | $pagecontext = context_module::instance($page->cmid); | |
973 | $pagecm = get_coursemodule_from_instance('page', $page->id); | |
974 | ||
975 | // Set the required capabilities by the external function. | |
976 | $coursecontext = context_course::instance($course->id); | |
977 | $categorycontext = context_coursecat::instance($course->category); | |
978 | $roleid = $this->assignUserCapability('moodle/course:create', $categorycontext->id); | |
979 | $this->assignUserCapability('moodle/course:view', $categorycontext->id, $roleid); | |
980 | $this->assignUserCapability('moodle/restore:restorecourse', $categorycontext->id, $roleid); | |
981 | $this->assignUserCapability('moodle/backup:backupcourse', $coursecontext->id, $roleid); | |
982 | $this->assignUserCapability('moodle/backup:configure', $coursecontext->id, $roleid); | |
983 | // Optional capabilities to copy user data. | |
984 | $this->assignUserCapability('moodle/backup:userinfo', $coursecontext->id, $roleid); | |
985 | $this->assignUserCapability('moodle/restore:userinfo', $categorycontext->id, $roleid); | |
986 | ||
987 | $newcourse['fullname'] = 'Course duplicate'; | |
988 | $newcourse['shortname'] = 'courseduplicate'; | |
989 | $newcourse['categoryid'] = $course->category; | |
990 | $newcourse['visible'] = true; | |
991 | $newcourse['options'][] = array('name' => 'users', 'value' => true); | |
992 | ||
993 | $duplicate = core_course_external::duplicate_course($course->id, $newcourse['fullname'], | |
994 | $newcourse['shortname'], $newcourse['categoryid'], $newcourse['visible'], $newcourse['options']); | |
995 | ||
fb695f6e JM |
996 | // We need to execute the return values cleaning process to simulate the web service server. |
997 | $duplicate = external_api::clean_returnvalue(core_course_external::duplicate_course_returns(), $duplicate); | |
998 | ||
2a7a0216 JM |
999 | // Check that the course has been duplicated. |
1000 | $this->assertEquals($newcourse['shortname'], $duplicate['shortname']); | |
1001 | } | |
791723c3 RT |
1002 | |
1003 | /** | |
1004 | * Test update_courses | |
1005 | */ | |
1006 | public function test_update_courses() { | |
a182f88f EL |
1007 | global $DB, $CFG, $USER, $COURSE; |
1008 | ||
1009 | // Get current $COURSE to be able to restore it later (defaults to $SITE). We need this | |
1010 | // trick because we are both updating and getting (for testing) course information | |
1011 | // in the same request and core_course_external::update_courses() | |
1012 | // is overwriting $COURSE all over the time with OLD values, so later | |
1013 | // use of get_course() fetches those OLD values instead of the updated ones. | |
1014 | // See MDL-39723 for more info. | |
1015 | $origcourse = clone($COURSE); | |
791723c3 RT |
1016 | |
1017 | $this->resetAfterTest(true); | |
1018 | ||
1019 | // Set the required capabilities by the external function. | |
1020 | $contextid = context_system::instance()->id; | |
1021 | $roleid = $this->assignUserCapability('moodle/course:update', $contextid); | |
1022 | $this->assignUserCapability('moodle/course:changecategory', $contextid, $roleid); | |
1023 | $this->assignUserCapability('moodle/course:changefullname', $contextid, $roleid); | |
1024 | $this->assignUserCapability('moodle/course:changeshortname', $contextid, $roleid); | |
1025 | $this->assignUserCapability('moodle/course:changeidnumber', $contextid, $roleid); | |
1026 | $this->assignUserCapability('moodle/course:changesummary', $contextid, $roleid); | |
1027 | $this->assignUserCapability('moodle/course:visibility', $contextid, $roleid); | |
1028 | $this->assignUserCapability('moodle/course:viewhiddencourses', $contextid, $roleid); | |
1029 | ||
1030 | // Create category and course. | |
1031 | $category1 = self::getDataGenerator()->create_category(); | |
1032 | $category2 = self::getDataGenerator()->create_category(); | |
1033 | $originalcourse1 = self::getDataGenerator()->create_course(); | |
1034 | self::getDataGenerator()->enrol_user($USER->id, $originalcourse1->id, $roleid); | |
1035 | $originalcourse2 = self::getDataGenerator()->create_course(); | |
1036 | self::getDataGenerator()->enrol_user($USER->id, $originalcourse2->id, $roleid); | |
1037 | ||
1038 | // Course values to be updated. | |
1039 | $course1['id'] = $originalcourse1->id; | |
1040 | $course1['fullname'] = 'Updated test course 1'; | |
1041 | $course1['shortname'] = 'Udestedtestcourse1'; | |
1042 | $course1['categoryid'] = $category1->id; | |
1043 | $course2['id'] = $originalcourse2->id; | |
1044 | $course2['fullname'] = 'Updated test course 2'; | |
1045 | $course2['shortname'] = 'Updestedtestcourse2'; | |
1046 | $course2['categoryid'] = $category2->id; | |
1047 | $course2['idnumber'] = 'Updatedidnumber2'; | |
1048 | $course2['summary'] = 'Updaated description for course 2'; | |
1049 | $course2['summaryformat'] = FORMAT_HTML; | |
1050 | $course2['format'] = 'topics'; | |
1051 | $course2['showgrades'] = 1; | |
1052 | $course2['newsitems'] = 3; | |
1053 | $course2['startdate'] = 1420092000; // 01/01/2015. | |
1054 | $course2['numsections'] = 4; | |
1055 | $course2['maxbytes'] = 100000; | |
1056 | $course2['showreports'] = 1; | |
1057 | $course2['visible'] = 0; | |
1058 | $course2['hiddensections'] = 0; | |
1059 | $course2['groupmode'] = 0; | |
1060 | $course2['groupmodeforce'] = 0; | |
1061 | $course2['defaultgroupingid'] = 0; | |
1062 | $course2['enablecompletion'] = 1; | |
1063 | $course2['lang'] = 'en'; | |
644fcbb6 | 1064 | $course2['forcetheme'] = 'bootstrapbase'; |
791723c3 RT |
1065 | $courses = array($course1, $course2); |
1066 | ||
1067 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1068 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1069 | $updatedcoursewarnings); | |
a182f88f | 1070 | $COURSE = $origcourse; // Restore $COURSE. Instead of using the OLD one set by the previous line. |
791723c3 RT |
1071 | |
1072 | // Check that right number of courses were created. | |
1073 | $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); | |
1074 | ||
1075 | // Check that the courses were correctly created. | |
1076 | foreach ($courses as $course) { | |
1077 | $courseinfo = course_get_format($course['id'])->get_course(); | |
1078 | if ($course['id'] == $course2['id']) { | |
1079 | $this->assertEquals($course2['fullname'], $courseinfo->fullname); | |
1080 | $this->assertEquals($course2['shortname'], $courseinfo->shortname); | |
1081 | $this->assertEquals($course2['categoryid'], $courseinfo->category); | |
1082 | $this->assertEquals($course2['idnumber'], $courseinfo->idnumber); | |
1083 | $this->assertEquals($course2['summary'], $courseinfo->summary); | |
1084 | $this->assertEquals($course2['summaryformat'], $courseinfo->summaryformat); | |
1085 | $this->assertEquals($course2['format'], $courseinfo->format); | |
1086 | $this->assertEquals($course2['showgrades'], $courseinfo->showgrades); | |
1087 | $this->assertEquals($course2['newsitems'], $courseinfo->newsitems); | |
1088 | $this->assertEquals($course2['startdate'], $courseinfo->startdate); | |
1089 | $this->assertEquals($course2['numsections'], $courseinfo->numsections); | |
1090 | $this->assertEquals($course2['maxbytes'], $courseinfo->maxbytes); | |
1091 | $this->assertEquals($course2['showreports'], $courseinfo->showreports); | |
1092 | $this->assertEquals($course2['visible'], $courseinfo->visible); | |
1093 | $this->assertEquals($course2['hiddensections'], $courseinfo->hiddensections); | |
1094 | $this->assertEquals($course2['groupmode'], $courseinfo->groupmode); | |
1095 | $this->assertEquals($course2['groupmodeforce'], $courseinfo->groupmodeforce); | |
1096 | $this->assertEquals($course2['defaultgroupingid'], $courseinfo->defaultgroupingid); | |
1097 | $this->assertEquals($course2['lang'], $courseinfo->lang); | |
1098 | ||
1099 | if (!empty($CFG->allowcoursethemes)) { | |
1100 | $this->assertEquals($course2['forcetheme'], $courseinfo->theme); | |
1101 | } | |
1102 | ||
8be9cffb | 1103 | $this->assertEquals($course2['enablecompletion'], $courseinfo->enablecompletion); |
791723c3 RT |
1104 | } else if ($course['id'] == $course1['id']) { |
1105 | $this->assertEquals($course1['fullname'], $courseinfo->fullname); | |
1106 | $this->assertEquals($course1['shortname'], $courseinfo->shortname); | |
1107 | $this->assertEquals($course1['categoryid'], $courseinfo->category); | |
1108 | $this->assertEquals(FORMAT_MOODLE, $courseinfo->summaryformat); | |
1109 | $this->assertEquals('topics', $courseinfo->format); | |
1110 | $this->assertEquals(5, $courseinfo->numsections); | |
1111 | $this->assertEquals(0, $courseinfo->newsitems); | |
1112 | $this->assertEquals(FORMAT_MOODLE, $courseinfo->summaryformat); | |
1113 | } else { | |
1114 | throw moodle_exception('Unexpected shortname'); | |
1115 | } | |
1116 | } | |
1117 | ||
1118 | $courses = array($course1); | |
1119 | // Try update course without update capability. | |
1120 | $user = self::getDataGenerator()->create_user(); | |
1121 | $this->setUser($user); | |
1122 | $this->unassignUserCapability('moodle/course:update', $contextid, $roleid); | |
1123 | self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); | |
1124 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1125 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1126 | $updatedcoursewarnings); | |
791723c3 RT |
1127 | $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); |
1128 | ||
1129 | // Try update course category without capability. | |
1130 | $this->assignUserCapability('moodle/course:update', $contextid, $roleid); | |
1131 | $this->unassignUserCapability('moodle/course:changecategory', $contextid, $roleid); | |
1132 | $user = self::getDataGenerator()->create_user(); | |
1133 | $this->setUser($user); | |
1134 | self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); | |
1135 | $course1['categoryid'] = $category2->id; | |
1136 | $courses = array($course1); | |
1137 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1138 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1139 | $updatedcoursewarnings); | |
791723c3 RT |
1140 | $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); |
1141 | ||
1142 | // Try update course fullname without capability. | |
1143 | $this->assignUserCapability('moodle/course:changecategory', $contextid, $roleid); | |
1144 | $this->unassignUserCapability('moodle/course:changefullname', $contextid, $roleid); | |
1145 | $user = self::getDataGenerator()->create_user(); | |
1146 | $this->setUser($user); | |
1147 | self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); | |
1148 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1149 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1150 | $updatedcoursewarnings); | |
791723c3 RT |
1151 | $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); |
1152 | $course1['fullname'] = 'Testing fullname without permission'; | |
1153 | $courses = array($course1); | |
1154 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1155 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1156 | $updatedcoursewarnings); | |
791723c3 RT |
1157 | $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); |
1158 | ||
1159 | // Try update course shortname without capability. | |
1160 | $this->assignUserCapability('moodle/course:changefullname', $contextid, $roleid); | |
1161 | $this->unassignUserCapability('moodle/course:changeshortname', $contextid, $roleid); | |
1162 | $user = self::getDataGenerator()->create_user(); | |
1163 | $this->setUser($user); | |
1164 | self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); | |
1165 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1166 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1167 | $updatedcoursewarnings); | |
791723c3 RT |
1168 | $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); |
1169 | $course1['shortname'] = 'Testing shortname without permission'; | |
1170 | $courses = array($course1); | |
1171 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1172 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1173 | $updatedcoursewarnings); | |
791723c3 RT |
1174 | $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); |
1175 | ||
1176 | // Try update course idnumber without capability. | |
1177 | $this->assignUserCapability('moodle/course:changeshortname', $contextid, $roleid); | |
1178 | $this->unassignUserCapability('moodle/course:changeidnumber', $contextid, $roleid); | |
1179 | $user = self::getDataGenerator()->create_user(); | |
1180 | $this->setUser($user); | |
1181 | self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); | |
1182 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1183 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1184 | $updatedcoursewarnings); | |
791723c3 RT |
1185 | $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); |
1186 | $course1['idnumber'] = 'NEWIDNUMBER'; | |
1187 | $courses = array($course1); | |
1188 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1189 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1190 | $updatedcoursewarnings); | |
791723c3 RT |
1191 | $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); |
1192 | ||
1193 | // Try update course summary without capability. | |
1194 | $this->assignUserCapability('moodle/course:changeidnumber', $contextid, $roleid); | |
1195 | $this->unassignUserCapability('moodle/course:changesummary', $contextid, $roleid); | |
1196 | $user = self::getDataGenerator()->create_user(); | |
1197 | $this->setUser($user); | |
1198 | self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); | |
1199 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1200 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1201 | $updatedcoursewarnings); | |
791723c3 RT |
1202 | $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); |
1203 | $course1['summary'] = 'New summary'; | |
1204 | $courses = array($course1); | |
1205 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1206 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1207 | $updatedcoursewarnings); | |
791723c3 RT |
1208 | $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); |
1209 | ||
1210 | // Try update course with invalid summary format. | |
1211 | $this->assignUserCapability('moodle/course:changesummary', $contextid, $roleid); | |
1212 | $user = self::getDataGenerator()->create_user(); | |
1213 | $this->setUser($user); | |
1214 | self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); | |
1215 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1216 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1217 | $updatedcoursewarnings); | |
791723c3 RT |
1218 | $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); |
1219 | $course1['summaryformat'] = 10; | |
1220 | $courses = array($course1); | |
1221 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1222 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1223 | $updatedcoursewarnings); | |
791723c3 RT |
1224 | $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); |
1225 | ||
1226 | // Try update course visibility without capability. | |
1227 | $this->unassignUserCapability('moodle/course:visibility', $contextid, $roleid); | |
1228 | $user = self::getDataGenerator()->create_user(); | |
1229 | $this->setUser($user); | |
1230 | self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); | |
1231 | $course1['summaryformat'] = FORMAT_MOODLE; | |
1232 | $courses = array($course1); | |
1233 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1234 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1235 | $updatedcoursewarnings); | |
791723c3 RT |
1236 | $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); |
1237 | $course1['visible'] = 0; | |
1238 | $courses = array($course1); | |
1239 | $updatedcoursewarnings = core_course_external::update_courses($courses); | |
bdf9f4d4 JL |
1240 | $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(), |
1241 | $updatedcoursewarnings); | |
791723c3 RT |
1242 | $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); |
1243 | } | |
05fc7ccc | 1244 | |
79949c1b MN |
1245 | /** |
1246 | * Test delete course_module. | |
1247 | */ | |
1248 | public function test_delete_modules() { | |
1249 | global $DB; | |
1250 | ||
1251 | // Ensure we reset the data after this test. | |
1252 | $this->resetAfterTest(true); | |
1253 | ||
1254 | // Create a user. | |
1255 | $user = self::getDataGenerator()->create_user(); | |
1256 | ||
1257 | // Set the tests to run as the user. | |
1258 | self::setUser($user); | |
1259 | ||
1260 | // Create a course to add the modules. | |
1261 | $course = self::getDataGenerator()->create_course(); | |
1262 | ||
1263 | // Create two test modules. | |
1264 | $record = new stdClass(); | |
1265 | $record->course = $course->id; | |
1266 | $module1 = self::getDataGenerator()->create_module('forum', $record); | |
40cb4879 | 1267 | $module2 = self::getDataGenerator()->create_module('assign', $record); |
79949c1b MN |
1268 | |
1269 | // Check the forum was correctly created. | |
1270 | $this->assertEquals(1, $DB->count_records('forum', array('id' => $module1->id))); | |
1271 | ||
1272 | // Check the assignment was correctly created. | |
40cb4879 | 1273 | $this->assertEquals(1, $DB->count_records('assign', array('id' => $module2->id))); |
79949c1b MN |
1274 | |
1275 | // Check data exists in the course modules table. | |
1276 | $this->assertEquals(2, $DB->count_records_select('course_modules', 'id = :module1 OR id = :module2', | |
1277 | array('module1' => $module1->cmid, 'module2' => $module2->cmid))); | |
1278 | ||
1279 | // Enrol the user in the course. | |
1280 | $enrol = enrol_get_plugin('manual'); | |
1281 | $enrolinstances = enrol_get_instances($course->id, true); | |
1282 | foreach ($enrolinstances as $courseenrolinstance) { | |
1283 | if ($courseenrolinstance->enrol == "manual") { | |
1284 | $instance = $courseenrolinstance; | |
1285 | break; | |
1286 | } | |
1287 | } | |
1288 | $enrol->enrol_user($instance, $user->id); | |
1289 | ||
1290 | // Assign capabilities to delete module 1. | |
1291 | $modcontext = context_module::instance($module1->cmid); | |
1292 | $this->assignUserCapability('moodle/course:manageactivities', $modcontext->id); | |
1293 | ||
1294 | // Assign capabilities to delete module 2. | |
1295 | $modcontext = context_module::instance($module2->cmid); | |
1296 | $newrole = create_role('Role 2', 'role2', 'Role 2 description'); | |
1297 | $this->assignUserCapability('moodle/course:manageactivities', $modcontext->id, $newrole); | |
1298 | ||
1299 | // Deleting these module instances. | |
1300 | core_course_external::delete_modules(array($module1->cmid, $module2->cmid)); | |
1301 | ||
1302 | // Check the forum was deleted. | |
1303 | $this->assertEquals(0, $DB->count_records('forum', array('id' => $module1->id))); | |
1304 | ||
1305 | // Check the assignment was deleted. | |
40cb4879 | 1306 | $this->assertEquals(0, $DB->count_records('assign', array('id' => $module2->id))); |
79949c1b MN |
1307 | |
1308 | // Check we retrieve no data in the course modules table. | |
1309 | $this->assertEquals(0, $DB->count_records_select('course_modules', 'id = :module1 OR id = :module2', | |
1310 | array('module1' => $module1->cmid, 'module2' => $module2->cmid))); | |
1311 | ||
1312 | // Call with non-existent course module id and ensure exception thrown. | |
1313 | try { | |
1314 | core_course_external::delete_modules(array('1337')); | |
1315 | $this->fail('Exception expected due to missing course module.'); | |
1316 | } catch (dml_missing_record_exception $e) { | |
affdc3b7 | 1317 | $this->assertEquals('invalidcoursemodule', $e->errorcode); |
79949c1b MN |
1318 | } |
1319 | ||
1320 | // Create two modules. | |
1321 | $module1 = self::getDataGenerator()->create_module('forum', $record); | |
40cb4879 | 1322 | $module2 = self::getDataGenerator()->create_module('assign', $record); |
79949c1b MN |
1323 | |
1324 | // Since these modules were recreated the user will not have capabilities | |
1325 | // to delete them, ensure exception is thrown if they try. | |
1326 | try { | |
1327 | core_course_external::delete_modules(array($module1->cmid, $module2->cmid)); | |
1328 | $this->fail('Exception expected due to missing capability.'); | |
1329 | } catch (moodle_exception $e) { | |
1330 | $this->assertEquals('nopermissions', $e->errorcode); | |
1331 | } | |
1332 | ||
1333 | // Unenrol user from the course. | |
1334 | $enrol->unenrol_user($instance, $user->id); | |
1335 | ||
1336 | // Try and delete modules from the course the user was unenrolled in, make sure exception thrown. | |
1337 | try { | |
1338 | core_course_external::delete_modules(array($module1->cmid, $module2->cmid)); | |
1339 | $this->fail('Exception expected due to being unenrolled from the course.'); | |
1340 | } catch (moodle_exception $e) { | |
1341 | $this->assertEquals('requireloginerror', $e->errorcode); | |
1342 | } | |
1343 | } | |
fce10644 DP |
1344 | |
1345 | /** | |
1346 | * Test import_course into an empty course | |
1347 | */ | |
1348 | public function test_import_course_empty() { | |
1349 | global $USER; | |
1350 | ||
1351 | $this->resetAfterTest(true); | |
1352 | ||
1353 | $course1 = self::getDataGenerator()->create_course(); | |
1354 | $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course1->id, 'name' => 'Forum test')); | |
1355 | $page = $this->getDataGenerator()->create_module('page', array('course' => $course1->id, 'name' => 'Page test')); | |
1356 | ||
1357 | $course2 = self::getDataGenerator()->create_course(); | |
1358 | ||
1359 | $course1cms = get_fast_modinfo($course1->id)->get_cms(); | |
1360 | $course2cms = get_fast_modinfo($course2->id)->get_cms(); | |
1361 | ||
1362 | // Verify the state of the courses before we do the import. | |
1363 | $this->assertCount(2, $course1cms); | |
1364 | $this->assertEmpty($course2cms); | |
1365 | ||
1366 | // Setup the user to run the operation (ugly hack because validate_context() will | |
1367 | // fail as the email is not set by $this->setAdminUser()). | |
1368 | $this->setAdminUser(); | |
0fe86bbd | 1369 | $USER->email = 'emailtopass@example.com'; |
fce10644 DP |
1370 | |
1371 | // Import from course1 to course2. | |
1372 | core_course_external::import_course($course1->id, $course2->id, 0); | |
1373 | ||
1374 | // Verify that now we have two modules in both courses. | |
1375 | $course1cms = get_fast_modinfo($course1->id)->get_cms(); | |
1376 | $course2cms = get_fast_modinfo($course2->id)->get_cms(); | |
1377 | $this->assertCount(2, $course1cms); | |
1378 | $this->assertCount(2, $course2cms); | |
1379 | ||
1380 | // Verify that the names transfered across correctly. | |
1381 | foreach ($course2cms as $cm) { | |
1382 | if ($cm->modname === 'page') { | |
1383 | $this->assertEquals($cm->name, $page->name); | |
1384 | } else if ($cm->modname === 'forum') { | |
1385 | $this->assertEquals($cm->name, $forum->name); | |
1386 | } else { | |
1387 | $this->fail('Unknown CM found.'); | |
1388 | } | |
1389 | } | |
fce10644 DP |
1390 | } |
1391 | ||
1392 | /** | |
1393 | * Test import_course into an filled course | |
1394 | */ | |
1395 | public function test_import_course_filled() { | |
1396 | global $USER; | |
1397 | ||
1398 | $this->resetAfterTest(true); | |
1399 | ||
1400 | // Add forum and page to course1. | |
1401 | $course1 = self::getDataGenerator()->create_course(); | |
1402 | $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course1->id, 'name' => 'Forum test')); | |
1403 | $page = $this->getDataGenerator()->create_module('page', array('course'=>$course1->id, 'name' => 'Page test')); | |
1404 | ||
1405 | // Add quiz to course 2. | |
1406 | $course2 = self::getDataGenerator()->create_course(); | |
1407 | $quiz = $this->getDataGenerator()->create_module('quiz', array('course'=>$course2->id, 'name' => 'Page test')); | |
1408 | ||
1409 | $course1cms = get_fast_modinfo($course1->id)->get_cms(); | |
1410 | $course2cms = get_fast_modinfo($course2->id)->get_cms(); | |
1411 | ||
1412 | // Verify the state of the courses before we do the import. | |
1413 | $this->assertCount(2, $course1cms); | |
1414 | $this->assertCount(1, $course2cms); | |
1415 | ||
1416 | // Setup the user to run the operation (ugly hack because validate_context() will | |
1417 | // fail as the email is not set by $this->setAdminUser()). | |
1418 | $this->setAdminUser(); | |
0fe86bbd | 1419 | $USER->email = 'emailtopass@example.com'; |
fce10644 DP |
1420 | |
1421 | // Import from course1 to course2 without deleting content. | |
1422 | core_course_external::import_course($course1->id, $course2->id, 0); | |
1423 | ||
1424 | $course2cms = get_fast_modinfo($course2->id)->get_cms(); | |
1425 | ||
1426 | // Verify that now we have three modules in course2. | |
1427 | $this->assertCount(3, $course2cms); | |
1428 | ||
1429 | // Verify that the names transfered across correctly. | |
1430 | foreach ($course2cms as $cm) { | |
1431 | if ($cm->modname === 'page') { | |
1432 | $this->assertEquals($cm->name, $page->name); | |
1433 | } else if ($cm->modname === 'forum') { | |
1434 | $this->assertEquals($cm->name, $forum->name); | |
1435 | } else if ($cm->modname === 'quiz') { | |
1436 | $this->assertEquals($cm->name, $quiz->name); | |
1437 | } else { | |
1438 | $this->fail('Unknown CM found.'); | |
1439 | } | |
1440 | } | |
fce10644 DP |
1441 | } |
1442 | ||
1443 | /** | |
1444 | * Test import_course with only blocks set to backup | |
1445 | */ | |
1446 | public function test_import_course_blocksonly() { | |
1447 | global $USER, $DB; | |
1448 | ||
1449 | $this->resetAfterTest(true); | |
1450 | ||
1451 | // Add forum and page to course1. | |
1452 | $course1 = self::getDataGenerator()->create_course(); | |
1453 | $course1ctx = context_course::instance($course1->id); | |
1454 | $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course1->id, 'name' => 'Forum test')); | |
1455 | $block = $this->getDataGenerator()->create_block('online_users', array('parentcontextid' => $course1ctx->id)); | |
1456 | ||
1457 | $course2 = self::getDataGenerator()->create_course(); | |
1458 | $course2ctx = context_course::instance($course2->id); | |
1459 | $initialblockcount = $DB->count_records('block_instances', array('parentcontextid' => $course2ctx->id)); | |
1460 | $initialcmcount = count(get_fast_modinfo($course2->id)->get_cms()); | |
1461 | ||
1462 | // Setup the user to run the operation (ugly hack because validate_context() will | |
1463 | // fail as the email is not set by $this->setAdminUser()). | |
1464 | $this->setAdminUser(); | |
0fe86bbd | 1465 | $USER->email = 'emailtopass@example.com'; |
fce10644 DP |
1466 | |
1467 | // Import from course1 to course2 without deleting content, but excluding | |
1468 | // activities. | |
1469 | $options = array( | |
1470 | array('name' => 'activities', 'value' => 0), | |
1471 | array('name' => 'blocks', 'value' => 1), | |
1472 | array('name' => 'filters', 'value' => 0), | |
1473 | ); | |
1474 | ||
1475 | core_course_external::import_course($course1->id, $course2->id, 0, $options); | |
1476 | ||
1477 | $newcmcount = count(get_fast_modinfo($course2->id)->get_cms()); | |
1478 | $newblockcount = $DB->count_records('block_instances', array('parentcontextid' => $course2ctx->id)); | |
1479 | // Check that course modules haven't changed, but that blocks have. | |
1480 | $this->assertEquals($initialcmcount, $newcmcount); | |
1481 | $this->assertEquals(($initialblockcount + 1), $newblockcount); | |
fce10644 DP |
1482 | } |
1483 | ||
1484 | /** | |
1485 | * Test import_course into an filled course, deleting content. | |
1486 | */ | |
1487 | public function test_import_course_deletecontent() { | |
1488 | global $USER; | |
1489 | $this->resetAfterTest(true); | |
1490 | ||
1491 | // Add forum and page to course1. | |
1492 | $course1 = self::getDataGenerator()->create_course(); | |
1493 | $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course1->id, 'name' => 'Forum test')); | |
1494 | $page = $this->getDataGenerator()->create_module('page', array('course'=>$course1->id, 'name' => 'Page test')); | |
1495 | ||
1496 | // Add quiz to course 2. | |
1497 | $course2 = self::getDataGenerator()->create_course(); | |
1498 | $quiz = $this->getDataGenerator()->create_module('quiz', array('course'=>$course2->id, 'name' => 'Page test')); | |
1499 | ||
1500 | $course1cms = get_fast_modinfo($course1->id)->get_cms(); | |
1501 | $course2cms = get_fast_modinfo($course2->id)->get_cms(); | |
1502 | ||
1503 | // Verify the state of the courses before we do the import. | |
1504 | $this->assertCount(2, $course1cms); | |
1505 | $this->assertCount(1, $course2cms); | |
1506 | ||
1507 | // Setup the user to run the operation (ugly hack because validate_context() will | |
1508 | // fail as the email is not set by $this->setAdminUser()). | |
1509 | $this->setAdminUser(); | |
0fe86bbd | 1510 | $USER->email = 'emailtopass@example.com'; |
fce10644 DP |
1511 | |
1512 | // Import from course1 to course2, deleting content. | |
1513 | core_course_external::import_course($course1->id, $course2->id, 1); | |
1514 | ||
1515 | $course2cms = get_fast_modinfo($course2->id)->get_cms(); | |
1516 | ||
1517 | // Verify that now we have two modules in course2. | |
1518 | $this->assertCount(2, $course2cms); | |
1519 | ||
1520 | // Verify that the course only contains the imported modules. | |
1521 | foreach ($course2cms as $cm) { | |
1522 | if ($cm->modname === 'page') { | |
1523 | $this->assertEquals($cm->name, $page->name); | |
1524 | } else if ($cm->modname === 'forum') { | |
1525 | $this->assertEquals($cm->name, $forum->name); | |
1526 | } else { | |
1527 | $this->fail('Unknown CM found: '.$cm->name); | |
1528 | } | |
1529 | } | |
fce10644 DP |
1530 | } |
1531 | ||
1532 | /** | |
1533 | * Ensure import_course handles incorrect deletecontent option correctly. | |
1534 | */ | |
1535 | public function test_import_course_invalid_deletecontent_option() { | |
1536 | $this->resetAfterTest(true); | |
1537 | ||
1538 | $course1 = self::getDataGenerator()->create_course(); | |
1539 | $course2 = self::getDataGenerator()->create_course(); | |
1540 | ||
52f3e060 RT |
1541 | $this->expectException('moodle_exception'); |
1542 | $this->expectExceptionMessage(get_string('invalidextparam', 'webservice', -1)); | |
fce10644 DP |
1543 | // Import from course1 to course2, with invalid option |
1544 | core_course_external::import_course($course1->id, $course2->id, -1);; | |
1545 | } | |
e81f67ca JL |
1546 | |
1547 | /** | |
1548 | * Test view_course function | |
1549 | */ | |
1550 | public function test_view_course() { | |
1551 | ||
1552 | $this->resetAfterTest(); | |
1553 | ||
1554 | // Course without sections. | |
1555 | $course = $this->getDataGenerator()->create_course(array('numsections' => 5), array('createsections' => true)); | |
1556 | $this->setAdminUser(); | |
1557 | ||
1558 | // Redirect events to the sink, so we can recover them later. | |
1559 | $sink = $this->redirectEvents(); | |
1560 | ||
bdf9f4d4 JL |
1561 | $result = core_course_external::view_course($course->id, 1); |
1562 | $result = external_api::clean_returnvalue(core_course_external::view_course_returns(), $result); | |
e81f67ca JL |
1563 | $events = $sink->get_events(); |
1564 | $event = reset($events); | |
1565 | ||
1566 | // Check the event details are correct. | |
1567 | $this->assertInstanceOf('\core\event\course_viewed', $event); | |
1568 | $this->assertEquals(context_course::instance($course->id), $event->get_context()); | |
1569 | $this->assertEquals(1, $event->other['coursesectionnumber']); | |
1570 | ||
bdf9f4d4 JL |
1571 | $result = core_course_external::view_course($course->id); |
1572 | $result = external_api::clean_returnvalue(core_course_external::view_course_returns(), $result); | |
e81f67ca JL |
1573 | $events = $sink->get_events(); |
1574 | $event = array_pop($events); | |
1575 | $sink->close(); | |
1576 | ||
1577 | // Check the event details are correct. | |
1578 | $this->assertInstanceOf('\core\event\course_viewed', $event); | |
1579 | $this->assertEquals(context_course::instance($course->id), $event->get_context()); | |
1580 | $this->assertEmpty($event->other); | |
1581 | ||
1582 | } | |
c5158499 JL |
1583 | |
1584 | /** | |
1585 | * Test get_course_module | |
1586 | */ | |
1587 | public function test_get_course_module() { | |
1588 | global $DB; | |
1589 | ||
1590 | $this->resetAfterTest(true); | |
1591 | ||
1592 | $this->setAdminUser(); | |
1593 | $course = self::getDataGenerator()->create_course(); | |
1594 | $record = array( | |
1595 | 'course' => $course->id, | |
1596 | 'name' => 'First Chat' | |
1597 | ); | |
1598 | $options = array( | |
1599 | 'idnumber' => 'ABC', | |
1600 | 'visible' => 0 | |
1601 | ); | |
1602 | // Hidden activity. | |
1603 | $chat = self::getDataGenerator()->create_module('chat', $record, $options); | |
1604 | ||
1605 | // Test admin user can see the complete hidden activity. | |
1606 | $result = core_course_external::get_course_module($chat->cmid); | |
1607 | $result = external_api::clean_returnvalue(core_course_external::get_course_module_returns(), $result); | |
1608 | ||
1609 | $this->assertCount(0, $result['warnings']); | |
1610 | // Test we retrieve all the fields. | |
e99b197e | 1611 | $this->assertCount(22, $result['cm']); |
c5158499 JL |
1612 | $this->assertEquals($record['name'], $result['cm']['name']); |
1613 | $this->assertEquals($options['idnumber'], $result['cm']['idnumber']); | |
1614 | ||
1615 | $student = $this->getDataGenerator()->create_user(); | |
1616 | $studentrole = $DB->get_record('role', array('shortname' => 'student')); | |
1617 | ||
1618 | self::getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id); | |
1619 | $this->setUser($student); | |
1620 | ||
1621 | // The user shouldn't be able to see the activity. | |
1622 | try { | |
1623 | core_course_external::get_course_module($chat->cmid); | |
1624 | $this->fail('Exception expected due to invalid permissions.'); | |
1625 | } catch (moodle_exception $e) { | |
1626 | $this->assertEquals('requireloginerror', $e->errorcode); | |
1627 | } | |
1628 | ||
1629 | // Make module visible. | |
1630 | set_coursemodule_visible($chat->cmid, 1); | |
1631 | ||
1632 | // Test student user. | |
1633 | $result = core_course_external::get_course_module($chat->cmid); | |
1634 | $result = external_api::clean_returnvalue(core_course_external::get_course_module_returns(), $result); | |
1635 | ||
1636 | $this->assertCount(0, $result['warnings']); | |
1637 | // Test we retrieve only the few files we can see. | |
1638 | $this->assertCount(11, $result['cm']); | |
1639 | $this->assertEquals($chat->cmid, $result['cm']['id']); | |
1640 | $this->assertEquals($course->id, $result['cm']['course']); | |
1641 | $this->assertEquals('chat', $result['cm']['modname']); | |
1642 | $this->assertEquals($chat->id, $result['cm']['instance']); | |
1643 | ||
1644 | } | |
13bb6819 JL |
1645 | |
1646 | /** | |
1647 | * Test get_course_module_by_instance | |
1648 | */ | |
1649 | public function test_get_course_module_by_instance() { | |
1650 | global $DB; | |
1651 | ||
1652 | $this->resetAfterTest(true); | |
1653 | ||
1654 | $this->setAdminUser(); | |
1655 | $course = self::getDataGenerator()->create_course(); | |
1656 | $record = array( | |
1657 | 'course' => $course->id, | |
1658 | 'name' => 'First Chat' | |
1659 | ); | |
1660 | $options = array( | |
1661 | 'idnumber' => 'ABC', | |
1662 | 'visible' => 0 | |
1663 | ); | |
1664 | // Hidden activity. | |
1665 | $chat = self::getDataGenerator()->create_module('chat', $record, $options); | |
1666 | ||
1667 | // Test admin user can see the complete hidden activity. | |
1668 | $result = core_course_external::get_course_module_by_instance('chat', $chat->id); | |
1669 | $result = external_api::clean_returnvalue(core_course_external::get_course_module_by_instance_returns(), $result); | |
1670 | ||
1671 | $this->assertCount(0, $result['warnings']); | |
1672 | // Test we retrieve all the fields. | |
1673 | $this->assertCount(22, $result['cm']); | |
1674 | $this->assertEquals($record['name'], $result['cm']['name']); | |
1675 | $this->assertEquals($options['idnumber'], $result['cm']['idnumber']); | |
1676 | ||
1677 | $student = $this->getDataGenerator()->create_user(); | |
1678 | $studentrole = $DB->get_record('role', array('shortname' => 'student')); | |
1679 | ||
1680 | self::getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id); | |
1681 | $this->setUser($student); | |
1682 | ||
1683 | // The user shouldn't be able to see the activity. | |
1684 | try { | |
1685 | core_course_external::get_course_module_by_instance('chat', $chat->id); | |
1686 | $this->fail('Exception expected due to invalid permissions.'); | |
1687 | } catch (moodle_exception $e) { | |
1688 | $this->assertEquals('requireloginerror', $e->errorcode); | |
1689 | } | |
1690 | ||
1691 | // Make module visible. | |
1692 | set_coursemodule_visible($chat->cmid, 1); | |
1693 | ||
1694 | // Test student user. | |
1695 | $result = core_course_external::get_course_module_by_instance('chat', $chat->id); | |
1696 | $result = external_api::clean_returnvalue(core_course_external::get_course_module_by_instance_returns(), $result); | |
1697 | ||
1698 | $this->assertCount(0, $result['warnings']); | |
1699 | // Test we retrieve only the few files we can see. | |
1700 | $this->assertCount(11, $result['cm']); | |
1701 | $this->assertEquals($chat->cmid, $result['cm']['id']); | |
1702 | $this->assertEquals($course->id, $result['cm']['course']); | |
1703 | $this->assertEquals('chat', $result['cm']['modname']); | |
1704 | $this->assertEquals($chat->id, $result['cm']['instance']); | |
1705 | ||
1706 | // Try with an invalid module name. | |
1707 | try { | |
1708 | core_course_external::get_course_module_by_instance('abc', $chat->id); | |
1709 | $this->fail('Exception expected due to invalid module name.'); | |
1710 | } catch (dml_read_exception $e) { | |
1711 | $this->assertEquals('dmlreadexception', $e->errorcode); | |
1712 | } | |
1713 | ||
1714 | } | |
7c4e686f JL |
1715 | |
1716 | /** | |
1717 | * Test get_activities_overview | |
1718 | */ | |
1719 | public function test_get_activities_overview() { | |
1720 | global $USER; | |
1721 | ||
1722 | $this->resetAfterTest(); | |
1723 | $course1 = self::getDataGenerator()->create_course(); | |
1724 | $course2 = self::getDataGenerator()->create_course(); | |
1725 | ||
1726 | // Create a viewer user. | |
1727 | $viewer = self::getDataGenerator()->create_user((object) array('trackforums' => 1)); | |
1728 | $this->getDataGenerator()->enrol_user($viewer->id, $course1->id); | |
1729 | $this->getDataGenerator()->enrol_user($viewer->id, $course2->id); | |
1730 | ||
1731 | // Create two forums - one in each course. | |
1732 | $record = new stdClass(); | |
1733 | $record->course = $course1->id; | |
1734 | $forum1 = self::getDataGenerator()->create_module('forum', (object) array('course' => $course1->id)); | |
1735 | $forum2 = self::getDataGenerator()->create_module('forum', (object) array('course' => $course2->id)); | |
1736 | ||
1737 | $this->setAdminUser(); | |
1738 | // A standard post in the forum. | |
1739 | $record = new stdClass(); | |
1740 | $record->course = $course1->id; | |
1741 | $record->userid = $USER->id; | |
1742 | $record->forum = $forum1->id; | |
1743 | $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); | |
1744 | ||
1745 | $this->setUser($viewer->id); | |
1746 | $courses = array($course1->id , $course2->id); | |
1747 | ||
1748 | $result = core_course_external::get_activities_overview($courses); | |
1749 | $result = external_api::clean_returnvalue(core_course_external::get_activities_overview_returns(), $result); | |
1750 | ||
1751 | // There should be one entry for course1, and no others. | |
1752 | $this->assertCount(1, $result['courses']); | |
1753 | $this->assertEquals($course1->id, $result['courses'][0]['id']); | |
1754 | // Check expected overview data for the module. | |
1755 | $this->assertEquals('forum', $result['courses'][0]['overviews'][0]['module']); | |
1756 | $this->assertContains('1 total unread', $result['courses'][0]['overviews'][0]['overviewtext']); | |
1757 | } | |
c115ff6a JL |
1758 | |
1759 | /** | |
1760 | * Test get_user_navigation_options | |
1761 | */ | |
1762 | public function test_get_user_navigation_options() { | |
1763 | global $USER; | |
1764 | ||
1765 | $this->resetAfterTest(); | |
1766 | $course1 = self::getDataGenerator()->create_course(); | |
1767 | $course2 = self::getDataGenerator()->create_course(); | |
1768 | ||
1769 | // Create a viewer user. | |
1770 | $viewer = self::getDataGenerator()->create_user(); | |
1771 | $this->getDataGenerator()->enrol_user($viewer->id, $course1->id); | |
1772 | $this->getDataGenerator()->enrol_user($viewer->id, $course2->id); | |
1773 | ||
1774 | $this->setUser($viewer->id); | |
1775 | $courses = array($course1->id , $course2->id, SITEID); | |
1776 | ||
1777 | $result = core_course_external::get_user_navigation_options($courses); | |
1778 | $result = external_api::clean_returnvalue(core_course_external::get_user_navigation_options_returns(), $result); | |
1779 | ||
1780 | $this->assertCount(0, $result['warnings']); | |
1781 | $this->assertCount(3, $result['courses']); | |
1782 | ||
1783 | foreach ($result['courses'] as $course) { | |
1784 | $navoptions = new stdClass; | |
1785 | foreach ($course['options'] as $option) { | |
1786 | $navoptions->{$option['name']} = $option['available']; | |
1787 | } | |
1788 | if ($course['id'] == SITEID) { | |
1789 | $this->assertCount(7, $course['options']); | |
1790 | $this->assertTrue($navoptions->blogs); | |
1791 | $this->assertFalse($navoptions->notes); | |
1792 | $this->assertFalse($navoptions->participants); | |
1793 | $this->assertTrue($navoptions->badges); | |
1794 | $this->assertTrue($navoptions->tags); | |
1795 | $this->assertFalse($navoptions->search); | |
1796 | $this->assertTrue($navoptions->calendar); | |
1797 | } else { | |
1798 | $this->assertCount(4, $course['options']); | |
1799 | $this->assertTrue($navoptions->blogs); | |
1800 | $this->assertFalse($navoptions->notes); | |
1801 | $this->assertTrue($navoptions->participants); | |
1802 | $this->assertTrue($navoptions->badges); | |
1803 | } | |
1804 | } | |
1805 | } | |
b9050b10 JL |
1806 | |
1807 | /** | |
1808 | * Test get_user_administration_options | |
1809 | */ | |
1810 | public function test_get_user_administration_options() { | |
1811 | global $USER; | |
1812 | ||
1813 | $this->resetAfterTest(); | |
1814 | $course1 = self::getDataGenerator()->create_course(); | |
1815 | $course2 = self::getDataGenerator()->create_course(); | |
1816 | ||
1817 | // Create a viewer user. | |
1818 | $viewer = self::getDataGenerator()->create_user(); | |
1819 | $this->getDataGenerator()->enrol_user($viewer->id, $course1->id); | |
1820 | $this->getDataGenerator()->enrol_user($viewer->id, $course2->id); | |
1821 | ||
1822 | $this->setUser($viewer->id); | |
1823 | $courses = array($course1->id , $course2->id, SITEID); | |
1824 | ||
1825 | $result = core_course_external::get_user_administration_options($courses); | |
1826 | $result = external_api::clean_returnvalue(core_course_external::get_user_administration_options_returns(), $result); | |
1827 | ||
1828 | $this->assertCount(0, $result['warnings']); | |
1829 | $this->assertCount(3, $result['courses']); | |
1830 | ||
1831 | foreach ($result['courses'] as $course) { | |
1832 | $adminoptions = new stdClass; | |
1833 | foreach ($course['options'] as $option) { | |
1834 | $adminoptions->{$option['name']} = $option['available']; | |
1835 | } | |
1836 | if ($course['id'] == SITEID) { | |
c874d9aa | 1837 | $this->assertCount(15, $course['options']); |
b9050b10 JL |
1838 | $this->assertFalse($adminoptions->update); |
1839 | $this->assertFalse($adminoptions->filters); | |
1840 | $this->assertFalse($adminoptions->reports); | |
1841 | $this->assertFalse($adminoptions->backup); | |
1842 | $this->assertFalse($adminoptions->restore); | |
1843 | $this->assertFalse($adminoptions->files); | |
c874d9aa JL |
1844 | $this->assertFalse(!isset($adminoptions->tags)); |
1845 | $this->assertFalse($adminoptions->gradebook); | |
1846 | $this->assertFalse($adminoptions->outcomes); | |
1847 | $this->assertFalse($adminoptions->badges); | |
1848 | $this->assertFalse($adminoptions->import); | |
1849 | $this->assertFalse($adminoptions->publish); | |
1850 | $this->assertFalse($adminoptions->reset); | |
1851 | $this->assertFalse($adminoptions->roles); | |
1852 | $this->assertFalse($adminoptions->grades); | |
b9050b10 JL |
1853 | } else { |
1854 | $this->assertCount(15, $course['options']); | |
1855 | $this->assertFalse($adminoptions->update); | |
1856 | $this->assertFalse($adminoptions->filters); | |
1857 | $this->assertFalse($adminoptions->reports); | |
1858 | $this->assertFalse($adminoptions->backup); | |
1859 | $this->assertFalse($adminoptions->restore); | |
1860 | $this->assertFalse($adminoptions->files); | |
1861 | $this->assertFalse($adminoptions->tags); | |
1862 | $this->assertFalse($adminoptions->gradebook); | |
1863 | $this->assertFalse($adminoptions->outcomes); | |
1864 | $this->assertTrue($adminoptions->badges); | |
1865 | $this->assertFalse($adminoptions->import); | |
1866 | $this->assertFalse($adminoptions->publish); | |
1867 | $this->assertFalse($adminoptions->reset); | |
1868 | $this->assertFalse($adminoptions->roles); | |
1869 | $this->assertTrue($adminoptions->grades); | |
1870 | } | |
1871 | } | |
1872 | } | |
2a7a0216 | 1873 | } |