MDL-62456 mod_lti: add missing add_external_location_link call
[moodle.git] / mod / lti / tests / privacy_provider_test.php
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/>.
17 /**
18  * Privacy provider tests.
19  *
20  * @package    mod_lti
21  * @copyright  2018 Mark Nelson <markn@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 use core_privacy\local\metadata\collection;
26 use mod_lti\privacy\provider;
28 defined('MOODLE_INTERNAL') || die();
30 /**
31  * Privacy provider tests class.
32  *
33  * @package    mod_lti
34  * @copyright  2018 Mark Nelson <markn@moodle.com>
35  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36  */
37 class mod_lti_privacy_provider_testcase extends \core_privacy\tests\provider_testcase {
39     /**
40      * Test for provider::get_metadata().
41      */
42     public function test_get_metadata() {
43         $collection = new collection('mod_lti');
44         $newcollection = provider::get_metadata($collection);
45         $itemcollection = $newcollection->get_collection();
46         $this->assertCount(4, $itemcollection);
48         $ltiproviderexternal = array_shift($itemcollection);
49         $this->assertEquals('lti_provider', $ltiproviderexternal->get_name());
51         $ltisubmissiontable = array_shift($itemcollection);
52         $this->assertEquals('lti_submission', $ltisubmissiontable->get_name());
54         $ltitoolproxies = array_shift($itemcollection);
55         $this->assertEquals('lti_tool_proxies', $ltitoolproxies->get_name());
57         $ltitypestable = array_shift($itemcollection);
58         $this->assertEquals('lti_types', $ltitypestable->get_name());
60         $privacyfields = $ltisubmissiontable->get_privacy_fields();
61         $this->assertArrayHasKey('userid', $privacyfields);
62         $this->assertArrayHasKey('datesubmitted', $privacyfields);
63         $this->assertArrayHasKey('dateupdated', $privacyfields);
64         $this->assertArrayHasKey('gradepercent', $privacyfields);
65         $this->assertArrayHasKey('originalgrade', $privacyfields);
66         $this->assertEquals('privacy:metadata:lti_submission', $ltisubmissiontable->get_summary());
68         $privacyfields = $ltitoolproxies->get_privacy_fields();
69         $this->assertArrayHasKey('name', $privacyfields);
70         $this->assertArrayHasKey('createdby', $privacyfields);
71         $this->assertArrayHasKey('timecreated', $privacyfields);
72         $this->assertArrayHasKey('timemodified', $privacyfields);
73         $this->assertEquals('privacy:metadata:lti_tool_proxies', $ltitoolproxies->get_summary());
75         $privacyfields = $ltitypestable->get_privacy_fields();
76         $this->assertArrayHasKey('name', $privacyfields);
77         $this->assertArrayHasKey('createdby', $privacyfields);
78         $this->assertArrayHasKey('timecreated', $privacyfields);
79         $this->assertArrayHasKey('timemodified', $privacyfields);
80         $this->assertEquals('privacy:metadata:lti_types', $ltitypestable->get_summary());
81     }
83     /**
84      * Test for provider::get_contexts_for_userid().
85      */
86     public function test_get_contexts_for_userid() {
87         $this->resetAfterTest();
89         $course = $this->getDataGenerator()->create_course();
91         // The LTI activity the user will have submitted something for.
92         $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id));
94         // Another LTI activity that has no user activity.
95         $this->getDataGenerator()->create_module('lti', array('course' => $course->id));
97         // Create a user which will make a submission.
98         $user = $this->getDataGenerator()->create_user();
100         $this->create_lti_submission($lti->id, $user->id);
102         // Check the contexts supplied are correct.
103         $contextlist = provider::get_contexts_for_userid($user->id);
104         $this->assertCount(2, $contextlist);
106         $contextformodule = $contextlist->current();
107         $cmcontext = context_module::instance($lti->cmid);
108         $this->assertEquals($cmcontext->id, $contextformodule->id);
110         $contextlist->next();
111         $contextforsystem = $contextlist->current();
112         $this->assertEquals(SYSCONTEXTID, $contextforsystem->id);
113     }
115     /**
116      * Test for provider::export_user_data().
117      */
118     public function test_export_for_context_submissions() {
119         $this->resetAfterTest();
121         $course = $this->getDataGenerator()->create_course();
123         $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id));
125         // Create users which will make submissions.
126         $user1 = $this->getDataGenerator()->create_user();
127         $user2 = $this->getDataGenerator()->create_user();
129         $this->create_lti_submission($lti->id, $user1->id);
130         $this->create_lti_submission($lti->id, $user1->id);
131         $this->create_lti_submission($lti->id, $user2->id);
133         // Export all of the data for the context for user 1.
134         $cmcontext = context_module::instance($lti->cmid);
135         $this->export_context_data_for_user($user1->id, $cmcontext, 'mod_lti');
136         $writer = \core_privacy\local\request\writer::with_context($cmcontext);
138         $this->assertTrue($writer->has_any_data());
140         $data = $writer->get_data();
141         $this->assertCount(2, $data->submissions);
142     }
144     /**
145      * Test for provider::export_user_data().
146      */
147     public function test_export_for_context_tool_types() {
148         $this->resetAfterTest();
150         $course1 = $this->getDataGenerator()->create_course();
151         $course2 = $this->getDataGenerator()->create_course();
153         // Create a user which will make a tool type.
154         $user = $this->getDataGenerator()->create_user();
155         $this->setUser($user);
157         // Create a user that will not make a tool type.
158         $this->getDataGenerator()->create_user();
160         $type = new stdClass();
161         $type->baseurl = 'http://moodle.org';
162         $type->course = $course1->id;
163         lti_add_type($type, new stdClass());
165         $type = new stdClass();
166         $type->baseurl = 'http://moodle.org';
167         $type->course = $course1->id;
168         lti_add_type($type, new stdClass());
170         $type = new stdClass();
171         $type->baseurl = 'http://moodle.org';
172         $type->course = $course2->id;
173         lti_add_type($type, new stdClass());
175         // Export all of the data for the context.
176         $coursecontext = context_course::instance($course1->id);
177         $this->export_context_data_for_user($user->id, $coursecontext, 'mod_lti');
178         $writer = \core_privacy\local\request\writer::with_context($coursecontext);
180         $this->assertTrue($writer->has_any_data());
182         $data = $writer->get_data();
183         $this->assertCount(2, $data->lti_types);
185         $coursecontext = context_course::instance($course2->id);
186         $this->export_context_data_for_user($user->id, $coursecontext, 'mod_lti');
187         $writer = \core_privacy\local\request\writer::with_context($coursecontext);
189         $this->assertTrue($writer->has_any_data());
191         $data = $writer->get_data();
192         $this->assertCount(1, $data->lti_types);
193     }
195     /**
196      * Test for provider::export_user_data().
197      */
198     public function test_export_for_context_tool_proxies() {
199         $this->resetAfterTest();
201         // Create a user that will not make a tool proxy.
202         $user = $this->getDataGenerator()->create_user();
203         $this->setUser($user);
205         $toolproxy = new stdClass();
206         $toolproxy->createdby = $user;
207         lti_add_tool_proxy($toolproxy);
209         // Export all of the data for the context.
210         $systemcontext = context_system::instance();
211         $this->export_context_data_for_user($user->id, $systemcontext, 'mod_lti');
212         $writer = \core_privacy\local\request\writer::with_context($systemcontext);
214         $this->assertTrue($writer->has_any_data());
216         $data = $writer->get_data();
217         $this->assertCount(1, $data->lti_tool_proxies);
218     }
220     /**
221      * Test for provider::delete_data_for_all_users_in_context().
222      */
223     public function test_delete_data_for_all_users_in_context() {
224         global $DB;
226         $this->resetAfterTest();
228         $course = $this->getDataGenerator()->create_course();
230         $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id));
232         // Create users that will make submissions.
233         $user1 = $this->getDataGenerator()->create_user();
234         $user2 = $this->getDataGenerator()->create_user();
236         $this->create_lti_submission($lti->id, $user1->id);
237         $this->create_lti_submission($lti->id, $user2->id);
239         // Before deletion, we should have 2 responses.
240         $count = $DB->count_records('lti_submission', ['ltiid' => $lti->id]);
241         $this->assertEquals(2, $count);
243         // Delete data based on context.
244         $cmcontext = context_module::instance($lti->cmid);
245         provider::delete_data_for_all_users_in_context($cmcontext);
247         // After deletion, the lti submissions for that lti activity should have been deleted.
248         $count = $DB->count_records('lti_submission', ['ltiid' => $lti->id]);
249         $this->assertEquals(0, $count);
250     }
252     /**
253      * Test for provider::delete_data_for_user().
254      */
255     public function test_delete_data_for_user() {
256         global $DB;
258         $this->resetAfterTest();
260         $course = $this->getDataGenerator()->create_course();
262         $lti = $this->getDataGenerator()->create_module('lti', array('course' => $course->id));
264         // Create users that will make submissions.
265         $user1 = $this->getDataGenerator()->create_user();
266         $user2 = $this->getDataGenerator()->create_user();
268         $this->create_lti_submission($lti->id, $user1->id);
269         $this->create_lti_submission($lti->id, $user2->id);
271         // Before deletion we should have 2 responses.
272         $count = $DB->count_records('lti_submission', ['ltiid' => $lti->id]);
273         $this->assertEquals(2, $count);
275         $context = \context_module::instance($lti->cmid);
276         $contextlist = new \core_privacy\local\request\approved_contextlist($user1, 'lti',
277             [context_system::instance()->id, $context->id]);
278         provider::delete_data_for_user($contextlist);
280         // After deletion the lti submission for the first user should have been deleted.
281         $count = $DB->count_records('lti_submission', ['ltiid' => $lti->id, 'userid' => $user1->id]);
282         $this->assertEquals(0, $count);
284         // Check the submission for the other user is still there.
285         $ltisubmission = $DB->get_records('lti_submission');
286         $this->assertCount(1, $ltisubmission);
287         $lastsubmission = reset($ltisubmission);
288         $this->assertEquals($user2->id, $lastsubmission->userid);
289     }
291     /**
292      * Mimicks the creation of an LTI submission.
293      *
294      * There is no API we can use to insert an LTI submission, so we
295      * will simply insert directly into the database.
296      *
297      * @param int $ltiid
298      * @param int $userid
299      */
300     protected function create_lti_submission(int $ltiid, int $userid) {
301         global $DB;
303         $ltisubmissiondata = [
304             'ltiid' => $ltiid,
305             'userid' => $userid,
306             'datesubmitted' => time(),
307             'dateupdated' => time(),
308             'gradepercent' => 65,
309             'originalgrade' => 70,
310             'launchid' => 3,
311             'state' => 1
312         ];
314         $DB->insert_record('lti_submission', $ltisubmissiondata);
315     }