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
 * Privacy tests for core_grading.
19
 *
20
 * @package    core_grading
21
 * @category   test
22
 * @copyright  2018 Sara Arjona <sara@moodle.com>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
namespace core_grading\privacy;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
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_grading\privacy\provider;
36
 
37
/**
38
 * Privacy tests for core_grading.
39
 *
40
 * @copyright  2018 Sara Arjona <sara@moodle.com>
41
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42
 */
43
class provider_test extends provider_testcase {
44
 
45
    /** @var stdClass User without data. */
46
    protected $user0;
47
 
48
    /** @var stdClass User with data. */
49
    protected $user1;
50
 
51
    /** @var stdClass User with data. */
52
    protected $user2;
53
 
54
    /** @var context context_module of an activity without grading definitions. */
55
    protected $instancecontext0;
56
 
57
    /** @var context context_module of the activity where the grading definitions are. */
58
    protected $instancecontext1;
59
 
60
    /** @var context context_module of the activity where the grading definitions are. */
61
    protected $instancecontext2;
62
 
63
    /**
64
     * Test getting the context for the user ID related to this plugin.
65
     */
11 efrain 66
    public function test_get_contexts_for_userid(): void {
1 efrain 67
        global $DB;
68
 
69
        $this->resetAfterTest();
70
        $this->grading_setup_test_scenario_data();
71
        $this->assertCount(2, $DB->get_records('grading_definitions'));
72
 
73
        // User1 has created grading definitions for instance1 and instance2.
74
        $contextlist = provider::get_contexts_for_userid($this->user1->id);
75
        $this->assertCount(2, $contextlist);
76
        $this->assertContainsEquals($this->instancecontext1->id, $contextlist->get_contextids());
77
        $this->assertContainsEquals($this->instancecontext2->id, $contextlist->get_contextids());
78
        $this->assertNotContainsEquals($this->instancecontext0->id, $contextlist->get_contextids());
79
 
80
        // User2 has only modified grading definitions for instance2.
81
        $contextlist = provider::get_contexts_for_userid($this->user2->id);
82
        $this->assertCount(1, $contextlist);
83
        $this->assertContainsEquals($this->instancecontext2->id, $contextlist->get_contextids());
84
 
85
        // User0 hasn't created or modified any grading definition.
86
        $contextlist = provider::get_contexts_for_userid($this->user0->id);
87
        $this->assertCount(0, $contextlist);
88
    }
89
 
90
    /**
91
     * Test retrieval of user ids in a given context.
92
     */
11 efrain 93
    public function test_get_users_in_context(): void {
1 efrain 94
        $this->resetAfterTest();
95
        $this->grading_setup_test_scenario_data();
96
        // Instance two has one user who created the definitions and another who modified it.
97
        $userlist = new \core_privacy\local\request\userlist($this->instancecontext2, 'core_grading');
98
        provider::get_users_in_context($userlist);
99
        // Check that we get both.
100
        $this->assertCount(2, $userlist->get_userids());
101
    }
102
 
103
    /**
104
     * Export for a user with no grading definitions created or modified will not have any data exported.
105
     */
11 efrain 106
    public function test_export_user_data_no_content(): void {
1 efrain 107
        $this->resetAfterTest();
108
 
109
        $user = $this->getDataGenerator()->create_user();
110
        $this->setUser($user);
111
        $context = \context_system::instance();
112
 
113
        /** @var \core_privacy\tests\request\content_writer $writer */
114
        $writer = writer::with_context($context);
115
        $this->assertFalse($writer->has_any_data());
116
        $this->export_context_data_for_user($user->id, $context, 'core_grading');
117
        $this->assertFalse(writer::with_context($context)->has_any_data());
118
    }
119
 
120
    /**
121
     * Test that data is exported correctly for this plugin.
122
     */
11 efrain 123
    public function test_export_user_data(): void {
1 efrain 124
        global $DB;
125
 
126
        $this->resetAfterTest();
127
        $now = time();
128
        $defnameprefix = 'fakename';
129
        $this->grading_setup_test_scenario_data($defnameprefix, $now);
130
        $this->assertCount(2, $DB->get_records('grading_definitions'));
131
 
132
        // Validate exported data: instance1 - user0 has NO data.
133
        $this->setUser($this->user0);
134
        writer::reset();
135
        $writer = writer::with_context($this->instancecontext1);
136
        $this->assertFalse($writer->has_any_data());
137
        $this->export_context_data_for_user($this->user0->id, $this->instancecontext1, 'core_grading');
138
        $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
139
        $this->assertEmpty($data);
140
 
141
        // Validate exported data: instance0 - user1 has NO data.
142
        $this->setUser($this->user1);
143
        writer::reset();
144
        $writer = writer::with_context($this->instancecontext0);
145
        $this->assertFalse($writer->has_any_data());
146
        $this->export_context_data_for_user($this->user1->id, $this->instancecontext0, 'core_grading');
147
        $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
148
        $this->assertEmpty($data);
149
 
150
        // Validate exported data: instance1 - user1 has data (user has created and modified it).
151
        writer::reset();
152
        $writer = writer::with_context($this->instancecontext1);
153
        $this->assertFalse($writer->has_any_data());
154
        $this->export_context_data_for_user($this->user1->id, $this->instancecontext1, 'core_grading');
155
        $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
156
        $this->assertCount(1, $data->definitions);
157
 
158
        $firstkey = reset($data->definitions);
159
        $this->assertNotEmpty($firstkey->name);
160
        $this->assertEquals('test_method', $firstkey->method);
161
        $this->assertEquals(transform::datetime($now), $firstkey->timecreated);
162
        $this->assertEquals($this->user1->id, $firstkey->usercreated);
163
        $this->assertEquals($defnameprefix.'1', $firstkey->name);
164
 
165
        // Validate exported data: instance2 - user1 has data (user has created it).
166
        writer::reset();
167
        $writer = writer::with_context($this->instancecontext2);
168
        $this->assertFalse($writer->has_any_data());
169
        $this->export_context_data_for_user($this->user1->id, $this->instancecontext2, 'core_grading');
170
        $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
171
        $this->assertCount(1, $data->definitions);
172
 
173
        $firstkey = reset($data->definitions);
174
        $this->assertNotEmpty($firstkey->name);
175
        $this->assertEquals('test_method', $firstkey->method);
176
        $this->assertEquals(transform::datetime($now), $firstkey->timecreated);
177
        $this->assertEquals($this->user1->id, $firstkey->usercreated);
178
        $this->assertEquals($defnameprefix.'2', $firstkey->name);
179
 
180
        // Validate exported data: instance1 - user2 has NO data.
181
        $this->setUser($this->user2);
182
        writer::reset();
183
        $writer = writer::with_context($this->instancecontext1);
184
        $this->assertFalse($writer->has_any_data());
185
        $this->export_context_data_for_user($this->user2->id, $this->instancecontext1, 'core_grading');
186
        $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
187
        $this->assertEmpty($data);
188
 
189
        // Validate exported data: instance2 - user2 has data (user has modified it).
190
        $this->setUser($this->user2);
191
        writer::reset();
192
        $writer = writer::with_context($this->instancecontext2);
193
        $this->assertFalse($writer->has_any_data());
194
        $this->export_context_data_for_user($this->user2->id, $this->instancecontext2, 'core_grading');
195
        $data = $writer->get_data([get_string('gradingmethod', 'grading')]);
196
        $this->assertCount(1, $data->definitions);
197
    }
198
 
199
    /**
200
     * Test for provider::delete_data_for_all_users_in_context().
201
     */
11 efrain 202
    public function test_delete_data_for_all_users_in_context(): void {
1 efrain 203
        global $DB;
204
 
205
        $this->resetAfterTest();
206
        $this->grading_setup_test_scenario_data();
207
 
208
        // Before deletion, we should have 2 grading_definitions.
209
        $this->assertCount(2, $DB->get_records('grading_definitions'));
210
 
211
        // Delete data.
212
        provider::delete_data_for_all_users_in_context($this->instancecontext0);
213
        provider::delete_data_for_all_users_in_context($this->instancecontext1);
214
        provider::delete_data_for_all_users_in_context($this->instancecontext2);
215
 
216
        // Before deletion, we should have same grading_definitions (nothing was deleted).
217
        $this->assertCount(2, $DB->get_records('grading_definitions'));
218
    }
219
 
220
    /**
221
     * Test for provider::delete_data_for_user().
222
     */
11 efrain 223
    public function test_delete_data_for_user(): void {
1 efrain 224
        global $DB;
225
 
226
        $this->resetAfterTest();
227
        $this->grading_setup_test_scenario_data();
228
 
229
        // Before deletion, we should have 2 grading_definitions.
230
        $this->assertCount(2, $DB->get_records('grading_definitions'));
231
 
232
        // Delete data for $user0.
233
        $contextlist = provider::get_contexts_for_userid($this->user0->id);
234
        $approvedcontextlist = new approved_contextlist(
235
            $this->user0,
236
            'core_grading',
237
            $contextlist->get_contextids()
238
        );
239
        provider::delete_data_for_user($approvedcontextlist);
240
 
241
        // Delete data for $user1.
242
        $contextlist = provider::get_contexts_for_userid($this->user1->id);
243
        $approvedcontextlist = new approved_contextlist(
244
            $this->user1,
245
            'core_grading',
246
            $contextlist->get_contextids()
247
        );
248
        provider::delete_data_for_user($approvedcontextlist);
249
 
250
        // Delete data for $user2.
251
        $contextlist = provider::get_contexts_for_userid($this->user2->id);
252
        $approvedcontextlist = new approved_contextlist(
253
            $this->user2,
254
            'core_grading',
255
            $contextlist->get_contextids()
256
        );
257
        provider::delete_data_for_user($approvedcontextlist);
258
 
259
        // Before deletion, we should have same grading_definitions (nothing was deleted).
260
        $this->assertCount(2, $DB->get_records('grading_definitions'));
261
    }
262
 
263
    /**
264
     * Test exporting user data relating to an item ID.
265
     */
11 efrain 266
    public function test_export_item_data(): void {
1 efrain 267
        global $DB;
268
        $this->resetAfterTest();
269
        $course = $this->getDataGenerator()->create_course();
270
        $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]);
