MDL-63531 assignfeedback: Update to use the new privacy interface.
authorAdrian Greeve <abgreeve@gmail.com>
Wed, 10 Oct 2018 00:55:20 +0000 (08:55 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Tue, 30 Oct 2018 01:47:14 +0000 (09:47 +0800)
This now uses the new interface to allow the deletion of users based
on a context.

mod/assign/classes/privacy/assignfeedback_user_provider.php [new file with mode: 0644]
mod/assign/feedback/comments/classes/privacy/provider.php
mod/assign/feedback/comments/tests/privacy_test.php
mod/assign/feedback/editpdf/classes/privacy/provider.php
mod/assign/feedback/editpdf/tests/privacy_test.php
mod/assign/feedback/file/classes/privacy/provider.php
mod/assign/feedback/file/tests/privacy_test.php

diff --git a/mod/assign/classes/privacy/assignfeedback_user_provider.php b/mod/assign/classes/privacy/assignfeedback_user_provider.php
new file mode 100644 (file)
index 0000000..9048430
--- /dev/null
@@ -0,0 +1,52 @@
+<?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/>.
+
+/**
+ * This file contains the assignfeedback_user_provider interface.
+ *
+ * Assignment Sub plugins should implement this if they store personal information and can retrieve a userid.
+ *
+ * @package mod_assign
+ * @copyright 2018 Adrian Greeve <adrian@moodle.com>
+ *
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace mod_assign\privacy;
+
+defined('MOODLE_INTERNAL') || die();
+
+interface assignfeedback_user_provider extends \core_privacy\local\request\plugin\subplugin_provider {
+
+    /**
+     * If you have tables that contain userids and you can generate entries in your tables without creating an
+     * entry in the assign_grades table then please fill in this method.
+     *
+     * @param  \core_privacy\local\request\userlist $userlist The userlist object
+     */
+    public static function get_userids_from_context(\core_privacy\local\request\userlist $userlist);
+
+    /**
+     * Deletes all feedback for the grade ids / userids provided in a context.
+     * assign_plugin_request_data contains:
+     * - context
+     * - assign object
+     * - grade ids (pluginids)
+     * - user ids
+     * @param  assign_plugin_request_data $deletedata A class that contains the relevant information required for deletion.
+     */
+    public static function delete_feedback_for_grades(assign_plugin_request_data $deletedata);
+
+}
\ No newline at end of file
index 9302526..e6453e6 100644 (file)
@@ -29,8 +29,6 @@ defined('MOODLE_INTERNAL') || die();
 require_once($CFG->dirroot . '/mod/assign/locallib.php');
 
 use \core_privacy\local\metadata\collection;
-use \core_privacy\local\metadata\provider as metadataprovider;
-use \mod_assign\privacy\assignfeedback_provider;
 use \core_privacy\local\request\writer;
 use \core_privacy\local\request\contextlist;
 use \mod_assign\privacy\assign_plugin_request_data;
