Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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/>.
16
 
17
/**
18
 * Data provider tests.
19
 *
20
 * @package    core_grades
21
 * @category   test
22
 * @copyright  2018 Frédéric Massart
23
 * @author     Frédéric Massart <fred@branchup.tech>
24
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25
 */
26
namespace core_grades\privacy;
27
 
28
defined('MOODLE_INTERNAL') || die();
29
global $CFG;
30
 
31
use core_privacy\tests\provider_testcase;
32
use core_privacy\local\request\approved_contextlist;
33
use core_privacy\local\request\transform;
34
use core_privacy\local\request\writer;
35
use core_grades\privacy\provider;
36
 
37
require_once($CFG->libdir . '/gradelib.php');
38
 
39
/**
40
 * Data provider testcase class.
41
 *
42
 * @package    core_grades
43
 * @category   test
44
 * @copyright  2018 Frédéric Massart
45
 * @author     Frédéric Massart <fred@branchup.tech>
46
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
47
 * @covers \core_grades\privacy\provider
48
 */
49
class provider_test extends provider_testcase {
50
 
51
    public function setUp(): void {
52
        global $PAGE;
53
        $this->resetAfterTest();
54
        $PAGE->get_renderer('core');
55
    }
56
 
11 efrain 57
    public function test_get_contexts_for_userid_gradebook_edits(): void {
1 efrain 58
        $dg = $this->getDataGenerator();
59
 
60
        $c1 = $dg->create_course();
61
        $c2 = $dg->create_course();
62
 
63
        $u1 = $dg->create_user();
64
        $u2 = $dg->create_user();
65
        $u3 = $dg->create_user();
66
        $u4 = $dg->create_user();
67
        $u5 = $dg->create_user();
68
        $u6 = $dg->create_user();
69
        $u7 = $dg->create_user();
70
        $u8 = $dg->create_user();
71
        $u9 = $dg->create_user();
72
        $u10 = $dg->create_user();
73
        $u11 = $dg->create_user();
74
 
75
        $sysctx = \context_system::instance();
76
        $c1ctx = \context_course::instance($c1->id);
77
        $c2ctx = \context_course::instance($c2->id);
78
 
79
        // Create some stuff.
80
        $gi1a = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
81
        $gi1b = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
82
        $gi2a = new \grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
83
        $gc1a = new \grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
84
        $gc1b = new \grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
85
        $gc2a = new \grade_category($dg->create_grade_category(['courseid' => $c2->id]), false);
86
        $go2 = new \grade_outcome($dg->create_grade_outcome(['courseid' => $c2->id, 'shortname' => 'go2',
87
            'fullname' => 'go2']), false);
88
 
89
        // Nothing as of now.
90
        foreach ([$u1, $u2, $u3, $u4, $u5, $u6, $u7, $u8, $u9, $u10, $u11] as $u) {
91
            $contexts = array_flip(provider::get_contexts_for_userid($u->id)->get_contextids());
92
            $this->assertEmpty($contexts);
93
        }
94
 
95
        $go0 = new \grade_outcome(['shortname' => 'go0', 'fullname' => 'go0', 'usermodified' => $u1->id]);
96
        $go0->insert();
97
        $go1 = new \grade_outcome(['shortname' => 'go1', 'fullname' => 'go1', 'courseid' => $c1->id, 'usermodified' => $u11->id]);
98
        $go1->insert();
99
 
100
        // Create scales.
101
        $s1 = new \grade_scale(['name' => 's1', 'scale' => 'a,b', 'userid' => $u7->id, 'courseid' => 0, 'description' => '']);
102
        $s1->insert();
103
        $s2 = new \grade_scale(['name' => 's2', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c1->id, 'description' => '']);
104
        $s2->insert();
105
 
106
        // User 2 creates history.
107
        $this->setUser($u2);
108
        $go0->shortname .= ' edited';
109
        $go0->update();
110
        $gc1a->fullname .= ' edited';
111
        $gc1a->update();
112
 
113
        // User 3 creates history.
114
        $this->setUser($u3);
115
        $go1->shortname .= ' edited';
116
        $go1->update();
117
        $gc2a->fullname .= ' a';
118
        $gc2a->update();
119
 
120
        // User 4 updates an outcome in course (creates history).
121
        $this->setUser($u4);
122
        $go2->shortname .= ' edited';
123
        $go2->update();
124
 
125
        // User 5 updates an item.
126
        $this->setUser($u5);
127
        $gi1a->itemname .= ' edited';
128
        $gi1a->update();
129
 
130
        // User 6 creates history.
131
        $this->setUser($u6);
132
        $gi2a->delete();
133
 
134
        // User 9 creates history.
135
        $this->setUser($u9);
136
        $s1->name .= ' edited';
137
        $s1->update();
138
 
139
        // Assert contexts.
140
        $contexts = array_flip(provider::get_contexts_for_userid($u1->id)->get_contextids());
141
        $this->assertCount(1, $contexts);
142
        $this->assertArrayHasKey($sysctx->id, $contexts);
143
        $contexts = array_flip(provider::get_contexts_for_userid($u11->id)->get_contextids());
144
        $this->assertCount(1, $contexts);
145
        $this->assertArrayHasKey($c1ctx->id, $contexts);
146
        $contexts = array_flip(provider::get_contexts_for_userid($u2->id)->get_contextids());
147
        $this->assertCount(2, $contexts);
148
        $this->assertArrayHasKey($sysctx->id, $contexts);
149
        $this->assertArrayHasKey($c1ctx->id, $contexts);
150
        $contexts = array_flip(provider::get_contexts_for_userid($u3->id)->get_contextids());
151
        $this->assertCount(2, $contexts);
152
        $this->assertArrayHasKey($c1ctx->id, $contexts);
153
        $this->assertArrayHasKey($c2ctx->id, $contexts);
154
        $contexts = array_flip(provider::get_contexts_for_userid($u4->id)->get_contextids());
155
        $this->assertCount(1, $contexts);
156
        $this->assertArrayHasKey($c2ctx->id, $contexts);
157
        $contexts = array_flip(provider::get_contexts_for_userid($u5->id)->get_contextids());
158
        $this->assertCount(1, $contexts);
159
        $this->assertArrayHasKey($c1ctx->id, $contexts);
160
        $contexts = array_flip(provider::get_contexts_for_userid($u6->id)->get_contextids());
161
        $this->assertCount(1, $contexts);
162
        $this->assertArrayHasKey($c2ctx->id, $contexts);
163
        $contexts = array_flip(provider::get_contexts_for_userid($u7->id)->get_contextids());
164
        $this->assertCount(1, $contexts);
165
        $this->assertArrayHasKey($sysctx->id, $contexts);
166
        $contexts = array_flip(provider::get_contexts_for_userid($u8->id)->get_contextids());
167
        $this->assertCount(1, $contexts);
168
        $this->assertArrayHasKey($c1ctx->id, $contexts);
169
        $contexts = array_flip(provider::get_contexts_for_userid($u9->id)->get_contextids());
170
        $this->assertCount(1, $contexts);
171
        $this->assertArrayHasKey($sysctx->id, $contexts);
172
 
173
        // User 10 creates history.
174
        $this->setUser($u10);
175
        $s2->delete();
176
 
177
        $contexts = array_flip(provider::get_contexts_for_userid($u10->id)->get_contextids());
178
        $this->assertCount(1, $contexts);
179
        $this->assertArrayHasKey($c1ctx->id, $contexts);
180
    }
181
 
11 efrain 182
    public function test_get_contexts_for_userid_grades_and_history(): void {
1 efrain 183
        $dg = $this->getDataGenerator();
184
 
185
        $c1 = $dg->create_course();
186
        $c2 = $dg->create_course();
187
 
188
        $u1 = $dg->create_user();
189
        $u2 = $dg->create_user();
190
        $u3 = $dg->create_user();
191
        $u4 = $dg->create_user();
192
        $u5 = $dg->create_user();
193
        $u6 = $dg->create_user();
194
 
195
        $sysctx = \context_system::instance();
196
        $c1ctx = \context_course::instance($c1->id);
197
        $c2ctx = \context_course::instance($c2->id);
198
 
199
        // Create some stuff.
200
        $gi1a = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
201
        $gi1b = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
202
        $gi2a = new \grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
203
        $gi2b = new \grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
204
 
205
        // Nothing as of now.
206
        foreach ([$u1, $u2, $u3, $u4, $u5, $u6] as $u) {
207
            $contexts = array_flip(provider::get_contexts_for_userid($u->id)->get_contextids());
208
            $this->assertEmpty($contexts);
209
        }
210
 
211
        // User 1 is graded in course 1.
212
        $gi1a->update_final_grade($u1->id, 1, 'test');
213
 
214
        // User 2 is graded in course 2.
215
        $gi2a->update_final_grade($u2->id, 10, 'test');
216
 
217
        // User 3 is set as modifier.
218
        $gi1a->update_final_grade($u1->id, 1, 'test', '', FORMAT_MOODLE, $u3->id);
219
 
220
        // User 4 is set as modifier, and creates history..
221
        $this->setUser($u4);
222
        $gi1a->update_final_grade($u2->id, 1, 'test');
223
 
224
        // User 5 creates history, user 6 is the known modifier, and we delete the item.
225
        $this->setUser($u5);
226
        $gi2b->update_final_grade($u2->id, 1, 'test', '', FORMAT_PLAIN, $u6->id);
227
        $gi2b->delete();
228
 
229
        // Assert contexts.
230
        $contexts = array_flip(provider::get_contexts_for_userid($u1->id)->get_contextids());
231
        $this->assertCount(1, $contexts);
232
        $this->assertArrayHasKey($c1ctx->id, $contexts);
233
        $contexts = array_flip(provider::get_contexts_for_userid($u2->id)->get_contextids());
234
        $this->assertCount(3, $contexts);
235
        $this->assertArrayHasKey($c1ctx->id, $contexts);
236
        $this->assertArrayHasKey($c2ctx->id, $contexts);
237
        $this->assertArrayHasKey(\context_user::instance($u2->id)->id, $contexts);
238
        $contexts = array_flip(provider::get_contexts_for_userid($u3->id)->get_contextids());
239
        $this->assertCount(1, $contexts);
240
        $this->assertArrayHasKey($c1ctx->id, $contexts);
241
        $contexts = array_flip(provider::get_contexts_for_userid($u4->id)->get_contextids());
242
        $this->assertCount(1, $contexts);
243
        $this->assertArrayHasKey($c1ctx->id, $contexts);
244
        $contexts = array_flip(provider::get_contexts_for_userid($u5->id)->get_contextids());
245
        $this->assertCount(2, $contexts);
246
        $this->assertArrayHasKey($c2ctx->id, $contexts);
247
        $this->assertArrayHasKey(\context_user::instance($u2->id)->id, $contexts);
248
        $contexts = array_flip(provider::get_contexts_for_userid($u6->id)->get_contextids());
249
        $this->assertCount(1, $contexts);
250
        $this->assertArrayHasKey(\context_user::instance($u2->id)->id, $contexts);
251
    }
252
 
253
    /**
254
     * Test that the appropriate user IDs are returned for a given context.
255
     */
11 efrain 256
    public function test_get_users_in_context_gradebook_edits(): void {
1 efrain 257
        $dg = $this->getDataGenerator();
258
 
259
        $c1 = $dg->create_course();
260
        $c2 = $dg->create_course();
261
 
262
        $u1 = $dg->create_user();
263
        $u2 = $dg->create_user();
264
        $u3 = $dg->create_user();
265
        $u4 = $dg->create_user();
266
        $u5 = $dg->create_user();
267
        $u6 = $dg->create_user();
268
        $u7 = $dg->create_user();
269
        $u8 = $dg->create_user();
270
        $u9 = $dg->create_user();
271
        $u10 = $dg->create_user();
272
        $u11 = $dg->create_user();
273
 
274
        $sysctx = \context_system::instance();
275
        $c1ctx = \context_course::instance($c1->id);
276
        $c2ctx = \context_course::instance($c2->id);
277
 
278
        // Create some stuff.
279
        $gi1a = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
280
        $gi1b = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
281
        $gi2a = new \grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
282
        $gc1a = new \grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
283
        $gc1b = new \grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
284
        $gc2a = new \grade_category($dg->create_grade_category(['courseid' => $c2->id]), false);
285
        $go2 = new \grade_outcome($dg->create_grade_outcome(['courseid' => $c2->id, 'shortname' => 'go2',
286
            'fullname' => 'go2']), false);
287
 
288
        $go0 = new \grade_outcome(['shortname' => 'go0', 'fullname' => 'go0', 'usermodified' => $u1->id]);
289
        $go0->insert();
290
        $go1 = new \grade_outcome(['shortname' => 'go1', 'fullname' => 'go1', 'courseid' => $c1->id, 'usermodified' => $u11->id]);
291
        $go1->insert();
292
 
293
        // Create scales.
294
        $s1 = new \grade_scale(['name' => 's1', 'scale' => 'a,b', 'userid' => $u7->id, 'courseid' => 0, 'description' => '']);
295
        $s1->insert();
296
        $s2 = new \grade_scale(['name' => 's2', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c1->id, 'description' => '']);
297
        $s2->insert();
298
 
299
        // User 2 creates history.
300
        $this->setUser($u2);
301
        $go0->shortname .= ' edited';
302
        $go0->update();
303
        $gc1a->fullname .= ' edited';
304
        $gc1a->update();
305
 
306
        // User 3 creates history.
307
        $this->setUser($u3);
308
        $go1->shortname .= ' edited';
309
        $go1->update();
310
        $gc2a->fullname .= ' a';
311
        $gc2a->update();
312
 
313
        // User 4 updates an outcome in course (creates history).
314
        $this->setUser($u4);
315
        $go2->shortname .= ' edited';
316
        $go2->update();
317
 
318
        // User 5 updates an item.
319
        $this->setUser($u5);
320
        $gi1a->itemname .= ' edited';
321
        $gi1a->update();
322
 
323
        // User 6 creates history.
324
        $this->setUser($u6);
325
        $gi2a->delete();
326
 
327
        // User 9 creates history.
328
        $this->setUser($u9);
329
        $s1->name .= ' edited';
330
        $s1->update();
331
 
332
        $userlist = new \core_privacy\local\request\userlist($sysctx, 'core_grades');
333
        provider::get_users_in_context($userlist);
334
        $systemcontextuserids = [$u1->id, $u2->id, $u7->id, $u9->id];
335
        $this->assertEquals($systemcontextuserids, $userlist->get_userids());
336
 
337
        $userlist = new \core_privacy\local\request\userlist($c1ctx, 'core_grades');
338
        provider::get_users_in_context($userlist);
339
        $course1userids = [$u11->id, $u3->id, $u8->id, $u5->id, $u2->id];
340
        $this->assertEquals($course1userids, $userlist->get_userids());
341
 
342
        $userlist = new \core_privacy\local\request\userlist($c2ctx, 'core_grades');
343
        provider::get_users_in_context($userlist);
344
        $course2userids = [$u4->id, $u6->id, $u3->id];
345
        $this->assertEquals($course2userids, $userlist->get_userids());
346
    }
347
 
348
    /**
349
     * Test that the appropriate user IDs are returned for a given context.
350
     */
11 efrain 351
    public function test_get_users_in_context_grades_and_history(): void {
1 efrain 352
        $dg = $this->getDataGenerator();
353
 
354
        $c1 = $dg->create_course();
355
        $c2 = $dg->create_course();
356
 
357
        $u1 = $dg->create_user();
358
        $u2 = $dg->create_user();
359
        $u3 = $dg->create_user();
360
        $u4 = $dg->create_user();
361
        $u5 = $dg->create_user();
362
        $u6 = $dg->create_user();
363
 
364
        $c1ctx = \context_course::instance($c1->id);
365
        $c2ctx = \context_course::instance($c2->id);
366
        $u2ctx = \context_user::instance($u2->id);
367
 
368
        // Create some stuff.
369
        $gi1a = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
370
        $gi1b = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
371
        $gi2a = new \grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
372
        $gi2b = new \grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
373
 
374
        // User 1 is graded in course 1.
375
        $gi1a->update_final_grade($u1->id, 1, 'test');
376
 
377
        // User 2 is graded in course 2.
378
        $gi2a->update_final_grade($u2->id, 10, 'test');
379
 
380
        // User 3 is set as modifier.
381
        $gi1a->update_final_grade($u1->id, 1, 'test', '', FORMAT_MOODLE, $u3->id);
382
 
383
        // User 4 is set as modifier, and creates history..
384
        $this->setUser($u4);
385
        $gi1a->update_final_grade($u2->id, 1, 'test');
386
 
387
        // User 5 creates history, user 6 is the known modifier, and we delete the item.
388
        $this->setUser($u5);
389
        $gi2b->update_final_grade($u2->id, 1, 'test', '', FORMAT_PLAIN, $u6->id);
390
        $gi2b->delete();
391
 
392
        $userlist = new \core_privacy\local\request\userlist($c1ctx, 'core_grades');
393
        provider::get_users_in_context($userlist);
394
        $course1userids = [$u1->id, $u2->id, $u3->id, $u4->id];
395
        $this->assertEqualsCanonicalizing($course1userids, $userlist->get_userids());
396
 
397
        $userlist = new \core_privacy\local\request\userlist($c2ctx, 'core_grades');
398
        provider::get_users_in_context($userlist);
399
        $course2userids = [$u5->id, $u2->id];
400
        $this->assertEqualsCanonicalizing($course2userids, $userlist->get_userids());
401
 
402
        $userlist = new \core_privacy\local\request\userlist($u2ctx, 'core_grades');
403
        provider::get_users_in_context($userlist);
404
        $this->assertEquals([$u2->id], $userlist->get_userids());
405
    }
406
 
11 efrain 407
    public function test_delete_data_for_all_users_in_context(): void {
1 efrain 408
        global $DB;
409
 
410
        $fs = new \file_storage();
411
 
412
        $dg = $this->getDataGenerator();
413
 
414
        $c1 = $dg->create_course();
415
        $c2 = $dg->create_course();
416
        $u1 = $dg->create_user();
417
        $u2 = $dg->create_user();
418
        $u1ctx = \context_user::instance($u1->id);
419
        $c1ctx = \context_course::instance($c1->id);
420
        $c2ctx = \context_course::instance($c2->id);
421
 
422
        $a1 = $dg->create_module('assign', ['course' => $c1->id]);
423
        $a2 = $dg->create_module('assign', ['course' => $c1->id]);
424
        $a3 = $dg->create_module('assign', ['course' => $c2->id]);
425
        $a4 = $dg->create_module('assign', ['course' => $c2->id]);
426
 
427
        $a1context = \context_module::instance($a1->cmid);
428
        $a2context = \context_module::instance($a2->cmid);
429
        $a3context = \context_module::instance($a3->cmid);
430
        $a4context = \context_module::instance($a4->cmid);
431
 
432
        // Create some stuff.
433
        $gi1a = new \grade_item($dg->create_grade_item(
434
            [
435
                'courseid' => $c1->id,
436
                'itemtype' => 'mod',
437
                'itemmodule' => 'assign',
438
                'iteminstance' => $a1->id
439
            ]
440
        ), false);
441
        $gi1b = new \grade_item($dg->create_grade_item(
442
            [
443
                'courseid' => $c1->id,
444
                'itemtype' => 'mod',
445
                'itemmodule' => 'assign',
446
                'iteminstance' => $a2->id
447
            ]
448
        ), false);
449
        $gi2a = new \grade_item($dg->create_grade_item(
450
            [
451
                'courseid' => $c2->id,
452
                'itemtype' => 'mod',
453
                'itemmodule' => 'assign',
454
                'iteminstance' => $a3->id
455
            ]
456
        ), false);
457
        $gi2b = new \grade_item($dg->create_grade_item(
458
            [
459
                'courseid' => $c2->id,
460
                'itemtype' => 'mod',
461
                'itemmodule' => 'assign',
462
                'iteminstance' => $a4->id
463
            ]
464
        ), false);
465
 
466
        $this->add_feedback_file_to_copy();
467
 
468
        $grades['feedback'] = 'Nice feedback!';
469
        $grades['feedbackformat'] = FORMAT_MOODLE;
470
        $grades['feedbackfiles'] = [
471
            'contextid' => 1,
472
            'component' => 'test',
473
            'filearea' => 'testarea',
474
            'itemid' => 1
475
        ];
476
 
477
        $grades['userid'] = $u1->id;
478
        grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance,
479
            $gi1a->itemnumber, $grades);
480
 
481
        $grades['userid'] = $u2->id;
482
        grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance,
483
            $gi1a->itemnumber, $grades);
