MDL-63692 core_message: Add favourite conversations to Privacy API
authorSara Arjona <sara@moodle.com>
Mon, 12 Nov 2018 19:15:35 +0000 (20:15 +0100)
committerSara Arjona <sara@moodle.com>
Mon, 19 Nov 2018 21:09:13 +0000 (22:09 +0100)
favourites/classes/privacy/provider.php
lang/en/message.php
message/classes/privacy/provider.php
message/tests/privacy_provider_test.php

index 44a076f..99757f0 100644 (file)
@@ -172,9 +172,11 @@ class provider implements
      * @param \context $context The context to which deletion is scoped.
      * @param string $component The favourite's component name.
      * @param string $itemtype The favourite's itemtype.
+     * @param int $itemid Optional itemid associated with component.
      * @throws \dml_exception if any errors are encountered during deletion.
      */
-    public static function delete_favourites_for_all_users(\context $context, string $component, string $itemtype) {
+    public static function delete_favourites_for_all_users(\context $context, string $component, string $itemtype,
+                                                           int $itemid = 0) {
         global $DB;
 
         $params = [
@@ -184,6 +186,11 @@ class provider implements
         ];
 
         $select = "component = :component AND itemtype =:itemtype AND contextid = :contextid";
+
+        if (!empty($itemid)) {
+            $select .= " AND itemid = :itemid";
+            $params['itemid'] = $itemid;
+        }
         $DB->delete_records_select('favourite', $select, $params);
     }
 
@@ -193,10 +200,11 @@ class provider implements
      * @param \core_privacy\local\request\approved_userlist $userlist The approved contexts and user information
      * to delete information for.
      * @param string $itemtype The favourite's itemtype.
+     * @param int $itemid Optional itemid associated with component.
      * @throws \dml_exception if any errors are encountered during deletion.
      */
     public static function delete_favourites_for_userlist(\core_privacy\local\request\approved_userlist $userlist,
-                                                          string $itemtype) {
+                                                          string $itemtype, int $itemid = 0) {
         global $DB;
 
         $userids = $userlist->get_userids();
@@ -217,6 +225,11 @@ class provider implements
         $params += $userparams;
         $select = "component = :component AND itemtype = :itemtype AND contextid = :contextid AND userid $usersql";
 
+        if (!empty($itemid)) {
+            $select .= " AND itemid = :itemid";
+            $params['itemid'] = $itemid;
+        }
+
         $DB->delete_records_select('favourite', $select, $params);
     }
 
@@ -224,12 +237,14 @@ class provider implements
      * Delete all favourites for the specified user, in the specified contexts.
      *
      * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
-     * @param string $component
-     * @param string $itemtype
+     * @param string $component The favourite's component name.
+     * @param string $itemtype The favourite's itemtype.
+     * @param int $itemid Optional itemid associated with component.
      * @throws \coding_exception
      * @throws \dml_exception
      */
-    public static function delete_favourites_for_user(approved_contextlist $contextlist, string $component, string $itemtype) {
+    public static function delete_favourites_for_user(approved_contextlist $contextlist, string $component, string $itemtype,
+                                                      int $itemid = 0) {
         global $DB;
 
         $userid = $contextlist->get_user()->id;
@@ -244,6 +259,12 @@ class provider implements
         $params += $inparams;
 
         $select = "userid = :userid AND component = :component AND itemtype =:itemtype AND contextid $insql";
+
+        if (!empty($itemid)) {
+            $select .= " AND itemid = :itemid";
+            $params['itemid'] = $itemid;
+        }
+
         $DB->delete_records_select('favourite', $select, $params);
     }
 }
index 2ec14d9..48864b1 100644 (file)
@@ -107,6 +107,7 @@ $string['outputenabled'] = 'Output enabled';
 $string['outputnotavailable'] = 'Not available';
 $string['outputnotconfigured'] = 'Not configured';
 $string['permitted'] = 'Permitted';
+$string['privacy:metadata:core_favourites'] = 'The conversations starred by the user';
 $string['privacy:metadata:messages'] = 'Messages';
 $string['privacy:metadata:messages:conversationid'] = 'The ID of the conversation';
 $string['privacy:metadata:messages:fullmessage'] = 'The full message';
index adee354..fbd6842 100644 (file)
@@ -157,6 +157,9 @@ class provider implements
         $items->add_user_preference('core_message_messageprovider_settings',
             'privacy:metadata:preference:core_message_settings');
 
+        // Add favourite conversations.
+        $items->link_subsystem('core_favourites', 'privacy:metadata:core_favourites');
+
         return $items;
     }
 
