diff --git a/grade/grading/form/guide/tests/privacy_test.php b/grade/grading/form/guide/tests/privacy_test.php index 4fc4278da0c..d92dbe626d1 100644 --- a/grade/grading/form/guide/tests/privacy_test.php +++ b/grade/grading/form/guide/tests/privacy_test.php @@ -25,6 +25,9 @@ defined('MOODLE_INTERNAL') || die(); +global $CFG; +require_once($CFG->dirroot . '/grade/grading/tests/fixtures/marking_guide.php'); + use \core_privacy\tests\provider_testcase; use \core_privacy\local\request\writer; use \gradingform_guide\privacy\provider; @@ -74,4 +77,149 @@ class gradingform_guide_privacy_testcase extends provider_testcase { $this->assertEquals(get_string('no'), $prefs->{'gradingform_guide-showmarkerdesc'}->value); $this->assertEquals(get_string('yes'), $prefs->{'gradingform_guide-showstudentdesc'}->value); } + + /** + * Test the export of rubric data. + */ + public function test_get_gradingform_export_data() { + global $DB; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); + $user = $this->getDataGenerator()->create_user(); + + $this->setUser($user); + + $modulecontext = context_module::instance($module->cmid); + $guide = new test_guide($modulecontext, 'testrubrib', 'Description text'); + $guide->add_criteria( + 'Spelling mistakes', + 'Full marks will be given for no spelling mistakes.', + 'Deduct 5 points per spelling mistake made.', + 25 + ); + $guide->add_criteria( + 'Pictures', + 'Full marks will be given for including 3 pictures.', + 'Give 5 points for each picture present', + 15 + ); + $guide->create_guide(); + + $controller = $guide->manager->get_controller('guide'); + // 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_guide_criteria'); + $data = ['criteria' => []]; + foreach ($criteria as $key => $value) { + if ($value->shortname == 'Spelling mistakes') { + $data['criteria'][$key]['remark'] = 'This user made several mistakes.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 5; + } else { + $data['criteria'][$key]['remark'] = 'This user has two pictures.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 10; + } + } + $data['itemid'] = $itemid; + + // Update this instance with data. + $instance->update($data); + + // Let's try the method we are testing. + provider::export_gradingform_instance_data($modulecontext, $instance->get_id(), ['Test']); + $data = (array) writer::with_context($modulecontext)->get_data(['Test', 'Marking guide']); + $this->assertCount(2, $data); + $this->assertEquals('Spelling mistakes', $data['Spelling mistakes']->shortname); + $this->assertEquals('This user made several mistakes.', $data['Spelling mistakes']->remark); + $this->assertEquals('Pictures', $data['Pictures']->shortname); + $this->assertEquals('This user has two pictures.', $data['Pictures']->remark); + } + + /** + * Test the deletion of rubric user information via the instance ID. + */ + public function test_delete_gradingform_for_instances() { + global $DB; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); + $user = $this->getDataGenerator()->create_user(); + + $this->setUser($user); + + $modulecontext = context_module::instance($module->cmid); + $guide = new test_guide($modulecontext, 'testrubrib', 'Description text'); + $guide->add_criteria( + 'Spelling mistakes', + 'Full marks will be given for no spelling mistakes.', + 'Deduct 5 points per spelling mistake made.', + 25 + ); + $guide->add_criteria( + 'Pictures', + 'Full marks will be given for including 3 pictures.', + 'Give 5 points for each picture present', + 15 + ); + $guide->create_guide(); + + $controller = $guide->manager->get_controller('guide'); + // 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_guide_criteria'); + $data = ['criteria' => []]; + foreach ($criteria as $key => $value) { + if ($value->shortname == 'Spelling mistakes') { + $data['criteria'][$key]['remark'] = 'This user made several mistakes.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 5; + } else { + $data['criteria'][$key]['remark'] = 'This user has two pictures.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 10; + } + } + $data['itemid'] = $itemid; + + // Update this instance with data. + $instance->update($data); + + $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_guide_criteria'); + $data = ['criteria' => []]; + foreach ($criteria as $key => $value) { + if ($value->shortname == 'Spelling mistakes') { + $data['criteria'][$key]['remark'] = 'This user made no mistakes.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 25; + } else { + $data['criteria'][$key]['remark'] = 'This user has one pictures.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 5; + } + } + $data['itemid'] = $itemid; + + // Update this instance with data. + $instance->update($data); + + // Check how many records we have in the fillings table. + $records = $DB->get_records('gradingform_guide_fillings'); + $this->assertCount(4, $records); + // Let's delete one of the instances (the last one would be the easiest). + provider::delete_gradingform_for_instances([$instance->get_id()]); + $records = $DB->get_records('gradingform_guide_fillings'); + $this->assertCount(2, $records); + foreach ($records as $record) { + $this->assertNotEquals($instance->get_id(), $record->instanceid); + } + } } diff --git a/grade/grading/form/rubric/tests/privacy_test.php b/grade/grading/form/rubric/tests/privacy_test.php new file mode 100644 index 00000000000..2974b83fad3 --- /dev/null +++ b/grade/grading/form/rubric/tests/privacy_test.php @@ -0,0 +1,312 @@ +. + +/** + * Privacy tests for gradingform_rubric + * + * @package gradingform_rubric + * @category test + * @copyright 2018 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +use \core_privacy\tests\provider_testcase; +use \core_privacy\local\request\writer; +use \gradingform_rubric\privacy\provider; + +/** + * Privacy tests for gradingform_rubric + * + * @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 { + + /** + * Test the export of rubric data. + */ + public function test_get_gradingform_export_data() { + global $DB; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); + $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(); + + $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; + + // Update this instance with data. + $instance->update($data); + + // Let's try the method we are testing. + provider::export_gradingform_instance_data($modulecontext, $instance->get_id(), ['Test']); + $data = (array) writer::with_context($modulecontext)->get_data(['Test', 'Rubric']); + $this->assertCount(2, $data); + $this->assertEquals('Spelling is important', $data['Spelling is important']->description); + $this->assertEquals('This user made several mistakes.', $data['Spelling is important']->remark); + $this->assertEquals('Pictures', $data['Pictures']->description); + $this->assertEquals('Please add more pictures.', $data['Pictures']->remark); + } + + /** + * Test the deletion of rubric user information via the instance ID. + */ + public function test_delete_gradingform_for_instances() { + global $DB; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); + $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(); + + $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; + + // Update this instance with data. + $instance->update($data); + + // 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; + + // Update this instance with data. + $instance->update($data); + + // Check how many records we have in the fillings table. + $records = $DB->get_records('gradingform_rubric_fillings'); + $this->assertCount(4, $records); + // Let's delete one of the instances (the last one would be the easiest). + provider::delete_gradingform_for_instances([$instance->get_id()]); + $records = $DB->get_records('gradingform_rubric_fillings'); + $this->assertCount(2, $records); + foreach ($records as $record) { + $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. + * + * @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. + */ + 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'); + } + + /** + * 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. + * + * @param test_criterion $criterion The criterion object (class below). + */ + public function add_criteria($criterion) { + + $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 + ]; + } +} diff --git a/grade/grading/tests/fixtures/marking_guide.php b/grade/grading/tests/fixtures/marking_guide.php new file mode 100644 index 00000000000..027aeb0ef97 --- /dev/null +++ b/grade/grading/tests/fixtures/marking_guide.php @@ -0,0 +1,118 @@ +. + +/** + * A test guide class fixture. + * + * @package core_grading + * @category test + * @copyright 2018 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Convenience class to create marking guides. + * + * @copyright 2018 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class test_guide { + + /** @var array $criteria Criteria for this marking guide. */ + protected $criteria = []; + /** @var context $context The context that this marking guide is used in. */ + protected $context; + /** @var string $name The name of this marking guide. */ + protected $name; + /** @var string $text A description of this marking guide. */ + protected $text; + /** @var integer $criterionid The current id for the criterion. */ + protected $criterionid = 0; + /** @var integer $sortorder The current id for the sort order. */ + protected $sortorder = 0; + + /** @var grading_manager $manager The grading manager to handle creating the real marking guide. */ + public $manager; + + /** + * The constuctor for this test_guide object. + * + * @param context $context The context that this marking guide is used in. + * @param string $name The name of the marking guide. + * @param string $text The description of the marking guide. + */ + 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'); + } + + /** + * Uses the appropriate data and APIs to create a marking guide. + */ + public function create_guide() { + + $data = (object) [ + 'areaid' => $this->context->id, + 'returnurl' => '', + 'name' => $this->name, + 'description_editor' => [ + 'text' => $this->text, + 'format' => 1, + 'itemid' => 1 + ], + 'guide' => [ + 'criteria' => $this->criteria, + 'options' => [ + 'alwaysshowdefinition' => 1, + 'showmarkspercriterionstudents' => 1 + ], + 'comments' => [] + ], + 'saveguide' => 'Continue', + 'status' => 20 + ]; + + $controller = $this->manager->get_controller('guide'); + $controller->update_definition($data); + } + + /** + * Adds criteria to the marking guide. + * + * @param string $shortname The shortname for the criterion. + * @param string $description The description for the criterion. + * @param string $descriptionmarkers The description for the marker for this criterion. + * @param int $maxscore The maximum score possible for this criterion. + */ + public function add_criteria($shortname, $description, $descriptionmarkers, $maxscore) { + $this->criterionid++; + $this->sortorder++; + $this->criteria['NEWID' . $this->criterionid] = [ + 'sortorder' => $this->sortorder, + 'shortname' => $shortname, + 'description' => $description, + 'descriptionmarkers' => $descriptionmarkers, + 'maxscore' => $maxscore + ]; + } +} diff --git a/grade/grading/tests/privacy_legacy_polyfill_test.php b/grade/grading/tests/privacy_legacy_polyfill_test.php index c0c2e3b8707..241224a9314 100644 --- a/grade/grading/tests/privacy_legacy_polyfill_test.php +++ b/grade/grading/tests/privacy_legacy_polyfill_test.php @@ -33,7 +33,45 @@ defined('MOODLE_INTERNAL') || die(); */ class gradeform_privacy_legacy_polyfill_test extends advanced_testcase { /** - * Test that the core_grading\privacy\legacy_polyfill works and that the static _get_grading_export_data can be called. + * Test that the core_grading\privacy\legacy_polyfill works and that the static _export_gradingform_instance_data can be called. + */ + public function test_export_gradingform_instance_data() { + $context = context_system::instance(); + + $mock = $this->createMock(test_gradingform_legacy_polyfill_mock_wrapper::class); + $mock->expects($this->once()) + ->method('get_return_value') + ->with('_export_gradingform_instance_data', [$context, 3, ['subcontext']]); + + test_legacy_polyfill_gradingform_provider::$mock = $mock; + test_legacy_polyfill_gradingform_provider::export_gradingform_instance_data($context, 3, ['subcontext']); + } + + /** + * Test for _get_metadata shim. + */ + public function test_get_metadata() { + $collection = new \core_privacy\local\metadata\collection('core_gradingform'); + $this->assertSame($collection, test_legacy_polyfill_gradingform_provider::get_metadata($collection)); + } + + /** + * Test the _delete_gradingform_for_instances shim. + */ + public function test_delete_gradingform_for_instances() { + $context = context_system::instance(); + + $mock = $this->createMock(test_gradingform_legacy_polyfill_mock_wrapper::class); + $mock->expects($this->once()) + ->method('get_return_value') + ->with('_delete_gradingform_for_instances', [[3, 17]]); + + test_legacy_polyfill_gradingform_provider::$mock = $mock; + test_legacy_polyfill_gradingform_provider::delete_gradingform_for_instances([3, 17]); + } + + /** + * Test the __get_gradingform_export_data shim. */ public function test_get_gradingform_export_data() { $userid = 476; @@ -46,14 +84,7 @@ class gradeform_privacy_legacy_polyfill_test extends advanced_testcase { test_legacy_polyfill_gradingform_provider::$mock = $mock; test_legacy_polyfill_gradingform_provider::get_gradingform_export_data($context, (object)[], $userid); - } - - /** - * Test for _get_metadata shim. - */ - public function test_get_metadata() { - $collection = new \core_privacy\local\metadata\collection('core_gradingform'); - $this->assertSame($collection, test_legacy_polyfill_gradingform_provider::get_metadata($collection)); + $this->assertDebuggingCalled(); } /** @@ -69,10 +100,11 @@ class gradeform_privacy_legacy_polyfill_test extends advanced_testcase { test_legacy_polyfill_gradingform_provider::$mock = $mock; test_legacy_polyfill_gradingform_provider::delete_gradingform_for_context($context); + $this->assertDebuggingCalled(); } /** - * Test the _delete_gradingform_for_context shim. + * Test the _delete_gradingform_for_userid shim. */ public function test_delete_gradingform_for_user() { $userid = 696; @@ -85,6 +117,7 @@ class gradeform_privacy_legacy_polyfill_test extends advanced_testcase { test_legacy_polyfill_gradingform_provider::$mock = $mock; test_legacy_polyfill_gradingform_provider::delete_gradingform_for_userid($userid, $context); + $this->assertDebuggingCalled(); } } @@ -96,7 +129,8 @@ class gradeform_privacy_legacy_polyfill_test extends advanced_testcase { */ class test_legacy_polyfill_gradingform_provider implements \core_privacy\local\metadata\provider, - \core_grading\privacy\gradingform_provider { + \core_grading\privacy\gradingform_provider, + \core_grading\privacy\gradingform_provider_v2 { use \core_grading\privacy\gradingform_legacy_polyfill; use \core_privacy\local\legacy_polyfill; @@ -107,32 +141,22 @@ class test_legacy_polyfill_gradingform_provider implements public static $mock = null; /** - * Export all user data for the gradingform plugin. + * Export user data relating to an instance ID. * - * @param context $context - * @param stdClass $definition - * @param int $userid + * @param \context $context Context to use with the export writer. + * @param int $instanceid The instance ID to export data for. + * @param array $subcontext The directory to export this data to. */ - protected static function _get_gradingform_export_data(\context $context, $definition, $userid) { + protected static function _export_gradingform_instance_data(\context $context, $instanceid, $subcontext) { static::$mock->get_return_value(__FUNCTION__, func_get_args()); } /** - * Deletes all user data for the given context. + * Deletes all user data related to the provided instance IDs. * - * @param context $context + * @param array $instanceids The instance IDs to delete information from. */ - protected static function _delete_gradingform_for_context(\context $context) { - static::$mock->get_return_value(__FUNCTION__, func_get_args()); - } - - /** - * Delete personal data for the given user and context. - * - * @param int $userid - * @param context $context - */ - protected static function _delete_gradingform_for_userid($userid, \context $context) { + protected static function _delete_gradingform_for_instances($instanceids) { static::$mock->get_return_value(__FUNCTION__, func_get_args()); } @@ -145,6 +169,47 @@ class test_legacy_polyfill_gradingform_provider implements protected static function _get_metadata(\core_privacy\local\metadata\collection $collection) { return $collection; } + + /** + * This method is used to export any user data this sub-plugin has using the object to get the context and userid. + * + * @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface. + * @todo MDL-63137 remove this method. + * + * @param context $context Context owner of the data. + * @param stdClass $definition Grading definition entry to export. + * @param int $userid The user whose information is to be exported. + * + * @return stdClass The data to export. + */ + protected static function _get_gradingform_export_data(\context $context, $definition, int $userid) { + static::$mock->get_return_value(__FUNCTION__, func_get_args()); + } + + /** + * Any call to this method should delete all user data for the context defined. + * + * @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface. + * @todo MDL-63137 remove this method. + * + * @param context $context Context owner of the data. + */ + protected static function _delete_gradingform_for_context(\context $context) { + static::$mock->get_return_value(__FUNCTION__, func_get_args()); + } + + /** + * A call to this method should delete user data (where practicle) from the userid and context. + * + * @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface. + * @todo MDL-63137 remove this method. + * + * @param int $userid The user whose information is to be deleted. + * @param context $context Context owner of the data. + */ + protected static function _delete_gradingform_for_userid(int $userid, \context $context) { + static::$mock->get_return_value(__FUNCTION__, func_get_args()); + } } /** diff --git a/grade/grading/tests/privacy_test.php b/grade/grading/tests/privacy_test.php index 8fcc46ccedb..0a46b5df7d9 100644 --- a/grade/grading/tests/privacy_test.php +++ b/grade/grading/tests/privacy_test.php @@ -25,6 +25,9 @@ defined('MOODLE_INTERNAL') || die(); +global $CFG; +require_once($CFG->dirroot . '/grade/grading/tests/fixtures/marking_guide.php'); + use \core_privacy\tests\provider_testcase; use \core_privacy\local\request\approved_contextlist; use \core_privacy\local\request\transform; @@ -243,6 +246,154 @@ class core_grading_privacy_testcase extends provider_testcase { $this->assertCount(2, $DB->get_records('grading_definitions')); } + /** + * Test exporting user data relating to an item ID. + */ + public function test_export_item_data() { + global $DB; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); + $user = $this->getDataGenerator()->create_user(); + + $this->setUser($user); + + $modulecontext = context_module::instance($module->cmid); + $guide = new test_guide($modulecontext, 'testrubrib', 'Description text'); + $guide->add_criteria( + 'Spelling mistakes', + 'Full marks will be given for no spelling mistakes.', + 'Deduct 5 points per spelling mistake made.', + 25 + ); + $guide->add_criteria( + 'Pictures', + 'Full marks will be given for including 3 pictures.', + 'Give 5 points for each picture present', + 15 + ); + $guide->create_guide(); + + $controller = $guide->manager->get_controller('guide'); + // 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_guide_criteria'); + $data = ['criteria' => []]; + foreach ($criteria as $key => $value) { + if ($value->shortname == 'Spelling mistakes') { + $data['criteria'][$key]['remark'] = 'This user made several mistakes.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 5; + } else { + $data['criteria'][$key]['remark'] = 'This user has two pictures.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 10; + } + } + $data['itemid'] = $itemid; + + // Update this instance with data. + $instance->update($data); + + provider::export_item_data($modulecontext, $itemid, ['Test']); + $data = (array) writer::with_context($modulecontext)->get_data(['Test', 'Marking guide']); + $this->assertCount(2, $data); + $this->assertEquals('This user made several mistakes.', $data['Spelling mistakes']->remark); + $this->assertEquals(5, $data['Spelling mistakes']->score); + $this->assertEquals('This user has two pictures.', $data['Pictures']->remark); + $this->assertEquals(10, $data['Pictures']->score); + } + + /** + * Test deleting user data related to a context and item ID. + */ + public function test_delete_instance_data() { + global $DB; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); + $user = $this->getDataGenerator()->create_user(); + + $this->setUser($user); + + $modulecontext = context_module::instance($module->cmid); + $guide = new test_guide($modulecontext, 'testrubrib', 'Description text'); + $guide->add_criteria( + 'Spelling mistakes', + 'Full marks will be given for no spelling mistakes.', + 'Deduct 5 points per spelling mistake made.', + 25 + ); + $guide->add_criteria( + 'Pictures', + 'Full marks will be given for including 3 pictures.', + 'Give 5 points for each picture present', + 15 + ); + $guide->create_guide(); + + $controller = $guide->manager->get_controller('guide'); + // 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_guide_criteria'); + $data = ['criteria' => []]; + foreach ($criteria as $key => $value) { + if ($value->shortname == 'Spelling mistakes') { + $data['criteria'][$key]['remark'] = 'This user made several mistakes.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 5; + } else { + $data['criteria'][$key]['remark'] = 'This user has two pictures.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 10; + } + } + $data['itemid'] = $itemid; + + // Update this instance with data. + $instance->update($data); + + $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_guide_criteria'); + $data = ['criteria' => []]; + foreach ($criteria as $key => $value) { + if ($value->shortname == 'Spelling mistakes') { + $data['criteria'][$key]['remark'] = 'This user made no mistakes.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 25; + } else { + $data['criteria'][$key]['remark'] = 'This user has one pictures.'; + $data['criteria'][$key]['remarkformat'] = 0; + $data['criteria'][$key]['score'] = 5; + } + } + $data['itemid'] = $itemid; + + // Update this instance with data. + $instance->update($data); + + // Check how many records we have in the fillings table. + $records = $DB->get_records('gradingform_guide_fillings'); + $this->assertCount(4, $records); + // Let's delete one of the instances (the last one would be the easiest). + provider::delete_instance_data($modulecontext, $itemid); + $records = $DB->get_records('gradingform_guide_fillings'); + $this->assertCount(2, $records); + foreach ($records as $record) { + $this->assertNotEquals($instance->get_id(), $record->instanceid); + } + // This will delete all the rest of the instances for this context. + provider::delete_instance_data($modulecontext); + $records = $DB->get_records('gradingform_guide_fillings'); + $this->assertEmpty($records); + } + /** * Helper function to setup the environment. *