484
 
485
        $grades['userid'] = $u1->id;
486
        grade_update('mod/assign', $gi1b->courseid, $gi1b->itemtype, $gi1b->itemmodule, $gi1b->iteminstance,
487
            $gi1b->itemnumber, $grades);
488
 
489
        $grades['userid'] = $u1->id;
490
        grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance,
491
            $gi2a->itemnumber, $grades);
492
 
493
        $grades['userid'] = $u2->id;
494
        grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance,
495
            $gi2a->itemnumber, $grades);
496
 
497
        $grades['userid'] = $u1->id;
498
        grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance,
499
            $gi2b->itemnumber, $grades);
500
 
501
        $grades['userid'] = $u2->id;
502
        grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance,
503
            $gi2b->itemnumber, $grades);
504
        $gi2b->delete();
505
 
506
        // Feedback file area.
507
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
508
        $this->assertEquals(4, count($files));
509
 
510
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
511
        $this->assertEquals(2, count($files));
512
 
513
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
514
        $this->assertEquals(4, count($files));
515
 
516
        // Grade item 2 was deleted, so the associated files were as well.
517
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
518
        $this->assertEquals(0, count($files));
519
 
520
        // History file area.
521
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
522
        $this->assertEquals(4, count($files));
523
 
