Esempio n. 1
0
 /**
  * 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]));
 }
Esempio n. 3
0
 /**
  * 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));
 }
Esempio n. 5
0
 /**
  * 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);
 }
Esempio n. 6
0
 /**
  * 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));
 }
Esempio n. 7
0
 /**
  * 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&amp;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]);
 }
Esempio n. 8
0
 /**
  * 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)));
 }
Esempio n. 9
0
 /**
  * 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));
     }
 }
Esempio n. 11
0
 /**
  * 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));
 }
Esempio n. 12
0
 /**
  * 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());
 }