Proyectos de Subversion Moodle

Rev

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