524
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
525
        $this->assertEquals(2, count($files));
526
 
527
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
528
        $this->assertEquals(4, count($files));
529
 
530
        // Grade item 2 was deleted, so the associated files were as well.
531
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
532
        $this->assertEquals(0, count($files));
533
 
534
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
535
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
536
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
537
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
538
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
539
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
540
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
541
 
542
        provider::delete_data_for_all_users_in_context($c1ctx);
543
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
544
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
545
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
546
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
547
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
548
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
549
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
550
 
551
        // Feedback file area.
552
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
553
        $this->assertEquals(0, count($files));
554
 
555
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
556
        $this->assertEquals(0, count($files));
557
 
558
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
559
        $this->assertEquals(4, count($files));
560
 
561
        // Grade item 2 was deleted, so the associated files were as well.
562
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
563
        $this->assertEquals(0, count($files));
564
 
565
        // History file area.
566
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
567
        $this->assertEquals(0, count($files));
568
 
569
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
570
        $this->assertEquals(0, count($files));
571
 
572
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
573
        $this->assertEquals(4, count($files));
574
 
575
        // Grade item 2 was deleted, so the associated files were as well.
576
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
577
        $this->assertEquals(0, count($files));
578
 
579
        provider::delete_data_for_all_users_in_context($u1ctx);
580
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
581
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
582
        $this->assertFalse($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
583
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
584
 
585
        // Feedback file area.
586
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
587
        $this->assertEquals(0, count($files));
588
 
589
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
590
        $this->assertEquals(0, count($files));
591
 
592
        // The user context is only reported when there are orphan historical grades, so we only delete those files.
593
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
594
        $this->assertEquals(4, count($files));
595
 
596
        // Grade item 2 was deleted, so the associated files were as well.
597
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
598
        $this->assertEquals(0, count($files));
599
 
600
        // History file area.
601
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
602
        $this->assertEquals(0, count($files));
603
 
604
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
605
        $this->assertEquals(0, count($files));
606
 
607
        // User 2 still has historical files.
608
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
609
        $this->assertEquals(2, count($files));
610
 
611
        // Grade item 2 was deleted, so the associated files were as well.
612
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
613
        $this->assertEquals(0, count($files));
614
 
615
        provider::delete_data_for_all_users_in_context($c2ctx);
616
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
617
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
618
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
619
 
620
        // Feedback file area.
621
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
622
        $this->assertEquals(0, count($files));
623
 
624
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
625
        $this->assertEquals(0, count($files));
626
 
627
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
628
        $this->assertEquals(0, count($files));
629
 
630
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
631
        $this->assertEquals(0, count($files));
632
 
633
        // History file area.
634
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
635
        $this->assertEquals(0, count($files));
636
 
637
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
638
        $this->assertEquals(0, count($files));
639
 
640
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
641
        $this->assertEquals(0, count($files));
642
 
643
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
644
        $this->assertEquals(0, count($files));
645
    }
646
 
