MDL-62535 core_grading: Unit test for new methods.
authorAdrian Greeve <adrian@moodle.com>
Fri, 15 Jun 2018 03:40:56 +0000 (11:40 +0800)
committerAdrian Greeve <abgreeve@gmail.com>
Mon, 20 Aug 2018 03:32:01 +0000 (11:32 +0800)
grade/grading/form/guide/tests/privacy_test.php
grade/grading/form/rubric/tests/privacy_test.php [new file with mode: 0644]
grade/grading/tests/fixtures/marking_guide.php [new file with mode: 0644]
grade/grading/tests/privacy_legacy_polyfill_test.php
grade/grading/tests/privacy_test.php

index 4fc4278..d92dbe6 100644 (file)
@@ -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 (file)
index 0000000..2974b83
--- /dev/null
@@ -0,0 +1,312 @@
+<?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/>.
+
+/**
+ * Privacy tests for gradingform_rubric
+ *
+ * @package    gradingform_rubric
+ * @category   test
+ * @copyright  2018 Adrian Greeve <adriangreeve.com>
+ * @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 <adriangreeve.com>
+ * @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 <adriangreeve.com>
+ * @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 <adriangreeve.com>
+ * @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 (file)
index 0000000..027aeb0
--- /dev/null
@@ -0,0 +1,118 @@
+<?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/>.
+
+/**
+ * A test guide class fixture.
+ *
+ * @package    core_grading
+ * @category   test
+ * @copyright  2018 Adrian Greeve <adriangreeve.com>
+ * @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 <adriangreeve.com>
+ * @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
+        ];
+    }
+}
index c0c2e3b..241224a 100644 (file)
@@ -33,19 +33,18 @@ 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_get_gradingform_export_data() {
-        $userid = 476;
+    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('_get_gradingform_export_data', [$context, (object)[], $userid]);
+            ->with('_export_gradingform_instance_data', [$context, 3, ['subcontext']]);
 
         test_legacy_polyfill_gradingform_provider::$mock = $mock;
-        test_legacy_polyfill_gradingform_provider::get_gradingform_export_data($context, (object)[], $userid);
+        test_legacy_polyfill_gradingform_provider::export_gradingform_instance_data($context, 3, ['subcontext']);
     }
 
     /**
@@ -56,6 +55,38 @@ class gradeform_privacy_legacy_polyfill_test extends advanced_testcase {
         $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;
+        $context = context_system::instance();
+
+        $mock = $this->createMock(test_gradingform_legacy_polyfill_mock_wrapper::class);
+        $mock->expects($this->once())
+            ->method('get_return_value')
+            ->with('_get_gradingform_export_data', [$context, (object)[], $userid]);
+
+        test_legacy_polyfill_gradingform_provider::$mock = $mock;
+        test_legacy_polyfill_gradingform_provider::get_gradingform_export_data($context, (object)[], $userid);
+        $this->assertDebuggingCalled();
+    }
+
     /**
      * Test the _delete_gradingform_for_context shim.
      */
@@ -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,43 +141,74 @@ 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) {
+    protected static function _delete_gradingform_for_instances($instanceids) {
         static::$mock->get_return_value(__FUNCTION__, func_get_args());
     }
 
     /**
-     * Delete personal data for the given user and context.
+     * Returns metadata about this plugin.
      *
-     * @param int $userid
-     * @param context $context
+     * @param   \core_privacy\local\metadata\collection $collection The initialised collection to add items to.
+     * @return  \core_privacy\local\metadata\collection     A listing of user data stored through this system.
      */
-    protected static function _delete_gradingform_for_userid($userid, \context $context) {
+    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());
     }
 
     /**
-     * Returns metadata about this plugin.
+     * Any call to this method should delete all user data for the context defined.
      *
-     * @param   \core_privacy\local\metadata\collection $collection The initialised collection to add items to.
-     * @return  \core_privacy\local\metadata\collection     A listing of user data stored through this system.
+     * @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 _get_metadata(\core_privacy\local\metadata\collection $collection) {
-        return $collection;
+    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());
     }
 }
 
index 8fcc46c..0a46b5d 100644 (file)
@@ -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.
      *