@@ -14,10 +14,19 @@ See the License for the specific language governing permissions and
14
14
limitations under the License.
15
15
*/
16
16
17
+ import { MockedObject } from "jest-mock" ;
18
+
17
19
import { MatrixEvent , MatrixEventEvent } from "../../../src/models/event" ;
18
20
import { emitPromise } from "../../test-utils/test-utils" ;
19
21
import { Crypto , IEventDecryptionResult } from "../../../src/crypto" ;
20
- import { IAnnotatedPushRule , PushRuleActionName , TweakName } from "../../../src" ;
22
+ import {
23
+ IAnnotatedPushRule ,
24
+ MatrixClient ,
25
+ PushRuleActionName ,
26
+ Room ,
27
+ THREAD_RELATION_TYPE ,
28
+ TweakName ,
29
+ } from "../../../src" ;
21
30
22
31
describe ( "MatrixEvent" , ( ) => {
23
32
it ( "should create copies of itself" , ( ) => {
@@ -77,17 +86,98 @@ describe("MatrixEvent", () => {
77
86
expect ( ev . getWireContent ( ) . body ) . toBeUndefined ( ) ;
78
87
expect ( ev . getWireContent ( ) . ciphertext ) . toBe ( "xyz" ) ;
79
88
89
+ const mockClient = { } as unknown as MockedObject < MatrixClient > ;
90
+ const room = new Room ( "!roomid:e.xyz" , mockClient , "myname" ) ;
80
91
const redaction = new MatrixEvent ( {
81
92
type : "m.room.redaction" ,
82
93
redacts : ev . getId ( ) ,
83
94
} ) ;
84
95
85
- ev . makeRedacted ( redaction ) ;
96
+ ev . makeRedacted ( redaction , room ) ;
86
97
expect ( ev . getContent ( ) . body ) . toBeUndefined ( ) ;
87
98
expect ( ev . getWireContent ( ) . body ) . toBeUndefined ( ) ;
88
99
expect ( ev . getWireContent ( ) . ciphertext ) . toBeUndefined ( ) ;
89
100
} ) ;
90
101
102
+ it ( "should remain in the main timeline when redacted" , async ( ) => {
103
+ // Given an event in the main timeline
104
+ const mockClient = {
105
+ supportsThreads : jest . fn ( ) . mockReturnValue ( true ) ,
106
+ decryptEventIfNeeded : jest . fn ( ) . mockReturnThis ( ) ,
107
+ getUserId : jest . fn ( ) . mockReturnValue ( "@user:server" ) ,
108
+ } as unknown as MockedObject < MatrixClient > ;
109
+ const room = new Room ( "!roomid:e.xyz" , mockClient , "myname" ) ;
110
+ const ev = new MatrixEvent ( {
111
+ type : "m.room.message" ,
112
+ content : {
113
+ body : "Test" ,
114
+ } ,
115
+ event_id : "$event1:server" ,
116
+ } ) ;
117
+
118
+ await room . addLiveEvents ( [ ev ] ) ;
119
+ await room . createThreadsTimelineSets ( ) ;
120
+ expect ( ev . threadRootId ) . toBeUndefined ( ) ;
121
+ expect ( mainTimelineLiveEventIds ( room ) ) . toEqual ( [ "$event1:server" ] ) ;
122
+
123
+ // When I redact it
124
+ const redaction = new MatrixEvent ( {
125
+ type : "m.room.redaction" ,
126
+ redacts : ev . getId ( ) ,
127
+ } ) ;
128
+ ev . makeRedacted ( redaction , room ) ;
129
+
130
+ // Then it remains in the main timeline
131
+ expect ( ev . threadRootId ) . toBeUndefined ( ) ;
132
+ expect ( mainTimelineLiveEventIds ( room ) ) . toEqual ( [ "$event1:server" ] ) ;
133
+ } ) ;
134
+
135
+ it ( "should move into the main timeline when redacted" , async ( ) => {
136
+ // Given an event in a thread
137
+ const mockClient = {
138
+ supportsThreads : jest . fn ( ) . mockReturnValue ( true ) ,
139
+ decryptEventIfNeeded : jest . fn ( ) . mockReturnThis ( ) ,
140
+ getUserId : jest . fn ( ) . mockReturnValue ( "@user:server" ) ,
141
+ } as unknown as MockedObject < MatrixClient > ;
142
+ const room = new Room ( "!roomid:e.xyz" , mockClient , "myname" ) ;
143
+ const threadRoot = new MatrixEvent ( {
144
+ type : "m.room.message" ,
145
+ content : {
146
+ body : "threadRoot" ,
147
+ } ,
148
+ event_id : "$threadroot:server" ,
149
+ } ) ;
150
+ const ev = new MatrixEvent ( {
151
+ type : "m.room.message" ,
152
+ content : {
153
+ "body" : "Test" ,
154
+ "m.relates_to" : {
155
+ rel_type : THREAD_RELATION_TYPE . name ,
156
+ event_id : "$threadroot:server" ,
157
+ } ,
158
+ } ,
159
+ event_id : "$event1:server" ,
160
+ } ) ;
161
+
162
+ await room . addLiveEvents ( [ threadRoot , ev ] ) ;
163
+ await room . createThreadsTimelineSets ( ) ;
164
+ expect ( ev . threadRootId ) . toEqual ( "$threadroot:server" ) ;
165
+ expect ( mainTimelineLiveEventIds ( room ) ) . toEqual ( [ "$threadroot:server" ] ) ;
166
+ expect ( threadLiveEventIds ( room , 0 ) ) . toEqual ( [ "$threadroot:server" , "$event1:server" ] ) ;
167
+
168
+ // When I redact it
169
+ const redaction = new MatrixEvent ( {
170
+ type : "m.room.redaction" ,
171
+ redacts : ev . getId ( ) ,
172
+ } ) ;
173
+ ev . makeRedacted ( redaction , room ) ;
174
+
175
+ // Then it disappears from the thread and appears in the main timeline
176
+ expect ( ev . threadRootId ) . toBeUndefined ( ) ;
177
+ expect ( mainTimelineLiveEventIds ( room ) ) . toEqual ( [ "$threadroot:server" , "$event1:server" ] ) ;
178
+ expect ( threadLiveEventIds ( room , 0 ) ) . not . toContain ( "$event1:server" ) ;
179
+ } ) ;
180
+
91
181
describe ( "applyVisibilityEvent" , ( ) => {
92
182
it ( "should emit VisibilityChange if a change was made" , async ( ) => {
93
183
const ev = new MatrixEvent ( {
@@ -330,3 +420,19 @@ describe("MatrixEvent", () => {
330
420
expect ( stateEvent . threadRootId ) . toBeUndefined ( ) ;
331
421
} ) ;
332
422
} ) ;
423
+
424
+ function mainTimelineLiveEventIds ( room : Room ) : Array < string > {
425
+ return room
426
+ . getLiveTimeline ( )
427
+ . getEvents ( )
428
+ . map ( ( e ) => e . getId ( ) ! ) ;
429
+ }
430
+
431
+ function threadLiveEventIds ( room : Room , threadIndex : number ) : Array < string > {
432
+ return room
433
+ . getThreads ( )
434
+ [ threadIndex ] . getUnfilteredTimelineSet ( )
435
+ . getLiveTimeline ( )
436
+ . getEvents ( )
437
+ . map ( ( e ) => e . getId ( ) ! ) ;
438
+ }
0 commit comments