@@ -15,15 +15,18 @@ limitations under the License.
1515*/
1616
1717import { render } from "@testing-library/react" ;
18+ import { MatrixEvent , MsgType , RelationType } from "matrix-js-sdk/src/matrix" ;
1819import { MatrixClient , PendingEventOrdering } from "matrix-js-sdk/src/client" ;
1920import { Feature , ServerSupport } from "matrix-js-sdk/src/feature" ;
2021import { NotificationCountType , Room } from "matrix-js-sdk/src/models/room" ;
22+ import { ReceiptType } from "matrix-js-sdk/src/@types/read_receipts" ;
2123import React from "react" ;
2224
2325import RoomHeaderButtons from "../../../../src/components/views/right_panel/RoomHeaderButtons" ;
2426import { MatrixClientPeg } from "../../../../src/MatrixClientPeg" ;
2527import SettingsStore from "../../../../src/settings/SettingsStore" ;
26- import { stubClient } from "../../../test-utils" ;
28+ import { mkEvent , stubClient } from "../../../test-utils" ;
29+ import { mkThread } from "../../../test-utils/threads" ;
2730
2831describe ( "RoomHeaderButtons-test.tsx" , function ( ) {
2932 const ROOM_ID = "!roomId:example.org" ;
@@ -35,6 +38,7 @@ describe("RoomHeaderButtons-test.tsx", function () {
3538
3639 stubClient ( ) ;
3740 client = MatrixClientPeg . get ( ) ;
41+ client . supportsExperimentalThreads = ( ) => true ;
3842 room = new Room ( ROOM_ID , client , client . getUserId ( ) ?? "" , {
3943 pendingEventOrdering : PendingEventOrdering . Detached ,
4044 } ) ;
@@ -52,7 +56,7 @@ describe("RoomHeaderButtons-test.tsx", function () {
5256 return container . querySelector ( ".mx_RightPanel_threadsButton" ) ;
5357 }
5458
55- function isIndicatorOfType ( container , type : "red" | "gray" ) {
59+ function isIndicatorOfType ( container , type : "red" | "gray" | "bold" ) {
5660 return container . querySelector ( ".mx_RightPanel_threadsButton .mx_Indicator" ) . className . includes ( type ) ;
5761 }
5862
@@ -76,7 +80,7 @@ describe("RoomHeaderButtons-test.tsx", function () {
7680 expect ( container . querySelector ( ".mx_RightPanel_threadsButton .mx_Indicator" ) ) . toBeNull ( ) ;
7781 } ) ;
7882
79- it ( "room wide notification does not change the thread button" , ( ) => {
83+ it ( "thread notification does change the thread button" , ( ) => {
8084 const { container } = getComponent ( room ) ;
8185
8286 room . setThreadUnreadNotificationCount ( "$123" , NotificationCountType . Total , 1 ) ;
@@ -91,6 +95,85 @@ describe("RoomHeaderButtons-test.tsx", function () {
9195 expect ( container . querySelector ( ".mx_RightPanel_threadsButton .mx_Indicator" ) ) . toBeNull ( ) ;
9296 } ) ;
9397
98+ it ( "thread activity does change the thread button" , async ( ) => {
99+ const { container } = getComponent ( room ) ;
100+
101+ // Thread activity should appear on the icon.
102+ const { rootEvent, events } = mkThread ( {
103+ room,
104+ client,
105+ authorId : client . getUserId ( ) ! ,
106+ participantUserIds : [ "@alice:example.org" ] ,
107+ } ) ;
108+ expect ( isIndicatorOfType ( container , "bold" ) ) . toBe ( true ) ;
109+
110+ // Sending the last event should clear the notification.
111+ let event = mkEvent ( {
112+ event : true ,
113+ type : "m.room.message" ,
114+ user : client . getUserId ( ) ! ,
115+ room : room . roomId ,
116+ content : {
117+ "msgtype" : MsgType . Text ,
118+ "body" : "Test" ,
119+ "m.relates_to" : {
120+ event_id : rootEvent . getId ( ) ,
121+ rel_type : RelationType . Thread ,
122+ } ,
123+ } ,
124+ } ) ;
125+ room . addLiveEvents ( [ event ] ) ;
126+ await expect ( container . querySelector ( ".mx_RightPanel_threadsButton .mx_Indicator" ) ) . toBeNull ( ) ;
127+
128+ // Mark it as unread again.
129+ event = mkEvent ( {
130+ event : true ,
131+ type : "m.room.message" ,
132+ user : "@alice:example.org" ,
133+ room : room . roomId ,
134+ content : {
135+ "msgtype" : MsgType . Text ,
136+ "body" : "Test" ,
137+ "m.relates_to" : {
138+ event_id : rootEvent . getId ( ) ,
139+ rel_type : RelationType . Thread ,
140+ } ,
141+ } ,
142+ } ) ;
143+ room . addLiveEvents ( [ event ] ) ;
144+ expect ( isIndicatorOfType ( container , "bold" ) ) . toBe ( true ) ;
145+
146+ // Sending a read receipt on an earlier event shouldn't do anything.
147+ let receipt = new MatrixEvent ( {
148+ type : "m.receipt" ,
149+ room_id : room . roomId ,
150+ content : {
151+ [ events . at ( - 1 ) . getId ( ) ! ] : {
152+ [ ReceiptType . Read ] : {
153+ [ client . getUserId ( ) ! ] : { ts : 1 , thread_id : rootEvent . getId ( ) } ,
154+ } ,
155+ } ,
156+ } ,
157+ } ) ;
158+ room . addReceipt ( receipt ) ;
159+ expect ( isIndicatorOfType ( container , "bold" ) ) . toBe ( true ) ;
160+
161+ // Sending a receipt on the latest event should clear the notification.
162+ receipt = new MatrixEvent ( {
163+ type : "m.receipt" ,
164+ room_id : room . roomId ,
165+ content : {
166+ [ event . getId ( ) ! ] : {
167+ [ ReceiptType . Read ] : {
168+ [ client . getUserId ( ) ! ] : { ts : 1 , thread_id : rootEvent . getId ( ) } ,
169+ } ,
170+ } ,
171+ } ,
172+ } ) ;
173+ room . addReceipt ( receipt ) ;
174+ expect ( container . querySelector ( ".mx_RightPanel_threadsButton .mx_Indicator" ) ) . toBeNull ( ) ;
175+ } ) ;
176+
94177 it ( "does not explode without a room" , ( ) => {
95178 client . canSupport . set ( Feature . ThreadUnreadNotifications , ServerSupport . Unsupported ) ;
96179 expect ( ( ) => getComponent ( ) ) . not . toThrow ( ) ;
0 commit comments