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 provider tests.
19
 *
20
 * @package     mod_glossary
21
 * @copyright   2018 Simey Lameze <simey@moodle.com>
22
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
namespace mod_glossary\privacy;
25
 
26
use core_privacy\local\metadata\collection;
27
use core_privacy\local\request\approved_userlist;
28
use core_privacy\local\request\deletion_criteria;
29
use mod_glossary\privacy\provider;
30
 
31
defined('MOODLE_INTERNAL') || die();
32
 
33
global $CFG;
34
require_once($CFG->dirroot . '/comment/lib.php');
35
require_once($CFG->dirroot . '/rating/lib.php');
36
 
37
/**
38
 * Privacy provider tests class.
39
 *
40
 * @package    mod_glossary
41
 * @copyright 2018 Simey Lameze <simey@moodle.com>
42
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43
 */
44
class provider_test extends \core_privacy\tests\provider_testcase {
45
    /** @var stdClass The student object. */
46
    protected $student;
47
 
48
    /** @var stdClass The teacher object. */
49
    protected $teacher;
50
 
51
    /** @var stdClass The glossary object. */
52
    protected $glossary;
53
 
54
    /** @var stdClass The course object. */
55
    protected $course;
56
 
57
    /** @var stdClass The plugin generator object. */
58
    protected $plugingenerator;
59
 
60
    /**
61
     * {@inheritdoc}
62
     */
63
    protected function setUp(): void {
64
        $this->resetAfterTest();
65
 
66
        global $DB;
67
        $generator = $this->getDataGenerator();
68
        $course = $generator->create_course();
69
        $this->course = $course;
70
 
71
        $this->plugingenerator = $generator->get_plugin_generator('mod_glossary');
72
 
73
        // The glossary activity the user will answer.
74
        $glossary = $this->plugingenerator->create_instance(['course' => $course->id]);
75
        $this->glossary = $glossary;
76
 
77
        $cm = get_coursemodule_from_instance('glossary', $glossary->id);
78
        $context = \context_module::instance($cm->id);
79
 
80
        // Create a student which will add an entry to a glossary.
81
        $student = $generator->create_user();
82
        $generator->enrol_user($student->id,  $course->id, 'student');
83
        $this->student = $student;
84
 
85
        $teacher = $generator->create_user();
86
        $generator->enrol_user($teacher->id,  $course->id, 'editingteacher');
87
        $this->teacher = $teacher;
88
 
89
        $this->setUser($student->id);
90
        $ge1 = $this->plugingenerator->create_content($glossary, ['concept' => 'first', 'approved' => 1], ['one']);
91
 
92
        // Student create a comment on a glossary entry.
93
        $this->setUser($student);
94
        $comment = $this->get_comment_object($context, $ge1->id);
95
        $comment->add('Hello, it\'s me!');
96
 
97
        // Attach tags.
98
        \core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge1->id, $context, ['Beer', 'Golf']);
99
    }
100
 
101
    /**
102
     * Test for provider::get_metadata().
103
     */
11 efrain 104
    public function test_get_metadata(): void {
1 efrain 105
        $collection = new collection('mod_glossary');
106
        $newcollection = provider::get_metadata($collection);
107
        $itemcollection = $newcollection->get_collection();
108
        $this->assertCount(5, $itemcollection);
109
 
110
        $table = reset($itemcollection);
111
        $this->assertEquals('glossary_entries', $table->get_name());
112
 
113
        $privacyfields = $table->get_privacy_fields();
114
        $this->assertArrayHasKey('glossaryid', $privacyfields);
115
        $this->assertArrayHasKey('concept', $privacyfields);
116
        $this->assertArrayHasKey('definition', $privacyfields);
117
        $this->assertArrayHasKey('attachment', $privacyfields);
118
        $this->assertArrayHasKey('userid', $privacyfields);
119
        $this->assertArrayHasKey('timemodified', $privacyfields);
120
 
121
        $this->assertEquals('privacy:metadata:glossary_entries', $table->get_summary());
122
    }
123
 
124
    /**
125
     * Test for provider::get_contexts_for_userid().
126
     */
