2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Tests for class coursecat from lib/coursecatlib.php
22 * @copyright 2013 Marina Glancy
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') ||
die();
29 require_once($CFG->libdir
. '/coursecatlib.php');
32 * Functional test for coursecatlib.php
34 class core_coursecatlib_testcase
extends advanced_testcase
{
38 protected function setUp() {
40 $this->resetAfterTest();
41 $user = $this->getDataGenerator()->create_user();
42 $this->setUser($user);
45 protected function get_roleid($context = null) {
47 if ($context === null) {
48 $context = context_system
::instance();
50 if (is_object($context)) {
51 $context = $context->id
;
53 if (empty($this->roles
)) {
54 $this->roles
= array();
56 if (empty($this->roles
[$USER->id
])) {
57 $this->roles
[$USER->id
] = array();
59 if (empty($this->roles
[$USER->id
][$context])) {
60 $this->roles
[$USER->id
][$context] = create_role('Role for '.$USER->id
.' in '.$context, 'role'.$USER->id
.'-'.$context, '-');
61 role_assign($this->roles
[$USER->id
][$context], $USER->id
, $context);
63 return $this->roles
[$USER->id
][$context];
66 protected function assign_capability($capability, $permission = CAP_ALLOW
, $contextid = null) {
67 if ($contextid === null) {
68 $contextid = context_system
::instance();
70 if (is_object($contextid)) {
71 $contextid = $contextid->id
;
73 assign_capability($capability, $permission, $this->get_roleid($contextid), $contextid, true);
74 accesslib_clear_all_caches_for_unit_testing();
77 public function test_create_coursecat() {
78 // Create the category.
79 $data = new stdClass();
81 $data->description
= 'aaa';
84 $category1 = coursecat
::create($data);
86 // Initially confirm that base data was inserted correctly.
87 $this->assertSame($data->name
, $category1->name
);
88 $this->assertSame($data->description
, $category1->description
);
89 $this->assertSame($data->idnumber
, $category1->idnumber
);
91 $this->assertGreaterThanOrEqual(1, $category1->sortorder
);
93 // Create two more categories and test the sortorder worked correctly.
95 $category2 = coursecat
::create($data);
98 $category3 = coursecat
::create($data);
100 $this->assertGreaterThan($category1->sortorder
, $category2->sortorder
);
101 $this->assertGreaterThan($category2->sortorder
, $category3->sortorder
);
104 public function test_name_idnumber_exceptions() {
106 coursecat
::create(array('name' => ''));
107 $this->fail('Missing category name exception expected in coursecat::create');
108 } catch (moodle_exception
$e) {
109 $this->assertInstanceOf('moodle_exception', $e);
111 $cat1 = coursecat
::create(array('name' => 'Cat1', 'idnumber' => '1'));
113 $cat1->update(array('name' => ''));
114 $this->fail('Missing category name exception expected in coursecat::update');
115 } catch (moodle_exception
$e) {
116 $this->assertInstanceOf('moodle_exception', $e);
119 coursecat
::create(array('name' => 'Cat2', 'idnumber' => '1'));
120 $this->fail('Duplicate idnumber exception expected in coursecat::create');
121 } catch (moodle_exception
$e) {
122 $this->assertInstanceOf('moodle_exception', $e);
124 $cat2 = coursecat
::create(array('name' => 'Cat2', 'idnumber' => '2'));
126 $cat2->update(array('idnumber' => '1'));
127 $this->fail('Duplicate idnumber exception expected in coursecat::update');
128 } catch (moodle_exception
$e) {
129 $this->assertInstanceOf('moodle_exception', $e);
133 public function test_visibility() {
134 $this->assign_capability('moodle/category:viewhiddencategories');
135 $this->assign_capability('moodle/category:manage');
137 // Create category 1 initially hidden.
138 $category1 = coursecat
::create(array('name' => 'Cat1', 'visible' => 0));
139 $this->assertEquals(0, $category1->visible
);
140 $this->assertEquals(0, $category1->visibleold
);
142 // Create category 2 initially hidden as a child of hidden category 1.
143 $category2 = coursecat
::create(array('name' => 'Cat2', 'visible' => 0, 'parent' => $category1->id
));
144 $this->assertEquals(0, $category2->visible
);
145 $this->assertEquals(0, $category2->visibleold
);
147 // Create category 3 initially visible as a child of hidden category 1.
148 $category3 = coursecat
::create(array('name' => 'Cat3', 'visible' => 1, 'parent' => $category1->id
));
149 $this->assertEquals(0, $category3->visible
);
150 $this->assertEquals(1, $category3->visibleold
);
152 // Show category 1 and make sure that category 2 is hidden and category 3 is visible.
154 $this->assertEquals(1, coursecat
::get($category1->id
)->visible
);
155 $this->assertEquals(0, coursecat
::get($category2->id
)->visible
);
156 $this->assertEquals(1, coursecat
::get($category3->id
)->visible
);
158 // Create visible category 4.
159 $category4 = coursecat
::create(array('name' => 'Cat4'));
160 $this->assertEquals(1, $category4->visible
);
161 $this->assertEquals(1, $category4->visibleold
);
163 // Create visible category 5 as a child of visible category 4.
164 $category5 = coursecat
::create(array('name' => 'Cat5', 'parent' => $category4->id
));
165 $this->assertEquals(1, $category5->visible
);
166 $this->assertEquals(1, $category5->visibleold
);
168 // Hide category 4 and make sure category 5 is hidden too.
170 $this->assertEquals(0, $category4->visible
);
171 $this->assertEquals(0, $category4->visibleold
);
172 $category5 = coursecat
::get($category5->id
); // We have to re-read from DB.
173 $this->assertEquals(0, $category5->visible
);
174 $this->assertEquals(1, $category5->visibleold
);
176 // Show category 4 and make sure category 5 is visible too.
178 $this->assertEquals(1, $category4->visible
);
179 $this->assertEquals(1, $category4->visibleold
);
180 $category5 = coursecat
::get($category5->id
); // We have to re-read from DB.
181 $this->assertEquals(1, $category5->visible
);
182 $this->assertEquals(1, $category5->visibleold
);
184 // Move category 5 under hidden category 2 and make sure it became hidden.
185 $category5->change_parent($category2->id
);
186 $this->assertEquals(0, $category5->visible
);
187 $this->assertEquals(1, $category5->visibleold
);
189 // Re-read object for category 5 from DB and check again.
190 $category5 = coursecat
::get($category5->id
);
191 $this->assertEquals(0, $category5->visible
);
192 $this->assertEquals(1, $category5->visibleold
);
194 // Rricky one! Move hidden category 5 under visible category ("Top") and make sure it is still hidden-
195 // WHY? Well, different people may expect different behaviour here. So better keep it hidden.
196 $category5->change_parent(0);
197 $this->assertEquals(0, $category5->visible
);
198 $this->assertEquals(1, $category5->visibleold
);
201 public function test_hierarchy() {
202 $this->assign_capability('moodle/category:viewhiddencategories');
203 $this->assign_capability('moodle/category:manage');
205 $category1 = coursecat
::create(array('name' => 'Cat1'));
206 $category2 = coursecat
::create(array('name' => 'Cat2', 'parent' => $category1->id
));
207 $category3 = coursecat
::create(array('name' => 'Cat3', 'parent' => $category1->id
));
208 $category4 = coursecat
::create(array('name' => 'Cat4', 'parent' => $category2->id
));
210 // Check function get_children().
211 $this->assertEquals(array($category2->id
, $category3->id
), array_keys($category1->get_children()));
212 // Check function get_parents().
213 $this->assertEquals(array($category1->id
, $category2->id
), $category4->get_parents());
215 // Can not move category to itself or to it's children.
216 $this->assertFalse($category1->can_change_parent($category2->id
));
217 $this->assertFalse($category2->can_change_parent($category2->id
));
218 // Can move category to grandparent.
219 $this->assertTrue($category4->can_change_parent($category1->id
));
222 $category2->change_parent($category4->id
);
223 $this->fail('Exception expected - can not move category');
224 } catch (moodle_exception
$e) {
225 $this->assertInstanceOf('moodle_exception', $e);
228 $category4->change_parent(0);
229 $this->assertEquals(array(), $category4->get_parents());
230 $this->assertEquals(array($category2->id
, $category3->id
), array_keys($category1->get_children()));
231 $this->assertEquals(array(), array_keys($category2->get_children()));
234 public function test_update() {
235 $category1 = coursecat
::create(array('name' => 'Cat1'));
236 $timecreated = $category1->timemodified
;
237 $this->assertSame('Cat1', $category1->name
);
238 $this->assertTrue(empty($category1->description
));
240 $testdescription = 'This is cat 1 а также русский текст';
241 $category1->update(array('description' => $testdescription));
242 $this->assertSame($testdescription, $category1->description
);
243 $category1 = coursecat
::get($category1->id
);
244 $this->assertSame($testdescription, $category1->description
);
245 cache_helper
::purge_by_event('changesincoursecat');
246 $category1 = coursecat
::get($category1->id
);
247 $this->assertSame($testdescription, $category1->description
);
249 $this->assertGreaterThan($timecreated, $category1->timemodified
);
252 public function test_delete() {
255 $this->assign_capability('moodle/category:manage');
256 $this->assign_capability('moodle/course:create');
258 $initialcatid = $DB->get_field_sql('SELECT max(id) from {course_categories}');
260 $category1 = coursecat
::create(array('name' => 'Cat1'));
261 $category2 = coursecat
::create(array('name' => 'Cat2', 'parent' => $category1->id
));
262 $category3 = coursecat
::create(array('name' => 'Cat3'));
263 $category4 = coursecat
::create(array('name' => 'Cat4', 'parent' => $category2->id
));
265 $course1 = $this->getDataGenerator()->create_course(array('category' => $category2->id
));
266 $course2 = $this->getDataGenerator()->create_course(array('category' => $category4->id
));
267 $course3 = $this->getDataGenerator()->create_course(array('category' => $category4->id
));
268 $course4 = $this->getDataGenerator()->create_course(array('category' => $category1->id
));
281 // Login as another user to test course:delete capability (user who created course can delete it within 24h even without cap).
282 $this->setUser($this->getDataGenerator()->create_user());
284 // Delete category 2 and move content to category 3.
285 $this->assertFalse($category2->can_move_content_to($category3->id
)); // No luck!
286 // Add necessary capabilities.
287 $this->assign_capability('moodle/course:create', CAP_ALLOW
, context_coursecat
::instance($category3->id
));
288 $this->assign_capability('moodle/category:manage');
289 $this->assertTrue($category2->can_move_content_to($category3->id
)); // Hurray!
290 $category2->delete_move($category3->id
);
292 // Make sure we have:
302 $this->assertNull(coursecat
::get($category2->id
, IGNORE_MISSING
, true));
303 $this->assertEquals(array(), $category1->get_children());
304 $this->assertEquals(array($category4->id
), array_keys($category3->get_children()));
305 $this->assertEquals($category4->id
, $DB->get_field('course', 'category', array('id' => $course2->id
)));
306 $this->assertEquals($category4->id
, $DB->get_field('course', 'category', array('id' => $course3->id
)));
307 $this->assertEquals($category3->id
, $DB->get_field('course', 'category', array('id' => $course1->id
)));
309 // Delete category 3 completely.
310 $this->assertFalse($category3->can_delete_full()); // No luck!
311 // Add necessary capabilities.
312 $this->assign_capability('moodle/course:delete', CAP_ALLOW
, context_coursecat
::instance($category3->id
));
313 $this->assertTrue($category3->can_delete_full()); // Hurray!
314 $category3->delete_full();
316 // Make sure we have:
321 // Note that we also have default 'Miscellaneous' category and default 'site' course.
322 $this->assertEquals(1, $DB->get_field_sql('SELECT count(*) FROM {course_categories} WHERE id > ?', array($initialcatid)));
323 $this->assertEquals($category1->id
, $DB->get_field_sql('SELECT max(id) FROM {course_categories}'));
324 $this->assertEquals(1, $DB->get_field_sql('SELECT count(*) FROM {course} WHERE id <> ?', array(SITEID
)));
325 $this->assertEquals(array('id' => $course4->id
, 'category' => $category1->id
),
326 (array)$DB->get_record_sql('SELECT id, category from {course} where id <> ?', array(SITEID
)));
329 public function test_get_children() {
330 $category1 = coursecat
::create(array('name' => 'Cat1'));
331 $category2 = coursecat
::create(array('name' => 'Cat2', 'parent' => $category1->id
));
332 $category3 = coursecat
::create(array('name' => 'Cat3', 'parent' => $category1->id
, 'visible' => 0));
333 $category4 = coursecat
::create(array('name' => 'Cat4', 'idnumber' => '12', 'parent' => $category1->id
));
334 $category5 = coursecat
::create(array('name' => 'Cat5', 'idnumber' => '11', 'parent' => $category1->id
, 'visible' => 0));
335 $category6 = coursecat
::create(array('name' => 'Cat6', 'idnumber' => '10', 'parent' => $category1->id
));
336 $category7 = coursecat
::create(array('name' => 'Cat0', 'parent' => $category1->id
));
338 $children = $category1->get_children();
339 // User does not have the capability to view hidden categories, so the list should be
341 $this->assertEquals(array($category2->id
, $category4->id
, $category6->id
, $category7->id
), array_keys($children));
342 $this->assertEquals(4, $category1->get_children_count());
344 $children = $category1->get_children(array('offset' => 2));
345 $this->assertEquals(array($category6->id
, $category7->id
), array_keys($children));
346 $this->assertEquals(4, $category1->get_children_count());
348 $children = $category1->get_children(array('limit' => 2));
349 $this->assertEquals(array($category2->id
, $category4->id
), array_keys($children));
351 $children = $category1->get_children(array('offset' => 1, 'limit' => 2));
352 $this->assertEquals(array($category4->id
, $category6->id
), array_keys($children));
354 $children = $category1->get_children(array('sort' => array('name' => 1)));
355 // Must be 7, 2, 4, 6.
356 $this->assertEquals(array($category7->id
, $category2->id
, $category4->id
, $category6->id
), array_keys($children));
358 $children = $category1->get_children(array('sort' => array('idnumber' => 1, 'name' => -1)));
359 // Must be 2, 7, 6, 4.
360 $this->assertEquals(array($category2->id
, $category7->id
, $category6->id
, $category4->id
), array_keys($children));
362 // Check that everything is all right after purging the caches.
363 cache_helper
::purge_by_event('changesincoursecat');
364 $children = $category1->get_children();
365 $this->assertEquals(array($category2->id
, $category4->id
, $category6->id
, $category7->id
), array_keys($children));
366 $this->assertEquals(4, $category1->get_children_count());
370 * Test the countall function
372 public function test_count_all() {
374 // Dont assume there is just one. An add-on might create a category as part of the install.
375 $numcategories = $DB->count_records('course_categories');
376 $this->assertEquals($numcategories, coursecat
::count_all());
377 $category1 = coursecat
::create(array('name' => 'Cat1'));
378 $category2 = coursecat
::create(array('name' => 'Cat2', 'parent' => $category1->id
));
379 $category3 = coursecat
::create(array('name' => 'Cat3', 'parent' => $category2->id
, 'visible' => 0));
380 // Now we've got three more.
381 $this->assertEquals($numcategories +
3, coursecat
::count_all());
382 cache_helper
::purge_by_event('changesincoursecat');
383 // We should still have 4.
384 $this->assertEquals($numcategories +
3, coursecat
::count_all());
388 * Test a categories ability to resort courses.
390 public function test_resort_courses() {
391 $this->resetAfterTest(true);
392 $generator = $this->getDataGenerator();
393 $category = $generator->create_category();
394 $course1 = $generator->create_course(array(
395 'category' => $category->id
,
396 'idnumber' => '006-01',
397 'shortname' => 'Biome Study',
398 'fullname' => '<span lang="ar" class="multilang">'.'دراسة منطقة إحيائية'.'</span><span lang="en" class="multilang">Biome Study</span>'
400 $course2 = $generator->create_course(array(
401 'category' => $category->id
,
402 'idnumber' => '007-02',
403 'shortname' => 'Chemistry Revision',
404 'fullname' => 'Chemistry Revision'
406 $course3 = $generator->create_course(array(
407 'category' => $category->id
,
408 'idnumber' => '007-03',
409 'shortname' => 'Swiss Rolls and Sunflowers',
410 'fullname' => 'Aarkvarks guide to Swiss Rolls and Sunflowers'
412 $course4 = $generator->create_course(array(
413 'category' => $category->id
,
414 'idnumber' => '006-04',
415 'shortname' => 'Scratch',
416 'fullname' => '<a href="test.php">Basic Scratch</a>'
418 $c1 = (int)$course1->id
;
419 $c2 = (int)$course2->id
;
420 $c3 = (int)$course3->id
;
421 $c4 = (int)$course4->id
;
423 $coursecat = coursecat
::get($category->id
);
424 $this->assertTrue($coursecat->resort_courses('idnumber'));
425 $this->assertSame(array($c1, $c4, $c2, $c3), array_keys($coursecat->get_courses()));
427 $this->assertTrue($coursecat->resort_courses('shortname'));
428 $this->assertSame(array($c1, $c2, $c4, $c3), array_keys($coursecat->get_courses()));
432 // Enable the multilang filter and set it to apply to headings and content.
433 filter_set_global_state('multilang', TEXTFILTER_ON
);
434 filter_set_applies_to_strings('multilang', true);
435 $expected = array($c3, $c4, $c1, $c2);
436 } catch (coding_exception
$ex) {
437 $expected = array($c3, $c4, $c2, $c1);
439 $this->assertTrue($coursecat->resort_courses('fullname'));
440 $this->assertSame($expected, array_keys($coursecat->get_courses()));
443 public function test_get_search_courses() {
444 $cat1 = coursecat
::create(array('name' => 'Cat1'));
445 $cat2 = coursecat
::create(array('name' => 'Cat2', 'parent' => $cat1->id
));
446 $c1 = $this->getDataGenerator()->create_course(array('category' => $cat1->id
, 'fullname' => 'Test 3', 'summary' => ' ', 'idnumber' => 'ID3'));
447 $c2 = $this->getDataGenerator()->create_course(array('category' => $cat1->id
, 'fullname' => 'Test 1', 'summary' => ' ', 'visible' => 0));
448 $c3 = $this->getDataGenerator()->create_course(array('category' => $cat1->id
, 'fullname' => 'Математика', 'summary' => ' Test '));
449 $c4 = $this->getDataGenerator()->create_course(array('category' => $cat1->id
, 'fullname' => 'Test 4', 'summary' => ' ', 'idnumber' => 'ID4'));
451 $c5 = $this->getDataGenerator()->create_course(array('category' => $cat2->id
, 'fullname' => 'Test 5', 'summary' => ' '));
452 $c6 = $this->getDataGenerator()->create_course(array('category' => $cat2->id
, 'fullname' => 'Дискретная Математика', 'summary' => ' '));
453 $c7 = $this->getDataGenerator()->create_course(array('category' => $cat2->id
, 'fullname' => 'Test 7', 'summary' => ' ', 'visible' => 0));
454 $c8 = $this->getDataGenerator()->create_course(array('category' => $cat2->id
, 'fullname' => 'Test 8', 'summary' => ' '));
456 // Get courses in category 1 (returned visible only because user is not enrolled).
457 $res = $cat1->get_courses(array('sortorder' => 1));
458 $this->assertEquals(array($c4->id
, $c3->id
, $c1->id
), array_keys($res)); // Courses are added in reverse order.
459 $this->assertEquals(3, $cat1->get_courses_count());
461 // Get courses in category 1 recursively (returned visible only because user is not enrolled).
462 $res = $cat1->get_courses(array('recursive' => 1));
463 $this->assertEquals(array($c4->id
, $c3->id
, $c1->id
, $c8->id
, $c6->id
, $c5->id
), array_keys($res));
464 $this->assertEquals(6, $cat1->get_courses_count(array('recursive' => 1)));
466 // Get courses sorted by fullname.
467 $res = $cat1->get_courses(array('sort' => array('fullname' => 1)));
468 $this->assertEquals(array($c1->id
, $c4->id
, $c3->id
), array_keys($res));
469 $this->assertEquals(3, $cat1->get_courses_count(array('sort' => array('fullname' => 1))));
471 // Get courses sorted by fullname recursively.
472 $res = $cat1->get_courses(array('recursive' => 1, 'sort' => array('fullname' => 1)));
473 $this->assertEquals(array($c1->id
, $c4->id
, $c5->id
, $c8->id
, $c6->id
, $c3->id
), array_keys($res));
474 $this->assertEquals(6, $cat1->get_courses_count(array('recursive' => 1, 'sort' => array('fullname' => 1))));
476 // Get courses sorted by fullname recursively, use offset and limit.
477 $res = $cat1->get_courses(array('recursive' => 1, 'offset' => 1, 'limit' => 2, 'sort' => array('fullname' => -1)));
478 $this->assertEquals(array($c6->id
, $c8->id
), array_keys($res));
479 // Offset and limit do not affect get_courses_count().
480 $this->assertEquals(6, $cat1->get_courses_count(array('recursive' => 1, 'offset' => 1, 'limit' => 2, 'sort' => array('fullname' => 1))));
482 // Calling get_courses_count without prior call to get_courses().
483 $this->assertEquals(3, $cat2->get_courses_count(array('recursive' => 1, 'sort' => array('idnumber' => 1))));
488 $res = coursecat
::search_courses(array('search' => 'Test'));
489 $this->assertEquals(array($c4->id
, $c3->id
, $c1->id
, $c8->id
, $c5->id
), array_keys($res));
490 $this->assertEquals(5, coursecat
::search_courses_count(array('search' => 'Test')));
492 // Search by text with specified offset and limit.
493 $options = array('sort' => array('fullname' => 1), 'offset' => 1, 'limit' => 2);
494 $res = coursecat
::search_courses(array('search' => 'Test'), $options);
495 $this->assertEquals(array($c4->id
, $c5->id
), array_keys($res));
496 $this->assertEquals(5, coursecat
::search_courses_count(array('search' => 'Test'), $options));
498 // IMPORTANT: the tests below may fail on some databases
499 // case-insensitive search.
500 $res = coursecat
::search_courses(array('search' => 'test'));
501 $this->assertEquals(array($c4->id
, $c3->id
, $c1->id
, $c8->id
, $c5->id
), array_keys($res));
502 $this->assertEquals(5, coursecat
::search_courses_count(array('search' => 'test')));
504 // Non-latin language search.
505 $res = coursecat
::search_courses(array('search' => 'Математика'));
506 $this->assertEquals(array($c3->id
, $c6->id
), array_keys($res));
507 $this->assertEquals(2, coursecat
::search_courses_count(array('search' => 'Математика'), array()));
510 public function test_course_contacts() {
512 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'));
513 $managerrole = $DB->get_record('role', array('shortname'=>'manager'));
514 $studentrole = $DB->get_record('role', array('shortname'=>'student'));
515 $oldcoursecontact = $CFG->coursecontact
;
517 $CFG->coursecontact
= $managerrole->id
. ','. $teacherrole->id
;
520 * User is listed in course contacts for the course if he has one of the
521 * "course contact" roles ($CFG->coursecontact) AND is enrolled in the course.
522 * If the user has several roles only the highest is displayed.
527 // == Cat1 (user2 has teacher role)
529 // -- course21 (user2 is enrolled as manager) | [Expected] Manager: F2 L2
530 // -- course22 (user2 is enrolled as student) | [Expected] Teacher: F2 L2
531 // == Cat4 (user2 has manager role)
532 // -- course41 (user4 is enrolled as teacher, user5 is enrolled as manager) | [Expected] Manager: F5 L5, Teacher: F4 L4
533 // -- course42 (user2 is enrolled as teacher) | [Expected] Manager: F2 L2
534 // == Cat3 (user3 has manager role)
535 // -- course31 (user3 is enrolled as student) | [Expected] Manager: F3 L3
536 // -- course32 | [Expected]
537 // -- course11 (user1 is enrolled as teacher) | [Expected] Teacher: F1 L1
538 // -- course12 (user1 has teacher role) | [Expected]
539 // also user4 is enrolled as teacher but enrolment is not active
540 $category = $course = $enrol = $user = array();
541 $category[1] = coursecat
::create(array('name' => 'Cat1'))->id
;
542 $category[2] = coursecat
::create(array('name' => 'Cat2', 'parent' => $category[1]))->id
;
543 $category[3] = coursecat
::create(array('name' => 'Cat3', 'parent' => $category[1]))->id
;
544 $category[4] = coursecat
::create(array('name' => 'Cat4', 'parent' => $category[2]))->id
;
545 foreach (array(1, 2, 3, 4) as $catid) {
546 foreach (array(1, 2) as $courseid) {
547 $course[$catid][$courseid] = $this->getDataGenerator()->create_course(array('idnumber' => 'id'.$catid.$courseid,
548 'category' => $category[$catid]))->id
;
549 $enrol[$catid][$courseid] = $DB->get_record('enrol', array('courseid'=>$course[$catid][$courseid], 'enrol'=>'manual'), '*', MUST_EXIST
);
552 foreach (array(1, 2, 3, 4, 5) as $userid) {
553 $user[$userid] = $this->getDataGenerator()->create_user(array('firstname' => 'F'.$userid, 'lastname' => 'L'.$userid))->id
;
556 $manual = enrol_get_plugin('manual');
558 // Cat1 (user2 has teacher role)
559 role_assign($teacherrole->id
, $user[2], context_coursecat
::instance($category[1]));
560 // course21 (user2 is enrolled as manager)
561 $manual->enrol_user($enrol[2][1], $user[2], $managerrole->id
);
562 // course22 (user2 is enrolled as student)
563 $manual->enrol_user($enrol[2][2], $user[2], $studentrole->id
);
564 // Cat4 (user2 has manager role)
565 role_assign($managerrole->id
, $user[2], context_coursecat
::instance($category[4]));
566 // course41 (user4 is enrolled as teacher, user5 is enrolled as manager)
567 $manual->enrol_user($enrol[4][1], $user[4], $teacherrole->id
);
568 $manual->enrol_user($enrol[4][1], $user[5], $managerrole->id
);
569 // course42 (user2 is enrolled as teacher)
570 $manual->enrol_user($enrol[4][2], $user[2], $teacherrole->id
);
571 // Cat3 (user3 has manager role)
572 role_assign($managerrole->id
, $user[3], context_coursecat
::instance($category[3]));
573 // course31 (user3 is enrolled as student)
574 $manual->enrol_user($enrol[3][1], $user[3], $studentrole->id
);
575 // course11 (user1 is enrolled as teacher)
576 $manual->enrol_user($enrol[1][1], $user[1], $teacherrole->id
);
577 // -- course12 (user1 has teacher role)
578 // also user4 is enrolled as teacher but enrolment is not active
579 role_assign($teacherrole->id
, $user[1], context_course
::instance($course[1][2]));
580 $manual->enrol_user($enrol[1][2], $user[4], $teacherrole->id
, 0, 0, ENROL_USER_SUSPENDED
);
582 $allcourses = coursecat
::get(0)->get_courses(array('recursive' => true, 'coursecontacts' => true, 'sort' => array('idnumber' => 1)));
583 // Simplify the list of contacts for each course (similar as renderer would do).
585 foreach (array(1, 2, 3, 4) as $catid) {
586 foreach (array(1, 2) as $courseid) {
588 foreach ($allcourses[$course[$catid][$courseid]]->get_course_contacts() as $contact) {
589 $tmp[] = $contact['rolename']. ': '. $contact['username'];
591 $contacts[$catid][$courseid] = join(', ', $tmp);
596 // -- course21 (user2 is enrolled as manager) | Manager: F2 L2
597 $this->assertSame('Manager: F2 L2', $contacts[2][1]);
598 // -- course22 (user2 is enrolled as student) | Teacher: F2 L2
599 $this->assertSame('Teacher: F2 L2', $contacts[2][2]);
600 // -- course41 (user4 is enrolled as teacher, user5 is enrolled as manager) | Manager: F5 L5, Teacher: F4 L4
601 $this->assertSame('Manager: F5 L5, Teacher: F4 L4', $contacts[4][1]);
602 // -- course42 (user2 is enrolled as teacher) | [Expected] Manager: F2 L2
603 $this->assertSame('Manager: F2 L2', $contacts[4][2]);
604 // -- course31 (user3 is enrolled as student) | Manager: F3 L3
605 $this->assertSame('Manager: F3 L3', $contacts[3][1]);
607 $this->assertSame('', $contacts[3][2]);
608 // -- course11 (user1 is enrolled as teacher) | Teacher: F1 L1
609 $this->assertSame('Teacher: F1 L1', $contacts[1][1]);
610 // -- course12 (user1 has teacher role) |
611 $this->assertSame('', $contacts[1][2]);
613 $CFG->coursecontact
= $oldcoursecontact;
616 public function test_overview_files() {
618 $this->setAdminUser();
619 $cat1 = coursecat
::create(array('name' => 'Cat1'));
621 // Create course c1 with one image file.
622 $dratid1 = $this->fill_draft_area(array('filename.jpg' => 'Test file contents1'));
623 $c1 = $this->getDataGenerator()->create_course(array('category' => $cat1->id
,
624 'fullname' => 'Test 1', 'overviewfiles_filemanager' => $dratid1));
625 // Create course c2 with two image files (only one file will be added because of settings).
626 $dratid2 = $this->fill_draft_area(array('filename21.jpg' => 'Test file contents21', 'filename22.jpg' => 'Test file contents22'));
627 $c2 = $this->getDataGenerator()->create_course(array('category' => $cat1->id
,
628 'fullname' => 'Test 2', 'overviewfiles_filemanager' => $dratid2));
629 // Create course c3 without files.
630 $c3 = $this->getDataGenerator()->create_course(array('category' => $cat1->id
, 'fullname' => 'Test 3'));
632 // Change the settings to allow multiple files of any types.
633 $CFG->courseoverviewfileslimit
= 3;
634 $CFG->courseoverviewfilesext
= '*';
635 // Create course c5 with two image files.
636 $dratid4 = $this->fill_draft_area(array('filename41.jpg' => 'Test file contents41', 'filename42.jpg' => 'Test file contents42'));
637 $c4 = $this->getDataGenerator()->create_course(array('category' => $cat1->id
,
638 'fullname' => 'Test 4', 'overviewfiles_filemanager' => $dratid4));
639 // Create course c6 with non-image file.
640 $dratid5 = $this->fill_draft_area(array('filename51.zip' => 'Test file contents51'));
641 $c5 = $this->getDataGenerator()->create_course(array('category' => $cat1->id
,
642 'fullname' => 'Test 5', 'overviewfiles_filemanager' => $dratid5));
644 // Reset default settings.
645 $CFG->courseoverviewfileslimit
= 1;
646 $CFG->courseoverviewfilesext
= '.jpg,.gif,.png';
648 $courses = $cat1->get_courses();
649 $this->assertTrue($courses[$c1->id
]->has_course_overviewfiles());
650 $this->assertTrue($courses[$c2->id
]->has_course_overviewfiles());
651 $this->assertFalse($courses[$c3->id
]->has_course_overviewfiles());
652 $this->assertTrue($courses[$c4->id
]->has_course_overviewfiles());
653 $this->assertTrue($courses[$c5->id
]->has_course_overviewfiles()); // Does not validate the filetypes.
655 $this->assertEquals(1, count($courses[$c1->id
]->get_course_overviewfiles()));
656 $this->assertEquals(1, count($courses[$c2->id
]->get_course_overviewfiles()));
657 $this->assertEquals(0, count($courses[$c3->id
]->get_course_overviewfiles()));
658 $this->assertEquals(1, count($courses[$c4->id
]->get_course_overviewfiles()));
659 $this->assertEquals(0, count($courses[$c5->id
]->get_course_overviewfiles())); // Validate the filetypes.
661 // Overview files are not allowed, all functions return empty values.
662 $CFG->courseoverviewfileslimit
= 0;
664 $this->assertFalse($courses[$c1->id
]->has_course_overviewfiles());
665 $this->assertFalse($courses[$c2->id
]->has_course_overviewfiles());
666 $this->assertFalse($courses[$c3->id
]->has_course_overviewfiles());
667 $this->assertFalse($courses[$c4->id
]->has_course_overviewfiles());
668 $this->assertFalse($courses[$c5->id
]->has_course_overviewfiles());
670 $this->assertEquals(0, count($courses[$c1->id
]->get_course_overviewfiles()));
671 $this->assertEquals(0, count($courses[$c2->id
]->get_course_overviewfiles()));
672 $this->assertEquals(0, count($courses[$c3->id
]->get_course_overviewfiles()));
673 $this->assertEquals(0, count($courses[$c4->id
]->get_course_overviewfiles()));
674 $this->assertEquals(0, count($courses[$c5->id
]->get_course_overviewfiles()));
676 // Multiple overview files are allowed but still limited to images.
677 $CFG->courseoverviewfileslimit
= 3;
679 $this->assertTrue($courses[$c1->id
]->has_course_overviewfiles());
680 $this->assertTrue($courses[$c2->id
]->has_course_overviewfiles());
681 $this->assertFalse($courses[$c3->id
]->has_course_overviewfiles());
682 $this->assertTrue($courses[$c4->id
]->has_course_overviewfiles());
683 $this->assertTrue($courses[$c5->id
]->has_course_overviewfiles()); // Still does not validate the filetypes.
685 $this->assertEquals(1, count($courses[$c1->id
]->get_course_overviewfiles()));
686 $this->assertEquals(1, count($courses[$c2->id
]->get_course_overviewfiles())); // Only 1 file was actually added.
687 $this->assertEquals(0, count($courses[$c3->id
]->get_course_overviewfiles()));
688 $this->assertEquals(2, count($courses[$c4->id
]->get_course_overviewfiles()));
689 $this->assertEquals(0, count($courses[$c5->id
]->get_course_overviewfiles()));
691 // Multiple overview files of any type are allowed.
692 $CFG->courseoverviewfilesext
= '*';
694 $this->assertTrue($courses[$c1->id
]->has_course_overviewfiles());
695 $this->assertTrue($courses[$c2->id
]->has_course_overviewfiles());
696 $this->assertFalse($courses[$c3->id
]->has_course_overviewfiles());
697 $this->assertTrue($courses[$c4->id
]->has_course_overviewfiles());
698 $this->assertTrue($courses[$c5->id
]->has_course_overviewfiles());
700 $this->assertEquals(1, count($courses[$c1->id
]->get_course_overviewfiles()));
701 $this->assertEquals(1, count($courses[$c2->id
]->get_course_overviewfiles()));
702 $this->assertEquals(0, count($courses[$c3->id
]->get_course_overviewfiles()));
703 $this->assertEquals(2, count($courses[$c4->id
]->get_course_overviewfiles()));
704 $this->assertEquals(1, count($courses[$c5->id
]->get_course_overviewfiles()));
708 * Creates a draft area for current user and fills it with fake files
710 * @param array $files array of files that need to be added to filearea, filename => filecontents
711 * @return int draftid for the filearea
713 protected function fill_draft_area(array $files) {
715 $usercontext = context_user
::instance($USER->id
);
716 $draftid = file_get_unused_draft_itemid();
717 foreach ($files as $filename => $filecontents) {
718 // Add actual file there.
719 $filerecord = array('component' => 'user', 'filearea' => 'draft',
720 'contextid' => $usercontext->id
, 'itemid' => $draftid,
721 'filename' => $filename, 'filepath' => '/');
722 $fs = get_file_storage();
723 $fs->create_file_from_string($filerecord, $filecontents);