MDL-61951 grading: Implement privacy API
[moodle.git] / grade / grading / tests / privacy_test.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Privacy tests for core_grading.
19  *
20  * @package    core_grading
21  * @category   test
22  * @copyright  2018 Sara Arjona <sara@moodle.com>
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 use \core_privacy\tests\provider_testcase;
29 use \core_privacy\local\request\approved_contextlist;
30 use \core_privacy\local\request\transform;
31 use \core_privacy\local\request\writer;
32 use \core_grading\privacy\provider;
34 /**
35  * Privacy tests for core_grading.
36  *
37  * @copyright  2018 Sara Arjona <sara@moodle.com>
38  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39  */
40 class core_grading_privacy_testcase extends provider_testcase {
42     /** @var stdClass User without data. */
43     protected $user0;
45     /** @var stdClass User with data. */
46     protected $user1;
48     /** @var stdClass User with data. */
49     protected $user2;
51     /** @var context context_module of an activity without grading definitions. */
52     protected $instancecontext0;
54     /** @var context context_module of the activity where the grading definitions are. */
55     protected $instancecontext1;
57     /** @var context context_module of the activity where the grading definitions are. */
58     protected $instancecontext2;
60     /**
61      * Test getting the context for the user ID related to this plugin.
62      */
63     public function test_get_contexts_for_userid() {
64         global $DB;
66         $this->resetAfterTest();
67         $this->grading_setup_test_scenario_data();
68         $this->assertCount(2, $DB->get_records('grading_definitions'));
70         // User1 has created grading definitions for instance1 and instance2.
71         $contextlist = provider::get_contexts_for_userid($this->user1->id);
72         $this->assertCount(2, $contextlist);
73         $this->assertContains($this->instancecontext1->id, $contextlist->get_contextids());
74         $this->assertContains($this->instancecontext2->id, $contextlist->get_contextids());
75         $this->assertNotContains($this->instancecontext0->id, $contextlist->get_contextids());
77         // User2 has only modified grading definitions for instance2.
78         $contextlist = provider::get_contexts_for_userid($this->user2->id);
79         $this->assertCount(1, $contextlist);
80         $this->assertContains($this->instancecontext2->id, $contextlist->get_contextids());
82         // User0 hasn't created or modified any grading definition.
83         $contextlist = provider::get_contexts_for_userid($this->user0->id);
84         $this->assertCount(0, $contextlist);
85     }
87     /**
88      * Export for a user with no grading definitions created or modified will not have any data exported.
89      */
90     public function test_export_user_data_no_content() {
91         $this->resetAfterTest();
93         $user = $this->getDataGenerator()->create_user();
94         $this->setUser($user);
95         $context = \context_system::instance();
97         $writer = writer::with_context($context);
98         $this->assertFalse($writer->has_any_data());
99         $this->export_context_data_for_user($user->id, $context, 'core_grading');
100         $this->assertFalse(writer::with_context($context)->has_any_data());
101     }
103     /**
104      * Test that data is exported correctly for this plugin.
105      */
106     public function test_export_user_data() {
107         global $DB;
109         $this->resetAfterTest();
110         $now = time();
111         $defnameprefix = 'fakename';
112         $this->grading_setup_test_scenario_data($defnameprefix, $now);
113         $this->assertCount(2, $DB->get_records('grading_definitions'));
115         // Validate exported data: instance1 - user0 has NO data.
116         $this->setUser($this->user0);
117         writer::reset();
118         $writer = writer::with_context($this->instancecontext1);
119         $this->assertFalse($writer->has_any_data());
120         $this->export_context_data_for_user($this->user0->id, $this->instancecontext1, 'core_grading');
121         $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
122         $this->assertEmpty($data);
124         // Validate exported data: instance0 - user1 has NO data.
125         $this->setUser($this->user1);
126         writer::reset();
127         $writer = writer::with_context($this->instancecontext0);
128         $this->assertFalse($writer->has_any_data());
129         $this->export_context_data_for_user($this->user1->id, $this->instancecontext0, 'core_grading');
130         $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
131         $this->assertEmpty($data);
133         // Validate exported data: instance1 - user1 has data (user has created and modified it).
134         writer::reset();
135         $writer = writer::with_context($this->instancecontext1);
136         $this->assertFalse($writer->has_any_data());
137         $this->export_context_data_for_user($this->user1->id, $this->instancecontext1, 'core_grading');
138         $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
139         $this->assertCount(1, $data->definitions);
141         $firstkey = reset($data->definitions);
142         $this->assertNotEmpty($firstkey->name);
143         $this->assertEquals('test_method', $firstkey->method);
144         $this->assertEquals(transform::datetime($now), $firstkey->timecreated);
145         $this->assertEquals($this->user1->id, $firstkey->usercreated);
146         $this->assertEquals($defnameprefix.'1', $firstkey->name);
148         // Validate exported data: instance2 - user1 has data (user has created it).
149         writer::reset();
150         $writer = writer::with_context($this->instancecontext2);
151         $this->assertFalse($writer->has_any_data());
152         $this->export_context_data_for_user($this->user1->id, $this->instancecontext2, 'core_grading');
153         $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
154         $this->assertCount(1, $data->definitions);
156         $firstkey = reset($data->definitions);
157         $this->assertNotEmpty($firstkey->name);
158         $this->assertEquals('test_method', $firstkey->method);
159         $this->assertEquals(transform::datetime($now), $firstkey->timecreated);
160         $this->assertEquals($this->user1->id, $firstkey->usercreated);
161         $this->assertEquals($defnameprefix.'2', $firstkey->name);
163         // Validate exported data: instance1 - user2 has NO data.
164         $this->setUser($this->user2);
165         writer::reset();
166         $writer = writer::with_context($this->instancecontext1);
167         $this->assertFalse($writer->has_any_data());
168         $this->export_context_data_for_user($this->user2->id, $this->instancecontext1, 'core_grading');
169         $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
170         $this->assertEmpty($data);
172         // Validate exported data: instance2 - user2 has data (user has modified it).
173         $this->setUser($this->user2);
174         writer::reset();
175         $writer = writer::with_context($this->instancecontext2);
176         $this->assertFalse($writer->has_any_data());
177         $this->export_context_data_for_user($this->user2->id, $this->instancecontext2, 'core_grading');
178         $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
179         $this->assertCount(1, $data->definitions);
180     }
182     /**
183      * Test for provider::delete_data_for_all_users_in_context().
184      */
185     public function test_delete_data_for_all_users_in_context() {
186         global $DB;
188         $this->resetAfterTest();
189         $this->grading_setup_test_scenario_data();
191         // Before deletion, we should have 2 grading_definitions.
192         $this->assertCount(2, $DB->get_records('grading_definitions'));
194         // Delete data.
195         provider::delete_data_for_all_users_in_context($this->instancecontext0);
196         provider::delete_data_for_all_users_in_context($this->instancecontext1);
197         provider::delete_data_for_all_users_in_context($this->instancecontext2);
199         // Before deletion, we should have same grading_definitions (nothing was deleted).
200         $this->assertCount(2, $DB->get_records('grading_definitions'));
201     }
203     /**
204      * Test for provider::delete_data_for_user().
205      */
206     public function test_delete_data_for_user() {
207         global $DB;
209         $this->resetAfterTest();
210         $this->grading_setup_test_scenario_data();
212         // Before deletion, we should have 2 grading_definitions.
213         $this->assertCount(2, $DB->get_records('grading_definitions'));
215         // Delete data for $user0.
216         $contextlist = provider::get_contexts_for_userid($this->user0->id);
217         $approvedcontextlist = new approved_contextlist(
218             $this->user0,
219             'core_grading',
220             $contextlist->get_contextids()
221         );
222         provider::delete_data_for_user($approvedcontextlist);
224         // Delete data for $user1.
225         $contextlist = provider::get_contexts_for_userid($this->user1->id);
226         $approvedcontextlist = new approved_contextlist(
227             $this->user1,
228             'core_grading',
229             $contextlist->get_contextids()
230         );
231         provider::delete_data_for_user($approvedcontextlist);
233         // Delete data for $user2.
234         $contextlist = provider::get_contexts_for_userid($this->user2->id);
235         $approvedcontextlist = new approved_contextlist(
236             $this->user2,
237             'core_grading',
238             $contextlist->get_contextids()
239         );
240         provider::delete_data_for_user($approvedcontextlist);
242         // Before deletion, we should have same grading_definitions (nothing was deleted).
243         $this->assertCount(2, $DB->get_records('grading_definitions'));
244     }
246     /**
247      * Helper function to setup the environment.
248      *
249      * course
250      *  |
251      *  +--instance0 (assignment)
252      *  |   |
253      *  +--instance1 (assignment)
254      *  |   |
255      *  |   +--grading_definition1 (created and modified by user1)
256      *  |   |
257      *  +--instance2 (assignment)
258      *  |   |
259      *  |   +--grading_definition2 (created by user1 and modified by user2)
260      *
261      *
262      * user0 hasn't any data.
263      *
264      * @param string $defnameprefix
265      * @param timestamp $now
266      */
267     protected function grading_setup_test_scenario_data($defnameprefix = null, $now = null) {
268         global $DB;
270         $this->user0 = $this->getDataGenerator()->create_user();
271         $this->user1 = $this->getDataGenerator()->create_user();
272         $this->user2 = $this->getDataGenerator()->create_user();
274         // Create a course.
275         $course = $this->getDataGenerator()->create_course();
276         $coursecontext = context_course::instance($course->id);
278         // Create some assignment instances.
279         $params = (object)array(
280             'course' => $course->id,
281             'name'   => 'Testing instance'
282         );
283         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
284         $instance0 = $generator->create_instance($params);
285         $cm0 = get_coursemodule_from_instance('assign', $instance0->id);
286         $this->instancecontext0 = context_module::instance($cm0->id);
287         $instance1 = $generator->create_instance($params);
288         $cm1 = get_coursemodule_from_instance('assign', $instance1->id);
289         $this->instancecontext1 = context_module::instance($cm1->id);
290         $instance2 = $generator->create_instance($params);
291         $cm2 = get_coursemodule_from_instance('assign', $instance2->id);
292         $this->instancecontext2 = context_module::instance($cm2->id);
294         // Create fake grading areas.
295         $fakearea1 = (object)array(
296             'contextid'    => $this->instancecontext1->id,
297             'component'    => 'mod_assign',
298             'areaname'     => 'submissions',
299             'activemethod' => 'test_method'
300         );
301         $fakeareaid1 = $DB->insert_record('grading_areas', $fakearea1);
302         $fakearea2 = clone($fakearea1);
303         $fakearea2->contextid = $this->instancecontext2->id;
304         $fakeareaid2 = $DB->insert_record('grading_areas', $fakearea2);
306         // Create fake grading definitions.
307         if (empty($now)) {
308             $now = time();
309         }
310         if (empty($defnameprefix)) {
311             $defnameprefix = 'fakename';
312         }
313         $fakedefinition1 = (object)array(
314             'areaid'       => $fakeareaid1,
315             'method'       => 'test_method',
316             'name'         => $defnameprefix.'1',
317             'status'       => 0,
318             'timecreated'  => $now,
319             'usercreated'  => $this->user1->id,
320             'timemodified' => $now + 1,
321             'usermodified' => $this->user1->id,
322         );
323         $fakedefid1 = $DB->insert_record('grading_definitions', $fakedefinition1);
324         $fakedefinition2 = clone($fakedefinition1);
325         $fakedefinition2->areaid = $fakeareaid2;
326         $fakedefinition2->name = $defnameprefix.'2';
327         $fakedefinition2->usermodified = $this->user2->id;
328         $fakedefid2 = $DB->insert_record('grading_definitions', $fakedefinition2);
329     }