From 071ffdf123239498dd40094a226164eacc133ca9 Mon Sep 17 00:00:00 2001 From: Adrian Perez Date: Thu, 18 Feb 2021 08:03:26 +0100 Subject: [PATCH] Assign role synchronization to course category context (#1) --- classes/form/edit.php | 41 ++++++-- classes/observers.php | 14 +-- classes/output/summary_table.php | 17 ++++ classes/persistent.php | 36 +++++++ db/install.xml | 4 +- db/upgrade.php | 28 ++++++ edit.php | 15 +-- index.php | 3 +- lang/en/local_cohortrole.php | 6 +- locallib.php | 95 +++++++++++++++---- ...behat_local_cohortrole_data_generators.php | 5 +- tests/behat/configure.feature | 53 +++++++---- tests/observers_test.php | 85 ++++++++++++----- tests/privacy_test.php | 5 +- version.php | 2 +- 15 files changed, 323 insertions(+), 86 deletions(-) diff --git a/classes/form/edit.php b/classes/form/edit.php index fc6bd76..bb8be02 100644 --- a/classes/form/edit.php +++ b/classes/form/edit.php @@ -33,6 +33,9 @@ class edit extends \core\form\persistent { /** @var string Persistent class name. */ protected static $persistentclass = persistent::class; + /** @var array Fields to remove when getting the final data. */ + protected static $fieldstoremove = array('submitbutton', 'modeid'); + /** * Form definition * @@ -41,16 +44,26 @@ class edit extends \core\form\persistent { protected function definition() { $mform = $this->_form; + $mode = $this->_customdata['modeid']; + + $mform->addElement('hidden', 'modeid', $mode); + $mform->setType('modeid', PARAM_INT); + $mform->addElement('select', 'cohortid', get_string('cohort', 'local_cohortrole'), self::get_cohorts()); $mform->addRule('cohortid', get_string('required'), 'required', null, 'client'); $mform->setType('cohortid', PARAM_INT); $mform->addHelpButton('cohortid', 'cohort', 'local_cohortrole'); - $mform->addElement('select', 'roleid', get_string('role', 'local_cohortrole'), self::get_roles()); + $mform->addElement('select', 'roleid', get_string('role', 'local_cohortrole'), self::get_roles($mode)); $mform->addRule('roleid', get_string('required'), 'required', null, 'client'); $mform->setType('roleid', PARAM_INT); $mform->addHelpButton('roleid', 'role', 'local_cohortrole'); + $mform->addElement('select', 'categoryid', get_string('category', 'local_cohortrole'), self::get_categories()); + $mform->setType('categoryid', PARAM_INT); + $mform->addHelpButton('categoryid', 'category', 'local_cohortrole'); + $mform->hideIf('categoryid', 'modeid', 'eq', 0); + $this->add_action_buttons(); } @@ -63,8 +76,8 @@ protected function definition() { * @return array */ public function extra_validation($data, $files, array &$errors) { - if ($this->get_persistent()->record_exists_select('cohortid = :cohortid AND roleid = :roleid', - ['cohortid' => $data->cohortid, 'roleid' => $data->roleid])) { + if ($this->get_persistent()->record_exists_select('cohortid = :cohortid AND roleid = :roleid AND categoryid = :categoryid', + ['cohortid' => $data->cohortid, 'roleid' => $data->roleid, 'categoryid' => $data->categoryid])) { $errors['cohortid'] = get_string('errorexists', 'local_cohortrole'); } @@ -89,15 +102,31 @@ protected static function get_cohorts() { } /** - * Get roles that are assignable in the system context + * Get roles that are assignable in the system or course category context * + * @param string $modeid The selected modeid (0 = System, 1 = Category) * @return array */ - protected static function get_roles() { - $roles = get_assignable_roles(\context_system::instance(), ROLENAME_ALIAS); + protected static function get_roles($modeid) { + $context = local_cohortrole_get_context($modeid); + + $roles = get_assignable_roles($context, ROLENAME_ALIAS); \core_collator::asort($roles, \core_collator::SORT_STRING); return $roles; } + + /** + * Get categories from the system + * + * @return array + */ + protected static function get_categories() { + $categories = [0 => get_string('choosedots')] + \core_course_category::make_categories_list(); + + \core_collator::asort($categories, \core_collator::SORT_STRING); + + return $categories; + } } diff --git a/classes/observers.php b/classes/observers.php index b1ce657..dcff584 100644 --- a/classes/observers.php +++ b/classes/observers.php @@ -39,12 +39,10 @@ public static function cohort_deleted(\core\event\cohort_deleted $event) { $cohort = $event->get_record_snapshot('cohort', $event->objectid); $instances = persistent::get_records(['cohortid' => $cohort->id]); - if (count($instances) > 0) { - local_cohortrole_unsynchronize($cohort->id); + foreach ($instances as $instance) { + local_cohortrole_unsynchronize($cohort->id, $instance->get('roleid'), $instance->get('categoryid')); - foreach ($instances as $instance) { - $instance->delete(); - } + $instance->delete(); } } } @@ -64,7 +62,8 @@ public static function cohort_member_added(\core\event\cohort_member_added $even $user = \core_user::get_user($event->relateduserid, '*', MUST_EXIST); foreach ($instances as $instance) { - local_cohortrole_role_assign($instance->get('cohortid'), $instance->get('roleid'), [$user->id]); + local_cohortrole_role_assign($instance->get('cohortid'), $instance->get('roleid'), $instance->get('categoryid'), + [$user->id]); } } } @@ -85,7 +84,8 @@ public static function cohort_member_removed(\core\event\cohort_member_removed $ $user = \core_user::get_user($event->relateduserid, '*', MUST_EXIST); foreach ($instances as $instance) { - local_cohortrole_role_unassign($instance->get('cohortid'), $instance->get('roleid'), [$user->id]); + local_cohortrole_role_unassign($instance->get('cohortid'), $instance->get('roleid'), + $instance->get('categoryid'), [$user->id]); } } } diff --git a/classes/output/summary_table.php b/classes/output/summary_table.php index 1431f76..f2a34ed 100644 --- a/classes/output/summary_table.php +++ b/classes/output/summary_table.php @@ -41,6 +41,7 @@ public function __construct() { $columns = [ 'cohort' => get_string('cohort', 'local_cohortrole'), 'role' => get_string('role', 'local_cohortrole'), + 'category' => get_string('category', 'local_cohortrole'), 'timecreated' => get_string('modified'), 'edit' => get_string('edit'), ]; @@ -124,6 +125,22 @@ public function col_role(\stdClass $record) { return role_get_name($persistent->get_role(), \context_system::instance(), ROLENAME_ALIAS); } + /** + * Format record category column + * + * @param stdClass $record + * @return string + */ + public function col_category(\stdClass $record) { + if ($record->categoryid == LOCAL_COHORTROLE_MODE_SYSTEM) { + return ''; + } + + $persistent = new persistent(0, $record); + + return $persistent->get_category()->name; + } + /** * Format record time created column * diff --git a/classes/persistent.php b/classes/persistent.php index 6be275f..42bb7fd 100644 --- a/classes/persistent.php +++ b/classes/persistent.php @@ -24,6 +24,8 @@ defined('MOODLE_INTERNAL') || die(); +require_once($CFG->dirroot . '/local/cohortrole/locallib.php'); + use \local_cohortrole\event\definition_created, \local_cohortrole\event\definition_deleted; @@ -45,6 +47,9 @@ protected static function define_properties() { 'roleid' => array( 'type' => PARAM_INT, ), + 'categoryid' => array( + 'type' => PARAM_INT, + ), ); } @@ -82,6 +87,26 @@ protected function validate_roleid($roleid) { return true; } + /** + * Validate category ID + * + * @param int $categoryid + * @return true|lang_string + */ + protected function validate_categoryid($categoryid) { + global $DB; + + if ($categoryid == LOCAL_COHORTROLE_MODE_SYSTEM) { + return true; + } + + if (! $DB->record_exists('course_categories', ['id' => $categoryid])) { + return new \lang_string('invalidcategoryid', 'error'); + } + + return true; + } + /** * Hook to execute after model is created * @@ -122,4 +147,15 @@ public function get_role() { return $DB->get_record('role', ['id' => $this->get('roleid')], '*', MUST_EXIST); } + + /** + * Returns the category object + * + * @return stdClass + */ + public function get_category() { + global $DB; + + return $DB->get_record('course_categories', ['id' => $this->get('categoryid')], '*', MUST_EXIST); + } } diff --git a/db/install.xml b/db/install.xml index 17c1101..353cd55 100644 --- a/db/install.xml +++ b/db/install.xml @@ -9,6 +9,7 @@ + @@ -17,10 +18,11 @@ + - + diff --git a/db/upgrade.php b/db/upgrade.php index e54529b..b43ae85 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -119,5 +119,33 @@ function xmldb_local_cohortrole_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2018121001, 'local', 'cohortrole'); } + if ($oldversion < 2020110901) { + // Define field categoryid to be added to local_cohortrole. + $table = new xmldb_table('local_cohortrole'); + $field = new xmldb_field('categoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'roleid'); + + // Conditionally launch add field categoryid. + if (! $dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Define key fk_category (foreign) to be added to local_cohortrole. + $key = new xmldb_key('fk_category', XMLDB_KEY_FOREIGN, array('categoryid'), 'course_categories', array('id')); + $dbman->add_key($table, $key); + + // Conditionally launch drop and add index 'uq_cohort_role'. + $index = new xmldb_index('uq_cohort_role', XMLDB_INDEX_UNIQUE, array('cohortid', 'roleid')); + + if ($dbman->index_exists($table, $index)) { + $dbman->drop_index($table, $index); + } + + $index = new xmldb_index('uq_cohort_role', XMLDB_INDEX_UNIQUE, array('cohortid', 'roleid', 'categoryid')); + $dbman->add_index($table, $index); + + // Cohortrole savepoint reached. + upgrade_plugin_savepoint(true, 2020110901, 'local', 'cohortrole'); + } + return true; } diff --git a/edit.php b/edit.php index aef49ed..79e7dbe 100644 --- a/edit.php +++ b/edit.php @@ -26,19 +26,20 @@ use \local_cohortrole\persistent; -$delete = optional_param('delete', 0, PARAM_INT); -$confirm = optional_param('confirm', 0, PARAM_BOOL); +$delete = optional_param('delete', 0, PARAM_INT); +$confirm = optional_param('confirm', 0, PARAM_BOOL); +$mode = optional_param('mode', 0, PARAM_INT); admin_externalpage_setup('local_cohortrole'); -$editurl = new moodle_url('/local/cohortrole/edit.php'); +$editurl = new moodle_url('/local/cohortrole/edit.php'); $returnurl = clone($PAGE->url); if ($delete) { $persistent = new persistent($delete); if ($confirm and confirm_sesskey()) { - local_cohortrole_unsynchronize($persistent->get('cohortid'), $persistent->get('roleid')); + local_cohortrole_unsynchronize($persistent->get('cohortid'), $persistent->get('roleid'), $persistent->get('categoryid')); $persistent->delete(); @@ -58,14 +59,14 @@ die; } -$mform = new \local_cohortrole\form\edit($editurl, ['persistent' => null]); +$mform = new \local_cohortrole\form\edit($editurl, ['persistent' => null, 'modeid' => $mode]); if ($mform->is_cancelled()) { redirect($returnurl); } else if ($data = $mform->get_data()) { $persistent = (new persistent(0, $data))->create(); - local_cohortrole_synchronize($persistent->get('cohortid'), $persistent->get('roleid')); + local_cohortrole_synchronize($persistent->get('cohortid'), $persistent->get('roleid'), $persistent->get('categoryid')); redirect($returnurl, get_string('notificationcreated', 'local_cohortrole'), null, \core\output\notification::NOTIFY_SUCCESS); @@ -74,7 +75,7 @@ $PAGE->navbar->add(get_string('add')); echo $OUTPUT->header(); -echo $OUTPUT->heading(get_string('heading_add', 'local_cohortrole')); +echo $OUTPUT->heading(get_string('heading_add', 'local_cohortrole', local_cohortrole_get_context_name($mode))); $mform->display(); diff --git a/index.php b/index.php index 726605d..6b35dc7 100644 --- a/index.php +++ b/index.php @@ -22,6 +22,7 @@ require(__DIR__ . '/../../config.php'); require_once($CFG->libdir . '/adminlib.php'); +require_once($CFG->dirroot . '/local/cohortrole/locallib.php'); admin_externalpage_setup('local_cohortrole'); @@ -33,6 +34,6 @@ echo $PAGE->get_renderer('local_cohortrole')->render($table); -echo $OUTPUT->single_button(new moodle_url('/local/cohortrole/edit.php'), get_string('add'), 'get', ['class' => 'continuebutton']); +echo local_cohortrole_render_add_buttons(); echo $OUTPUT->footer(); diff --git a/lang/en/local_cohortrole.php b/lang/en/local_cohortrole.php index fac2125..fa81976 100644 --- a/lang/en/local_cohortrole.php +++ b/lang/en/local_cohortrole.php @@ -28,7 +28,7 @@ $string['errorexists'] = 'Synchronization already defined'; $string['eventdefinitioncreated'] = 'Cohort role synchronization created'; $string['eventdefinitiondeleted'] = 'Cohort role synchronization deleted'; -$string['heading_add'] = 'Define new synchronization'; +$string['heading_add'] = 'Define new synchronization in {$a}'; $string['heading_delete'] = 'Delete defined synchronization'; $string['heading_index'] = 'Currently defined synchronization'; $string['notificationcreated'] = 'Created new synchronization'; @@ -40,4 +40,6 @@ $string['privacy:metadata:cohortrole:usermodified'] = 'The ID of the user who created the definition'; $string['privacy:metadata:cohortrole:timecreated'] = 'The timestamp the definition was created'; $string['role'] = 'Role'; -$string['role_help'] = 'List of assignable roles in the system context'; +$string['role_help'] = 'List of assignable roles in the selected mode context'; +$string['category'] = 'Category'; +$string['category_help'] = 'You can optionally select a course category to assign roles not in the system context'; diff --git a/locallib.php b/locallib.php index f8697bb..88d24a1 100644 --- a/locallib.php +++ b/locallib.php @@ -22,18 +22,21 @@ defined('MOODLE_INTERNAL') || die(); +define('LOCAL_COHORTROLE_MODE_SYSTEM', '0'); +define('LOCAL_COHORTROLE_MODE_CATEGORY', '1'); define('LOCAL_COHORTROLE_ROLE_COMPONENT', 'local_cohortrole'); /** * Assign users to a role; using local role component * - * @param integer $cohortid the id of a cohort - * @param integer $roleid the id of a role + * @param int $cohortid the id of a cohort + * @param int $roleid the id of a role + * @param int $categoryid the id of a category * @param array $userids an array of user ids to assign * @return void */ -function local_cohortrole_role_assign($cohortid, $roleid, array $userids) { - $context = context_system::instance(); +function local_cohortrole_role_assign($cohortid, $roleid, $categoryid, array $userids) { + $context = local_cohortrole_get_context($categoryid); foreach ($userids as $userid) { role_assign($roleid, $userid, $context->id, LOCAL_COHORTROLE_ROLE_COMPONENT, $cohortid); @@ -43,13 +46,14 @@ function local_cohortrole_role_assign($cohortid, $roleid, array $userids) { /** * Unassign users from a role; using local role component * - * @param integer $cohortid the id of a cohort - * @param integer $roleid the id of a role + * @param int $cohortid the id of a cohort + * @param int $roleid the id of a role + * @param int $categoryid the id of a category * @param array $userids an array of user ids to unassign * @return void */ -function local_cohortrole_role_unassign($cohortid, $roleid, array $userids) { - $context = context_system::instance(); +function local_cohortrole_role_unassign($cohortid, $roleid, $categoryid, array $userids) { + $context = local_cohortrole_get_context($categoryid); foreach ($userids as $userid) { role_unassign($roleid, $userid, $context->id, LOCAL_COHORTROLE_ROLE_COMPONENT, $cohortid); @@ -59,16 +63,17 @@ function local_cohortrole_role_unassign($cohortid, $roleid, array $userids) { /** * Add users to a role that synchronizes from a cohort * - * @param integer $cohortid the id of a cohort - * @param integer $roleid the id of a role + * @param int $cohortid the id of a cohort + * @param int $roleid the id of a role + * @param int $categoryid the id of a category * @return void */ -function local_cohortrole_synchronize($cohortid, $roleid) { +function local_cohortrole_synchronize($cohortid, $roleid, $categoryid) { global $DB; $userids = $DB->get_records_menu('cohort_members', array('cohortid' => $cohortid), null, 'id, userid'); - local_cohortrole_role_assign($cohortid, $roleid, $userids); + local_cohortrole_role_assign($cohortid, $roleid, $categoryid, $userids); } /** @@ -78,9 +83,11 @@ function local_cohortrole_synchronize($cohortid, $roleid) { * @param integer|null $roleid the id of a role, all roles if null * @return void */ -function local_cohortrole_unsynchronize($cohortid, $roleid = null) { +function local_cohortrole_unsynchronize($cohortid, $roleid = null, $categoryid) { + $context = local_cohortrole_get_context($categoryid); + $params = array( - 'contextid' => context_system::instance()->id, 'component' => LOCAL_COHORTROLE_ROLE_COMPONENT, 'itemid' => $cohortid); + 'contextid' => $context->id, 'component' => LOCAL_COHORTROLE_ROLE_COMPONENT, 'itemid' => $cohortid); if ($roleid === null) { $roleids = local_cohortrole_get_cohort_roles($cohortid); @@ -98,11 +105,67 @@ function local_cohortrole_unsynchronize($cohortid, $roleid = null) { /** * Get roles defined as being populated by a cohort * - * @param integer $cohortid the id of a cohort + * @param int $cohortid the id of a cohort * @return array role ids */ -function local_cohortrole_get_cohort_roles($cohortid) { +function local_cohortrole_get_cohort_roles(int $cohortid) { global $DB; return $DB->get_records_menu('local_cohortrole', array('cohortid' => $cohortid), null, 'id, roleid'); } + +/** + * Get the context to assign and unassign roles. + * + * @param int $categoryid + * @return bool|context|context_coursecat|context_system|null + * @throws dml_exception + */ +function local_cohortrole_get_context(int $categoryid) { + if ($categoryid >= LOCAL_COHORTROLE_MODE_CATEGORY) { + return context_coursecat::instance($categoryid); + } + + return $context = context_system::instance(); +} + +/** + * Returns the context name by the given mode. + * + * @param $mode + * @return string + * @throws coding_exception + * @throws dml_exception + */ +function local_cohortrole_get_context_name($mode): string { + $context = local_cohortrole_get_context($mode); + $contextname = strtok($context->get_context_name(), ':'); + + return $contextname; +} + +/** + * Returns the buttons to launch the edit form by mode. + * + * @return string + * @throws coding_exception + * @throws dml_exception + * @throws moodle_exception + */ +function local_cohortrole_render_add_buttons(): string { + global $OUTPUT; + + $output = html_writer::start_div('continuebutton mt-3', ['role' => 'group']); + + $modes = [LOCAL_COHORTROLE_MODE_SYSTEM, LOCAL_COHORTROLE_MODE_CATEGORY]; + foreach ($modes as $mode) { + $contextname = local_cohortrole_get_context_name($mode); + + $output .= $OUTPUT->single_button(new moodle_url('/local/cohortrole/edit.php', ['mode' => $mode]), + get_string('assignrolesin', 'core_role', $contextname), 'get'); + } + + $output .= html_writer::end_div(); + + return $output; +} diff --git a/tests/behat/behat_local_cohortrole_data_generators.php b/tests/behat/behat_local_cohortrole_data_generators.php index 9ec195a..21dbee2 100644 --- a/tests/behat/behat_local_cohortrole_data_generators.php +++ b/tests/behat/behat_local_cohortrole_data_generators.php @@ -40,7 +40,7 @@ public function the_following_cohort_role_definitions_exist(TableNode $data) { $generator = testing_util::get_data_generator()->get_plugin_generator('local_cohortrole'); - $requiredfields = ['cohort', 'role']; + $requiredfields = ['cohort', 'role', 'category']; foreach ($data->getHash() as $elementdata) { foreach ($requiredfields as $requiredfield) { @@ -71,6 +71,9 @@ protected function preprocess_definition(array $data) { $data['roleid'] = $DB->get_field('role', 'id', ['shortname' => $data['role']], MUST_EXIST); unset($data['role']); + $data['categoryid'] = $DB->get_field('course_categories', 'id', ['idnumber' => $data['category']], MUST_EXIST); + unset($data['category']); + return $data; } } diff --git a/tests/behat/configure.feature b/tests/behat/configure.feature index ddd5523..b5dc400 100644 --- a/tests/behat/configure.feature +++ b/tests/behat/configure.feature @@ -6,37 +6,56 @@ Feature: An admin can configure Cohort role synchronizations Background: Given the following "cohorts" exist: - | name | idnumber | - | Cohort One | C1 | - | Cohort Two | C2 | + | name | idnumber | + | Cohort One | C1 | + | Cohort Two | C2 | And the following "roles" exist: - | name | shortname | - | Super Role | R1 | + | name | shortname | + | Super Role | R1 | + And the following "categories" exist: + | name | category | idnumber | + | Cat 1 | 0 | CAT1 | And the following Cohort role definitions exist: - | cohort | role | - | C1 | R1 | + | cohort | role | category | + | C1 | R1 | CAT1 | And I log in as "admin" And I navigate to "Users > Accounts > Cohort role synchronization" in site administration @javascript - Scenario: Add new Cohort role definition - When I press "Add" + Scenario: Add new Cohort role system definition + When I press "Assign roles in System" And I set the following fields to these values: | Cohort | Cohort Two | - | Role | Super Role | + | Role | Super Role | And I click on "Save changes" "button" Then I should see "Created new synchronization" And the following should exist in the "local-cohortrole-summary-table" table: - | Cohort | Role | - | Cohort One | Super Role | - | Cohort Two | Super Role | + | Cohort | Role | Category | + | Cohort One | Super Role | Cat 1 | + | Cohort Two | Super Role | | + + @javascript + Scenario: Add new Cohort role category definition + When I press "Assign roles in Category" + And I set the following fields to these values: + | Cohort | Cohort Two | + | Role | Super Role | + | Category | Cat 1 | + And I click on "Save changes" "button" + Then I should see "Created new synchronization" + And the following should exist in the "local-cohortrole-summary-table" table: + | Cohort | Role | Category | + | Cohort One | Super Role | Cat 1 | + | Cohort Two | Super Role | | + | Cohort Two | Super Role | Cat 1 | @javascript Scenario: Add duplicate Cohort role definition - When I press "Add" + When I press "Assign roles in Category" And I set the following fields to these values: - | Cohort | Cohort One | - | Role | Super Role | + | Cohort | Cohort One | + | Role | Super Role | + | Category | Cat 1 | And I click on "Save changes" "button" Then I should see "Synchronization already defined" And I click on "Cancel" "button" @@ -48,5 +67,5 @@ Feature: An admin can configure Cohort role synchronizations And I click on "Continue" "button" And I should see "Deleted synchronization" And the following should not exist in the "local-cohortrole-summary-table" table: - | Cohort | Role | + | Cohort | Role | | Cohort One | Super Role | diff --git a/tests/observers_test.php b/tests/observers_test.php index 85f7ab5..ce1429f 100644 --- a/tests/observers_test.php +++ b/tests/observers_test.php @@ -32,7 +32,7 @@ */ class local_cohortrole_observers_testcase extends advanced_testcase { - /** @var \local_cohortrole\persistent $persistent. */ + /** @var \local_cohortrole\persistent $persistent */ protected $persistent; /** @@ -42,6 +42,7 @@ public static function setUpBeforeClass(): void { global $CFG; require_once("{$CFG->dirroot}/cohort/lib.php"); + require_once("{$CFG->dirroot}/local/cohortrole/locallib.php"); } /** @@ -50,13 +51,17 @@ public static function setUpBeforeClass(): void { protected function setUp(): void { $this->resetAfterTest(true); - // Create test role/cohort. + // Create test role, cohort and category. $roleid = $this->getDataGenerator()->create_role(); $cohort = $this->getDataGenerator()->create_cohort(); - - // Link them together. - $this->persistent = $this->getDataGenerator()->get_plugin_generator('local_cohortrole') - ->create_persistent(['roleid' => $roleid, 'cohortid' => $cohort->id]); + $category = $this->getDataGenerator()->create_category(); + + // Create role synchronizations and link them together. + $categoryids = [0, $category->id]; + foreach ($categoryids as $categoryid) { + $this->persistent = $this->getDataGenerator()->get_plugin_generator('local_cohortrole') + ->create_persistent(['roleid' => $roleid, 'cohortid' => $cohort->id, 'categoryid' => $categoryid]); + } } /** @@ -65,19 +70,29 @@ protected function setUp(): void { * @return void */ public function test_cohort_deleted() { - $context = context_system::instance(); + $systemcontext = local_cohortrole_get_context(LOCAL_COHORTROLE_MODE_SYSTEM); + $coursecategorycontext = local_cohortrole_get_context($this->persistent->get('categoryid')); $user = $this->getDataGenerator()->create_user(); cohort_add_member($this->persistent->get('cohortid'), $user->id); - $userhasrole = user_has_role_assignment($user->id, $this->persistent->get('roleid'), $context->id); - $this->assertTrue($userhasrole); + $userhasroleinsystem = user_has_role_assignment($user->id, $this->persistent->get('roleid'), $systemcontext->id); + $this->assertTrue($userhasroleinsystem); + + $userhasroleincoursecategory = + user_has_role_assignment($user->id, $this->persistent->get('roleid'), $coursecategorycontext->id); + $this->assertTrue($userhasroleincoursecategory); cohort_delete_cohort($this->persistent->get_cohort()); - // User should not be assigned to the test role. - $userhasrole = user_has_role_assignment($user->id, $this->persistent->get('roleid'), $context->id); - $this->assertFalse($userhasrole); + // User should not be assigned to the test role in the system. + $userhasroleinsystem = user_has_role_assignment($user->id, $this->persistent->get('roleid'), $systemcontext->id); + $this->assertFalse($userhasroleinsystem); + + // User should not be assigned to the test role in the course category. + $userhasroleincoursecategory = + user_has_role_assignment($user->id, $this->persistent->get('roleid'), $coursecategorycontext->id); + $this->assertFalse($userhasroleincoursecategory); // Ensure plugin tables are cleaned up. $exists = $this->persistent->record_exists_select('cohortid = ?', [$this->persistent->get('cohortid')]); @@ -90,18 +105,28 @@ public function test_cohort_deleted() { * @return void */ public function test_cohort_member_added() { - $context = context_system::instance(); + $systemcontext = local_cohortrole_get_context(LOCAL_COHORTROLE_MODE_SYSTEM); + $coursecategorycontext = local_cohortrole_get_context($this->persistent->get('categoryid')); $user = $this->getDataGenerator()->create_user(); - $userhasrole = user_has_role_assignment($user->id, $this->persistent->get('roleid'), $context->id); - $this->assertFalse($userhasrole); + $userhasroleinsystem = user_has_role_assignment($user->id, $this->persistent->get('roleid'), $systemcontext->id); + $this->assertFalse($userhasroleinsystem); + + $userhasroleincoursecategory = + user_has_role_assignment($user->id, $this->persistent->get('roleid'), $coursecategorycontext->id); + $this->assertFalse($userhasroleincoursecategory); cohort_add_member($this->persistent->get('cohortid'), $user->id); - // User should be assigned to the test role. - $userhasrole = user_has_role_assignment($user->id, $this->persistent->get('roleid'), $context->id); - $this->assertTrue($userhasrole); + // User should be assigned to the test role in the system. + $userhasroleinsystem = user_has_role_assignment($user->id, $this->persistent->get('roleid'), $systemcontext->id); + $this->assertTrue($userhasroleinsystem); + + // User should be assigned to the test role in the course category. + $userhasroleincoursecategory = + user_has_role_assignment($user->id, $this->persistent->get('roleid'), $coursecategorycontext->id); + $this->assertTrue($userhasroleincoursecategory); } /** @@ -110,7 +135,8 @@ public function test_cohort_member_added() { * @return void */ public function test_cohort_member_removed() { - $context = context_system::instance(); + $systemcontext = local_cohortrole_get_context(LOCAL_COHORTROLE_MODE_SYSTEM); + $coursecategorycontext = local_cohortrole_get_context($this->persistent->get('categoryid')); $user1 = $this->getDataGenerator()->create_user(); cohort_add_member($this->persistent->get('cohortid'), $user1->id); @@ -120,12 +146,21 @@ public function test_cohort_member_removed() { cohort_remove_member($this->persistent->get('cohortid'), $user1->id); - // User 2 should be assigned to the test role, user 1 should not. - $userhasrole = user_has_role_assignment($user2->id, $this->persistent->get('roleid'), $context->id); - $this->assertTrue($userhasrole); + // User 2 should be assigned to the test role in the system, user 1 should not. + $userhasroleinsystem = user_has_role_assignment($user2->id, $this->persistent->get('roleid'), $systemcontext->id); + $this->assertTrue($userhasroleinsystem); + + $userhasroleinsystem = user_has_role_assignment($user1->id, $this->persistent->get('roleid'), $systemcontext->id); + $this->assertFalse($userhasroleinsystem); + + // User 2 should be assigned to the test role in the course category, user 1 should not. + $userhasroleincoursecategory = + user_has_role_assignment($user2->id, $this->persistent->get('roleid'), $coursecategorycontext->id); + $this->assertTrue($userhasroleincoursecategory); - $userhasrole = user_has_role_assignment($user1->id, $this->persistent->get('roleid'), $context->id); - $this->assertFalse($userhasrole); + $userhasroleincoursecategory = + user_has_role_assignment($user1->id, $this->persistent->get('roleid'), $coursecategorycontext->id); + $this->assertFalse($userhasroleincoursecategory); } /** @@ -140,4 +175,4 @@ public function test_role_deleted() { $exists = $this->persistent->record_exists_select('roleid = ?', [$this->persistent->get('roleid')]); $this->assertFalse($exists); } -} \ No newline at end of file +} diff --git a/tests/privacy_test.php b/tests/privacy_test.php index bbec147..774b31c 100644 --- a/tests/privacy_test.php +++ b/tests/privacy_test.php @@ -55,13 +55,14 @@ protected function setUp(): void { $this->user = $this->getDataGenerator()->create_user(); $this->setUser($this->user); - // Create test role/cohort. + // Create test role, cohort and category. $roleid = $this->getDataGenerator()->create_role(); $cohort = $this->getDataGenerator()->create_cohort(); + $category = $this->getDataGenerator()->create_category(); // Link them together. $this->persistent = $this->getDataGenerator()->get_plugin_generator('local_cohortrole') - ->create_persistent(['roleid' => $roleid, 'cohortid' => $cohort->id]); + ->create_persistent(['roleid' => $roleid, 'cohortid' => $cohort->id, 'categoryid' => $category->id]); } /** diff --git a/version.php b/version.php index 064b0d8..8e14dc9 100644 --- a/version.php +++ b/version.php @@ -24,6 +24,6 @@ $plugin->component = 'local_cohortrole'; $plugin->release = '3.3'; -$plugin->version = 2020110900; +$plugin->version = 2020110901; $plugin->requires = 2018051703; // Moodle 3.5.3 onwards. $plugin->maturity = MATURITY_STABLE;