271
        $user = $this->getDataGenerator()->create_user();
272
        $guidegenerator = \testing_util::get_data_generator()->get_plugin_generator('gradingform_guide');
273
 
274
        $this->setUser($user);
275
 
276
        $modulecontext = \context_module::instance($module->cmid);
277
        $controller = $guidegenerator->get_test_guide($modulecontext);
278
 
279
        // In the situation of mod_assign this would be the id from assign_grades.
280
        $itemid = 1;
281
        $instance = $controller->create_instance($user->id, $itemid);
282
        $data = $guidegenerator->get_test_form_data(
283
            $controller,
284
            $itemid,
285
            5, 'This user made several mistakes.',
286
            10, 'This user has two pictures.'
287
        );
288
 
289
        $instance->update($data);
290
        $instanceid = $instance->get_data('id');
291
 
292
        provider::export_item_data($modulecontext, $itemid, ['Test']);
293
        $data = (array) writer::with_context($modulecontext)->get_data(['Test', 'Marking guide', $instance->get_data('id')]);
294
        $this->assertCount(2, $data);
295
        $this->assertEquals('This user made several mistakes.', $data['Spelling mistakes']->remark);
296
        $this->assertEquals(5, $data['Spelling mistakes']->score);
297
        $this->assertEquals('This user has two pictures.', $data['Pictures']->remark);
