Proyectos de Subversion Moodle

Rev

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