From c4cd3a61c847e28ae04182d5560f868c9f42e0ad Mon Sep 17 00:00:00 2001 From: Ilya Tregubov Date: Thu, 7 Jul 2022 16:09:55 +0400 Subject: [PATCH 1/6] MDL-75173 core_completion: Fix course completion criteria marking. SQL was fetching activities where completion state was 'completed, but not passed reqyured grade'. For course completion such states must be ignored. Also fixed progress bar on my courses page. Same reasoning as above. --- completion/classes/api.php | 2 - completion/classes/progress.php | 6 +- ...ourse_completion_activity_criteria.feature | 90 +++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 completion/tests/behat/course_completion_activity_criteria.feature diff --git a/completion/classes/api.php b/completion/classes/api.php index 4912f514cfe..edec5a49e8a 100644 --- a/completion/classes/api.php +++ b/completion/classes/api.php @@ -151,7 +151,6 @@ class api { AND ( mc.completionstate = :completionstate OR mc.completionstate = :completionstatepass - OR mc.completionstate = :completionstatefail )"; $params = [ @@ -159,7 +158,6 @@ class api { 'contextlevel' => CONTEXT_COURSE, 'completionstate' => COMPLETION_COMPLETE, 'completionstatepass' => COMPLETION_COMPLETE_PASS, - 'completionstatefail' => COMPLETION_COMPLETE_FAIL ]; if ($userdata) { diff --git a/completion/classes/progress.php b/completion/classes/progress.php index 49702f4d4fd..c95352259f5 100644 --- a/completion/classes/progress.php +++ b/completion/classes/progress.php @@ -80,7 +80,11 @@ class progress { $completed = 0; foreach ($modules as $module) { $data = $completion->get_data($module, true, $userid); - $completed += $data->completionstate == COMPLETION_INCOMPLETE ? 0 : 1; + if (($data->completionstate == COMPLETION_INCOMPLETE) || ($data->completionstate == COMPLETION_COMPLETE_FAIL)) { + $completed += 0; + } else { + $completed += 1; + }; } return ($completed / $count) * 100; diff --git a/completion/tests/behat/course_completion_activity_criteria.feature b/completion/tests/behat/course_completion_activity_criteria.feature new file mode 100644 index 00000000000..3d1b69b5cf7 --- /dev/null +++ b/completion/tests/behat/course_completion_activity_criteria.feature @@ -0,0 +1,90 @@ +@block @block_completionstatus @javascript +Feature: Course completion state should match completion criteria + In order to understand the configuration or status of an course's completion + As a user + I need to see the appropriate completion information on course and dashboard pages + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | idnumber | + | teacher1 | Teacher | 1 | teacher1@example.com | T1 | + | teacher2 | Teacher | 2 | teacher1@example.com | T2 | + | student1 | Student | 1 | student1@example.com | S1 | + And the following "courses" exist: + | fullname | shortname | category | enablecompletion | showcompletionconditions | + | Course 1 | C1 | 0 | 1 | 1 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | teacher2 | C1 | teacher | + | student1 | C1 | student | + And the following "activity" exists: + | activity | assign | + | course | C1 | + | section | 1 | + | name | Test assignment name | + | intro | Submit your online text | + | completion | 1 | + | assignsubmission_onlinetext_enabled | 1 | + | grade[modgrade_type] | Point | + | grade[modgrade_point] | 100 | + And I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I navigate to "Course completion" in current page administration + And I click on "Condition: Activity completion" "link" + And I set the field "Assignment - Test assignment name" to "1" + And I press "Save changes" + And I add the "Course completion status" block + And I am on the "Test assignment name" "assign activity" page + And I navigate to "Settings" in current page administration + And I set the following fields to these values: + | Completion tracking | Show activity as complete when conditions are met | + | completionusegrade | 1 | + | completionpassgrade | 1 | + | gradepass | 70 | + And I press "Save and return to course" + And I log out + + Scenario: Completion status show match completion criteria. + Given I log in as "student1" + And I am on "Course 1" course homepage + And the "Receive a grade" completion condition of "Test assignment name" is displayed as "todo" + And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "todo" + And I should see "Status: Not yet started" in the "Course completion status" "block" + And I am on the "Test assignment name" "assign activity" page + And I press "Add submission" + And I set the following fields to these values: + | Online text | I'm the student1 submission | + And I press "Save changes" + And I press "Submit assignment" + And I press "Continue" + And I log out + And I am on the "Test assignment name" "assign activity" page logged in as teacher1 + And I follow "View all submissions" + And I click on "Grade" "link" in the "Student 1" "table_row" + And I set the following fields to these values: + | Grade out of 100 | 50.0 | + And I press "Save changes" + And I log out + When I log in as "student1" + And I am on "Course 1" course homepage + And I should see "Status: Pending" in the "Course completion status" "block" + And the "Receive a grade" completion condition of "Test assignment name" is displayed as "done" + And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "failed" + And I am on the "My courses" page + And I should not see "100%" in the "Course overview" "block" + And I log out + And I am on the "Test assignment name" "assign activity" page logged in as teacher1 + And I follow "View all submissions" + And I click on "Grade" "link" in the "Student 1" "table_row" + And I set the following fields to these values: + | Grade out of 100 | 75.0 | + And I press "Save changes" + And I log out + And I log in as "student1" + And I am on "Course 1" course homepage + And I should see "Status: Complete" in the "Course completion status" "block" + And the "Receive a grade" completion condition of "Test assignment name" is displayed as "done" + And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "done" + And I am on the "My courses" page + Then I should see "100%" in the "Course overview" "block" From aa34b109a4893cf9a8ab9622555b992f7b0bbe03 Mon Sep 17 00:00:00 2001 From: Ilya Tregubov Date: Fri, 8 Jul 2022 15:13:20 +0400 Subject: [PATCH 2/6] MDL-75173 behat: Fix broken test. Test was testing failing state when student didn't receive passing grade. But it was expecting that completion criteria is completed which was wrong. --- .../behat/block_completionstatus_activity_completion.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/completionstatus/tests/behat/block_completionstatus_activity_completion.feature b/blocks/completionstatus/tests/behat/block_completionstatus_activity_completion.feature index a3094956a65..32f1ca06837 100644 --- a/blocks/completionstatus/tests/behat/block_completionstatus_activity_completion.feature +++ b/blocks/completionstatus/tests/behat/block_completionstatus_activity_completion.feature @@ -133,4 +133,4 @@ Feature: Enable Block Completion in a course using activity completion And I am on "Course 1" course homepage And I follow "More details" And I should see "Achieving grade, Achieving passing grade" in the "Activity completion" "table_row" - And I should see "Yes" in the "Activity completion" "table_row" + And I should see "No" in the "Activity completion" "table_row" From 289d5f3faaa6cc1a8242f8d8aa1ddc8ee3a2a293 Mon Sep 17 00:00:00 2001 From: Ilya Tregubov Date: Fri, 8 Jul 2022 15:15:23 +0400 Subject: [PATCH 3/6] MDL-75173 core_completion: Inconsistent status check. There is inconsistent status check for course completion block and completion details page. Completion block was taking to account pending statuses for completion criteria while completion details page was ignoring those. --- blocks/completionstatus/details.php | 51 +++++++++++++++++------------ 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/blocks/completionstatus/details.php b/blocks/completionstatus/details.php index ec48b4b15ea..b493e1dd862 100644 --- a/blocks/completionstatus/details.php +++ b/blocks/completionstatus/details.php @@ -110,7 +110,36 @@ $params = array( ); $ccompletion = new completion_completion($params); -if ($coursecomplete) { +// Save row data. +$rows = array(); + +// Flag to set if current completion data is inconsistent with what is stored in the database. +$pendingupdate = false; + +// Load criteria to display. +$completions = $info->get_completions($user->id); + +// Loop through course criteria. +foreach ($completions as $completion) { + $criteria = $completion->get_criteria(); + + if (!$pendingupdate && $criteria->is_pending($completion)) { + $pendingupdate = true; + } + + $row = array(); + $row['type'] = $criteria->criteriatype; + $row['title'] = $criteria->get_title(); + $row['status'] = $completion->get_status(); + $row['complete'] = $completion->is_complete(); + $row['timecompleted'] = $completion->timecompleted; + $row['details'] = $criteria->get_details($completion); + $rows[] = $row; +} + +if ($pendingupdate) { + echo html_writer::tag('i', get_string('pending', 'completion')); +} else if ($coursecomplete) { echo get_string('complete'); } else if (!$criteriacomplete && !$ccompletion->timestarted) { echo html_writer::tag('i', get_string('notyetstarted', 'completion')); @@ -121,9 +150,6 @@ if ($coursecomplete) { echo html_writer::end_tag('td'); echo html_writer::end_tag('tr'); -// Load criteria to display. -$completions = $info->get_completions($user->id); - // Check if this course has any criteria. if (empty($completions)) { echo html_writer::start_tag('tr'); @@ -166,23 +192,6 @@ if (empty($completions)) { echo html_writer::tag('th', get_string('completiondate', 'report_completion'), array('class' => 'c5 header', 'scope' => 'col')); echo html_writer::end_tag('tr'); - // Save row data. - $rows = array(); - - // Loop through course criteria. - foreach ($completions as $completion) { - $criteria = $completion->get_criteria(); - - $row = array(); - $row['type'] = $criteria->criteriatype; - $row['title'] = $criteria->get_title(); - $row['status'] = $completion->get_status(); - $row['complete'] = $completion->is_complete(); - $row['timecompleted'] = $completion->timecompleted; - $row['details'] = $criteria->get_details($completion); - $rows[] = $row; - } - // Print table. $last_type = ''; $agg_type = false; From 1a7d05eca779b86661902e225507881c9b0cb50c Mon Sep 17 00:00:00 2001 From: Ilya Tregubov Date: Thu, 4 Aug 2022 14:01:57 +0400 Subject: [PATCH 4/6] MDL-75173 core_completion: Fix completion for different settings. --- completion/classes/api.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/completion/classes/api.php b/completion/classes/api.php index edec5a49e8a..6a1bc31be9a 100644 --- a/completion/classes/api.php +++ b/completion/classes/api.php @@ -142,6 +142,7 @@ class api { INNER JOIN {course} c ON cr.course = c.id INNER JOIN {context} con ON con.instanceid = c.id INNER JOIN {role_assignments} ra ON ra.contextid = con.id + INNER JOIN {course_modules} cm ON cm.id = cr.moduleinstance INNER JOIN {course_modules_completion} mc ON mc.coursemoduleid = cr.moduleinstance AND mc.userid = ra.userid LEFT JOIN {course_completion_crit_compl} cc ON cc.criteriaid = cr.id AND cc.userid = ra.userid WHERE cr.criteriatype = :criteriatype @@ -150,14 +151,17 @@ class api { AND cc.id IS NULL AND ( mc.completionstate = :completionstate - OR mc.completionstate = :completionstatepass + OR (cm.completionpassgrade = 1 AND mc.completionstate = :completionstatepass1) + OR (cm.completionpassgrade = 0 AND (mc.completionstate = :completionstatepass2 OR mc.completionstate = :completionstatefail)) )"; $params = [ 'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY, 'contextlevel' => CONTEXT_COURSE, 'completionstate' => COMPLETION_COMPLETE, - 'completionstatepass' => COMPLETION_COMPLETE_PASS, + 'completionstatepass1' => COMPLETION_COMPLETE_PASS, + 'completionstatepass2' => COMPLETION_COMPLETE_PASS, + 'completionstatefail' => COMPLETION_COMPLETE_FAIL ]; if ($userdata) { From 59303de673df7ed50f9907ebbc2985b574cb6c76 Mon Sep 17 00:00:00 2001 From: Ilya Tregubov Date: Mon, 10 Oct 2022 10:00:21 +0400 Subject: [PATCH 5/6] MDL-75173 core_completion: Fixes after review. Unit tests added. Used new steps in Behat. Code style fix for long line. --- completion/classes/api.php | 3 +- completion/tests/api_test.php | 97 +++++++++++++++++++ ...ourse_completion_activity_criteria.feature | 9 +- 3 files changed, 102 insertions(+), 7 deletions(-) diff --git a/completion/classes/api.php b/completion/classes/api.php index 6a1bc31be9a..d4c83a238ce 100644 --- a/completion/classes/api.php +++ b/completion/classes/api.php @@ -152,7 +152,8 @@ class api { AND ( mc.completionstate = :completionstate OR (cm.completionpassgrade = 1 AND mc.completionstate = :completionstatepass1) - OR (cm.completionpassgrade = 0 AND (mc.completionstate = :completionstatepass2 OR mc.completionstate = :completionstatefail)) + OR (cm.completionpassgrade = 0 AND (mc.completionstate = :completionstatepass2 + OR mc.completionstate = :completionstatefail)) )"; $params = [ diff --git a/completion/tests/api_test.php b/completion/tests/api_test.php index a18f3706c5e..4875a69f367 100644 --- a/completion/tests/api_test.php +++ b/completion/tests/api_test.php @@ -287,4 +287,101 @@ class api_test extends \advanced_testcase { $this->assertEquals($student1->id, reset($actual)->userid); $this->assertEquals($student2->id, end($actual)->userid); } + + /** + * Test for mark_course_completions_activity_criteria() with different completionpassgrade settings. + * @covers ::mark_course_completions_activity_criteria + */ + public function test_mark_course_completions_activity_criteria_completion_states() { + global $DB, $CFG; + require_once($CFG->dirroot . '/completion/criteria/completion_criteria_activity.php'); + $this->resetAfterTest(true); + + $courses[] = $this->getDataGenerator()->create_course(['shortname' => 'completionpassgradenotset', + 'enablecompletion' => 1]); + $courses[] = $this->getDataGenerator()->create_course(['shortname' => 'completionpassgradeset', + 'enablecompletion' => 1]); + + $student1 = $this->getDataGenerator()->create_user(); + $student2 = $this->getDataGenerator()->create_user(); + + $teacher = $this->getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); + + foreach ($courses as $course) { + $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); + $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); + $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); + + $completioncriteria = [ + 'completionusegrade' => 1, + 'gradepass' => 50 + ]; + + if ($course->shortname == 'completionpassgradeset') { + $completioncriteria['completionpassgrade'] = 1; + } + + /** @var \mod_assign_generator $assigngenerator */ + $assigngenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); + $assign = $assigngenerator->create_instance([ + 'course' => $course->id, + 'completion' => COMPLETION_ENABLED, + ] + $completioncriteria); + + $cmassing = get_coursemodule_from_id('assign', $assign->cmid); + $cm = get_coursemodule_from_instance('assign', $assign->id); + $c = new \completion_info($course); + + // Add activity completion criteria. + $criteriadata = new \stdClass(); + $criteriadata->id = $course->id; + $criteriadata->criteria_activity = array(); + // Some activities. + $criteriadata->criteria_activity[$cmassing->id] = 1; + $criterion = new \completion_criteria_activity(); + $criterion->update_config($criteriadata); + + $this->setUser($teacher); + + // Mark user completions. + $completion = new \stdClass(); + $completion->coursemoduleid = $cm->id; + $completion->timemodified = time(); + $completion->viewed = COMPLETION_NOT_VIEWED; + $completion->overrideby = null; + + // Student1 achieved passgrade. + $completion->id = 0; + $completion->completionstate = COMPLETION_COMPLETE_PASS; + $completion->userid = $student1->id; + $c->internal_set_data($cm, $completion, true); + + // Student2 has not achieved passgrade. + $completion->id = 0; + $completion->completionstate = COMPLETION_COMPLETE_FAIL; + $completion->userid = $student2->id; + $c->internal_set_data($cm, $completion, true); + + $actual = $DB->get_records('course_completions', ['course' => $course->id]); + $this->assertEmpty($actual); + + // Run course completions cron. + $coursecompletionid = \core_completion\api::mark_course_completions_activity_criteria(); + $this->assertEquals(0, $coursecompletionid); + $actual = $DB->get_records('course_completions', ['course' => $course->id]); + + if ($course->shortname == 'completionpassgradeset') { + // Only student1 has completed a course. + $this->assertEquals(1, count($actual)); + $this->assertEquals($student1->id, reset($actual)->userid); + } else { + // Both students completed a course. + $this->assertEquals(2, count($actual)); + $this->assertEquals($student1->id, reset($actual)->userid); + $this->assertEquals($student2->id, end($actual)->userid); + } + } + } } diff --git a/completion/tests/behat/course_completion_activity_criteria.feature b/completion/tests/behat/course_completion_activity_criteria.feature index 3d1b69b5cf7..ea0ee3ce0e3 100644 --- a/completion/tests/behat/course_completion_activity_criteria.feature +++ b/completion/tests/behat/course_completion_activity_criteria.feature @@ -46,8 +46,7 @@ Feature: Course completion state should match completion criteria And I log out Scenario: Completion status show match completion criteria. - Given I log in as "student1" - And I am on "Course 1" course homepage + Given I am on the "Course 1" course page logged in as "student1" And the "Receive a grade" completion condition of "Test assignment name" is displayed as "todo" And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "todo" And I should see "Status: Not yet started" in the "Course completion status" "block" @@ -66,8 +65,7 @@ Feature: Course completion state should match completion criteria | Grade out of 100 | 50.0 | And I press "Save changes" And I log out - When I log in as "student1" - And I am on "Course 1" course homepage + When I am on the "Course 1" course page logged in as "student1" And I should see "Status: Pending" in the "Course completion status" "block" And the "Receive a grade" completion condition of "Test assignment name" is displayed as "done" And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "failed" @@ -81,8 +79,7 @@ Feature: Course completion state should match completion criteria | Grade out of 100 | 75.0 | And I press "Save changes" And I log out - And I log in as "student1" - And I am on "Course 1" course homepage + And I am on the "Course 1" course page logged in as "student1" And I should see "Status: Complete" in the "Course completion status" "block" And the "Receive a grade" completion condition of "Test assignment name" is displayed as "done" And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "done" From ddb0f7dc9287dd34d37500ea8878860b1e5c11d1 Mon Sep 17 00:00:00 2001 From: Ilya Tregubov Date: Fri, 14 Oct 2022 11:15:33 +0300 Subject: [PATCH 6/6] MDL-75173 core_completion: More unit tests and Behat. --- ...ourse_completion_activity_criteria.feature | 83 +++++++++++++- completion/tests/progress_test.php | 108 ++++++++++++++++++ 2 files changed, 190 insertions(+), 1 deletion(-) diff --git a/completion/tests/behat/course_completion_activity_criteria.feature b/completion/tests/behat/course_completion_activity_criteria.feature index ea0ee3ce0e3..998fd1656ef 100644 --- a/completion/tests/behat/course_completion_activity_criteria.feature +++ b/completion/tests/behat/course_completion_activity_criteria.feature @@ -45,7 +45,7 @@ Feature: Course completion state should match completion criteria And I press "Save and return to course" And I log out - Scenario: Completion status show match completion criteria. + Scenario: Completion status show match completion criteria when passgrage condition is set. Given I am on the "Course 1" course page logged in as "student1" And the "Receive a grade" completion condition of "Test assignment name" is displayed as "todo" And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "todo" @@ -64,6 +64,14 @@ Feature: Course completion state should match completion criteria And I set the following fields to these values: | Grade out of 100 | 50.0 | And I press "Save changes" + And I am on the "Course 1" course page + And I navigate to "Reports" in current page administration + And I click on "Activity completion" "link" + And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row" + And I navigate to "Reports" in current page administration + And I click on "Course completion" "link" in the "region-main" "region" + And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row" + And "Student 1, Course complete: Not completed" "icon" should exist in the "Student 1" "table_row" And I log out When I am on the "Course 1" course page logged in as "student1" And I should see "Status: Pending" in the "Course completion status" "block" @@ -78,6 +86,14 @@ Feature: Course completion state should match completion criteria And I set the following fields to these values: | Grade out of 100 | 75.0 | And I press "Save changes" + And I am on the "Course 1" course page + And I navigate to "Reports" in current page administration + And I click on "Activity completion" "link" + And "Student 1, Test assignment name: Completed (achieved pass grade)" "icon" should exist in the "Student 1" "table_row" + And I navigate to "Reports" in current page administration + And I click on "Course completion" "link" in the "region-main" "region" + And "Student 1, Test assignment name: Completed (achieved pass grade)" "icon" should exist in the "Student 1" "table_row" + And "Student 1, Course complete: Completed" "icon" should exist in the "Student 1" "table_row" And I log out And I am on the "Course 1" course page logged in as "student1" And I should see "Status: Complete" in the "Course completion status" "block" @@ -85,3 +101,68 @@ Feature: Course completion state should match completion criteria And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "done" And I am on the "My courses" page Then I should see "100%" in the "Course overview" "block" + + Scenario: Completion status show match completion criteria when passgrage condition is not set. + Given I am on the "Course 1" course page logged in as "teacher1" + And I am on the "Test assignment name" "assign activity" page + And I navigate to "Settings" in current page administration + And I set the following fields to these values: + | Completion tracking | Show activity as complete when conditions are met | + | completionusegrade | 1 | + | completionpassgrade | 0 | + | gradepass | 70 | + And I press "Save and return to course" + And I log out + And I am on the "Course 1" course page logged in as "student1" + And the "Receive a grade" completion condition of "Test assignment name" is displayed as "todo" + And I should see "Status: Not yet started" in the "Course completion status" "block" + And I am on the "Test assignment name" "assign activity" page + And I press "Add submission" + And I set the following fields to these values: + | Online text | I'm the student1 submission | + And I press "Save changes" + And I press "Submit assignment" + And I press "Continue" + And I log out + And I am on the "Test assignment name" "assign activity" page logged in as teacher1 + And I follow "View all submissions" + And I click on "Grade" "link" in the "Student 1" "table_row" + And I set the following fields to these values: + | Grade out of 100 | 50.0 | + And I press "Save changes" + And I am on the "Course 1" course page + And I navigate to "Reports" in current page administration + And I click on "Activity completion" "link" + And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row" + And I navigate to "Reports" in current page administration + And I click on "Course completion" "link" in the "region-main" "region" + And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row" + And "Student 1, Course complete: Completed" "icon" should exist in the "Student 1" "table_row" + And I log out + When I am on the "Course 1" course page logged in as "student1" + And I should see "Status: Complete" in the "Course completion status" "block" + # Once MDL-75582 is fixed "failed" should be changed to "done" + And the "Receive a grade" completion condition of "Test assignment name" is displayed as "failed" + And I am on the "My courses" page + And I should see "100%" in the "Course overview" "block" + And I log out + And I am on the "Test assignment name" "assign activity" page logged in as teacher1 + And I follow "View all submissions" + And I click on "Grade" "link" in the "Student 1" "table_row" + And I set the following fields to these values: + | Grade out of 100 | 75.0 | + And I press "Save changes" + And I am on the "Course 1" course page + And I navigate to "Reports" in current page administration + And I click on "Activity completion" "link" + And "Student 1, Test assignment name: Completed (achieved pass grade)" "icon" should exist in the "Student 1" "table_row" + And I navigate to "Reports" in current page administration + And I click on "Course completion" "link" in the "region-main" "region" + And "Student 1, Test assignment name: Completed (achieved pass grade)" "icon" should exist in the "Student 1" "table_row" + And "Student 1, Course complete: Completed" "icon" should exist in the "Student 1" "table_row" + And I log out + And I am on the "Course 1" course page logged in as "student1" + And I should see "Status: Complete" in the "Course completion status" "block" + And the "Receive a grade" completion condition of "Test assignment name" is displayed as "done" + And I am on the "My courses" page + Then I should see "100%" in the "Course overview" "block" diff --git a/completion/tests/progress_test.php b/completion/tests/progress_test.php index 08785fa3b25..16f77290acd 100644 --- a/completion/tests/progress_test.php +++ b/completion/tests/progress_test.php @@ -120,6 +120,114 @@ class progress_test extends \advanced_testcase { $this->assertEquals('100', \core_completion\progress::get_course_progress_percentage($course, $user->id)); } + /** + * Tests that the course progress percentage is returned correctly for various grade to pass settings + * + * @covers \core_completion\progress::get_course_progress_percentage. + */ + public function test_course_progress_percentage_completion_state() { + global $DB; + + // Add a course that supports completion. + $course = $this->getDataGenerator()->create_course(['enablecompletion' => 1]); + + // Enrol a user in the course. + $teacher = $this->getDataGenerator()->create_user(); + $user = $this->getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', ['shortname' => 'student']); + $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); + $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); + $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); + + // Add three activities that use completion. + /** @var \mod_assign_generator $assigngenerator */ + $assigngenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); + $assign['passgragepassed'] = $assigngenerator->create_instance([ + 'course' => $course->id, + 'completion' => COMPLETION_ENABLED, + 'completionusegrade' => 1, + 'gradepass' => 50, + 'completionpassgrade' => 1 + ]); + + $assign['passgragefailed'] = $assigngenerator->create_instance([ + 'course' => $course->id, + 'completion' => COMPLETION_ENABLED, + 'completionusegrade' => 1, + 'gradepass' => 50, + 'completionpassgrade' => 1 + ]); + + $assign['passgragenotused'] = $assigngenerator->create_instance([ + 'course' => $course->id, + 'completion' => COMPLETION_ENABLED, + 'completionusegrade' => 1, + 'gradepass' => 50, + ]); + + $assign['nograde'] = $assigngenerator->create_instance([ + 'course' => $course->id, + 'completion' => COMPLETION_ENABLED, + ]); + + $c = new \completion_info($course); + + foreach ($assign as $item) { + $cmassing = get_coursemodule_from_id('assign', $item->cmid); + + // Add activity completion criteria. + $criteriadata = new \stdClass(); + $criteriadata->id = $course->id; + $criteriadata->criteria_activity = []; + // Some activities. + $criteriadata->criteria_activity[$cmassing->id] = 1; + $criterion = new \completion_criteria_activity(); + $criterion->update_config($criteriadata); + } + + $this->setUser($teacher); + + foreach ($assign as $key => $item) { + $cm = get_coursemodule_from_instance('assign', $item->id); + + // Mark user completions. + $completion = new \stdClass(); + $completion->coursemoduleid = $cm->id; + $completion->timemodified = time(); + $completion->viewed = COMPLETION_NOT_VIEWED; + $completion->overrideby = null; + + if ($key == 'passgragepassed') { + $completion->id = 0; + $completion->completionstate = COMPLETION_COMPLETE_PASS; + $completion->userid = $user->id; + $c->internal_set_data($cm, $completion, true); + } else if ($key == 'passgragefailed') { + $completion->id = 0; + $completion->completionstate = COMPLETION_COMPLETE_FAIL; + $completion->userid = $user->id; + $c->internal_set_data($cm, $completion, true); + } else if ($key == 'passgragenotused') { + $completion->id = 0; + $completion->completionstate = COMPLETION_COMPLETE; + $completion->userid = $user->id; + $c->internal_set_data($cm, $completion, true); + } else if ($key == 'nograde') { + $completion->id = 0; + $completion->completionstate = COMPLETION_COMPLETE; + $completion->userid = $user->id; + $c->internal_set_data($cm, $completion, true); + } + } + + // Run course completions cron. + \core_completion\api::mark_course_completions_activity_criteria(); + + // Check we have received valid data. + // Only assign2 is not completed. + $this->assertEquals('75', \core_completion\progress::get_course_progress_percentage($course, $user->id)); + } + /** * Tests that the course progress returns null when the course does not support it. */