diff --git a/message/tests/migrate_message_data_task_test.php b/message/tests/migrate_message_data_task_test.php new file mode 100644 index 00000000000..7094a899011 --- /dev/null +++ b/message/tests/migrate_message_data_task_test.php @@ -0,0 +1,314 @@ +. + +/** + * Tests the migrate message data task. + * + * @package core_message + * @category test + * @copyright 2018 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; + +require_once($CFG->dirroot . '/message/tests/messagelib_test.php'); + +/** + * Class for testing the migrate message data task. + * + * @package core_message + * @category test + * @copyright 2018 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_message_migrate_message_data_task_testcase extends advanced_testcase { + + /** + * Test set up. + * + * This is executed before running any test in this file. + */ + public function setUp() { + $this->resetAfterTest(); + } + + /** + * Test migrating legacy messages. + */ + public function test_migrating_messages() { + global $DB; + + // Create users to test with. + $user1 = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $user3 = $this->getDataGenerator()->create_user(); + + // Get the current time minus some, to make sure our data is migrated accurately and just not using the current timestamp. + $now = time(); + $timedeleted1 = $now - (2 * DAYSECS); + $timedeleted2 = $now - (2 * DAYSECS) + 1; + $timeread1 = $now - DAYSECS; + $timeread2 = $now - DAYSECS + 1; + $timeread3 = $now - DAYSECS + 2; + + // Send messages from user 1 to user 2. + $m1 = $this->create_legacy_message_or_notification($user1->id, $user2->id, 1, false, $timeread1); + $m2 = $this->create_legacy_message_or_notification($user1->id, $user2->id, 2); + $m3 = $this->create_legacy_message_or_notification($user1->id, $user2->id, 3); + + // Send messages from user 3 to user 1. + $m4 = $this->create_legacy_message_or_notification($user3->id, $user1->id, 4, false, $timeread2); + $m5 = $this->create_legacy_message_or_notification($user3->id, $user1->id, 5); + $m6 = $this->create_legacy_message_or_notification($user3->id, $user1->id, 6); + + // Send messages from user 3 to user 2. + $m7 = $this->create_legacy_message_or_notification($user3->id, $user2->id, 7, false, $timeread3); + $m8 = $this->create_legacy_message_or_notification($user3->id, $user2->id, 8); + $m9 = $this->create_legacy_message_or_notification($user3->id, $user2->id, 9); + + // Let's delete some messages, not using API here as it does not use the legacy tables. + $messageupdate = new stdClass(); + $messageupdate->id = $m1; + $messageupdate->timeusertodeleted = $timedeleted1; + $DB->update_record('message_read', $messageupdate); + + $messageupdate = new stdClass(); + $messageupdate->id = $m5; + $messageupdate->timeuserfromdeleted = $timedeleted2; + $DB->update_record('message', $messageupdate); + + // Now, let's execute the task for user 1. + $task = new \core_message\task\migrate_message_data(); + $task->set_custom_data( + [ + 'userid' => $user1->id + ] + ); + $task->execute(); + + // Ok, now we need to confirm all is good. + // Remember - we are only converting the messages related to user 1. + $this->assertEquals(2, $DB->count_records('message')); + $this->assertEquals(1, $DB->count_records('message_read')); + $this->assertEquals(6, $DB->count_records('messages')); + + // Get the conversations. + $conversation1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); + $conversation2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]); + + // Confirm what we have in the messages table is correct. + $messages = $DB->get_records('messages', [], 'timecreated ASC'); + $i = 1; + foreach ($messages as $message) { + $useridfrom = $user1->id; + $conversationid = $conversation1; + if ($i > 3) { + $useridfrom = $user3->id; + $conversationid = $conversation2; + } + + if ($i == 1) { + $messagereadid1 = $message->id; + $messagedeletedid1 = $message->id; + } else if ($i == 4) { + $messagereadid2 = $message->id; + } else if ($i == 5) { + $messagedeletedid2 = $message->id; + } + + $this->assertEquals($useridfrom, $message->useridfrom); + $this->assertEquals($conversationid, $message->conversationid); + $this->assertEquals('Subject ' . $i, $message->subject); + $this->assertEquals('Full message ' . $i, $message->fullmessage); + $this->assertEquals(FORMAT_PLAIN, $message->fullmessageformat); + $this->assertEquals('Full message HTML '. $i, $message->fullmessagehtml); + $this->assertEquals('Small message ' . $i, $message->smallmessage); + $this->assertEquals($i, $message->timecreated); + $i++; + } + + // Confirm there are 4 actions. + $this->assertEquals(4, $DB->count_records('message_user_actions')); + + // Confirm the messages that were marked as read have actions associated with them. + $muas = $DB->get_records('message_user_actions', ['action' => \core_message\api::MESSAGE_ACTION_READ], 'timecreated DESC'); + $this->assertCount(2, $muas); + + // Message user action for message read by user 1 (referring to $m4). + $mua1 = array_shift($muas); + // Message user action for message read by user 2 (referring to $m1). + $mua2 = array_shift($muas); + + $this->assertEquals($user1->id, $mua1->userid); + $this->assertEquals($messagereadid2, $mua1->messageid); + $this->assertEquals($timeread2, $mua1->timecreated); + + $this->assertEquals($user2->id, $mua2->userid); + $this->assertEquals($messagereadid1, $mua2->messageid); + $this->assertEquals($timeread1, $mua2->timecreated); + + // Confirm the messages that were deleted have actions associated with them. + $muas = $DB->get_records('message_user_actions', ['action' => \core_message\api::MESSAGE_ACTION_DELETED], + 'timecreated DESC'); + $this->assertCount(2, $muas); + + // Message user action for message deleted by user 3 (referring to $m5). + $mua1 = array_shift($muas); + // Message user action for message deleted by user 2 (referring to $m1). + $mua2 = array_shift($muas); + + $this->assertEquals($user3->id, $mua1->userid); + $this->assertEquals($messagedeletedid2, $mua1->messageid); + $this->assertEquals($timedeleted2, $mua1->timecreated); + + $this->assertEquals($user2->id, $mua2->userid); + $this->assertEquals($messagedeletedid1, $mua2->messageid); + $this->assertEquals($timedeleted1, $mua2->timecreated); + } + + /** + * Test migrating legacy notifications. + */ + public function test_migrating_notifications() { + global $DB; + + // Create users to test with. + $user1 = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $user3 = $this->getDataGenerator()->create_user(); + + // Get the current time minus some, to make sure our data is migrated accurately and just not using the current timestamp. + $timeread = time() - DAYSECS; + + // Send notifications from user 1 to user 2. + $this->create_legacy_message_or_notification($user1->id, $user2->id, 1, true, $timeread); + $this->create_legacy_message_or_notification($user1->id, $user2->id, 2, true); + $this->create_legacy_message_or_notification($user1->id, $user2->id, 3, true); + + // Send notifications from user 3 to user 1. + $this->create_legacy_message_or_notification($user3->id, $user1->id, 4, true, $timeread); + $this->create_legacy_message_or_notification($user3->id, $user1->id, 5, true); + $this->create_legacy_message_or_notification($user3->id, $user1->id, 6, true); + + // Send notifications from user 3 to user 2. + $this->create_legacy_message_or_notification($user3->id, $user2->id, 7, true, $timeread); + $this->create_legacy_message_or_notification($user3->id, $user2->id, 8, true); + $this->create_legacy_message_or_notification($user3->id, $user2->id, 9, true); + + // Now, let's execute the task for user 1. + $task = new \core_message\task\migrate_message_data(); + $task->set_custom_data( + [ + 'userid' => $user1->id + ] + ); + $task->execute(); + + // Ok, now we need to confirm all is good. + // Remember - we are only converting the notifications related to user 1. + $this->assertEquals(2, $DB->count_records('message')); + $this->assertEquals(1, $DB->count_records('message_read')); + $this->assertEquals(6, $DB->count_records('notifications')); + + // Confirm what we have in the notifications table is correct. + $notifications = $DB->get_records('notifications', [], 'timecreated ASC'); + $i = 1; + foreach ($notifications as $notification) { + $useridfrom = $user1->id; + $useridto = $user2->id; + if ($i > 3) { + $useridfrom = $user3->id; + $useridto = $user1->id; + } + + $this->assertEquals($useridfrom, $notification->useridfrom); + $this->assertEquals($useridto, $notification->useridto); + $this->assertEquals('Subject ' . $i, $notification->subject); + $this->assertEquals('Full message ' . $i, $notification->fullmessage); + $this->assertEquals(FORMAT_PLAIN, $notification->fullmessageformat); + $this->assertEquals('Full message HTML '. $i, $notification->fullmessagehtml); + $this->assertEquals('Small message ' . $i, $notification->smallmessage); + $this->assertEquals('mod_assign', $notification->component); + $this->assertEquals('assign_notification', $notification->eventtype); + $this->assertEquals('https://www.google.com', $notification->contexturl); + $this->assertEquals('google', $notification->contexturlname); + $this->assertEquals($i, $notification->timecreated); + + if (($i == 1) || ($i == 4)) { + $this->assertEquals($timeread, $notification->timeread); + } else { + $this->assertNull($notification->timeread); + } + + $i++; + } + } + + /** + * Creates a legacy message or notification to be used for testing. + * + * @param int $useridfrom The user id from + * @param int $useridto The user id to + * @param int $timecreated + * @param bool $notification + * @param int|null $timeread The time the message/notification was read, null if it hasn't been. + * @return int The id of the message (in either the message or message_read table) + * @throws dml_exception + */ + private function create_legacy_message_or_notification($useridfrom, $useridto, $timecreated = null, + $notification = false, $timeread = null) { + global $DB; + + $tabledata = new \stdClass(); + + if (is_null($timecreated)) { + $timecreated = time(); + } + + if (!is_null($timeread)) { + $table = 'message_read'; + $tabledata->timeread = $timeread; + } else { + $table = 'message'; + } + + if ($notification) { + $tabledata->eventtype = 'assign_notification'; + $tabledata->component = 'mod_assign'; + $tabledata->notification = 1; + $tabledata->contexturl = 'https://www.google.com'; + $tabledata->contexturlname = 'google'; + } else { + $tabledata->eventtype = 'instantmessage'; + $tabledata->component = 'moodle'; + $tabledata->notification = 0; + } + + $tabledata->useridfrom = $useridfrom; + $tabledata->useridto = $useridto; + $tabledata->subject = 'Subject ' . $timecreated; + $tabledata->fullmessage = 'Full message ' . $timecreated; + $tabledata->fullmessageformat = FORMAT_PLAIN; + $tabledata->fullmessagehtml = 'Full message HTML ' . $timecreated; + $tabledata->smallmessage = 'Small message ' . $timecreated; + $tabledata->timecreated = $timecreated; + + return $DB->insert_record($table, $tabledata); + } +}