Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

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