From d6576ca2292d2f87999a7f9913166c7f30a7e6d3 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 23 Sep 2019 19:10:10 +0800 Subject: [PATCH] MDL-66748 gradingform_rubric: Add data generators --- .../form/rubric/tests/generator/criterion.php | 121 +++++++ .../form/rubric/tests/generator/lib.php | 240 +++++++++++++ .../form/rubric/tests/generator/rubric.php | 133 ++++++++ .../form/rubric/tests/generator_test.php | 319 ++++++++++++++++++ .../form/rubric/tests/privacy_test.php | 270 ++++----------- 5 files changed, 883 insertions(+), 200 deletions(-) create mode 100644 grade/grading/form/rubric/tests/generator/criterion.php create mode 100644 grade/grading/form/rubric/tests/generator/lib.php create mode 100644 grade/grading/form/rubric/tests/generator/rubric.php create mode 100644 grade/grading/form/rubric/tests/generator_test.php diff --git a/grade/grading/form/rubric/tests/generator/criterion.php b/grade/grading/form/rubric/tests/generator/criterion.php new file mode 100644 index 00000000000..75f5cf9b31e --- /dev/null +++ b/grade/grading/form/rubric/tests/generator/criterion.php @@ -0,0 +1,121 @@ +. + +/** + * Generator for the gradingforum_rubric plugin. + * + * @package gradingform_rubric + * @category test + * @copyright 2018 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace tests\gradingform_rubric\generator; + +/** + * Convenience class to create rubric criterion. + * + * @package gradingform_rubric + * @copyright 2018 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class criterion { + /** @var string $description A description of the criterion. */ + public $description; + + /** @var integer $sortorder sort order of the criterion. */ + public $sortorder = 0; + + /** @var array $levels The levels for this criterion. */ + public $levels = []; + + /** + * Constructor for this test_criterion object + * + * @param string $description A description of this criterion. + * @param array $levels + */ + public function __construct(string $description, array $levels = []) { + $this->description = $description; + foreach ($levels as $definition => $score) { + $this->add_level($definition, $score); + } + } + + /** + * Adds levels to the criterion. + * + * @param string $definition The definition for this level. + * @param int $score The score received if this level is selected. + * @return self + */ + public function add_level(string $definition, int $score): self { + $this->levels[] = [ + 'definition' => $definition, + 'score' => $score + ]; + + return $this; + } + + /** + * Get the description for this criterion. + * + * @return string + */ + public function get_description(): string { + return $this->description; + } + + /** + * Get the levels for this criterion. + * + * @return array + */ + public function get_levels(): array { + return $this->levels; + } + + /** + * Get all values in an array for use when creating a new guide. + * + * @param int $sortorder + * @return array + */ + public function get_all_values(int $sortorder): array { + return [ + 'sortorder' => $sortorder, + 'description' => $this->get_description(), + 'levels' => $this->get_all_level_values(), + ]; + } + + /** + * Get all level values. + * + * @return array + */ + public function get_all_level_values(): array { + $result = []; + + foreach ($this->get_levels() as $index => $level) { + $id = $index + 1; + $result["NEWID{$id}"] = $level; + } + + return $result; + } +} diff --git a/grade/grading/form/rubric/tests/generator/lib.php b/grade/grading/form/rubric/tests/generator/lib.php new file mode 100644 index 00000000000..bed21f8caa7 --- /dev/null +++ b/grade/grading/form/rubric/tests/generator/lib.php @@ -0,0 +1,240 @@ +. + +/** + * Generator for the gradingforum_rubric plugin. + * + * @package gradingform_rubric + * @category test + * @copyright 2019 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once(__DIR__ . '/rubric.php'); +require_once(__DIR__ . '/criterion.php'); + +use tests\gradingform_rubric\generator\rubric; +use tests\gradingform_rubric\generator\criterion; + +/** + * Generator for the gradingforum_rubric plugintype. + * + * @package gradingform_rubric + * @category test + * @copyright 2019 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class gradingform_rubric_generator extends component_generator_base { + + /** + * Create an instance of a rubric. + * + * @param context $context + * @param string $component + * @param string $area + * @param string $name + * @param string $description + * @param array $criteria The list of criteria to add to the generated rubric + * @return gradingform_rubric_controller + */ + public function create_instance( + context $context, + string $component, + string $area, + string $name, + string $description, + array $criteria + ): gradingform_rubric_controller { + global $USER; + + if ($USER->id === 0) { + throw new \coding_exception('Creation of a rubric must currently be run as a user.'); + } + + // Fetch the controller for this context/component/area. + $generator = \testing_util::get_data_generator(); + $gradinggenerator = $generator->get_plugin_generator('core_grading'); + $controller = $gradinggenerator->create_instance($context, $component, $area, 'rubric'); + + // Generate a definition for the supplied rubric. + $rubric = $this->get_rubric($name, $description); + foreach ($criteria as $name => $criterion) { + $rubric->add_criteria($this->get_criterion($name, $criterion)); + } + + // Update the controller wih the rubric definition. + $controller->update_definition($rubric->get_definition()); + + return $controller; + } + + /** + * Get a new rubric for use with the rubric controller. + * + * Note: This is just a helper class used to build a new definition. It does not persist the data. + * + * @param string $name + * @param string $description + * @return rubric + */ + protected function get_rubric(string $name, string $description): rubric { + return new rubric($name, $description); + } + + /** + * Get a new rubric for use with a gradingform_rubric_generator_rubric. + * + * Note: This is just a helper class used to build a new definition. It does not persist the data. + * + * @param string $description + * @param array $levels Set of levels in the form definition => score + * @return gradingform_rubric_generator_criterion + */ + protected function get_criterion(string $description, array $levels = []): criterion { + return new criterion($description, $levels); + } + + /** + * Given a controller instance, fetch the level and criterion information for the specified values. + * + * @param gradingform_controller $controller + * @param string $description The description to match the criterion on + * @param float $score The value to match the level on + * @return array + */ + public function get_level_and_criterion_for_values( + gradingform_controller $controller, + string $description, + float $score + ): array { + $definition = $controller->get_definition(); + $criteria = $definition->rubric_criteria; + + $criterion = $level = null; + + $criterion = array_reduce($criteria, function($carry, $criterion) use ($description) { + if ($criterion['description'] === $description) { + $carry = $criterion; + } + + return $carry; + }, null); + + if ($criterion) { + $criterion = (object) $criterion; + $level = array_reduce($criterion->levels, function($carry, $level) use ($score) { + if ($level['score'] == $score) { + $carry = $level; + } + return $carry; + }); + $level = $level ? (object) $level : null; + } + + return [ + 'criterion' => $criterion, + 'level' => $level, + ]; + } + + /** + * Get submitted form data for the supplied controller, itemid, and values. + * The returned data is in the format used by rubric when handling form submission. + * + * @param gradingform_rubric_controller $controller + * @param int $itemid + * @param array $values A set of array values where the array key is the name of the criterion, and the value is an + * array with the desired score, and any remark. + */ + public function get_submitted_form_data(gradingform_rubric_controller $controller, int $itemid, array $values): array { + $result = [ + 'itemid' => $itemid, + 'criteria' => [], + ]; + foreach ($values as $criterionname => ['score' => $score, 'remark' => $remark]) { + [ + 'criterion' => $criterion, + 'level' => $level, + ] = $this->get_level_and_criterion_for_values($controller, $criterionname, $score); + $result['criteria'][$criterion->id] = [ + 'levelid' => $level->id, + 'remark' => $remark, + ]; + } + + return $result; + } + + /** + * Generate a rubric controller with sample data required for testing of this class. + * + * @param context $context + * @param string $component + * @param string $area + * @return gradingform_rubric_controller + */ + public function get_test_rubric(context $context, string $component, string $area): gradingform_rubric_controller { + $criteria = [ + 'Spelling is important' => [ + 'Nothing but mistakes' => 0, + 'Several mistakes' => 1, + 'No mistakes' => 2, + ], + 'Pictures' => [ + 'No pictures' => 0, + 'One picture' => 1, + 'More than one picture' => 2, + ], + ]; + + return $this->create_instance($context, $component, $area, 'testrubric', 'Description text', $criteria); + } + + /** + * Fetch a set of sample data. + * + * @param gradingform_rubric_controller $controller + * @param int $itemid + * @param float $spellingscore + * @param string $spellingremark + * @param float $picturescore + * @param string $pictureremark + * @return array + */ + public function get_test_form_data( + gradingform_rubric_controller $controller, + int $itemid, + float $spellingscore, + string $spellingremark, + float $picturescore, + string $pictureremark + ): array { + $generator = \testing_util::get_data_generator(); + $rubricgenerator = $generator->get_plugin_generator('gradingform_rubric'); + return $rubricgenerator->get_submitted_form_data($controller, $itemid, [ + 'Spelling is important' => [ + 'score' => $spellingscore, + 'remark' => $spellingremark, + ], + 'Pictures' => [ + 'score' => $picturescore, + 'remark' => $pictureremark, + ], + ]); + } +} diff --git a/grade/grading/form/rubric/tests/generator/rubric.php b/grade/grading/form/rubric/tests/generator/rubric.php new file mode 100644 index 00000000000..c388c51fa8b --- /dev/null +++ b/grade/grading/form/rubric/tests/generator/rubric.php @@ -0,0 +1,133 @@ +. + +/** + * Generator for the gradingforum_rubric plugin. + * + * @package gradingform_rubric + * @category test + * @copyright 2018 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace tests\gradingform_rubric\generator; + +use gradingform_controller; +use stdClass; + +/** + * Test rubric. + * + * @package gradingform_rubric + * @category test + * @copyright 2018 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class rubric { + + /** @var array $criteria The criteria for this rubric. */ + protected $criteria = []; + + /** @var string The name of this rubric. */ + protected $name; + + /** @var string A description for this rubric. */ + protected $description; + + /** @var array The rubric options. */ + protected $options = []; + + /** + * Create a new gradingform_rubric_generator_rubric. + * + * @param string $name + * @param string $description + */ + public function __construct(string $name, string $description) { + $this->name = $name; + $this->description = $description; + + $this->set_option('sortlevelsasc', 1); + $this->set_option('lockzeropoints', 1); + $this->set_option('showdescriptionteacher', 1); + $this->set_option('showdescriptionstudent', 1); + $this->set_option('showscoreteacher', 1); + $this->set_option('showscorestudent', 1); + $this->set_option('enableremarks', 1); + $this->set_option('showremarksstudent', 1); + } + + /** + * Creates the rubric using the appropriate APIs. + */ + public function get_definition(): stdClass { + return (object) [ + 'name' => $this->name, + 'description_editor' => [ + 'text' => $this->description, + 'format' => FORMAT_HTML, + 'itemid' => 1 + ], + 'rubric' => [ + 'criteria' => $this->get_all_criterion_values(), + 'options' => $this->options, + ], + 'saverubric' => 'Save rubric and make it ready', + 'status' => gradingform_controller::DEFINITION_STATUS_READY, + ]; + } + + /** + * Set an option for the rubric. + * + * @param string $key + * @param mixed $value + * @return self + */ + public function set_option(string $key, $value): self { + $this->options[$key] = $value; + return $this; + } + + /** + * Adds a criterion to the rubric. + * + * @param criterion $criterion The criterion object (class below). + * @return self + */ + public function add_criteria(criterion $criterion): self { + $this->criteria[] = $criterion; + + return $this; + } + + /** + * Get all criterion values. + * + * @return array + */ + protected function get_all_criterion_values(): array { + $result = []; + + foreach ($this->criteria as $index => $criterion) { + $id = $index + 1; + $result["NEWID{$id}"] = $criterion->get_all_values($id); + } + + return $result; + + } +} diff --git a/grade/grading/form/rubric/tests/generator_test.php b/grade/grading/form/rubric/tests/generator_test.php new file mode 100644 index 00000000000..798633f3588 --- /dev/null +++ b/grade/grading/form/rubric/tests/generator_test.php @@ -0,0 +1,319 @@ +. + +/** + * Generator testcase for the gradingforum_rubric generator. + * + * @package gradingform_rubric + * @category test + * @copyright 2019 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace tests\gradingform_rubric; + +use advanced_testcase; +use context_module; +use gradingform_rubric_controller; +use gradingform_controller; + +/** + * Generator testcase for the gradingforum_rubric generator. + * + * @package gradingform_rubric + * @category test + * @copyright 2019 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class generator_testcase extends advanced_testcase { + + /** + * Test rubric creation. + */ + public function test_rubric_creation(): void { + $this->resetAfterTest(true); + + // Fetch generators. + $generator = \testing_util::get_data_generator(); + $rubricgenerator = $generator->get_plugin_generator('gradingform_rubric'); + + // Create items required for testing. + $course = $generator->create_course(); + $module = $generator->create_module('assign', ['course' => $course]); + $user = $generator->create_user(); + $context = context_module::instance($module->cmid); + + // Data for testing. + $name = 'myfirstrubric'; + $description = 'My first rubric'; + $criteria = [ + 'Alphabet' => [ + 'Not known' => 0, + 'Letters known but out of order' => 1, + 'Letters known in order ascending' => 2, + 'Letters known and can recite forwards and backwards' => 4, + ], + 'Times tables' => [ + 'Not known' => 0, + '2 times table known' => 2, + '2 and 5 times table known' => 4, + '2, 5, and 10 times table known' => 8, + ], + ]; + + // Unit under test. + $this->setUser($user); + $controller = $rubricgenerator->create_instance($context, 'mod_assign', 'submission', $name, $description, $criteria); + + $this->assertInstanceOf(gradingform_rubric_controller::class, $controller); + + $definition = $controller->get_definition(); + $this->assertNotEmpty($definition->id); + $this->assertEquals($name, $definition->name); + $this->assertEquals($description, $definition->description); + $this->assertEquals(gradingform_controller::DEFINITION_STATUS_READY, $definition->status); + $this->assertNotEmpty($definition->timecreated); + $this->assertNotEmpty($definition->timemodified); + $this->assertEquals($user->id, $definition->usercreated); + + $this->assertNotEmpty($definition->rubric_criteria); + $this->assertCount(2, $definition->rubric_criteria); + + // Check the alphabet criteria. + $criteriaids = array_keys($definition->rubric_criteria); + + $alphabet = $definition->rubric_criteria[$criteriaids[0]]; + $this->assertNotEmpty($alphabet['id']); + $this->assertEquals(1, $alphabet['sortorder']); + $this->assertEquals('Alphabet', $alphabet['description']); + + $this->assertNotEmpty($alphabet['levels']); + $levels = $alphabet['levels']; + $levelids = array_keys($levels); + + $level = $levels[$levelids[0]]; + $this->assertEquals(0, $level['score']); + $this->assertEquals('Not known', $level['definition']); + + $level = $levels[$levelids[1]]; + $this->assertEquals(1, $level['score']); + $this->assertEquals('Letters known but out of order', $level['definition']); + + $level = $levels[$levelids[2]]; + $this->assertEquals(2, $level['score']); + $this->assertEquals('Letters known in order ascending', $level['definition']); + + $level = $levels[$levelids[3]]; + $this->assertEquals(4, $level['score']); + $this->assertEquals('Letters known and can recite forwards and backwards', $level['definition']); + + // Check the times tables criteria. + $tables = $definition->rubric_criteria[$criteriaids[1]]; + $this->assertNotEmpty($tables['id']); + $this->assertEquals(2, $tables['sortorder']); + $this->assertEquals('Times tables', $tables['description']); + + $this->assertNotEmpty($tables['levels']); + $levels = $tables['levels']; + $levelids = array_keys($levels); + + $level = $levels[$levelids[0]]; + $this->assertEquals(0, $level['score']); + $this->assertEquals('Not known', $level['definition']); + + $level = $levels[$levelids[1]]; + $this->assertEquals(2, $level['score']); + $this->assertEquals('2 times table known', $level['definition']); + + $level = $levels[$levelids[2]]; + $this->assertEquals(4, $level['score']); + $this->assertEquals('2 and 5 times table known', $level['definition']); + + $level = $levels[$levelids[3]]; + $this->assertEquals(8, $level['score']); + $this->assertEquals('2, 5, and 10 times table known', $level['definition']); + } + + /** + * Test the get_level_and_criterion_for_values function. + * This is used for finding criterion and level information within a rubric. + */ + public function test_get_level_and_criterion_for_values(): void { + $this->resetAfterTest(true); + + // Fetch generators. + $generator = \testing_util::get_data_generator(); + $rubricgenerator = $generator->get_plugin_generator('gradingform_rubric'); + + // Create items required for testing. + $course = $generator->create_course(); + $module = $generator->create_module('assign', ['course' => $course]); + $user = $generator->create_user(); + $context = context_module::instance($module->cmid); + + // Data for testing. + $description = 'My first rubric'; + $criteria = [ + 'Alphabet' => [ + 'Not known' => 0, + 'Letters known but out of order' => 1, + 'Letters known in order ascending' => 2, + 'Letters known and can recite forwards and backwards' => 4, + ], + 'Times tables' => [ + 'Not known' => 0, + '2 times table known' => 2, + '2 and 5 times table known' => 4, + '2, 5, and 10 times table known' => 8, + ], + ]; + + $this->setUser($user); + $controller = $rubricgenerator->create_instance($context, 'mod_assign', 'submission', 'rubric', $description, $criteria); + + // Valid criterion and level. + $result = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Alphabet', 2); + $this->assertEquals('Alphabet', $result['criterion']->description); + $this->assertEquals('2', $result['level']->score); + $this->assertEquals('Letters known in order ascending', $result['level']->definition); + + // Valid criterion. Invalid level. + $result = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Alphabet', 3); + $this->assertEquals('Alphabet', $result['criterion']->description); + $this->assertNull($result['level']); + + // Invalid criterion. + $result = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Foo', 0); + $this->assertNull($result['criterion']); + } + + /** + * Tests for the get_test_rubric function. + */ + public function test_get_test_rubric(): void { + $this->resetAfterTest(true); + + // Fetch generators. + $generator = \testing_util::get_data_generator(); + $rubricgenerator = $generator->get_plugin_generator('gradingform_rubric'); + + // Create items required for testing. + $course = $generator->create_course(); + $module = $generator->create_module('assign', ['course' => $course]); + $user = $generator->create_user(); + $context = context_module::instance($module->cmid); + + $this->setUser($user); + $rubric = $rubricgenerator->get_test_rubric($context, 'assign', 'submissions'); + $definition = $rubric->get_definition(); + + $this->assertEquals('testrubric', $definition->name); + $this->assertEquals('Description text', $definition->description); + $this->assertEquals(gradingform_controller::DEFINITION_STATUS_READY, $definition->status); + + // Should create a rubric with 2 criterion. + $this->assertCount(2, $definition->rubric_criteria); + } + + /** + * Test the get_submitted_form_data function. + */ + public function test_get_submitted_form_data(): void { + $this->resetAfterTest(true); + + // Fetch generators. + $generator = \testing_util::get_data_generator(); + $rubricgenerator = $generator->get_plugin_generator('gradingform_rubric'); + + // Create items required for testing. + $course = $generator->create_course(); + $module = $generator->create_module('assign', ['course' => $course]); + $user = $generator->create_user(); + $context = context_module::instance($module->cmid); + + $this->setUser($user); + $controller = $rubricgenerator->get_test_rubric($context, 'assign', 'submissions'); + + $result = $rubricgenerator->get_submitted_form_data($controller, 93, [ + 'Spelling is important' => [ + 'score' => 1, + 'remark' => 'Good speeling', + ], + 'Pictures' => [ + 'score' => 2, + 'remark' => 'Lots of nice pictures!', + ] + ]); + + $this->assertIsArray($result); + $this->assertEquals(93, $result['itemid']); + $this->assertIsArray($result['criteria']); + $this->assertCount(2, $result['criteria']); + + $spelling = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Spelling is important', 1); + $this->assertIsArray($result['criteria'][$spelling['criterion']->id]); + $this->assertEquals($spelling['level']->id, $result['criteria'][$spelling['criterion']->id]['levelid']); + $this->assertEquals('Good speeling', $result['criteria'][$spelling['criterion']->id]['remark']); + + $pictures = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Pictures', 2); + $this->assertIsArray($result['criteria'][$pictures['criterion']->id]); + $this->assertEquals($pictures['level']->id, $result['criteria'][$pictures['criterion']->id]['levelid']); + $this->assertEquals('Lots of nice pictures!', $result['criteria'][$pictures['criterion']->id]['remark']); + } + + /** + * Test the get_test_form_data function. + */ + public function test_get_test_form_data(): void { + $this->resetAfterTest(true); + + // Fetch generators. + $generator = \testing_util::get_data_generator(); + $rubricgenerator = $generator->get_plugin_generator('gradingform_rubric'); + + // Create items required for testing. + $course = $generator->create_course(); + $module = $generator->create_module('assign', ['course' => $course]); + $user = $generator->create_user(); + $context = context_module::instance($module->cmid); + + $this->setUser($user); + $controller = $rubricgenerator->get_test_rubric($context, 'assign', 'submissions'); + + // Unit under test. + $result = $rubricgenerator->get_test_form_data( + $controller, + 1839, + 1, 'Propper good speling', + 0, 'ASCII art is not a picture' + ); + + $this->assertIsArray($result); + $this->assertEquals(1839, $result['itemid']); + $this->assertIsArray($result['criteria']); + $this->assertCount(2, $result['criteria']); + + $spelling = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Spelling is important', 1); + $this->assertIsArray($result['criteria'][$spelling['criterion']->id]); + $this->assertEquals($spelling['level']->id, $result['criteria'][$spelling['criterion']->id]['levelid']); + $this->assertEquals('Propper good speling', $result['criteria'][$spelling['criterion']->id]['remark']); + + $pictures = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Pictures', 0); + $this->assertIsArray($result['criteria'][$pictures['criterion']->id]); + $this->assertEquals($pictures['level']->id, $result['criteria'][$pictures['criterion']->id]['levelid']); + $this->assertEquals('ASCII art is not a picture', $result['criteria'][$pictures['criterion']->id]['remark']); + } +} diff --git a/grade/grading/form/rubric/tests/privacy_test.php b/grade/grading/form/rubric/tests/privacy_test.php index 9f9ab835327..4167dfece5e 100644 --- a/grade/grading/form/rubric/tests/privacy_test.php +++ b/grade/grading/form/rubric/tests/privacy_test.php @@ -23,11 +23,13 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die(); +namespace tests\gradingform_rubric; -use \core_privacy\tests\provider_testcase; -use \core_privacy\local\request\writer; -use \gradingform_rubric\privacy\provider; +use core_privacy\tests\provider_testcase; +use core_privacy\local\request\writer; +use gradingform_rubric\privacy\provider; +use gradingform_rubric_controller; +use context_module; /** * Privacy tests for gradingform_rubric @@ -35,7 +37,7 @@ use \gradingform_rubric\privacy\provider; * @copyright 2018 Adrian Greeve * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class gradingform_rubric_privacy_testcase extends provider_testcase { +class privacy_testcase extends provider_testcase { /** * Test the export of rubric data. @@ -45,43 +47,23 @@ class gradingform_rubric_privacy_testcase extends provider_testcase { $this->resetAfterTest(); $course = $this->getDataGenerator()->create_course(); $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); + $modulecontext = context_module::instance($module->cmid); $user = $this->getDataGenerator()->create_user(); - $this->setUser($user); - $modulecontext = context_module::instance($module->cmid); - $rubric = new test_rubric($modulecontext, 'testrubrib', 'Description text'); - $criterion = new test_criterion('Spelling is important'); - $criterion->add_level('Nothing but mistakes', 0); - $criterion->add_level('Several mistakes', 1); - $criterion->add_level('No mistakes', 2); - $rubric->add_criteria($criterion); - $criterion = new test_criterion('Pictures'); - $criterion->add_level('No pictures', 0); - $criterion->add_level('One picture', 1); - $criterion->add_level('More than one picture', 2); - $rubric->add_criteria($criterion); - $rubric->create_rubric(); + // Generate a test rubric and get its controller. + $controller = $this->get_test_rubric($modulecontext, 'assign', 'submissions'); - $controller = $rubric->manager->get_controller('rubric'); // In the situation of mod_assign this would be the id from assign_grades. $itemid = 1; $instance = $controller->create_instance($user->id, $itemid); - // I need the ids for the criteria and there doesn't seem to be a nice method to get it. - $criteria = $DB->get_records('gradingform_rubric_criteria'); - $data = ['criteria' => []]; - foreach ($criteria as $key => $value) { - if ($value->description == 'Spelling is important') { - $level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 1]); - $data['criteria'][$key]['levelid'] = $level->id; - $data['criteria'][$key]['remark'] = 'This user made several mistakes.'; - } else { - $level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 0]); - $data['criteria'][$key]['levelid'] = $level->id; - $data['criteria'][$key]['remark'] = 'Please add more pictures.'; - } - } - $data['itemid'] = $itemid; + + $data = $this->get_test_form_data( + $controller, + $itemid, + 1, 'This user made several mistakes.', + 0, 'Please add more pictures.' + ); // Update this instance with data. $instance->update($data); @@ -105,43 +87,23 @@ class gradingform_rubric_privacy_testcase extends provider_testcase { $this->resetAfterTest(); $course = $this->getDataGenerator()->create_course(); $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); + $modulecontext = context_module::instance($module->cmid); $user = $this->getDataGenerator()->create_user(); - $this->setUser($user); - $modulecontext = context_module::instance($module->cmid); - $rubric = new test_rubric($modulecontext, 'testrubrib', 'Description text'); - $criterion = new test_criterion('Spelling is important'); - $criterion->add_level('Nothing but mistakes', 0); - $criterion->add_level('Several mistakes', 1); - $criterion->add_level('No mistakes', 2); - $rubric->add_criteria($criterion); - $criterion = new test_criterion('Pictures'); - $criterion->add_level('No pictures', 0); - $criterion->add_level('One picture', 1); - $criterion->add_level('More than one picture', 2); - $rubric->add_criteria($criterion); - $rubric->create_rubric(); + // Generate a test rubric and get its controller. + $controller = $this->get_test_rubric($modulecontext, 'assign', 'submissions'); - $controller = $rubric->manager->get_controller('rubric'); // In the situation of mod_assign this would be the id from assign_grades. $itemid = 1; $instance = $controller->create_instance($user->id, $itemid); - // I need the ids for the criteria and there doesn't seem to be a nice method to get it. - $criteria = $DB->get_records('gradingform_rubric_criteria'); - $data = ['criteria' => []]; - foreach ($criteria as $key => $value) { - if ($value->description == 'Spelling is important') { - $level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 1]); - $data['criteria'][$key]['levelid'] = $level->id; - $data['criteria'][$key]['remark'] = 'This user made several mistakes.'; - } else { - $level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 0]); - $data['criteria'][$key]['levelid'] = $level->id; - $data['criteria'][$key]['remark'] = 'Please add more pictures.'; - } - } - $data['itemid'] = $itemid; + + $data = $this->get_test_form_data( + $controller, + $itemid, + 1, 'This user made several mistakes.', + 0, 'Please add more pictures.' + ); // Update this instance with data. $instance->update($data); @@ -149,21 +111,13 @@ class gradingform_rubric_privacy_testcase extends provider_testcase { // Second instance. $itemid = 2; $instance = $controller->create_instance($user->id, $itemid); - // I need the ids for the criteria and there doesn't seem to be a nice method to get it. - $criteria = $DB->get_records('gradingform_rubric_criteria'); - $data = ['criteria' => []]; - foreach ($criteria as $key => $value) { - if ($value->description == 'Spelling is important') { - $level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 0]); - $data['criteria'][$key]['levelid'] = $level->id; - $data['criteria'][$key]['remark'] = 'Too many mistakes. Please try again.'; - } else { - $level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 2]); - $data['criteria'][$key]['levelid'] = $level->id; - $data['criteria'][$key]['remark'] = 'Great number of pictures. Well done.'; - } - } - $data['itemid'] = $itemid; + + $data = $this->get_test_form_data( + $controller, + $itemid, + 0, 'Too many mistakes. Please try again.', + 2, 'Great number of pictures. Well done.' + ); // Update this instance with data. $instance->update($data); @@ -179,135 +133,51 @@ class gradingform_rubric_privacy_testcase extends provider_testcase { $this->assertNotEquals($instance->get_id(), $record->instanceid); } } -} - -/** - * Convenience class to create rubrics. - * - * @copyright 2018 Adrian Greeve - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class test_rubric { - - /** @var array $criteria The criteria for this rubric. */ - protected $criteria = []; - /** @var context The context that this rubric is in. */ - protected $context; - /** @var string The name of this rubric. */ - protected $name; - /** @var string A description for this rubric. */ - protected $text; - /** @var integer The current criterion ID. This is incremented when a new criterion is added. */ - protected $criterionid = 0; - /** @var grading_manager An object for managing the rubric. */ - public $manager; /** - * Constuctor for this rubric. + * Generate a rubric controller with sample data required for testing of this class. * - * @param context $context The context that this rubric is being used in. - * @param string $name Name of the rubric. - * @param string $text Description of the rubric. + * @param context_module $context + * @param string $component + * @param string $area + * @return gradingform_rubric_controller */ - public function __construct($context, $name, $text) { - $this->context = $context; - $this->name = $name; - $this->text = $text; - $this->manager = get_grading_manager(); - $this->manager->set_context($context); - $this->manager->set_component('mod_assign'); - $this->manager->set_area('submission'); + protected function get_test_rubric(context_module $context, string $component, string $area): gradingform_rubric_controller { + $generator = \testing_util::get_data_generator(); + $rubricgenerator = $generator->get_plugin_generator('gradingform_rubric'); + + return $rubricgenerator->get_test_rubric($context, $component, $area); } /** - * Creates the rubric using the appropriate APIs. - */ - public function create_rubric() { - - $data = (object) [ - 'areaid' => $this->context->id, - 'returnurl' => '', - 'name' => $this->name, - 'description_editor' => [ - 'text' => $this->text, - 'format' => 1, - 'itemid' => 1 - ], - 'rubric' => [ - 'criteria' => $this->criteria, - 'options' => [ - 'sortlevelsasc' => 1, - 'lockzeropoints' => 1, - 'showdescriptionteacher' => 1, - 'showdescriptionstudent' => 1, - 'showscoreteacher' => 1, - 'showscorestudent' => 1, - 'enableremarks' => 1, - 'showremarksstudent' => 1 - ] - ], - 'saverubric' => 'Save rubric and make it ready', - 'status' => 20 - ]; - - $controller = $this->manager->get_controller('rubric'); - $controller->update_definition($data); - } - - /** - * Adds a criterion to the rubric. + * Fetch a set of sample data. * - * @param test_criterion $criterion The criterion object (class below). + * @param gradingform_rubric_controller $controller + * @param int $itemid + * @param float $spellingscore + * @param string $spellingremark + * @param float $picturescore + * @param string $pictureremark + * @return array */ - public function add_criteria($criterion) { + protected function get_test_form_data( + gradingform_rubric_controller $controller, + int $itemid, + float $spellingscore, + string $spellingremark, + float $picturescore, + string $pictureremark + ): array { + $generator = \testing_util::get_data_generator(); + $rubricgenerator = $generator->get_plugin_generator('gradingform_rubric'); - $this->criterionid++; - $this->criteria['NEWID' . $this->criterionid] = [ - 'description' => $criterion->description, - 'sortorder' => $this->criterionid, - 'levels' => $criterion->levels - ]; - } - -} - -/** - * Convenience class to create rubric criterion. - * - * @copyright 2018 Adrian Greeve - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class test_criterion { - - /** @var string $description A description of the criterion. */ - public $description; - /** @var integer $sortorder sort order of the criterion. */ - public $sortorder = 0; - /** @var integer $levelid The current level id for this level*/ - public $levelid = 0; - /** @var array $levels The levels for this criterion. */ - public $levels = []; - - /** - * Constructor for this test_criterion object - * - * @param string $description A description of this criterion. - */ - public function __construct($description) { - $this->description = $description; - } - - /** - * Adds levels to the criterion. - * - * @param string $definition The definition for this level. - * @param int $score The score received if this level is selected. - */ - public function add_level($definition, $score) { - $this->levelid++; - $this->levels['NEWID' . $this->levelid] = [ - 'definition' => $definition, - 'score' => $score - ]; + return $rubricgenerator->get_test_form_data( + $controller, + $itemid, + $spellingscore, + $spellingremark, + $picturescore, + $pictureremark + ); } }