11 efrain 647
    public function test_delete_data_for_user(): void {
1 efrain 648
        global $DB;
649
 
650
        $fs = new \file_storage();
651
 
652
        $dg = $this->getDataGenerator();
653
 
654
        $c1 = $dg->create_course();
655
        $c2 = $dg->create_course();
656
        $u1 = $dg->create_user();
657
        $u2 = $dg->create_user();
658
        $u1ctx = \context_user::instance($u1->id);
659
        $u2ctx = \context_user::instance($u2->id);
660
        $c1ctx = \context_course::instance($c1->id);
661
        $c2ctx = \context_course::instance($c2->id);
662
 
663
        $a1 = $dg->create_module('assign', ['course' => $c1->id]);
664
        $a2 = $dg->create_module('assign', ['course' => $c1->id]);
665
        $a3 = $dg->create_module('assign', ['course' => $c2->id]);
666
        $a4 = $dg->create_module('assign', ['course' => $c2->id]);
667
 
668
        $a1context = \context_module::instance($a1->cmid);
669
        $a2context = \context_module::instance($a2->cmid);
670
        $a3context = \context_module::instance($a3->cmid);
671
        $a4context = \context_module::instance($a4->cmid);
672
 
673
        // Create some stuff.
674
        $gi1a = new \grade_item($dg->create_grade_item(
675
            [
676
                'courseid' => $c1->id,
677
                'itemtype' => 'mod',
678
                'itemmodule' => 'assign',
679
                'iteminstance' => $a1->id
680
            ]
681
        ), false);
682
        $gi1b = new \grade_item($dg->create_grade_item(
683
            [
684
                'courseid' => $c1->id,
685
                'itemtype' => 'mod',
686
                'itemmodule' => 'assign',
687
                'iteminstance' => $a2->id
688
            ]
689
        ), false);
690
        $gi2a = new \grade_item($dg->create_grade_item(
691
            [
692
                'courseid' => $c2->id,
693
                'itemtype' => 'mod',
694
                'itemmodule' => 'assign',
695
                'iteminstance' => $a3->id
696
            ]
697
        ), false);
698
        $gi2b = new \grade_item($dg->create_grade_item(
699
            [
700
                'courseid' => $c2->id,
701
                'itemtype' => 'mod',
702
                'itemmodule' => 'assign',
703
                'iteminstance' => $a4->id
704
            ]
705
        ), false);
706
 
707
        $this->add_feedback_file_to_copy();
708
 
709
        $grades['feedback'] = 'Nice feedback!';
710
        $grades['feedbackfiles'] = [
711
            'contextid' => 1,
712
            'component' => 'test',
713
            'filearea' => 'testarea',
714
            'itemid' => 1
715
        ];
716
 
717
        $grades['userid'] = $u1->id;
718
        grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance,
719
            $gi1a->itemnumber, $grades);
720
 
721
        $grades['userid'] = $u2->id;
722
        grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance,
723
            $gi1a->itemnumber, $grades);
724
 
725
        $grades['userid'] = $u1->id;
726
        grade_update('mod/assign', $gi1b->courseid, $gi1b->itemtype, $gi1b->itemmodule, $gi1b->iteminstance,
727
            $gi1b->itemnumber, $grades);
728
 
729
        $grades['userid'] = $u1->id;
730
        grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance,
731
            $gi2a->itemnumber, $grades);
732
 
733
        $grades['userid'] = $u2->id;
734
        grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance,
735
            $gi2a->itemnumber, $grades);
736
 
737
        $grades['userid'] = $u1->id;
738
        grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance,
739
            $gi2b->itemnumber, $grades);
740
 
741
        $grades['userid'] = $u2->id;
742
        grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance,
743
            $gi2b->itemnumber, $grades);
744
 
745
        $gi2b->delete();
746
 
747
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
748
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
749
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
750
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
751
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
752
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
753
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
754
 
755
        // Feedback file area.
756
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
757
        $this->assertEquals(4, count($files));
758
 
759
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
760
        $this->assertEquals(2, count($files));
761
 
762
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
763
        $this->assertEquals(4, count($files));
764
 
765
        // Grade item 2 was deleted, so the associated files were as well.
766
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
767
        $this->assertEquals(0, count($files));
768
 
769
        // History file area.
770
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
771
        $this->assertEquals(4, count($files));
772
 
773
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
774
        $this->assertEquals(2, count($files));
775
 
776
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
777
        $this->assertEquals(4, count($files));
778
 
779
        // Grade item 2 was deleted, so the associated files were as well.
780
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
781
        $this->assertEquals(0, count($files));
782
 
783
        provider::delete_data_for_user(new approved_contextlist($u1, 'core_grades', [$c1ctx->id]));
784
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
785
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
786
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
787
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
788
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
789
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
790
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
791
 
792
        // Feedback file area.
793
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
794
        $this->assertEquals(2, count($files));
795
 
796
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
797
        $this->assertEquals(0, count($files));
798
 
799
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
800
        $this->assertEquals(4, count($files));
801
 
802
        // Grade item 2 was deleted, so the associated files were as well.
803
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
804
        $this->assertEquals(0, count($files));
805
 
806
        // History file area.
807
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
808
        $this->assertEquals(2, count($files));
809
 
810
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
811
        $this->assertEquals(0, count($files));
812
 
813
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
814
        $this->assertEquals(4, count($files));
815
 
816
        // Grade item 2 was deleted, so the associated files were as well.
817
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
818
        $this->assertEquals(0, count($files));
819
 
820
        provider::delete_data_for_user(new approved_contextlist($u1, 'core_grades', [$u1ctx->id]));
821
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
822
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
823
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
824
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
825
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
826
        $this->assertFalse($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
827
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
828
 
829
        // Feedback file area.
830
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
831
        $this->assertEquals(2, count($files));
832
 
833
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
834
        $this->assertEquals(0, count($files));
835
 
836
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
837
        $this->assertEquals(4, count($files));
838
 
839
        // Grade item 2 was deleted, so the associated files were as well.
840
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
841
        $this->assertEquals(0, count($files));
842
 
843
        // History file area.
844
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
845
        $this->assertEquals(2, count($files));
846
 
847
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
848
        $this->assertEquals(0, count($files));
849
 
850
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
851
        $this->assertEquals(2, count($files));
852
 
853
        // Grade item 2 was deleted, so the associated files were as well.
854
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
855
        $this->assertEquals(0, count($files));
856
 
857
        provider::delete_data_for_user(new approved_contextlist($u1, 'core_grades', [$u2ctx->id, $c2ctx->id]));
858
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
859
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
860
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
861
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
862
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
863
        $this->assertFalse($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
864
        $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
865
 
866
        // Feedback file area.
867
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
868
        $this->assertEquals(2, count($files));
869
 
870
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
871
        $this->assertEquals(0, count($files));
872
 
873
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
874
        $this->assertEquals(2, count($files));
875
 
876
        // Grade item 2 was deleted, so the associated files were as well.
877
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
878
        $this->assertEquals(0, count($files));
879
 
880
        // History file area.
881
        $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
882
        $this->assertEquals(2, count($files));
883
 
884
        $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
885
        $this->assertEquals(0, count($files));
886
 
887
        $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
888
        $this->assertEquals(2, count($files));
889
 
890
        // Grade item 2 was deleted, so the associated files were as well.
891
        $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
892
        $this->assertEquals(0, count($files));
893
    }
894
 
895
    /**
896
     * Test deleting multiple users for a context works.
897
     */
11 efrain 898
    public function test_delete_data_for_users(): void {
1 efrain 899
        global $DB;
900
        $dg = $this->getDataGenerator();
901
 
902
        $c1 = $dg->create_course();
903
        $c2 = $dg->create_course();
904
        $u1 = $dg->create_user();
905
        $u2 = $dg->create_user();
906
        $u3 = $dg->create_user();
907
        $u4 = $dg->create_user();
908
        $u1ctx = \context_user::instance($u1->id);
909
        $u2ctx = \context_user::instance($u2->id);
910
        $c1ctx = \context_course::instance($c1->id);
911
        $c2ctx = \context_course::instance($c2->id);
912
 
913
        // Create some stuff.
914
        $gi1a = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
915
        $gi1b = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
916
        $gi2a = new \grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
917
        $gi2b = new \grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
918
 
919
        $gi1a->update_final_grade($u1->id, 1, 'test');
920
        $gi1a->update_final_grade($u2->id, 1, 'test');
921
        $gi1a->update_final_grade($u3->id, 1, 'test');
922
        $gi1b->update_final_grade($u1->id, 1, 'test');
923
        $gi1b->update_final_grade($u4->id, 1, 'test');
924
        $gi2a->update_final_grade($u1->id, 1, 'test');
925
        $gi2a->update_final_grade($u2->id, 1, 'test');
926
        $gi2a->update_final_grade($u4->id, 1, 'test');
927
        $gi2b->update_final_grade($u1->id, 1, 'test');
928
        $gi2b->update_final_grade($u2->id, 1, 'test');
929
        $gi2b->update_final_grade($u3->id, 1, 'test');
930
        $gi2b->delete();
931
 
932
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
933
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
934
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi1a->id]));
935
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
936
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi1b->id]));
937
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
938
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
939
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi2a->id]));
940
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
941
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
942
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi2b->id]));
943
 