11 efrain 127
    public function test_get_contexts_for_userid(): void {
1 efrain 128
        $cm = get_coursemodule_from_instance('glossary', $this->glossary->id);
129
 
130
        $contextlist = provider::get_contexts_for_userid($this->student->id);
131
        $this->assertCount(1, $contextlist);
132
        $contextforuser = $contextlist->current();
133
        $cmcontext = \context_module::instance($cm->id);
134
        $this->assertEquals($cmcontext->id, $contextforuser->id);
135
    }
136
 
137
    /**
138
     * Test for provider::get_users_in_context().
139
     */
11 efrain 140
    public function test_get_users_in_context(): void {
1 efrain 141
        $component = 'mod_glossary';
142
        $cm = get_coursemodule_from_instance('glossary', $this->glossary->id);
143
        $cmcontext = \context_module::instance($cm->id);
144
 
145
        $userlist = new \core_privacy\local\request\userlist($cmcontext, $component);
146
        provider::get_users_in_context($userlist);
147
 
148
        $this->assertCount(1, $userlist);
149
 
150
        $expected = [$this->student->id];
151
        $actual = $userlist->get_userids();
152
        sort($expected);
153
        sort($actual);
154
 
155
        $this->assertEquals($expected, $actual);
156
    }
157
 
158
    /**
159
     * Test for provider::export_user_data().
160
     */
11 efrain 161
    public function test_export_for_context(): void {
1 efrain 162
        $cm = get_coursemodule_from_instance('glossary', $this->glossary->id);
163
        $cmcontext = \context_module::instance($cm->id);
164
 
165
        // Export all of the data for the context.
166
        $writer = \core_privacy\local\request\writer::with_context($cmcontext);
167
        $contextlist = new \core_privacy\local\request\approved_contextlist($this->student, 'mod_glossary' , [$cmcontext->id]);
168
 
169
        \mod_glossary\privacy\provider::export_user_data($contextlist);
170
        $this->assertTrue($writer->has_any_data());
171
        $data = $writer->get_data([]);
172
 
173
        $this->assertEquals('Glossary 1', $data->name);
174
        $this->assertEquals('first', $data->entries[0]['concept']);
175
    }
176
 
177
    /**
178
     * Test for provider::delete_data_for_all_users_in_context().
179
     */
11 efrain 180
    public function test_delete_data_for_all_users_in_context(): void {
1 efrain 181
        global $DB;
182
 
183
        $generator = $this->getDataGenerator();
184
        $cm = get_coursemodule_from_instance('glossary', $this->glossary->id);
185
        $context = \context_module::instance($cm->id);
186
        // Create another student who will add an entry the glossary activity.
187
        $student2 = $generator->create_user();
188
        $generator->enrol_user($student2->id, $this->course->id, 'student');
189
 
190
        $this->setUser($student2);
191
        $ge3 = $this->plugingenerator->create_content($this->glossary, ['concept' => 'first', 'approved' => 1], ['three']);
192
        $comment = $this->get_comment_object($context, $ge3->id);
193
        $comment->add('User 2 comment');
194
 
195
        $this->plugingenerator->create_category($this->glossary, ['cat1'], [$ge3]);
196
        $count = $DB->count_records('glossary_entries_categories', ['entryid' => $ge3->id]);
197
        $this->assertEquals(1, $count);
198
        \core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge3->id, $context, ['Pizza', 'Noodles']);
199
 
200
        // As a teacher, rate student 2 entry.
201
        $this->setUser($this->teacher);
202
        $rating = $this->get_rating_object($context, $ge3->id);
203
        $rating->update_rating(2);
204
 
205
        // Before deletion, we should have 2 entries.
206
        $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id]);
207
        $this->assertEquals(2, $count);
208
        $aliascount = $DB->count_records('glossary_alias');
209
        $this->assertEquals(2, $aliascount);
210
        // Delete data based on context.
211
        provider::delete_data_for_all_users_in_context($context);
212
 
213
        // After deletion, the glossary entries and aliases for that glossary activity should have been deleted.
214
        $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id]);
215
        $this->assertEquals(0, $count);
216
        $this->assertEquals(0, $DB->count_records('glossary_alias'));
