/** * Generates a fully set up mod_ratingallocate module * @param advanced_testcase $tc * @param array $record * @param boolean $assert_intermediate_result */ public function __construct(advanced_testcase $tc, $record = null, $assert_intermediate_result = true) { global $DB; $tc->resetAfterTest(); $tc->setAdminUser(); if (is_null($record)) { $record = array(); } elseif (!is_array($record)) { $tc->fail('$record must be null or an array'); } if (!array_key_exists('course', $record)) { $record['course'] = $tc->getDataGenerator()->create_course(); } $this->course = $record['course']; $this->teacher = mod_ratingallocate_generator::create_user_and_enrol($tc, $this->course, true); $tc->setUser($this->teacher); if ($assert_intermediate_result) { $tc->assertFalse($DB->record_exists(this_db\ratingallocate::TABLE, array(this_db\ratingallocate::COURSE => $this->course->id)), 'There should not be any module for that course first'); } // create activity $this->mod_db = $tc->getDataGenerator()->create_module(ratingallocate_MOD_NAME, $record); $tc->assertEquals(2, $DB->count_records(this_db\ratingallocate_choices::TABLE), array(this_db\ratingallocate_choices::ID => $this->mod_db->id)); // create students $num_students = array_key_exists('num_students', $record) ? $record['num_students'] : 20; for ($i = 0; $i < $num_students; $i++) { $this->students[$i] = mod_ratingallocate_generator::create_user_and_enrol($tc, $this->course); } // load choices $ratingallocate = mod_ratingallocate_generator::get_ratingallocate_for_user($tc, $this->mod_db, $this->teacher); $this->choices = $choices = $ratingallocate->get_rateable_choices(); $choices_nummerated = array_values($choices); $num_choices = sizeof($choices_nummerated); // create students' preferences as array // array ('Choice 1' => 1 ) if (!array_key_exists('ratings', $record)) { $record['ratings'] = array(); for ($i = 0; $i < $num_students; $i++) { $record['ratings'][$i] = array($choices_nummerated[$i % $num_choices]->{this_db\ratingallocate_choices::TITLE} => 1); } } $this->ratings = $record['ratings']; // Create preferences $prefers_non = array(); $choice_id_by_title = array(); foreach ($choices as $choice) { $prefers_non[$choice->{this_db\ratingallocate_choices::ID}] = array(this_db\ratingallocate_ratings::CHOICEID => $choice->{this_db\ratingallocate_choices::ID}, this_db\ratingallocate_ratings::RATING => 0); $choice_id_by_title[$choice->{this_db\ratingallocate_choices::TITLE}] = $choice->{this_db\ratingallocate_choices::ID}; } // rate for student for ($i = 0; $i < $num_students; $i++) { $rating = json_decode(json_encode($prefers_non), true); // create user's rating according to the modules specifications foreach ($this->ratings[$i] as $choice_name => $preference) { $choice_id = $choice_id_by_title[$choice_name]; $rating[$choice_id][this_db\ratingallocate_ratings::RATING] = $preference; } // assign preferences mod_ratingallocate_generator::save_rating_for_user($tc, $this->mod_db, $this->students[$i], $rating); if ($assert_intermediate_result) { $alloc = mod_ratingallocate_generator::get_ratingallocate_for_user($tc, $this->mod_db, $this->students[$i]); $saved_ratings = $alloc->get_rating_data_for_user($this->students[$i]->id); $saved_rating_arr = array(); foreach ($saved_ratings as $saved_rat) { if (!$saved_rat->{this_db\ratingallocate_ratings::RATING} == 0) { $saved_rating_arr[$saved_rat->{this_db\ratingallocate_choices::TITLE}] = $saved_rat->{this_db\ratingallocate_ratings::RATING}; } } $tc->assertEquals($this->ratings[$i], $saved_rating_arr); } } // allocate choices $ratingallocate = mod_ratingallocate_generator::get_ratingallocate_for_user($tc, $this->mod_db, $this->teacher); $time_needed = $ratingallocate->distrubute_choices(); $tc->assertGreaterThan(0, $time_needed); $tc->assertLessThan(0.2, $time_needed, 'Allocation is very slow'); $this->allocations = $ratingallocate->get_allocations(); }
public function test_simple() { global $DB, $USER; core_php_time_limit::raise(); $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $teacher = mod_ratingallocate_generator::create_user_and_enrol($this, $course, true); $this->setUser($teacher); // There should not be any module for that course first $this->assertFalse($DB->record_exists(this_db\ratingallocate::TABLE, array(this_db\ratingallocate::COURSE => $course->id))); //set default data for category $data = mod_ratingallocate_generator::get_default_values(); $data['course'] = $course; foreach ($data as $name => $value) { if (subStr($name, strlen($name) - 7, 7) === 'maxsize') { $data[$name] = 2; } if (subStr($name, strlen($name) - 6, 6) === 'active') { $data[$name] = true; } } // create activity $mod = $this->getDataGenerator()->create_module(ratingallocate_MOD_NAME, $data); $this->assertEquals(2, $DB->count_records(this_db\ratingallocate_choices::TABLE), array(this_db\ratingallocate_choices::ID => $mod->id)); $student_1 = mod_ratingallocate_generator::create_user_and_enrol($this, $course); $student_2 = mod_ratingallocate_generator::create_user_and_enrol($this, $course); $student_3 = mod_ratingallocate_generator::create_user_and_enrol($this, $course); $student_4 = mod_ratingallocate_generator::create_user_and_enrol($this, $course); $ratingallocate = mod_ratingallocate_generator::get_ratingallocate_for_user($this, $mod, $teacher); $choices = $ratingallocate->get_rateable_choices(); $choice1 = reset($choices); $choice2 = end($choices); //Create preferences $prefers_non = array(); foreach ($choices as $choice) { $prefers_non[$choice->{this_db\ratingallocate_choices::ID}] = array(this_db\ratingallocate_ratings::CHOICEID => $choice->{this_db\ratingallocate_choices::ID}, this_db\ratingallocate_ratings::RATING => 0); } $prefers_first = json_decode(json_encode($prefers_non), true); $prefers_first[$choice1->{this_db\ratingallocate_choices::ID}][this_db\ratingallocate_ratings::RATING] = true; $prefers_second = json_decode(json_encode($prefers_non), true); $prefers_second[$choice2->{this_db\ratingallocate_choices::ID}][this_db\ratingallocate_ratings::RATING] = true; //assign preferences mod_ratingallocate_generator::save_rating_for_user($this, $mod, $student_1, $prefers_first); mod_ratingallocate_generator::save_rating_for_user($this, $mod, $student_2, $prefers_first); mod_ratingallocate_generator::save_rating_for_user($this, $mod, $student_3, $prefers_second); mod_ratingallocate_generator::save_rating_for_user($this, $mod, $student_4, $prefers_second); // allocate choices $ratingallocate = mod_ratingallocate_generator::get_ratingallocate_for_user($this, $mod, $teacher); $time_needed = $ratingallocate->distrubute_choices(); $this->assertGreaterThan(0, $time_needed); $this->assertLessThan(0.1, $time_needed, 'Allocation is very slow'); $allocation_count = $ratingallocate->get_choices_with_allocationcount(); $this->assertCount(2, $allocation_count); //Test allocations $num_allocations = $DB->count_records(this_db\ratingallocate_allocations::TABLE); $this->assertEquals(4, $num_allocations, 'There should be only 4 allocations, since there are only 4 choices.'); $allocations = $DB->get_records(this_db\ratingallocate_allocations::TABLE, array(this_db\ratingallocate_allocations::RATINGALLOCATEID => $mod->{this_db\ratingallocate::ID}), ''); // '' /*sort*/, /*fields*/ this_db\ratingallocate_allocations::USERID . ',' . this_db\ratingallocate_allocations::CHOICEID ); $map_user_id = function ($elem) { return $elem->{this_db\ratingallocate_allocations::USERID}; }; $alloc1 = self::filter_allocations_by_choice($allocations, $choice1->{this_db\ratingallocate_choices::ID}); $alloc2 = self::filter_allocations_by_choice($allocations, $choice2->{this_db\ratingallocate_choices::ID}); //Assert, that student 1 was allocated to choice 1 $this->assertContains($student_1->id, array_map($map_user_id, $alloc1)); //Assert, that student 2 was allocated to choice 1 $this->assertContains($student_2->id, array_map($map_user_id, $alloc1)); //Assert, that student 3 was allocated to choice 2 $this->assertContains($student_3->id, array_map($map_user_id, $alloc2)); //Assert, that student 4 was allocated to choice 2 $this->assertContains($student_4->id, array_map($map_user_id, $alloc2)); }
/** * Create an ratingallocate module with 4 enroled students and their ratings. * @param $ratingperiodended determines if the rating period should have ended. * @param int $algorithmstatus the algorithm status of the modul to be created. * @param datetime $algorithmstarttime the start time of the algorithm. */ private function create_ratingallocate($ratingperiodended, $algorithmstatus = \mod_ratingallocate\algorithm_status::notstarted, $algorithmstarttime = null) { global $DB; $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $this->teacher = mod_ratingallocate_generator::create_user_and_enrol($this, $course, true); $this->setUser($this->teacher); // There should not be any module for that course first $this->assertFalse($DB->record_exists(this_db\ratingallocate::TABLE, array(this_db\ratingallocate::COURSE => $course->id))); $data = mod_ratingallocate_generator::get_default_values(); $data['course'] = $course; // Shift the rating period depending on its ending. $data['accesstimestart'] = time(); $data['accesstimestop'] = time(); if ($ratingperiodended) { $data['accesstimestart'] -= 6 * 24 * 60 * 60; // Necessary to ensure access time stop being in the past --$data['accesstimestop']; } else { $data['accesstimestop'] += 6 * 24 * 60 * 60; } $data['algorithmstatus'] = $algorithmstatus; $data['algorithmstarttime'] = $algorithmstarttime; // create activity $this->mod = $this->getDataGenerator()->create_module(ratingallocate_MOD_NAME, $data); $this->assertEquals(2, $DB->count_records(this_db\ratingallocate_choices::TABLE, array(this_db\ratingallocate_choices::RATINGALLOCATEID => $this->mod->id))); $student_1 = mod_ratingallocate_generator::create_user_and_enrol($this, $course); $student_2 = mod_ratingallocate_generator::create_user_and_enrol($this, $course); $student_3 = mod_ratingallocate_generator::create_user_and_enrol($this, $course); $student_4 = mod_ratingallocate_generator::create_user_and_enrol($this, $course); $ratingallocate = mod_ratingallocate_generator::get_ratingallocate_for_user($this, $this->mod, $this->teacher); $choices = $ratingallocate->get_rateable_choices(); $choice1 = reset($choices); $choice2 = end($choices); //Create preferences $prefers_non = array(); foreach ($choices as $choice) { $prefers_non[$choice->{this_db\ratingallocate_choices::ID}] = array(this_db\ratingallocate_ratings::CHOICEID => $choice->{this_db\ratingallocate_choices::ID}, this_db\ratingallocate_ratings::RATING => 0); } $prefers_first = json_decode(json_encode($prefers_non), true); $prefers_first[$choice1->{this_db\ratingallocate_choices::ID}][this_db\ratingallocate_ratings::RATING] = true; $prefers_second = json_decode(json_encode($prefers_non), true); $prefers_second[$choice2->{this_db\ratingallocate_choices::ID}][this_db\ratingallocate_ratings::RATING] = true; //assign preferences mod_ratingallocate_generator::save_rating_for_user($this, $this->mod, $student_1, $prefers_first); mod_ratingallocate_generator::save_rating_for_user($this, $this->mod, $student_2, $prefers_first); mod_ratingallocate_generator::save_rating_for_user($this, $this->mod, $student_3, $prefers_second); mod_ratingallocate_generator::save_rating_for_user($this, $this->mod, $student_4, $prefers_second); $this->assertEquals(0, $DB->count_records(this_db\ratingallocate_allocations::TABLE, array(this_db\ratingallocate_allocations::RATINGALLOCATEID => $this->mod->id))); }