11/*
2- Copyright 2022 The Matrix.org Foundation C.I.C.
2+ Copyright 2022 - 2023 The Matrix.org Foundation C.I.C.
33
44Licensed under the Apache License, Version 2.0 (the "License");
55you may not use this file except in compliance with the License.
@@ -15,38 +15,165 @@ limitations under the License.
1515*/
1616
1717import { Room } from "matrix-js-sdk/src/models/room" ;
18- import { MatrixEventEvent , MatrixEvent , MatrixClient } from "matrix-js-sdk/src/matrix" ;
18+ import {
19+ MatrixEventEvent ,
20+ PendingEventOrdering ,
21+ EventStatus ,
22+ NotificationCountType ,
23+ EventType ,
24+ } from "matrix-js-sdk/src/matrix" ;
25+ import { MatrixEvent } from "matrix-js-sdk/src/matrix" ;
1926
20- import { stubClient } from "../../test-utils " ;
21- import { MatrixClientPeg } from "../../../src/MatrixClientPeg " ;
27+ import type { MatrixClient } from "matrix-js-sdk/src/matrix " ;
28+ import { mkEvent , muteRoom , stubClient } from "../../test-utils " ;
2229import { RoomNotificationState } from "../../../src/stores/notifications/RoomNotificationState" ;
23- import * as testUtils from "../../test-utils" ;
2430import { NotificationStateEvents } from "../../../src/stores/notifications/NotificationState" ;
31+ import { NotificationColor } from "../../../src/stores/notifications/NotificationColor" ;
32+ import { createMessageEventContent } from "../../test-utils/events" ;
2533
2634describe ( "RoomNotificationState" , ( ) => {
27- let testRoom : Room ;
35+ let room : Room ;
2836 let client : MatrixClient ;
2937
3038 beforeEach ( ( ) => {
31- stubClient ( ) ;
32- client = MatrixClientPeg . get ( ) ;
33- testRoom = testUtils . mkStubRoom ( "$aroomid" , "Test room" , client ) ;
39+ client = stubClient ( ) ;
40+ room = new Room ( "!room:example.com" , client , "@user:example.org" , {
41+ pendingEventOrdering : PendingEventOrdering . Detached ,
42+ } ) ;
3443 } ) ;
3544
45+ function addThread ( room : Room ) : void {
46+ const threadId = "thread_id" ;
47+ jest . spyOn ( room , "eventShouldLiveIn" ) . mockReturnValue ( {
48+ shouldLiveInRoom : true ,
49+ shouldLiveInThread : true ,
50+ threadId,
51+ } ) ;
52+ const thread = room . createThread (
53+ threadId ,
54+ new MatrixEvent ( {
55+ room_id : room . roomId ,
56+ event_id : "event_root_1" ,
57+ type : EventType . RoomMessage ,
58+ sender : "userId" ,
59+ content : createMessageEventContent ( "RootEvent" ) ,
60+ } ) ,
61+ [ ] ,
62+ true ,
63+ ) ;
64+ for ( let i = 0 ; i < 10 ; i ++ ) {
65+ thread . addEvent (
66+ new MatrixEvent ( {
67+ room_id : room . roomId ,
68+ event_id : "event_reply_1" + i ,
69+ type : EventType . RoomMessage ,
70+ sender : "userId" ,
71+ content : createMessageEventContent ( "ReplyEvent" + 1 ) ,
72+ } ) ,
73+ false ,
74+ ) ;
75+ }
76+ }
77+
78+ function setUnreads ( room : Room , greys : number , reds : number ) : void {
79+ room . setUnreadNotificationCount ( NotificationCountType . Highlight , reds ) ;
80+ room . setUnreadNotificationCount ( NotificationCountType . Total , greys ) ;
81+ }
82+
3683 it ( "Updates on event decryption" , ( ) => {
37- const roomNotifState = new RoomNotificationState ( testRoom as any as Room ) ;
84+ const roomNotifState = new RoomNotificationState ( room ) ;
3885 const listener = jest . fn ( ) ;
3986 roomNotifState . addListener ( NotificationStateEvents . Update , listener ) ;
4087 const testEvent = {
41- getRoomId : ( ) => testRoom . roomId ,
88+ getRoomId : ( ) => room . roomId ,
4289 } as unknown as MatrixEvent ;
43- testRoom . getUnreadNotificationCount = jest . fn ( ) . mockReturnValue ( 1 ) ;
90+ room . getUnreadNotificationCount = jest . fn ( ) . mockReturnValue ( 1 ) ;
4491 client . emit ( MatrixEventEvent . Decrypted , testEvent ) ;
4592 expect ( listener ) . toHaveBeenCalled ( ) ;
4693 } ) ;
4794
4895 it ( "removes listeners" , ( ) => {
49- const roomNotifState = new RoomNotificationState ( testRoom as any as Room ) ;
96+ const roomNotifState = new RoomNotificationState ( room ) ;
5097 expect ( ( ) => roomNotifState . destroy ( ) ) . not . toThrow ( ) ;
5198 } ) ;
99+
100+ it ( "suggests an 'unread' ! if there are unsent messages" , ( ) => {
101+ const roomNotifState = new RoomNotificationState ( room ) ;
102+
103+ const event = mkEvent ( {
104+ event : true ,
105+ type : "m.message" ,
106+ user : "@user:example.org" ,
107+ content : { } ,
108+ } ) ;
109+ event . status = EventStatus . NOT_SENT ;
110+ room . addPendingEvent ( event , "txn" ) ;
111+
112+ expect ( roomNotifState . color ) . toBe ( NotificationColor . Unsent ) ;
113+ expect ( roomNotifState . symbol ) . toBe ( "!" ) ;
114+ expect ( roomNotifState . count ) . toBeGreaterThan ( 0 ) ;
115+ } ) ;
116+
117+ it ( "suggests nothing if the room is muted" , ( ) => {
118+ const roomNotifState = new RoomNotificationState ( room ) ;
119+
120+ muteRoom ( room ) ;
121+ setUnreads ( room , 1234 , 0 ) ;
122+ room . updateMyMembership ( "join" ) ; // emit
123+
124+ expect ( roomNotifState . color ) . toBe ( NotificationColor . None ) ;
125+ expect ( roomNotifState . symbol ) . toBe ( null ) ;
126+ expect ( roomNotifState . count ) . toBe ( 0 ) ;
127+ } ) ;
128+
129+ it ( "suggests a red ! if the user has been invited to a room" , ( ) => {
130+ const roomNotifState = new RoomNotificationState ( room ) ;
131+
132+ room . updateMyMembership ( "invite" ) ; // emit
133+
134+ expect ( roomNotifState . color ) . toBe ( NotificationColor . Red ) ;
135+ expect ( roomNotifState . symbol ) . toBe ( "!" ) ;
136+ expect ( roomNotifState . count ) . toBeGreaterThan ( 0 ) ;
137+ } ) ;
138+
139+ it ( "returns a proper count and color for regular unreads" , ( ) => {
140+ const roomNotifState = new RoomNotificationState ( room ) ;
141+
142+ setUnreads ( room , 4321 , 0 ) ;
143+ room . updateMyMembership ( "join" ) ; // emit
144+
145+ expect ( roomNotifState . color ) . toBe ( NotificationColor . Grey ) ;
146+ expect ( roomNotifState . symbol ) . toBe ( null ) ;
147+ expect ( roomNotifState . count ) . toBe ( 4321 ) ;
148+ } ) ;
149+
150+ it ( "returns a proper count and color for highlights" , ( ) => {
151+ const roomNotifState = new RoomNotificationState ( room ) ;
152+
153+ setUnreads ( room , 0 , 69 ) ;
154+ room . updateMyMembership ( "join" ) ; // emit
155+
156+ expect ( roomNotifState . color ) . toBe ( NotificationColor . Red ) ;
157+ expect ( roomNotifState . symbol ) . toBe ( null ) ;
158+ expect ( roomNotifState . count ) . toBe ( 69 ) ;
159+ } ) ;
160+
161+ it ( "includes threads" , async ( ) => {
162+ const roomNotifState = new RoomNotificationState ( room ) ;
163+
164+ room . timeline . push (
165+ new MatrixEvent ( {
166+ room_id : room . roomId ,
167+ type : EventType . RoomMessage ,
168+ sender : "userId" ,
169+ content : createMessageEventContent ( "timeline event" ) ,
170+ } ) ,
171+ ) ;
172+
173+ addThread ( room ) ;
174+ room . updateMyMembership ( "join" ) ; // emit
175+
176+ expect ( roomNotifState . color ) . toBe ( NotificationColor . Bold ) ;
177+ expect ( roomNotifState . symbol ) . toBe ( null ) ;
178+ } ) ;
52179} ) ;
0 commit comments