@@ -43,7 +41,10 @@ use \mod_assign\privacy\useridlist;
  * @copyright  2018 Adrian Greeve <adrian@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class provider implements metadataprovider, assignfeedback_provider {
+class provider implements
+        \core_privacy\local\metadata\provider,
+        \mod_assign\privacy\assignfeedback_provider,
+        \mod_assign\privacy\assignfeedback_user_provider {
 
     /**
      * Return meta data about this plugin.
@@ -83,6 +84,16 @@ class provider implements metadataprovider, assignfeedback_provider {
         // Not required.
     }
 
+    /**
+     * If you have tables that contain userids and you can generate entries in your tables without creating an
+     * entry in the assign_grades table then please fill in this method.
+     *
+     * @param  \core_privacy\local\request\userlist $userlist The userlist object
+     */
+    public static function get_userids_from_context(\core_privacy\local\request\userlist $userlist) {
+        // Not required.
+    }
+
     /**
      * Export all user data for this plugin.
      *
@@ -146,7 +157,37 @@ class provider implements metadataprovider, assignfeedback_provider {
         $fs->delete_area_files($requestdata->get_context()->id, ASSIGNFEEDBACK_COMMENTS_COMPONENT,
             ASSIGNFEEDBACK_COMMENTS_FILEAREA, $requestdata->get_pluginobject()->id);
 
-        $DB->delete_records('assignfeedback_comments', ['assignment' => $requestdata->get_assign()->get_instance()->id,
+        $DB->delete_records('assignfeedback_comments', ['assignment' => $requestdata->get_assignid(),
                 'grade' => $requestdata->get_pluginobject()->id]);
     }
+
+    /**
+     * Deletes all feedback for the grade ids / userids provided in a context.
+     * assign_plugin_request_data contains:
+     * - context
+     * - assign object
+     * - grade ids (pluginids)
+     * - user ids
+     * @param  assign_plugin_request_data $deletedata A class that contains the relevant information required for deletion.
+     */
+    public static function delete_feedback_for_grades(assign_plugin_request_data $deletedata) {
+        global $DB;
+        if (empty($deletedata->get_gradeids())) {
+            return;
+        }
+
+        list($sql, $params) = $DB->get_in_or_equal($deletedata->get_gradeids(), SQL_PARAMS_NAMED);
+
+        $fs = new \file_storage();
+        $fs->delete_area_files_select(
+                $deletedata->get_context()->id,
+                ASSIGNFEEDBACK_COMMENTS_COMPONENT,
+                ASSIGNFEEDBACK_COMMENTS_FILEAREA,
+                $sql,
+                $params
+            );
+
+        $params['assignment'] = $deletedata->get_assignid();
+        $DB->delete_records_select('assignfeedback_comments', "assignment = :assignment AND grade $sql", $params);
+    }
 }
index 276b9cf..2cfe8d5 100644 (file)
@@ -267,4 +267,83 @@ class assignfeedback_comments_privacy_testcase extends \mod_assign\tests\mod_ass
         $this->assertEquals('feedback1.txt', $file->get_filename());
         $this->assertEquals($grade2->id, $file->get_itemid());
     }
+
+    /**
+     * Test that a grade item is deleted for a user.
+     */
+    public function test_delete_feedback_for_grades() {
+        $this->resetAfterTest();
+        // Create course, assignment, submission, and then a feedback comment.
+        $course = $this->getDataGenerator()->create_course();
+        // Student.
+        $user1 = $this->getDataGenerator()->create_user();
+        $user2 = $this->getDataGenerator()->create_user();
+        $user3 = $this->getDataGenerator()->create_user();
+        $user4 = $this->getDataGenerator()->create_user();
+        // Teacher.
+        $user5 = $this->getDataGenerator()->create_user();
+        $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user4->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user5->id, $course->id, 'editingteacher');
+        $assign1 = $this->create_instance(['course' => $course]);
+        $assign2 = $this->create_instance(['course' => $course]);
+
+        $feedbacktext = '<p>first comment for this test</p>';
+        list($plugin1, $grade1) = $this->create_feedback($assign1, $user1, $user5, 'Submission text', $feedbacktext);
+        $feedbacktext = '<p>Comment for second student.</p>';
+        list($plugin2, $grade2) = $this->create_feedback($assign1, $user2, $user5, 'Submission text', $feedbacktext);
+        $feedbacktext = '<p>Comment for third student.</p>';
+        list($plugin3, $grade3) = $this->create_feedback($assign1, $user3, $user5, 'Submission text', $feedbacktext);
+        $feedbacktext = '<p>Comment for third student in the second assignment.</p>';
+        list($plugin4, $grade4) = $this->create_feedback($assign2, $user3, $user5, 'Submission text', $feedbacktext);
+        $feedbacktext = '<p>Comment for fourth student in the second assignment.</p>';
+        list($plugin5, $grade5) = $this->create_feedback($assign2, $user4, $user5, 'Submission text', $feedbacktext);
+
+        // Check that we have data.
+        $feedbackcomments = $plugin1->get_feedback_comments($grade1->id);
+        $this->assertNotEmpty($feedbackcomments);
+        $feedbackcomments = $plugin2->get_feedback_comments($grade2->id);
+        $this->assertNotEmpty($feedbackcomments);
+        $feedbackcomments = $plugin3->get_feedback_comments($grade3->id);
+        $this->assertNotEmpty($feedbackcomments);
+        $feedbackcomments = $plugin4->get_feedback_comments($grade4->id);
+        $this->assertNotEmpty($feedbackcomments);
+        $feedbackcomments = $plugin5->get_feedback_comments($grade5->id);
+        $this->assertNotEmpty($feedbackcomments);
+
+        $fs = new file_storage();
+        // 6 including directories for assign 1.
+        // 4 including directories for assign 2.
+        $this->assertCount(6, $fs->get_area_files($assign1->get_context()->id,
+                ASSIGNFEEDBACK_COMMENTS_COMPONENT, ASSIGNFEEDBACK_COMMENTS_FILEAREA));
+        $this->assertCount(4, $fs->get_area_files($assign2->get_context()->id,
+                ASSIGNFEEDBACK_COMMENTS_COMPONENT, ASSIGNFEEDBACK_COMMENTS_FILEAREA));
+
+        $deletedata = new \mod_assign\privacy\assign_plugin_request_data($assign1->get_context(), $assign1);
+        $deletedata->set_userids([$user1->id, $user3->id]);
+        $deletedata->populate_submissions_and_grades();
+        assignfeedback_comments\privacy\provider::delete_feedback_for_grades($deletedata);
+
+        // Check that grade 1 and grade 3 have been removed.
+        $feedbackcomments = $plugin1->get_feedback_comments($grade1->id);
+        $this->assertEmpty($feedbackcomments);
+        $feedbackcomments = $plugin2->get_feedback_comments($grade2->id);
+        $this->assertNotEmpty($feedbackcomments);
+        $feedbackcomments = $plugin3->get_feedback_comments($grade3->id);
+        $this->assertEmpty($feedbackcomments);
+        $feedbackcomments = $plugin4->get_feedback_comments($grade4->id);
+        $this->assertNotEmpty($feedbackcomments);
+        $feedbackcomments = $plugin5->get_feedback_comments($grade5->id);
+        $this->assertNotEmpty($feedbackcomments);
+
+        // We have deleted two from assign 1, and none from assign 2.
+        // 2 including directories for assign 1.
+        // 4 including directories for assign 2.
+        $this->assertCount(2, $fs->get_area_files($assign1->get_context()->id,
+                ASSIGNFEEDBACK_COMMENTS_COMPONENT, ASSIGNFEEDBACK_COMMENTS_FILEAREA));
+        $this->assertCount(4, $fs->get_area_files($assign2->get_context()->id,
+                ASSIGNFEEDBACK_COMMENTS_COMPONENT, ASSIGNFEEDBACK_COMMENTS_FILEAREA));
+    }
 }
