first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,70 @@
@mod @mod_assign @assignfeedback @assignfeedback_file @_file_upload
Feature: In an assignment, teacher can submit feedback files during grading
In order to provide a feedback file
As a teacher
I need to submit a feedback file.
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And the following "groups" exist:
| name | course | idnumber |
| G1 | C1 | G1 |
And the following "group members" exist:
| user | group |
| student1 | G1 |
| student2 | G1 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment name |
| assignsubmission_file_enabled | 1 |
| assignsubmission_file_maxfiles | 1 |
| assignsubmission_file_maxsizebytes | 1024 |
| assignfeedback_comments_enabled | 1 |
| assignfeedback_file_enabled | 1 |
| maxfilessubmission | 2 |
| teamsubmission | 1 |
| submissiondrafts | 0 |
And the following "mod_assign > submission" exists:
| assign | Test assignment name |
| user | student1 |
| file | mod/assign/feedback/file/tests/fixtures/submission.txt |
And I am on the "Test assignment name" Activity page logged in as teacher1
And I click on "Grade" "link" in the ".tertiary-navigation" "css_element"
And I upload "mod/assign/feedback/file/tests/fixtures/feedback.txt" file to "Feedback files" filemanager
@javascript
Scenario: A teacher can provide a feedback file when grading an assignment.
Given I set the field "applytoall" to "0"
And I press "Save changes"
And I click on "Course 1" "link" in the "[data-region=assignment-info]" "css_element"
And I log out
And I am on the "Test assignment name" Activity page logged in as student1
And I should see "feedback.txt"
And I log out
And I am on the "Test assignment name" Activity page logged in as student2
Then I should not see "feedback.txt"
@javascript
Scenario: A teacher can provide a feedback file when grading an assignment and all students in the group will receive the file.
Given I press "Save changes"
And I click on "Course 1" "link" in the "[data-region=assignment-info]" "css_element"
And I log out
And I am on the "Test assignment name" Activity page logged in as student1
And I should see "feedback.txt"
And I log out
When I am on the "Test assignment name" Activity page logged in as student2
Then I should see "feedback.txt"
@@ -0,0 +1,176 @@
<?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/>.
namespace assignfeedback_file;
use mod_assign_test_generator;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/mod/assign/tests/generator.php');
/**
* Unit tests for assignfeedback_file
*
* @package assignfeedback_file
* @copyright 2016 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class feedback_test extends \advanced_testcase {
// Use the generator helper.
use mod_assign_test_generator;
/**
* Test the is_feedback_modified() method for the file feedback.
*/
public function test_is_feedback_modified(): void {
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course();
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
$assign = $this->create_instance($course, [
'assignsubmission_onlinetext_enabled' => 1,
'assignfeedback_comments_enabled' => 1,
]);
// Create an online text submission.
$this->add_submission($student, $assign);
$this->setUser($teacher);
$fs = get_file_storage();
$context = \context_user::instance($teacher->id);
$draftitemid = file_get_unused_draft_itemid();
file_prepare_draft_area($draftitemid, $context->id, 'assignfeedback_file', 'feedback_files', 1);
$dummy = array(
'contextid' => $context->id,
'component' => 'user',
'filearea' => 'draft',
'itemid' => $draftitemid,
'filepath' => '/',
'filename' => 'feedback1.txt'
);
$file = $fs->create_file_from_string($dummy, 'This is the first feedback file');
// Create formdata.
$data = new \stdClass();
$data->{'files_' . $student->id . '_filemanager'} = $draftitemid;
$grade = $assign->get_user_grade($student->id, true);
// This is the first time that we are submitting feedback, so it is modified.
$plugin = $assign->get_feedback_plugin_by_type('file');
$this->assertTrue($plugin->is_feedback_modified($grade, $data));
// Save the feedback.
$plugin->save($grade, $data);
// Try again with the same data.
$draftitemid = file_get_unused_draft_itemid();
file_prepare_draft_area($draftitemid, $context->id, 'assignfeedback_file', 'feedback_files', 1);
$dummy['itemid'] = $draftitemid;
$file = $fs->create_file_from_string($dummy, 'This is the first feedback file');
// Create formdata.
$data = new \stdClass();
$data->{'files_' . $student->id . '_filemanager'} = $draftitemid;
$this->assertFalse($plugin->is_feedback_modified($grade, $data));
// Same name for the file but different content.
$draftitemid = file_get_unused_draft_itemid();
file_prepare_draft_area($draftitemid, $context->id, 'assignfeedback_file', 'feedback_files', 1);
$dummy['itemid'] = $draftitemid;
$file = $fs->create_file_from_string($dummy, 'This is different feedback');
// Create formdata.
$data = new \stdClass();
$data->{'files_' . $student->id . '_filemanager'} = $draftitemid;
$this->assertTrue($plugin->is_feedback_modified($grade, $data));
$plugin->save($grade, $data);
// Add another file.
$draftitemid = file_get_unused_draft_itemid();
file_prepare_draft_area($draftitemid, $context->id, 'assignfeedback_file', 'feedback_files', 1);
$dummy['itemid'] = $draftitemid;
$file = $fs->create_file_from_string($dummy, 'This is different feedback');
$dummy['filename'] = 'feedback2.txt';
$file = $fs->create_file_from_string($dummy, 'A second feedback file');
// Create formdata.
$data = new \stdClass();
$data->{'files_' . $student->id . '_filemanager'} = $draftitemid;
$this->assertTrue($plugin->is_feedback_modified($grade, $data));
$plugin->save($grade, $data);
// Deleting a file.
$draftitemid = file_get_unused_draft_itemid();
file_prepare_draft_area($draftitemid, $context->id, 'assignfeedback_file', 'feedback_files', 1);
$dummy['itemid'] = $draftitemid;
$file = $fs->create_file_from_string($dummy, 'This is different feedback');
// Create formdata.
$data = new \stdClass();
$data->{'files_' . $student->id . '_filemanager'} = $draftitemid;
$this->assertTrue($plugin->is_feedback_modified($grade, $data));
$plugin->save($grade, $data);
// The file was moved to a folder.
$draftitemid = file_get_unused_draft_itemid();
file_prepare_draft_area($draftitemid, $context->id, 'assignfeedback_file', 'feedback_files', 1);
$dummy['itemid'] = $draftitemid;
$dummy['filepath'] = '/testdir/';
$file = $fs->create_file_from_string($dummy, 'This is different feedback');
// Create formdata.
$data = new \stdClass();
$data->{'files_' . $student->id . '_filemanager'} = $draftitemid;
$this->assertTrue($plugin->is_feedback_modified($grade, $data));
$plugin->save($grade, $data);
// No modification to the file in the folder.
$draftitemid = file_get_unused_draft_itemid();
file_prepare_draft_area($draftitemid, $context->id, 'assignfeedback_file', 'feedback_files', 1);
$dummy['itemid'] = $draftitemid;
$dummy['filepath'] = '/testdir/';
$file = $fs->create_file_from_string($dummy, 'This is different feedback');
// Create formdata.
$data = new \stdClass();
$data->{'files_' . $student->id . '_filemanager'} = $draftitemid;
$this->assertFalse($plugin->is_feedback_modified($grade, $data));
}
}
+1
View File
@@ -0,0 +1 @@
feedback.txt
@@ -0,0 +1 @@
submission.txt
@@ -0,0 +1,153 @@
<?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/>.
/**
* Unit tests for importziplib.
*
* @package assignfeedback_file
* @copyright 2020 Eric Merrill <merrill@oakland.edu>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignfeedback_file;
use mod_assign_test_generator;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/mod/assign/tests/generator.php');
require_once($CFG->dirroot . '/mod/assign/feedback/file/importziplib.php');
/**
* Unit tests for importziplib.
*
* @package assignfeedback_file
* @copyright 2020 Eric Merrill <merrill@oakland.edu>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class importziplib_test extends \advanced_testcase {
// Use the generator helper.
use mod_assign_test_generator;
/**
* Test the assignfeedback_file_zip_importer->is_valid_filename_for_import() method.
*/
public function test_is_valid_filename_for_import(): void {
// Do the initial assign setup.
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course();
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
$assign = $this->create_instance($course, [
'assignsubmission_onlinetext_enabled' => 1,
'assignfeedback_file_enabled' => 1,
]);
// Create an online text submission.
$this->add_submission($student, $assign);
// Now onto the file work.
$fs = get_file_storage();
// Setup a basic file we will work with. We will keep renaming and repathing it.
$record = new \stdClass;
$record->contextid = $assign->get_context()->id;
$record->component = 'assignfeedback_file';
$record->filearea = ASSIGNFEEDBACK_FILE_FILEAREA;
$record->itemid = $assign->get_user_grade($student->id, true)->id;
$record->filepath = '/';
$record->filename = '1.txt';
$record->source = 'test';
$file = $fs->create_file_from_string($record, 'file content');
// The importer we will use.
$importer = new \assignfeedback_file_zip_importer();
// Setup some variable we use.
$user = null;
$plugin = null;
$filename = '';
$allusers = $assign->list_participants(0, false);
$participants = array();
foreach ($allusers as $user) {
$participants[$assign->get_uniqueid_for_user($user->id)] = $user;
}
$file->rename('/import/', '.hiddenfile');
$result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
$this->assertFalse($result);
$file->rename('/import/', '~hiddenfile');
$result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
$this->assertFalse($result);
$file->rename('/import/some_path_here/', 'RandomFile.txt');
$result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
$this->assertFalse($result);
$file->rename('/import/', '~hiddenfile');
$result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
$this->assertFalse($result);
// Get the students assign id.
$studentid = $assign->get_uniqueid_for_user($student->id);
// Submissions are identified with the format:
// StudentName_StudentID_PluginType_Plugin_FilePathAndName.
// Test a string student id.
$badname = 'Student Name_StringID_assignsubmission_file_My_cool_filename.txt';
$file->rename('/import/', $badname);
$result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
$this->assertFalse($result);
// Test an invalid student id.
$badname = 'Student Name_' . ($studentid + 100) . '_assignsubmission_file_My_cool_filename.txt';
$file->rename('/import/', $badname);
$result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
$this->assertFalse($result);
// Test an invalid submission plugin.
$badname = 'Student Name_' . $studentid . '_assignsubmission_noplugin_My_cool_filename.txt';
$file->rename('/import/', $badname);
$result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
$this->assertFalse($result);
// Test a basic, good file.
$goodbase = 'Student Name_' . $studentid . '_assignsubmission_file_';
$file->rename('/import/', $goodbase . "My_cool_filename.txt");
$result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
$this->assertTrue($result);
$this->assertEquals($participants[$studentid], $user);
$this->assertEquals('My_cool_filename.txt', $filename);
$this->assertInstanceOf(\assign_submission_file::class, $plugin);
// Test another good file, with some additional path and underscores.
$user = null;
$plugin = null;
$filename = '';
$file->rename('/import/some_path_here/' . $goodbase . '/some_path/', 'My File.txt');
$result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
$this->assertTrue($result);
$this->assertEquals($participants[$studentid], $user);
$this->assertEquals('/some_path/My File.txt', $filename);
$this->assertInstanceOf(\assign_submission_file::class, $plugin);
}
}
@@ -0,0 +1,269 @@
<?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/>.
/**
* Unit tests for assignfeedback_file.
*
* @package assignfeedback_file
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignfeedback_file\privacy;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/mod/assign/locallib.php');
require_once($CFG->dirroot . '/mod/assign/tests/privacy/provider_test.php');
use mod_assign\privacy\assign_plugin_request_data;
/**
* Unit tests for mod/assign/feedback/file/classes/privacy/
*
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider_test extends \mod_assign\privacy\provider_test {
/**
* Convenience function for creating feedback data.
*
* @param object $assign assign object
* @param \stdClass $student user object
* @param \stdClass $teacher user object
* @param string $submissiontext Submission text
* @param string $feedbacktext Feedback text
* @return array Feedback plugin object and the grade object.
*/
protected function create_feedback($assign, $student, $teacher, $submissiontext, $feedbacktext) {
$submission = new \stdClass();
$submission->assignment = $assign->get_instance()->id;
$submission->userid = $student->id;
$submission->timecreated = time();
$submission->onlinetext_editor = ['text' => $submissiontext,
'format' => FORMAT_MOODLE];
$this->setUser($student);
$notices = [];
$assign->save_submission($submission, $notices);
$grade = $assign->get_user_grade($student->id, true);
$this->setUser($teacher);
$context = \context_user::instance($teacher->id);
$draftitemid = file_get_unused_draft_itemid();
file_prepare_draft_area($draftitemid, $context->id, 'assignfeedback_file', 'feedback_files', 1);
$dummy = array(
'contextid' => $context->id,
'component' => 'user',
'filearea' => 'draft',
'itemid' => $draftitemid,
'filepath' => '/',
'filename' => 'feedback1.txt'
);
$fs = get_file_storage();
$file = $fs->create_file_from_string($dummy, $feedbacktext);
// Create formdata.
$data = new \stdClass();
$data->{'files_' . $teacher->id . '_filemanager'} = $draftitemid;
$plugin = $assign->get_feedback_plugin_by_type('file');
// Save the feedback.
$plugin->save($grade, $data);
return [$plugin, $grade];
}
/**
* Quick test to make sure that get_metadata returns something.
*/
public function test_get_metadata(): void {
$collection = new \core_privacy\local\metadata\collection('assignfeedback_file');
$collection = \assignfeedback_file\privacy\provider::get_metadata($collection);
$this->assertNotEmpty($collection);
}
/**
* Test that feedback comments are exported for a user.
*/
public function test_export_feedback_user_data(): void {
$this->resetAfterTest();
// Create course, assignment, submission, and then a feedback comment.
$course = $this->getDataGenerator()->create_course();
// Student.
$user1 = $this->getDataGenerator()->create_user();
// Teacher.
$user2 = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'editingteacher');
$assign = $this->create_instance(['course' => $course]);
$context = $assign->get_context();
$feedbacktext = '<p>first comment for this test</p>';
list($plugin, $grade) = $this->create_feedback($assign, $user1, $user2, 'Submission text', $feedbacktext);
$writer = \core_privacy\local\request\writer::with_context($context);
$this->assertFalse($writer->has_any_data());
// The student should be able to see the teachers feedback.
$exportdata = new \mod_assign\privacy\assign_plugin_request_data($context, $assign, $grade, [], $user1);
\assignfeedback_file\privacy\provider::export_feedback_user_data($exportdata);
$feedbackfile = $writer->get_files([get_string('privacy:path', 'assignfeedback_file')])['feedback1.txt'];
// Check that we got a stored file.
$this->assertInstanceOf('stored_file', $feedbackfile);
$this->assertEquals('feedback1.txt', $feedbackfile->get_filename());
}
/**
* Test that all feedback is deleted for a context.
*/
public function test_delete_feedback_for_context(): void {
$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();
// Teacher.
$user3 = $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, 'editingteacher');
$assign = $this->create_instance(['course' => $course]);
$context = $assign->get_context();
$feedbacktext = '<p>first comment for this test</p>';
list($plugin1, $grade1) = $this->create_feedback($assign, $user1, $user3, 'Submission text', $feedbacktext);
$feedbacktext = '<p>Comment for second submission.</p>';
list($plugin2, $grade2) = $this->create_feedback($assign, $user2, $user3, 'Submission text', $feedbacktext);
// Check that we have data.
$this->assertFalse($plugin1->is_empty($grade1));
$this->assertFalse($plugin2->is_empty($grade2));
$requestdata = new assign_plugin_request_data($context, $assign);
\assignfeedback_file\privacy\provider::delete_feedback_for_context($requestdata);
// Check that we now have no data.
$this->assertTrue($plugin1->is_empty($grade1));
$this->assertTrue($plugin2->is_empty($grade2));
}
/**
* Test that a grade item is deleted for a user.
*/
public function test_delete_feedback_for_grade(): void {
$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();
// Teacher.
$user3 = $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, 'editingteacher');
$assign = $this->create_instance(['course' => $course]);
$context = $assign->get_context();
$feedbacktext = '<p>first comment for this test</p>';
list($plugin1, $grade1) = $this->create_feedback($assign, $user1, $user3, 'Submission text', $feedbacktext);
$feedbacktext = '<p>Comment for second submission.</p>';
list($plugin2, $grade2) = $this->create_feedback($assign, $user2, $user3, 'Submission text', $feedbacktext);
// Check that we have data.
$this->assertFalse($plugin1->is_empty($grade1));
$this->assertFalse($plugin2->is_empty($grade2));
$requestdata = new assign_plugin_request_data($context, $assign, $grade1, [], $user1);
\assignfeedback_file\privacy\provider::delete_feedback_for_grade($requestdata);
// 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));
}
/**
* Test that a grade item is deleted for a user.
*/
public function test_delete_feedback_for_grades(): void {
$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));
}
}