298
        $this->assertEquals(10, $data['Pictures']->score);
299
    }
300
 
301
    /**
302
     * Test deleting user data related to a context and item ID.
303
     */
11 efrain 304
    public function test_delete_instance_data(): void {
1 efrain 305
        global $DB;
306
        $this->resetAfterTest();
307
        $course = $this->getDataGenerator()->create_course();
308
        $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]);
309
        $user = $this->getDataGenerator()->create_user();
310
        $guidegenerator = \testing_util::get_data_generator()->get_plugin_generator('gradingform_guide');
311
 
312
        $this->setUser($user);
313
 
314
        $modulecontext = \context_module::instance($module->cmid);
315
        $controller = $guidegenerator->get_test_guide($modulecontext);
316
 
317
        // In the situation of mod_assign this would be the id from assign_grades.
318
        $itemid = 1;
319
        $instance = $controller->create_instance($user->id, $itemid);
320
        $data = $guidegenerator->get_test_form_data(
321
            $controller,
322
            $itemid,
323
            5, 'This user made several mistakes.',
324
            10, 'This user has two pictures.'
325
        );
326
        $instance->update($data);
327
 
328
        $itemid = 2;
329
        $instance = $controller->create_instance($user->id, $itemid);
330
        $data = $guidegenerator->get_test_form_data(
331
            $controller,
332
            $itemid,
333
            25, 'This user made no mistakes.',
334
            5, 'This user has one picture.'
335
        );
