MDL-73091 core_badges: Avoid undefined variable notice in review

* Fix review method for award_criteria_courseset when courseset is empty
* Add unit tests for coverage of the award_criteria_courseset class

@co-authored jz-reichert@web.de
This commit is contained in:
Wolfgang Reichert 2021-11-16 16:11:47 +01:00 committed by Laurent David
parent 2bf886f9dd
commit 1264e3e0f0
2 changed files with 61 additions and 0 deletions

View File

@ -197,6 +197,7 @@ class award_criteria_courseset extends award_criteria {
* @return bool Whether criteria is complete
*/
public function review($userid, $filtered = false) {
$overall = false;
foreach ($this->params as $param) {
$course = new stdClass();
$course->id = $param['course'];

View File

@ -757,6 +757,66 @@ class badgeslib_test extends advanced_testcase {
$this->assertSame(0, $badge->review_all_criteria()); // Verify award_criteria_cohort->get_completed_criteria_sql().
}
/**
* Test badges observer when user_updated event is fired.
* @covers \award_criteria_courseset
*/
public function test_badges_observer_courseset_criteria_review(): void {
$this->preventResetByRollback(); // Messaging is not compatible with transactions.
$badge = new badge($this->coursebadge);
$this->assertFalse($badge->is_issued($this->user->id));
$additionalcourse = $this->getDataGenerator()->create_course(['enablecompletion' => true]);
$this->getDataGenerator()->enrol_user($this->user->id, $additionalcourse->id);
$criteriaoverall = award_criteria::build(['criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id]);
$criteriaoverall->save(['agg' => BADGE_CRITERIA_AGGREGATION_ANY]);
$criteriaoverall1 = award_criteria::build(['criteriatype' => BADGE_CRITERIA_TYPE_COURSESET, 'badgeid' => $badge->id]);
$criteriaoverall1->save(['agg' => BADGE_CRITERIA_AGGREGATION_ANY, 'course_' . $this->course->id => $this->course->id,
'course_' . $additionalcourse->id => $additionalcourse->id]);
$ccompletion = new completion_completion(['course' => $this->course->id, 'userid' => $this->user->id]);
$ccompletion2 = new completion_completion(['course' => $additionalcourse->id, 'userid' => $this->user->id]);
// Assert the badge will not be issued to the user as is.
$badge = new badge($this->coursebadge);
$badge->review_all_criteria();
$this->assertFalse($badge->is_issued($this->user->id));
// Mark course as complete.
$sink = $this->redirectMessages();
$ccompletion->mark_complete();
$ccompletion2->mark_complete();
// Thee messages are generated: Two for the course completed and the other one for the badge awarded.
$messages = $sink->get_messages();
$this->assertCount(3, $messages);
$this->assertEquals('badgerecipientnotice', $messages[0]->eventtype);
$this->assertEquals('coursecompleted', $messages[1]->eventtype);
$sink->close();
// Check if badge is awarded.
$this->assertDebuggingCalled('Error baking badge image!');
$this->assertTrue($badge->is_issued($this->user->id));
}
/**
* Test the criteria review method for courseset
* @covers \award_criteria_courseset::review
*/
public function test_badges_courseset_criteria_review_empty_courseset(): void {
$this->preventResetByRollback(); // Messaging is not compatible with transactions.
$badge = new badge($this->coursebadge);
$this->assertFalse($badge->is_issued($this->user->id));
$criteriaoverall = award_criteria::build(['criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id]);
$criteriaoverall->save(['agg' => BADGE_CRITERIA_AGGREGATION_ANY]);
$criteriaoverall1 = award_criteria::build(['criteriatype' => BADGE_CRITERIA_TYPE_COURSESET, 'badgeid' => $badge->id]);
$criteriaoverall1->save();
// Assert the badge will not be issued to the user as is.
$badge = new badge($this->coursebadge);
$badge->review_all_criteria();
$this->assertFalse($badge->is_issued($this->user->id));
}
/**
* Test badges observer when cohort_member_added event is fired and user required to belong to multiple (all) cohorts.
*