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 namespace core_xapi\privacy; 18 19 use core_privacy\tests\provider_testcase; 20 use core_privacy\local\request\transform; 21 use core_xapi\privacy\provider; 22 use core_xapi\local\statement\item_activity; 23 use core_xapi\test_helper; 24 25 /** 26 * Privacy tests for core_xapi. 27 * 28 * @package core_xapi 29 * @category test 30 * @copyright 2023 Sara Arjona (sara@moodle.com) 31 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 32 * @covers \core_xapi\privacy\provider 33 */ 34 class provider_test extends provider_testcase { 35 36 /** 37 * Setup to ensure that fixtures are loaded. 38 */ 39 public static function setUpBeforeClass(): void { 40 global $CFG; 41 require_once($CFG->dirroot.'/lib/xapi/tests/helper.php'); 42 } 43 44 /** 45 * Helper to set up some sample data. 46 * 47 * @return array Array with the users that have been created. 48 */ 49 protected function set_up_data(): array { 50 $user1 = self::getDataGenerator()->create_user(); 51 $user2 = self::getDataGenerator()->create_user(); 52 $user3 = self::getDataGenerator()->create_user(); 53 54 // Add a few xAPI state records to database. 55 $context = \context_system::instance(); 56 $cid = $context->id; 57 $this->setUser($user1); 58 test_helper::create_state(['activity' => item_activity::create_from_id($context->id)], true); 59 test_helper::create_state(['activity' => item_activity::create_from_id('2')], true); 60 test_helper::create_state(['activity' => item_activity::create_from_id('3'), 'component' => 'mod_h5pactivity'], true); 61 $this->setUser($user2); 62 test_helper::create_state(['activity' => item_activity::create_from_id($context->id)], true); 63 test_helper::create_state(['activity' => item_activity::create_from_id('2')], true); 64 test_helper::create_state(['activity' => item_activity::create_from_id('4')], true); 65 test_helper::create_state(['activity' => item_activity::create_from_id('5')], true); 66 $this->setUser($user3); 67 test_helper::create_state(['activity' => item_activity::create_from_id($cid), 'component' => 'mod_h5pactivity'], true); 68 69 return [$user1, $user2, $user3]; 70 } 71 72 /** 73 * Test confirming that contexts of xapi items can be added to the contextlist. 74 */ 75 public function test_add_contexts_for_userid(): void { 76 $this->resetAfterTest(); 77 78 // Scenario. 79 list($user1, $user2) = $this->set_up_data(); 80 81 // Ask the xapi privacy api to export contexts for xapi of the type we just created, for user1. 82 $contextlist = new \core_privacy\local\request\contextlist(); 83 provider::add_contexts_for_userid($contextlist, $user1->id, 'fake_component'); 84 $this->assertCount(2, $contextlist->get_contextids()); 85 86 $contextlist = new \core_privacy\local\request\contextlist(); 87 provider::add_contexts_for_userid($contextlist, $user1->id, 'mod_h5pactivity'); 88 $this->assertCount(1, $contextlist->get_contextids()); 89 90 // Ask the xapi privacy api to export contexts for xapi of the type we just created, for user2. 91 $contextlist = new \core_privacy\local\request\contextlist(); 92 provider::add_contexts_for_userid($contextlist, $user2->id, 'fake_component'); 93 $this->assertCount(4, $contextlist->get_contextids()); 94 95 $contextlist = new \core_privacy\local\request\contextlist(); 96 provider::add_contexts_for_userid($contextlist, $user2->id, 'mod_h5pactivity'); 97 $this->assertCount(0, $contextlist->get_contextids()); 98 } 99 100 /** 101 * Test confirming that user ID's of xapi states can be added to the userlist. 102 */ 103 public function test_add_userids_for_context() { 104 global $DB; 105 106 $this->resetAfterTest(); 107 108 // Scenario. 109 list($user1, $user2, $user3) = $this->set_up_data(); 110 $this->assertEquals(3, $DB->count_records('xapi_states', ['userid' => $user1->id])); 111 $this->assertEquals(4, $DB->count_records('xapi_states', ['userid' => $user2->id])); 112 $this->assertEquals(1, $DB->count_records('xapi_states', ['userid' => $user3->id])); 113 $systemcontext = \context_system::instance(); 114 115 // Ask the xapi privacy api to export userids for xapi states of the type we just created, in the system context. 116 $userlist = new \core_privacy\local\request\userlist($systemcontext, 'fake_component'); 117 provider::add_userids_for_context($userlist, 'fake_component'); 118 // Only user1 and user2 should be returned, because user3 has a different component for the system context. 119 $this->assertCount(2, $userlist->get_userids()); 120 $expected = [ 121 $user1->id, 122 $user2->id, 123 ]; 124 $this->assertEqualsCanonicalizing($expected, $userlist->get_userids()); 125 126 // Ask the xapi privacy api to export userids for xapi states of the type we just created for a different component. 127 $userlist = new \core_privacy\local\request\userlist($systemcontext, 'mod_h5pactivity'); 128 provider::add_userids_for_context($userlist, 'mod_h5pactivity'); 129 // Only user3 should be returned, because the others have a different component for the system context. 130 $this->assertCount(1, $userlist->get_userids()); 131 $expected = [$user3->id]; 132 $this->assertEqualsCanonicalizing($expected, $userlist->get_userids()); 133 134 // Ask the xapi privacy api to export userids xapi states for an empty component. 135 $userlist = new \core_privacy\local\request\userlist($systemcontext, 'empty_component'); 136 provider::add_userids_for_context($userlist, 'empty_component'); 137 $this->assertCount(0, $userlist->get_userids()); 138 } 139 140 /** 141 * Test fetching the xapi state data for a specified user in a specified component and itemid. 142 */ 143 public function test_get_xapi_states_for_user() { 144 global $DB; 145 146 $this->resetAfterTest(); 147 148 // Scenario. 149 list($user1, $user2, $user3) = $this->set_up_data(); 150 $this->assertEquals(3, $DB->count_records('xapi_states', ['userid' => $user1->id])); 151 $this->assertEquals(4, $DB->count_records('xapi_states', ['userid' => $user2->id])); 152 $this->assertEquals(1, $DB->count_records('xapi_states', ['userid' => $user3->id])); 153 $systemcontext = \context_system::instance(); 154 155 // Get the states info for user1 in the system context. 156 $result = provider::get_xapi_states_for_user($user1->id, 'fake_component', $systemcontext->id); 157 $info = (object) reset($result); 158 // Ensure the correct data has been returned. 159 $this->assertNotEmpty($info->statedata); 160 $this->assertNotEmpty(transform::datetime($info->timecreated)); 161 $this->assertNotEmpty(transform::datetime($info->timemodified)); 162 163 // Get the states info for user2 in the system context. 164 $result = provider::get_xapi_states_for_user($user2->id, 'fake_component', $systemcontext->id); 165 $info = (object) reset($result); 166 // Ensure the correct data has been returned. 167 $this->assertNotEmpty($info->statedata); 168 $this->assertNotEmpty(transform::datetime($info->timecreated)); 169 $this->assertNotEmpty(transform::datetime($info->timemodified)); 170 171 // Get the states info for user3 in the system context (it should be empty). 172 $info = provider::get_xapi_states_for_user($user3->id, 'fake_component', $systemcontext->id); 173 // Ensure the correct data has been returned. 174 $this->assertEmpty($info); 175 } 176 177 /** 178 * Test deletion of user xapi states based on an approved_contextlist and component area. 179 */ 180 public function test_delete_states_for_user(): void { 181 global $DB; 182 183 $this->resetAfterTest(); 184 185 // Scenario. 186 list($user1, $user2, $user3) = $this->set_up_data(); 187 $this->assertEquals(3, $DB->count_records('xapi_states', ['userid' => $user1->id])); 188 $this->assertEquals(4, $DB->count_records('xapi_states', ['userid' => $user2->id])); 189 $this->assertEquals(1, $DB->count_records('xapi_states', ['userid' => $user3->id])); 190 191 // Now, delete the xapistates for user1 only. 192 $user1context = \context_user::instance($user1->id); 193 $approvedcontextlist = new \core_privacy\local\request\approved_contextlist($user1, 'fake_component', [$user1context->id]); 194 provider::delete_states_for_user($approvedcontextlist, 'fake_component'); 195 196 // Verify that we have no xapi states for user1 for the fake_component but that the rest of records are intact. 197 $this->assertEquals(0, $DB->count_records('xapi_states', ['userid' => $user1->id, 'component' => 'fake_component'])); 198 $this->assertEquals(1, $DB->count_records('xapi_states', ['userid' => $user1->id, 'component' => 'mod_h5pactivity'])); 199 $this->assertEquals(4, $DB->count_records('xapi_states', ['userid' => $user2->id])); 200 $this->assertEquals(1, $DB->count_records('xapi_states', ['userid' => $user3->id])); 201 } 202 203 /** 204 * Test deletion of all user xapi states. 205 */ 206 public function test_delete_states_for_all_users(): void { 207 global $DB; 208 209 $this->resetAfterTest(); 210 211 // Scenario. 212 list($user1, $user2, $user3) = $this->set_up_data(); 213 $this->assertEquals(3, $DB->count_records('xapi_states', ['userid' => $user1->id])); 214 $this->assertEquals(4, $DB->count_records('xapi_states', ['userid' => $user2->id])); 215 $this->assertEquals(1, $DB->count_records('xapi_states', ['userid' => $user3->id])); 216 217 // Now, delete all course module xapi states in the 'fake_component' context only. 218 provider::delete_states_for_all_users(\context_system::instance(), 'fake_component'); 219 220 // Verify that only content with the context_system for the fake_component have been removed. 221 $this->assertEquals(2, $DB->count_records('xapi_states', ['userid' => $user1->id])); 222 $this->assertEquals(3, $DB->count_records('xapi_states', ['userid' => $user2->id])); 223 $this->assertEquals(1, $DB->count_records('xapi_states', ['userid' => $user3->id])); 224 } 225 226 /** 227 * Test deletion of user xapi states based on an approved_userlist and component area. 228 */ 229 public function test_delete_states_for_userlist() { 230 global $DB; 231 232 $this->resetAfterTest(); 233 234 // Scenario. 235 list($user1, $user2, $user3) = $this->set_up_data(); 236 $this->assertEquals(3, $DB->count_records('xapi_states', ['userid' => $user1->id])); 237 $this->assertEquals(4, $DB->count_records('xapi_states', ['userid' => $user2->id])); 238 $this->assertEquals(1, $DB->count_records('xapi_states', ['userid' => $user3->id])); 239 $systemcontext = \context_system::instance(); 240 241 // Ask the xapi privacy api to export userids for states of the type we just created, in the system context. 242 $userlist1 = new \core_privacy\local\request\userlist($systemcontext, 'fake_component'); 243 provider::add_userids_for_context($userlist1); 244 // Verify we have two userids in the list for system context. 245 $this->assertCount(2, $userlist1->get_userids()); 246 247 // Now, delete the states for user1 only in the system context. 248 $approveduserlist = new \core_privacy\local\request\approved_userlist($systemcontext, 'fake_component', [$user1->id]); 249 provider::delete_states_for_userlist($approveduserlist); 250 // Ensure user1's data was deleted and user2 is still returned for system context. 251 $userlist1 = new \core_privacy\local\request\userlist($systemcontext, 'fake_component'); 252 provider::add_userids_for_context($userlist1); 253 $this->assertCount(1, $userlist1->get_userids()); 254 // Verify that user2 is still in the list for system context. 255 $expected = [$user2->id]; 256 $this->assertEquals($expected, $userlist1->get_userids()); 257 // Verify that the data of user1 in other contexts was not deleted. 258 $this->assertEquals(1, $DB->count_records('xapi_states', ['userid' => $user3->id])); 259 $this->assertEquals(1, $DB->count_records('xapi_states', ['userid' => $user1->id])); 260 $this->assertEquals(2, $DB->count_records('xapi_states', ['itemid' => $systemcontext->id])); 261 262 // Verify that no data is removed if the component is empty. 263 $userlist3 = new \core_privacy\local\request\userlist($systemcontext, 'empty_component'); 264 provider::add_userids_for_context($userlist3); 265 $this->assertCount(0, $userlist3->get_userids()); 266 $this->assertEquals(2, $DB->count_records('xapi_states', ['itemid' => $systemcontext->id])); 267 } 268 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body