Merge branch 'MDL-81007-master' of https://github.com/jleyva/moodle

This commit is contained in:
Sara Arjona 2024-03-14 10:37:43 +01:00
commit 4b5f957743
No known key found for this signature in database
3 changed files with 91 additions and 21 deletions

View File

@ -118,6 +118,11 @@ class get_user_acceptances extends external_api {
[$policy['acceptance']['note']] = util::format_text($version->acceptance->note, FORMAT_MOODLE, $systemcontext);
}
}
// Return permission for actions for the current policy and user.
$policy['canaccept'] = api::can_accept_policies([$version->id], $user->id);
$policy['candecline'] = api::can_decline_policies([$version->id], $user->id);
$policy['canrevoke'] = api::can_revoke_policies([$version->id], $user->id);
$policies[] = $policy;
}
}
@ -157,6 +162,9 @@ class get_user_acceptances extends external_api {
'note' => new external_value(PARAM_TEXT, 'The policy note/remarks.', VALUE_OPTIONAL),
'modfullname' => new external_value(PARAM_NOTAGS, 'The fullname who accepted on behalf.', VALUE_OPTIONAL),
], 'Acceptance status for the given user.', VALUE_OPTIONAL),
'canaccept' => new external_value(PARAM_BOOL, 'Whether the policy can be accepted.'),
'candecline' => new external_value(PARAM_BOOL, 'Whether the policy can be declined.'),
'canrevoke' => new external_value(PARAM_BOOL, 'Whether the policy can be revoked.'),
]), 'Policies and acceptance status for the given user.', VALUE_OPTIONAL
),
'warnings' => new external_warnings(),

View File

