Automatic installer lang files (20100904)
[moodle.git] / lib / simpletest / testconditionlib.php
blobda837f9214ca4e42a30de96b65fc5f9f6fd7dfec
1 <?php
2 if (!defined('MOODLE_INTERNAL')) {
3 die('Direct access to this script is forbidden.');
6 require_once($CFG->dirroot . '/lib/conditionlib.php');
8 class conditionlib_test extends UnitTestCaseUsingDatabase {
9 public static $includecoverage = array('lib/conditionlib.php');
11 public $conditionlib_tables = array(
12 'lib' => array(
13 'context', 'capabilities', 'role',
14 'role_capabilities', 'role_assignments',
15 'course_categories', 'course',
16 'modules',
17 'course_sections', 'course_modules',
18 'course_modules_availability',
19 'course_modules_completion',
20 'grade_items', 'grade_grades'),
21 'mod/resource' => array(
22 'resource'));
23 public $oldcfg;
25 public function setUp() {
26 global $CFG;
27 parent::setUp();
28 $this->oldcfg=clone $CFG;
29 $CFG->enableavailability=true;
30 $CFG->enablecompletion=true;
32 $this->switch_to_test_db(); // All operations until end of test method will happen in test DB
34 foreach ($this->conditionlib_tables as $dir => $tables) {
35 $this->create_test_tables($tables, $dir); // Create tables
37 $this->fill_records(); // Add common stuff needed by various test methods
40 /**
41 * Method called after each test method. Doesn't do anything extraordinary except restore the global $DB to the real one.
43 public function tearDown() {
44 global $CFG;
45 $CFG->enableavailability=$this->oldcfg->enableavailability;
46 $CFG->enablecompletion=$this->oldcfg->enablecompletion;
47 parent::tearDown(); // All the test tables created in setUp will be dropped by this
50 private function fill_records() {
51 global $DB;
53 // We need the resource modules record available
54 $DB->insert_record('modules', (object)array('name' => 'resource'));
56 // We (get_fast_modinfo) need some capabilities present
57 $DB->insert_record('capabilities', (object)array('name' => 'moodle/course:viewhiddenactivities',
58 'contextlevel' => CONTEXT_COURSE));
61 function test_constructor() {
62 global $DB,$CFG;
63 $cm=new stdClass;
65 // Test records
66 $id=$DB->insert_record('course_modules',(object)array(
67 'showavailability'=>1,'availablefrom'=>17,'availableuntil'=>398,'course'=>64));
69 // no ID
70 try {
71 $test=new condition_info($cm);
72 $this->fail();
73 } catch(coding_exception $e) {
76 // no other data
77 $cm->id=$id;
78 $test=new condition_info($cm,CONDITION_MISSING_EVERYTHING);
79 $this->assertEqual(
80 (object)array('id'=>$id,'showavailability'=>1,
81 'availablefrom'=>17,'availableuntil'=>398,'course'=>64,
82 'conditionsgrade'=>array(), 'conditionscompletion'=>array()),
83 $test->get_full_course_module());
85 // just the course_modules stuff; check it doesn't request that from db
86 $cm->showavailability=0;
87 $cm->availablefrom=2;
88 $cm->availableuntil=74;
89 $cm->course=38;
90 $test=new condition_info($cm,CONDITION_MISSING_EXTRATABLE);
91 $this->assertEqual(
92 (object)array('id'=>$id,'showavailability'=>0,
93 'availablefrom'=>2,'availableuntil'=>74,'course'=>38,
94 'conditionsgrade'=>array(), 'conditionscompletion'=>array()),
95 $test->get_full_course_module());
97 // Now let's add some actual grade/completion conditions
98 $DB->insert_record('course_modules_availability',(object)array(
99 'coursemoduleid'=>$id,
100 'sourcecmid'=>42,
101 'requiredcompletion'=>2
103 $DB->insert_record('course_modules_availability',(object)array(
104 'coursemoduleid'=>$id,
105 'sourcecmid'=>666,
106 'requiredcompletion'=>1
108 $DB->insert_record('course_modules_availability',(object)array(
109 'coursemoduleid'=>$id,
110 'gradeitemid'=>37,
111 'grademin'=>5.5
114 $cm=(object)array('id'=>$id);
115 $test=new condition_info($cm,CONDITION_MISSING_EVERYTHING);
116 $fullcm=$test->get_full_course_module();
117 $this->assertEqual(array(42=>2,666=>1),$fullcm->conditionscompletion);
118 $this->assertEqual(array(37=>(object)array('min'=>5.5,'max'=>null,'name'=>'!missing')),
119 $fullcm->conditionsgrade);
122 private function make_course() {
123 global $DB;
124 $categoryid=$DB->insert_record('course_categories',(object)array('name'=>'conditionlibtest'));
125 return $DB->insert_record('course',(object)array(
126 'fullname'=>'Condition test','shortname'=>'CT1',
127 'category'=>$categoryid,'enablecompletion'=>1));
130 private function make_course_module($courseid,$params=array()) {
131 global $DB;
132 static $moduleid=0;
133 if(!$moduleid) {
134 $moduleid=$DB->get_field('modules','id',array('name'=>'resource'));
137 $rid=$DB->insert_record('resource',(object)array('course'=>$courseid,
138 'name'=>'xxx','alltext'=>'','popup'=>''));
139 $settings=(object)array(
140 'course'=>$courseid,'module'=>$moduleid,'instance'=>$rid);
141 foreach($params as $name=>$value) {
142 $settings->{$name}=$value;
144 return $DB->insert_record('course_modules',$settings);
147 private function make_section($courseid,$cmids,$sectionnum=0) {
148 global $DB;
149 $DB->insert_record('course_sections',(object)array(
150 'course'=>$courseid,'sequence'=>implode(',',$cmids),'section'=>$sectionnum));
153 function test_modinfo() {
154 global $DB;
156 // Let's make a course
157 $courseid=$this->make_course();
159 // Now let's make a couple modules on that course
160 $cmid1=$this->make_course_module($courseid,array(
161 'showavailability'=>1,'availablefrom'=>17,'availableuntil'=>398,
162 'completion'=>COMPLETION_TRACKING_MANUAL));
163 $cmid2=$this->make_course_module($courseid,array(
164 'showavailability'=>0,'availablefrom'=>0,'availableuntil'=>0));
165 $this->make_section($courseid,array($cmid1,$cmid2));
167 // Add a fake grade item
168 $gradeitemid=$DB->insert_record('grade_items',(object)array(
169 'courseid'=>$courseid,'itemname'=>'frog'));
171 // One of the modules has grade and completion conditions, other doesn't
172 $DB->insert_record('course_modules_availability',(object)array(
173 'coursemoduleid'=>$cmid2,
174 'sourcecmid'=>$cmid1,
175 'requiredcompletion'=>1
177 $DB->insert_record('course_modules_availability',(object)array(
178 'coursemoduleid'=>$cmid2,
179 'gradeitemid'=>$gradeitemid,
180 'grademin'=>5.5
183 // Okay sweet, now get modinfo
184 $modinfo=get_fast_modinfo($DB->get_record('course',array('id'=>$courseid)));
186 // Test basic data
187 $this->assertEqual(1,$modinfo->cms[$cmid1]->showavailability);
188 $this->assertEqual(17,$modinfo->cms[$cmid1]->availablefrom);
189 $this->assertEqual(398,$modinfo->cms[$cmid1]->availableuntil);
190 $this->assertEqual(0,$modinfo->cms[$cmid2]->showavailability);
191 $this->assertEqual(0,$modinfo->cms[$cmid2]->availablefrom);
192 $this->assertEqual(0,$modinfo->cms[$cmid2]->availableuntil);
194 // Test condition arrays
195 $this->assertEqual(array(),$modinfo->cms[$cmid1]->conditionscompletion);
196 $this->assertEqual(array(),$modinfo->cms[$cmid1]->conditionsgrade);
197 $this->assertEqual(array($cmid1=>1),
198 $modinfo->cms[$cmid2]->conditionscompletion);
199 $this->assertEqual(array($gradeitemid=>(object)array('min'=>5.5,'max'=>null,'name'=>'frog')),
200 $modinfo->cms[$cmid2]->conditionsgrade);
203 function test_add_and_remove() {
204 global $DB;
205 // Make course and module
206 $courseid=$this->make_course();
207 $cmid=$this->make_course_module($courseid,array(
208 'showavailability'=>0,'availablefrom'=>0,'availableuntil'=>0));
209 $this->make_section($courseid,array($cmid));
211 // Check it has no conditions
212 $test1=new condition_info((object)array('id'=>$cmid),
213 CONDITION_MISSING_EVERYTHING);
214 $cm=$test1->get_full_course_module();
215 $this->assertEqual(array(),$cm->conditionscompletion);
216 $this->assertEqual(array(),$cm->conditionsgrade);
218 // Add conditions of each type
219 $test1->add_completion_condition(13,3);
220 $this->assertEqual(array(13=>3),$cm->conditionscompletion);
221 $test1->add_grade_condition(666,0.4,null,true);
222 $this->assertEqual(array(666=>(object)array('min'=>0.4,'max'=>null,'name'=>'!missing')),
223 $cm->conditionsgrade);
225 // Check they were really added in db
226 $test2=new condition_info((object)array('id'=>$cmid),
227 CONDITION_MISSING_EVERYTHING);
228 $cm=$test2->get_full_course_module();
229 $this->assertEqual(array(13=>3),$cm->conditionscompletion);
230 $this->assertEqual(array(666=>(object)array('min'=>0.4,'max'=>null,'name'=>'!missing')),
231 $cm->conditionsgrade);
233 // Wipe conditions
234 $test2->wipe_conditions();
235 $this->assertEqual(array(),$cm->conditionscompletion);
236 $this->assertEqual(array(),$cm->conditionsgrade);
238 // Check they were really wiped
239 $test3=new condition_info((object)array('id'=>$cmid),
240 CONDITION_MISSING_EVERYTHING);
241 $cm=$test3->get_full_course_module();
242 $this->assertEqual(array(),$cm->conditionscompletion);
243 $this->assertEqual(array(),$cm->conditionsgrade);
246 function test_is_available() {
247 global $DB,$USER;
248 $courseid=$this->make_course();
250 // No conditions
251 $cmid=$this->make_course_module($courseid);
252 $ci=new condition_info((object)array('id'=>$cmid),
253 CONDITION_MISSING_EVERYTHING);
254 $this->assertTrue($ci->is_available($text,false,0));
255 $this->assertEqual('',$text);
257 // Time (from)
258 $time=time()+100;
259 $cmid=$this->make_course_module($courseid,array('availablefrom'=>$time));
260 $ci=new condition_info((object)array('id'=>$cmid),
261 CONDITION_MISSING_EVERYTHING);
262 $this->assertFalse($ci->is_available($text));
263 $this->assert(new PatternExpectation(
264 '/'.preg_quote(userdate($time,get_string('strftimedate','langconfig'))).'/'),$text);
266 $time=time()-100;
267 $cmid=$this->make_course_module($courseid,array('availablefrom'=>$time));
268 $ci=new condition_info((object)array('id'=>$cmid),
269 CONDITION_MISSING_EVERYTHING);
270 $this->assertTrue($ci->is_available($text));
271 $this->assertEqual('',$text);
272 $this->assert(new PatternExpectation(
273 '/'.preg_quote(userdate($time,get_string('strftimedate','langconfig'))).'/'),$ci->get_full_information());
275 // Time (until)
276 $cmid=$this->make_course_module($courseid,array('availableuntil'=>time()-100));
277 $ci=new condition_info((object)array('id'=>$cmid),
278 CONDITION_MISSING_EVERYTHING);
279 $this->assertFalse($ci->is_available($text));
280 $this->assertEqual('',$text);
282 // Completion
283 $oldid=$cmid;
284 $cmid=$this->make_course_module($courseid);
285 $this->make_section($courseid,array($oldid,$cmid));
286 $oldcm=$DB->get_record('course_modules',array('id'=>$oldid));
287 $oldcm->completion=COMPLETION_TRACKING_MANUAL;
288 $DB->update_record('course_modules',$oldcm);
290 $ci=new condition_info((object)array('id'=>$cmid),CONDITION_MISSING_EVERYTHING);
291 $ci->add_completion_condition($oldid,COMPLETION_COMPLETE);
292 $this->assertFalse($ci->is_available($text,false));
293 $this->assertEqual(get_string('requires_completion_1','condition','xxx'),$text);
295 $completion=new completion_info($DB->get_record('course',array('id'=>$courseid)));
296 $completion->update_state($oldcm,COMPLETION_COMPLETE);
297 completion_info::wipe_session_cache();
298 condition_info::wipe_session_cache();
300 $this->assertTrue($ci->is_available($text));
301 $this->assertFalse($ci->is_available($text,false,$USER->id+1));
302 completion_info::wipe_session_cache();
303 condition_info::wipe_session_cache();
304 $completion=new completion_info($DB->get_record('course',array('id'=>$courseid)));
305 $completion->update_state($oldcm,COMPLETION_INCOMPLETE);
306 $this->assertFalse($ci->is_available($text));
308 $ci->wipe_conditions();
309 $ci->add_completion_condition($oldid,COMPLETION_INCOMPLETE);
310 condition_info::wipe_session_cache();
311 $this->assertTrue($ci->is_available($text));
312 $this->assertTrue($ci->is_available($text,false,$USER->id+1));
314 condition_info::wipe_session_cache();
315 $this->assertTrue($ci->is_available($text,true));
317 // Grade
318 $ci->wipe_conditions();
319 // Add a fake grade item
320 $gradeitemid=$DB->insert_record('grade_items',(object)array(
321 'courseid'=>$courseid,'itemname'=>'frog'));
322 // Add a condition on a value existing...
323 $ci->add_grade_condition($gradeitemid,null,null,true);
324 $this->assertFalse($ci->is_available($text));
325 $this->assertEqual(get_string('requires_grade_any','condition','frog'),$text);
327 // Fake it existing
328 $DB->insert_record('grade_grades',(object)array(
329 'itemid'=>$gradeitemid,'userid'=>$USER->id,'finalgrade'=>3.78));
330 condition_info::wipe_session_cache();
331 $this->assertTrue($ci->is_available($text));
333 condition_info::wipe_session_cache();
334 $this->assertTrue($ci->is_available($text,true));
336 // Now require that user gets more than 3.78001
337 $ci->wipe_conditions();
338 $ci->add_grade_condition($gradeitemid,3.78001,null,true);
339 condition_info::wipe_session_cache();
340 $this->assertFalse($ci->is_available($text));
341 $this->assertEqual(get_string('requires_grade_min','condition','frog'),$text);
343 // ...just on 3.78...
344 $ci->wipe_conditions();
345 $ci->add_grade_condition($gradeitemid,3.78,null,true);
346 condition_info::wipe_session_cache();
347 $this->assertTrue($ci->is_available($text));
349 // ...less than 3.78
350 $ci->wipe_conditions();
351 $ci->add_grade_condition($gradeitemid,null,3.78,true);
352 condition_info::wipe_session_cache();
353 $this->assertFalse($ci->is_available($text));
354 $this->assertEqual(get_string('requires_grade_max','condition','frog'),$text);
356 // ...less than 3.78001
357 $ci->wipe_conditions();
358 $ci->add_grade_condition($gradeitemid,null,3.78001,true);
359 condition_info::wipe_session_cache();
360 $this->assertTrue($ci->is_available($text));
362 // ...in a range that includes it
363 $ci->wipe_conditions();
364 $ci->add_grade_condition($gradeitemid,3,4,true);
365 condition_info::wipe_session_cache();
366 $this->assertTrue($ci->is_available($text));
368 // ...in a range that doesn't include it
369 $ci->wipe_conditions();
370 $ci->add_grade_condition($gradeitemid,4,5,true);
371 condition_info::wipe_session_cache();
372 $this->assertFalse($ci->is_available($text));
373 $this->assertEqual(get_string('requires_grade_range','condition','frog'),$text);