index 7170604..c3fb4da 100644 (file)
@@ -29,7 +29,6 @@ defined('MOODLE_INTERNAL') || die();
 require_once($CFG->dirroot . '/mod/assign/locallib.php');
 
 use \core_privacy\local\metadata\collection;
-use \core_privacy\local\metadata\provider as metadataprovider;
 use \mod_assign\privacy\assignfeedback_provider;
 use \core_privacy\local\request\writer;
 use \core_privacy\local\request\contextlist;
@@ -43,7 +42,10 @@ use \mod_assign\privacy\useridlist;
  * @copyright  2018 Adrian Greeve <adrian@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class provider implements metadataprovider, assignfeedback_provider {
+class provider implements
+        \core_privacy\local\metadata\provider,
+        \mod_assign\privacy\assignfeedback_provider,
+        \mod_assign\privacy\assignfeedback_user_provider {
 
     /**
      * Return meta data about this plugin.
@@ -83,6 +85,16 @@ class provider implements metadataprovider, assignfeedback_provider {
         // Not required.
     }
 
+    /**
+     * If you have tables that contain userids and you can generate entries in your tables without creating an
+     * entry in the assign_grades table then please fill in this method.
+     *
+     * @param  \core_privacy\local\request\userlist $userlist The userlist object
+     */
+    public static function get_userids_from_context(\core_privacy\local\request\userlist $userlist) {
+        // Not required.
+    }
+
     /**
      * Export all user data for this plugin.
      *
@@ -127,21 +139,41 @@ class provider implements metadataprovider, assignfeedback_provider {
      * @param  assign_plugin_request_data $requestdata Data useful for deleting user data.
      */
     public static function delete_feedback_for_grade(assign_plugin_request_data $requestdata) {
+        $requestdata->set_userids([$requestdata->get_user()->id]);
+        $requestdata->populate_submissions_and_grades();
+        self::delete_feedback_for_grades($requestdata);
+    }
+
+
+    /**
+     * Deletes all feedback for the grade ids / userids provided in a context.
+     * assign_plugin_request_data contains:
+     * - context
+     * - assign object
+     * - grade ids (pluginids)
+     * - user ids
+     * @param  assign_plugin_request_data $deletedata A class that contains the relevant information required for deletion.
+     */
+    public static function delete_feedback_for_grades(assign_plugin_request_data $deletedata) {
         global $DB;
 
-        $assign = $requestdata->get_assign();
+        if (empty($deletedata->get_gradeids())) {
+            return;
+        }
+
+        $assign = $deletedata->get_assign();
         $plugin = $assign->get_plugin_by_type('assignfeedback', 'editpdf');
         $fileareas = $plugin->get_file_areas();
         $fs = get_file_storage();
+        list($sql, $params) = $DB->get_in_or_equal($deletedata->get_gradeids(), SQL_PARAMS_NAMED);
         foreach ($fileareas as $filearea => $notused) {
             // Delete pdf files.
-            $fs->delete_area_files($requestdata->get_context()->id, 'assignfeedback_editpdf',
-                    $filearea, $requestdata->get_pluginobject()->id);
+            $fs->delete_area_files_select($deletedata->get_context()->id, 'assignfeedback_editpdf', $filearea, $sql, $params);
         }
 
         // Remove table entries.
-        $DB->delete_records('assignfeedback_editpdf_annot', ['gradeid' => $requestdata->get_pluginobject()->id]);
-        $DB->delete_records('assignfeedback_editpdf_cmnt', ['gradeid' => $requestdata->get_pluginobject()->id]);
+        $DB->delete_records_select('assignfeedback_editpdf_annot', "gradeid $sql", $params);
+        $DB->delete_records_select('assignfeedback_editpdf_cmnt', "gradeid $sql", $params);
         // Submission records in assignfeedback_editpdf_queue will be cleaned up in a scheduled task
     }
 }
index 2291d6c..af07abe 100644 (file)
@@ -241,4 +241,78 @@ class assignfeedback_editpdf_privacy_testcase extends \mod_assign\tests\mod_assi
         // Check that user 2 data is still there.
         $this->assertFalse($plugin2->is_empty($grade2));
     }