@ -48,11 +48,14 @@ class set_acceptances_status extends external_api {
new external_single_structure([
'versionid' => new external_value(PARAM_INT, 'The policy version id.'),
'status' => new external_value(PARAM_INT, 'The policy acceptance status. 0: decline, 1: accept.'),
'note' => new external_value(PARAM_NOTAGS,
'Any comments added by a user when giving consent on behalf of another user.', VALUE_OPTIONAL, null),
]), 'Policies acceptances for the given user.'
),
'userid' => new external_value(PARAM_INT,
'The user id we want to set the acceptances. Default is the current user.', VALUE_DEFAULT, 0
),
]
);
}
@ -91,18 +94,25 @@ class set_acceptances_status extends external_api {
}
// Split acceptances.
$allcurrentpolicies = api::list_current_versions(policy_version::AUDIENCE_LOGGEDIN);
$requestedpolicies = $agreepolicies = $declinepolicies = [];
$requestedpolicies = $agreepolicies = $declinepolicies = $notes = [];
foreach ($params['policies'] as $policy) {
$requestedpolicies[$policy['versionid']] = $policy['status'];
if ($USER->id != $user->id) {
// Notes are only allowed when setting acceptances on behalf of another user.
$notes[$policy['versionid']] = $policy['note'] ?? null;
}
}
foreach ($allcurrentpolicies as $policy) {
if (isset($requestedpolicies[$policy->id])) {
if ($requestedpolicies[$policy->id] === 1) {
$agreepolicies[] = $policy->id;
} else if ($requestedpolicies[$policy->id] === 0) {
$declinepolicies[] = $policy->id;
// Retrieve all policies and their acceptances.
$allpolicies = api::get_policies_with_acceptances($user->id);
foreach ($allpolicies as $policy) {
foreach ($policy->versions as $version) {
if (isset($requestedpolicies[$version->id])) {
if ($requestedpolicies[$version->id] === 1) {
$agreepolicies[] = $version->id;
} else if ($requestedpolicies[$version->id] === 0) {
$declinepolicies[] = $version->id;
}
}
}
}
@ -112,8 +122,12 @@ class set_acceptances_status extends external_api {
api::can_decline_policies($declinepolicies, $user->id, true);
// Good to go.
api::accept_policies($agreepolicies, $user->id, null);
api::decline_policies($declinepolicies, $user->id, null);
foreach ($agreepolicies as $policyversionid) {
api::accept_policies($policyversionid, $user->id, $notes[$policyversionid] ?? null);
}
foreach ($declinepolicies as $policyversionid) {
api::decline_policies($policyversionid, $user->id, $notes[$policyversionid] ?? null);
}
$return = [
'policyagreed' => (int) $user->policyagreed, // Final policy agreement status for $user.

View File

@ -260,20 +260,34 @@ class externallib_test extends externallib_advanced_testcase {
$formdata->content_editor = ['text' => 'content', 'format' => FORMAT_HTML, 'itemid' => 0];
$optionalpolicy = api::form_policydoc_add($formdata);
api::make_current($optionalpolicy->get('id'));
// Accept this version.
api::accept_policies([$optionalpolicy->get('id')], $user->id, null);
// Generate new version.
$formdata = api::form_policydoc_data($optionalpolicy);
$formdata->revision = 'v2';
$optionalpolicynew = api::form_policydoc_update_new($formdata);
api::make_current($optionalpolicynew->get('id'));
// Now return all policies the user should be able to see, including previous versions of existing policies, if accepted/declined.
$policies = \tool_policy\external\get_user_acceptances::execute();
$policies = \core_external\external_api::clean_returnvalue(
\tool_policy\external\get_user_acceptances::execute_returns(), $policies);
$this->assertCount(2, $policies['policies']);
$this->assertCount(3, $policies['policies']);
$this->assertCount(0, $policies['warnings']);
foreach ($policies['policies'] as $policy) {
if ($policy['versionid'] == $this->policy2->get('id')) {
$this->assertEquals($this->policy2->get('name'), $policy['name']);
$this->assertEquals(0, $policy['optional']);
$this->assertTrue($policy['canaccept']);
$this->assertFalse($policy['candecline']); // Cannot decline or revoke mandatory for myself.
$this->assertFalse($policy['canrevoke']);
} else {
$this->assertEquals($optionalpolicy->get('name'), $policy['name']);
$this->assertEquals(1, $policy['optional']);
$this->assertTrue($policy['canaccept']);
$this->assertTrue($policy['candecline']); // Can decline or revoke optional for myself.
$this->assertTrue($policy['canrevoke']);
}
$this->assertNotContains('acceptance', $policy); // Nothing accepted yet.
}
@ -285,6 +299,18 @@ class externallib_test extends externallib_advanced_testcase {
$policies = \core_external\external_api::clean_returnvalue(
\tool_policy\external\get_user_acceptances::execute_returns(), $policies);
$this->assertCount(2, $policies['policies']);
foreach ($policies['policies'] as $policy) {
if ($policy['versionid'] == $this->policy2->get('id')) {
$this->assertTrue($policy['canaccept']);
$this->assertFalse($policy['candecline']); // Cannot decline mandatory in general.
$this->assertTrue($policy['canrevoke']);
} else {
$this->assertTrue($policy['canaccept']);
$this->assertTrue($policy['candecline']);
$this->assertTrue($policy['canrevoke']);
}
$this->assertNotContains('acceptance', $policy); // Nothing accepted yet.
}
// Get other user acceptances without permission.
$this->expectException(\required_capability_exception::class);
@ -311,9 +337,19 @@ class externallib_test extends externallib_advanced_testcase {
$formdata->content_editor = ['text' => 'content', 'format' => FORMAT_HTML, 'itemid' => 0];
$optionalpolicy = api::form_policydoc_add($formdata);
api::make_current($optionalpolicy->get('id'));
// Decline this version.
api::decline_policies([$optionalpolicy->get('id')], $user->id, null);
// Generate new version and make it current.
$formdata = api::form_policydoc_data($optionalpolicy);
$formdata->revision = 'v2';
$optionalpolicynew = api::form_policydoc_update_new($formdata);
api::make_current($optionalpolicynew->get('id'));
// Accept all the policies.
$ids = [['versionid' => $this->policy2->get('id'), 'status' => 1], ['versionid' => $optionalpolicy->get('id'), 'status' => 1]];
// Accept all the current policies.
$ids = [
['versionid' => $this->policy2->get('id'), 'status' => 1],
['versionid' => $optionalpolicynew->get('id'), 'status' => 1],
];
$policies = \tool_policy\external\set_acceptances_status::execute($ids);
$policies = \core_external\external_api::clean_returnvalue(
@ -322,17 +358,25 @@ class externallib_test extends externallib_advanced_testcase {
$this->assertEquals(1, $policies['policyagreed']);
$this->assertCount(0, $policies['warnings']);
// And now accept and old one.
$ids = [['versionid' => $optionalpolicy->get('id'), 'status' => 1, 'note' => 'I accept for me.']]; // The note will be ignored.
$policies = \tool_policy\external\set_acceptances_status::execute($ids);
$policies = \core_external\external_api::clean_returnvalue(
\tool_policy\external\set_acceptances_status::execute_returns(), $policies);
// Retrieve and check all are accepted now.
$policies = \tool_policy\external\get_user_acceptances::execute();
$policies = \core_external\external_api::clean_returnvalue(
\tool_policy\external\get_user_acceptances::execute_returns(), $policies);
$this->assertCount(2, $policies['policies']);
$this->assertCount(3, $policies['policies']);
foreach ($policies['policies'] as $policy) {
$this->assertEquals(1, $policy['acceptance']['status']); // Check all accepted.
$this->assertEmpty($policy['acceptance']['note']); // The note was not recorded because it was for itself.
}
// Decline optional only.
$policies = \tool_policy\external\set_acceptances_status::execute([['versionid' => $optionalpolicy->get('id'), 'status' => 0]]);
$policies = \tool_policy\external\set_acceptances_status::execute([['versionid' => $optionalpolicynew->get('id'), 'status' => 0]]);
$policies = \core_external\external_api::clean_returnvalue(
\tool_policy\external\set_acceptances_status::execute_returns(), $policies);
@ -343,19 +387,21 @@ class externallib_test extends externallib_advanced_testcase {
$policies = \core_external\external_api::clean_returnvalue(
\tool_policy\external\get_user_acceptances::execute_returns(), $policies);
$this->assertCount(2, $policies['policies']);
$this->assertCount(3, $policies['policies']);
foreach ($policies['policies'] as $policy) {
if ($policy['versionid'] == $this->policy2->get('id')) {
$this->assertEquals(1, $policy['acceptance']['status']); // Still accepted.
} else {
if ($policy['versionid'] == $optionalpolicynew->get('id')) {
$this->assertEquals(0, $policy['acceptance']['status']); // Not accepted.
} else {
$this->assertEquals(1, $policy['acceptance']['status']); // Accepted.
}
}
// Parent & child case now. Accept the optional ONLY on behalf of someone else.
$this->parent->policyagreed = 1;
$this->setUser($this->parent);
$policies = \tool_policy\external\set_acceptances_status::execute([['versionid' => $optionalpolicy->get('id'), 'status' => 1]], $this->child->id);
$notetext = 'I accept this on behalf of my child Santiago.';
$policies = \tool_policy\external\set_acceptances_status::execute(
[['versionid' => $optionalpolicynew->get('id'), 'status' => 1, 'note' => $notetext]], $this->child->id);
$policies = \core_external\external_api::clean_returnvalue(
\tool_policy\external\set_acceptances_status::execute_returns(), $policies);
@ -370,14 +416,16 @@ class externallib_test extends externallib_advanced_testcase {
foreach ($policies['policies'] as $policy) {
if ($policy['versionid'] == $this->policy2->get('id')) {
$this->assertNotContains('acceptance', $policy); // Not yet accepted.
$this->assertArrayNotHasKey('acceptance', $policy);
} else {
$this->assertEquals(1, $policy['acceptance']['status']); // Accepted.
$this->assertEquals($notetext, $policy['acceptance']['note']);
}
}
// Try to accept on behalf of other user with no permissions.
$this->expectException(\required_capability_exception::class);
$policies = \tool_policy\external\set_acceptances_status::execute([['versionid' => $optionalpolicy->get('id'), 'status' => 1]], $user->id);
$policies = \tool_policy\external\set_acceptances_status::execute([['versionid' => $optionalpolicynew->get('id'), 'status' => 1]], $user->id);
}
/**