2023-12-05 18:37:23 +08:00
/ *
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 { customEvent , many , test } from "." ;
test . describe ( "Read receipts" , ( ) = > {
test . describe ( "Ignored events" , ( ) = > {
test ( "If all events after receipt are unimportant, the room is read" , async ( {
roomAlpha : room1 ,
roomBeta : room2 ,
util ,
} ) = > {
await util . goTo ( room1 ) ;
await util . assertRead ( room2 ) ;
await util . receiveMessages ( room2 , [ "Msg1" , "Msg2" ] ) ;
await util . assertUnread ( room2 , 2 ) ;
await util . markAsRead ( room2 ) ;
await util . assertRead ( room2 ) ;
await util . receiveMessages ( room2 , [ customEvent ( "org.custom.event" , { body : "foobar" } ) ] ) ;
await util . assertRead ( room2 ) ;
} ) ;
test ( "Sending an important event after unimportant ones makes the room unread" , async ( {
roomAlpha : room1 ,
roomBeta : room2 ,
util ,
} ) = > {
// Given We have read the important messages
await util . goTo ( room1 ) ;
await util . assertRead ( room2 ) ;
await util . receiveMessages ( room2 , [ "Msg1" , "Msg2" ] ) ;
await util . assertUnread ( room2 , 2 ) ;
await util . goTo ( room2 ) ;
await util . assertRead ( room2 ) ;
await util . goTo ( room1 ) ;
// When we receive unimportant messages
await util . receiveMessages ( room2 , [ customEvent ( "org.custom.event" , { body : "foobar" } ) ] ) ;
// Then the room is still read
await util . assertStillRead ( room2 ) ;
// And when we receive more important ones
await util . receiveMessages ( room2 , [ "Hello" ] ) ;
// The room is unread again
await util . assertUnread ( room2 , 1 ) ;
} ) ;
test ( "A receipt for the last unimportant event makes the room read, even if all are unimportant" , async ( {
roomAlpha : room1 ,
roomBeta : room2 ,
util ,
} ) = > {
// Display room 1
await util . goTo ( room1 ) ;
// The room 2 is read
await util . assertRead ( room2 ) ;
// We received 3 unimportant messages to room2
await util . receiveMessages ( room2 , [
customEvent ( "org.custom.event" , { body : "foobar1" } ) ,
customEvent ( "org.custom.event" , { body : "foobar2" } ) ,
customEvent ( "org.custom.event" , { body : "foobar3" } ) ,
] ) ;
// The room 2 is still read
await util . assertStillRead ( room2 ) ;
} ) ;
} ) ;
test . describe ( "Paging up" , ( ) = > {
2023-12-11 18:11:26 +08:00
test ( "Paging up through old messages after a room is read leaves the room read" , async ( {
2023-12-05 18:37:23 +08:00
page ,
roomAlpha : room1 ,
roomBeta : room2 ,
util ,
} ) = > {
// Given lots of messages are in the room, but we have read them
await util . goTo ( room1 ) ;
await util . receiveMessages ( room2 , many ( "Msg" , 110 ) ) ;
await util . assertUnread ( room2 , 110 ) ;
await util . goTo ( room2 ) ;
await util . assertRead ( room2 ) ;
await util . goTo ( room1 ) ;
// When we restart, so only recent messages are loaded
await util . saveAndReload ( ) ;
await util . goTo ( room2 ) ;
await util . assertMessageNotLoaded ( "Msg0010" ) ;
// And we page up, loading in old messages
await util . pageUp ( ) ;
await page . waitForTimeout ( 200 ) ;
await util . pageUp ( ) ;
await page . waitForTimeout ( 200 ) ;
await util . pageUp ( ) ;
await util . assertMessageLoaded ( "Msg0010" ) ;
// Then the room remains read
await util . assertStillRead ( room2 ) ;
} ) ;
test ( "Paging up through old messages of an unread room leaves the room unread" , async ( {
roomAlpha : room1 ,
roomBeta : room2 ,
util ,
msg ,
} ) = > {
// Given lots of messages are in the room, and they are not read
await util . goTo ( room1 ) ;
await util . receiveMessages ( room2 , many ( "x\ny\nz\nMsg" , 40 ) ) ; // newline to spread out messages
await util . assertUnread ( room2 , 40 ) ;
// When I jump to a message in the middle and page up
await msg . jumpTo ( room2 . name , "x\ny\nz\nMsg0020" ) ;
await util . pageUp ( ) ;
// Then the room is still unread
await util . assertUnreadGreaterThan ( room2 , 1 ) ;
} ) ;
test ( "Paging up to find old threads that were previously read leaves the room read" , async ( {
roomAlpha : room1 ,
roomBeta : room2 ,
util ,
msg ,
} ) = > {
test . slow ( ) ;
// Given lots of messages in threads are all read
await util . goTo ( room1 ) ;
await util . receiveMessages ( room2 , [
"Root1" ,
"Root2" ,
"Root3" ,
. . . msg . manyThreadedOff ( "Root1" , many ( "T" , 20 ) ) ,
. . . msg . manyThreadedOff ( "Root2" , many ( "T" , 20 ) ) ,
. . . msg . manyThreadedOff ( "Root3" , many ( "T" , 20 ) ) ,
] ) ;
await util . goTo ( room2 ) ;
2024-04-29 23:30:19 +08:00
await util . assertRead ( room2 ) ;
await util . assertUnreadThread ( "Root1" ) ;
await util . assertUnreadThread ( "Root2" ) ;
await util . assertUnreadThread ( "Root3" ) ;
2023-12-05 18:37:23 +08:00
await util . openThread ( "Root1" ) ;
await util . assertReadThread ( "Root1" ) ;
await util . openThread ( "Root2" ) ;
await util . assertReadThread ( "Root2" ) ;
await util . openThread ( "Root3" ) ;
await util . assertReadThread ( "Root3" ) ;
// When I restart and page up to load old thread roots
await util . goTo ( room1 ) ;
await util . saveAndReload ( ) ;
await util . goTo ( room2 ) ;
await util . pageUp ( ) ;
// Then the room and threads remain read
await util . assertRead ( room2 ) ;
await util . assertReadThread ( "Root1" ) ;
await util . assertReadThread ( "Root2" ) ;
await util . assertReadThread ( "Root3" ) ;
} ) ;
2024-04-29 23:30:19 +08:00
2023-12-05 18:37:23 +08:00
test ( "Paging up to find old threads that were never read keeps the room unread" , async ( {
roomAlpha : room1 ,
roomBeta : room2 ,
util ,
msg ,
} ) = > {
test . slow ( ) ;
// Given lots of messages in threads that are unread
await util . goTo ( room1 ) ;
await util . receiveMessages ( room2 , [
"Root1" ,
"Root2" ,
"Root3" ,
. . . msg . manyThreadedOff ( "Root1" , many ( "T" , 2 ) ) ,
. . . msg . manyThreadedOff ( "Root2" , many ( "T" , 2 ) ) ,
. . . msg . manyThreadedOff ( "Root3" , many ( "T" , 2 ) ) ,
. . . many ( "Msg" , 100 ) ,
] ) ;
await util . goTo ( room2 ) ;
2024-04-29 23:30:19 +08:00
await util . assertRead ( room2 ) ;
2023-12-05 18:37:23 +08:00
await util . assertUnreadThread ( "Root1" ) ;
await util . assertUnreadThread ( "Root2" ) ;
await util . assertUnreadThread ( "Root3" ) ;
// When I restart
await util . closeThreadsPanel ( ) ;
await util . goTo ( room1 ) ;
await util . saveAndReload ( ) ;
2024-04-29 23:30:19 +08:00
// Then the room remembers it's read
2023-12-05 18:37:23 +08:00
// TODO: I (andyb) think this will fall in an encrypted room
2024-04-29 23:30:19 +08:00
await util . assertRead ( room2 ) ;
2023-12-05 18:37:23 +08:00
// And when I page up to load old thread roots
await util . goTo ( room2 ) ;
await util . pageUp ( ) ;
2024-04-29 23:30:19 +08:00
// Then the room remains read
await util . assertRead ( room2 ) ;
2023-12-05 18:37:23 +08:00
await util . assertUnreadThread ( "Root1" ) ;
await util . assertUnreadThread ( "Root2" ) ;
await util . assertUnreadThread ( "Root3" ) ;
} ) ;
2024-04-29 23:30:19 +08:00
2023-12-11 18:11:26 +08:00
test ( "Looking in thread view to find old threads that were never read makes the room unread" , async ( {
2023-12-05 18:37:23 +08:00
roomAlpha : room1 ,
roomBeta : room2 ,
util ,
msg ,
} ) = > {
// Given lots of messages in threads that are unread
await util . goTo ( room1 ) ;
await util . receiveMessages ( room2 , [
"Root1" ,
"Root2" ,
"Root3" ,
. . . msg . manyThreadedOff ( "Root1" , many ( "T" , 2 ) ) ,
. . . msg . manyThreadedOff ( "Root2" , many ( "T" , 2 ) ) ,
. . . msg . manyThreadedOff ( "Root3" , many ( "T" , 2 ) ) ,
. . . many ( "Msg" , 100 ) ,
] ) ;
await util . goTo ( room2 ) ;
2024-04-29 23:30:19 +08:00
await util . assertRead ( room2 ) ;
2023-12-05 18:37:23 +08:00
await util . assertUnreadThread ( "Root1" ) ;
await util . assertUnreadThread ( "Root2" ) ;
await util . assertUnreadThread ( "Root3" ) ;
// When I restart
await util . closeThreadsPanel ( ) ;
await util . goTo ( room1 ) ;
await util . saveAndReload ( ) ;
2024-04-29 23:30:19 +08:00
// Then the room remembers it's read
2023-12-05 18:37:23 +08:00
// TODO: I (andyb) think this will fall in an encrypted room
2024-04-29 23:30:19 +08:00
await util . assertRead ( room2 ) ;
2023-12-05 18:37:23 +08:00
// And when I open the threads view
await util . goTo ( room2 ) ;
await util . openThreadList ( ) ;
2024-04-29 23:30:19 +08:00
// Then the room remains read
await util . assertRead ( room2 ) ;
2023-12-05 18:37:23 +08:00
await util . assertUnreadThread ( "Root1" ) ;
await util . assertUnreadThread ( "Root2" ) ;
await util . assertUnreadThread ( "Root3" ) ;
} ) ;
2024-04-29 23:30:19 +08:00
2023-12-05 18:37:23 +08:00
test ( "After marking room as read, paging up to find old threads that were never read leaves the room read" , async ( {
roomAlpha : room1 ,
roomBeta : room2 ,
util ,
msg ,
} ) = > {
test . slow ( ) ;
// Given lots of messages in threads that are unread but I marked as read on a main timeline message
await util . goTo ( room1 ) ;
await util . receiveMessages ( room2 , [
"Root1" ,
"Root2" ,
"Root3" ,
. . . msg . manyThreadedOff ( "Root1" , many ( "T" , 2 ) ) ,
. . . msg . manyThreadedOff ( "Root2" , many ( "T" , 2 ) ) ,
. . . msg . manyThreadedOff ( "Root3" , many ( "T" , 2 ) ) ,
. . . many ( "Msg" , 100 ) ,
] ) ;
await util . markAsRead ( room2 ) ;
await util . assertRead ( room2 ) ;
// When I restart
await util . saveAndReload ( ) ;
// Then the room remembers it's read
await util . assertRead ( room2 ) ;
// And when I page up to load old thread roots
await util . goTo ( room2 ) ;
await util . pageUp ( ) ;
await util . pageUp ( ) ;
await util . pageUp ( ) ;
// Then the room remains read
await util . assertStillRead ( room2 ) ;
await util . assertReadThread ( "Root1" ) ;
await util . assertReadThread ( "Root2" ) ;
await util . assertReadThread ( "Root3" ) ;
} ) ;
2023-12-11 18:11:26 +08:00
test ( "After marking room as read based on a thread message, opening threads view to find old threads that were never read leaves the room read" , async ( {
2023-12-05 18:37:23 +08:00
roomAlpha : room1 ,
roomBeta : room2 ,
util ,
msg ,
} ) = > {
// Given lots of messages in threads that are unread but I marked as read on a thread message
await util . goTo ( room1 ) ;
await util . receiveMessages ( room2 , [
"Root1" ,
"Root2" ,
"Root3" ,
. . . msg . manyThreadedOff ( "Root1" , many ( "T1-" , 2 ) ) ,
. . . msg . manyThreadedOff ( "Root2" , many ( "T2-" , 2 ) ) ,
. . . msg . manyThreadedOff ( "Root3" , many ( "T3-" , 2 ) ) ,
. . . many ( "Msg" , 100 ) ,
msg . threadedOff ( "Msg0099" , "Thread off 99" ) ,
] ) ;
await util . markAsRead ( room2 ) ;
await util . assertRead ( room2 ) ;
// When I restart
await util . saveAndReload ( ) ;
// Then the room remembers it's read
await util . assertRead ( room2 ) ;
// And when I page up to load old thread roots
await util . goTo ( room2 ) ;
await util . openThreadList ( ) ;
// Then the room remains read
await util . assertStillRead ( room2 ) ;
await util . assertReadThread ( "Root1" ) ;
await util . assertReadThread ( "Root2" ) ;
await util . assertReadThread ( "Root3" ) ;
} ) ;
} ) ;
} ) ;