944
        $userlist = new \core_privacy\local\request\approved_userlist($c1ctx, 'core_grades', [$u1->id, $u2->id]);
945
        provider::delete_data_for_users($userlist);
946
 
947
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
948
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
949
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi1a->id]));
950
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
951
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi1b->id]));
952
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
953
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
954
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi2a->id]));
955
 
956
        $userlist = new \core_privacy\local\request\approved_userlist($c2ctx, 'core_grades', [$u2->id, $u4->id]);
957
        provider::delete_data_for_users($userlist);
958
 
959
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
960
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
961
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi1a->id]));
962
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
963
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi1b->id]));
964
        $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
965
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
966
        $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi2a->id]));
967
    }
968
 
11 efrain 969
    public function test_export_data_for_user_about_grades_and_history(): void {
1 efrain 970
        $dg = $this->getDataGenerator();
971
 
972
        $c1 = $dg->create_course();
973
        $c2 = $dg->create_course();
974
 
975
        // Users being graded.
976
        $ug1 = $dg->create_user();
977
        $ug2 = $dg->create_user();
978
        $ug3 = $dg->create_user();
979
        // Users performing actions.
980
        $ua1 = $dg->create_user();
981
        $ua2 = $dg->create_user();
982
        $ua3 = $dg->create_user();
983
 
984
        $ug1ctx = \context_user::instance($ug1->id);
985
        $ug2ctx = \context_user::instance($ug2->id);
986
        $c1ctx = \context_course::instance($c1->id);
987
        $c2ctx = \context_course::instance($c2->id);
988
 
989
        $rootpath = [get_string('grades', 'core_grades')];
990
        $relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]);
991
 
992
        // Create the course minimal stuff.
993
        \grade_category::fetch_course_category($c1->id);
994
        $ci1 = \grade_item::fetch_course_item($c1->id);
995
        \grade_category::fetch_course_category($c2->id);
996
        $ci2 = \grade_item::fetch_course_item($c2->id);
997
 
998
        $this->add_feedback_file_to_copy();
999
 
1000
        $grades['feedbackfiles'] = [
1001
            'contextid' => 1,
1002
            'component' => 'test',
1003
            'filearea' => 'testarea',
1004
            'itemid' => 1
1005
        ];
1006
 
1007
        $a1 = $dg->create_module('assign', ['course' => $c1->id]);
1008
 
1009
        // Create data that will sit in the user context because we will delete the grate item.
1010
        $gi1 = new \grade_item($dg->create_grade_item(
1011
            [
1012
                'courseid' => $c1->id,
1013
                'itemtype' => 'mod',
1014
                'itemmodule' => 'assign',
1015
                'iteminstance' => $a1->id,
1016
                'aggregationcoef2' => 1
1017
            ]
1018
        ), false);
1019
 
1020
        $grades['feedback'] = 'Well done!';
1021
        $grades['feedbackformat'] = FORMAT_PLAIN;
1022
        $grades['userid'] = $ug1->id;
1023
        $grades['usermodified'] = $ua2->id;
1024
        $grades['rawgrade'] = 100;
1025
        grade_update('mod/assign', $gi1->courseid, $gi1->itemtype, $gi1->itemmodule, $gi1->iteminstance,
1026
            $gi1->itemnumber, $grades);
1027
 
1028
        $grades['feedback'] = 'Hi';
1029
        $grades['userid'] = $ug1->id;
1030
        $grades['usermodified'] = $ua2->id;
1031
        $grades['rawgrade'] = 1;
1032
        grade_update('mod/assign', $gi1->courseid, $gi1->itemtype, $gi1->itemmodule, $gi1->iteminstance,
1033
            $gi1->itemnumber, $grades);
1034
 
1035
        $grades['feedback'] = 'Hello';
1036
        $grades['userid'] = $ug3->id;
1037
        $grades['usermodified'] = $ua2->id;
1038
        $grades['rawgrade'] = 12;
1039
        grade_update('mod/assign', $gi1->courseid, $gi1->itemtype, $gi1->itemmodule, $gi1->iteminstance,
1040
            $gi1->itemnumber, $grades);
1041
 
1042
        // Create another set for another user.
1043
        $a2 = $dg->create_module('assign', ['course' => $c2->id]);
1044
        $a3 = $dg->create_module('assign', ['course' => $c2->id]);
1045
        $gi2a = new \grade_item($dg->create_grade_item(
1046
            [
1047
                'courseid' => $c2->id,
1048
                'itemtype' => 'mod',
1049
                'itemmodule' => 'assign',
1050
                'iteminstance' => $a2->id
1051
            ]
1052
        ), false);
1053
        $gi2b = new \grade_item($dg->create_grade_item(
1054
            [
1055
                'courseid' => $c2->id,
1056
                'itemtype' => 'mod',
1057
                'itemmodule' => 'assign',
1058
                'iteminstance' => $a3->id
1059
            ]
1060
        ), false);
1061
 
1062
        $grades['feedback'] = '';
1063
        $grades['userid'] = $ug1->id;
1064
        $grades['usermodified'] = $ua2->id;
1065
        $grades['rawgrade'] = 15;
1066
        grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance,
1067
            $gi2a->itemnumber, $grades);
1068
 
1069
        $grades['feedback'] = 'Well played!';
1070
        $grades['userid'] = $ug1->id;
1071
        $grades['usermodified'] = $ua2->id;
1072
        $grades['rawgrade'] = 30;
1073
        grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance,
1074
            $gi2b->itemnumber, $grades);
1075
 
1076
        // Export action user 1 everywhere.
1077
        provider::export_user_data(new approved_contextlist($ua1, 'core_grades', [$ug1ctx->id, $ug2ctx->id,
1078
            $c1ctx->id, $c2ctx->id]));
1079
        $this->assert_context_has_no_data($ug1ctx);
1080
        $this->assert_context_has_no_data($ug2ctx);
1081
        $this->assert_context_has_no_data($c1ctx);
1082
        $this->assert_context_has_no_data($c2ctx);
1083
 
1084
        // Export action user 2 in course 1.
1085
        writer::reset();
1086
        provider::export_user_data(new approved_contextlist($ua2, 'core_grades', [$c1ctx->id]));
1087
        $this->assert_context_has_no_data($ug1ctx);
1088
        $this->assert_context_has_no_data($ug2ctx);
1089
        $this->assert_context_has_no_data($c2ctx);
1090
        $data = writer::with_context($c1ctx)->get_data($rootpath);
1091
        $this->assertEmpty($data);
1092
 
1093
        // Here we are testing the export of grades that we've changed.
1094
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'grades');
1095
        $this->assertCount(2, $data->grades);
1096
        $this->assertEquals($gi1->get_name(), $data->grades[0]['item']);
1097
        $this->assertEquals(1, $data->grades[0]['grade']);
1098
        $this->assertEquals('Hi', $data->grades[0]['feedback']);
1099
        $this->assertEquals(transform::yesno(true), $data->grades[0]['created_or_modified_by_you']);
1100
        $this->assertEquals($gi1->get_name(), $data->grades[1]['item']);
1101
        $this->assertEquals(12, $data->grades[1]['grade']);
1102
        $this->assertEquals('Hello', $data->grades[1]['feedback']);
1103
        $this->assertEquals(transform::yesno(true), $data->grades[1]['created_or_modified_by_you']);
1104
 
1105
        $pathtofiles = [
1106
            get_string('grades', 'core_grades'),
1107
            get_string('feedbackfiles', 'core_grades')
1108
        ];