+
+    /**
+     * Test that a grade item is deleted for a user.
+     */
+    public function test_delete_feedback_for_grades() {
+        global $DB;
+
+        $this->resetAfterTest();
+        // Create course, assignment, submission, and then a feedback comment.
+        $course = $this->getDataGenerator()->create_course();
+        // Students.
+        $user1 = $this->getDataGenerator()->create_user();
+        $user2 = $this->getDataGenerator()->create_user();
+        $user3 = $this->getDataGenerator()->create_user();
+        $user4 = $this->getDataGenerator()->create_user();
+        // Teacher.
+        $user5 = $this->getDataGenerator()->create_user();
+        $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user4->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user5->id, $course->id, 'editingteacher');
+        $assign1 = $this->create_instance(['course' => $course,
+                'assignsubmission_file_enabled' => 1,
+                'assignsubmission_file_maxfiles' => 1,
+                'assignfeedback_editpdf_enabled' => 1,
+                'assignsubmission_file_maxsizebytes' => 1000000]);
+
+        $assign2 = $this->create_instance(['course' => $course,
+                'assignsubmission_file_enabled' => 1,
+                'assignsubmission_file_maxfiles' => 1,
+                'assignfeedback_editpdf_enabled' => 1,
+                'assignsubmission_file_maxsizebytes' => 1000000]);
+
+        $context = $assign1->get_context();
+
+        list($plugin1, $grade1, $storedfile1) = $this->create_feedback($assign1, $user1, $user5);
+        list($plugin2, $grade2, $storedfile2) = $this->create_feedback($assign1, $user2, $user5);
+        list($plugin3, $grade3, $storedfile3) = $this->create_feedback($assign1, $user3, $user5);
+        list($plugin4, $grade4, $storedfile4) = $this->create_feedback($assign2, $user3, $user5);
+        list($plugin5, $grade5, $storedfile5) = $this->create_feedback($assign2, $user4, $user5);
+
+        // Check that we have data.
+        $this->assertFalse($plugin1->is_empty($grade1));
+        $this->assertFalse($plugin2->is_empty($grade2));
+        $this->assertFalse($plugin3->is_empty($grade3));
+        $this->assertFalse($plugin4->is_empty($grade4));
+        $this->assertFalse($plugin5->is_empty($grade5));
+
+        // Check that there are also files generated.
+        $files = $DB->get_records('files', ['component' => 'assignfeedback_editpdf', 'filearea' => 'download']);
+        $this->assertCount(10, $files);
+
+        $deletedata = new assign_plugin_request_data($context, $assign1);
+        $deletedata->set_userids([$user1->id, $user3->id]);
+        $deletedata->populate_submissions_and_grades();
+        \assignfeedback_editpdf\privacy\provider::delete_feedback_for_grades($deletedata);
+
+        // Check that we now have no data for user 1.
+        $this->assertTrue($plugin1->is_empty($grade1));
+        // Check that user 2 data is still there.
+        $this->assertFalse($plugin2->is_empty($grade2));
+        // User 3 in assignment 1 should be gone.
+        $this->assertTrue($plugin3->is_empty($grade3));
+        // User 3 in assignment 2 should still be here.
+        $this->assertFalse($plugin4->is_empty($grade4));
+        // User 4 in assignment 2 should also still be here.
+        $this->assertFalse($plugin5->is_empty($grade5));
+
+        // Check the files as well.
+        $files = $DB->get_records('files', ['component' => 'assignfeedback_editpdf', 'filearea' => 'download']);
+        // We should now only have six records here.
+        $this->assertCount(6, $files);
+    }
 }
