See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
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 * Provides the {@link tool_policy_api_testcase} class. 19 * 20 * @package tool_policy 21 * @category test 22 * @copyright 2018 David Mudrák <david@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 use tool_policy\api; 27 use tool_policy\policy_version; 28 use tool_policy\test\helper; 29 30 defined('MOODLE_INTERNAL') || die(); 31 32 global $CFG; 33 34 /** 35 * Unit tests for the {@link \tool_policy\api} class. 36 * 37 * @copyright 2018 David Mudrak <david@moodle.com> 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class tool_policy_api_testcase extends advanced_testcase { 41 42 /** 43 * Test the common operations with a policy document and its versions. 44 */ 45 public function test_policy_document_life_cycle() { 46 $this->resetAfterTest(); 47 $this->setAdminUser(); 48 49 // Prepare the form data for adding a new policy document. 50 $formdata = api::form_policydoc_data(new policy_version(0)); 51 $this->assertObjectHasAttribute('name', $formdata); 52 $this->assertArrayHasKey('text', $formdata->summary_editor); 53 $this->assertArrayHasKey('format', $formdata->content_editor); 54 55 // Save the form. 56 $formdata->name = 'Test terms & conditions'; 57 $formdata->type = policy_version::TYPE_OTHER; 58 $policy = api::form_policydoc_add($formdata); 59 $record = $policy->to_record(); 60 61 $this->assertNotEmpty($record->id); 62 $this->assertNotEmpty($record->policyid); 63 $this->assertNotEmpty($record->timecreated); 64 $this->assertNotEmpty($record->timemodified); 65 $this->assertNotNull($record->name); 66 $this->assertNotNull($record->summary); 67 $this->assertNotNull($record->summaryformat); 68 $this->assertNotNull($record->content); 69 $this->assertNotNull($record->contentformat); 70 71 // Update the policy document version. 72 $formdata = api::form_policydoc_data($policy); 73 $formdata->revision = '*** Unit test ***'; 74 $formdata->summary_editor['text'] = '__Just a summary__'; 75 $formdata->summary_editor['format'] = FORMAT_MARKDOWN; 76 $formdata->content_editor['text'] = '### Just a test ###'; 77 $formdata->content_editor['format'] = FORMAT_MARKDOWN; 78 $updated = api::form_policydoc_update_overwrite($formdata); 79 $this->assertEquals($policy->get('id'), $updated->get('id')); 80 $this->assertEquals($policy->get('policyid'), $updated->get('policyid')); 81 82 // Save form as a new version. 83 $formdata = api::form_policydoc_data($policy); 84 $formdata->name = 'New terms & conditions'; 85 $formdata->revision = '*** Unit test 2 ***'; 86 $formdata->summary_editor['text'] = '<strong>Yet another summary</strong>'; 87 $formdata->summary_editor['format'] = FORMAT_MOODLE; 88 $formdata->content_editor['text'] = '<h3>Yet another test</h3>'; 89 $formdata->content_editor['format'] = FORMAT_HTML; 90 $new = api::form_policydoc_update_new($formdata); 91 $this->assertNotEquals($policy->get('id'), $new->get('id')); 92 $this->assertEquals($policy->get('policyid'), $new->get('policyid')); 93 94 // Add yet another policy document. 95 $formdata = api::form_policydoc_data(new policy_version(0)); 96 $formdata->name = 'Privacy terms'; 97 $formdata->type = policy_version::TYPE_PRIVACY; 98 $another = api::form_policydoc_add($formdata); 99 100 // Get the list of all policies and their versions. 101 $docs = api::list_policies(); 102 $this->assertEquals(2, count($docs)); 103 104 // Get just one policy and all its versions. 105 $docs = api::list_policies($another->get('policyid')); 106 $this->assertEquals(1, count($docs)); 107 108 // Activate a policy. 109 $this->assertEquals(0, count(api::list_current_versions())); 110 api::make_current($updated->get('id')); 111 $current = api::list_current_versions(); 112 $this->assertEquals(1, count($current)); 113 $first = reset($current); 114 $this->assertEquals('Test terms & conditions', $first->name); 115 116 // Activate another policy version. 117 api::make_current($new->get('id')); 118 $current = api::list_current_versions(); 119 $this->assertEquals(1, count($current)); 120 $first = reset($current); 121 $this->assertEquals('New terms & conditions', $first->name); 122 123 // Inactivate the policy. 124 api::inactivate($new->get('policyid')); 125 $this->assertEmpty(api::list_current_versions()); 126 $archived = api::get_policy_version($new->get('id')); 127 $this->assertEquals(policy_version::STATUS_ARCHIVED, $archived->status); 128 129 // Create a new draft from an archived version. 130 $draft = api::revert_to_draft($archived->id); 131 $draft = api::get_policy_version($draft->get('id')); 132 $archived = api::get_policy_version($archived->id); 133 $this->assertEmpty(api::list_current_versions()); 134 $this->assertNotEquals($draft->id, $archived->id); 135 $this->assertEquals(policy_version::STATUS_DRAFT, $draft->status); 136 $this->assertEquals(policy_version::STATUS_ARCHIVED, $archived->status); 137 138 // An active policy can't be set to draft. 139 api::make_current($draft->id); 140 $this->expectException('coding_exception'); 141 $this->expectExceptionMessage('Version not found or is not archived'); 142 api::revert_to_draft($draft->id); 143 } 144 145 /** 146 * Test changing the sort order of the policy documents. 147 */ 148 public function test_policy_sortorder() { 149 global $DB; 150 $this->resetAfterTest(); 151 $this->setAdminUser(); 152 153 $formdata = api::form_policydoc_data(new policy_version(0)); 154 $formdata->name = 'Policy1'; 155 $formdata->summary_editor = ['text' => 'P1 summary', 'format' => FORMAT_HTML, 'itemid' => 0]; 156 $formdata->content_editor = ['text' => 'P1 content', 'format' => FORMAT_HTML, 'itemid' => 0]; 157 $policy1 = api::form_policydoc_add($formdata); 158 $policy1sortorder = $DB->get_field('tool_policy', 'sortorder', ['id' => $policy1->get('policyid')]); 159 160 $formdata = api::form_policydoc_data(new policy_version(0)); 161 $formdata->name = 'Policy2'; 162 $formdata->summary_editor = ['text' => 'P2 summary', 'format' => FORMAT_HTML, 'itemid' => 0]; 163 $formdata->content_editor = ['text' => 'P2 content', 'format' => FORMAT_HTML, 'itemid' => 0]; 164 $policy2 = api::form_policydoc_add($formdata); 165 $policy2sortorder = $DB->get_field('tool_policy', 'sortorder', ['id' => $policy2->get('policyid')]); 166 167 $this->assertTrue($policy1sortorder < $policy2sortorder); 168 169 $formdata = api::form_policydoc_data(new policy_version(0)); 170 $formdata->name = 'Policy3'; 171 $formdata->summary_editor = ['text' => 'P3 summary', 'format' => FORMAT_HTML, 'itemid' => 0]; 172 $formdata->content_editor = ['text' => 'P3 content', 'format' => FORMAT_HTML, 'itemid' => 0]; 173 $policy3 = api::form_policydoc_add($formdata); 174 $policy3sortorder = $DB->get_field('tool_policy', 'sortorder', ['id' => $policy3->get('policyid')]); 175 176 $this->assertTrue($policy1sortorder < $policy2sortorder); 177 $this->assertTrue($policy2sortorder < $policy3sortorder); 178 179 api::move_up($policy3->get('policyid')); 180 181 $policy1sortorder = $DB->get_field('tool_policy', 'sortorder', ['id' => $policy1->get('policyid')]); 182 $policy2sortorder = $DB->get_field('tool_policy', 'sortorder', ['id' => $policy2->get('policyid')]); 183 $policy3sortorder = $DB->get_field('tool_policy', 'sortorder', ['id' => $policy3->get('policyid')]); 184 185 $this->assertTrue($policy1sortorder < $policy3sortorder); 186 $this->assertTrue($policy3sortorder < $policy2sortorder); 187 188 api::move_down($policy1->get('policyid')); 189 190 $policy1sortorder = $DB->get_field('tool_policy', 'sortorder', ['id' => $policy1->get('policyid')]); 191 $policy2sortorder = $DB->get_field('tool_policy', 'sortorder', ['id' => $policy2->get('policyid')]); 192 $policy3sortorder = $DB->get_field('tool_policy', 'sortorder', ['id' => $policy3->get('policyid')]); 193 194 $this->assertTrue($policy3sortorder < $policy1sortorder); 195 $this->assertTrue($policy1sortorder < $policy2sortorder); 196 197 $orderedlist = []; 198 foreach (api::list_policies() as $policy) { 199 $orderedlist[] = $policy->id; 200 } 201 $this->assertEquals([$policy3->get('policyid'), $policy1->get('policyid'), $policy2->get('policyid')], $orderedlist); 202 } 203 204 /** 205 * Test that list of policies can be filtered by audience 206 */ 207 public function test_list_policies_audience() { 208 $this->resetAfterTest(); 209 $this->setAdminUser(); 210 211 $policy1 = helper::add_policy(['audience' => policy_version::AUDIENCE_LOGGEDIN]); 212 $policy2 = helper::add_policy(['audience' => policy_version::AUDIENCE_GUESTS]); 213 $policy3 = helper::add_policy(); 214 215 api::make_current($policy1->get('id')); 216 api::make_current($policy2->get('id')); 217 api::make_current($policy3->get('id')); 218 219 $list = array_map(function ($version) { 220 return $version->policyid; 221 }, api::list_current_versions()); 222 $this->assertEquals([$policy1->get('policyid'), $policy2->get('policyid'), $policy3->get('policyid')], 223 array_values($list)); 224 $ids = api::get_current_versions_ids(); 225 $this->assertEquals([$policy1->get('policyid') => $policy1->get('id'), 226 $policy2->get('policyid') => $policy2->get('id'), 227 $policy3->get('policyid') => $policy3->get('id')], $ids); 228 229 $list = array_map(function ($version) { 230 return $version->policyid; 231 }, api::list_current_versions(policy_version::AUDIENCE_LOGGEDIN)); 232 $this->assertEquals([$policy1->get('policyid'), $policy3->get('policyid')], array_values($list)); 233 $ids = api::get_current_versions_ids(policy_version::AUDIENCE_LOGGEDIN); 234 $this->assertEquals([$policy1->get('policyid') => $policy1->get('id'), 235 $policy3->get('policyid') => $policy3->get('id')], $ids); 236 237 $list = array_map(function ($version) { 238 return $version->policyid; 239 }, api::list_current_versions(policy_version::AUDIENCE_GUESTS)); 240 $this->assertEquals([$policy2->get('policyid'), $policy3->get('policyid')], array_values($list)); 241 $ids = api::get_current_versions_ids(policy_version::AUDIENCE_GUESTS); 242 $this->assertEquals([$policy2->get('policyid') => $policy2->get('id'), 243 $policy3->get('policyid') => $policy3->get('id')], $ids); 244 } 245 246 /** 247 * Test behaviour of the {@link api::can_user_view_policy_version()} method. 248 */ 249 public function test_can_user_view_policy_version() { 250 global $CFG; 251 $this->resetAfterTest(); 252 $this->setAdminUser(); 253 254 $child = $this->getDataGenerator()->create_user(); 255 $parent = $this->getDataGenerator()->create_user(); 256 $this->getDataGenerator()->create_user(); 257 $officer = $this->getDataGenerator()->create_user(); 258 $manager = $this->getDataGenerator()->create_user(); 259 260 $syscontext = context_system::instance(); 261 $childcontext = context_user::instance($child->id); 262 263 $roleminorid = create_role('Digital minor', 'digiminor', 'Not old enough to accept site policies themselves'); 264 $roleparentid = create_role('Parent', 'parent', 'Can accept policies on behalf of their child'); 265 $roleofficerid = create_role('Policy officer', 'policyofficer', 'Can see all acceptances but can\'t edit policy documents'); 266 $rolemanagerid = create_role('Policy manager', 'policymanager', 'Can manage policy documents'); 267 268 assign_capability('tool/policy:accept', CAP_PROHIBIT, $roleminorid, $syscontext->id); 269 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleparentid, $syscontext->id); 270 assign_capability('tool/policy:viewacceptances', CAP_ALLOW, $roleofficerid, $syscontext->id); 271 assign_capability('tool/policy:managedocs', CAP_ALLOW, $rolemanagerid, $syscontext->id); 272 273 role_assign($roleminorid, $child->id, $syscontext->id); 274 // Becoming a parent is easy. Being a good one is difficult. 275 role_assign($roleparentid, $parent->id, $childcontext->id); 276 role_assign($roleofficerid, $officer->id, $syscontext->id); 277 role_assign($rolemanagerid, $manager->id, $syscontext->id); 278 279 accesslib_clear_all_caches_for_unit_testing(); 280 281 // Prepare a policy document with some versions. 282 list($policy1, $policy2, $policy3) = helper::create_versions(3); 283 284 // Normally users do not have access to policy drafts. 285 $this->assertFalse(api::can_user_view_policy_version($policy1, null, $child->id)); 286 $this->assertFalse(api::can_user_view_policy_version($policy2, null, $parent->id)); 287 $this->assertFalse(api::can_user_view_policy_version($policy3, null, $CFG->siteguest)); 288 289 // Officers and managers have access even to drafts. 290 $this->assertTrue(api::can_user_view_policy_version($policy1, null, $officer->id)); 291 $this->assertTrue(api::can_user_view_policy_version($policy3, null, $manager->id)); 292 293 // Current versions are public so that users can decide whether to even register on such a site. 294 api::make_current($policy2->id); 295 $policy1 = api::get_policy_version($policy1->id); 296 $policy2 = api::get_policy_version($policy2->id); 297 $policy3 = api::get_policy_version($policy3->id); 298 299 $this->assertFalse(api::can_user_view_policy_version($policy1, null, $child->id)); 300 $this->assertTrue(api::can_user_view_policy_version($policy2, null, $child->id)); 301 $this->assertTrue(api::can_user_view_policy_version($policy2, null, $CFG->siteguest)); 302 $this->assertFalse(api::can_user_view_policy_version($policy3, null, $child->id)); 303 304 // Let the parent accept the policy on behalf of her child. 305 $this->setUser($parent); 306 api::accept_policies($policy2->id, $child->id); 307 308 // Release a new version of the policy. 309 api::make_current($policy3->id); 310 $policy1 = api::get_policy_version($policy1->id); 311 $policy2 = api::get_policy_version($policy2->id); 312 $policy3 = api::get_policy_version($policy3->id); 313 314 api::get_user_minors($parent->id); 315 // They should now have access to the archived version (because they agreed) and the current one. 316 $this->assertFalse(api::can_user_view_policy_version($policy1, null, $child->id)); 317 $this->assertFalse(api::can_user_view_policy_version($policy1, null, $parent->id)); 318 $this->assertTrue(api::can_user_view_policy_version($policy2, null, $child->id)); 319 $this->assertTrue(api::can_user_view_policy_version($policy2, null, $parent->id)); 320 $this->assertTrue(api::can_user_view_policy_version($policy3, null, $child->id)); 321 $this->assertTrue(api::can_user_view_policy_version($policy3, null, $parent->id)); 322 } 323 324 /** 325 * Test behaviour of the {@link api::can_accept_policies()} method. 326 */ 327 public function test_can_accept_policies() { 328 global $CFG; 329 330 $this->resetAfterTest(); 331 $this->setAdminUser(); 332 333 $user = $this->getDataGenerator()->create_user(); 334 $child = $this->getDataGenerator()->create_user(); 335 $parent = $this->getDataGenerator()->create_user(); 336 $officer = $this->getDataGenerator()->create_user(); 337 $manager = $this->getDataGenerator()->create_user(); 338 339 $syscontext = context_system::instance(); 340 $childcontext = context_user::instance($child->id); 341 342 $roleminorid = create_role('Digital minor', 'digiminor', 'Not old enough to accept site policies themselves'); 343 $roleparentid = create_role('Parent', 'parent', 'Can accept policies on behalf of their child'); 344 $roleofficerid = create_role('Policy officer', 'policyofficer', 'Can see all acceptances but can\'t edit policy documents'); 345 $rolemanagerid = create_role('Policy manager', 'policymanager', 'Can manage policy documents'); 346 347 assign_capability('tool/policy:accept', CAP_PROHIBIT, $roleminorid, $syscontext->id); 348 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleparentid, $syscontext->id); 349 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleofficerid, $syscontext->id); 350 assign_capability('tool/policy:viewacceptances', CAP_ALLOW, $roleofficerid, $syscontext->id); 351 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $rolemanagerid, $syscontext->id); 352 assign_capability('tool/policy:managedocs', CAP_ALLOW, $rolemanagerid, $syscontext->id); 353 354 role_assign($roleminorid, $child->id, $syscontext->id); 355 role_assign($roleparentid, $parent->id, $childcontext->id); 356 role_assign($roleofficerid, $officer->id, $syscontext->id); 357 role_assign($rolemanagerid, $manager->id, $syscontext->id); 358 359 accesslib_clear_all_caches_for_unit_testing(); 360 361 $policy1 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record(); 362 $policy2 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record(); 363 $policy3 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record(); 364 $policy4 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record(); 365 366 $mixed = [$policy1->id, $policy2->id, $policy3->id, $policy4->id]; 367 $compulsory = [$policy1->id, $policy2->id]; 368 $optional = [$policy3->id, $policy4->id]; 369 370 // Normally users can accept all policies. 371 $this->setUser($user); 372 $this->assertTrue(api::can_accept_policies($mixed)); 373 $this->assertTrue(api::can_accept_policies($compulsory)); 374 $this->assertTrue(api::can_accept_policies($optional)); 375 376 // Digital minors can be set to not be able to accept policies themselves. 377 $this->setUser($child); 378 $this->assertFalse(api::can_accept_policies($mixed)); 379 $this->assertFalse(api::can_accept_policies($compulsory)); 380 $this->assertFalse(api::can_accept_policies($optional)); 381 382 // The parent can accept optional policies on child's behalf. 383 $this->setUser($parent); 384 $this->assertTrue(api::can_accept_policies($mixed, $child->id)); 385 $this->assertTrue(api::can_accept_policies($compulsory, $child->id)); 386 $this->assertTrue(api::can_accept_policies($optional, $child->id)); 387 388 // Officers and managers can accept on other user's behalf. 389 $this->setUser($officer); 390 $this->assertTrue(api::can_accept_policies($mixed, $parent->id)); 391 $this->assertTrue(api::can_accept_policies($compulsory, $parent->id)); 392 $this->assertTrue(api::can_accept_policies($optional, $parent->id)); 393 394 $this->setUser($manager); 395 $this->assertTrue(api::can_accept_policies($mixed, $parent->id)); 396 $this->assertTrue(api::can_accept_policies($compulsory, $parent->id)); 397 $this->assertTrue(api::can_accept_policies($optional, $parent->id)); 398 } 399 400 /** 401 * Test behaviour of the {@link api::can_decline_policies()} method. 402 */ 403 public function test_can_decline_policies() { 404 global $CFG; 405 406 $this->resetAfterTest(); 407 $this->setAdminUser(); 408 409 $user = $this->getDataGenerator()->create_user(); 410 $child = $this->getDataGenerator()->create_user(); 411 $parent = $this->getDataGenerator()->create_user(); 412 $officer = $this->getDataGenerator()->create_user(); 413 $manager = $this->getDataGenerator()->create_user(); 414 415 $syscontext = context_system::instance(); 416 $childcontext = context_user::instance($child->id); 417 418 $roleminorid = create_role('Digital minor', 'digiminor', 'Not old enough to accept site policies themselves'); 419 $roleparentid = create_role('Parent', 'parent', 'Can accept policies on behalf of their child'); 420 $roleofficerid = create_role('Policy officer', 'policyofficer', 'Can see all acceptances but can\'t edit policy documents'); 421 $rolemanagerid = create_role('Policy manager', 'policymanager', 'Can manage policy documents'); 422 423 assign_capability('tool/policy:accept', CAP_PROHIBIT, $roleminorid, $syscontext->id); 424 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleparentid, $syscontext->id); 425 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleofficerid, $syscontext->id); 426 assign_capability('tool/policy:viewacceptances', CAP_ALLOW, $roleofficerid, $syscontext->id); 427 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $rolemanagerid, $syscontext->id); 428 assign_capability('tool/policy:managedocs', CAP_ALLOW, $rolemanagerid, $syscontext->id); 429 430 role_assign($roleminorid, $child->id, $syscontext->id); 431 role_assign($roleparentid, $parent->id, $childcontext->id); 432 role_assign($roleofficerid, $officer->id, $syscontext->id); 433 role_assign($rolemanagerid, $manager->id, $syscontext->id); 434 435 accesslib_clear_all_caches_for_unit_testing(); 436 437 $policy1 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record(); 438 $policy2 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record(); 439 $policy3 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record(); 440 $policy4 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record(); 441 442 $mixed = [$policy1->id, $policy2->id, $policy3->id, $policy4->id]; 443 $compulsory = [$policy1->id, $policy2->id]; 444 $optional = [$policy3->id, $policy4->id]; 445 446 // Normally users can decline only optional policies. 447 $this->setUser($user); 448 $this->assertFalse(api::can_decline_policies($mixed)); 449 $this->assertFalse(api::can_decline_policies($compulsory)); 450 $this->assertTrue(api::can_decline_policies($optional)); 451 452 // If they can't accept them, they can't decline them too. 453 $this->setUser($child); 454 $this->assertFalse(api::can_decline_policies($mixed)); 455 $this->assertFalse(api::can_decline_policies($compulsory)); 456 $this->assertFalse(api::can_decline_policies($optional)); 457 458 // The parent can decline optional policies on child's behalf. 459 $this->setUser($parent); 460 $this->assertFalse(api::can_decline_policies($mixed, $child->id)); 461 $this->assertFalse(api::can_decline_policies($compulsory, $child->id)); 462 $this->assertTrue(api::can_decline_policies($optional, $child->id)); 463 464 // Even officers or managers cannot decline compulsory policies. 465 $this->setUser($officer); 466 $this->assertFalse(api::can_decline_policies($mixed)); 467 $this->assertFalse(api::can_decline_policies($compulsory)); 468 $this->assertTrue(api::can_decline_policies($optional)); 469 $this->assertFalse(api::can_decline_policies($mixed, $child->id)); 470 $this->assertFalse(api::can_decline_policies($compulsory, $child->id)); 471 $this->assertTrue(api::can_decline_policies($optional, $child->id)); 472 473 $this->setUser($manager); 474 $this->assertFalse(api::can_decline_policies($mixed)); 475 $this->assertFalse(api::can_decline_policies($compulsory)); 476 $this->assertTrue(api::can_decline_policies($optional)); 477 $this->assertFalse(api::can_decline_policies($mixed, $child->id)); 478 $this->assertFalse(api::can_decline_policies($compulsory, $child->id)); 479 $this->assertTrue(api::can_decline_policies($optional, $child->id)); 480 } 481 482 /** 483 * Test behaviour of the {@link api::can_revoke_policies()} method. 484 */ 485 public function test_can_revoke_policies() { 486 global $CFG; 487 488 $this->resetAfterTest(); 489 $this->setAdminUser(); 490 491 $user = $this->getDataGenerator()->create_user(); 492 $child = $this->getDataGenerator()->create_user(); 493 $parent = $this->getDataGenerator()->create_user(); 494 $officer = $this->getDataGenerator()->create_user(); 495 $manager = $this->getDataGenerator()->create_user(); 496 497 $syscontext = context_system::instance(); 498 $childcontext = context_user::instance($child->id); 499 500 $roleminorid = create_role('Digital minor', 'digiminor', 'Not old enough to accept site policies themselves'); 501 $roleparentid = create_role('Parent', 'parent', 'Can accept policies on behalf of their child'); 502 $roleofficerid = create_role('Policy officer', 'policyofficer', 'Can see all acceptances but can\'t edit policy documents'); 503 $rolemanagerid = create_role('Policy manager', 'policymanager', 'Can manage policy documents'); 504 505 assign_capability('tool/policy:accept', CAP_PROHIBIT, $roleminorid, $syscontext->id); 506 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleparentid, $syscontext->id); 507 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleofficerid, $syscontext->id); 508 assign_capability('tool/policy:viewacceptances', CAP_ALLOW, $roleofficerid, $syscontext->id); 509 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $rolemanagerid, $syscontext->id); 510 assign_capability('tool/policy:managedocs', CAP_ALLOW, $rolemanagerid, $syscontext->id); 511 512 role_assign($roleminorid, $child->id, $syscontext->id); 513 // Becoming a parent is easy. Being a good one is difficult. 514 role_assign($roleparentid, $parent->id, $childcontext->id); 515 role_assign($roleofficerid, $officer->id, $syscontext->id); 516 role_assign($rolemanagerid, $manager->id, $syscontext->id); 517 518 accesslib_clear_all_caches_for_unit_testing(); 519 520 $policy1 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record(); 521 $policy2 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record(); 522 523 $versionids = [$policy1->id, $policy2->id]; 524 525 // Guests cannot revoke anything. 526 $this->setGuestUser(); 527 $this->assertFalse(api::can_revoke_policies($versionids)); 528 529 // Normally users do not have access to revoke policies. 530 $this->setUser($user); 531 $this->assertFalse(api::can_revoke_policies($versionids, $user->id)); 532 $this->setUser($child); 533 $this->assertFalse(api::can_revoke_policies($versionids, $child->id)); 534 535 // Optional policies can be revoked if the user can accept them. 536 $this->setUser($user); 537 $this->assertTrue(api::can_revoke_policies([$policy2->id])); 538 $this->assertTrue(api::can_revoke_policies([$policy2->id], $user->id)); 539 $this->setUser($child); 540 $this->assertFalse(api::can_revoke_policies([$policy2->id])); 541 $this->assertFalse(api::can_revoke_policies([$policy2->id], $child->id)); 542 543 // The parent can revoke the policy on behalf of her child (but not her own policies, unless they are optional). 544 $this->setUser($parent); 545 $this->assertFalse(api::can_revoke_policies($versionids, $parent->id)); 546 $this->assertTrue(api::can_revoke_policies($versionids, $child->id)); 547 $this->assertTrue(api::can_revoke_policies([$policy2->id])); 548 $this->assertTrue(api::can_revoke_policies([$policy2->id], $child->id)); 549 550 // Officers and managers can revoke everything. 551 $this->setUser($officer); 552 $this->assertTrue(api::can_revoke_policies($versionids, $officer->id)); 553 $this->assertTrue(api::can_revoke_policies($versionids, $child->id)); 554 $this->assertTrue(api::can_revoke_policies($versionids, $parent->id)); 555 $this->assertTrue(api::can_revoke_policies($versionids, $manager->id)); 556 557 $this->setUser($manager); 558 $this->assertTrue(api::can_revoke_policies($versionids, $manager->id)); 559 $this->assertTrue(api::can_revoke_policies($versionids, $child->id)); 560 $this->assertTrue(api::can_revoke_policies($versionids, $parent->id)); 561 $this->assertTrue(api::can_revoke_policies($versionids, $officer->id)); 562 } 563 564 /** 565 * Test {@link api::fix_revision_values()} behaviour. 566 */ 567 public function test_fix_revision_values() { 568 $this->resetAfterTest(); 569 $this->setAdminUser(); 570 571 $versions = [ 572 (object) ['id' => 80, 'timecreated' => mktime(1, 1, 1, 12, 28, 2018), 'revision' => '', 'e' => '28 December 2018'], 573 (object) ['id' => 70, 'timecreated' => mktime(1, 1, 1, 12, 27, 2018), 'revision' => '', 'e' => '27 December 2018 - v2'], 574 (object) ['id' => 60, 'timecreated' => mktime(1, 1, 1, 12, 27, 2018), 'revision' => '', 'e' => '27 December 2018 - v1'], 575 (object) ['id' => 50, 'timecreated' => mktime(0, 0, 0, 12, 26, 2018), 'revision' => '0', 'e' => '0'], 576 (object) ['id' => 40, 'timecreated' => mktime(0, 0, 0, 12, 26, 2018), 'revision' => '1.1', 'e' => '1.1 - v2'], 577 (object) ['id' => 30, 'timecreated' => mktime(0, 0, 0, 12, 26, 2018), 'revision' => '1.1', 'e' => '1.1 - v1'], 578 (object) ['id' => 20, 'timecreated' => mktime(0, 0, 0, 12, 26, 2018), 'revision' => '', 'e' => '26 December 2018'], 579 (object) ['id' => 10, 'timecreated' => mktime(17, 57, 00, 12, 25, 2018), 'revision' => '1.0', 'e' => '1.0'], 580 ]; 581 582 api::fix_revision_values($versions); 583 584 foreach ($versions as $version) { 585 $this->assertSame($version->revision, $version->e); 586 } 587 } 588 589 /** 590 * Test that accepting policy updates 'policyagreed' 591 */ 592 public function test_accept_policies() { 593 global $DB; 594 $this->resetAfterTest(); 595 $this->setAdminUser(); 596 597 $policy1 = helper::add_policy()->to_record(); 598 api::make_current($policy1->id); 599 $policy2 = helper::add_policy()->to_record(); 600 api::make_current($policy2->id); 601 $policy3 = helper::add_policy(['optional' => true])->to_record(); 602 api::make_current($policy3->id); 603 604 // Accept policy on behalf of somebody else. 605 $user1 = $this->getDataGenerator()->create_user(); 606 $this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 607 608 // Accepting just compulsory policies is not enough, we want to hear explicitly about the optional one, too. 609 api::accept_policies([$policy1->id, $policy2->id], $user1->id); 610 $this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 611 612 // Optional policy does not need to be accepted, but it must be answered explicitly. 613 api::decline_policies([$policy3->id], $user1->id); 614 $this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 615 616 // Revoke previous agreement to a compulsory policy. 617 api::revoke_acceptance($policy1->id, $user1->id); 618 $this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 619 620 // Accept policies for oneself. 621 $user2 = $this->getDataGenerator()->create_user(); 622 $this->setUser($user2); 623 624 $this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user2->id])); 625 626 api::accept_policies([$policy1->id]); 627 $this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user2->id])); 628 629 api::accept_policies([$policy2->id]); 630 $this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user2->id])); 631 632 api::decline_policies([$policy3->id]); 633 $this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user2->id])); 634 635 api::accept_policies([$policy3->id]); 636 $this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user2->id])); 637 } 638 639 /** 640 * Test that activating a new policy resets everybody's policyagreed flag in the database. 641 */ 642 public function test_reset_policyagreed() { 643 global $DB; 644 $this->resetAfterTest(); 645 $this->setAdminUser(); 646 647 $user1 = $this->getDataGenerator()->create_user(); 648 649 // Introducing a new policy. 650 list($policy1v1, $policy1v2) = helper::create_versions(2); 651 api::make_current($policy1v1->id); 652 $this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 653 api::accept_policies([$policy1v1->id], $user1->id); 654 $this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 655 656 // Introducing another policy. 657 $policy2v1 = helper::add_policy()->to_record(); 658 api::make_current($policy2v1->id); 659 $this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 660 api::accept_policies([$policy2v1->id], $user1->id); 661 $this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 662 663 // Updating an existing policy (major update). 664 api::make_current($policy1v2->id); 665 $this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 666 api::accept_policies([$policy1v2->id], $user1->id); 667 $this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 668 669 // Do not touch the flag if there is no new version (e.g. a minor update). 670 api::make_current($policy2v1->id); 671 api::make_current($policy1v2->id); 672 $this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 673 674 // Do not touch the flag if inactivating a policy. 675 api::inactivate($policy1v2->policyid); 676 $this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 677 678 // Do not touch the flag if setting to draft a policy. 679 api::revert_to_draft($policy1v2->id); 680 $this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user1->id])); 681 } 682 683 /** 684 * Test behaviour of the {@link api::get_user_minors()} method. 685 */ 686 public function test_get_user_minors() { 687 $this->resetAfterTest(); 688 689 // A mother having two children, each child having own father. 690 $mother1 = $this->getDataGenerator()->create_user(); 691 $father1 = $this->getDataGenerator()->create_user(); 692 $father2 = $this->getDataGenerator()->create_user(); 693 $child1 = $this->getDataGenerator()->create_user(); 694 $child2 = $this->getDataGenerator()->create_user(); 695 696 $syscontext = context_system::instance(); 697 $child1context = context_user::instance($child1->id); 698 $child2context = context_user::instance($child2->id); 699 700 $roleparentid = create_role('Parent', 'parent', 'Can accept policies on behalf of their child'); 701 702 assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleparentid, $syscontext->id); 703 704 role_assign($roleparentid, $mother1->id, $child1context->id); 705 role_assign($roleparentid, $mother1->id, $child2context->id); 706 role_assign($roleparentid, $father1->id, $child1context->id); 707 role_assign($roleparentid, $father2->id, $child2context->id); 708 709 accesslib_clear_all_caches_for_unit_testing(); 710 711 $mother1minors = api::get_user_minors($mother1->id); 712 $this->assertEquals(2, count($mother1minors)); 713 714 $father1minors = api::get_user_minors($father1->id); 715 $this->assertEquals(1, count($father1minors)); 716 $this->assertEquals($child1->id, $father1minors[$child1->id]->id); 717 718 $father2minors = api::get_user_minors($father2->id); 719 $this->assertEquals(1, count($father2minors)); 720 $this->assertEquals($child2->id, $father2minors[$child2->id]->id); 721 722 $this->assertEmpty(api::get_user_minors($child1->id)); 723 $this->assertEmpty(api::get_user_minors($child2->id)); 724 725 $extradata = api::get_user_minors($mother1->id, ['policyagreed', 'deleted']); 726 $this->assertTrue(property_exists($extradata[$child1->id], 'policyagreed')); 727 $this->assertTrue(property_exists($extradata[$child1->id], 'deleted')); 728 $this->assertTrue(property_exists($extradata[$child2->id], 'policyagreed')); 729 $this->assertTrue(property_exists($extradata[$child2->id], 'deleted')); 730 } 731 732 /** 733 * Test behaviour of the {@link api::create_acceptances_user_created()} method. 734 */ 735 public function test_create_acceptances_user_created() { 736 global $CFG, $DB; 737 $this->resetAfterTest(); 738 $this->setAdminUser(); 739 740 $CFG->sitepolicyhandler = 'tool_policy'; 741 742 $policy = helper::add_policy()->to_record(); 743 api::make_current($policy->id); 744 745 // User has not accepted any policies. 746 $user1 = $this->getDataGenerator()->create_user(); 747 \core\event\user_created::create_from_userid($user1->id)->trigger(); 748 749 $this->assertEquals(0, $DB->count_records('tool_policy_acceptances', 750 ['userid' => $user1->id, 'policyversionid' => $policy->id])); 751 752 // User has accepted policies. 753 $user2 = $this->getDataGenerator()->create_user(); 754 $DB->set_field('user', 'policyagreed', 1, ['id' => $user2->id]); 755 \core\event\user_created::create_from_userid($user2->id)->trigger(); 756 757 $this->assertEquals(1, $DB->count_records('tool_policy_acceptances', 758 ['userid' => $user2->id, 'policyversionid' => $policy->id])); 759 } 760 761 /** 762 * Test that user can login if sitepolicyhandler is set but there are no policies. 763 */ 764 public function test_login_with_handler_without_policies() { 765 global $CFG; 766 767 $this->resetAfterTest(); 768 $user = $this->getDataGenerator()->create_user(); 769 $this->setUser($user); 770 771 $CFG->sitepolicyhandler = 'tool_policy'; 772 773 require_login(null, false, null, false, true); 774 } 775 776 /** 777 * Test the three-state logic of the value returned by {@link api::is_user_version_accepted()}. 778 */ 779 public function test_is_user_version_accepted() { 780 781 $preloadedacceptances = [ 782 4 => (object) [ 783 'policyversionid' => 4, 784 'mainuserid' => 13, 785 'status' => 1, 786 ], 787 6 => (object) [ 788 'policyversionid' => 6, 789 'mainuserid' => 13, 790 'status' => 0, 791 ], 792 ]; 793 794 $this->assertTrue(api::is_user_version_accepted(13, 4, $preloadedacceptances)); 795 $this->assertFalse(api::is_user_version_accepted(13, 6, $preloadedacceptances)); 796 $this->assertNull(api::is_user_version_accepted(13, 5, $preloadedacceptances)); 797 } 798 799 /** 800 * Test the functionality of {@link api::get_agreement_optional()}. 801 */ 802 public function test_get_agreement_optional() { 803 global $DB; 804 $this->resetAfterTest(); 805 $this->setAdminUser(); 806 807 $policy1 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record(); 808 api::make_current($policy1->id); 809 $policy2 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record(); 810 api::make_current($policy2->id); 811 812 $this->assertEquals(api::get_agreement_optional($policy1->id), policy_version::AGREEMENT_OPTIONAL); 813 $this->assertEquals(api::get_agreement_optional($policy2->id), policy_version::AGREEMENT_COMPULSORY); 814 } 815 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body