on-demand release 3.5beta+
[moodle.git] / admin / tool / dataprivacy / tests / expired_contexts_test.php
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/>.
17 /**
18  * Expired contexts tests.
19  *
20  * @package    tool_dataprivacy
21  * @copyright  2018 David Monllao
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 use tool_dataprivacy\api;
26 use tool_dataprivacy\data_registry;
27 use tool_dataprivacy\expired_context;
29 defined('MOODLE_INTERNAL') || die();
30 global $CFG;
32 /**
33  * Expired contexts tests.
34  *
35  * @package    tool_dataprivacy
36  * @copyright  2018 David Monllao
37  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class tool_dataprivacy_expired_contexts_testcase extends advanced_testcase {
41     /**
42      * setUp.
43      */
44     public function setUp() {
45         $this->resetAfterTest();
46         $this->setAdminUser();
47     }
49     /**
50      * Test expired users flagging and deletion.
51      *
52      * @return null
53      */
54     public function test_expired_users() {
55         global $DB;
57         $purpose = api::create_purpose((object)['name' => 'p1', 'retentionperiod' => 'PT1H', 'lawfulbases' => 'gdpr_art_6_1_a']);
58         $cat = api::create_category((object)['name' => 'a']);
60         $record = (object)[
61             'purposeid' => $purpose->get('id'),
62             'categoryid' => $cat->get('id'),
63             'contextlevel' => CONTEXT_SYSTEM,
64         ];
65         api::set_contextlevel($record);
66         $record->contextlevel = CONTEXT_USER;
67         api::set_contextlevel($record);
69         $userdata = ['lastaccess' => '123'];
70         $user1 = $this->getDataGenerator()->create_user($userdata);
71         $user2 = $this->getDataGenerator()->create_user($userdata);
72         $user3 = $this->getDataGenerator()->create_user($userdata);
73         $user4 = $this->getDataGenerator()->create_user($userdata);
74         $user5 = $this->getDataGenerator()->create_user();
76         $course1 = $this->getDataGenerator()->create_course();
77         // Old course.
78         $course2 = $this->getDataGenerator()->create_course(['startdate' => '1', 'enddate' => '2']);
79         // Ongoing course.
80         $course3 = $this->getDataGenerator()->create_course(['startdate' => '1', 'enddate' => time() + YEARSECS]);
82         $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
83         $this->getDataGenerator()->enrol_user($user2->id, $course2->id, 'student');
84         $this->getDataGenerator()->enrol_user($user3->id, $course2->id, 'student');
85         $this->getDataGenerator()->enrol_user($user4->id, $course3->id, 'student');
87         // Users without lastaccess are skipped as well as users enroled in courses with no end date.
88         $expired = new \tool_dataprivacy\expired_user_contexts();
89         $numexpired = $expired->flag_expired();
90         $this->assertEquals(2, $numexpired);
91         $this->assertEquals(2, $DB->count_records('tool_dataprivacy_ctxexpired', ['status' => expired_context::STATUS_EXPIRED]));
93         // Approve user2 to be deleted.
94         $user2ctx = \context_user::instance($user2->id);
95         $expiredctx = expired_context::get_record(['contextid' => $user2ctx->id]);
96         api::set_expired_context_status($expiredctx, expired_context::STATUS_APPROVED);
97         $this->assertEquals(1, $DB->count_records('tool_dataprivacy_ctxexpired', ['status' => expired_context::STATUS_APPROVED]));
99         // Delete expired contexts.
100         $deleted = $expired->delete();
101         $this->assertEquals(1, $deleted);
102         $this->assertEquals(1, $DB->count_records('tool_dataprivacy_ctxexpired', ['status' => expired_context::STATUS_EXPIRED]));
103         $this->assertEquals(1, $DB->count_records('tool_dataprivacy_ctxexpired', ['status' => expired_context::STATUS_CLEANED]));
105         // No new records are generated.
106         $numexpired = $expired->flag_expired();
107         $this->assertEquals(0, $numexpired);
108         $this->assertEquals(2, $DB->count_records('tool_dataprivacy_ctxexpired'));
109         $deleted = $expired->delete();
110         $this->assertEquals(0, $deleted);
112         // The user is deleted.
113         $deleteduser = \core_user::get_user($user2->id, 'id, deleted', IGNORE_MISSING);
114         $this->assertEquals(1, $deleteduser->deleted);
115     }
117     /**
118      * Test expired course and course stuff flagging and deletion.
119      *
120      * @return null
121      */
122     public function test_expired_course_related_contexts() {
123         global $DB;
125         $purpose1 = api::create_purpose((object)['name' => 'p1', 'retentionperiod' => 'PT1H', 'lawfulbases' => 'gdpr_art_6_1_a']);
126         $purpose2 = api::create_purpose((object)['name' => 'p1', 'retentionperiod' => 'P1000Y', 'lawfulbases' => 'gdpr_art_6_1_b']);
127         $cat = api::create_category((object)['name' => 'a']);
129         $record = (object)[
130             'purposeid' => $purpose1->get('id'),
131             'categoryid' => $cat->get('id'),
132             'contextlevel' => CONTEXT_SYSTEM,
133         ];
134         api::set_contextlevel($record);
136         list($purposevar, $categoryvar) = data_registry::var_names_from_context(
137             \context_helper::get_class_for_level(CONTEXT_COURSE)
138         );
139         set_config($purposevar, $purpose1->get('id'), 'tool_dataprivacy');
141         // A lot more time for modules.
142         list($purposevar, $categoryvar) = data_registry::var_names_from_context(
143             \context_helper::get_class_for_level(CONTEXT_MODULE)
144         );
145         set_config($purposevar, $purpose2->get('id'), 'tool_dataprivacy');
147         $course1 = $this->getDataGenerator()->create_course();
149         // Old course.
150         $course2 = $this->getDataGenerator()->create_course(['startdate' => '1', 'enddate' => '2']);
151         $forum1 = $this->getDataGenerator()->create_module('forum', array('course' => $course2->id));
152         $forum2 = $this->getDataGenerator()->create_module('forum', array('course' => $course2->id));
154         // We want to override this last module instance purpose so we can test that modules are also
155         // returned as expired.
156         $forum2ctx = \context_module::instance($forum2->cmid);
157         $record = (object)[
158             'purposeid' => $purpose1->get('id'),
159             'categoryid' => $cat->get('id'),
160             'contextid' => $forum2ctx->id,
161         ];
162         api::set_context_instance($record);
164         // Ongoing course.
165         $course3 = $this->getDataGenerator()->create_course(['startdate' => '1', 'enddate' => time()]);
166         $forum3 = $this->getDataGenerator()->create_module('forum', array('course' => $course3->id));
168         $expired = new \tool_dataprivacy\expired_course_related_contexts();
169         $numexpired = $expired->flag_expired();
171         // Only 1 module has expired.
172         $this->assertEquals(1, $numexpired);
173         $this->assertEquals(1, $DB->count_records('tool_dataprivacy_ctxexpired', ['status' => expired_context::STATUS_EXPIRED]));
175         // Add a forum1 override to 1h retention period so both forum1 and course2 are also expired.
176         $forum1ctx = \context_module::instance($forum1->cmid);
177         $record->purposeid = $purpose1->get('id');
178         $record->contextid = $forum1ctx->id;
179         api::set_context_instance($record);
180         $numexpired = $expired->flag_expired();
181         $this->assertEquals(2, $numexpired);
182         $this->assertEquals(3, $DB->count_records('tool_dataprivacy_ctxexpired', ['status' => expired_context::STATUS_EXPIRED]));
184         // Approve forum1 to be deleted.
185         $expiredctx = expired_context::get_record(['contextid' => $forum1ctx->id]);
186         api::set_expired_context_status($expiredctx, expired_context::STATUS_APPROVED);
188         // Delete expired contexts.
189         $deleted = $expired->delete();
190         $this->assertEquals(1, $deleted);
191         $this->assertEquals(1, $DB->count_records('tool_dataprivacy_ctxexpired', ['status' => expired_context::STATUS_CLEANED]));
193         $expiredctx = expired_context::get_record(['contextid' => $forum2ctx->id]);
194         api::set_expired_context_status($expiredctx, expired_context::STATUS_APPROVED);
196         $course2ctx = \context_course::instance($course2->id);
197         $expiredctx = expired_context::get_record(['contextid' => $course2ctx->id]);
198         api::set_expired_context_status($expiredctx, expired_context::STATUS_APPROVED);
200         // Delete expired contexts.
201         $deleted = $expired->delete();
202         $this->assertEquals(2, $deleted);
203         $this->assertEquals(3, $DB->count_records('tool_dataprivacy_ctxexpired', ['status' => expired_context::STATUS_CLEANED]));
205         // No new records are generated.
206         $numexpired = $expired->flag_expired();
207         $this->assertEquals(0, $numexpired);
208         $this->assertEquals(3, $DB->count_records('tool_dataprivacy_ctxexpired'));
209         $deleted = $expired->delete();
210         $this->assertEquals(0, $deleted);
212     }