217
        $count = $DB->count_records('glossary_entries_categories', ['entryid' => $ge3->id]);
218
        $this->assertEquals(0, $count);
219
        $tagcount = $DB->count_records('tag_instance', ['component' => 'mod_glossary', 'itemtype' => 'glossary_entries',
220
            'itemid' => $ge3->id]);
221
        $this->assertEquals(0, $tagcount);
222
 
223
        $commentcount = $DB->count_records('comments', ['component' => 'mod_glossary', 'commentarea' => 'glossary_entry',
224
            'itemid' => $ge3->id, 'userid' => $student2->id]);
225
        $this->assertEquals(0, $commentcount);
226
 
227
        $ratingcount = $DB->count_records('rating', ['component' => 'mod_glossary', 'ratingarea' => 'entry',
228
            'itemid' => $ge3->id]);
229
        $this->assertEquals(0, $ratingcount);
230
    }
231
 
232
    /**
233
     * Test for provider::delete_data_for_user().
234
     */
11 efrain 235
    public function test_delete_data_for_user(): void {
1 efrain 236
        global $DB;
237
        $generator = $this->getDataGenerator();
238
 
239
        // Create another student who will add an entry to the first glossary.
240
        $student2 = $generator->create_user();
241
        $generator->enrol_user($student2->id, $this->course->id, 'student');
242
 
243
        $cm1 = get_coursemodule_from_instance('glossary', $this->glossary->id);
244
        $glossary2 = $this->plugingenerator->create_instance(['course' => $this->course->id]);
245
        $cm2 = get_coursemodule_from_instance('glossary', $glossary2->id);
246
 
247
        $ge1 = $this->plugingenerator->create_content($this->glossary, ['concept' => 'first user glossary entry', 'approved' => 1]);
248
        $this->plugingenerator->create_content($glossary2, ['concept' => 'first user second glossary entry', 'approved' => 1]);
249
 
250
        $context1 = \context_module::instance($cm1->id);
251
        $context2 = \context_module::instance($cm2->id);
252
        \core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge1->id, $context1, ['Parmi', 'Sushi']);
253
 
254
        $this->setUser($student2);
255
        $ge3 = $this->plugingenerator->create_content($this->glossary, ['concept' => 'second user glossary entry',
256
                'approved' => 1], ['three']);
257
 
258
        $comment = $this->get_comment_object($context1, $ge3->id);
259
        $comment->add('User 2 comment');
260
 
261
        \core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge3->id, $context1, ['Pizza', 'Noodles']);
262
 
263
        // As a teacher, rate student 2's entry.
264
        $this->setUser($this->teacher);
265
        $rating = $this->get_rating_object($context1, $ge3->id);
266
        $rating->update_rating(2);
267
 
268
        // Before deletion, we should have 3 entries, one rating and 2 tag instances.
269
        $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id]);
270
        $this->assertEquals(3, $count);
271
        $tagcount = $DB->count_records('tag_instance', ['component' => 'mod_glossary', 'itemtype' => 'glossary_entries',
272
            'itemid' => $ge3->id]);
273
        $this->assertEquals(2, $tagcount);
274
        $aliascount = $DB->count_records('glossary_alias', ['entryid' => $ge3->id]);
275
        $this->assertEquals(1, $aliascount);
276
        $ratingcount = $DB->count_records('rating', ['component' => 'mod_glossary', 'ratingarea' => 'entry',
277
            'itemid' => $ge3->id]);
278
        $this->assertEquals(1, $ratingcount);
279
 
280
        $contextlist = new \core_privacy\local\request\approved_contextlist($student2, 'glossary',
281
            [$context1->id, $context2->id]);
282
        provider::delete_data_for_user($contextlist);
283
 
284
        // After deletion, the glossary entry and tags for the second student should have been deleted.
285
        $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id, 'userid' => $student2->id]);
286
        $this->assertEquals(0, $count);
287
 
288
        $tagcount = $DB->count_records('tag_instance', ['component' => 'mod_glossary', 'itemtype' => 'glossary_entries',
289
                'itemid' => $ge3->id]);
290
        $this->assertEquals(0, $tagcount);
291
 
