MDL-35339 Better cache reset for get_fast_modinfo(), allow exec get_fast_modinfo...
[moodle.git] / course / tests / courselib_test.php
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/>.
17 /**
18  * Course related unit tests
19  *
20  * @package    core
21  * @category   phpunit
22  * @copyright  2012 Petr Skoda {@link http://skodak.org}
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
29 require_once($CFG->dirroot.'/course/lib.php');
31 class courselib_testcase extends advanced_testcase {
33     public function test_create_course() {
34         global $DB;
35         $this->resetAfterTest(true);
36         $defaultcategory = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
38         $course = new stdClass();
39         $course->fullname = 'Apu loves Unit Təsts';
40         $course->shortname = 'Spread the lŭve';
41         $course->idnumber = '123';
42         $course->summary = 'Awesome!';
43         $course->summaryformat = FORMAT_PLAIN;
44         $course->format = 'topics';
45         $course->newsitems = 0;
46         $course->numsections = 5;
47         $course->category = $defaultcategory;
49         $created = create_course($course);
50         $context = context_course::instance($created->id);
52         // Compare original and created.
53         $original = (array) $course;
54         $this->assertEquals($original, array_intersect_key((array) $created, $original));
56         // Ensure default section is created.
57         $sectioncreated = $DB->record_exists('course_sections', array('course' => $created->id, 'section' => 0));
58         $this->assertTrue($sectioncreated);
60         // Ensure blocks have been associated to the course.
61         $blockcount = $DB->count_records('block_instances', array('parentcontextid' => $context->id));
62         $this->assertGreaterThan(0, $blockcount);
63     }
65     public function test_create_course_with_generator() {
66         global $DB;
67         $this->resetAfterTest(true);
68         $course = $this->getDataGenerator()->create_course();
70         // Ensure default section is created.
71         $sectioncreated = $DB->record_exists('course_sections', array('course' => $course->id, 'section' => 0));
72         $this->assertTrue($sectioncreated);
73     }
75     public function test_create_course_sections() {
76         global $DB;
77         $this->resetAfterTest(true);
79         $course = $this->getDataGenerator()->create_course(
80                 array('shortname' => 'GrowingCourse',
81                     'fullname' => 'Growing Course',
82                     'numsections' => 5),
83                 array('createsections' => true));
85         // Ensure all 6 (0-5) sections were created and modinfo/sectioninfo cache works properly
86         $sectionscreated = array_keys(get_fast_modinfo($course)->get_section_info_all());
87         $this->assertEquals(range(0, $course->numsections), $sectionscreated);
89         // this will do nothing, section already exists
90         $this->assertFalse(course_create_sections_if_missing($course, $course->numsections));
92         // this will create new section
93         $this->assertTrue(course_create_sections_if_missing($course, $course->numsections + 1));
95         // Ensure all 7 (0-6) sections were created and modinfo/sectioninfo cache works properly
96         $sectionscreated = array_keys(get_fast_modinfo($course)->get_section_info_all());
97         $this->assertEquals(range(0, $course->numsections + 1), $sectionscreated);
98     }
100     public function test_reorder_sections() {
101         global $DB;
102         $this->resetAfterTest(true);
104         $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections'=>true));
105         $course = $this->getDataGenerator()->create_course(array('numsections'=>10), array('createsections'=>true));
106         $oldsections = array();
107         $sections = array();
108         foreach ($DB->get_records('course_sections', array('course'=>$course->id), 'id') as $section) {
109             $oldsections[$section->section] = $section->id;
110             $sections[$section->id] = $section->section;
111         }
112         ksort($oldsections);
114         $neworder = reorder_sections($sections, 2, 4);
115         $neworder = array_keys($neworder);
116         $this->assertEquals($oldsections[0], $neworder[0]);
117         $this->assertEquals($oldsections[1], $neworder[1]);
118         $this->assertEquals($oldsections[2], $neworder[4]);
119         $this->assertEquals($oldsections[3], $neworder[2]);
120         $this->assertEquals($oldsections[4], $neworder[3]);
121         $this->assertEquals($oldsections[5], $neworder[5]);
122         $this->assertEquals($oldsections[6], $neworder[6]);
124         $neworder = reorder_sections($sections, 4, 2);
125         $neworder = array_keys($neworder);
126         $this->assertEquals($oldsections[0], $neworder[0]);
127         $this->assertEquals($oldsections[1], $neworder[1]);
128         $this->assertEquals($oldsections[2], $neworder[3]);
129         $this->assertEquals($oldsections[3], $neworder[4]);
130         $this->assertEquals($oldsections[4], $neworder[2]);
131         $this->assertEquals($oldsections[5], $neworder[5]);
132         $this->assertEquals($oldsections[6], $neworder[6]);
134         $neworder = reorder_sections(1, 2, 4);
135         $this->assertFalse($neworder);
136     }
138     public function test_move_section_down() {
139         global $DB;
140         $this->resetAfterTest(true);
142         $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections'=>true));
143         $course = $this->getDataGenerator()->create_course(array('numsections'=>10), array('createsections'=>true));
144         $oldsections = array();
145         foreach ($DB->get_records('course_sections', array('course'=>$course->id)) as $section) {
146             $oldsections[$section->section] = $section->id;
147         }
148         ksort($oldsections);
150         // Test move section down..
151         move_section_to($course, 2, 4);
152         $sections = array();
153         foreach ($DB->get_records('course_sections', array('course'=>$course->id)) as $section) {
154             $sections[$section->section] = $section->id;
155         }
156         ksort($sections);
158         $this->assertEquals($oldsections[0], $sections[0]);
159         $this->assertEquals($oldsections[1], $sections[1]);
160         $this->assertEquals($oldsections[2], $sections[4]);
161         $this->assertEquals($oldsections[3], $sections[2]);
162         $this->assertEquals($oldsections[4], $sections[3]);
163         $this->assertEquals($oldsections[5], $sections[5]);
164         $this->assertEquals($oldsections[6], $sections[6]);
165     }
167     public function test_move_section_up() {
168         global $DB;
169         $this->resetAfterTest(true);
171         $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections'=>true));
172         $course = $this->getDataGenerator()->create_course(array('numsections'=>10), array('createsections'=>true));
173         $oldsections = array();
174         foreach ($DB->get_records('course_sections', array('course'=>$course->id)) as $section) {
175             $oldsections[$section->section] = $section->id;
176         }
177         ksort($oldsections);
179         // Test move section up..
180         move_section_to($course, 6, 4);
181         $sections = array();
182         foreach ($DB->get_records('course_sections', array('course'=>$course->id)) as $section) {
183             $sections[$section->section] = $section->id;
184         }
185         ksort($sections);
187         $this->assertEquals($oldsections[0], $sections[0]);
188         $this->assertEquals($oldsections[1], $sections[1]);
189         $this->assertEquals($oldsections[2], $sections[2]);
190         $this->assertEquals($oldsections[3], $sections[3]);
191         $this->assertEquals($oldsections[4], $sections[5]);
192         $this->assertEquals($oldsections[5], $sections[6]);
193         $this->assertEquals($oldsections[6], $sections[4]);
194     }
196     public function test_move_section_marker() {
197         global $DB;
198         $this->resetAfterTest(true);
200         $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections'=>true));
201         $course = $this->getDataGenerator()->create_course(array('numsections'=>10), array('createsections'=>true));
203         // Set course marker to the section we are going to move..
204         course_set_marker($course->id, 2);
205         // Verify that the course marker is set correctly.
206         $course = $DB->get_record('course', array('id' => $course->id));
207         $this->assertEquals(2, $course->marker);
209         // Test move the marked section down..
210         move_section_to($course, 2, 4);
212         // Verify that the coruse marker has been moved along with the section..
213         $course = $DB->get_record('course', array('id' => $course->id));
214         $this->assertEquals(4, $course->marker);
216         // Test move the marked section up..
217         move_section_to($course, 4, 3);
219         // Verify that the course marker has been moved along with the section..
220         $course = $DB->get_record('course', array('id' => $course->id));
221         $this->assertEquals(3, $course->marker);
223         // Test moving a non-marked section above the marked section..
224         move_section_to($course, 4, 2);
226         // Verify that the course marker has been moved down to accomodate..
227         $course = $DB->get_record('course', array('id' => $course->id));
228         $this->assertEquals(4, $course->marker);
230         // Test moving a non-marked section below the marked section..
231         move_section_to($course, 3, 6);
233         // Verify that the course marker has been up to accomodate..
234         $course = $DB->get_record('course', array('id' => $course->id));
235         $this->assertEquals(3, $course->marker);
236     }
238     public function test_get_course_display_name_for_list() {
239         global $CFG;
240         $this->resetAfterTest(true);
242         $course = $this->getDataGenerator()->create_course(array('shortname' => 'FROG101', 'fullname' => 'Introduction to pond life'));
244         $CFG->courselistshortnames = 0;
245         $this->assertEquals('Introduction to pond life', get_course_display_name_for_list($course));
247         $CFG->courselistshortnames = 1;
248         $this->assertEquals('FROG101 Introduction to pond life', get_course_display_name_for_list($course));
249     }
251     public function test_create_course_category() {
252         global $CFG, $DB;
253         $this->resetAfterTest(true);
255         // Create the category
256         $data = new stdClass();
257         $data->name = 'aaa';
258         $data->description = 'aaa';
259         $data->idnumber = '';
261         $category1 = create_course_category($data);
263         // Initially confirm that base data was inserted correctly
264         $this->assertEquals($data->name, $category1->name);
265         $this->assertEquals($data->description, $category1->description);
266         $this->assertEquals($data->idnumber, $category1->idnumber);
268         // sortorder should be blank initially
269         $this->assertEmpty($category1->sortorder);
271         // Calling fix_course_sortorder() should provide a new sortorder
272         fix_course_sortorder();
273         $category1 = $DB->get_record('course_categories', array('id' => $category1->id));
275         $this->assertGreaterThanOrEqual(1, $category1->sortorder);
277         // Create two more categories and test the sortorder worked correctly
278         $data->name = 'ccc';
279         $category2 = create_course_category($data);
280         $this->assertEmpty($category2->sortorder);
282         $data->name = 'bbb';
283         $category3 = create_course_category($data);
284         $this->assertEmpty($category3->sortorder);
286         // Calling fix_course_sortorder() should provide a new sortorder to give category1,
287         // category2, category3. New course categories are ordered by id not name
288         fix_course_sortorder();
290         $category1 = $DB->get_record('course_categories', array('id' => $category1->id));
291         $category2 = $DB->get_record('course_categories', array('id' => $category2->id));
292         $category3 = $DB->get_record('course_categories', array('id' => $category3->id));
294         $this->assertGreaterThanOrEqual($category1->sortorder, $category2->sortorder);
295         $this->assertGreaterThanOrEqual($category2->sortorder, $category3->sortorder);
296         $this->assertGreaterThanOrEqual($category1->sortorder, $category3->sortorder);
297     }
299     public function test_move_module_in_course() {
300         $this->resetAfterTest(true);
301         // Setup fixture
302         $course = $this->getDataGenerator()->create_course(array('numsections'=>5));
303         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
305         $cms = get_fast_modinfo($course)->get_cms();
306         $cm = reset($cms);
308         course_create_sections_if_missing($course, 3);
309         $section3 = get_fast_modinfo($course)->get_section_info(3);
311         moveto_module($cm, $section3);
313         $modinfo = get_fast_modinfo($course);
314         $this->assertTrue(empty($modinfo->sections[0]));
315         $this->assertFalse(empty($modinfo->sections[3]));
316     }