@@ -224,6 +227,9 @@ class provider implements
             $contextlist->add_user_context($userid);
         }
 
+        // Add favourite conversations.
+        \core_favourites\privacy\provider::add_contexts_for_userid($contextlist, $userid, 'core_message', 'message_conversations');
+
         return $contextlist;
     }
 
@@ -273,6 +279,16 @@ class provider implements
         if ($hasdata) {
             $userlist->add_user($userid);
         }
+
+        // Add favourite conversations.
+        $component = $userlist->get_component();
+        if ($component != 'core_message') {
+            $userlist->set_component('core_message');
+        }
+        \core_favourites\privacy\provider::add_userids_for_context($userlist, 'message_conversations');
+        if ($component != 'core_message') {
+            $userlist->set_component($component);
+        }
     }
 
     /**
@@ -407,6 +423,10 @@ class provider implements
         }
 
         $contextlist->add_from_sql($sql, $params);
+
+        // Add favourite conversations. We don't need to filter by itemid because for now they are in the system context.
+        \core_favourites\privacy\provider::add_contexts_for_userid($contextlist, $userid, 'core_message', 'message_conversations');
+
     }
 
     /**
@@ -435,6 +455,16 @@ class provider implements
         }
 
         $userlist->add_from_sql('userid', $sql, $params);
+
+        // Add favourite conversations.
+        $component = $userlist->get_component();
+        if ($component != 'core_message') {
+            $userlist->set_component('core_message');
+        }
+        \core_favourites\privacy\provider::add_userids_for_context($userlist, 'message_conversations');
+        if ($component != 'core_message') {
+            $userlist->set_component($component);
+        }
     }
 
     /**
@@ -519,6 +549,15 @@ class provider implements
             $messageids = $DB->get_records_list('messages', 'conversationid', $conversationids);
             $messageids = array_keys($messageids);
 
+            // Delete these favourite conversations to all the users.
+            foreach ($conversationids as $conversationid) {
+                \core_favourites\privacy\provider::delete_favourites_for_all_users(
+                    $context,
+                    'core_message',
+                    'message_conversations',
+                    $conversationid);
+            }
+
             // Delete messages and user_actions.
             $DB->delete_records_list('message_user_actions', 'messageid', $messageids);
             $DB->delete_records_list('messages', 'id', $messageids);
@@ -629,6 +668,13 @@ class provider implements
             $sql = "conversationid $conversationidsql AND userid $useridsql";
             // Reuse the $params var because it contains the useridparams and the conversationids.
             $DB->delete_records_select('message_conversation_members', $sql, $params);
+
+            // Delete the favourite conversations.
+            $userlist = new \core_privacy\local\request\approved_userlist($context, 'core_message', $userids);
+            \core_favourites\privacy\provider::delete_favourites_for_userlist(
+                $userlist,
+                'message_conversations'
+            );
         }
     }
 
@@ -712,6 +758,24 @@ class provider implements
             $sql = "conversationid $conversationidsql AND userid = :userid";
             // Reuse the $params var because it contains the userid and the conversationids.
             $DB->delete_records_select('message_conversation_members', $sql, $params);
+
+            // Delete the favourite conversations.
+            if (empty($contextids) && empty($component) && empty($itemtype) && empty($itemid)) {
+                // Favourites for individual conversations are stored into the user context.
+                $favouritectxids = [\context_user::instance($userid)->id];
+            } else {
+                $favouritectxids = $contextids;
+            }
+            $contextlist = new \core_privacy\local\request\approved_contextlist(
+                \core_user::get_user($userid),
+                'core_message',
+                $favouritectxids
+            );
+            \core_favourites\privacy\provider::delete_favourites_for_user(
+                $contextlist,
+                'core_message',
+                'message_conversations'
+            );
         }
     }
 
@@ -874,6 +938,9 @@ class provider implements
                     $subcontext,
                     [get_string('messages', 'core_message'), $otherusertext]
                 );
+
+                // Get the context for the favourite conversation.
+                $conversationctx = \context_user::instance($userid);
             } else {
                 // Conversations with context are stored in 'Messages | <Conversation item type> | <Conversation name>'.
                 if (get_string_manager()->string_exists($conversation->itemtype, $conversation->component)) {
@@ -888,10 +955,21 @@ class provider implements
                     $subcontext,
                     [get_string('messages', 'core_message'), $itemtypestring, $conversationname]
                 );
+
+                // Get the context for the favourite conversation.
+                $conversationctx = \context::instance_by_id($conversation->contextid);
             }
 
             // Export the conversation messages.
             writer::with_context($context)->export_data($subcontext, (object) $messagedata);
+
+            // Get user's favourites information for the particular conversation.
+            $conversationfavourite = \core_favourites\privacy\provider::get_favourites_info_for_user($userid, $conversationctx,
+                'core_message', 'message_conversations', $conversation->id);
+            if ($conversationfavourite) {
+                // If the conversation has been favorited by the user, include it in the export.
+                writer::with_context($context)->export_related_data($subcontext, 'starred', (object) $conversationfavourite);
+            }
         }
     }
 
index 1a63583..127f27f 100644 (file)
@@ -47,7 +47,7 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $collection = new collection('core_message');
         $newcollection = provider::get_metadata($collection);
         $itemcollection = $newcollection->get_collection();
-        $this->assertCount(8, $itemcollection);
+        $this->assertCount(9, $itemcollection);
 
         $messagestable = array_shift($itemcollection);
         $this->assertEquals('messages', $messagestable->get_name());
@@ -73,6 +73,10 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $usersettings = array_shift($itemcollection);
         $this->assertEquals('core_message_messageprovider_settings', $usersettings->get_name());
 
+        $favouriteconversations = array_shift($itemcollection);
+        $this->assertEquals('core_favourites', $favouriteconversations->get_name());
+        $this->assertEquals('privacy:metadata:core_favourites', $favouriteconversations->get_summary());
+
         $privacyfields = $messagestable->get_privacy_fields();
         $this->assertArrayHasKey('useridfrom', $privacyfields);
         $this->assertArrayHasKey('conversationid', $privacyfields);
@@ -1570,7 +1574,11 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
         $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
 
+        // Send some private messages between user 1 and user 2.
+        $pm1id = $this->create_message($user1->id, $user2->id, $now);
+
         // Get conversation.
+        $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
         $component = 'core_group';
         $itemtype = 'groups';
         $conversation1 = \core_message\api::get_conversation_by_area(
@@ -1580,6 +1588,10 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
             $coursecontext1->id
         );
 
+        // Make favourite some conversations.
+        \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
+        \core_message\api::set_favourite_conversation($iconversation1id, $user2->id);
+
         // Send some messages to the conversation.
         $m1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1', $now + 1);
         $m2 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 2', $now + 2);
@@ -1589,9 +1601,6 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $dbm2 = $DB->get_record('messages', ['id' => $m2]);
         $dbm3 = $DB->get_record('messages', ['id' => $m3]);
 
-        // Send some private messages between user 1 and user 2.
-        $pm1id = $this->create_message($user1->id, $user2->id, $now);
-
         // Mark as read and delete some messages.
         \core_message\api::mark_message_as_read($user1->id, $dbm3, $now + 5);
         \core_message\api::delete_message($user1->id, $m2);
@@ -1645,6 +1654,18 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->assertEquals(transform::datetime($now + 5), $m3->timeread);
         $this->assertArrayNotHasKey('timedeleted', (array) $m3);
 
+        // Confirm the favourite group conversation is correct.
+        $favourite = (array) $writer->get_related_data([
+            get_string('messages', 'core_message'),
+            get_string($conversation1->itemtype, $conversation1->component),
+            get_string('privacy:export:conversationprefix', 'core_message') . $conversation1->name
+        ], 'starred');
+        $this->assertCount(4, $favourite);
+        $this->assertEquals(get_string('yes'), $favourite['starred']);
+
+        // Reset writer before exporting conversations for user2.
+        writer::reset();
+
         // Export all the conversations related to the groups in course1 for user2.
         provider::export_conversations($user2->id, 'core_group', 'groups', $coursecontext1);
 
@@ -1693,6 +1714,14 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->assertEquals(transform::datetime($now + 3), $m3->timecreated);
         $this->assertEquals('-', $m3->timeread);
         $this->assertArrayNotHasKey('timedeleted', (array) $m3);
+
+        // Confirm there are no favourite group conversation for user2.
+        $favourite = (array) $writer->get_related_data([
+            get_string('messages', 'core_message'),
+            get_string($conversation1->itemtype, $conversation1->component),
+            $conversation1->name
+        ], 'starred');
+        $this->assertCount(0, $favourite);
     }
 
     /**
@@ -1765,7 +1794,8 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
         $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user2->id));
 
-        // Get conversation.
+        // Get conversations.
+        $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
         $conversation1 = \core_message\api::get_conversation_by_area(
             $component,
             $itemtype,
@@ -1779,6 +1809,11 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
             $coursecontext2->id
         );
 
+        // Make favourite some conversations.
+        \core_message\api::set_favourite_conversation($iconversation1id, $user1->id);
+        \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
+        \core_message\api::set_favourite_conversation($conversation1->id, $user2->id);
+
         // Send some messages to the conversation.
         $gm1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.1', $now + 1);
         $gm2 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.2', $now + 2);
@@ -1819,6 +1854,9 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         // There should be 5 notifications - 3 notifications + 2 for the contact request.
         $this->assertEquals(5, $DB->count_records('notifications'));
 
+        // There should be 3 favourite conversations.
+        $this->assertEquals(3, $DB->count_records('favourite'));
+
         // Delete conversations for all users in course1.
         provider::delete_conversations_for_all_users($coursecontext1, $component, $itemtype);
 
@@ -1858,6 +1896,9 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
 
         // There should be 6 conversation members - (2 + 2) individual + 2 group.
         $this->assertEquals(6, $DB->count_records('message_conversation_members'));
+
+        // There should be 1 favourite conversation - the individual one.
+        $this->assertEquals(1, $DB->count_records('favourite'));
     }
 
     /**
@@ -1930,7 +1971,8 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
         $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user2->id));
 
-        // Get conversation.
+        // Get conversations.
+        $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
         $conversation1 = \core_message\api::get_conversation_by_area(
             $component,
             $itemtype,
@@ -1944,6 +1986,11 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
             $coursecontext2->id
         );
 
+        // Make favourite some conversations.
+        \core_message\api::set_favourite_conversation($iconversation1id, $user1->id);
+        \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
+        \core_message\api::set_favourite_conversation($conversation1->id, $user2->id);
+
         // Send some messages to the conversation.
         $gm1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.1', $now + 1);
         $gm2 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.2', $now + 2);
@@ -1980,6 +2027,9 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         // There should be 5 notifications - 3 notifications + 2 for the contact request.
         $this->assertEquals(5, $DB->count_records('notifications'));
 
+        // There should be 3 favourite conversations.
+        $this->assertEquals(3, $DB->count_records('favourite'));
+
         // Delete group conversations for all users in system context.
         provider::delete_conversations_for_all_users($systemcontext, $component, $itemtype);
 
@@ -1992,6 +2042,7 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->assertEquals(4, $DB->count_records('message_conversations'));
         $this->assertEquals(9, $DB->count_records('message_conversation_members'));
         $this->assertEquals(5, $DB->count_records('notifications'));
+        $this->assertEquals(3, $DB->count_records('favourite'));
 
         // Delete individual conversations for all users in system context.
         provider::delete_conversations_for_all_users($systemcontext, '', '');
@@ -2005,6 +2056,7 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->assertEquals(4, $DB->count_records('message_conversations'));
         $this->assertEquals(9, $DB->count_records('message_conversation_members'));
         $this->assertEquals(5, $DB->count_records('notifications'));
+        $this->assertEquals(3, $DB->count_records('favourite'));
     }
 
     /**
@@ -2093,6 +2145,11 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
             $coursecontext2->id
         );
 
+        // Make favourite some conversations.
+        \core_message\api::set_favourite_conversation($iconversation1id, $user1->id);
+        \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
+        \core_message\api::set_favourite_conversation($conversation1->id, $user2->id);
+
         // Send some messages to the conversation.
         $gm1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.1', $now + 1);
         $gm2 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.2', $now + 2);
@@ -2129,6 +2186,9 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         // There should be 5 notifications - 3 notifications + 2 for the contact request.
         $this->assertEquals(5, $DB->count_records('notifications'));
 
+        // There should be 3 favourite conversations.
+        $this->assertEquals(3, $DB->count_records('favourite'));
+
         // Delete group conversations for all users in user context.
         provider::delete_conversations_for_all_users($user1context, $component, $itemtype);
 
@@ -2141,6 +2201,7 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->assertEquals(4, $DB->count_records('message_conversations'));
         $this->assertEquals(9, $DB->count_records('message_conversation_members'));
         $this->assertEquals(5, $DB->count_records('notifications'));
+        $this->assertEquals(3, $DB->count_records('favourite'));
 
         // Delete individual conversations for all users in user context.
         provider::delete_conversations_for_all_users($user1context, '', '');
@@ -2154,6 +2215,7 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->assertEquals(4, $DB->count_records('message_conversations'));
         $this->assertEquals(9, $DB->count_records('message_conversation_members'));
         $this->assertEquals(5, $DB->count_records('notifications'));
+        $this->assertEquals(3, $DB->count_records('favourite'));
     }
 
     /**
@@ -2224,6 +2286,7 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
 
         // Get conversation.
+        $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
         $conversation1 = \core_message\api::get_conversation_by_area(
             $component,
             $itemtype,
@@ -2231,6 +2294,11 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
             $coursecontext1->id
         );
 
+        // Make favourite some conversations.
+        \core_message\api::set_favourite_conversation($iconversation1id, $user1->id);
+        \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
+        \core_message\api::set_favourite_conversation($conversation1->id, $user2->id);
+
         // Send some messages to the conversation.
         $gm1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1', $now + 1);
         $gm2 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 2', $now + 2);
@@ -2270,6 +2338,9 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         }, $members);
         $this->assertContains($user1->id, $members);
 
+        // There should be three favourite conversations.
+        $this->assertEquals(3, $DB->count_records('favourite'));
+
         // Delete group conversations for user1 in course1 and course2.
         $approvedcontextlist = new \core_privacy\tests\request\approved_contextlist($user1, 'core_message',
                 [$coursecontext1->id, $coursecontext2->id]);
@@ -2313,6 +2384,17 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
                 return $member->userid;
         }, $members);
         $this->assertNotContains($user1->id, $members);
+
+        // There should be 2 favourite conversations - 2 group.
+        $this->assertEquals(2, $DB->count_records('favourite'));
+        $favourites = $DB->get_records('favourite');
+        foreach ($favourites as $favourite) {
+            if ($favourite->userid == $user1->id) {
+                $this->assertEquals($iconversation1id, $favourite->itemid);
+            } else if ($favourite->userid == $user2->id) {
+                $this->assertEquals($conversation1->id, $favourite->itemid);
+            }
+        }
     }
 
 
@@ -2387,6 +2469,7 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user4->id));
 
         // Get conversation.
+        $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
         $conversation1 = \core_message\api::get_conversation_by_area(
             $component,
             $itemtype,
@@ -2394,6 +2477,11 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
             $coursecontext1->id
         );
 
+        // Make favourite some conversations.
+        \core_message\api::set_favourite_conversation($iconversation1id, $user1->id);
+        \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
+        \core_message\api::set_favourite_conversation($conversation1->id, $user3->id);
+
         // Send some messages to the conversation.
         $gm1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1', $now + 1);
         $gm2 = testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 2', $now + 2);
@@ -2434,6 +2522,9 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->assertContains($user1->id, $members);
         $this->assertContains($user4->id, $members);
 
+        // There should be 3 favourite conversations.
+        $this->assertEquals(3, $DB->count_records('favourite'));
+
         // Delete group conversations for user1 and user2 in course2 context.
         $approveduserlist = new \core_privacy\local\request\approved_userlist($coursecontext2, 'core_message',
                 [$user1->id, $user2->id]);
@@ -2448,6 +2539,7 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->assertEquals(4, $DB->count_records('message_user_actions'));
         $this->assertEquals(4, $DB->count_records('message_conversations'));
         $this->assertEquals(8, $DB->count_records('message_conversation_members'));
+        $this->assertEquals(3, $DB->count_records('favourite'));
 
         // Delete group conversations for user4 in course1 context.
         $approveduserlist = new \core_privacy\local\request\approved_userlist($coursecontext1, 'core_message',
@@ -2462,6 +2554,7 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         $this->assertEquals(6, $DB->count_records('messages'));
         $this->assertEquals(4, $DB->count_records('message_user_actions'));
         $this->assertEquals(4, $DB->count_records('message_conversations'));
+        $this->assertEquals(3, $DB->count_records('favourite'));
         // There should be 7 conversation members - (2 + 2) private + 3 group.
         $this->assertEquals(7, $DB->count_records('message_conversation_members'));
 
@@ -2509,6 +2602,17 @@ class core_message_privacy_provider_testcase extends \core_privacy\tests\provide
         }, $members);
         $this->assertNotContains($user1->id, $members);
         $this->assertNotContains($user2->id, $members);
+
+        // There should be 2 favourite conversations - user1 individual + user3 group.
+        $this->assertEquals(2, $DB->count_records('favourite'));
+        $favourites = $DB->get_records('favourite');
+        foreach ($favourites as $favourite) {
+            if ($favourite->userid == $user1->id) {
+                $this->assertEquals($iconversation1id, $favourite->itemid);
+            } else if ($favourite->userid == $user3->id) {
+                $this->assertEquals($conversation1->id, $favourite->itemid);
+            }
+        }
     }
 
     /**