292
        $commentcount = $DB->count_records('comments', ['component' => 'mod_glossary', 'commentarea' => 'glossary_entry',
293
                'itemid' => $ge3->id, 'userid' => $student2->id]);
294
        $this->assertEquals(0, $commentcount);
295
        $aliascount = $DB->count_records('glossary_alias', ['entryid' => $ge3->id]);
296
        $this->assertEquals(0, $aliascount);
297
 
298
        // Student's 1 entries, comments and tags should not be removed.
299
        $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id,
300
                'userid' => $this->student->id]);
301
        $this->assertEquals(2, $count);
302
 
303
        $tagcount = $DB->count_records('tag_instance', ['component' => 'mod_glossary', 'itemtype' => 'glossary_entries',
304
            'itemid' => $ge1->id]);
305
        $this->assertEquals(2, $tagcount);
306
 
307
        $commentcount = $DB->count_records('comments', ['component' => 'mod_glossary', 'commentarea' => 'glossary_entry',
308
             'userid' => $this->student->id]);
309
        $this->assertEquals(1, $commentcount);
310
 
311
        $ratingcount = $DB->count_records('rating', ['component' => 'mod_glossary', 'ratingarea' => 'entry',
312
            'itemid' => $ge3->id]);
313
        $this->assertEquals(0, $ratingcount);
314
    }
315
 
316
    /**
317
     * Test for provider::delete_data_for_users().
318
     */
11 efrain 319
    public function test_delete_data_for_users(): void {
1 efrain 320
        global $DB;
321
        $generator = $this->getDataGenerator();
322
 
323
        $student2 = $generator->create_user();
324
        $generator->enrol_user($student2->id, $this->course->id, 'student');
325
 
326
        $cm1 = get_coursemodule_from_instance('glossary', $this->glossary->id);
327
        $glossary2 = $this->plugingenerator->create_instance(['course' => $this->course->id]);
328
        $cm2 = get_coursemodule_from_instance('glossary', $glossary2->id);
329
 
330
        $ge1 = $this->plugingenerator->create_content($this->glossary, ['concept' => 'first user glossary entry', 'approved' => 1]);
331
        $ge2 = $this->plugingenerator->create_content($glossary2, ['concept' => 'first user second glossary entry',
332
                'approved' => 1], ['two']);
333
 
334
        $context1 = \context_module::instance($cm1->id);
335
        $context2 = \context_module::instance($cm2->id);
336
        \core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge1->id, $context1, ['Parmi', 'Sushi']);
337
 
338
        $this->setUser($student2);
339
        $ge3 = $this->plugingenerator->create_content($this->glossary, ['concept' => 'second user glossary entry',
340
                'approved' => 1], ['three']);
341
 
342
        $comment = $this->get_comment_object($context1, $ge3->id);
343
        $comment->add('User 2 comment 1');
344
        $comment = $this->get_comment_object($context2, $ge2->id);
345
        $comment->add('User 2 comment 2');
346
 
347
        \core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge3->id, $context1, ['Pizza', 'Noodles']);
348
        \core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge2->id, $context2, ['Potato', 'Kumara']);
349
 
350
        // As a teacher, rate student 2's entry.
351
        $this->setUser($this->teacher);
352
        $rating = $this->get_rating_object($context1, $ge3->id);
353
        $rating->update_rating(2);
354
 
355
        // Check correct glossary 1 record counts before deletion.
356
        $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id]);
357
        // Note: There is an additional student entry from setUp().
358
        $this->assertEquals(3, $count);
359
 
360
        list($context1itemsql, $context1itemparams) = $DB->get_in_or_equal([$ge1->id, $ge3->id], SQL_PARAMS_NAMED);
361
        $geparams = [
362
            'component' => 'mod_glossary',
363
            'itemtype' => 'glossary_entries',
364
        ];
365
        $geparams += $context1itemparams;
366
        $wheresql = "component = :component AND itemtype = :itemtype AND itemid {$context1itemsql}";
367
 
368
        $tagcount = $DB->count_records_select('tag_instance', $wheresql, $geparams);
369
        $this->assertEquals(4, $tagcount);
370
 
