From 8db355c58fd97b20e4f1d0f1cde4124ca30189bf Mon Sep 17 00:00:00 2001 From: Jake Dallimore Date: Thu, 16 Mar 2017 15:27:25 +0800 Subject: [PATCH] MDL-58138 tests: unit and behat tests covering bulk and default tabs Part of MDL-58138 epic --- .../bulk_edit_activity_completion.feature | 62 +++++++++++++++++++ .../behat/default_activity_completion.feature | 53 ++++++++++++++++ course/templates/activityinstance.mustache | 5 +- mod/assign/tests/lib_test.php | 27 ++++++++ mod/choice/tests/lib_test.php | 40 +++++++++++- mod/feedback/tests/lib_test.php | 44 ++++++++++++- mod/forum/lib.php | 1 - mod/forum/tests/lib_test.php | 50 +++++++++++++++ mod/glossary/tests/lib_test.php | 38 ++++++++++++ mod/lesson/tests/lib_test.php | 46 ++++++++++++++ mod/quiz/tests/lib_test.php | 45 ++++++++++++++ mod/scorm/lib.php | 1 - mod/scorm/tests/lib_test.php | 61 +++++++++++++++++- mod/survey/tests/lib_test.php | 38 ++++++++++++ 14 files changed, 502 insertions(+), 9 deletions(-) create mode 100644 completion/tests/behat/bulk_edit_activity_completion.feature create mode 100644 completion/tests/behat/default_activity_completion.feature diff --git a/completion/tests/behat/bulk_edit_activity_completion.feature b/completion/tests/behat/bulk_edit_activity_completion.feature new file mode 100644 index 00000000000..9f7df57f842 --- /dev/null +++ b/completion/tests/behat/bulk_edit_activity_completion.feature @@ -0,0 +1,62 @@ +@core @core_completion +Feature: Allow teachers to bulk edit activity completion rules in a course. + In order to avoid editing single activities + As a teacher + I need to be able to edit the completion rules for a group of activities. + + # Given I am a teacher in a course with completion tracking enabled and activities present. + # When I bulk edit activity completion rules for activities of the same kind. + # Then the completion rules should be updated for all selected activities. + @javascript + Scenario: Bulk edit activity completion rules + Given the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | Frist | teacher1@example.com | + | student1 | Student | First | student1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + And the following "activities" exist: + | activity | course | idnumber | name | intro | grade | + | assign | C1 | a1 | Test assignment one | Submit something! | 300 | + | assign | C1 | a2 | Test assignment two | Submit something! | 100 | + | assign | C1 | a3 | Test assignment three | Submit something! | 150 | + | assign | C1 | a4 | Test assignment four | Submit nothing! | 150 | + And I log in as "teacher1" + And I am on site homepage + And I follow "Course 1" + And I turn editing mode on + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | Enable completion tracking | Yes | + And I press "Save and display" + When I navigate to "Course completion" in current page administration + And I follow "Bulk edit activity completion" + And I click on "Test assignment one" "checkbox" + And I click on "Test assignment two" "checkbox" + And I click on "Edit" "button" + And I should see "Completion tracking" + And I should see "The changes will affect the following 2 Activities/Resources" + And I should see "Student must submit to this activity to complete it" + And I select "Show activity as complete when conditions are met" from the "completion" singleselect + And I click on "completionview" "checkbox" + And I click on "completionusegrade" "checkbox" + And I click on "completionsubmit" "checkbox" + And I click on "Save changes" "button" + Then I should see "Updated completion for activity Test assignment one" + And I should see "Updated completion for activity Test assignment two" + And I should see "With conditions" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Test assignment one']]" "xpath_element" + And I should see "Student must view this activity to complete it" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Test assignment one']]" "xpath_element" + And I should see "Student must receive a grade to complete this activity" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Test assignment one']]" "xpath_element" + And I should see "Student must submit to this activity to complete it" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Test assignment one']]" "xpath_element" + And I should not see "Completion expected on" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Test assignment one']]" "xpath_element" + And I should see "With conditions" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Test assignment two']]" "xpath_element" + And I should see "Student must view this activity to complete it" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Test assignment two']]" "xpath_element" + And I should see "Student must receive a grade to complete this activity" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Test assignment two']]" "xpath_element" + And I should see "Student must submit to this activity to complete it" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Test assignment two']]" "xpath_element" + And I should not see "Completion expected on" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Test assignment two']]" "xpath_element" + diff --git a/completion/tests/behat/default_activity_completion.feature b/completion/tests/behat/default_activity_completion.feature new file mode 100644 index 00000000000..f9efd6edc20 --- /dev/null +++ b/completion/tests/behat/default_activity_completion.feature @@ -0,0 +1,53 @@ +@core @core_completion +Feature: Allow teachers to bulk edit activity completion rules in a course. + In order to avoid editing single activities + As a teacher + I need to be able to edit the completion rules for a group of activities. + + # Given I am a teacher in a course with completion tracking enabled and activities present. + # When I edit activity completion defaults for activity types. + # Then the completion rule defaults should apply only to activities created from that point onwards. + @javascript + Scenario: Bulk edit activity completion rules + Given the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | Frist | teacher1@example.com | + | student1 | Student | First | student1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + And the following "activities" exist: + | activity | course | idnumber | name | intro | grade | + | assign | C1 | a1 | Test assignment one | Submit something! | 300 | + And I log in as "teacher1" + And I am on site homepage + And I follow "Course 1" + And I turn editing mode on + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | Enable completion tracking | Yes | + And I press "Save and display" + When I navigate to "Course completion" in current page administration + And I follow "Default activity completion" + And I click on "Assignments" "checkbox" + And I click on "Edit" "button" + And I should see "Completion tracking" + And I should see "The changes will affect the following 1 Activities/Resources" + And I should see "Student must submit to this activity to complete it" + And I select "Show activity as complete when conditions are met" from the "completion" singleselect + And I click on "completionview" "checkbox" + And I click on "completionusegrade" "checkbox" + And I click on "completionsubmit" "checkbox" + And I click on "Save changes" "button" + #Then I should see "Updated completion for activity Test assignment one" + #And I should see "Updated completion for activity Test assignment two" + And I should see "With conditions" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element" + And I should see "Student must view this activity to complete it" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element" + And I should see "Student must receive a grade to complete this activity" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element" + And I should see "Student must submit to this activity to complete it" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element" + And I should not see "Completion expected on" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element" + diff --git a/course/templates/activityinstance.mustache b/course/templates/activityinstance.mustache index 3843a8c4473..fab2fe96798 100644 --- a/course/templates/activityinstance.mustache +++ b/course/templates/activityinstance.mustache @@ -38,7 +38,8 @@
{{#canmanage}} - + + {{/canmanage}}  @@ -46,7 +47,7 @@
-
+
{{#completionstatus.icon}}  diff --git a/mod/assign/tests/lib_test.php b/mod/assign/tests/lib_test.php index 62e3bdd712c..f6412d6a652 100644 --- a/mod/assign/tests/lib_test.php +++ b/mod/assign/tests/lib_test.php @@ -607,4 +607,31 @@ class mod_assign_lib_testcase extends mod_assign_base_testcase { return calendar_event::create($event); } + + /** + * Test the callback responsible for returning the completion rule descriptions. + * This function should work given either an instance of the module (cm_info), such as when checking the active rules, + * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type. + */ + public function test_mod_assign_completion_get_active_rule_descriptions() { + $this->resetAfterTest(); + $this->setAdminUser(); + + // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't. + $cm1 = $this->create_instance(['completion' => '2', 'completionsubmit' => '1'])->get_course_module(); + $cm2 = $this->create_instance(['completion' => '2', 'completionsubmit' => '0'])->get_course_module(); + + // Data for the stdClass input type. + // This type of input would occur when checking the default completion rules for an activity type, where we don't have + // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info. + $moddefaults = new stdClass(); + $moddefaults->customdata = ['customcompletionrules' => ['completionsubmit' => '1']]; + $moddefaults->completion = 2; + + $activeruledescriptions = [get_string('completionsubmit', 'assign')]; + $this->assertEquals(mod_assign_get_completion_active_rule_descriptions($cm1), $activeruledescriptions); + $this->assertEquals(mod_assign_get_completion_active_rule_descriptions($cm2), []); + $this->assertEquals(mod_assign_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); + $this->assertEquals(mod_assign_get_completion_active_rule_descriptions(new stdClass()), []); + } } diff --git a/mod/choice/tests/lib_test.php b/mod/choice/tests/lib_test.php index 97323c1d94e..540671c9400 100644 --- a/mod/choice/tests/lib_test.php +++ b/mod/choice/tests/lib_test.php @@ -390,7 +390,7 @@ class mod_choice_lib_testcase extends externallib_advanced_testcase { private function create_action_event($courseid, $instanceid, $eventtype) { $event = new stdClass(); $event->name = 'Calendar event'; - $event->modulename = 'choice'; + $event->modulename = 'choice'; $event->courseid = $courseid; $event->instance = $instanceid; $event->type = CALENDAR_EVENT_TYPE_ACTION; @@ -399,4 +399,42 @@ class mod_choice_lib_testcase extends externallib_advanced_testcase { return calendar_event::create($event); } + + /** + * Test the callback responsible for returning the completion rule descriptions. + * This function should work given either an instance of the module (cm_info), such as when checking the active rules, + * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type. + */ + public function test_mod_choice_completion_get_active_rule_descriptions() { + $this->resetAfterTest(); + $this->setAdminUser(); + + // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't. + $course = $this->getDataGenerator()->create_course(['enablecompletion' => 1]); + $choice1 = $this->getDataGenerator()->create_module('choice', [ + 'course' => $course->id, + 'completion' => 2, + 'completionsubmit' => 1 + ]); + $choice2 = $this->getDataGenerator()->create_module('choice', [ + 'course' => $course->id, + 'completion' => 2, + 'completionsubmit' => 0 + ]); + $cm1 = cm_info::create(get_coursemodule_from_instance('choice', $choice1->id)); + $cm2 = cm_info::create(get_coursemodule_from_instance('choice', $choice2->id)); + + // Data for the stdClass input type. + // This type of input would occur when checking the default completion rules for an activity type, where we don't have + // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info. + $moddefaults = new stdClass(); + $moddefaults->customdata = ['customcompletionrules' => ['completionsubmit' => 1]]; + $moddefaults->completion = 2; + + $activeruledescriptions = [get_string('completionsubmit', 'choice')]; + $this->assertEquals(mod_choice_get_completion_active_rule_descriptions($cm1), $activeruledescriptions); + $this->assertEquals(mod_choice_get_completion_active_rule_descriptions($cm2), []); + $this->assertEquals(mod_choice_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); + $this->assertEquals(mod_choice_get_completion_active_rule_descriptions(new stdClass()), []); + } } diff --git a/mod/feedback/tests/lib_test.php b/mod/feedback/tests/lib_test.php index 5f92789719d..6e8ad88b0dd 100644 --- a/mod/feedback/tests/lib_test.php +++ b/mod/feedback/tests/lib_test.php @@ -125,8 +125,8 @@ class mod_feedback_lib_testcase extends advanced_testcase { 'anonymous_response' => FEEDBACK_ANONYMOUS_NO, 'courseid' => $course->id, ]; - $DB->insert_record('feedback_completed', (object) $record); - $DB->insert_record('feedback_completedtmp', (object) $record); + $DB->insert_record('feedback_completed', (object)$record); + $DB->insert_record('feedback_completedtmp', (object)$record); // Check now for finished and unfinished attempts. $updates = feedback_check_updates_since($cm, $onehourago); @@ -240,7 +240,7 @@ class mod_feedback_lib_testcase extends advanced_testcase { private function create_action_event($courseid, $instanceid, $eventtype) { $event = new stdClass(); $event->name = 'Calendar event'; - $event->modulename = 'feedback'; + $event->modulename = 'feedback'; $event->courseid = $courseid; $event->instance = $instanceid; $event->type = CALENDAR_EVENT_TYPE_ACTION; @@ -249,4 +249,42 @@ class mod_feedback_lib_testcase extends advanced_testcase { return calendar_event::create($event); } + + /** + * Test the callback responsible for returning the completion rule descriptions. + * This function should work given either an instance of the module (cm_info), such as when checking the active rules, + * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type. + */ + public function test_mod_feedback_completion_get_active_rule_descriptions() { + $this->resetAfterTest(); + $this->setAdminUser(); + + // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't. + $course = $this->getDataGenerator()->create_course(['enablecompletion' => 2]); + $feedback1 = $this->getDataGenerator()->create_module('feedback', [ + 'course' => $course->id, + 'completion' => 2, + 'completionsubmit' => 1 + ]); + $feedback2 = $this->getDataGenerator()->create_module('feedback', [ + 'course' => $course->id, + 'completion' => 2, + 'completionsubmit' => 0 + ]); + $cm1 = cm_info::create(get_coursemodule_from_instance('feedback', $feedback1->id)); + $cm2 = cm_info::create(get_coursemodule_from_instance('feedback', $feedback2->id)); + + // Data for the stdClass input type. + // This type of input would occur when checking the default completion rules for an activity type, where we don't have + // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info. + $moddefaults = new stdClass(); + $moddefaults->customdata = ['customcompletionrules' => ['completionsubmit' => 1]]; + $moddefaults->completion = 2; + + $activeruledescriptions = [get_string('completionsubmit', 'feedback')]; + $this->assertEquals(mod_feedback_get_completion_active_rule_descriptions($cm1), $activeruledescriptions); + $this->assertEquals(mod_feedback_get_completion_active_rule_descriptions($cm2), []); + $this->assertEquals(mod_feedback_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); + $this->assertEquals(mod_feedback_get_completion_active_rule_descriptions(new stdClass()), []); + } } diff --git a/mod/forum/lib.php b/mod/forum/lib.php index 96e3985bb8e..d1293e2c803 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -8180,7 +8180,6 @@ function mod_forum_get_fontawesome_icon_map() { } /** -<<<<<<< HEAD * Callback function that determines whether an action event should be showing its item count * based on the event type and the item count. * diff --git a/mod/forum/tests/lib_test.php b/mod/forum/tests/lib_test.php index 59ed1cb6fea..4441bf1d0cf 100644 --- a/mod/forum/tests/lib_test.php +++ b/mod/forum/tests/lib_test.php @@ -3519,4 +3519,54 @@ class mod_forum_lib_testcase extends advanced_testcase { return calendar_event::create($event); } + + /** + * Test the callback responsible for returning the completion rule descriptions. + * This function should work given either an instance of the module (cm_info), such as when checking the active rules, + * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type. + */ + public function test_mod_forum_completion_get_active_rule_descriptions() { + $this->resetAfterTest(); + $this->setAdminUser(); + + // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't. + $course = $this->getDataGenerator()->create_course(['enablecompletion' => 2]); + $forum1 = $this->getDataGenerator()->create_module('forum', [ + 'course' => $course->id, + 'completion' => 2, + 'completiondiscussions' => 3, + 'completionreplies' => 3, + 'completionposts' => 3 + ]); + $forum2 = $this->getDataGenerator()->create_module('forum', [ + 'course' => $course->id, + 'completion' => 2, + 'completiondiscussions' => 0, + 'completionreplies' => 0, + 'completionposts' => 0 + ]); + $cm1 = cm_info::create(get_coursemodule_from_instance('forum', $forum1->id)); + $cm2 = cm_info::create(get_coursemodule_from_instance('forum', $forum2->id)); + + // Data for the stdClass input type. + // This type of input would occur when checking the default completion rules for an activity type, where we don't have + // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info. + $moddefaults = new stdClass(); + $moddefaults->customdata = ['customcompletionrules' => [ + 'completiondiscussions' => 3, + 'completionreplies' => 3, + 'completionposts' => 3 + ]]; + $moddefaults->completion = 2; + + $activeruledescriptions = [ + get_string('completiondiscussionsdesc', 'forum', 3), + get_string('completionrepliesdesc', 'forum', 3), + get_string('completionpostsdesc', 'forum', 3) + ]; + $this->assertEquals(mod_forum_get_completion_active_rule_descriptions($cm1), $activeruledescriptions); + $this->assertEquals(mod_forum_get_completion_active_rule_descriptions($cm2), []); + $this->assertEquals(mod_forum_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); + $this->assertEquals(mod_forum_get_completion_active_rule_descriptions(new stdClass()), []); + } } diff --git a/mod/glossary/tests/lib_test.php b/mod/glossary/tests/lib_test.php index df2be0c07f3..49f47592f53 100644 --- a/mod/glossary/tests/lib_test.php +++ b/mod/glossary/tests/lib_test.php @@ -194,4 +194,42 @@ class mod_glossary_lib_testcase extends advanced_testcase { return calendar_event::create($event); } + + /** + * Test the callback responsible for returning the completion rule descriptions. + * This function should work given either an instance of the module (cm_info), such as when checking the active rules, + * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type. + */ + public function test_mod_glossary_completion_get_active_rule_descriptions() { + $this->resetAfterTest(); + $this->setAdminUser(); + + // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't. + $course = $this->getDataGenerator()->create_course(['enablecompletion' => 2]); + $glossary1 = $this->getDataGenerator()->create_module('glossary', [ + 'course' => $course->id, + 'completion' => 2, + 'completionentries' => 3 + ]); + $glossary2 = $this->getDataGenerator()->create_module('glossary', [ + 'course' => $course->id, + 'completion' => 2, + 'completionentries' => 0 + ]); + $cm1 = cm_info::create(get_coursemodule_from_instance('glossary', $glossary1->id)); + $cm2 = cm_info::create(get_coursemodule_from_instance('glossary', $glossary2->id)); + + // Data for the stdClass input type. + // This type of input would occur when checking the default completion rules for an activity type, where we don't have + // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info. + $moddefaults = new stdClass(); + $moddefaults->customdata = ['customcompletionrules' => ['completionentries' => 3]]; + $moddefaults->completion = 2; + + $activeruledescriptions = [get_string('completionentriesdesc', 'glossary', $glossary1->completionentries)]; + $this->assertEquals(mod_glossary_get_completion_active_rule_descriptions($cm1), $activeruledescriptions); + $this->assertEquals(mod_glossary_get_completion_active_rule_descriptions($cm2), []); + $this->assertEquals(mod_glossary_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); + $this->assertEquals(mod_glossary_get_completion_active_rule_descriptions(new stdClass()), []); + } } diff --git a/mod/lesson/tests/lib_test.php b/mod/lesson/tests/lib_test.php index 7bd187d3852..e9a679c24e2 100644 --- a/mod/lesson/tests/lib_test.php +++ b/mod/lesson/tests/lib_test.php @@ -289,4 +289,50 @@ class mod_lesson_lib_testcase extends advanced_testcase { $event->timestart = time(); return calendar_event::create($event); } + + /** + * Test the callback responsible for returning the completion rule descriptions. + * This function should work given either an instance of the module (cm_info), such as when checking the active rules, + * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type. + */ + public function test_mod_lesson_completion_get_active_rule_descriptions() { + $this->resetAfterTest(); + $this->setAdminUser(); + + // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't. + $course = $this->getDataGenerator()->create_course(['enablecompletion' => 2]); + $lesson1 = $this->getDataGenerator()->create_module('lesson', [ + 'course' => $course->id, + 'completion' => 2, + 'completionendreached' => 1, + 'completiontimespent' => 3600 + ]); + $lesson2 = $this->getDataGenerator()->create_module('lesson', [ + 'course' => $course->id, + 'completion' => 2, + 'completionendreached' => 0, + 'completiontimespent' => 0 + ]); + $cm1 = cm_info::create(get_coursemodule_from_instance('lesson', $lesson1->id)); + $cm2 = cm_info::create(get_coursemodule_from_instance('lesson', $lesson2->id)); + + // Data for the stdClass input type. + // This type of input would occur when checking the default completion rules for an activity type, where we don't have + // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info. + $moddefaults = new stdClass(); + $moddefaults->customdata = ['customcompletionrules' => [ + 'completionendreached' => 1, + 'completiontimespent' => 3600 + ]]; + $moddefaults->completion = 2; + + $activeruledescriptions = [ + get_string('completionendreached_desc', 'lesson'), + get_string('completiontimespentdesc', 'lesson', format_time(3600)), + ]; + $this->assertEquals(mod_lesson_get_completion_active_rule_descriptions($cm1), $activeruledescriptions); + $this->assertEquals(mod_lesson_get_completion_active_rule_descriptions($cm2), []); + $this->assertEquals(mod_lesson_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); + $this->assertEquals(mod_lesson_get_completion_active_rule_descriptions(new stdClass()), []); + } } diff --git a/mod/quiz/tests/lib_test.php b/mod/quiz/tests/lib_test.php index a7bf1d2df6c..a260a05522b 100644 --- a/mod/quiz/tests/lib_test.php +++ b/mod/quiz/tests/lib_test.php @@ -691,4 +691,49 @@ class mod_quiz_lib_testcase extends advanced_testcase { return calendar_event::create($event); } + /** + * Test the callback responsible for returning the completion rule descriptions. + * This function should work given either an instance of the module (cm_info), such as when checking the active rules, + * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type. + */ + public function test_mod_quiz_completion_get_active_rule_descriptions() { + $this->resetAfterTest(); + $this->setAdminUser(); + + // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't. + $course = $this->getDataGenerator()->create_course(['enablecompletion' => 2]); + $quiz1 = $this->getDataGenerator()->create_module('quiz', [ + 'course' => $course->id, + 'completion' => 2, + 'completionattemptsexhausted' => 1, + 'completionpass' => 1 + ]); + $quiz2 = $this->getDataGenerator()->create_module('quiz', [ + 'course' => $course->id, + 'completion' => 2, + 'completionattemptsexhausted' => 0, + 'completionpass' => 0 + ]); + $cm1 = cm_info::create(get_coursemodule_from_instance('quiz', $quiz1->id)); + $cm2 = cm_info::create(get_coursemodule_from_instance('quiz', $quiz2->id)); + + // Data for the stdClass input type. + // This type of input would occur when checking the default completion rules for an activity type, where we don't have + // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info. + $moddefaults = new stdClass(); + $moddefaults->customdata = ['customcompletionrules' => [ + 'completionattemptsexhausted' => 1, + 'completionpass' => 1 + ]]; + $moddefaults->completion = 2; + + $activeruledescriptions = [ + get_string('completionattemptsexhausteddesc', 'quiz'), + get_string('completionpassdesc', 'quiz'), + ]; + $this->assertEquals(mod_quiz_get_completion_active_rule_descriptions($cm1), $activeruledescriptions); + $this->assertEquals(mod_quiz_get_completion_active_rule_descriptions($cm2), []); + $this->assertEquals(mod_quiz_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); + $this->assertEquals(mod_quiz_get_completion_active_rule_descriptions(new stdClass()), []); + } } diff --git a/mod/scorm/lib.php b/mod/scorm/lib.php index a9a0419712c..32ed0268a2b 100644 --- a/mod/scorm/lib.php +++ b/mod/scorm/lib.php @@ -1580,7 +1580,6 @@ function mod_scorm_get_fontawesome_icon_map() { } /** -<<<<<<< HEAD * This standard function will check all instances of this module * and make sure there are up-to-date events created for each of them. * If courseid = 0, then every scorm event in the site is checked, else diff --git a/mod/scorm/tests/lib_test.php b/mod/scorm/tests/lib_test.php index fcc928b9339..6aac2524aec 100644 --- a/mod/scorm/tests/lib_test.php +++ b/mod/scorm/tests/lib_test.php @@ -318,7 +318,7 @@ class mod_scorm_lib_testcase extends externallib_advanced_testcase { private function create_action_event($courseid, $instanceid, $eventtype) { $event = new stdClass(); $event->name = 'Calendar event'; - $event->modulename = 'scorm'; + $event->modulename = 'scorm'; $event->courseid = $courseid; $event->instance = $instanceid; $event->type = CALENDAR_EVENT_TYPE_ACTION; @@ -327,4 +327,63 @@ class mod_scorm_lib_testcase extends externallib_advanced_testcase { return calendar_event::create($event); } + + /** + * Test the callback responsible for returning the completion rule descriptions. + * This function should work given either an instance of the module (cm_info), such as when checking the active rules, + * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type. + */ + public function test_mod_scorm_completion_get_active_rule_descriptions() { + $this->resetAfterTest(); + $this->setAdminUser(); + + // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't. + $course = $this->getDataGenerator()->create_course(['enablecompletion' => 2]); + $scorm1 = $this->getDataGenerator()->create_module('scorm', [ + 'course' => $course->id, + 'completion' => 2, + 'completionstatusrequired' => 6, + 'completionscorerequired' => 5, + 'completionstatusallscos' => 1 + ]); + $scorm2 = $this->getDataGenerator()->create_module('scorm', [ + 'course' => $course->id, + 'completion' => 2, + 'completionstatusrequired' => null, + 'completionscorerequired' => null, + 'completionstatusallscos' => null + ]); + $cm1 = cm_info::create(get_coursemodule_from_instance('scorm', $scorm1->id)); + $cm2 = cm_info::create(get_coursemodule_from_instance('scorm', $scorm2->id)); + + // Data for the stdClass input type. + // This type of input would occur when checking the default completion rules for an activity type, where we don't have + // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info. + $moddefaults = new stdClass(); + $moddefaults->customdata = ['customcompletionrules' => [ + 'completionstatusrequired' => 6, + 'completionscorerequired' => 5, + 'completionstatusallscos' => 1 + ]]; + $moddefaults->completion = 2; + + // Determine the selected statuses using a bitwise operation. + $cvalues = array(); + foreach (scorm_status_options(true) as $key => $value) { + if (($scorm1->completionstatusrequired & $key) == $key) { + $cvalues[] = $value; + } + } + $statusstring = implode(', ', $cvalues); + + $activeruledescriptions = [ + get_string('completionstatusrequireddesc', 'scorm', $statusstring), + get_string('completionscorerequireddesc', 'scorm', $scorm1->completionscorerequired), + get_string('completionstatusallscos', 'scorm'), + ]; + $this->assertEquals(mod_scorm_get_completion_active_rule_descriptions($cm1), $activeruledescriptions); + $this->assertEquals(mod_scorm_get_completion_active_rule_descriptions($cm2), []); + $this->assertEquals(mod_scorm_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); + $this->assertEquals(mod_scorm_get_completion_active_rule_descriptions(new stdClass()), []); + } } diff --git a/mod/survey/tests/lib_test.php b/mod/survey/tests/lib_test.php index 545b96a175b..e3994ab10ad 100644 --- a/mod/survey/tests/lib_test.php +++ b/mod/survey/tests/lib_test.php @@ -275,4 +275,42 @@ class mod_survey_lib_testcase extends advanced_testcase { return calendar_event::create($event); } + + /** + * Test the callback responsible for returning the completion rule descriptions. + * This function should work given either an instance of the module (cm_info), such as when checking the active rules, + * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type. + */ + public function test_mod_survey_completion_get_active_rule_descriptions() { + $this->resetAfterTest(); + $this->setAdminUser(); + + // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't. + $course = $this->getDataGenerator()->create_course(['enablecompletion' => 2]); + $survey1 = $this->getDataGenerator()->create_module('survey', [ + 'course' => $course->id, + 'completion' => 2, + 'completionsubmit' => 1, + ]); + $survey2 = $this->getDataGenerator()->create_module('survey', [ + 'course' => $course->id, + 'completion' => 2, + 'completionsubmit' => 0, + ]); + $cm1 = cm_info::create(get_coursemodule_from_instance('survey', $survey1->id)); + $cm2 = cm_info::create(get_coursemodule_from_instance('survey', $survey2->id)); + + // Data for the stdClass input type. + // This type of input would occur when checking the default completion rules for an activity type, where we don't have + // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info. + $moddefaults = new stdClass(); + $moddefaults->customdata = ['customcompletionrules' => ['completionsubmit' => 1]]; + $moddefaults->completion = 2; + + $activeruledescriptions = [get_string('completionsubmit', 'survey')]; + $this->assertEquals(mod_survey_get_completion_active_rule_descriptions($cm1), $activeruledescriptions); + $this->assertEquals(mod_survey_get_completion_active_rule_descriptions($cm2), []); + $this->assertEquals(mod_survey_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); + $this->assertEquals(mod_survey_get_completion_active_rule_descriptions(new stdClass()), []); + } }