first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,483 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* mod_h5pactivity attempt tests
*
* @package mod_h5pactivity
* @category test
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_h5pactivity\local;
use \core_xapi\local\statement;
use \core_xapi\local\statement\item;
use \core_xapi\local\statement\item_agent;
use \core_xapi\local\statement\item_activity;
use \core_xapi\local\statement\item_definition;
use \core_xapi\local\statement\item_verb;
use \core_xapi\local\statement\item_result;
use core_xapi\test_helper;
use stdClass;
/**
* Attempt tests class for mod_h5pactivity.
*
* @package mod_h5pactivity
* @category test
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class attempt_test extends \advanced_testcase {
/**
* Generate a scenario to run all tests.
* @return array course_modules, user record, course record
*/
private function generate_testing_scenario(): array {
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
$cm = get_coursemodule_from_id('h5pactivity', $activity->cmid, 0, false, MUST_EXIST);
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
return [$cm, $student, $course];
}
/**
* Test for create_attempt method.
*/
public function test_create_attempt(): void {
global $CFG, $DB;
require_once($CFG->dirroot.'/lib/xapi/tests/helper.php');
[$cm, $student, $course] = $this->generate_testing_scenario();
$student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
// Save the current state for this activity for student1 and student2 (before creating the first attempt).
$manager = manager::create_from_coursemodule($cm);
$this->setUser($student2);
test_helper::create_state([
'activity' => item_activity::create_from_id($manager->get_context()->id),
'component' => 'mod_h5pactivity',
], true);
$this->setUser($student);
test_helper::create_state([
'activity' => item_activity::create_from_id($manager->get_context()->id),
'component' => 'mod_h5pactivity',
], true);
$this->assertEquals(2, $DB->count_records('xapi_states'));
// Create first attempt.
$attempt = attempt::new_attempt($student, $cm);
$this->assertEquals($student->id, $attempt->get_userid());
$this->assertEquals($cm->instance, $attempt->get_h5pactivityid());
$this->assertEquals(1, $attempt->get_attempt());
$this->assertEquals(1, $DB->count_records('xapi_states'));
$this->assertEquals(0, $DB->count_records('xapi_states', ['userid' => $student->id]));
// Create a second attempt.
$attempt = attempt::new_attempt($student, $cm);
$this->assertEquals($student->id, $attempt->get_userid());
$this->assertEquals($cm->instance, $attempt->get_h5pactivityid());
$this->assertEquals(2, $attempt->get_attempt());
}
/**
* Test for last_attempt method
*/
public function test_last_attempt(): void {
list($cm, $student) = $this->generate_testing_scenario();
// Create first attempt.
$attempt = attempt::last_attempt($student, $cm);
$this->assertEquals($student->id, $attempt->get_userid());
$this->assertEquals($cm->instance, $attempt->get_h5pactivityid());
$this->assertEquals(1, $attempt->get_attempt());
$lastid = $attempt->get_id();
// Get last attempt.
$attempt = attempt::last_attempt($student, $cm);
$this->assertEquals($student->id, $attempt->get_userid());
$this->assertEquals($cm->instance, $attempt->get_h5pactivityid());
$this->assertEquals(1, $attempt->get_attempt());
$this->assertEquals($lastid, $attempt->get_id());
// Now force a new attempt.
$attempt = attempt::new_attempt($student, $cm);
$this->assertEquals($student->id, $attempt->get_userid());
$this->assertEquals($cm->instance, $attempt->get_h5pactivityid());
$this->assertEquals(2, $attempt->get_attempt());
$lastid = $attempt->get_id();
// Get last attempt.
$attempt = attempt::last_attempt($student, $cm);
$this->assertEquals($student->id, $attempt->get_userid());
$this->assertEquals($cm->instance, $attempt->get_h5pactivityid());
$this->assertEquals(2, $attempt->get_attempt());
$this->assertEquals($lastid, $attempt->get_id());
}
/**
* Test saving statements.
*
* @dataProvider save_statement_data
* @param string $subcontent subcontent identifier
* @param bool $hasdefinition generate definition
* @param bool $hasresult generate result
* @param array $results 0 => insert ok, 1 => maxscore, 2 => rawscore, 3 => count
*/
public function test_save_statement(string $subcontent, bool $hasdefinition, bool $hasresult, array $results): void {
list($cm, $student) = $this->generate_testing_scenario();
$attempt = attempt::new_attempt($student, $cm);
$this->assertEquals(0, $attempt->get_maxscore());
$this->assertEquals(0, $attempt->get_rawscore());
$this->assertEquals(0, $attempt->count_results());
$this->assertEquals(0, $attempt->get_duration());
$this->assertNull($attempt->get_completion());
$this->assertNull($attempt->get_success());
$this->assertFalse($attempt->get_scoreupdated());
$statement = $this->generate_statement($hasdefinition, $hasresult);
$result = $attempt->save_statement($statement, $subcontent);
$this->assertEquals($results[0], $result);
$this->assertEquals($results[1], $attempt->get_maxscore());
$this->assertEquals($results[2], $attempt->get_rawscore());
$this->assertEquals($results[3], $attempt->count_results());
$this->assertEquals($results[4], $attempt->get_duration());
$this->assertEquals($results[5], $attempt->get_completion());
$this->assertEquals($results[6], $attempt->get_success());
if ($results[5]) {
$this->assertTrue($attempt->get_scoreupdated());
} else {
$this->assertFalse($attempt->get_scoreupdated());
}
}
/**
* Data provider for data request creation tests.
*
* @return array
*/
public function save_statement_data(): array {
return [
'Statement without definition and result' => [
'', false, false, [false, 0, 0, 0, 0, null, null]
],
'Statement with definition but no result' => [
'', true, false, [false, 0, 0, 0, 0, null, null]
],
'Statement with result but no definition' => [
'', true, false, [false, 0, 0, 0, 0, null, null]
],
'Statement subcontent without definition and result' => [
'111-222-333', false, false, [false, 0, 0, 0, 0, null, null]
],
'Statement subcontent with definition but no result' => [
'111-222-333', true, false, [false, 0, 0, 0, 0, null, null]
],
'Statement subcontent with result but no definition' => [
'111-222-333', true, false, [false, 0, 0, 0, 0, null, null]
],
'Statement with definition, result but no subcontent' => [
'', true, true, [true, 2, 2, 1, 25, 1, 1]
],
'Statement with definition, result and subcontent' => [
'111-222-333', true, true, [true, 0, 0, 1, 0, null, null]
],
];
}
/**
* Test delete results from attempt.
*/
public function test_delete_results(): void {
list($cm, $student) = $this->generate_testing_scenario();
$attempt = $this->generate_full_attempt($student, $cm);
$attempt->delete_results();
$this->assertEquals(0, $attempt->count_results());
}
/**
* Test delete attempt.
*/
public function test_delete_attempt(): void {
global $DB;
list($cm, $student) = $this->generate_testing_scenario();
// Check no previous attempts are created.
$count = $DB->count_records('h5pactivity_attempts');
$this->assertEquals(0, $count);
$count = $DB->count_records('h5pactivity_attempts_results');
$this->assertEquals(0, $count);
// Generate one attempt.
$attempt1 = $this->generate_full_attempt($student, $cm);
$count = $DB->count_records('h5pactivity_attempts');
$this->assertEquals(1, $count);
$count = $DB->count_records('h5pactivity_attempts_results');
$this->assertEquals(2, $count);
// Generate a second attempt.
$attempt2 = $this->generate_full_attempt($student, $cm);
$count = $DB->count_records('h5pactivity_attempts');
$this->assertEquals(2, $count);
$count = $DB->count_records('h5pactivity_attempts_results');
$this->assertEquals(4, $count);
// Delete the first attempt.
attempt::delete_attempt($attempt1);
$count = $DB->count_records('h5pactivity_attempts');
$this->assertEquals(1, $count);
$count = $DB->count_records('h5pactivity_attempts_results');
$this->assertEquals(2, $count);
$this->assertEquals(2, $attempt2->count_results());
}
/**
* Test delete all attempts.
*
* @dataProvider delete_all_attempts_data
* @param bool $hasstudent if user is specificed
* @param int[] 0-3 => statements count results, 4-5 => totals
*/
public function test_delete_all_attempts(bool $hasstudent, array $results): void {
global $DB;
list($cm, $student, $course) = $this->generate_testing_scenario();
// For this test we need extra activity and student.
$activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
$cm2 = get_coursemodule_from_id('h5pactivity', $activity->cmid, 0, false, MUST_EXIST);
$student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
// Check no previous attempts are created.
$count = $DB->count_records('h5pactivity_attempts');
$this->assertEquals(0, $count);
$count = $DB->count_records('h5pactivity_attempts_results');
$this->assertEquals(0, $count);
// Generate some attempts attempt on both activities and students.
$attempts = [];
$attempts[] = $this->generate_full_attempt($student, $cm);
$attempts[] = $this->generate_full_attempt($student2, $cm);
$attempts[] = $this->generate_full_attempt($student, $cm2);
$attempts[] = $this->generate_full_attempt($student2, $cm2);
$count = $DB->count_records('h5pactivity_attempts');
$this->assertEquals(4, $count);
$count = $DB->count_records('h5pactivity_attempts_results');
$this->assertEquals(8, $count);
// Delete all specified attempts.
$user = ($hasstudent) ? $student : null;
attempt::delete_all_attempts($cm, $user);
// Check data.
for ($assert = 0; $assert < 4; $assert++) {
$count = $attempts[$assert]->count_results();
$this->assertEquals($results[$assert], $count);
}
$count = $DB->count_records('h5pactivity_attempts');
$this->assertEquals($results[4], $count);
$count = $DB->count_records('h5pactivity_attempts_results');
$this->assertEquals($results[5], $count);
}
/**
* Data provider for data request creation tests.
*
* @return array
*/
public function delete_all_attempts_data(): array {
return [
'Delete all attempts from activity' => [
false, [0, 0, 2, 2, 2, 4]
],
'Delete all attempts from user' => [
true, [0, 2, 2, 2, 3, 6]
],
];
}
/**
* Test set_score method.
*
*/
public function test_set_score(): void {
global $DB;
list($cm, $student, $course) = $this->generate_testing_scenario();
// Generate one attempt.
$attempt = $this->generate_full_attempt($student, $cm);
$dbattempt = $DB->get_record('h5pactivity_attempts', ['id' => $attempt->get_id()]);
$this->assertEquals($dbattempt->rawscore, $attempt->get_rawscore());
$this->assertEquals(2, $dbattempt->rawscore);
$this->assertEquals($dbattempt->maxscore, $attempt->get_maxscore());
$this->assertEquals(2, $dbattempt->maxscore);
$this->assertEquals(1, $dbattempt->scaled);
// Set attempt score.
$attempt->set_score(5, 10);
$this->assertEquals(5, $attempt->get_rawscore());
$this->assertEquals(10, $attempt->get_maxscore());
$this->assertTrue($attempt->get_scoreupdated());
// Save new score into DB.
$attempt->save();
$dbattempt = $DB->get_record('h5pactivity_attempts', ['id' => $attempt->get_id()]);
$this->assertEquals($dbattempt->rawscore, $attempt->get_rawscore());
$this->assertEquals(5, $dbattempt->rawscore);
$this->assertEquals($dbattempt->maxscore, $attempt->get_maxscore());
$this->assertEquals(10, $dbattempt->maxscore);
$this->assertEquals(0.5, $dbattempt->scaled);
}
/**
* Test set_duration method.
*
* @dataProvider basic_setters_data
* @param string $attribute the stribute to test
* @param int $oldvalue attribute old value
* @param int $newvalue attribute new expected value
*/
public function test_basic_setters(string $attribute, int $oldvalue, int $newvalue): void {
global $DB;
list($cm, $student, $course) = $this->generate_testing_scenario();
// Generate one attempt.
$attempt = $this->generate_full_attempt($student, $cm);
$setmethod = 'set_'.$attribute;
$getmethod = 'get_'.$attribute;
$dbattempt = $DB->get_record('h5pactivity_attempts', ['id' => $attempt->get_id()]);
$this->assertEquals($dbattempt->$attribute, $attempt->$getmethod());
$this->assertEquals($oldvalue, $dbattempt->$attribute);
// Set attempt attribute.
$attempt->$setmethod($newvalue);
$this->assertEquals($newvalue, $attempt->$getmethod());
// Save new score into DB.
$attempt->save();
$dbattempt = $DB->get_record('h5pactivity_attempts', ['id' => $attempt->get_id()]);
$this->assertEquals($dbattempt->$attribute, $attempt->$getmethod());
$this->assertEquals($newvalue, $dbattempt->$attribute);
// Set null $attribute.
$attempt->$setmethod(null);
$this->assertNull($attempt->$getmethod());
// Save new score into DB.
$attempt->save();
$dbattempt = $DB->get_record('h5pactivity_attempts', ['id' => $attempt->get_id()]);
$this->assertEquals($dbattempt->$attribute, $attempt->$getmethod());
$this->assertNull($dbattempt->$attribute);
}
/**
* Data provider for testing basic setters.
*
* @return array
*/
public function basic_setters_data(): array {
return [
'Set attempt duration' => [
'duration', 25, 35
],
'Set attempt completion' => [
'completion', 1, 0
],
'Set attempt success' => [
'success', 1, 0
],
];
}
/**
* Generate a fake attempt with two results.
*
* @param stdClass $student a user record
* @param stdClass $cm a course_module record
* @return attempt
*/
private function generate_full_attempt($student, $cm): attempt {
$attempt = attempt::new_attempt($student, $cm);
$this->assertEquals(0, $attempt->get_maxscore());
$this->assertEquals(0, $attempt->get_rawscore());
$this->assertEquals(0, $attempt->count_results());
$statement = $this->generate_statement(true, true);
$saveok = $attempt->save_statement($statement, '');
$this->assertTrue($saveok);
$saveok = $attempt->save_statement($statement, '111-222-333');
$this->assertTrue($saveok);
$this->assertEquals(2, $attempt->count_results());
return $attempt;
}
/**
* Return a xAPI partial statement with object defined.
* @param bool $hasdefinition if has to include definition
* @param bool $hasresult if has to include results
* @return statement
*/
private function generate_statement(bool $hasdefinition, bool $hasresult): statement {
global $USER;
$statement = new statement();
$statement->set_actor(item_agent::create_from_user($USER));
$statement->set_verb(item_verb::create_from_id('http://adlnet.gov/expapi/verbs/completed'));
$definition = null;
if ($hasdefinition) {
$definition = item_definition::create_from_data((object)[
'interactionType' => 'compound',
'correctResponsesPattern' => '1',
]);
}
$statement->set_object(item_activity::create_from_id('something', $definition));
if ($hasresult) {
$statement->set_result(item_result::create_from_data((object)[
'completion' => true,
'success' => true,
'score' => (object) ['min' => 0, 'max' => 2, 'raw' => 2, 'scaled' => 1],
'duration' => 'PT25S',
]));
}
return $statement;
}
}
+360
View File
@@ -0,0 +1,360 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* mod_h5pactivity grader tests
*
* @package mod_h5pactivity
* @category test
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_h5pactivity\local;
use grade_item;
use stdClass;
/**
* Grader tests class for mod_h5pactivity.
*
* @package mod_h5pactivity
* @category test
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grader_test extends \advanced_testcase {
/**
* Setup to ensure that fixtures are loaded.
*/
public static function setupBeforeClass(): void {
global $CFG;
require_once($CFG->libdir.'/gradelib.php');
}
/**
* Test for grade item delete.
*/
public function test_grade_item_delete(): void {
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
$user = $this->getDataGenerator()->create_and_enrol($course, 'student');
$grader = new grader($activity);
// Force a user grade.
$this->generate_fake_attempt($activity, $user, 5, 10);
$grader->update_grades($user->id);
$gradeinfo = grade_get_grades($course->id, 'mod', 'h5pactivity', $activity->id, $user->id);
$this->assertNotEquals(0, count($gradeinfo->items));
$this->assertArrayHasKey($user->id, $gradeinfo->items[0]->grades);
$grader->grade_item_delete();
$gradeinfo = grade_get_grades($course->id, 'mod', 'h5pactivity', $activity->id, $user->id);
$this->assertEquals(0, count($gradeinfo->items));
}
/**
* Test for grade item update.
*
* @dataProvider grade_item_update_data
* @param int $newgrade new activity grade
* @param bool $reset if has to reset grades
* @param string $idnumber the new idnumber
*/
public function test_grade_item_update(int $newgrade, bool $reset, string $idnumber): void {
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
$user = $this->getDataGenerator()->create_and_enrol($course, 'student');
// Force a user initial grade.
$grader = new grader($activity);
$this->generate_fake_attempt($activity, $user, 5, 10);
$grader->update_grades($user->id);
$gradeinfo = grade_get_grades($course->id, 'mod', 'h5pactivity', $activity->id, $user->id);
$this->assertNotEquals(0, count($gradeinfo->items));
$item = array_shift($gradeinfo->items);
$this->assertArrayHasKey($user->id, $item->grades);
$this->assertEquals(50, round($item->grades[$user->id]->grade));
// Module grade value determine the way gradebook acts. That means that the expected
// result depends on this value.
// - Grade > 0: regular max grade value.
// - Grade = 0: no grading is used (but grademax remains the same).
// - Grade < 0: a scaleid is used (value = -scaleid).
if ($newgrade > 0) {
$grademax = $newgrade;
$scaleid = null;
$usergrade = ($newgrade > 50) ? 50 : $newgrade;
} else if ($newgrade == 0) {
$grademax = 100;
$scaleid = null;
$usergrade = null; // No user grades expected.
} else if ($newgrade < 0) {
$scale = $this->getDataGenerator()->create_scale(array("scale" => "value1, value2, value3"));
$newgrade = -1 * $scale->id;
$grademax = 3;
$scaleid = $scale->id;
$usergrade = 3; // 50 value will ve converted to "value 3" on scale.
}
// Update grade item.
$activity->grade = $newgrade;
// In case a reset is need, usergrade will be empty.
if ($reset) {
$param = 'reset';
$usergrade = null;
} else {
// Individual user gradings will be tested as a subcall of update_grades.
$param = null;
}
$grader = new grader($activity, $idnumber);
$grader->grade_item_update($param);
// Check new grade item and grades.
$gradeinfo = grade_get_grades($course->id, 'mod', 'h5pactivity', $activity->id, $user->id);
$item = array_shift($gradeinfo->items);
$this->assertEquals($scaleid, $item->scaleid);
$this->assertEquals($grademax, $item->grademax);
$this->assertArrayHasKey($user->id, $item->grades);
if ($usergrade) {
$this->assertEquals($usergrade, round($item->grades[$user->id]->grade));
} else {
$this->assertEmpty($item->grades[$user->id]->grade);
}
if (!empty($idnumber)) {
$gradeitem = grade_item::fetch(['idnumber' => $idnumber, 'courseid' => $course->id]);
$this->assertInstanceOf('grade_item', $gradeitem);
}
}
/**
* Data provider for test_grade_item_update.
*
* @return array
*/
public function grade_item_update_data(): array {
return [
'Change idnumber' => [
100, false, 'newidnumber'
],
'Increase max grade to 110' => [
110, false, ''
],
'Decrease max grade to 80' => [
40, false, ''
],
'Decrease max grade to 40 (less than actual grades)' => [
40, false, ''
],
'Reset grades' => [
100, true, ''
],
'Disable grades' => [
0, false, ''
],
'Use scales' => [
-1, false, ''
],
'Use scales with reset' => [
-1, true, ''
],
];
}
/**
* Test for grade update.
*
* @dataProvider update_grades_data
* @param int $newgrade the new activity grade
* @param bool $all if has to be applied to all students or just to one
* @param int $completion 1 all student have the activity completed, 0 one have incompleted
* @param array $results expected results (user1 grade, user2 grade)
*/
public function test_update_grades(int $newgrade, bool $all, int $completion, array $results): void {
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
$user1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
$user2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
// Force a user initial grade.
$grader = new grader($activity);
$this->generate_fake_attempt($activity, $user1, 5, 10);
$this->generate_fake_attempt($activity, $user2, 3, 12, $completion);
$grader->update_grades();
$gradeinfo = grade_get_grades($course->id, 'mod', 'h5pactivity', $activity->id, [$user1->id, $user2->id]);
$this->assertNotEquals(0, count($gradeinfo->items));
$item = array_shift($gradeinfo->items);
$this->assertArrayHasKey($user1->id, $item->grades);
$this->assertArrayHasKey($user2->id, $item->grades);
$this->assertEquals(50, $item->grades[$user1->id]->grade);
// Uncompleted attempts does not generate grades.
if ($completion) {
$this->assertEquals(25, $item->grades[$user2->id]->grade);
} else {
$this->assertNull($item->grades[$user2->id]->grade);
}
// Module grade value determine the way gradebook acts. That means that the expected
// result depends on this value.
// - Grade > 0: regular max grade value.
// - Grade <= 0: no grade calculation is used (scale and no grading).
if ($newgrade < 0) {
$scale = $this->getDataGenerator()->create_scale(array("scale" => "value1, value2, value3"));
$activity->grade = -1 * $scale->id;
} else {
$activity->grade = $newgrade;
}
$userid = ($all) ? 0 : $user1->id;
$grader = new grader($activity);
$grader->update_grades($userid);
// Check new grade item and grades.
$gradeinfo = grade_get_grades($course->id, 'mod', 'h5pactivity', $activity->id, [$user1->id, $user2->id]);
$item = array_shift($gradeinfo->items);
$this->assertArrayHasKey($user1->id, $item->grades);
$this->assertArrayHasKey($user2->id, $item->grades);
$this->assertEquals($results[0], $item->grades[$user1->id]->grade);
$this->assertEquals($results[1], $item->grades[$user2->id]->grade);
}
/**
* Data provider for test_grade_item_update.
*
* @return array
*/
public function update_grades_data(): array {
return [
// Quantitative grade, all attempts completed.
'Same grademax, all users, all completed' => [
100, true, 1, [50, 25]
],
'Same grademax, one user, all completed' => [
100, false, 1, [50, 25]
],
'Increade max, all users, all completed' => [
200, true, 1, [100, 50]
],
'Increade max, one user, all completed' => [
200, false, 1, [100, 25]
],
'Decrease max, all users, all completed' => [
50, true, 1, [25, 12.5]
],
'Decrease max, one user, all completed' => [
50, false, 1, [25, 25]
],
// Quantitative grade, some attempts not completed.
'Same grademax, all users, not completed' => [
100, true, 0, [50, null]
],
'Same grademax, one user, not completed' => [
100, false, 0, [50, null]
],
'Increade max, all users, not completed' => [
200, true, 0, [100, null]
],
'Increade max, one user, not completed' => [
200, false, 0, [100, null]
],
'Decrease max, all users, not completed' => [
50, true, 0, [25, null]
],
'Decrease max, one user, not completed' => [
50, false, 0, [25, null]
],
// No grade (no grade will be used).
'No grade, all users, all completed' => [
0, true, 1, [null, null]
],
'No grade, one user, all completed' => [
0, false, 1, [null, null]
],
'No grade, all users, not completed' => [
0, true, 0, [null, null]
],
'No grade, one user, not completed' => [
0, false, 0, [null, null]
],
// Scale (grate item will updated but without regrading).
'Scale, all users, all completed' => [
-1, true, 1, [3, 3]
],
'Scale, one user, all completed' => [
-1, false, 1, [3, 3]
],
'Scale, all users, not completed' => [
-1, true, 0, [3, null]
],
'Scale, one user, not completed' => [
-1, false, 0, [3, null]
],
];
}
/**
* Create a fake attempt for a specific user.
*
* @param stdClass $activity activity instance record.
* @param stdClass $user user record
* @param int $rawscore score obtained
* @param int $maxscore attempt max score
* @param int $completion 1 for activity completed, 0 for not completed yet
* @return stdClass the attempt record
*/
private function generate_fake_attempt(stdClass $activity, stdClass $user,
int $rawscore, int $maxscore, int $completion = 1): stdClass {
global $DB;
$attempt = (object)[
'h5pactivityid' => $activity->id,
'userid' => $user->id,
'timecreated' => 10,
'timemodified' => 20,
'attempt' => 1,
'rawscore' => $rawscore,
'maxscore' => $maxscore,
'duration' => 2,
'completion' => $completion,
'success' => 0,
];
$attempt->scaled = $attempt->rawscore / $attempt->maxscore;
$attempt->id = $DB->insert_record('h5pactivity_attempts', $attempt);
return $attempt;
}
}
File diff suppressed because it is too large Load Diff