MDL-62597 Privacy: Request date column should include time
[moodle.git] / message / tests / migrate_message_data_task_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  * Tests the migrate message data task.
19  *
20  * @package core_message
21  * @category test
22  * @copyright 2018 Mark Nelson <markn@moodle.com>
23  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
30 require_once($CFG->dirroot . '/message/tests/messagelib_test.php');
32 /**
33  * Class for testing the migrate message data task.
34  *
35  * @package core_message
36  * @category test
37  * @copyright 2018 Mark Nelson <markn@moodle.com>
38  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39  */
40 class core_message_migrate_message_data_task_testcase extends advanced_testcase {
42     /**
43      * Test set up.
44      *
45      * This is executed before running any test in this file.
46      */
47     public function setUp() {
48         $this->resetAfterTest();
49     }
51     /**
52      * Test migrating legacy messages.
53      */
54     public function test_migrating_messages() {
55         global $DB;
57         // Create users to test with.
58         $user1 = $this->getDataGenerator()->create_user();
59         $user2 = $this->getDataGenerator()->create_user();
60         $user3 = $this->getDataGenerator()->create_user();
62         // Get the current time minus some, to make sure our data is migrated accurately and just not using the current timestamp.
63         $now = time();
64         $timedeleted1 = $now - (2 * DAYSECS);
65         $timedeleted2 = $now - (2 * DAYSECS) + 1;
66         $timeread1 = $now - DAYSECS;
67         $timeread2 = $now - DAYSECS + 1;
68         $timeread3 = $now - DAYSECS + 2;
70         // Send messages from user 1 to user 2.
71         $m1 = $this->create_legacy_message_or_notification($user1->id, $user2->id, 1, false, $timeread1);
72         $m2 = $this->create_legacy_message_or_notification($user1->id, $user2->id, 2);
73         $m3 = $this->create_legacy_message_or_notification($user1->id, $user2->id, 3);
75         // Send messages from user 3 to user 1.
76         $m4 = $this->create_legacy_message_or_notification($user3->id, $user1->id, 4, false, $timeread2);
77         $m5 = $this->create_legacy_message_or_notification($user3->id, $user1->id, 5);
78         $m6 = $this->create_legacy_message_or_notification($user3->id, $user1->id, 6);
80         // Send messages from user 3 to user 2.
81         $m7 = $this->create_legacy_message_or_notification($user3->id, $user2->id, 7, false, $timeread3);
82         $m8 = $this->create_legacy_message_or_notification($user3->id, $user2->id, 8);
83         $m9 = $this->create_legacy_message_or_notification($user3->id, $user2->id, 9);
85         // Let's delete some messages, not using API here as it does not use the legacy tables.
86         $messageupdate = new stdClass();
87         $messageupdate->id = $m1;
88         $messageupdate->timeusertodeleted = $timedeleted1;
89         $DB->update_record('message_read', $messageupdate);
91         $messageupdate = new stdClass();
92         $messageupdate->id = $m5;
93         $messageupdate->timeuserfromdeleted = $timedeleted2;
94         $DB->update_record('message', $messageupdate);
96         // Now, let's execute the task for user 1.
97         $task = new \core_message\task\migrate_message_data();
98         $task->set_custom_data(
99             [
100                 'userid' => $user1->id
101             ]
102         );
103         $task->execute();
105         // Ok, now we need to confirm all is good.
106         // Remember - we are only converting the messages related to user 1.
107         $this->assertEquals(2, $DB->count_records('message'));
108         $this->assertEquals(1, $DB->count_records('message_read'));
109         $this->assertEquals(6, $DB->count_records('messages'));
110         $this->assertEquals(0, $DB->count_records('notifications'));
111         $this->assertEquals(0, $DB->count_records('message_popup_notifications'));
113         // Get the conversations.
114         $conversation1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
115         $conversation2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
117         // Confirm what we have in the messages table is correct.
118         $messages = $DB->get_records('messages', [], 'timecreated ASC');
119         $i = 1;
120         foreach ($messages as $message) {
121             $useridfrom = $user1->id;
122             $conversationid = $conversation1;
123             if ($i > 3) {
124                 $useridfrom = $user3->id;
125                 $conversationid = $conversation2;
126             }
128             if ($i == 1) {
129                 $messagereadid1 = $message->id;
130                 $messagedeletedid1 = $message->id;
131             } else if ($i == 4) {
132                 $messagereadid2 = $message->id;
133             } else if ($i == 5) {
134                 $messagedeletedid2 = $message->id;
135             }
137             $this->assertEquals($useridfrom, $message->useridfrom);
138             $this->assertEquals($conversationid, $message->conversationid);
139             $this->assertEquals('Subject ' . $i, $message->subject);
140             $this->assertEquals('Full message ' . $i, $message->fullmessage);
141             $this->assertEquals(FORMAT_PLAIN, $message->fullmessageformat);
142             $this->assertEquals('Full message HTML '. $i, $message->fullmessagehtml);
143             $this->assertEquals('Small message ' . $i, $message->smallmessage);
144             $this->assertEquals($i, $message->timecreated);
145             $i++;
146         }
148         // Confirm there are 4 actions.
149         $this->assertEquals(4, $DB->count_records('message_user_actions'));
151         // Confirm the messages that were marked as read have actions associated with them.
152         $muas = $DB->get_records('message_user_actions', ['action' => \core_message\api::MESSAGE_ACTION_READ], 'timecreated DESC');
153         $this->assertCount(2, $muas);
155         // Message user action for message read by user 1 (referring to $m4).
156         $mua1 = array_shift($muas);
157         // Message user action for message read by user 2 (referring to $m1).
158         $mua2 = array_shift($muas);
160         $this->assertEquals($user1->id, $mua1->userid);
161         $this->assertEquals($messagereadid2, $mua1->messageid);
162         $this->assertEquals($timeread2, $mua1->timecreated);
164         $this->assertEquals($user2->id, $mua2->userid);
165         $this->assertEquals($messagereadid1, $mua2->messageid);
166         $this->assertEquals($timeread1, $mua2->timecreated);
168         // Confirm the messages that were deleted have actions associated with them.
169         $muas = $DB->get_records('message_user_actions', ['action' => \core_message\api::MESSAGE_ACTION_DELETED],
170             'timecreated DESC');
171         $this->assertCount(2, $muas);
173         // Message user action for message deleted by user 3 (referring to $m5).
174         $mua1 = array_shift($muas);
175         // Message user action for message deleted by user 2 (referring to $m1).
176         $mua2 = array_shift($muas);
178         $this->assertEquals($user3->id, $mua1->userid);
179         $this->assertEquals($messagedeletedid2, $mua1->messageid);
180         $this->assertEquals($timedeleted2, $mua1->timecreated);
182         $this->assertEquals($user2->id, $mua2->userid);
183         $this->assertEquals($messagedeletedid1, $mua2->messageid);
184         $this->assertEquals($timedeleted1, $mua2->timecreated);
185     }
187     /**
188      * Test migrating legacy notifications.
189      */
190     public function test_migrating_notifications() {
191         global $DB;
193         // Create users to test with.
194         $user1 = $this->getDataGenerator()->create_user();
195         $user2 = $this->getDataGenerator()->create_user();
196         $user3 = $this->getDataGenerator()->create_user();
198         // Get the current time minus some, to make sure our data is migrated accurately and just not using the current timestamp.
199         $timeread = time() - DAYSECS;
201         // Send notifications from user 1 to user 2.
202         $this->create_legacy_message_or_notification($user1->id, $user2->id, 1, true, $timeread);
203         $this->create_legacy_message_or_notification($user1->id, $user2->id, 2, true);
204         $this->create_legacy_message_or_notification($user1->id, $user2->id, 3, true);
206         // Send notifications from user 3 to user 1.
207         $this->create_legacy_message_or_notification($user3->id, $user1->id, 4, true, $timeread);
208         $this->create_legacy_message_or_notification($user3->id, $user1->id, 5, true);
209         $this->create_legacy_message_or_notification($user3->id, $user1->id, 6, true);
211         // Send notifications from user 3 to user 2.
212         $this->create_legacy_message_or_notification($user3->id, $user2->id, 7, true, $timeread);
213         $this->create_legacy_message_or_notification($user3->id, $user2->id, 8, true);
214         $this->create_legacy_message_or_notification($user3->id, $user2->id, 9, true);
216         // Now, let's execute the task for user 1.
217         $task = new \core_message\task\migrate_message_data();
218         $task->set_custom_data(
219             [
220                 'userid' => $user1->id
221             ]
222         );
223         $task->execute();
225         // Ok, now we need to confirm all is good.
226         // Remember - we are only converting the notifications related to user 1.
227         $this->assertEquals(2, $DB->count_records('message'));
228         $this->assertEquals(1, $DB->count_records('message_read'));
229         $this->assertEquals(3, $DB->count_records('message_popup'));
230         $this->assertEquals(6, $DB->count_records('notifications'));
231         $this->assertEquals(6, $DB->count_records('message_popup_notifications'));
233         // Confirm what we have in the notifications table is correct.
234         $notifications = $DB->get_records('notifications', [], 'timecreated ASC');
235         $popupnotifications = $DB->get_records('message_popup_notifications', [], 'notificationid ASC', 'notificationid');
236         $i = 1;
237         foreach ($notifications as $notification) {
238             // Assert the correct id is stored in the 'message_popup_notifications' table.
239             $this->assertArrayHasKey($notification->id, $popupnotifications);
241             $useridfrom = $user1->id;
242             $useridto = $user2->id;
243             if ($i > 3) {
244                 $useridfrom = $user3->id;
245                 $useridto = $user1->id;
246             }
248             $this->assertEquals($useridfrom, $notification->useridfrom);
249             $this->assertEquals($useridto, $notification->useridto);
250             $this->assertEquals('Subject ' . $i, $notification->subject);
251             $this->assertEquals('Full message ' . $i, $notification->fullmessage);
252             $this->assertEquals(FORMAT_PLAIN, $notification->fullmessageformat);
253             $this->assertEquals('Full message HTML '. $i, $notification->fullmessagehtml);
254             $this->assertEquals('Small message ' . $i, $notification->smallmessage);
255             $this->assertEquals('mod_assign', $notification->component);
256             $this->assertEquals('assign_notification', $notification->eventtype);
257             $this->assertEquals('https://www.google.com', $notification->contexturl);
258             $this->assertEquals('google', $notification->contexturlname);
259             $this->assertEquals($i, $notification->timecreated);
261             if (($i == 1) || ($i == 4)) {
262                 $this->assertEquals($timeread, $notification->timeread);
263             } else {
264                 $this->assertNull($notification->timeread);
265             }
267             $i++;
268         }
269     }
271     /**
272      * Creates a legacy message or notification to be used for testing.
273      *
274      * @param int $useridfrom The user id from
275      * @param int $useridto The user id to
276      * @param int $timecreated
277      * @param bool $notification
278      * @param int|null $timeread The time the message/notification was read, null if it hasn't been.
279      * @return int The id of the message (in either the message or message_read table)
280      * @throws dml_exception
281      */
282     private function create_legacy_message_or_notification($useridfrom, $useridto, $timecreated = null,
283             $notification = false, $timeread = null) {
284         global $DB;
286         $tabledata = new \stdClass();
288         if (is_null($timecreated)) {
289             $timecreated = time();
290         }
292         if (!is_null($timeread)) {
293             $table = 'message_read';
294             $tabledata->timeread = $timeread;
295         } else {
296             $table = 'message';
297         }
299         if ($notification) {
300             $tabledata->eventtype = 'assign_notification';
301             $tabledata->component = 'mod_assign';
302             $tabledata->notification = 1;
303             $tabledata->contexturl = 'https://www.google.com';
304             $tabledata->contexturlname = 'google';
305         } else {
306             $tabledata->eventtype = 'instantmessage';
307             $tabledata->component = 'moodle';
308             $tabledata->notification = 0;
309         }
311         $tabledata->useridfrom = $useridfrom;
312         $tabledata->useridto = $useridto;
313         $tabledata->subject = 'Subject ' . $timecreated;
314         $tabledata->fullmessage = 'Full message ' . $timecreated;
315         $tabledata->fullmessageformat = FORMAT_PLAIN;
316         $tabledata->fullmessagehtml = 'Full message HTML ' . $timecreated;
317         $tabledata->smallmessage = 'Small message ' . $timecreated;
318         $tabledata->timecreated = $timecreated;
320         $id = $DB->insert_record($table, $tabledata);
322         // Insert into the legacy 'message_popup' table if it is a notification.
323         if ($notification) {
324             $mp = new stdClass();
325             $mp->messageid = $id;
326             $mp->isread = (!is_null($timeread)) ? 1 : 0;
328             $DB->insert_record('message_popup', $mp);
329         }
331         return $id;
332     }