1109
        $file = writer::with_context($gi1->get_context())->get_files($pathtofiles)['feedback1.txt'];
1110
 
1111
        $this->assertInstanceOf('stored_file', $file);
1112
        $this->assertEquals('feedback1.txt', $file->get_filename());
1113
 
1114
        $relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]);
1115
 
1116
        // Here we are testing the export of history of grades that we've changed.
1117
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'grades_history');
1118
        $this->assertCount(3, $data->modified_records);
1119
        $grade = $data->modified_records[0];
1120
        $this->assertEquals($ug1->id, $grade['userid']);
1121
        $this->assertEquals($gi1->get_name(), $grade['item']);
1122
        $this->assertEquals(100, $grade['grade']);
1123
        $this->assertEquals('Well done!', $grade['feedback']);
1124
        $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
1125
        $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
1126
        $grade = $data->modified_records[1];
1127
        $this->assertEquals($ug1->id, $grade['userid']);
1128
        $this->assertEquals($gi1->get_name(), $grade['item']);
1129
        $this->assertEquals(1, $grade['grade']);
1130
        $this->assertEquals('Hi', $grade['feedback']);
1131
        $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
1132
        $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
1133
        $grade = $data->modified_records[2];
1134
        $this->assertEquals($ug3->id, $grade['userid']);
1135
        $this->assertEquals($gi1->get_name(), $grade['item']);
1136
        $this->assertEquals(12, $grade['grade']);
1137
        $this->assertEquals('Hello', $grade['feedback']);
1138
        $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
1139
        $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
1140
 
1141
        $pathtofiles = [
1142
            get_string('grades', 'core_grades'),
1143
            get_string('feedbackhistoryfiles', 'core_grades')
1144
        ];
1145
        $file = writer::with_context($gi1->get_context())->get_files($pathtofiles)['feedback1.txt'];
1146
 
1147
        $this->assertInstanceOf('stored_file', $file);
1148
        $this->assertEquals('feedback1.txt', $file->get_filename());
1149
 
1150
        // Create a history record with logged user.
1151
        $this->setUser($ua3);
1152
        $gi1->update_final_grade($ug3->id, 50, 'test', '...', FORMAT_PLAIN, $ua2->id);
1153
        writer::reset();
1154
        provider::export_user_data(new approved_contextlist($ua3, 'core_grades', [$c1ctx->id]));
1155
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'grades_history');
1156
        $this->assertCount(1, $data->modified_records);
1157
        $grade = $data->modified_records[0];
1158
        $this->assertEquals($ug3->id, $grade['userid']);
1159
        $this->assertEquals($gi1->get_name(), $grade['item']);
1160
        $this->assertEquals(50, $grade['grade']);
1161
        $this->assertEquals('...', $grade['feedback']);
1162
        $this->assertEquals(transform::yesno(true), $grade['logged_in_user_was_you']);
1163
        $this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']);
1164
 
1165
        // Test that we export our own grades.
1166
        writer::reset();
1167
        provider::export_user_data(new approved_contextlist($ug1, 'core_grades', [$c1ctx->id]));
1168
        $data = writer::with_context($c1ctx)->get_data($rootpath);
1169
        $this->assert_context_has_no_data($c2ctx);
1170
        $this->assertCount(3, $data->grades);
1171
        $grade = $data->grades[0];
1172
        $this->assertEquals($ci1->get_name(), $grade['item']);
1173
        $this->assertEquals(1, $grade['grade']);
1174
        $grade = $data->grades[2];
1175
        $this->assertEquals($gi1->get_name(), $grade['item']);
1176
        $this->assertEquals(1, $grade['grade']);
1177
        $this->assertEquals('Hi', $grade['feedback']);
1178
 
1179
        // Test that we export our own grades in two courses.
1180
        writer::reset();
1181
        provider::export_user_data(new approved_contextlist($ug1, 'core_grades', [$ug1ctx->id, $c1ctx->id, $c2ctx->id]));
1182
        $this->assert_context_has_no_data($ug1ctx);
1183
        $data = writer::with_context($c1ctx)->get_data($rootpath);
1184
        $this->assertCount(3, $data->grades);
1185
        $grade = $data->grades[0];
1186
        $this->assertEquals($ci1->get_name(), $grade['item']);
1187
        $this->assertEquals(1, $grade['grade']);
1188
        $grade = $data->grades[2];
1189
        $this->assertEquals($gi1->get_name(), $grade['item']);
1190
        $this->assertEquals(1, $grade['grade']);
1191
        $this->assertEquals('Hi', $grade['feedback']);
1192
 
1193
        $data = writer::with_context($c2ctx)->get_data($rootpath);
1194
        $this->assertCount(5, $data->grades);
1195
        $grade = $data->grades[0];
1196
        $this->assertEquals($ci2->get_name(), $grade['item']);
1197
        $grade = $data->grades[3];
1198
        $this->assertEquals($gi2a->get_name(), $grade['item']);
1199
        $this->assertEquals(15, $grade['grade']);
1200
        $this->assertEquals('', $grade['feedback']);
1201
        $grade = $data->grades[4];
1202
        $this->assertEquals($gi2b->get_name(), $grade['item']);
1203
        $this->assertEquals(30, $grade['grade']);
1204
        $this->assertEquals('Well played!', $grade['feedback']);
1205
 
1206
        // Delete a grade item.
1207
        $this->setUser($ua3);
1208
        $gi1->delete();
1209
 
1210
        // Now, we should find history of grades in our own context.
1211
        writer::reset();
1212
        provider::export_user_data(new approved_contextlist($ug1, 'core_grades', [$ug1ctx->id, $c1ctx->id, $c2ctx->id]));
1213
        $data = writer::with_context($c1ctx)->get_data($rootpath);
1214
        $this->assertCount(2, $data->grades);
1215
        $this->assertEquals($ci1->get_name(), $data->grades[0]['item']);
1216
        $data = writer::with_context($c2ctx)->get_data($rootpath);
1217
        $this->assertCount(5, $data->grades);
1218
        $data = writer::with_context($ug1ctx)->get_related_data($rootpath, 'history');
1219
        $this->assertCount(3, $data->grades);
1220
        $grade = $data->grades[0];
1221
        $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
1222
        $this->assertEquals(100, $grade['grade']);
1223
        $this->assertEquals('Well done!', $grade['feedback']);
1224
        $this->assertEquals(transform::yesno(true), $grade['graded_user_was_you']);
1225
        $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
1226
        $this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']);
1227
        $this->assertEquals(get_string('privacy:request:historyactioninsert', 'core_grades'), $grade['action']);
1228
        $grade = $data->grades[1];
1229
        $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
1230
        $this->assertEquals(1, $grade['grade']);
1231
        $this->assertEquals('Hi', $grade['feedback']);
1232
        $this->assertEquals(transform::yesno(true), $grade['graded_user_was_you']);
1233
        $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
1234
        $this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']);
1235
        $this->assertEquals(get_string('privacy:request:historyactionupdate', 'core_grades'), $grade['action']);
1236
        $grade = $data->grades[2];
1237
        $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
1238
        $this->assertEquals(1, $grade['grade']);
1239
        $this->assertEquals('Hi', $grade['feedback']);
1240
        $this->assertEquals(transform::yesno(true), $grade['graded_user_was_you']);
1241
        $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
1242
        $this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']);
1243
        $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), $grade['action']);
1244
 
1245
        // The action user 3 should have a record of the deletion in the user's context.
1246
        writer::reset();
1247
        provider::export_user_data(new approved_contextlist($ua3, 'core_grades', [$ug1ctx->id]));
1248
        $data = writer::with_context($ug1ctx)->get_related_data($rootpath, 'history');
1249
        $this->assertCount(1, $data->grades);
1250
        $grade = $data->grades[0];
1251
        $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
1252
        $this->assertEquals(1, $grade['grade']);
1253
        $this->assertEquals('Hi', $grade['feedback']);
1254
        $this->assertEquals(transform::yesno(true), $grade['logged_in_user_was_you']);
1255
        $this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']);
1256
        $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), $grade['action']);
1257
 
1258
        // The action user 2 should have a record of their edits in the user's context.
1259
        writer::reset();
1260
        provider::export_user_data(new approved_contextlist($ua2, 'core_grades', [$ug1ctx->id]));
1261
        $data = writer::with_context($ug1ctx)->get_related_data($rootpath, 'history');
