| 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 | namespace tool_policy;
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 | use externallib_advanced_testcase;
 | 
        
           |  |  | 20 | use tool_mobile\external as external_mobile;
 | 
        
           |  |  | 21 |   | 
        
           |  |  | 22 | defined('MOODLE_INTERNAL') || die();
 | 
        
           |  |  | 23 |   | 
        
           |  |  | 24 | global $CFG;
 | 
        
           |  |  | 25 |   | 
        
           |  |  | 26 | require_once($CFG->dirroot . '/webservice/tests/helpers.php');
 | 
        
           |  |  | 27 | require_once($CFG->dirroot . '/user/externallib.php');
 | 
        
           |  |  | 28 |   | 
        
           |  |  | 29 | /**
 | 
        
           |  |  | 30 |  * External policy webservice API tests.
 | 
        
           |  |  | 31 |  *
 | 
        
           |  |  | 32 |  * @package tool_policy
 | 
        
           |  |  | 33 |  * @copyright 2018 Sara Arjona <sara@moodle.com>
 | 
        
           |  |  | 34 |  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 35 |  */
 | 
        
           | 1441 | ariadna | 36 | final class externallib_test extends externallib_advanced_testcase {
 | 
        
           | 1 | efrain | 37 |   | 
        
           |  |  | 38 |     /** @var \tool_policy\policy_version $policy1 Policy document 1. */
 | 
        
           |  |  | 39 |     protected $policy1;
 | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 |     /** @var \tool_policy\policy_version $policy2 Policy document 2. */
 | 
        
           |  |  | 42 |     protected $policy2;
 | 
        
           |  |  | 43 |   | 
        
           |  |  | 44 |     /** @var \tool_policy\policy_version $policy3 Policy document 3. */
 | 
        
           |  |  | 45 |     protected $policy3;
 | 
        
           |  |  | 46 |   | 
        
           |  |  | 47 |     /** @var \stdClass $child user record. */
 | 
        
           |  |  | 48 |     protected $child;
 | 
        
           |  |  | 49 |   | 
        
           |  |  | 50 |     /** @var \stdClass $parent user record. */
 | 
        
           |  |  | 51 |     protected $parent;
 | 
        
           |  |  | 52 |   | 
        
           |  |  | 53 |     /** @var \stdClass $adult user record. */
 | 
        
           |  |  | 54 |     protected $adult;
 | 
        
           |  |  | 55 |   | 
        
           |  |  | 56 |     /**
 | 
        
           |  |  | 57 |      * Setup function- we will create some policy docs.
 | 
        
           |  |  | 58 |      */
 | 
        
           |  |  | 59 |     public function setUp(): void {
 | 
        
           | 1441 | ariadna | 60 |         parent::setUp();
 | 
        
           | 1 | efrain | 61 |         $this->resetAfterTest(true);
 | 
        
           |  |  | 62 |         $this->setAdminUser();
 | 
        
           |  |  | 63 |   | 
        
           |  |  | 64 |         // Prepare a policy document with some versions.
 | 
        
           |  |  | 65 |         $formdata = api::form_policydoc_data(new \tool_policy\policy_version(0));
 | 
        
           |  |  | 66 |         $formdata->name = 'Test policy';
 | 
        
           |  |  | 67 |         $formdata->revision = 'v1';
 | 
        
           |  |  | 68 |         $formdata->summary_editor = ['text' => 'summary', 'format' => FORMAT_HTML, 'itemid' => 0];
 | 
        
           |  |  | 69 |         $formdata->content_editor = ['text' => 'content', 'format' => FORMAT_HTML, 'itemid' => 0];
 | 
        
           |  |  | 70 |         $this->policy1 = api::form_policydoc_add($formdata);
 | 
        
           |  |  | 71 |   | 
        
           |  |  | 72 |         $formdata = api::form_policydoc_data($this->policy1);
 | 
        
           |  |  | 73 |         $formdata->revision = 'v2';
 | 
        
           |  |  | 74 |         $this->policy2 = api::form_policydoc_update_new($formdata);
 | 
        
           |  |  | 75 |   | 
        
           |  |  | 76 |         $formdata = api::form_policydoc_data($this->policy1);
 | 
        
           |  |  | 77 |         $formdata->revision = 'v3';
 | 
        
           |  |  | 78 |         $this->policy3 = api::form_policydoc_update_new($formdata);
 | 
        
           |  |  | 79 |   | 
        
           |  |  | 80 |         api::make_current($this->policy2->get('id'));
 | 
        
           |  |  | 81 |   | 
        
           |  |  | 82 |         // Create users.
 | 
        
           |  |  | 83 |         $this->child = $this->getDataGenerator()->create_user();
 | 
        
           |  |  | 84 |         $this->parent = $this->getDataGenerator()->create_user();
 | 
        
           |  |  | 85 |         $this->adult = $this->getDataGenerator()->create_user();
 | 
        
           |  |  | 86 |   | 
        
           |  |  | 87 |         $syscontext = \context_system::instance();
 | 
        
           |  |  | 88 |         $childcontext = \context_user::instance($this->child->id);
 | 
        
           |  |  | 89 |   | 
        
           |  |  | 90 |         $roleminorid = create_role('Digital minor', 'digiminor', 'Not old enough to accept site policies themselves');
 | 
        
           |  |  | 91 |         $roleparentid = create_role('Parent', 'parent', 'Can accept policies on behalf of their child');
 | 
        
           |  |  | 92 |   | 
        
           |  |  | 93 |         assign_capability('tool/policy:accept', CAP_PROHIBIT, $roleminorid, $syscontext->id);
 | 
        
           |  |  | 94 |         assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleparentid, $syscontext->id);
 | 
        
           |  |  | 95 |   | 
        
           |  |  | 96 |         role_assign($roleminorid, $this->child->id, $syscontext->id);
 | 
        
           |  |  | 97 |         role_assign($roleparentid, $this->parent->id, $childcontext->id);
 | 
        
           |  |  | 98 |     }
 | 
        
           |  |  | 99 |   | 
        
           |  |  | 100 |     /**
 | 
        
           |  |  | 101 |      * Test for the get_policy_version() function.
 | 
        
           |  |  | 102 |      */
 | 
        
           | 11 | efrain | 103 |     public function test_get_policy_version(): void {
 | 
        
           | 1 | efrain | 104 |         $this->setUser($this->adult);
 | 
        
           |  |  | 105 |   | 
        
           |  |  | 106 |         // View current policy version.
 | 
        
           |  |  | 107 |         $result = external::get_policy_version($this->policy2->get('id'));
 | 
        
           |  |  | 108 |         $result = \core_external\external_api::clean_returnvalue(external::get_policy_version_returns(), $result);
 | 
        
           |  |  | 109 |         $this->assertCount(1, $result['result']);
 | 
        
           |  |  | 110 |         $this->assertEquals($this->policy1->get('name'), $result['result']['policy']['name']);
 | 
        
           |  |  | 111 |         $this->assertEquals($this->policy1->get('content'), $result['result']['policy']['content']);
 | 
        
           |  |  | 112 |   | 
        
           |  |  | 113 |         // View draft policy version.
 | 
        
           |  |  | 114 |         $result = external::get_policy_version($this->policy3->get('id'));
 | 
        
           |  |  | 115 |         $result = \core_external\external_api::clean_returnvalue(external::get_policy_version_returns(), $result);
 | 
        
           |  |  | 116 |         $this->assertCount(0, $result['result']);
 | 
        
           |  |  | 117 |         $this->assertCount(1, $result['warnings']);
 | 
        
           |  |  | 118 |         $this->assertEquals(array_pop($result['warnings'])['warningcode'], 'errorusercantviewpolicyversion');
 | 
        
           |  |  | 119 |   | 
        
           |  |  | 120 |         // Add test for non existing versionid.
 | 
        
           |  |  | 121 |         $result = external::get_policy_version(999);
 | 
        
           |  |  | 122 |         $result = \core_external\external_api::clean_returnvalue(external::get_policy_version_returns(), $result);
 | 
        
           |  |  | 123 |         $this->assertCount(0, $result['result']);
 | 
        
           |  |  | 124 |         $this->assertCount(1, $result['warnings']);
 | 
        
           |  |  | 125 |         $this->assertEquals(array_pop($result['warnings'])['warningcode'], 'errorpolicyversionnotfound');
 | 
        
           |  |  | 126 |   | 
        
           |  |  | 127 |         // View previous non-accepted version in behalf of a child.
 | 
        
           |  |  | 128 |         $this->setUser($this->parent);
 | 
        
           |  |  | 129 |         $result = external::get_policy_version($this->policy1->get('id'), $this->child->id);
 | 
        
           |  |  | 130 |         $result = \core_external\external_api::clean_returnvalue(external::get_policy_version_returns(), $result);
 | 
        
           |  |  | 131 |         $this->assertCount(0, $result['result']);
 | 
        
           |  |  | 132 |         $this->assertCount(1, $result['warnings']);
 | 
        
           |  |  | 133 |         $this->assertEquals(array_pop($result['warnings'])['warningcode'], 'errorusercantviewpolicyversion');
 | 
        
           |  |  | 134 |   | 
        
           |  |  | 135 |         // Let the parent accept the policy on behalf of her child and view it again.
 | 
        
           |  |  | 136 |         api::accept_policies($this->policy1->get('id'), $this->child->id);
 | 
        
           |  |  | 137 |         $result = external::get_policy_version($this->policy1->get('id'), $this->child->id);
 | 
        
           |  |  | 138 |         $result = \core_external\external_api::clean_returnvalue(external::get_policy_version_returns(), $result);
 | 
        
           |  |  | 139 |         $this->assertCount(1, $result['result']);
 | 
        
           |  |  | 140 |         $this->assertEquals($this->policy1->get('name'), $result['result']['policy']['name']);
 | 
        
           |  |  | 141 |         $this->assertEquals($this->policy1->get('content'), $result['result']['policy']['content']);
 | 
        
           |  |  | 142 |   | 
        
           |  |  | 143 |         // Only parent is able to view the child policy version accepted by her child.
 | 
        
           |  |  | 144 |         $this->setUser($this->adult);
 | 
        
           |  |  | 145 |         $result = external::get_policy_version($this->policy1->get('id'), $this->child->id);
 | 
        
           |  |  | 146 |         $result = \core_external\external_api::clean_returnvalue(external::get_policy_version_returns(), $result);
 | 
        
           |  |  | 147 |         $this->assertCount(0, $result['result']);
 | 
        
           |  |  | 148 |         $this->assertCount(1, $result['warnings']);
 | 
        
           |  |  | 149 |         $this->assertEquals(array_pop($result['warnings'])['warningcode'], 'errorusercantviewpolicyversion');
 | 
        
           |  |  | 150 |     }
 | 
        
           |  |  | 151 |   | 
        
           |  |  | 152 |     /**
 | 
        
           |  |  | 153 |      * Test tool_mobile\external callback to site_policy_handler.
 | 
        
           |  |  | 154 |      */
 | 
        
           | 11 | efrain | 155 |     public function test_get_config_with_site_policy_handler(): void {
 | 
        
           | 1 | efrain | 156 |         global $CFG;
 | 
        
           |  |  | 157 |   | 
        
           |  |  | 158 |         $this->resetAfterTest(true);
 | 
        
           |  |  | 159 |   | 
        
           |  |  | 160 |         // Set the handler for the site policy, make sure it substitutes link to the sitepolicy.
 | 
        
           |  |  | 161 |         $CFG->sitepolicyhandler = 'tool_policy';
 | 
        
           |  |  | 162 |         $sitepolicymanager = new \core_privacy\local\sitepolicy\manager();
 | 
        
           |  |  | 163 |         $result = external_mobile::get_config();
 | 
        
           |  |  | 164 |         $result = \core_external\external_api::clean_returnvalue(external_mobile::get_config_returns(), $result);
 | 
        
           |  |  | 165 |         $toolsitepolicy = $sitepolicymanager->get_embed_url();
 | 
        
           |  |  | 166 |         foreach (array_values($result['settings']) as $r) {
 | 
        
           |  |  | 167 |             if ($r['name'] == 'sitepolicy') {
 | 
        
           |  |  | 168 |                 $configsitepolicy = $r['value'];
 | 
        
           |  |  | 169 |             }
 | 
        
           |  |  | 170 |         }
 | 
        
           |  |  | 171 |         $this->assertEquals($toolsitepolicy, $configsitepolicy);
 | 
        
           |  |  | 172 |     }
 | 
        
           |  |  | 173 |   | 
        
           |  |  | 174 |     /**
 | 
        
           |  |  | 175 |      * Test for core_privacy\sitepolicy\manager::accept() when site policy handler is set.
 | 
        
           |  |  | 176 |      */
 | 
        
           | 11 | efrain | 177 |     public function test_agree_site_policy_with_handler(): void {
 | 
        
           | 1 | efrain | 178 |         global $CFG, $DB, $USER;
 | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 |         $this->resetAfterTest(true);
 | 
        
           |  |  | 181 |         $user = self::getDataGenerator()->create_user();
 | 
        
           |  |  | 182 |         $this->setUser($user);
 | 
        
           |  |  | 183 |   | 
        
           |  |  | 184 |         // Set mock site policy handler. See function tool_phpunit_site_policy_handler() below.
 | 
        
           |  |  | 185 |         $CFG->sitepolicyhandler = 'tool_policy';
 | 
        
           |  |  | 186 |         $this->assertEquals(0, $USER->policyagreed);
 | 
        
           |  |  | 187 |         $sitepolicymanager = new \core_privacy\local\sitepolicy\manager();
 | 
        
           |  |  | 188 |   | 
        
           |  |  | 189 |         // Make sure user can not login.
 | 
        
           |  |  | 190 |         $toolconsentpage = $sitepolicymanager->get_redirect_url();
 | 
        
           |  |  | 191 |         $this->expectException(\moodle_exception::class);
 | 
        
           |  |  | 192 |         $this->expectExceptionMessage(get_string('sitepolicynotagreed', 'error', $toolconsentpage->out()));
 | 
        
           |  |  | 193 |         \core_user_external::validate_context(\context_system::instance());
 | 
        
           |  |  | 194 |   | 
        
           |  |  | 195 |         // Call WS to agree to the site policy. It will call tool_policy handler.
 | 
        
           |  |  | 196 |         $result = \core_user_external::agree_site_policy();
 | 
        
           |  |  | 197 |         $result = \core_external\external_api::clean_returnvalue(\core_user_external::agree_site_policy_returns(), $result);
 | 
        
           |  |  | 198 |         $this->assertTrue($result['status']);
 | 
        
           |  |  | 199 |         $this->assertCount(0, $result['warnings']);
 | 
        
           |  |  | 200 |         $this->assertEquals(1, $USER->policyagreed);
 | 
        
           |  |  | 201 |         $this->assertEquals(1, $DB->get_field('user', 'policyagreed', array('id' => $USER->id)));
 | 
        
           |  |  | 202 |   | 
        
           |  |  | 203 |         // Try again, we should get a warning.
 | 
        
           |  |  | 204 |         $result = \core_user_external::agree_site_policy();
 | 
        
           |  |  | 205 |         $result = \core_external\external_api::clean_returnvalue(\core_user_external::agree_site_policy_returns(), $result);
 | 
        
           |  |  | 206 |         $this->assertFalse($result['status']);
 | 
        
           |  |  | 207 |         $this->assertCount(1, $result['warnings']);
 | 
        
           |  |  | 208 |         $this->assertEquals('alreadyagreed', $result['warnings'][0]['warningcode']);
 | 
        
           |  |  | 209 |     }
 | 
        
           |  |  | 210 |   | 
        
           |  |  | 211 |     /**
 | 
        
           |  |  | 212 |      * Test for core_privacy\sitepolicy\manager::accept() when site policy handler is set.
 | 
        
           |  |  | 213 |      */
 | 
        
           | 11 | efrain | 214 |     public function test_checkcanaccept_with_handler(): void {
 | 
        
           | 1 | efrain | 215 |         global $CFG;
 | 
        
           |  |  | 216 |   | 
        
           |  |  | 217 |         $this->resetAfterTest(true);
 | 
        
           |  |  | 218 |         $CFG->sitepolicyhandler = 'tool_policy';
 | 
        
           |  |  | 219 |         $syscontext = \context_system::instance();
 | 
        
           |  |  | 220 |         $sitepolicymanager = new \core_privacy\local\sitepolicy\manager();
 | 
        
           |  |  | 221 |   | 
        
           |  |  | 222 |         $adult = $this->getDataGenerator()->create_user();
 | 
        
           |  |  | 223 |   | 
        
           |  |  | 224 |         $child = $this->getDataGenerator()->create_user();
 | 
        
           |  |  | 225 |         $rolechildid = create_role('Child', 'child', 'Not old enough to accept site policies themselves');
 | 
        
           |  |  | 226 |         assign_capability('tool/policy:accept', CAP_PROHIBIT, $rolechildid, $syscontext->id);
 | 
        
           |  |  | 227 |         role_assign($rolechildid, $child->id, $syscontext->id);
 | 
        
           |  |  | 228 |   | 
        
           |  |  | 229 |         // Default user can accept policies.
 | 
        
           |  |  | 230 |         $this->setUser($adult);
 | 
        
           |  |  | 231 |         $result = external_mobile::get_config();
 | 
        
           |  |  | 232 |         $result = \core_external\external_api::clean_returnvalue(external_mobile::get_config_returns(), $result);
 | 
        
           |  |  | 233 |         $toolsitepolicy = $sitepolicymanager->accept();
 | 
        
           |  |  | 234 |         $this->assertTrue($toolsitepolicy);
 | 
        
           |  |  | 235 |   | 
        
           |  |  | 236 |         // Child user can not accept policies.
 | 
        
           |  |  | 237 |         $this->setUser($child);
 | 
        
           |  |  | 238 |         $result = external_mobile::get_config();
 | 
        
           |  |  | 239 |         $result = \core_external\external_api::clean_returnvalue(external_mobile::get_config_returns(), $result);
 | 
        
           |  |  | 240 |         $this->expectException(\required_capability_exception::class);
 | 
        
           |  |  | 241 |         $sitepolicymanager->accept();
 | 
        
           |  |  | 242 |     }
 | 
        
           |  |  | 243 |   | 
        
           |  |  | 244 |     /**
 | 
        
           |  |  | 245 |      * Test for external function get_user_acceptances().
 | 
        
           |  |  | 246 |      */
 | 
        
           | 11 | efrain | 247 |     public function test_external_get_user_acceptances(): void {
 | 
        
           | 1 | efrain | 248 |         global $CFG;
 | 
        
           |  |  | 249 |   | 
        
           |  |  | 250 |         $this->resetAfterTest(true);
 | 
        
           |  |  | 251 |         $CFG->sitepolicyhandler = 'tool_policy';
 | 
        
           |  |  | 252 |         $user = $this->getDataGenerator()->create_user();
 | 
        
           |  |  | 253 |         $this->setUser($user);
 | 
        
           |  |  | 254 |   | 
        
           |  |  | 255 |         // Create optional policy.
 | 
        
           |  |  | 256 |         $formdata = api::form_policydoc_data(new \tool_policy\policy_version(0));
 | 
        
           |  |  | 257 |         $formdata->name = 'Test optional policy';
 | 
        
           |  |  | 258 |         $formdata->revision = 'v1';
 | 
        
           |  |  | 259 |         $formdata->optional = 1;
 | 
        
           |  |  | 260 |         $formdata->summary_editor = ['text' => 'summary', 'format' => FORMAT_HTML, 'itemid' => 0];
 | 
        
           |  |  | 261 |         $formdata->content_editor = ['text' => 'content', 'format' => FORMAT_HTML, 'itemid' => 0];
 | 
        
           |  |  | 262 |         $optionalpolicy = api::form_policydoc_add($formdata);
 | 
        
           |  |  | 263 |         api::make_current($optionalpolicy->get('id'));
 | 
        
           |  |  | 264 |         // Accept this version.
 | 
        
           |  |  | 265 |         api::accept_policies([$optionalpolicy->get('id')], $user->id, null);
 | 
        
           |  |  | 266 |         // Generate new version.
 | 
        
           |  |  | 267 |         $formdata = api::form_policydoc_data($optionalpolicy);
 | 
        
           |  |  | 268 |         $formdata->revision = 'v2';
 | 
        
           |  |  | 269 |         $optionalpolicynew = api::form_policydoc_update_new($formdata);
 | 
        
           |  |  | 270 |         api::make_current($optionalpolicynew->get('id'));
 | 
        
           |  |  | 271 |   | 
        
           |  |  | 272 |         // Now return all policies the user should be able to see, including previous versions of existing policies, if accepted/declined.
 | 
        
           |  |  | 273 |         $policies = \tool_policy\external\get_user_acceptances::execute();
 | 
        
           |  |  | 274 |         $policies = \core_external\external_api::clean_returnvalue(
 | 
        
           |  |  | 275 |             \tool_policy\external\get_user_acceptances::execute_returns(), $policies);
 | 
        
           |  |  | 276 |   | 
        
           |  |  | 277 |         $this->assertCount(3, $policies['policies']);
 | 
        
           |  |  | 278 |         $this->assertCount(0, $policies['warnings']);
 | 
        
           |  |  | 279 |         foreach ($policies['policies'] as $policy) {
 | 
        
           |  |  | 280 |             if ($policy['versionid'] == $this->policy2->get('id')) {
 | 
        
           |  |  | 281 |                 $this->assertEquals($this->policy2->get('name'), $policy['name']);
 | 
        
           |  |  | 282 |                 $this->assertEquals(0, $policy['optional']);
 | 
        
           |  |  | 283 |                 $this->assertTrue($policy['canaccept']);
 | 
        
           |  |  | 284 |                 $this->assertFalse($policy['candecline']);  // Cannot decline or revoke mandatory for myself.
 | 
        
           |  |  | 285 |                 $this->assertFalse($policy['canrevoke']);
 | 
        
           |  |  | 286 |             } else {
 | 
        
           |  |  | 287 |                 $this->assertEquals($optionalpolicy->get('name'), $policy['name']);
 | 
        
           |  |  | 288 |                 $this->assertEquals(1, $policy['optional']);
 | 
        
           |  |  | 289 |                 $this->assertTrue($policy['canaccept']);
 | 
        
           |  |  | 290 |                 $this->assertTrue($policy['candecline']);   // Can decline or revoke optional for myself.
 | 
        
           |  |  | 291 |                 $this->assertTrue($policy['canrevoke']);
 | 
        
           |  |  | 292 |             }
 | 
        
           |  |  | 293 |             $this->assertNotContains('acceptance', $policy);    // Nothing accepted yet.
 | 
        
           |  |  | 294 |         }
 | 
        
           |  |  | 295 |   | 
        
           |  |  | 296 |         // Get other user acceptances.
 | 
        
           |  |  | 297 |         $this->parent->policyagreed = 1;
 | 
        
           |  |  | 298 |         $this->setUser($this->parent);
 | 
        
           |  |  | 299 |         $policies = \tool_policy\external\get_user_acceptances::execute($this->child->id);
 | 
        
           |  |  | 300 |         $policies = \core_external\external_api::clean_returnvalue(
 | 
        
           |  |  | 301 |             \tool_policy\external\get_user_acceptances::execute_returns(), $policies);
 | 
        
           |  |  | 302 |         $this->assertCount(2, $policies['policies']);
 | 
        
           |  |  | 303 |         foreach ($policies['policies'] as $policy) {
 | 
        
           |  |  | 304 |             if ($policy['versionid'] == $this->policy2->get('id')) {
 | 
        
           |  |  | 305 |                 $this->assertTrue($policy['canaccept']);
 | 
        
           |  |  | 306 |                 $this->assertFalse($policy['candecline']);  // Cannot decline mandatory in general.
 | 
        
           |  |  | 307 |                 $this->assertTrue($policy['canrevoke']);
 | 
        
           |  |  | 308 |             } else {
 | 
        
           |  |  | 309 |                 $this->assertTrue($policy['canaccept']);
 | 
        
           |  |  | 310 |                 $this->assertTrue($policy['candecline']);
 | 
        
           |  |  | 311 |                 $this->assertTrue($policy['canrevoke']);
 | 
        
           |  |  | 312 |             }
 | 
        
           |  |  | 313 |             $this->assertNotContains('acceptance', $policy);    // Nothing accepted yet.
 | 
        
           |  |  | 314 |         }
 | 
        
           |  |  | 315 |   | 
        
           |  |  | 316 |         // Get other user acceptances without permission.
 | 
        
           |  |  | 317 |         $this->expectException(\required_capability_exception::class);
 | 
        
           |  |  | 318 |         $policies = \tool_policy\external\get_user_acceptances::execute($user->id);
 | 
        
           |  |  | 319 |     }
 | 
        
           |  |  | 320 |   | 
        
           |  |  | 321 |     /**
 | 
        
           |  |  | 322 |      * Test for external function set_acceptances_status().
 | 
        
           |  |  | 323 |      */
 | 
        
           | 11 | efrain | 324 |     public function test_external_set_acceptances_status(): void {
 | 
        
           | 1 | efrain | 325 |         global $CFG;
 | 
        
           |  |  | 326 |   | 
        
           |  |  | 327 |         $this->resetAfterTest(true);
 | 
        
           |  |  | 328 |         $CFG->sitepolicyhandler = 'tool_policy';
 | 
        
           |  |  | 329 |         $user = $this->getDataGenerator()->create_user();
 | 
        
           |  |  | 330 |         $this->setUser($user);
 | 
        
           |  |  | 331 |   | 
        
           |  |  | 332 |         // Create optional policy.
 | 
        
           |  |  | 333 |         $formdata = api::form_policydoc_data(new \tool_policy\policy_version(0));
 | 
        
           |  |  | 334 |         $formdata->name = 'Test optional policy';
 | 
        
           |  |  | 335 |         $formdata->revision = 'v1';
 | 
        
           |  |  | 336 |         $formdata->optional = 1;
 | 
        
           |  |  | 337 |         $formdata->summary_editor = ['text' => 'summary', 'format' => FORMAT_HTML, 'itemid' => 0];
 | 
        
           |  |  | 338 |         $formdata->content_editor = ['text' => 'content', 'format' => FORMAT_HTML, 'itemid' => 0];
 | 
        
           |  |  | 339 |         $optionalpolicy = api::form_policydoc_add($formdata);
 | 
        
           |  |  | 340 |         api::make_current($optionalpolicy->get('id'));
 | 
        
           |  |  | 341 |         // Decline this version.
 | 
        
           |  |  | 342 |         api::decline_policies([$optionalpolicy->get('id')], $user->id, null);
 | 
        
           |  |  | 343 |         // Generate new version and make it current.
 | 
        
           |  |  | 344 |         $formdata = api::form_policydoc_data($optionalpolicy);
 | 
        
           |  |  | 345 |         $formdata->revision = 'v2';
 | 
        
           |  |  | 346 |         $optionalpolicynew = api::form_policydoc_update_new($formdata);
 | 
        
           |  |  | 347 |         api::make_current($optionalpolicynew->get('id'));
 | 
        
           |  |  | 348 |   | 
        
           |  |  | 349 |         // Accept all the current policies.
 | 
        
           |  |  | 350 |         $ids = [
 | 
        
           |  |  | 351 |             ['versionid' => $this->policy2->get('id'), 'status' => 1],
 | 
        
           |  |  | 352 |             ['versionid' => $optionalpolicynew->get('id'), 'status' => 1],
 | 
        
           |  |  | 353 |         ];
 | 
        
           |  |  | 354 |   | 
        
           |  |  | 355 |         $policies = \tool_policy\external\set_acceptances_status::execute($ids);
 | 
        
           |  |  | 356 |         $policies = \core_external\external_api::clean_returnvalue(
 | 
        
           |  |  | 357 |             \tool_policy\external\set_acceptances_status::execute_returns(), $policies);
 | 
        
           |  |  | 358 |   | 
        
           |  |  | 359 |         $this->assertEquals(1, $policies['policyagreed']);
 | 
        
           |  |  | 360 |         $this->assertCount(0, $policies['warnings']);
 | 
        
           |  |  | 361 |   | 
        
           |  |  | 362 |         // And now accept and old one.
 | 
        
           |  |  | 363 |         $ids = [['versionid' => $optionalpolicy->get('id'), 'status' => 1, 'note' => 'I accept for me.']];  // The note will be ignored.
 | 
        
           |  |  | 364 |         $policies = \tool_policy\external\set_acceptances_status::execute($ids);
 | 
        
           |  |  | 365 |         $policies = \core_external\external_api::clean_returnvalue(
 | 
        
           |  |  | 366 |             \tool_policy\external\set_acceptances_status::execute_returns(), $policies);
 | 
        
           |  |  | 367 |   | 
        
           |  |  | 368 |         // Retrieve and check all are accepted now.
 | 
        
           |  |  | 369 |         $policies = \tool_policy\external\get_user_acceptances::execute();
 | 
        
           |  |  | 370 |         $policies = \core_external\external_api::clean_returnvalue(
 | 
        
           |  |  | 371 |             \tool_policy\external\get_user_acceptances::execute_returns(), $policies);
 | 
        
           |  |  | 372 |   | 
        
           |  |  | 373 |         $this->assertCount(3, $policies['policies']);
 | 
        
           |  |  | 374 |         foreach ($policies['policies'] as $policy) {
 | 
        
           |  |  | 375 |             $this->assertEquals(1, $policy['acceptance']['status']);    // Check all accepted.
 | 
        
           |  |  | 376 |             $this->assertEmpty($policy['acceptance']['note']);  // The note was not recorded because it was for itself.
 | 
        
           |  |  | 377 |         }
 | 
        
           |  |  | 378 |   | 
        
           |  |  | 379 |         // Decline optional only.
 | 
        
           |  |  | 380 |         $policies = \tool_policy\external\set_acceptances_status::execute([['versionid' => $optionalpolicynew->get('id'), 'status' => 0]]);
 | 
        
           |  |  | 381 |         $policies = \core_external\external_api::clean_returnvalue(
 | 
        
           |  |  | 382 |             \tool_policy\external\set_acceptances_status::execute_returns(), $policies);
 | 
        
           |  |  | 383 |   | 
        
           |  |  | 384 |         $this->assertEquals(1, $policies['policyagreed']);
 | 
        
           |  |  | 385 |         $this->assertCount(0, $policies['warnings']);
 | 
        
           |  |  | 386 |   | 
        
           |  |  | 387 |         $policies = \tool_policy\external\get_user_acceptances::execute();
 | 
        
           |  |  | 388 |         $policies = \core_external\external_api::clean_returnvalue(
 | 
        
           |  |  | 389 |             \tool_policy\external\get_user_acceptances::execute_returns(), $policies);
 | 
        
           |  |  | 390 |   | 
        
           |  |  | 391 |         $this->assertCount(3, $policies['policies']);
 | 
        
           |  |  | 392 |         foreach ($policies['policies'] as $policy) {
 | 
        
           |  |  | 393 |             if ($policy['versionid'] == $optionalpolicynew->get('id')) {
 | 
        
           |  |  | 394 |                 $this->assertEquals(0, $policy['acceptance']['status']);    // Not accepted.
 | 
        
           |  |  | 395 |             } else {
 | 
        
           |  |  | 396 |                 $this->assertEquals(1, $policy['acceptance']['status']);    // Accepted.
 | 
        
           |  |  | 397 |             }
 | 
        
           |  |  | 398 |         }
 | 
        
           |  |  | 399 |   | 
        
           |  |  | 400 |         // Parent & child case now. Accept the optional ONLY on behalf of someone else.
 | 
        
           |  |  | 401 |         $this->parent->policyagreed = 1;
 | 
        
           |  |  | 402 |         $this->setUser($this->parent);
 | 
        
           |  |  | 403 |         $notetext = 'I accept this on behalf of my child Santiago.';
 | 
        
           |  |  | 404 |         $policies = \tool_policy\external\set_acceptances_status::execute(
 | 
        
           |  |  | 405 |             [['versionid' => $optionalpolicynew->get('id'), 'status' => 1, 'note' => $notetext]], $this->child->id);
 | 
        
           |  |  | 406 |         $policies = \core_external\external_api::clean_returnvalue(
 | 
        
           |  |  | 407 |             \tool_policy\external\set_acceptances_status::execute_returns(), $policies);
 | 
        
           |  |  | 408 |   | 
        
           |  |  | 409 |         $this->assertEquals(0, $policies['policyagreed']);  // Mandatory missing.
 | 
        
           |  |  | 410 |         $this->assertCount(0, $policies['warnings']);
 | 
        
           |  |  | 411 |   | 
        
           |  |  | 412 |         $policies = \tool_policy\external\get_user_acceptances::execute($this->child->id);
 | 
        
           |  |  | 413 |         $policies = \core_external\external_api::clean_returnvalue(
 | 
        
           |  |  | 414 |             \tool_policy\external\get_user_acceptances::execute_returns(), $policies);
 | 
        
           |  |  | 415 |   | 
        
           |  |  | 416 |         $this->assertCount(2, $policies['policies']);
 | 
        
           |  |  | 417 |         foreach ($policies['policies'] as $policy) {
 | 
        
           |  |  | 418 |             if ($policy['versionid'] == $this->policy2->get('id')) {
 | 
        
           |  |  | 419 |                 $this->assertNotContains('acceptance', $policy);    // Not yet accepted.
 | 
        
           |  |  | 420 |                 $this->assertArrayNotHasKey('acceptance', $policy);
 | 
        
           |  |  | 421 |             } else {
 | 
        
           |  |  | 422 |                 $this->assertEquals(1, $policy['acceptance']['status']);    // Accepted.
 | 
        
           |  |  | 423 |                 $this->assertEquals($notetext, $policy['acceptance']['note']);
 | 
        
           |  |  | 424 |             }
 | 
        
           |  |  | 425 |         }
 | 
        
           |  |  | 426 |   | 
        
           |  |  | 427 |         // Try to accept on behalf of other user with no permissions.
 | 
        
           |  |  | 428 |         $this->expectException(\required_capability_exception::class);
 | 
        
           |  |  | 429 |         $policies = \tool_policy\external\set_acceptances_status::execute([['versionid' => $optionalpolicynew->get('id'), 'status' => 1]], $user->id);
 | 
        
           |  |  | 430 |     }
 | 
        
           |  |  | 431 |   | 
        
           |  |  | 432 |     /**
 | 
        
           |  |  | 433 |      * Test for external function set_acceptances_status decline mandatory.
 | 
        
           |  |  | 434 |      */
 | 
        
           | 11 | efrain | 435 |     public function test_external_set_acceptances_status_decline_mandatory(): void {
 | 
        
           | 1 | efrain | 436 |         global $CFG;
 | 
        
           |  |  | 437 |   | 
        
           |  |  | 438 |         $this->resetAfterTest(true);
 | 
        
           |  |  | 439 |         $CFG->sitepolicyhandler = 'tool_policy';
 | 
        
           |  |  | 440 |         $this->parent->policyagreed = 1;
 | 
        
           |  |  | 441 |         $this->setUser($this->parent);
 | 
        
           |  |  | 442 |   | 
        
           |  |  | 443 |         $this->expectException(\moodle_exception::class);
 | 
        
           |  |  | 444 |         $this->expectExceptionMessage(get_string('errorpolicyversioncompulsory', 'tool_policy'));
 | 
        
           |  |  | 445 |         $ids = [['versionid' => $this->policy2->get('id'), 'status' => 0]];
 | 
        
           |  |  | 446 |         $policies = \tool_policy\external\set_acceptances_status::execute($ids, $this->child->id);
 | 
        
           |  |  | 447 |     }
 | 
        
           |  |  | 448 | }
 |