index f2f609f..839e957 100644 (file)
@@ -29,9 +29,7 @@ defined('MOODLE_INTERNAL') || die();
 require_once($CFG->dirroot . '/mod/assign/locallib.php');
 
 use \core_privacy\local\metadata\collection;
-use \core_privacy\local\metadata\provider as metadataprovider;
-use core_privacy\local\request\contextlist;
-use \mod_assign\privacy\assignfeedback_provider;
+use \core_privacy\local\request\contextlist;
 use \mod_assign\privacy\assign_plugin_request_data;
 use mod_assign\privacy\useridlist;
 
@@ -42,7 +40,10 @@ use mod_assign\privacy\useridlist;
  * @copyright  2018 Adrian Greeve <adrian@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class provider implements metadataprovider, assignfeedback_provider {
+class provider implements
+        \core_privacy\local\metadata\provider,
+        \mod_assign\privacy\assignfeedback_provider,
+        \mod_assign\privacy\assignfeedback_user_provider {
 
     /**
      * Return meta data about this plugin.
@@ -75,6 +76,16 @@ class provider implements metadataprovider, assignfeedback_provider {
         // Not required.
     }
 
+    /**
+     * If you have tables that contain userids and you can generate entries in your tables without creating an
+     * entry in the assign_grades table then please fill in this method.
+     *
+     * @param  \core_privacy\local\request\userlist $userlist The userlist object
+     */
+    public static function get_userids_from_context(\core_privacy\local\request\userlist $userlist) {
+        // Not required.
+    }
+
     /**
      * Export all user data for this plugin.
      *
@@ -121,20 +132,40 @@ class provider implements metadataprovider, assignfeedback_provider {
      * @param  assign_plugin_request_data $requestdata Data useful for deleting user data.
      */
     public static function delete_feedback_for_grade(assign_plugin_request_data $requestdata) {
+        $requestdata->set_userids([$requestdata->get_user()->id]);
+        $requestdata->populate_submissions_and_grades();
+        self::delete_feedback_for_grades($requestdata);
+    }
+
+
+    /**
+     * Deletes all feedback for the grade ids / userids provided in a context.
+     * assign_plugin_request_data contains:
+     * - context
+     * - assign object
+     * - grade ids (pluginids)
+     * - user ids
+     * @param  assign_plugin_request_data $deletedata A class that contains the relevant information required for deletion.
+     */
+    public static function delete_feedback_for_grades(assign_plugin_request_data $deletedata) {
         global $DB;
 
-        $assign = $requestdata->get_assign();
+        if (empty($deletedata->get_gradeids())) {
+            return;
+        }
+
+        $assign = $deletedata->get_assign();
         $plugin = $assign->get_plugin_by_type('assignfeedback', 'file');
         $fileareas = $plugin->get_file_areas();
         $fs = get_file_storage();
+        list($sql, $params) = $DB->get_in_or_equal($deletedata->get_gradeids(), SQL_PARAMS_NAMED);
+        $params['assignment'] = $deletedata->get_assignid();
         foreach ($fileareas as $filearea => $notused) {
             // Delete feedback files.
-            $fs->delete_area_files($requestdata->get_context()->id, 'assignfeedback_file', $filearea,
-                    $requestdata->get_pluginobject()->id);
+            $fs->delete_area_files_select($deletedata->get_context()->id, 'assignfeedback_file', $filearea, $sql, $params);
         }
 
         // Delete table entries.
-        $DB->delete_records('assignfeedback_file', ['assignment' => $requestdata->get_assign()->get_instance()->id,
-                'grade' => $requestdata->get_pluginobject()->id]);
+        $DB->delete_records_select('assignfeedback_file', "assignment = :assignment AND grade $sql", $params);
     }
 }
index 5537755..38bd49b 100644 (file)
@@ -206,4 +206,63 @@ class assignfeedback_file_privacy_testcase extends \mod_assign\tests\mod_assign_
         // User 2's data should still be intact.
         $this->assertFalse($plugin2->is_empty($grade2));
     }
