/* Copyright 2023 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* See readme.md for tips on writing these tests. */ import { many, test } from "."; test.describe("Read receipts", () => { test.describe("new messages", () => { test.describe("in threads", () => { test("Receiving a message makes a room unread", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given a message arrived and is read await util.goTo(room1); await util.receiveMessages(room2, ["Msg1"]); await util.assertUnread(room2, 1); await util.goTo(room2); await util.assertRead(room2); await util.goTo(room1); // When I receive a threaded message await util.receiveMessages(room2, [msg.threadedOff("Msg1", "Resp1")]); // Then the room stays read await util.assertRead(room2); // but the thread is unread await util.goTo(room2); await util.assertUnreadThread("Msg1"); }); test("Reading the last threaded message makes the room read", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given a thread exists and is not read await util.goTo(room1); await util.receiveMessages(room2, ["Msg1", msg.threadedOff("Msg1", "Resp1")]); await util.assertUnread(room2, 1); await util.goTo(room2); // When I read it await util.openThread("Msg1"); // The thread becomes read await util.assertReadThread("Msg1"); }); test("Reading a thread message makes the thread read", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given a thread exists await util.goTo(room1); await util.receiveMessages(room2, [ "Msg1", msg.threadedOff("Msg1", "Resp1"), msg.threadedOff("Msg1", "Resp2"), ]); await util.assertUnread(room2, 1); // (Sanity) // When I read the main timeline await util.goTo(room2); // Then room is read await util.assertRead(room2); // Reading the thread causes it to become read too await util.openThread("Msg1"); await util.assertReadThread("Msg1"); await util.assertRead(room2); }); test("Reading an older thread message leaves the thread unread", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given there are many messages in a thread await util.goTo(room1); await util.receiveMessages(room2, [ "ThreadRoot", ...msg.manyThreadedOff("ThreadRoot", many("InThread", 20)), ]); await util.assertUnread(room2, 1); await util.goTo(room2); await util.assertUnreadThread("ThreadRoot"); await util.goTo(room1); // When I read an older message in the thread await msg.jumpTo(room2.name, "InThread0000", true); // Then the thread is still marked as unread await util.backToThreadsList(); await util.assertUnreadThread("ThreadRoot"); }); test("Reading only one thread's message makes that thread read but not others", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given I have unread threads await util.goTo(room1); await util.receiveMessages(room2, [ "Msg1", "Msg2", msg.threadedOff("Msg1", "Resp1"), msg.threadedOff("Msg2", "Resp2"), ]); await util.assertUnread(room2, 2); // (Sanity) await util.goTo(room2); await util.assertRead(room2); await util.assertUnreadThread("Msg1"); await util.assertUnreadThread("Msg2"); // When I read one of them await util.openThread("Msg1"); // Then that one is read, but the other is not await util.assertReadThread("Msg1"); await util.assertUnreadThread("Msg2"); }); test("Reading the main timeline does not mark a thread message as read", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given a thread exists await util.goTo(room1); await util.receiveMessages(room2, [ "Msg1", msg.threadedOff("Msg1", "Resp1"), msg.threadedOff("Msg1", "Resp2"), ]); await util.assertUnread(room2, 1); // (Sanity) // When I read the main timeline await util.goTo(room2); await util.assertRead(room2); // Then thread does appear unread await util.assertUnreadThread("Msg1"); }); test("Marking a room with unread threads as read makes it read", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given I have an unread thread await util.goTo(room1); await util.receiveMessages(room2, [ "Msg1", msg.threadedOff("Msg1", "Resp1"), msg.threadedOff("Msg1", "Resp2"), ]); await util.assertUnread(room2, 1); // (Sanity) // When I mark the room as read await util.markAsRead(room2); // Then the room is read await util.assertRead(room2); // and so are the threads await util.assertReadThread("Msg1"); }); test("Sending a new thread message after marking as read makes it unread", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given a thread exists await util.goTo(room1); await util.receiveMessages(room2, [ "Msg1", msg.threadedOff("Msg1", "Resp1"), msg.threadedOff("Msg1", "Resp2"), ]); // When I mark the room as read await util.markAsRead(room2); await util.assertRead(room2); // Then another message appears in the thread await util.receiveMessages(room2, [msg.threadedOff("Msg1", "Resp3")]); // Then the thread becomes unread await util.goTo(room2); await util.assertUnreadThread("Msg1"); }); test("Sending a new different-thread message after marking as read makes it unread", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given 2 threads exist, and Thread2 has the latest message in it await util.goTo(room1); await util.receiveMessages(room2, ["Thread1", "Thread2", msg.threadedOff("Thread1", "t1a")]); // Make sure the message in Thread 1 has definitely arrived, so that we know for sure // that the one in Thread 2 is the latest. await util.receiveMessages(room2, [msg.threadedOff("Thread2", "t2a")]); // When I mark the room as read (making an unthreaded receipt for t2a) await util.markAsRead(room2); await util.assertRead(room2); // Then another message appears in the other thread await util.receiveMessages(room2, [msg.threadedOff("Thread1", "t1b")]); // Then the other thread becomes unread await util.goTo(room2); await util.assertUnreadThread("Thread1"); }); test("A room with a new threaded message is still unread after restart", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given a thread exists await util.goTo(room1); await util.receiveMessages(room2, [ "Msg1", msg.threadedOff("Msg1", "Resp1"), msg.threadedOff("Msg1", "Resp2"), ]); await util.assertUnread(room2, 1); // (Sanity) // When I read the main timeline await util.goTo(room2); // Then room appears read await util.assertRead(room2); /// but with an unread thread await util.assertUnreadThread("Msg1"); await util.saveAndReload(); await util.assertRead(room2); await util.goTo(room2); await util.assertUnreadThread("Msg1"); // Opening the thread now marks it as read await util.openThread("Msg1"); await util.assertReadThread("Msg1"); }); test("A room where all threaded messages are read is still read after restart", async ({ roomAlpha: room1, roomBeta: room2, util, msg, }) => { // Given I have read all the threads await util.goTo(room1); await util.receiveMessages(room2, [ "Msg1", msg.threadedOff("Msg1", "Resp1"), msg.threadedOff("Msg1", "Resp2"), ]); await util.assertUnread(room2, 1); // (Sanity) await util.goTo(room2); await util.assertRead(room2); await util.assertUnreadThread("Msg1"); await util.openThread("Msg1"); await util.assertReadThread("Msg1"); // When I restart await util.saveAndReload(); // Then the room & thread still read await util.assertRead(room2); await util.goTo(room2); await util.assertReadThread("Msg1"); }); }); }); });