371
        $aliascount = $DB->count_records_select('glossary_alias', "entryid {$context1itemsql}", $context1itemparams);
372
        $this->assertEquals(1, $aliascount);
373
 
374
        $commentparams = [
375
            'component' => 'mod_glossary',
376
            'commentarea' => 'glossary_entry',
377
        ];
378
        $commentparams += $context1itemparams;
379
        $commentwhere = "component = :component AND commentarea = :commentarea AND itemid {$context1itemsql}";
380
 
381
        $commentcount = $DB->count_records_select('comments', $commentwhere, $commentparams);
382
        $this->assertEquals(1, $commentcount);
383
 
384
        $ratingcount = $DB->count_records('rating', ['component' => 'mod_glossary', 'ratingarea' => 'entry',
385
            'itemid' => $ge3->id]);
386
        $this->assertEquals(1, $ratingcount);
387
 
388
        // Perform deletion within context 1 for both students.
389
        $approveduserlist = new approved_userlist($context1, 'mod_glossary',
390
                [$this->student->id, $student2->id]);
391
        provider::delete_data_for_users($approveduserlist);
392
 
393
        // After deletion, all context 1 entries, tags and comment should be deleted.
394
        $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id]);
395
        $this->assertEquals(0, $count);
396
 
397
        $tagcount = $DB->count_records_select('tag_instance', $wheresql, $geparams);
398
        $this->assertEquals(0, $tagcount);
399
 
400
        $aliascount = $DB->count_records_select('glossary_alias', "entryid {$context1itemsql}", $context1itemparams);
401
        $this->assertEquals(0, $aliascount);
402
 
403
        $commentcount = $DB->count_records_select('comments', $commentwhere, $commentparams);
404
        $this->assertEquals(0, $commentcount);
405
 
406
        // Context 2 entries should remain intact.
407
        $count = $DB->count_records('glossary_entries', ['glossaryid' => $glossary2->id]);
408
        $this->assertEquals(1, $count);
409
 
410
        $tagcount = $DB->count_records('tag_instance', ['component' => 'mod_glossary', 'itemtype' => 'glossary_entries',
411
                'itemid' => $ge2->id]);
412
        $this->assertEquals(2, $tagcount);
413
 
414
        $aliascount = $DB->count_records('glossary_alias', ['entryid' => $ge2->id]);
415
        $this->assertEquals(1, $aliascount);
416
 
417
        $commentcount = $DB->count_records('comments', ['component' => 'mod_glossary', 'commentarea' => 'glossary_entry',
418
             'itemid' => $ge2->id]);
419
        $this->assertEquals(1, $commentcount);
420
 
421
        $ratingcount = $DB->count_records('rating', ['component' => 'mod_glossary', 'ratingarea' => 'entry',
422
            'itemid' => $ge3->id]);
423
        $this->assertEquals(0, $ratingcount);
424
    }
425
 
426
    /**
427
     * Get the comment area for glossary module.
428
     *
429
     * @param context $context The context.
430
     * @param int $itemid The item ID.
431
     * @return comment
432
     */
433
    protected function get_comment_object(\context $context, $itemid) {
434
        $args = new \stdClass();
435
 
436
        $args->context = $context;
437
        $args->course = get_course(SITEID);
438
        $args->area = 'glossary_entry';
439
        $args->itemid = $itemid;
440
        $args->component = 'mod_glossary';
441
        $comment = new \comment($args);
442
        $comment->set_post_permission(true);
443
 
444
        return $comment;
445
    }
446
 
447
    /**
448
     * Get the rating area for glossary module.
449
     *
450
     * @param context $context The context.
451
     * @param int $itemid The item ID.
452
     * @return rating object
453
     */
454
    protected function get_rating_object(\context $context, $itemid) {
455
        global $USER;
456
 
457
        $ratingoptions = new \stdClass;
458
        $ratingoptions->context = $context;
459
        $ratingoptions->ratingarea = 'entry';
460
        $ratingoptions->component = 'mod_glossary';
461
        $ratingoptions->itemid  = $itemid;
462
        $ratingoptions->scaleid = 2;
463
        $ratingoptions->userid  = $USER->id;
464
        return new \rating($ratingoptions);
465
    }
466
}