+
+    /**
+     * Test that a grade item is deleted for a user.
+     */
+    public function test_delete_feedback_for_grades() {
+        $this->resetAfterTest();
+        // Create course, assignment, submission, and then a feedback comment.
+        $course = $this->getDataGenerator()->create_course();
+        // Students.
+        $user1 = $this->getDataGenerator()->create_user();
+        $user2 = $this->getDataGenerator()->create_user();
+        $user3 = $this->getDataGenerator()->create_user();
+        $user4 = $this->getDataGenerator()->create_user();
+        // Teacher.
+        $user5 = $this->getDataGenerator()->create_user();
+        $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user4->id, $course->id, 'student');
+        $this->getDataGenerator()->enrol_user($user5->id, $course->id, 'editingteacher');
+        $assign1 = $this->create_instance(['course' => $course]);
+        $assign2 = $this->create_instance(['course' => $course]);
+
+        $context = $assign1->get_context();
+
+        $feedbacktext = '<p>first comment for this test</p>';
+        list($plugin1, $grade1) = $this->create_feedback($assign1, $user1, $user5, 'Submission text', $feedbacktext);
+        $feedbacktext = '<p>Comment for second submission.</p>';
+        list($plugin2, $grade2) = $this->create_feedback($assign1, $user2, $user5, 'Submission text', $feedbacktext);
+        $feedbacktext = '<p>Comment for second submission.</p>';
+        list($plugin3, $grade3) = $this->create_feedback($assign1, $user3, $user5, 'Submission text', $feedbacktext);
+        $feedbacktext = '<p>Comment for second submission.</p>';
+        list($plugin4, $grade4) = $this->create_feedback($assign2, $user3, $user5, 'Submission text', $feedbacktext);
+        $feedbacktext = '<p>Comment for second submission.</p>';
+        list($plugin5, $grade5) = $this->create_feedback($assign2, $user4, $user5, 'Submission text', $feedbacktext);
+
+        // Check that we have data.
+        $this->assertFalse($plugin1->is_empty($grade1));
+        $this->assertFalse($plugin2->is_empty($grade2));
+        $this->assertFalse($plugin3->is_empty($grade3));
+        $this->assertFalse($plugin4->is_empty($grade4));
+        $this->assertFalse($plugin5->is_empty($grade5));
+
+        $deletedata = new assign_plugin_request_data($context, $assign1);
+        $deletedata->set_userids([$user1->id, $user3->id]);
+        $deletedata->populate_submissions_and_grades();
+        \assignfeedback_file\privacy\provider::delete_feedback_for_grades($deletedata);
+
+        // Check that we now have no data.
+        $this->assertTrue($plugin1->is_empty($grade1));
+        // User 2's data should still be intact.
+        $this->assertFalse($plugin2->is_empty($grade2));
+        // User 3's data in assignment 1 should be gone.
+        $this->assertTrue($plugin3->is_empty($grade3));
+        // User 3's data in assignment 2 should still be intact.
+        $this->assertFalse($plugin4->is_empty($grade4));
+        // User 4's data in assignment 2 should still be intact.
+        $this->assertFalse($plugin5->is_empty($grade5));
+    }
 }