Proyectos de Subversion Moodle

Rev

Rev 11 | | 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
 */
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
}