336
        $instance->update($data);
337
 
338
        // Check how many records we have in the fillings table.
339
        $records = $DB->get_records('gradingform_guide_fillings');
340
        $this->assertCount(4, $records);
341
        // Let's delete one of the instances (the last one would be the easiest).
342
        provider::delete_instance_data($modulecontext, $itemid);
343
        $records = $DB->get_records('gradingform_guide_fillings');
344
        $this->assertCount(2, $records);
345
        foreach ($records as $record) {
346
            $this->assertNotEquals($instance->get_id(), $record->instanceid);
347
        }
348
        // This will delete all the rest of the instances for this context.
349
        provider::delete_instance_data($modulecontext);
350
        $records = $DB->get_records('gradingform_guide_fillings');
351
        $this->assertEmpty($records);
352
    }
353
 
354
    /**
355
     * Test the deletion of multiple instances at once.
356
     */
11 efrain 357
    public function test_delete_data_for_instances(): void {
1 efrain 358
        global $DB;
359
        $this->resetAfterTest();
360
        $course = $this->getDataGenerator()->create_course();
361
        $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]);
362
        $user1 = $this->getDataGenerator()->create_user();
363
        $user2 = $this->getDataGenerator()->create_user();
364
        $user3 = $this->getDataGenerator()->create_user();
365
        $guidegenerator = \testing_util::get_data_generator()->get_plugin_generator('gradingform_guide');
366
 
367
        $this->setUser($user1);
368
 
369
        $modulecontext = \context_module::instance($module->cmid);
370
        $controller = $guidegenerator->get_test_guide($modulecontext);
371
 
372
        // In the situation of mod_assign this would be the id from assign_grades.
373
        $itemid1 = 1;
374
        $instance1 = $controller->create_instance($user1->id, $itemid1);
375
        $data = $guidegenerator->get_test_form_data(
376
            $controller,
377
            $itemid1,
378
            5, 'This user made several mistakes.',
379
            10, 'This user has two pictures.'
380
        );
381
        $instance1->update($data);
382
 
383
        $itemid2 = 2;
384
        $instance2 = $controller->create_instance($user2->id, $itemid2);
385
        $data = $guidegenerator->get_test_form_data(
386
            $controller,
387
            $itemid2,
388
            15, 'This user made a couple of mistakes.',
389
            10, 'This user has one picture.'
390
        );
391
        $instance2->update($data);
392
 
393
        $itemid3 = 3;
394
        $instance3 = $controller->create_instance($user3->id, $itemid3);
395
        $data = $guidegenerator->get_test_form_data(
396
            $controller,
397
            $itemid3,
398
            20, 'This user made one mistakes.',
399
            10, 'This user has one picture.'
400
        );
401
        $instance3->update($data);
402
 
403
        $records = $DB->get_records('gradingform_guide_fillings');
404
        $this->assertCount(6, $records);
405
 
406
        // Delete all user data for items 1 and 3.
