MDL-75572 criteria: Only award badges to sucessfull completions

The UX team confirmed a badge shouldn't be awarded when the criteria
use a passing grade and the user gets a failing grade.
So the COMPLETION_COMPLETE_FAIL status won't be considered
completed for activities with completion that require a passing
grade.
This commit is contained in:
Sara Arjona 2023-10-04 17:13:47 +02:00
parent d76e211be6
commit 95e50b59ea
No known key found for this signature in database
3 changed files with 92 additions and 81 deletions

View file

@ -14,20 +14,17 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
use \core_badges\badge;
/** /**
* Local stuff for category enrolment plugin. * Event observer for badges.
* *
* @package core_badges * @package core_badges
* @copyright 2013 Rajesh Taneja <rajesh@moodle.com> * @copyright 2013 Rajesh Taneja <rajesh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
defined('MOODLE_INTERNAL') || die();
use \core_badges\badge;
/**
* Event observer for badges.
*/
class core_badges_observer { class core_badges_observer {
/** /**
* Triggered when 'course_module_completion_updated' event is triggered. * Triggered when 'course_module_completion_updated' event is triggered.

View file

@ -188,8 +188,6 @@ class award_criteria_activity extends award_criteria {
* @return bool Whether criteria is complete * @return bool Whether criteria is complete
*/ */
public function review($userid, $filtered = false) { public function review($userid, $filtered = false) {
$completionstates = array(COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL);
if ($this->course->startdate > time()) { if ($this->course->startdate > time()) {
return false; return false;
} }
@ -209,6 +207,15 @@ class award_criteria_activity extends award_criteria {
$check_date = ($date <= $param['bydate']); $check_date = ($date <= $param['bydate']);
} }
// Successfull completion states depend on the completion settings.
if (isset($data->passgrade)) {
// Passing grade is required. Don't issue a badge when state is COMPLETION_COMPLETE_FAIL.
$completionstates = [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS];
} else {
// Any grade is required. Issue a badge even when state is COMPLETION_COMPLETE_FAIL.
$completionstates = [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL];
}
if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) { if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) {
if (in_array($data->completionstate, $completionstates) && $check_date) { if (in_array($data->completionstate, $completionstates) && $check_date) {
$overall = true; $overall = true;

View file

@ -1,14 +1,14 @@
@mod @mod_quiz @core @core_badges @javascript @mod @mod_quiz @core @core_badges @core_completion @javascript
Feature: Award badges based on activity completion Feature: Award badges based on activity completion
In order to ensure a student has learned the material before being marked complete In order to ensure a student has learned the material before being marked complete
As a teacher As a teacher
I need to set a quiz to award a badge when upon completion when the student receives a passing grade, or completed_fail if they use all attempts without passing I need to configure an activity to grant a badge only when the student achieves a passing grade upon completion.
Background: Background:
Given the following "users" exist: Given the following "users" exist:
| username | firstname | lastname | email | | username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com | | student1 | Student | 1 | student1@example.com |
| student2 | Student | 1 | student2@example.com | | student2 | Student | 2 | student2@example.com |
| teacher1 | Teacher | 1 | teacher1@example.com | | teacher1 | Teacher | 1 | teacher1@example.com |
And the following "courses" exist: And the following "courses" exist:
| fullname | shortname | category | enablecompletion | | fullname | shortname | category | enablecompletion |
@ -27,96 +27,103 @@ Feature: Award badges based on activity completion
| questioncategory | qtype | name | questiontext | | questioncategory | qtype | name | questiontext |
| Test questions | truefalse | First question | Answer the first question | | Test questions | truefalse | First question | Answer the first question |
And the following "activities" exist: And the following "activities" exist:
| activity | name | course | idnumber | attempts | gradepass | completion | completionattemptsexhausted | completionpassgrade | completionusegrade | | activity | name | course | idnumber | attempts | gradepass | completion | completionpassgrade | completionusegrade |
| quiz | Test quiz name | C1 | quiz1 | 2 | 5.00 | 2 | 1 | 1 | 1 | | quiz | Test quiz name 1 | C1 | quiz1 | 2 | 5.00 | 2 | 1 | 1 |
And quiz "Test quiz name" contains the following questions: | quiz | Test quiz name 2 | C1 | quiz2 | 2 | 5.00 | 2 | 0 | 1 |
And quiz "Test quiz name 1" contains the following questions:
| question | page |
| First question | 1 |
And quiz "Test quiz name 2" contains the following questions:
| question | page | | question | page |
| First question | 1 | | First question | 1 |
And user "student1" has attempted "Test quiz name" with responses:
| slot | response |
| 1 | False |
And user "student2" has attempted "Test quiz name" with responses:
| slot | response |
| 1 | False |
And the following "core_badges > Badge" exists: And the following "core_badges > Badge" exists:
| name | Course Badge | | name | Course Badge 1 |
| status | 0 | | status | 0 |
| type | 2 | | type | 2 |
| course | C1 | | course | C1 |
| description | Course badge description | | description | Course badge 1 description |
| image | badges/tests/behat/badge.png | | image | badges/tests/behat/badge.png |
And the following "core_badges > Badge" exists:
| name | Course Badge 2 |
| status | 0 |
| type | 2 |
| course | C1 |
| description | Course badge 2 description |
| image | badges/tests/behat/badge.png |
And I am on the "Course 1" course page logged in as teacher1
Scenario: Student earns a badge using activity completion, but does not get passing grade Scenario: Student does not earn a badge using activity completion when does not get passing grade
Given I am on the "Course 1" course page logged in as teacher1 Given I navigate to "Badges" in current page administration
And I navigate to "Badges" in current page administration
And I press "Manage badges" And I press "Manage badges"
And I follow "Course Badge" And I follow "Course Badge 1"
And I select "Criteria" from the "jump" singleselect And I select "Criteria" from the "jump" singleselect
And I set the field "type" to "Activity completion" And I set the field "type" to "Activity completion"
And I set the field "Quiz - Test quiz name" to "1" And I set the field "Quiz - Test quiz name 1" to "1"
And I press "Save" And I press "Save"
And I press "Enable access" And I press "Enable access"
And I press "Continue" And I press "Continue"
And I should see "Recipients (0)" And I should see "Recipients (0)"
And I log out # Pass grade for student1. Activity is considered complete because student1 got a passing grade.
And I am on the "Course 1" course page logged in as student1 And user "student1" has attempted "Test quiz name 1" with responses:
And the "Receive a grade" completion condition of "Test quiz name" is displayed as "done" | slot | response |
And the "Receive a passing grade" completion condition of "Test quiz name" is displayed as "failed" | 1 | True |
And the "Receive a pass grade or complete all available attempts" completion condition of "Test quiz name" is displayed as "todo" # Fail grade for student2. Activity is considered incomplete because student2 got a failing grade.
When I am on the "Test quiz name" "quiz activity" page And user "student2" has attempted "Test quiz name 1" with responses:
And I press "Re-attempt quiz" | slot | response |
And I set the field "False" to "1" | 1 | False |
And I press "Finish attempt ..."
And I press "Submit all and finish"
And I click on "Submit" "button" in the "Submit all your answers and finish?" "dialogue"
And I log out
And I am on the "Course 1" course page logged in as teacher1
And I navigate to "Badges > Manage badges" in current page administration And I navigate to "Badges > Manage badges" in current page administration
And I follow "Course Badge" And I follow "Course Badge 1"
Then I should see "Recipients (1)" Then I should see "Recipients (1)"
And I select "Recipients (1)" from the "jump" singleselect
And I should see "Student 1"
And I should not see "Student 2"
Scenario Outline: Previously graded pass/fail students should earn a badge after enabling a badge Scenario: Students with any grades in an activity will receive a badge if the completion condition is set to receive any grade
Given I am on the "Course 1" course page logged in as teacher1 Given I navigate to "Badges" in current page administration
And I navigate to "Badges" in current page administration
And I press "Manage badges" And I press "Manage badges"
And I follow "Course Badge" And I follow "Course Badge 2"
And I select "Criteria" from the "jump" singleselect And I select "Criteria" from the "jump" singleselect
And I set the field "type" to "Activity completion" And I set the field "type" to "Activity completion"
And I click on "Expand all" "link" in the "region-main" "region" And I set the field "Quiz - Test quiz name 2" to "1"
And I set the field "Quiz - Test quiz name" to "1"
And I set the field "<aggregationcriteria>" to "1"
And I press "Save" And I press "Save"
And I press "Enable access"
# Fail grade with student2 And I press "Continue"
And I am on the "Course 1" course page logged in as student2 # Pass grade for student1.
And I am on the "Test quiz name" "quiz activity" page And user "student1" has attempted "Test quiz name 2" with responses:
And I press "Re-attempt quiz" | slot | response |
And I set the field "False" to "1" | 1 | True |
And I press "Finish attempt ..." # Fail grade for student2. Activity is considered complete even if student2 got a failing grade.
And I press "Submit all and finish" And user "student2" has attempted "Test quiz name 2" with responses:
And I click on "Submit" "button" in the "Submit all your answers and finish?" "dialogue" | slot | response |
And I log out | 1 | False |
# Pass grade with student1
And I am on the "Course 1" course page logged in as student1
And I am on the "Test quiz name" "quiz activity" page
And I press "Re-attempt quiz"
And I set the field "False" to "0"
And I press "Finish attempt ..."
And I press "Submit all and finish"
And I click on "Submit" "button" in the "Submit all your answers and finish?" "dialogue"
And I log out
# Enable badge access once all students have completed an activity.
And I am on the "Course 1" course page logged in as teacher1
And I navigate to "Badges > Manage badges" in current page administration And I navigate to "Badges > Manage badges" in current page administration
And I follow "Course Badge" And I follow "Course Badge 2"
Then I should see "Recipients (2)"
And I select "Recipients (2)" from the "jump" singleselect
And I should see "Student 1"
And I should see "Student 2"
Scenario: Previously graded pass/fail students should earn a badge after enabling a badge
# Pass grade for student1.
Given user "student1" has attempted "Test quiz name 1" with responses:
| slot | response |
| 1 | True |
# Fail grade for student2.
And user "student2" has attempted "Test quiz name 1" with responses:
| slot | response |
| 1 | False |
And I navigate to "Badges" in current page administration
And I press "Manage badges"
And I follow "Course Badge 1"
And I select "Criteria" from the "jump" singleselect
And I set the field "type" to "Activity completion"
And I set the field "Quiz - Test quiz name 1" to "1"
And I press "Save"
# Enable badge access once students have completed the activity.
When I press "Enable access" When I press "Enable access"
And I press "Continue" And I press "Continue"
Then I should see "Recipients (2)" # Only student1 should earn the badge because student2 did not pass the quiz.
Then I should see "Recipients (1)"
Examples: And I select "Recipients (1)" from the "jump" singleselect
| aggregationcriteria | And I should see "Student 1"
| Any of the selected activities is complete | And I should not see "Student 2"
| All of the selected activities are complete |