1262
        $this->assertCount(3, $data->grades);
1263
        $grade = $data->grades[0];
1264
        $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
1265
        $this->assertEquals(100, $grade['grade']);
1266
        $this->assertEquals('Well done!', $grade['feedback']);
1267
        $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
1268
        $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
1269
        $this->assertEquals(get_string('privacy:request:historyactioninsert', 'core_grades'), $grade['action']);
1270
        $grade = $data->grades[1];
1271
        $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
1272
        $this->assertEquals(1, $grade['grade']);
1273
        $this->assertEquals('Hi', $grade['feedback']);
1274
        $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
1275
        $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
1276
        $this->assertEquals(get_string('privacy:request:historyactionupdate', 'core_grades'), $grade['action']);
1277
        $grade = $data->grades[2];
1278
        $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
1279
        $this->assertEquals(1, $grade['grade']);
1280
        $this->assertEquals('Hi', $grade['feedback']);
1281
        $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
1282
        $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
1283
        $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), $grade['action']);
1284
    }
1285
 
11 efrain 1286
    public function test_export_data_for_user_with_scale(): void {
1 efrain 1287
        global $DB;
1288
        $dg = $this->getDataGenerator();
1289
        $c1 = $dg->create_course();
1290
        $scale = $dg->create_scale(['scale' => 'Awesome,OK,Reasonable,Bad']);
1291
        $u1 = $dg->create_user();
1292
        $u2 = $dg->create_user();
1293
 
1294
        $u1ctx = \context_user::instance($u1->id);
1295
        $c1ctx = \context_course::instance($c1->id);
1296
 
1297
        $rootpath = [get_string('grades', 'core_grades')];
1298
 
1299
        // Create another set for another user.
1300
        $gi1 = new \grade_item($dg->create_grade_item(['courseid' => $c1->id, 'scaleid' => $scale->id]), false);
1301
        $gi1->update_final_grade($u1->id, 1, 'test', '', FORMAT_PLAIN, $u2->id);
1302
        $gi2 = new \grade_item($dg->create_grade_item(['courseid' => $c1->id, 'scaleid' => $scale->id]), false);
1303
        $gi2->update_final_grade($u1->id, 3, 'test', '', FORMAT_PLAIN, $u2->id);
1304
 
1305
        // Export user's data.
1306
        writer::reset();
1307
        provider::export_user_data(new approved_contextlist($u1, 'core_grades', [$c1ctx->id]));
1308
        $data = writer::with_context($c1ctx)->get_data($rootpath);
1309
        $this->assertCount(3, $data->grades);
1310
        $this->assertEquals(\grade_item::fetch_course_item($c1->id)->get_name(), $data->grades[0]['item']);
1311
        $this->assertEquals($gi1->get_name(), $data->grades[1]['item']);
1312
        $this->assertEquals(1, $data->grades[1]['grade']);
1313
        $this->assertEquals('Awesome', $data->grades[1]['grade_formatted']);
1314
        $this->assertEquals($gi2->get_name(), $data->grades[2]['item']);
1315
        $this->assertEquals(3, $data->grades[2]['grade']);
1316
        $this->assertEquals('Reasonable', $data->grades[2]['grade_formatted']);
1317
    }
1318
 
11 efrain 1319
    public function test_export_data_for_user_about_gradebook_edits(): void {
1 efrain 1320
        global $DB;
1321
        $dg = $this->getDataGenerator();
1322
        $c1 = $dg->create_course();
1323
        $c2 = $dg->create_course();
1324
        $u1 = $dg->create_user();
1325
        $u2 = $dg->create_user();
1326
        $u3 = $dg->create_user();
1327
        $u4 = $dg->create_user();
1328
        $u5 = $dg->create_user();
1329
        $u6 = $dg->create_user();
1330
        $u7 = $dg->create_user();
1331
        $u8 = $dg->create_user();
1332
        $u9 = $dg->create_user();
1333
        $u10 = $dg->create_user();
1334
 
1335
        $sysctx = \context_system::instance();
1336
        $u1ctx = \context_user::instance($u1->id);
1337
        $u2ctx = \context_user::instance($u2->id);
1338
        $u3ctx = \context_user::instance($u3->id);
1339
        $u4ctx = \context_user::instance($u4->id);
1340
        $u5ctx = \context_user::instance($u5->id);
1341
        $u6ctx = \context_user::instance($u6->id);
1342
        $c1ctx = \context_course::instance($c1->id);
1343
        $c2ctx = \context_course::instance($c2->id);
1344
 
1345
        $rootpath = [get_string('grades', 'core_grades')];
1346
        $relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]);
1347
        $allcontexts = [$sysctx->id, $c1ctx->id, $c2ctx->id, $u1ctx->id, $u2ctx->id, $u3ctx->id, $u4ctx->id,
1348
            $u5ctx->id, $u6ctx->id];
1349
        $updateactionstr = get_string('privacy:request:historyactionupdate', 'core_grades');
1350
 
1351
        // Create some stuff.
1352
        $gi1a = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
1353
        $gi1b = new \grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
1354
        $gi2a = new \grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
1355
        $gc1a = new \grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
1356
        $gc1b = new \grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
1357
        $gc2a = new \grade_category($dg->create_grade_category(['courseid' => $c2->id]), false);
1358
        $go2 = new \grade_outcome($dg->create_grade_outcome(['courseid' => $c2->id, 'shortname' => 'go2',
1359
            'fullname' => 'go2']), false);
1360
 
1361
        $go0 = new \grade_outcome(['shortname' => 'go0', 'fullname' => 'go0', 'usermodified' => $u1->id]);
1362
        $go0->insert();
1363
        $go1 = new \grade_outcome(['shortname' => 'go1', 'fullname' => 'go1', 'courseid' => $c1->id, 'usermodified' => $u1->id]);
1364
        $go1->insert();
1365
 
1366
        // Create scales.
1367
        $s1 = new \grade_scale(['name' => 's1', 'scale' => 'a,b', 'userid' => $u7->id, 'courseid' => 0, 'description' => '']);
1368
        $s1->insert();
1369
        $s2 = new \grade_scale(['name' => 's2', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c1->id, 'description' => '']);
1370
        $s2->insert();
1371
        $s3 = new \grade_scale(['name' => 's3', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c2->id, 'description' => '']);
1372
        $s3->insert();
1373
 
1374
        // User 2 creates history.
1375
        $this->setUser($u2);
1376
        $go0->shortname .= ' edited';
1377
        $go0->update();
1378
        $gc1a->fullname .= ' edited';
1379
        $gc1a->update();
1380
 
1381
        // User 3 creates history.
1382
        $this->setUser($u3);
1383
        $go1->shortname .= ' edited';
1384
        $go1->update();
1385
        $gc2a->fullname .= ' a';
1386
        $gc2a->update();
1387
 
1388
        // User 4 updates an outcome in course (creates history).
1389
        $this->setUser($u4);
1390
        $go2->shortname .= ' edited';
1391
        $go2->update();
1392
 
1393
        // User 5 updates an item.
1394
        $this->setUser($u5);
1395
        $gi1a->itemname .= ' edited';
1396
        $gi1a->update();
1397
 
1398
        // User 6 creates history.
1399
        $this->setUser($u6);
1400
        $gi2a->delete();
1401
 
1402
        // User 9 creates history.
1403
        $this->setUser($u9);
1404
        $s1->name .= ' edited';
1405
        $s1->update();
1406
 
1407
        // User 10 creates history.
1408
        $this->setUser($u10);
1409
        $s3->delete();
1410
 
1411
        $this->setAdminUser();
1412
 
1413
        // Export data for u1.
1414
        writer::reset();
1415
        provider::export_user_data(new approved_contextlist($u1, 'core_grades', $allcontexts));
1416
        $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes');
1417
        $this->assertCount(1, $data->outcomes);
1418
        $this->assertEquals($go0->shortname, $data->outcomes[0]['shortname']);
1419
        $this->assertEquals($go0->fullname, $data->outcomes[0]['fullname']);
1420
        $this->assertEquals(transform::yesno(true), $data->outcomes[0]['created_or_modified_by_you']);
1421
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes');
1422
        $this->assertCount(1, $data->outcomes);
1423
        $this->assertEquals($go1->shortname, $data->outcomes[0]['shortname']);
1424
        $this->assertEquals($go1->fullname, $data->outcomes[0]['fullname']);
