/** * Tests constructing and using date condition as part of tree. */ public function test_in_tree() { global $SITE, $USER, $CFG; $this->resetAfterTest(); $this->setAdminUser(); // Set server timezone for test. (Important as otherwise the timezone // could be anything - this is modified by other unit tests, too.) $this->setTimezone('UTC'); // SEt user to GMT+5. $USER->timezone = 5; // Construct tree with date condition. $time = strtotime('2014-02-18 14:20:00 GMT'); $structure = (object) array('op' => '|', 'show' => true, 'c' => array((object) array('type' => 'date', 'd' => '>=', 't' => $time))); $tree = new \core_availability\tree($structure); $info = new \core_availability\mock_info(); // Check if available (when not available). condition::set_current_time_for_test($time - 1); $information = ''; $result = $tree->check_available(false, $info, true, $USER->id); $this->assertFalse($result->is_available()); $information = $tree->get_result_information($info, $result); // Note: PM is normally upper-case, but an issue with PHP on Mac means // that on that platform, it is reported lower-case. $this->assertRegExp('~from.*18 February 2014, 7:20 (PM|pm)~', $information); // Check if available (when available). condition::set_current_time_for_test($time); $result = $tree->check_available(false, $info, true, $USER->id); $this->assertTrue($result->is_available()); $information = $tree->get_result_information($info, $result); $this->assertEquals('', $information); }
public function test_course_completion() { global $DB; $this->resetAfterTest(); // Enable avaibility. // If not enabled all conditional fields will be ignored. set_config('enableavailability', 1); // Enable course completion. // If not enabled all completion settings will be ignored. set_config('enablecompletion', COMPLETION_ENABLED); $generator = $this->getDataGenerator(); // Create course with completion tracking enabled. $course = $generator->create_course(['enablecompletion' => 1, 'numsections' => 3], ['createsections' => true]); // Enrol user to completion tracking course. $sturole = $DB->get_record('role', array('shortname' => 'student')); $generator->enrol_user($this->user1->id, $course->id, $sturole->id); // Create page with completion marked on view. $page1 = $generator->create_module('page', array('course' => $course->id, 'name' => 'page1 complete on view'), array('completion' => 2, 'completionview' => 1)); $modinfo = get_fast_modinfo($course); $page1cm = $modinfo->get_cm($page1->cmid); // Create page restricted to only show when first page is viewed. $moduleinfo = (object) []; $moduleinfo->course = $course->id; $moduleinfo->name = 'page2 available after page1 viewed'; $moduleinfo->availability = json_encode(\core_availability\tree::get_root_json([\availability_completion\condition::get_json($page1->cmid, COMPLETION_COMPLETE)], '&')); $page2 = $generator->create_module('page', $moduleinfo); // Make section 2 restricted to only show when first page is viewed. $section = $modinfo->get_section_info(2); $sectionupdate = ['id' => $section->id, 'availability' => json_encode(\core_availability\tree::get_root_json([\availability_completion\condition::get_json($page1->cmid, COMPLETION_COMPLETE)], '&'))]; $DB->update_record('course_sections', $sectionupdate); // Check user1 has expected unavailable section and mod. $this->setUser($this->user1); // Dump cache and reget modinfo. get_fast_modinfo($course, 0, true); $modinfo = get_fast_modinfo($course); $page2cm = $modinfo->get_cm($page2->cmid); list($previouslyunavailablesections, $previouslyunavailablemods) = local::conditionally_unavailable_elements($course); $this->assertContains(2, $previouslyunavailablesections); $this->assertContains($page2cm->id, $previouslyunavailablemods); // View page1 to trigger completion $context = context_module::instance($page1->cmid); page_view($page1, $course, $page1cm, $context); $completion = new completion_info($course); $completiondata = $completion->get_data($page1cm); $this->assertEquals(COMPLETION_COMPLETE, $completiondata->completionstate); get_fast_modinfo($course, 0, true); // Reset modinfo. // Make sure that unavailable sections and mods no longer contain the ones requiring availabililty criteria // satisfying. list($unavailablesections, $unavailablemods) = local::conditionally_unavailable_elements($course); $this->assertNotContains($page2cm->id, $unavailablemods); $this->assertNotContains(2, $unavailablesections); $result = $this->courseservice->course_completion($course->shortname, $previouslyunavailablesections, $previouslyunavailablemods); // Make sure that the second page module (which is now newly available) appears in the list of newly available // module html. $this->assertTrue(isset($result['newlyavailablemodhtml'][$page2->cmid])); // Make sure that the second section (which is now wnely available) appears in the list of newly available // section html. $this->assertTrue(isset($result['newlyavailablesectionhtml'][2])); }
/** * Tests that when creating or updating a module, if the availability settings * are present but set to an empty tree, availability is set to null in * database. */ public function test_empty_availability_settings() { global $DB; $this->setAdminUser(); $this->resetAfterTest(); // Enable availability. set_config('enableavailability', 1); // Test add. $emptyavailability = json_encode(\core_availability\tree::get_root_json(array())); $course = self::getDataGenerator()->create_course(); $label = self::getDataGenerator()->create_module('label', array('course' => $course, 'availability' => $emptyavailability)); $this->assertNull($DB->get_field('course_modules', 'availability', array('id' => $label->cmid))); // Test update. $formdata = $DB->get_record('course_modules', array('id' => $label->cmid)); unset($formdata->availability); $formdata->availabilityconditionsjson = $emptyavailability; $formdata->modulename = 'label'; $formdata->coursemodule = $label->cmid; $draftid = 0; file_prepare_draft_area($draftid, context_module::instance($label->cmid)->id, 'mod_label', 'intro', 0); $formdata->introeditor = array('itemid' => $draftid, 'text' => '<p>Yo</p>', 'format' => FORMAT_HTML); update_module($formdata); $this->assertNull($DB->get_field('course_modules', 'availability', array('id' => $label->cmid))); }
public function test_group_members_only() { global $CFG; $this->setAdminUser(); $this->create_extra_users(); $CFG->enableavailability = true; $grouping = $this->getDataGenerator()->create_grouping(array('courseid' => $this->course->id)); groups_assign_grouping($grouping->id, $this->groups[0]->id); // Force create an assignment with SEPARATEGROUPS. $instance = $this->getDataGenerator()->create_module('assign', array('course' => $this->course->id), array('availability' => json_encode(\core_availability\tree::get_root_json(array(\availability_grouping\condition::get_json()))), 'groupingid' => $grouping->id)); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new testable_assign($context, $cm, $this->course); $this->setUser($this->teachers[0]); get_fast_modinfo($this->course, 0, true); $this->assertCount(5, $assign->list_participants(0, true)); }
/** * Tests get_user_list_sql. */ public function test_get_user_list_sql() { global $DB; $this->resetAfterTest(); $generator = $this->getDataGenerator(); // Create a test course with 2 groups and users in each combination of them. $course = $generator->create_course(); $group1 = $generator->create_group(array('courseid' => $course->id)); $group2 = $generator->create_group(array('courseid' => $course->id)); $userin1 = $generator->create_user(); $userin2 = $generator->create_user(); $userinboth = $generator->create_user(); $userinneither = $generator->create_user(); $studentroleid = $DB->get_field('role', 'id', array('shortname' => 'student')); foreach (array($userin1, $userin2, $userinboth, $userinneither) as $user) { $generator->enrol_user($user->id, $course->id, $studentroleid); } groups_add_member($group1, $userin1); groups_add_member($group2, $userin2); groups_add_member($group1, $userinboth); groups_add_member($group2, $userinboth); $info = new \core_availability\mock_info($course); // Tree with single group condition. $tree = new tree(tree::get_root_json(array(\availability_group\condition::get_json($group1->id)))); list($sql, $params) = $tree->get_user_list_sql(false, $info, false); $result = $DB->get_fieldset_sql($sql, $params); sort($result); $this->assertEquals(array($userin1->id, $userinboth->id), $result); // Tree with 'AND' of both group conditions. $tree = new tree(tree::get_root_json(array(\availability_group\condition::get_json($group1->id), \availability_group\condition::get_json($group2->id)))); list($sql, $params) = $tree->get_user_list_sql(false, $info, false); $result = $DB->get_fieldset_sql($sql, $params); sort($result); $this->assertEquals(array($userinboth->id), $result); // Tree with 'AND' of both group conditions. $tree = new tree(tree::get_root_json(array(\availability_group\condition::get_json($group1->id), \availability_group\condition::get_json($group2->id)), tree::OP_OR)); list($sql, $params) = $tree->get_user_list_sql(false, $info, false); $result = $DB->get_fieldset_sql($sql, $params); sort($result); $this->assertEquals(array($userin1->id, $userin2->id, $userinboth->id), $result); // Check with flipped logic (NOT above level of tree). list($sql, $params) = $tree->get_user_list_sql(true, $info, false); $result = $DB->get_fieldset_sql($sql, $params); sort($result); $this->assertEquals(array($userinneither->id), $result); }
/** * Tests user restrictions, as they affect lists of users returned by * core API functions. * * This includes the groupingid option (when group mode is in use), and * standard activity restrictions using the availability API. */ public function test_user_restrictions() { global $DB, $CFG; $this->resetAfterTest(); // Use existing sample course from setUp. $courseid = $this->workshop->course->id; // Make a test grouping and two groups. $generator = $this->getDataGenerator(); $grouping = $generator->create_grouping(array('courseid' => $courseid)); $group1 = $generator->create_group(array('courseid' => $courseid)); groups_assign_grouping($grouping->id, $group1->id); $group2 = $generator->create_group(array('courseid' => $courseid)); groups_assign_grouping($grouping->id, $group2->id); // Group 3 is not in the grouping. $group3 = $generator->create_group(array('courseid' => $courseid)); // Enrol some students. $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); $student1 = $generator->create_user(); $student2 = $generator->create_user(); $student3 = $generator->create_user(); $generator->enrol_user($student1->id, $courseid, $roleids['student']); $generator->enrol_user($student2->id, $courseid, $roleids['student']); $generator->enrol_user($student3->id, $courseid, $roleids['student']); // Place students in groups (except student 3). groups_add_member($group1, $student1); groups_add_member($group2, $student2); groups_add_member($group3, $student3); // The existing workshop doesn't have any restrictions, so user lists // should include all three users. $allusers = get_enrolled_users(context_course::instance($courseid)); $result = $this->workshop->get_grouped($allusers); $this->assertCount(4, $result); $users = array_keys($result[0]); sort($users); $this->assertEquals(array($student1->id, $student2->id, $student3->id), $users); $this->assertEquals(array($student1->id), array_keys($result[$group1->id])); $this->assertEquals(array($student2->id), array_keys($result[$group2->id])); $this->assertEquals(array($student3->id), array_keys($result[$group3->id])); // Test get_users_with_capability_sql (via get_potential_authors). $users = $this->workshop->get_potential_authors(false); $this->assertCount(3, $users); $users = $this->workshop->get_potential_authors(false, $group2->id); $this->assertEquals(array($student2->id), array_keys($users)); // Create another test workshop with grouping set. $workshopitem = $this->getDataGenerator()->create_module('workshop', array('course' => $courseid, 'groupmode' => SEPARATEGROUPS, 'groupingid' => $grouping->id)); $cm = get_coursemodule_from_instance('workshop', $workshopitem->id, $courseid, false, MUST_EXIST); $workshopgrouping = new testable_workshop($workshopitem, $cm, $this->workshop->course); // This time the result should only include users and groups in the // selected grouping. $result = $workshopgrouping->get_grouped($allusers); $this->assertCount(3, $result); $users = array_keys($result[0]); sort($users); $this->assertEquals(array($student1->id, $student2->id), $users); $this->assertEquals(array($student1->id), array_keys($result[$group1->id])); $this->assertEquals(array($student2->id), array_keys($result[$group2->id])); // Test get_users_with_capability_sql (via get_potential_authors). $users = $workshopgrouping->get_potential_authors(false); $userids = array_keys($users); sort($userids); $this->assertEquals(array($student1->id, $student2->id), $userids); $users = $workshopgrouping->get_potential_authors(false, $group2->id); $this->assertEquals(array($student2->id), array_keys($users)); // Enable the availability system and create another test workshop with // availability restriction on grouping. $CFG->enableavailability = true; $workshopitem = $this->getDataGenerator()->create_module('workshop', array('course' => $courseid, 'availability' => json_encode(\core_availability\tree::get_root_json(array(\availability_grouping\condition::get_json($grouping->id)), \core_availability\tree::OP_AND, false)))); $cm = get_coursemodule_from_instance('workshop', $workshopitem->id, $courseid, false, MUST_EXIST); $workshoprestricted = new testable_workshop($workshopitem, $cm, $this->workshop->course); // The get_grouped function isn't intended to apply this restriction, // so it should be the same as the base workshop. (Note: in reality, // get_grouped is always run with the parameter being the result of // one of the get_potential_xxx functions, so it works.) $result = $workshoprestricted->get_grouped($allusers); $this->assertCount(4, $result); $this->assertCount(3, $result[0]); // The get_users_with_capability_sql-based functions should apply it. $users = $workshoprestricted->get_potential_authors(false); $userids = array_keys($users); sort($userids); $this->assertEquals(array($student1->id, $student2->id), $userids); $users = $workshoprestricted->get_potential_authors(false, $group2->id); $this->assertEquals(array($student2->id), array_keys($users)); }
/** * Test convect fetching. */ public function test_concept_fetching() { global $CFG, $DB; $this->resetAfterTest(true); $this->setAdminUser(); $CFG->glossary_linkbydefault = 1; $CFG->glossary_linkentries = 0; // Create a test courses. $course1 = $this->getDataGenerator()->create_course(); $course2 = $this->getDataGenerator()->create_course(); $site = $DB->get_record('course', array('id' => SITEID)); // Create a glossary. $glossary1a = $this->getDataGenerator()->create_module('glossary', array('course' => $course1->id, 'mainglossary' => 1, 'usedynalink' => 1)); $glossary1b = $this->getDataGenerator()->create_module('glossary', array('course' => $course1->id, 'mainglossary' => 1, 'usedynalink' => 1)); $glossary1c = $this->getDataGenerator()->create_module('glossary', array('course' => $course1->id, 'mainglossary' => 1, 'usedynalink' => 0)); $glossary2 = $this->getDataGenerator()->create_module('glossary', array('course' => $course2->id, 'mainglossary' => 1, 'usedynalink' => 1)); $glossary3 = $this->getDataGenerator()->create_module('glossary', array('course' => $site->id, 'mainglossary' => 1, 'usedynalink' => 1, 'globalglossary' => 1)); /** @var mod_glossary_generator $generator */ $generator = $this->getDataGenerator()->get_plugin_generator('mod_glossary'); $entry1a1 = $generator->create_content($glossary1a, array('concept' => 'first', 'usedynalink' => 1), array('prvni', 'erste')); $entry1a2 = $generator->create_content($glossary1a, array('concept' => 'A&B', 'usedynalink' => 1)); $entry1a3 = $generator->create_content($glossary1a, array('concept' => 'neee', 'usedynalink' => 0)); $entry1b1 = $generator->create_content($glossary1b, array('concept' => 'second', 'usedynalink' => 1)); $entry1c1 = $generator->create_content($glossary1c, array('concept' => 'third', 'usedynalink' => 1)); $entry31 = $generator->create_content($glossary3, array('concept' => 'global', 'usedynalink' => 1), array('globalni')); $cat1 = $generator->create_category($glossary1a, array('name' => 'special'), array($entry1a1, $entry1a2)); \mod_glossary\local\concept_cache::reset_caches(); $concepts1 = \mod_glossary\local\concept_cache::get_concepts($course1->id); $this->assertCount(3, $concepts1[0]); $this->arrayHasKey($concepts1[0], $glossary1a->id); $this->arrayHasKey($concepts1[0], $glossary1b->id); $this->arrayHasKey($concepts1[0], $glossary3->id); $this->assertCount(3, $concepts1[1]); $this->arrayHasKey($concepts1[1], $glossary1a->id); $this->arrayHasKey($concepts1[1], $glossary1b->id); $this->arrayHasKey($concepts1[0], $glossary3->id); $this->assertCount(5, $concepts1[1][$glossary1a->id]); foreach ($concepts1[1][$glossary1a->id] as $concept) { $this->assertSame(array('id', 'glossaryid', 'concept', 'casesensitive', 'category', 'fullmatch'), array_keys((array) $concept)); if ($concept->concept === 'first') { $this->assertEquals($entry1a1->id, $concept->id); $this->assertEquals($glossary1a->id, $concept->glossaryid); $this->assertEquals(0, $concept->category); } else { if ($concept->concept === 'prvni') { $this->assertEquals($entry1a1->id, $concept->id); $this->assertEquals($glossary1a->id, $concept->glossaryid); $this->assertEquals(0, $concept->category); } else { if ($concept->concept === 'erste') { $this->assertEquals($entry1a1->id, $concept->id); $this->assertEquals($glossary1a->id, $concept->glossaryid); $this->assertEquals(0, $concept->category); } else { if ($concept->concept === 'A&B') { $this->assertEquals($entry1a2->id, $concept->id); $this->assertEquals($glossary1a->id, $concept->glossaryid); $this->assertEquals(0, $concept->category); } else { if ($concept->concept === 'special') { $this->assertEquals($cat1->id, $concept->id); $this->assertEquals($glossary1a->id, $concept->glossaryid); $this->assertEquals(1, $concept->category); } else { $this->fail('Unexpected concept: ' . $concept->concept); } } } } } } $this->assertCount(1, $concepts1[1][$glossary1b->id]); foreach ($concepts1[1][$glossary1b->id] as $concept) { $this->assertSame(array('id', 'glossaryid', 'concept', 'casesensitive', 'category', 'fullmatch'), array_keys((array) $concept)); if ($concept->concept === 'second') { $this->assertEquals($entry1b1->id, $concept->id); $this->assertEquals($glossary1b->id, $concept->glossaryid); $this->assertEquals(0, $concept->category); } else { $this->fail('Unexpected concept: ' . $concept->concept); } } $this->assertCount(2, $concepts1[1][$glossary3->id]); foreach ($concepts1[1][$glossary3->id] as $concept) { $this->assertSame(array('id', 'glossaryid', 'concept', 'casesensitive', 'category', 'fullmatch'), array_keys((array) $concept)); if ($concept->concept === 'global') { $this->assertEquals($entry31->id, $concept->id); $this->assertEquals($glossary3->id, $concept->glossaryid); $this->assertEquals(0, $concept->category); } else { if ($concept->concept === 'globalni') { $this->assertEquals($entry31->id, $concept->id); $this->assertEquals($glossary3->id, $concept->glossaryid); $this->assertEquals(0, $concept->category); } else { $this->fail('Unexpected concept: ' . $concept->concept); } } } $concepts3 = \mod_glossary\local\concept_cache::get_concepts($site->id); $this->assertCount(1, $concepts3[0]); $this->arrayHasKey($concepts3[0], $glossary3->id); $this->assertCount(1, $concepts3[1]); $this->arrayHasKey($concepts3[0], $glossary3->id); foreach ($concepts3[1][$glossary3->id] as $concept) { $this->assertSame(array('id', 'glossaryid', 'concept', 'casesensitive', 'category', 'fullmatch'), array_keys((array) $concept)); if ($concept->concept === 'global') { $this->assertEquals($entry31->id, $concept->id); $this->assertEquals($glossary3->id, $concept->glossaryid); $this->assertEquals(0, $concept->category); } else { if ($concept->concept === 'globalni') { $this->assertEquals($entry31->id, $concept->id); $this->assertEquals($glossary3->id, $concept->glossaryid); $this->assertEquals(0, $concept->category); } else { $this->fail('Unexpected concept: ' . $concept->concept); } } } $concepts2 = \mod_glossary\local\concept_cache::get_concepts($course2->id); $this->assertEquals($concepts3, $concepts2); // Test uservisible flag. set_config('enableavailability', 1); $glossary1d = $this->getDataGenerator()->create_module('glossary', array('course' => $course1->id, 'mainglossary' => 1, 'usedynalink' => 1, 'availability' => json_encode(\core_availability\tree::get_root_json(array(\availability_group\condition::get_json()))))); $entry1d1 = $generator->create_content($glossary1d, array('concept' => 'membersonly', 'usedynalink' => 1)); $user = $this->getDataGenerator()->create_user(); $this->getDataGenerator()->enrol_user($user->id, $course1->id); $this->getDataGenerator()->enrol_user($user->id, $course2->id); \mod_glossary\local\concept_cache::reset_caches(); $concepts1 = \mod_glossary\local\concept_cache::get_concepts($course1->id); $this->assertCount(4, $concepts1[0]); $this->assertCount(4, $concepts1[1]); $this->setUser($user); course_modinfo::clear_instance_cache(); \mod_glossary\local\concept_cache::reset_caches(); $concepts1 = \mod_glossary\local\concept_cache::get_concepts($course1->id); $this->assertCount(3, $concepts1[0]); $this->assertCount(3, $concepts1[1]); }
/** * Tests the update_all_dates function. */ public function test_update_all_dates() { global $DB; $this->resetAfterTest(); // Create a course with 3 pages. $generator = $this->getDataGenerator(); $course = $generator->create_course(); $rec = array('course' => $course); $page1 = $generator->get_plugin_generator('mod_page')->create_instance($rec); $page2 = $generator->get_plugin_generator('mod_page')->create_instance($rec); $page3 = $generator->get_plugin_generator('mod_page')->create_instance($rec); // Set the availability page 2 to a simple date condition. You can access // it from 1337 onwards. $simplecondition = tree::get_root_json(array(condition::get_json(condition::DIRECTION_FROM, 1337))); $DB->set_field('course_modules', 'availability', json_encode($simplecondition), array('id' => $page2->cmid)); // Set page 3 to a complex set of conditions including a nested date condition. // You can access it until 1459, *or* after 2810 if you belong to a group. $complexcondition = tree::get_root_json(array(condition::get_json(condition::DIRECTION_UNTIL, 1459), tree::get_nested_json(array(condition::get_json(condition::DIRECTION_FROM, 2810), \availability_group\condition::get_json()))), tree::OP_OR); $DB->set_field('course_modules', 'availability', json_encode($complexcondition), array('id' => $page3->cmid)); // Now use the update_all_dates function to move date forward 100000. condition::update_all_dates($course->id, 100000); // Get the expected conditions after adjusting time, and compare to database. $simplecondition->c[0]->t = 101337; $complexcondition->c[0]->t = 101459; $complexcondition->c[1]->c[0]->t = 102810; $this->assertEquals($simplecondition, json_decode($DB->get_field('course_modules', 'availability', array('id' => $page2->cmid)))); $this->assertEquals($complexcondition, json_decode($DB->get_field('course_modules', 'availability', array('id' => $page3->cmid)))); // The one without availability conditions should still be null. $this->assertNull($DB->get_field('course_modules', 'availability', array('id' => $page1->cmid))); }
/** * Test upcoming deadlines restricted by group * * @throws \coding_exception */ public function test_upcoming_deadlines_group() { global $DB; $this->resetAfterTest(); $generator = $this->getDataGenerator(); $course = $generator->create_course(); $student1 = $generator->create_user(); $student2 = $generator->create_user(); $teacher = $generator->create_user(); $group1 = $this->create_group($course->id, 'group1'); $group2 = $this->create_group($course->id, 'group2'); // Enrol students. $studentrole = $DB->get_record('role', array('shortname' => 'student')); foreach ([$student1, $student2] as $student) { $generator->enrol_user($student->id, $course->id, $studentrole->id); } // Enrol teacher. $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); $generator->enrol_user($teacher->id, $course->id, $teacherrole->id); // Add students to groups. groups_add_member($group1, $student1); groups_add_member($group2, $student2); // Create assignment restricted to group1. $opts = ['availability' => json_encode(\core_availability\tree::get_root_json([\availability_group\condition::get_json($group1->id)]))]; $duedate1 = time() + DAYSECS * 2; $this->create_assignment($course->id, $duedate1, $opts); // Create assignment restricted to group2. $opts = ['availability' => json_encode(\core_availability\tree::get_root_json([\availability_group\condition::get_json($group2->id)]))]; $duedate2 = time() + DAYSECS * 3; $this->create_assignment($course->id, $duedate2, $opts); // Ensure student1 only has 1 deadline and that it is for group1. $stu1deadlines = local::upcoming_deadlines($student1->id); $this->assertCount(1, $stu1deadlines); $this->assertEquals($duedate1, reset($stu1deadlines)->timestart); // Ensure student2 only has 1 deadline and that it is for group2. $stu2deadlines = local::upcoming_deadlines($student2->id); $this->assertCount(1, $stu2deadlines); $this->assertEquals($duedate2, reset($stu2deadlines)->timestart); // Ensure teacher can see both deadlines. $tchdeadlines = local::upcoming_deadlines($teacher->id); $this->assertCount(2, $tchdeadlines); }
/** * Sets the value(s) of an availability element. * * At present this only supports the following value 'Grouping: xxx' where * xxx is the name of a grouping. Additional value types can be added as * necessary. * * @param string $value Value code * @return void */ public function set_value($value) { global $DB; $driver = $this->session->getDriver(); // Check the availability condition is currently unset - we don't yet // support changing an existing one. $existing = $this->get_value(); if ($existing && $existing !== '{"op":"&","c":[],"showc":[]}') { throw new Exception('Cannot automatically set availability when ' . 'there is existing setting - must clear manually'); } // Check the value matches a supported format. $matches = array(); if (!preg_match('~^\\s*([^:]*):\\s*(.*?)\\s*$~', $value, $matches)) { throw new Exception('Value for availability field does not match correct ' . 'format. Example: "Grouping: G1"'); } $type = $matches[1]; $param = $matches[2]; if ($this->running_javascript()) { switch (strtolower($type)) { case 'grouping': // Set a grouping condition. $driver->click('//div[@class="availability-button"]/button'); $driver->click('//button[@id="availability_addrestriction_grouping"]'); $escparam = $this->session->getSelectorsHandler()->xpathLiteral($param); $nodes = $driver->find('//span[contains(concat(" " , @class, " "), " availability_grouping ")]//' . 'option[normalize-space(.) = ' . $escparam . ']'); if (count($nodes) != 1) { throw new Exception('Cannot find grouping in dropdown' . count($nodes)); } $node = reset($nodes); $value = $node->getValue(); $driver->selectOption('//span[contains(concat(" " , @class, " "), " availability_grouping ")]//' . 'select', $value); break; default: // We don't support other types yet. The test author must write // manual 'click on that button, etc' commands. throw new Exception('The availability type "' . $type . '" is currently not supported - must set manually'); } } else { $courseid = $driver->getValue('//input[@name="course"]'); switch (strtolower($type)) { case 'grouping': // Define result with one grouping condition. $groupingid = $DB->get_field('groupings', 'id', array('courseid' => $courseid, 'name' => $param)); $json = \core_availability\tree::get_root_json(array(\availability_grouping\condition::get_json($groupingid))); break; default: // We don't support other types yet. throw new Exception('The availability type "' . $type . '" is currently not supported - must set with JavaScript'); } $driver->setValue('//textarea[@name="availabilityconditionsjson"]', json_encode($json)); } }
/** * Tests the filter_users function. */ public function test_filter_users() { $info = new \core_availability\mock_info(); $checker = new capability_checker($info->get_context()); // Don't need to create real users in database, just use these ids. $users = array(1 => null, 2 => null, 3 => null); // Test basic tree with one condition that doesn't filter. $structure = self::tree(array(self::mock(array()))); $tree = new \core_availability\tree($structure); $result = $tree->filter_user_list($users, false, $info, $checker); ksort($result); $this->assertEquals(array(1, 2, 3), array_keys($result)); // Now a tree with one condition that filters. $structure = self::tree(array(self::mock(array('filter' => array(2, 3))))); $tree = new \core_availability\tree($structure); $result = $tree->filter_user_list($users, false, $info, $checker); ksort($result); $this->assertEquals(array(2, 3), array_keys($result)); // Tree with two conditions that both filter (|). $structure = self::tree(array(self::mock(array('filter' => array(3))), self::mock(array('filter' => array(1))))); $tree = new \core_availability\tree($structure); $result = $tree->filter_user_list($users, false, $info, $checker); ksort($result); $this->assertEquals(array(1, 3), array_keys($result)); // Tree with two condition that both filter (&). $structure = self::tree(array(self::mock(array('filter' => array(2, 3))), self::mock(array('filter' => array(1, 2)))), '&', false, array(true, true)); $tree = new \core_availability\tree($structure); $result = $tree->filter_user_list($users, false, $info, $checker); ksort($result); $this->assertEquals(array(2), array_keys($result)); // Tree with child tree with NOT condition. $structure = self::tree(array(self::tree(self::mock(array('filter' => array(1))), '!&', null))); $tree = new \core_availability\tree($structure); $result = $tree->filter_user_list($users, false, $info, $checker); ksort($result); $this->assertEquals(array(2, 3), array_keys($result)); }
/** * Tests the is_empty() function. */ public function test_is_empty() { // Tree with nothing in should be empty. $structure = self::tree(array()); $tree = new tree($structure); $this->assertTrue($tree->is_empty()); // Tree with something in is not empty. $structure = self::tree(array(self::mock(array('m' => '1')))); $tree = new tree($structure); $this->assertFalse($tree->is_empty()); }