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