1425
        $this->assertEquals(transform::yesno(true), $data->outcomes[0]['created_or_modified_by_you']);
1426
        $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes_history');
1427
        $this->assertEmpty($data);
1428
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes_history');
1429
        $this->assertEmpty($data);
1430
 
1431
        // Export data for u2.
1432
        writer::reset();
1433
        provider::export_user_data(new approved_contextlist($u2, 'core_grades', $allcontexts));
1434
        $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes');
1435
        $this->assertEmpty($data);
1436
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes');
1437
        $this->assertEmpty($data);
1438
        $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes_history');
1439
        $this->assertCount(1, $data->modified_records);
1440
        $this->assertEquals($go0->shortname, $data->modified_records[0]['shortname']);
1441
        $this->assertEquals($go0->fullname, $data->modified_records[0]['fullname']);
1442
        $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
1443
        $this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
1444
 
1445
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'categories_history');
1446
        $this->assertCount(1, $data->modified_records);
1447
        $this->assertEquals($gc1a->fullname, $data->modified_records[0]['name']);
1448
        $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
1449
        $this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
1450
 
1451
        // Export data for u3.
1452
        writer::reset();
1453
        provider::export_user_data(new approved_contextlist($u3, 'core_grades', $allcontexts));
1454
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes_history');
1455
        $this->assertCount(1, $data->modified_records);
1456
        $this->assertEquals($go1->shortname, $data->modified_records[0]['shortname']);
1457
        $this->assertEquals($go1->fullname, $data->modified_records[0]['fullname']);
1458
        $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
1459
        $this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
1460
 
1461
        $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'categories_history');
1462
        $this->assertCount(1, $data->modified_records);
1463
        $this->assertEquals($gc2a->fullname, $data->modified_records[0]['name']);
1464
        $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
1465
        $this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
1466
 
1467
        // Export data for u4.
1468
        writer::reset();
1469
        provider::export_user_data(new approved_contextlist($u4, 'core_grades', $allcontexts));
1470
        $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'outcomes_history');
1471
        $this->assertCount(1, $data->modified_records);
1472
        $this->assertEquals($go2->shortname, $data->modified_records[0]['shortname']);
1473
        $this->assertEquals($go2->fullname, $data->modified_records[0]['fullname']);
1474
        $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
1475
        $this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
1476
 
1477
        // Export data for u5.
1478
        writer::reset();
1479
        provider::export_user_data(new approved_contextlist($u5, 'core_grades', $allcontexts));
1480
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'items_history');
1481
        $this->assertCount(1, $data->modified_records);
1482
        $this->assertEquals($gi1a->itemname, $data->modified_records[0]['name']);
1483
        $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
1484
        $this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
1485
 
1486
        // Export data for u6.
1487
        writer::reset();
1488
        provider::export_user_data(new approved_contextlist($u6, 'core_grades', $allcontexts));
1489
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'items_history');
1490
        $this->assertEmpty($data);
1491
        $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'items_history');
1492
        $this->assertCount(1, $data->modified_records);
1493
        $this->assertEquals($gi2a->itemname, $data->modified_records[0]['name']);
1494
        $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
1495
        $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'),
1496
            $data->modified_records[0]['action']);
1497
 
1498
        // Export data for u7.
1499
        writer::reset();
1500
        provider::export_user_data(new approved_contextlist($u7, 'core_grades', $allcontexts));
1501
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales');
1502
        $this->assertEmpty($data);
1503
        $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales');
1504
        $this->assertCount(1, $data->scales);
1505
        $this->assertEquals($s1->name, $data->scales[0]['name']);
1506
        $this->assertEquals(transform::yesno(true), $data->scales[0]['created_or_modified_by_you']);
1507
 
1508
        // Export data for u8.
1509
        writer::reset();
1510
        provider::export_user_data(new approved_contextlist($u8, 'core_grades', $allcontexts));
1511
        $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales');
1512
        $this->assertEmpty($data);
1513
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales');
1514
        $this->assertCount(1, $data->scales);
1515
        $this->assertEquals($s2->name, $data->scales[0]['name']);
1516
        $this->assertEquals(transform::yesno(true), $data->scales[0]['created_or_modified_by_you']);
1517
        $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'scales_history');
1518
        $this->assertCount(2, $data->modified_records);
1519
        $this->assertEquals($s3->name, $data->modified_records[0]['name']);
1520
        $this->assertEquals(transform::yesno(true), $data->modified_records[0]['author_of_change_was_you']);
1521
        $this->assertEquals(transform::yesno(false), $data->modified_records[0]['author_of_action_was_you']);
1522
        $this->assertEquals(get_string('privacy:request:historyactioninsert', 'core_grades'),
1523
            $data->modified_records[0]['action']);
1524
        $this->assertEquals($s3->name, $data->modified_records[1]['name']);
1525
        $this->assertEquals(transform::yesno(true), $data->modified_records[1]['author_of_change_was_you']);
1526
        $this->assertEquals(transform::yesno(false), $data->modified_records[1]['author_of_action_was_you']);
1527
        $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'),
1528
            $data->modified_records[1]['action']);
1529
 
1530
        // Export data for u9.
1531
        writer::reset();
1532
        provider::export_user_data(new approved_contextlist($u9, 'core_grades', $allcontexts));
1533
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales');
1534
        $this->assertEmpty($data);
1535
        $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales');
1536
        $this->assertEmpty($data);
1537
        $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales_history');
1538
        $this->assertCount(1, $data->modified_records);
1539
        $this->assertEquals($s1->name, $data->modified_records[0]['name']);
1540
        $this->assertEquals(transform::yesno(false), $data->modified_records[0]['author_of_change_was_you']);
1541
        $this->assertEquals(transform::yesno(true), $data->modified_records[0]['author_of_action_was_you']);
1542
        $this->assertEquals(get_string('privacy:request:historyactionupdate', 'core_grades'),
1543
            $data->modified_records[0]['action']);
1544
 
1545
        // Export data for u10.
1546
        writer::reset();
1547
        provider::export_user_data(new approved_contextlist($u10, 'core_grades', $allcontexts));
1548
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales');
1549
        $this->assertEmpty($data);
1550
        $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'scales');
1551
        $this->assertEmpty($data);
1552
        $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales');
1553
        $this->assertEmpty($data);
1554
        $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales_history');
1555
        $this->assertEmpty($data);
1556
        $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales_history');
1557
        $this->assertEmpty($data);
1558
        $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'scales_history');
1559
        $this->assertCount(1, $data->modified_records);
1560
        $this->assertEquals($s3->name, $data->modified_records[0]['name']);
1561
        $this->assertEquals(transform::yesno(false), $data->modified_records[0]['author_of_change_was_you']);
1562
        $this->assertEquals(transform::yesno(true), $data->modified_records[0]['author_of_action_was_you']);
1563
        $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'),
1564
            $data->modified_records[0]['action']);
1565
    }
1566
 
1567
    /**
1568
     * Assert there is no grade data in the context.
1569
     *
1570
     * @param context $context The context.
1571
     * @return void
1572
     */
1573
    protected function assert_context_has_no_data(\context $context) {
1574
        $rootpath = [get_string('grades', 'core_grades')];
1575
        $relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]);
1576
 
1577
        $data = writer::with_context($context)->get_data($rootpath);
1578
        $this->assertEmpty($data);
1579
 
1580
        $data = writer::with_context($context)->get_related_data($rootpath, 'history');
1581
        $this->assertEmpty($data);
1582
 
1583
        $files = ['categories_history', 'items_history', 'outcomes', 'outcomes_history', 'grades', 'grades_history', 'history'];
1584
        foreach ($files as $file) {
1585
            $data = writer::with_context($context)->get_related_data($relatedtomepath, $file);
1586
            $this->assertEmpty($data);
1587
        }
1588
    }
1589
 
1590
    /**
1591
     * Creates a feedback file to copy to the gradebook area.
1592
     */
1593
    private function add_feedback_file_to_copy() {
1594
        $dummy = array(
1595
            'contextid' => 1,
1596
            'component' => 'test',
1597
            'filearea' => 'testarea',
1598
            'itemid' => 1,
1599
            'filepath' => '/',
1600
            'filename' => 'feedback1.txt'
1601
        );
1602
 
1603
        $fs = get_file_storage();
1604
        $fs->create_file_from_string($dummy, '');
1605
    }
1606
}