Proyectos de Subversion Moodle

Rev

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