|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 if (!defined('MOODLE_INTERNAL')) { 00003 die('Direct access to this script is forbidden.'); 00004 } 00005 00006 require_once($CFG->dirroot . '/lib/conditionlib.php'); 00007 00008 class conditionlib_test extends UnitTestCaseUsingDatabase { 00009 public static $includecoverage = array('lib/conditionlib.php'); 00010 00011 public $conditionlib_tables = array( 00012 'lib' => array( 00013 'files','context', 'capabilities', 'role', 00014 'role_capabilities', 'role_assignments', 00015 'course_categories', 'course', 00016 'modules', 00017 'course_sections', 'course_modules', 00018 'course_modules_availability', 00019 'course_modules_completion', 00020 'grade_items', 'grade_grades'), 00021 'mod/resource' => array( 00022 'resource')); 00023 public $oldcfg; 00024 00025 public function setUp() { 00026 global $CFG; 00027 parent::setUp(); 00028 $this->oldcfg=clone $CFG; 00029 $CFG->enableavailability=true; 00030 $CFG->enablecompletion=true; 00031 00032 $this->switch_to_test_db(); // All operations until end of test method will happen in test DB 00033 00034 foreach ($this->conditionlib_tables as $dir => $tables) { 00035 $this->create_test_tables($tables, $dir); // Create tables 00036 } 00037 $this->fill_records(); // Add common stuff needed by various test methods 00038 } 00039 00043 public function tearDown() { 00044 global $CFG; 00045 $CFG->enableavailability=$this->oldcfg->enableavailability; 00046 $CFG->enablecompletion=$this->oldcfg->enablecompletion; 00047 parent::tearDown(); // All the test tables created in setUp will be dropped by this 00048 } 00049 00050 private function fill_records() { 00051 global $DB; 00052 00053 // We need the resource modules record available 00054 $DB->insert_record('modules', (object)array('name' => 'resource')); 00055 00056 // We (get_fast_modinfo) need some capabilities present 00057 $DB->insert_record('capabilities', (object)array('name' => 'moodle/course:viewhiddenactivities', 00058 'contextlevel' => CONTEXT_COURSE)); 00059 } 00060 00061 function test_constructor() { 00062 global $DB,$CFG; 00063 $cm=new stdClass; 00064 00065 // Test records 00066 $id=$DB->insert_record('course_modules',(object)array( 00067 'showavailability'=>1,'availablefrom'=>17,'availableuntil'=>398,'course'=>64)); 00068 00069 // no ID 00070 try { 00071 $test=new condition_info($cm); 00072 $this->fail(); 00073 } catch(coding_exception $e) { 00074 } 00075 00076 // no other data 00077 $cm->id=$id; 00078 $test=new condition_info($cm,CONDITION_MISSING_EVERYTHING); 00079 $this->assertEqual( 00080 (object)array('id'=>$id,'showavailability'=>1, 00081 'availablefrom'=>17,'availableuntil'=>398,'course'=>64, 00082 'conditionsgrade'=>array(), 'conditionscompletion'=>array()), 00083 $test->get_full_course_module()); 00084 00085 // just the course_modules stuff; check it doesn't request that from db 00086 $cm->showavailability=0; 00087 $cm->availablefrom=2; 00088 $cm->availableuntil=74; 00089 $cm->course=38; 00090 $test=new condition_info($cm,CONDITION_MISSING_EXTRATABLE); 00091 $this->assertEqual( 00092 (object)array('id'=>$id,'showavailability'=>0, 00093 'availablefrom'=>2,'availableuntil'=>74,'course'=>38, 00094 'conditionsgrade'=>array(), 'conditionscompletion'=>array()), 00095 $test->get_full_course_module()); 00096 00097 // Now let's add some actual grade/completion conditions 00098 $DB->insert_record('course_modules_availability',(object)array( 00099 'coursemoduleid'=>$id, 00100 'sourcecmid'=>42, 00101 'requiredcompletion'=>2 00102 )); 00103 $DB->insert_record('course_modules_availability',(object)array( 00104 'coursemoduleid'=>$id, 00105 'sourcecmid'=>666, 00106 'requiredcompletion'=>1 00107 )); 00108 $DB->insert_record('course_modules_availability',(object)array( 00109 'coursemoduleid'=>$id, 00110 'gradeitemid'=>37, 00111 'grademin'=>5.5 00112 )); 00113 00114 $cm=(object)array('id'=>$id); 00115 $test=new condition_info($cm,CONDITION_MISSING_EVERYTHING); 00116 $fullcm=$test->get_full_course_module(); 00117 $this->assertEqual(array(42=>2,666=>1),$fullcm->conditionscompletion); 00118 $this->assertEqual(array(37=>(object)array('min'=>5.5,'max'=>null,'name'=>'!missing')), 00119 $fullcm->conditionsgrade); 00120 } 00121 00122 private function make_course() { 00123 global $DB; 00124 $categoryid=$DB->insert_record('course_categories',(object)array('name'=>'conditionlibtest')); 00125 return $DB->insert_record('course',(object)array( 00126 'fullname'=>'Condition test','shortname'=>'CT1', 00127 'category'=>$categoryid,'enablecompletion'=>1)); 00128 } 00129 00130 private function make_course_module($courseid,$params=array()) { 00131 global $DB; 00132 static $moduleid=0; 00133 if(!$moduleid) { 00134 $moduleid=$DB->get_field('modules','id',array('name'=>'resource')); 00135 } 00136 00137 $rid=$DB->insert_record('resource',(object)array('course'=>$courseid, 00138 'name'=>'xxx','alltext'=>'','popup'=>'')); 00139 $settings=(object)array( 00140 'course'=>$courseid,'module'=>$moduleid,'instance'=>$rid); 00141 foreach($params as $name=>$value) { 00142 $settings->{$name}=$value; 00143 } 00144 return $DB->insert_record('course_modules',$settings); 00145 } 00146 00147 private function make_section($courseid,$cmids,$sectionnum=0) { 00148 global $DB; 00149 $DB->insert_record('course_sections',(object)array( 00150 'course'=>$courseid,'sequence'=>implode(',',$cmids),'section'=>$sectionnum)); 00151 } 00152 00153 function test_modinfo() { 00154 global $DB; 00155 00156 // Let's make a course 00157 $courseid=$this->make_course(); 00158 00159 // Now let's make a couple modules on that course 00160 $cmid1=$this->make_course_module($courseid,array( 00161 'showavailability'=>1,'availablefrom'=>17,'availableuntil'=>398, 00162 'completion'=>COMPLETION_TRACKING_MANUAL)); 00163 $cmid2=$this->make_course_module($courseid,array( 00164 'showavailability'=>0,'availablefrom'=>0,'availableuntil'=>0)); 00165 $this->make_section($courseid,array($cmid1,$cmid2)); 00166 00167 // Add a fake grade item 00168 $gradeitemid=$DB->insert_record('grade_items',(object)array( 00169 'courseid'=>$courseid,'itemname'=>'frog')); 00170 00171 // One of the modules has grade and completion conditions, other doesn't 00172 $DB->insert_record('course_modules_availability',(object)array( 00173 'coursemoduleid'=>$cmid2, 00174 'sourcecmid'=>$cmid1, 00175 'requiredcompletion'=>1 00176 )); 00177 $DB->insert_record('course_modules_availability',(object)array( 00178 'coursemoduleid'=>$cmid2, 00179 'gradeitemid'=>$gradeitemid, 00180 'grademin'=>5.5 00181 )); 00182 00183 // Okay sweet, now get modinfo 00184 $modinfo=get_fast_modinfo($DB->get_record('course',array('id'=>$courseid))); 00185 00186 // Test basic data 00187 $this->assertEqual(1,$modinfo->cms[$cmid1]->showavailability); 00188 $this->assertEqual(17,$modinfo->cms[$cmid1]->availablefrom); 00189 $this->assertEqual(398,$modinfo->cms[$cmid1]->availableuntil); 00190 $this->assertEqual(0,$modinfo->cms[$cmid2]->showavailability); 00191 $this->assertEqual(0,$modinfo->cms[$cmid2]->availablefrom); 00192 $this->assertEqual(0,$modinfo->cms[$cmid2]->availableuntil); 00193 00194 // Test condition arrays 00195 $this->assertEqual(array(),$modinfo->cms[$cmid1]->conditionscompletion); 00196 $this->assertEqual(array(),$modinfo->cms[$cmid1]->conditionsgrade); 00197 $this->assertEqual(array($cmid1=>1), 00198 $modinfo->cms[$cmid2]->conditionscompletion); 00199 $this->assertEqual(array($gradeitemid=>(object)array('min'=>5.5,'max'=>null,'name'=>'frog')), 00200 $modinfo->cms[$cmid2]->conditionsgrade); 00201 } 00202 00203 function test_add_and_remove() { 00204 global $DB; 00205 // Make course and module 00206 $courseid=$this->make_course(); 00207 $cmid=$this->make_course_module($courseid,array( 00208 'showavailability'=>0,'availablefrom'=>0,'availableuntil'=>0)); 00209 $this->make_section($courseid,array($cmid)); 00210 00211 // Check it has no conditions 00212 $test1=new condition_info((object)array('id'=>$cmid), 00213 CONDITION_MISSING_EVERYTHING); 00214 $cm=$test1->get_full_course_module(); 00215 $this->assertEqual(array(),$cm->conditionscompletion); 00216 $this->assertEqual(array(),$cm->conditionsgrade); 00217 00218 // Add conditions of each type 00219 $test1->add_completion_condition(13,3); 00220 $this->assertEqual(array(13=>3),$cm->conditionscompletion); 00221 $test1->add_grade_condition(666,0.4,null,true); 00222 $this->assertEqual(array(666=>(object)array('min'=>0.4,'max'=>null,'name'=>'!missing')), 00223 $cm->conditionsgrade); 00224 00225 // Check they were really added in db 00226 $test2=new condition_info((object)array('id'=>$cmid), 00227 CONDITION_MISSING_EVERYTHING); 00228 $cm=$test2->get_full_course_module(); 00229 $this->assertEqual(array(13=>3),$cm->conditionscompletion); 00230 $this->assertEqual(array(666=>(object)array('min'=>0.4,'max'=>null,'name'=>'!missing')), 00231 $cm->conditionsgrade); 00232 00233 // Wipe conditions 00234 $test2->wipe_conditions(); 00235 $this->assertEqual(array(),$cm->conditionscompletion); 00236 $this->assertEqual(array(),$cm->conditionsgrade); 00237 00238 // Check they were really wiped 00239 $test3=new condition_info((object)array('id'=>$cmid), 00240 CONDITION_MISSING_EVERYTHING); 00241 $cm=$test3->get_full_course_module(); 00242 $this->assertEqual(array(),$cm->conditionscompletion); 00243 $this->assertEqual(array(),$cm->conditionsgrade); 00244 } 00245 00246 function test_is_available() { 00247 global $DB,$USER; 00248 $courseid=$this->make_course(); 00249 00250 // No conditions 00251 $cmid=$this->make_course_module($courseid); 00252 $ci=new condition_info((object)array('id'=>$cmid), 00253 CONDITION_MISSING_EVERYTHING); 00254 $this->assertTrue($ci->is_available($text,false,0)); 00255 $this->assertEqual('',$text); 00256 00257 // Time (from) 00258 $time=time()+100; 00259 $cmid=$this->make_course_module($courseid,array('availablefrom'=>$time)); 00260 $ci=new condition_info((object)array('id'=>$cmid), 00261 CONDITION_MISSING_EVERYTHING); 00262 $this->assertFalse($ci->is_available($text)); 00263 $this->assert(new PatternExpectation( 00264 '/'.preg_quote(userdate($time,get_string('strftimedate','langconfig'))).'/'),$text); 00265 00266 $time=time()-100; 00267 $cmid=$this->make_course_module($courseid,array('availablefrom'=>$time)); 00268 $ci=new condition_info((object)array('id'=>$cmid), 00269 CONDITION_MISSING_EVERYTHING); 00270 $this->assertTrue($ci->is_available($text)); 00271 $this->assertEqual('',$text); 00272 $this->assert(new PatternExpectation( 00273 '/'.preg_quote(userdate($time,get_string('strftimedate','langconfig'))).'/'),$ci->get_full_information()); 00274 00275 // Time (until) 00276 $cmid=$this->make_course_module($courseid,array('availableuntil'=>time()-100)); 00277 $ci=new condition_info((object)array('id'=>$cmid), 00278 CONDITION_MISSING_EVERYTHING); 00279 $this->assertFalse($ci->is_available($text)); 00280 $this->assertEqual('',$text); 00281 00282 // Completion 00283 $oldid=$cmid; 00284 $cmid=$this->make_course_module($courseid); 00285 $this->make_section($courseid,array($oldid,$cmid)); 00286 $oldcm=$DB->get_record('course_modules',array('id'=>$oldid)); 00287 $oldcm->completion=COMPLETION_TRACKING_MANUAL; 00288 $DB->update_record('course_modules',$oldcm); 00289 00290 // Need to reset modinfo after changing the options 00291 rebuild_course_cache($courseid); 00292 $reset = 'reset'; 00293 get_fast_modinfo($reset); 00294 00295 $ci=new condition_info((object)array('id'=>$cmid),CONDITION_MISSING_EVERYTHING); 00296 $ci->add_completion_condition($oldid,COMPLETION_COMPLETE); 00297 condition_info::wipe_session_cache(); 00298 00299 $this->assertFalse($ci->is_available($text,false)); 00300 $this->assertEqual(get_string('requires_completion_1','condition','xxx'),$text); 00301 completion_info::wipe_session_cache(); 00302 $completion=new completion_info($DB->get_record('course',array('id'=>$courseid))); 00303 $completion->update_state($oldcm,COMPLETION_COMPLETE); 00304 completion_info::wipe_session_cache(); 00305 condition_info::wipe_session_cache(); 00306 00307 $this->assertTrue($ci->is_available($text)); 00308 $this->assertFalse($ci->is_available($text,false,$USER->id+1)); 00309 completion_info::wipe_session_cache(); 00310 condition_info::wipe_session_cache(); 00311 $completion=new completion_info($DB->get_record('course',array('id'=>$courseid))); 00312 $completion->update_state($oldcm,COMPLETION_INCOMPLETE); 00313 $this->assertFalse($ci->is_available($text)); 00314 00315 $ci->wipe_conditions(); 00316 $ci->add_completion_condition($oldid,COMPLETION_INCOMPLETE); 00317 condition_info::wipe_session_cache(); 00318 $this->assertTrue($ci->is_available($text)); 00319 $this->assertTrue($ci->is_available($text,false,$USER->id+1)); 00320 00321 condition_info::wipe_session_cache(); 00322 $this->assertTrue($ci->is_available($text,true)); 00323 00324 // Grade 00325 $ci->wipe_conditions(); 00326 // Add a fake grade item 00327 $gradeitemid=$DB->insert_record('grade_items',(object)array( 00328 'courseid'=>$courseid,'itemname'=>'frog')); 00329 // Add a condition on a value existing... 00330 $ci->add_grade_condition($gradeitemid,null,null,true); 00331 $this->assertFalse($ci->is_available($text)); 00332 $this->assertEqual(get_string('requires_grade_any','condition','frog'),$text); 00333 00334 // Fake it existing 00335 $DB->insert_record('grade_grades',(object)array( 00336 'itemid'=>$gradeitemid,'userid'=>$USER->id,'finalgrade'=>3.78)); 00337 condition_info::wipe_session_cache(); 00338 $this->assertTrue($ci->is_available($text)); 00339 00340 condition_info::wipe_session_cache(); 00341 $this->assertTrue($ci->is_available($text,true)); 00342 00343 // Now require that user gets more than 3.78001 00344 $ci->wipe_conditions(); 00345 $ci->add_grade_condition($gradeitemid,3.78001,null,true); 00346 condition_info::wipe_session_cache(); 00347 $this->assertFalse($ci->is_available($text)); 00348 $this->assertEqual(get_string('requires_grade_min','condition','frog'),$text); 00349 00350 // ...just on 3.78... 00351 $ci->wipe_conditions(); 00352 $ci->add_grade_condition($gradeitemid,3.78,null,true); 00353 condition_info::wipe_session_cache(); 00354 $this->assertTrue($ci->is_available($text)); 00355 00356 // ...less than 3.78 00357 $ci->wipe_conditions(); 00358 $ci->add_grade_condition($gradeitemid,null,3.78,true); 00359 condition_info::wipe_session_cache(); 00360 $this->assertFalse($ci->is_available($text)); 00361 $this->assertEqual(get_string('requires_grade_max','condition','frog'),$text); 00362 00363 // ...less than 3.78001 00364 $ci->wipe_conditions(); 00365 $ci->add_grade_condition($gradeitemid,null,3.78001,true); 00366 condition_info::wipe_session_cache(); 00367 $this->assertTrue($ci->is_available($text)); 00368 00369 // ...in a range that includes it 00370 $ci->wipe_conditions(); 00371 $ci->add_grade_condition($gradeitemid,3,4,true); 00372 condition_info::wipe_session_cache(); 00373 $this->assertTrue($ci->is_available($text)); 00374 00375 // ...in a range that doesn't include it 00376 $ci->wipe_conditions(); 00377 $ci->add_grade_condition($gradeitemid,4,5,true); 00378 condition_info::wipe_session_cache(); 00379 $this->assertFalse($ci->is_available($text)); 00380 $this->assertEqual(get_string('requires_grade_range','condition','frog'),$text); 00381 } 00382 00383 } 00384