See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
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 /** 18 * Step definitions to generate database fixtures for the data privacy tool. 19 * 20 * @package tool_dataprivacy 21 * @category test 22 * @copyright 2018 Jun Pataleta 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 require_once (__DIR__ . '/../../../../../lib/behat/behat_base.php'); 27 28 use Behat\Gherkin\Node\TableNode as TableNode; 29 use Behat\Behat\Tester\Exception\PendingException as PendingException; 30 use tool_dataprivacy\api; 31 32 /** 33 * Step definitions to generate database fixtures for the data privacy tool. 34 * 35 * @package tool_dataprivacy 36 * @category test 37 * @copyright 2018 Jun Pataleta 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class behat_tool_dataprivacy extends behat_base { 41 42 /** 43 * Each element specifies: 44 * - The data generator suffix used. 45 * - The required fields. 46 * - The mapping between other elements references and database field names. 47 * @var array 48 */ 49 protected static $elements = array( 50 'categories' => array( 51 'datagenerator' => 'category', 52 'required' => array() 53 ), 54 'purposes' => array( 55 'datagenerator' => 'purpose', 56 'required' => array() 57 ), 58 ); 59 60 /** 61 * Creates the specified element. More info about available elements in https://moodledev.io/general/development/tools/behat. 62 * 63 * @Given /^the following data privacy "(?P<element_string>(?:[^"]|\\")*)" exist:$/ 64 * 65 * @param string $elementname The name of the entity to add 66 * @param TableNode $data 67 */ 68 public function the_following_data_categories_exist($elementname, TableNode $data) { 69 70 // Now that we need them require the data generators. 71 require_once (__DIR__.'/../../../../../lib/phpunit/classes/util.php'); 72 73 if (empty(self::$elements[$elementname])) { 74 throw new PendingException($elementname . ' data generator is not implemented'); 75 } 76 77 $datagenerator = testing_util::get_data_generator(); 78 $dataprivacygenerator = $datagenerator->get_plugin_generator('tool_dataprivacy'); 79 80 $elementdatagenerator = self::$elements[$elementname]['datagenerator']; 81 $requiredfields = self::$elements[$elementname]['required']; 82 if (!empty(self::$elements[$elementname]['switchids'])) { 83 $switchids = self::$elements[$elementname]['switchids']; 84 } 85 86 foreach ($data->getHash() as $elementdata) { 87 88 // Check if all the required fields are there. 89 foreach ($requiredfields as $requiredfield) { 90 if (!isset($elementdata[$requiredfield])) { 91 throw new Exception($elementname . ' requires the field ' . $requiredfield . ' to be specified'); 92 } 93 } 94 95 // Switch from human-friendly references to ids. 96 if (isset($switchids)) { 97 foreach ($switchids as $element => $field) { 98 $methodname = 'get_' . $element . '_id'; 99 100 // Not all the switch fields are required, default vars will be assigned by data generators. 101 if (isset($elementdata[$element])) { 102 // Temp $id var to avoid problems when $element == $field. 103 $id = $this->{$methodname}($elementdata[$element]); 104 unset($elementdata[$element]); 105 $elementdata[$field] = $id; 106 } 107 } 108 } 109 110 // Preprocess the entities that requires a special treatment. 111 if (method_exists($this, 'preprocess_' . $elementdatagenerator)) { 112 $elementdata = $this->{'preprocess_' . $elementdatagenerator}($elementdata); 113 } 114 115 // Creates element. 116 $methodname = 'create_' . $elementdatagenerator; 117 if (method_exists($dataprivacygenerator, $methodname)) { 118 // Using data generators directly. 119 $dataprivacygenerator->{$methodname}($elementdata); 120 121 } else if (method_exists($this, 'process_' . $elementdatagenerator)) { 122 // Using an alternative to the direct data generator call. 123 $this->{'process_' . $elementdatagenerator}($elementdata); 124 } else { 125 throw new PendingException($elementname . ' data generator is not implemented'); 126 } 127 } 128 } 129 130 /** 131 * Sets the data category and data storage purpose for the site. 132 * 133 * @Given /^I set the site category and purpose to "(?P<category_string>(?:[^"]|\\")*)" and "(?P<purpose_string>(?:[^"]|\\")*)"$/ 134 * 135 * @param string $category The ID of the category to be set for the instance. 136 * @param string $purpose The ID of the purpose to be set for the instance. 137 */ 138 public function i_set_the_site_category_and_purpose($category, $purpose) { 139 $category = \tool_dataprivacy\category::get_record(['name' => $category]); 140 $purpose = \tool_dataprivacy\purpose::get_record(['name' => $purpose]); 141 $data = (object)[ 142 'contextlevel' => CONTEXT_SYSTEM, 143 'categoryid' => $category->get('id'), 144 'purposeid' => $purpose->get('id'), 145 ]; 146 api::set_contextlevel($data); 147 } 148 149 /** 150 * Sets the data category and data storage purpose for a course category instance. 151 * 152 * @Given /^I set the category and purpose for the course category "(?P<categoryname_string>(?:[^"]|\\")*)" to "(?P<category_string>(?:[^"]|\\")*)" and "(?P<purpose_string>(?:[^"]|\\")*)"$/ 153 * 154 * @param string $name The instance name. It should match the name or the idnumber. 155 * @param string $category The ID of the category to be set for the instance. 156 * @param string $purpose The ID of the purpose to be set for the instance. 157 */ 158 public function i_set_the_category_and_purpose_for_course_category($name, $category, $purpose) { 159 global $DB; 160 161 $params = [ 162 'name' => $name, 163 'idnumber' => $name, 164 ]; 165 $select = 'name = :name OR idnumber = :idnumber'; 166 $coursecatid = $DB->get_field_select('course_categories', 'id', $select, $params, MUST_EXIST); 167 $context = context_coursecat::instance($coursecatid); 168 169 $this->set_category_and_purpose($context->id, $category, $purpose); 170 } 171 172 /** 173 * Sets the data category and data storage purpose for a course instance. 174 * 175 * @Given /^I set the category and purpose for the course "(?P<coursename_string>(?:[^"]|\\")*)" to "(?P<category_string>(?:[^"]|\\")*)" and "(?P<purpose_string>(?:[^"]|\\")*)"$/ 176 * 177 * @param string $name The instance name. It should match the fullname or the shortname, or the idnumber. 178 * @param string $category The ID of the category to be set for the instance. 179 * @param string $purpose The ID of the purpose to be set for the instance. 180 */ 181 public function i_set_the_category_and_purpose_for_course($name, $category, $purpose) { 182 global $DB; 183 184 $params = [ 185 'shortname' => $name, 186 'fullname' => $name, 187 'idnumber' => $name, 188 ]; 189 $select = 'shortname = :shortname OR fullname = :fullname OR idnumber = :idnumber'; 190 $courseid = $DB->get_field_select('course', 'id', $select, $params, MUST_EXIST); 191 $context = context_course::instance($courseid); 192 193 $this->set_category_and_purpose($context->id, $category, $purpose); 194 } 195 196 /** 197 * Sets the data category and data storage purpose for a course instance. 198 * 199 * @Given /^I set the category and purpose for the "(?P<activityname_string>(?:[^"]|\\")*)" "(?P<activitytype_string>(?:[^"]|\\")*)" in course "(?P<coursename_string>(?:[^"]|\\")*)" to "(?P<category_string>(?:[^"]|\\")*)" and "(?P<purpose_string>(?:[^"]|\\")*)"$/ 200 * 201 * @param string $name The instance name. It should match the name of the activity. 202 * @param string $type The activity type. E.g. assign, quiz, forum, etc. 203 * @param string $coursename The course name. It should match the fullname or the shortname, or the idnumber. 204 * @param string $category The ID of the category to be set for the instance. 205 * @param string $purpose The ID of the purpose to be set for the instance. 206 */ 207 public function i_set_the_category_and_purpose_for_activity($name, $type, $coursename, $category, $purpose) { 208 global $DB; 209 210 $params = [ 211 'shortname' => $coursename, 212 'fullname' => $coursename, 213 'idnumber' => $coursename, 214 ]; 215 $select = 'shortname = :shortname OR fullname = :fullname OR idnumber = :idnumber'; 216 $courseid = $DB->get_field_select('course', 'id', $select, $params, MUST_EXIST); 217 218 $cmid = null; 219 $cms = get_coursemodules_in_course($type, $courseid); 220 foreach ($cms as $cm) { 221 if ($cm->name === $name || $cm->idnumber === $name) { 222 $cmid = $cm->id; 223 break; 224 } 225 } 226 if ($cmid === null) { 227 throw new coding_exception("Activity module '{$name}' of type '{$type}' not found!"); 228 } 229 $context = context_module::instance($cmid); 230 231 $this->set_category_and_purpose($context->id, $category, $purpose); 232 } 233 234 /** 235 * Sets the data category and data storage purpose for a course instance. 236 * 237 * @Given /^I set the category and purpose for the "(?P<blockname_string>(?:[^"]|\\")*)" block in the "(?P<coursename_string>(?:[^"]|\\")*)" course to "(?P<category_string>(?:[^"]|\\")*)" and "(?P<purpose_string>(?:[^"]|\\")*)"$/ 238 * 239 * @param string $name The instance name. It should match the name of the block. (e.g. online_users) 240 * @param string $coursename The course name. It should match the fullname or the shortname, or the idnumber. 241 * @param string $category The ID of the category to be set for the instance. 242 * @param string $purpose The ID of the purpose to be set for the instance. 243 */ 244 public function i_set_the_category_and_purpose_for_block($name, $coursename, $category, $purpose) { 245 global $DB; 246 247 $params = [ 248 'shortname' => $coursename, 249 'fullname' => $coursename, 250 'idnumber' => $coursename, 251 ]; 252 $select = 'shortname = :shortname OR fullname = :fullname OR idnumber = :idnumber'; 253 $courseid = $DB->get_field_select('course', 'id', $select, $params, MUST_EXIST); 254 255 // Fetch the course context. 256 $coursecontext = context_course::instance($courseid); 257 258 // Fetch the block record and context. 259 $blockid = $DB->get_field('block_instances', 'id', ['blockname' => $name, 'parentcontextid' => $coursecontext->id]); 260 $context = context_block::instance($blockid); 261 262 // Set the category and purpose. 263 $this->set_category_and_purpose($context->id, $category, $purpose); 264 } 265 266 /** 267 * Sets the category and purpose for a context instance. 268 * 269 * @param int $contextid The context ID. 270 * @param int $categoryname The category name. 271 * @param int $purposename The purpose name. 272 * @throws coding_exception 273 */ 274 protected function set_category_and_purpose($contextid, $categoryname, $purposename) { 275 $category = \tool_dataprivacy\category::get_record(['name' => $categoryname]); 276 $purpose = \tool_dataprivacy\purpose::get_record(['name' => $purposename]); 277 278 api::set_context_instance((object) [ 279 'contextid' => $contextid, 280 'purposeid' => $purpose->get('id'), 281 'categoryid' => $category->get('id'), 282 ]); 283 } 284 285 /** 286 * Create a dataprivacy request. 287 * 288 * @Given /^I create a dataprivacy "(?P<type_string>(?:[^"]|\\")*)" request for "(?P<user_string>(?:[^"]|\\")*)"$/ 289 * 290 * @param string $type The type of request to create (delete, or export) 291 * @param string $username The username to create for 292 */ 293 public function i_create_a_dataprivacy_request_for($type, $username) { 294 if ($type === 'delete') { 295 $type = \tool_dataprivacy\api::DATAREQUEST_TYPE_DELETE; 296 } else if ($type === 'export') { 297 $type = \tool_dataprivacy\api::DATAREQUEST_TYPE_EXPORT; 298 } else { 299 throw new \Behat\Behat\Tester\Exception\ExpectationException("Unknown request type '{$type}'"); 300 } 301 302 $user = \core_user::get_user_by_username($username); 303 304 \tool_dataprivacy\api::create_data_request($user->id, $type); 305 } 306 307 /** 308 * Approve a dataprivacy request. 309 * 310 * @Given /^I approve a dataprivacy "(?P<type_string>(?:[^"]|\\")*)" request for "(?P<user_string>(?:[^"]|\\")*)"$/ 311 * 312 * @param string $type The type of request to create (delete, or export) 313 * @param string $username The username to create for 314 */ 315 public function i_approve_a_dataprivacy_request_for($type, $username) { 316 if ($type === 'delete') { 317 $type = \tool_dataprivacy\api::DATAREQUEST_TYPE_DELETE; 318 } else if ($type === 'export') { 319 $type = \tool_dataprivacy\api::DATAREQUEST_TYPE_EXPORT; 320 } else { 321 throw new \Behat\Behat\Tester\Exception\ExpectationException("Unknown request type '{$type}'"); 322 } 323 324 $user = \core_user::get_user_by_username($username); 325 326 $request = \tool_dataprivacy\data_request::get_record([ 327 'userid' => $user->id, 328 'type' => $type, 329 'status' => \tool_dataprivacy\api::DATAREQUEST_STATUS_AWAITING_APPROVAL, 330 ]); 331 332 \tool_dataprivacy\api::approve_data_request($request->get('id')); 333 } 334 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body