407
        provider::delete_data_for_instances($modulecontext, [$itemid1, $itemid3]);
408
 
409
        $records = $DB->get_records('gradingform_guide_fillings');
410
        $this->assertCount(2, $records);
411
        $instanceid = $instance2->get_data('id');
412
        // The instance id should match for all remaining records.
413
        foreach ($records as $record) {
414
            $this->assertEquals($instanceid, $record->instanceid);
415
        }
416
    }
417
 
418
    /**
419
     * Helper function to setup the environment.
420
     *
421
     * course
422
     *  |
423
     *  +--instance0 (assignment)
424
     *  |   |
425
     *  +--instance1 (assignment)
426
     *  |   |
427
     *  |   +--grading_definition1 (created and modified by user1)
428
     *  |   |
429
     *  +--instance2 (assignment)
430
     *  |   |
431
     *  |   +--grading_definition2 (created by user1 and modified by user2)
432
     *
433
     *
434
     * user0 hasn't any data.
435
     *
436
     * @param string $defnameprefix
437
     * @param timestamp $now
438
     */
439
    protected function grading_setup_test_scenario_data($defnameprefix = null, $now = null) {
440
        global $DB;
441
 
442
        $this->user0 = $this->getDataGenerator()->create_user();
443
        $this->user1 = $this->getDataGenerator()->create_user();
444
        $this->user2 = $this->getDataGenerator()->create_user();
445
 
446
        // Create a course.
447
        $course = $this->getDataGenerator()->create_course();
448
        $coursecontext = \context_course::instance($course->id);
449
 
450
        // Create some assignment instances.
451
        $params = (object)array(
452
            'course' => $course->id,
453
            'name'   => 'Testing instance'
454
        );
455
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
456
        $instance0 = $generator->create_instance($params);
457
        $cm0 = get_coursemodule_from_instance('assign', $instance0->id);
458
        $this->instancecontext0 = \context_module::instance($cm0->id);
459
        $instance1 = $generator->create_instance($params);
460
        $cm1 = get_coursemodule_from_instance('assign', $instance1->id);
461
        $this->instancecontext1 = \context_module::instance($cm1->id);
462
        $instance2 = $generator->create_instance($params);
463
        $cm2 = get_coursemodule_from_instance('assign', $instance2->id);
464
        $this->instancecontext2 = \context_module::instance($cm2->id);
465
 
466
        // Create fake grading areas.
467
        $fakearea1 = (object)array(
468
            'contextid'    => $this->instancecontext1->id,
469
            'component'    => 'mod_assign',
470
            'areaname'     => 'submissions',
471
            'activemethod' => 'test_method'
472
        );
473
        $fakeareaid1 = $DB->insert_record('grading_areas', $fakearea1);
474
        $fakearea2 = clone($fakearea1);
475
        $fakearea2->contextid = $this->instancecontext2->id;
476
        $fakeareaid2 = $DB->insert_record('grading_areas', $fakearea2);
477
 
478
        // Create fake grading definitions.
479
        if (empty($now)) {
480
            $now = time();
481
        }
482
        if (empty($defnameprefix)) {
483
            $defnameprefix = 'fakename';
484
        }
485
        $fakedefinition1 = (object)array(
486
            'areaid'       => $fakeareaid1,
487
            'method'       => 'test_method',
488
            'name'         => $defnameprefix.'1',
489
            'status'       => 0,
490
            'timecreated'  => $now,
491
            'usercreated'  => $this->user1->id,
492
            'timemodified' => $now + 1,
493
            'usermodified' => $this->user1->id,
494
        );
495
        $fakedefid1 = $DB->insert_record('grading_definitions', $fakedefinition1);
496
        $fakedefinition2 = clone($fakedefinition1);
497
        $fakedefinition2->areaid = $fakeareaid2;
498
        $fakedefinition2->name = $defnameprefix.'2';
499
        $fakedefinition2->usermodified = $this->user2->id;
500
        $fakedefid2 = $DB->insert_record('grading_definitions', $fakedefinition2);
501
    }
502
}