@@ -27,12 +27,11 @@ import {
27
27
MatrixEvent ,
28
28
PendingEventOrdering ,
29
29
Room ,
30
- RoomEvent ,
31
30
} from "../../src/matrix" ;
32
31
import { logger } from "../../src/logger" ;
33
- import { encodeUri } from "../../src/utils" ;
32
+ import { encodeParams , encodeUri , QueryDict , replaceParam } from "../../src/utils" ;
34
33
import { TestClient } from "../TestClient" ;
35
- import { FeatureSupport , Thread , THREAD_RELATION_TYPE } from "../../src/models/thread" ;
34
+ import { FeatureSupport , Thread , THREAD_RELATION_TYPE , ThreadEvent } from "../../src/models/thread" ;
36
35
import { emitPromise } from "../test-utils/test-utils" ;
37
36
38
37
const userId = "@alice:localhost" ;
@@ -47,6 +46,18 @@ const withoutRoomId = (e: Partial<IEvent>): Partial<IEvent> => {
47
46
return copy ;
48
47
} ;
49
48
49
+ /**
50
+ * Our httpBackend only allows matching calls if we have the exact same query, in the exact same order
51
+ * This method allows building queries with the exact same parameter order as the fetchRelations method in client
52
+ * @param params query parameters
53
+ */
54
+ const buildRelationPaginationQuery = ( params : QueryDict ) : string => {
55
+ if ( Thread . hasServerSideFwdPaginationSupport === FeatureSupport . Experimental ) {
56
+ params = replaceParam ( "dir" , "org.matrix.msc3715.dir" , params ) ;
57
+ }
58
+ return "?" + encodeParams ( params ) . toString ( ) ;
59
+ } ;
60
+
50
61
const USER_MEMBERSHIP_EVENT = utils . mkMembership ( {
51
62
room : roomId ,
52
63
mship : "join" ,
@@ -595,42 +606,6 @@ describe("MatrixClient event timelines", function () {
595
606
. respond ( 200 , function ( ) {
596
607
return THREAD_ROOT ;
597
608
} ) ;
598
-
599
- httpBackend
600
- . when (
601
- "GET" ,
602
- "/_matrix/client/v1/rooms/!foo%3Abar/relations/" +
603
- encodeURIComponent ( THREAD_ROOT . event_id ! ) +
604
- "/" +
605
- encodeURIComponent ( THREAD_RELATION_TYPE . name ) +
606
- "?dir=b&limit=1" ,
607
- )
608
- . respond ( 200 , function ( ) {
609
- return {
610
- original_event : THREAD_ROOT ,
611
- chunk : [ THREAD_REPLY ] ,
612
- // no next batch as this is the oldest end of the timeline
613
- } ;
614
- } ) ;
615
-
616
- const thread = room . createThread ( THREAD_ROOT . event_id ! , undefined , [ ] , false ) ;
617
- await httpBackend . flushAllExpected ( ) ;
618
- const timelineSet = thread . timelineSet ;
619
-
620
- const timelinePromise = client . getEventTimeline ( timelineSet , THREAD_REPLY . event_id ! ) ;
621
- const timeline = await timelinePromise ;
622
-
623
- expect ( timeline ! . getEvents ( ) . find ( ( e ) => e . getId ( ) === THREAD_ROOT . event_id ! ) ) . toBeTruthy ( ) ;
624
- expect ( timeline ! . getEvents ( ) . find ( ( e ) => e . getId ( ) === THREAD_REPLY . event_id ! ) ) . toBeTruthy ( ) ;
625
- } ) ;
626
-
627
- it ( "should handle thread replies with server support by fetching a contiguous thread timeline" , async ( ) => {
628
- // @ts -ignore
629
- client . clientOpts . experimentalThreadSupport = true ;
630
- Thread . setServerSideSupport ( FeatureSupport . Experimental ) ;
631
- await client . stopClient ( ) ; // we don't need the client to be syncing at this time
632
- const room = client . getRoom ( roomId ) ! ;
633
-
634
609
httpBackend
635
610
. when ( "GET" , "/rooms/!foo%3Abar/event/" + encodeURIComponent ( THREAD_ROOT . event_id ! ) )
636
611
. respond ( 200 , function ( ) {
@@ -644,7 +619,7 @@ describe("MatrixClient event timelines", function () {
644
619
encodeURIComponent ( THREAD_ROOT . event_id ! ) +
645
620
"/" +
646
621
encodeURIComponent ( THREAD_RELATION_TYPE . name ) +
647
- "? dir=b& limit=1" ,
622
+ buildRelationPaginationQuery ( { dir : Direction . Backward , limit : 1 } ) ,
648
623
)
649
624
. respond ( 200 , function ( ) {
650
625
return {
@@ -656,15 +631,14 @@ describe("MatrixClient event timelines", function () {
656
631
const thread = room . createThread ( THREAD_ROOT . event_id ! , undefined , [ ] , false ) ;
657
632
await httpBackend . flushAllExpected ( ) ;
658
633
const timelineSet = thread . timelineSet ;
659
-
660
634
httpBackend
661
635
. when ( "GET" , "/rooms/!foo%3Abar/event/" + encodeURIComponent ( THREAD_ROOT . event_id ! ) )
662
636
. respond ( 200 , function ( ) {
663
637
return THREAD_ROOT ;
664
638
} ) ;
639
+ await flushHttp ( emitPromise ( thread , ThreadEvent . Update ) ) ;
665
640
666
- const timelinePromise = client . getEventTimeline ( timelineSet , THREAD_REPLY . event_id ! ) ;
667
- const [ timeline ] = await Promise . all ( [ timelinePromise , httpBackend . flushAllExpected ( ) ] ) ;
641
+ const timeline = await client . getEventTimeline ( timelineSet , THREAD_REPLY . event_id ! ) ;
668
642
669
643
const eventIds = timeline ! . getEvents ( ) . map ( ( it ) => it . getId ( ) ) ;
670
644
expect ( eventIds ) . toContain ( THREAD_ROOT . event_id ) ;
@@ -1273,7 +1247,7 @@ describe("MatrixClient event timelines", function () {
1273
1247
event_id : THREAD_ROOT . event_id ,
1274
1248
} ,
1275
1249
} ,
1276
- event : false ,
1250
+ event : true ,
1277
1251
} ) ;
1278
1252
1279
1253
// Test data for the first thread, with the second reply
@@ -1286,7 +1260,7 @@ describe("MatrixClient event timelines", function () {
1286
1260
"io.element.thread" : {
1287
1261
...THREAD_ROOT . unsigned ! [ "m.relations" ] ! [ "io.element.thread" ] ,
1288
1262
count : 2 ,
1289
- latest_event : THREAD_REPLY2 ,
1263
+ latest_event : THREAD_REPLY2 . event ,
1290
1264
} ,
1291
1265
} ,
1292
1266
} ,
@@ -1314,12 +1288,13 @@ describe("MatrixClient event timelines", function () {
1314
1288
respondToThreads ( threadsResponse ) ;
1315
1289
respondToThreads ( threadsResponse ) ;
1316
1290
respondToEvent ( THREAD_ROOT ) ;
1317
- respondToEvent ( THREAD_ROOT ) ;
1318
- respondToEvent ( THREAD2_ROOT ) ;
1319
1291
respondToEvent ( THREAD2_ROOT ) ;
1320
1292
respondToThread ( THREAD_ROOT , [ THREAD_REPLY ] ) ;
1321
1293
respondToThread ( THREAD2_ROOT , [ THREAD2_REPLY ] ) ;
1322
1294
await flushHttp ( room . fetchRoomThreads ( ) ) ;
1295
+ const threadIds = room . getThreads ( ) . map ( ( thread ) => thread . id ) ;
1296
+ expect ( threadIds ) . toContain ( THREAD_ROOT . event_id ) ;
1297
+ expect ( threadIds ) . toContain ( THREAD2_ROOT . event_id ) ;
1323
1298
const [ allThreads ] = timelineSets ! ;
1324
1299
const timeline = allThreads . getLiveTimeline ( ) ! ;
1325
1300
// Test threads are in chronological order
@@ -1330,12 +1305,15 @@ describe("MatrixClient event timelines", function () {
1330
1305
1331
1306
// Test adding a second event to the first thread
1332
1307
const thread = room . getThread ( THREAD_ROOT . event_id ! ) ! ;
1333
- const prom = emitPromise ( allThreads ! , RoomEvent . Timeline ) ;
1334
- await thread . addEvent ( client . getEventMapper ( ) ( THREAD_REPLY2 ) , false ) ;
1308
+ const prom = emitPromise ( room , ThreadEvent . NewReply ) ;
1309
+ respondToEvent ( THREAD_ROOT_UPDATED ) ;
1335
1310
respondToEvent ( THREAD_ROOT_UPDATED ) ;
1336
1311
respondToEvent ( THREAD_ROOT_UPDATED ) ;
1312
+ respondToEvent ( THREAD2_ROOT ) ;
1313
+ room . addLiveEvents ( [ THREAD_REPLY2 ] ) ;
1337
1314
await httpBackend . flushAllExpected ( ) ;
1338
1315
await prom ;
1316
+ expect ( thread . length ) . toBe ( 2 ) ;
1339
1317
// Test threads are in chronological order
1340
1318
expect ( timeline ! . getEvents ( ) . map ( ( it ) => it . event . event_id ) ) . toEqual ( [
1341
1319
THREAD2_ROOT . event_id ,
@@ -1652,24 +1630,6 @@ describe("MatrixClient event timelines", function () {
1652
1630
const thread = room . getThread ( THREAD_ROOT . event_id ! ) ! ;
1653
1631
const timelineSet = thread . timelineSet ;
1654
1632
1655
- const buildParams = ( direction : Direction , token : string ) : string => {
1656
- if ( Thread . hasServerSideFwdPaginationSupport === FeatureSupport . Experimental ) {
1657
- return `?from=${ token } &org.matrix.msc3715.dir=${ direction } ` ;
1658
- } else {
1659
- return `?dir=${ direction } &from=${ token } ` ;
1660
- }
1661
- } ;
1662
-
1663
- httpBackend
1664
- . when ( "GET" , "/rooms/!foo%3Abar/context/" + encodeURIComponent ( THREAD_ROOT . event_id ! ) )
1665
- . respond ( 200 , {
1666
- start : "start_token" ,
1667
- events_before : [ ] ,
1668
- event : THREAD_ROOT ,
1669
- events_after : [ ] ,
1670
- state : [ ] ,
1671
- end : "end_token" ,
1672
- } ) ;
1673
1633
httpBackend
1674
1634
. when ( "GET" , "/rooms/!foo%3Abar/event/" + encodeURIComponent ( THREAD_ROOT . event_id ! ) )
1675
1635
. respond ( 200 , function ( ) {
@@ -1692,27 +1652,11 @@ describe("MatrixClient event timelines", function () {
1692
1652
encodeURIComponent ( THREAD_ROOT . event_id ! ) +
1693
1653
"/" +
1694
1654
encodeURIComponent ( THREAD_RELATION_TYPE . name ) +
1695
- buildParams ( Direction . Backward , "start_token" ) ,
1655
+ buildRelationPaginationQuery ( { dir : Direction . Backward , limit : 1 } ) ,
1696
1656
)
1697
1657
. respond ( 200 , function ( ) {
1698
1658
return {
1699
- original_event : THREAD_ROOT ,
1700
- chunk : [ ] ,
1701
- } ;
1702
- } ) ;
1703
- httpBackend
1704
- . when (
1705
- "GET" ,
1706
- "/_matrix/client/v1/rooms/!foo%3Abar/relations/" +
1707
- encodeURIComponent ( THREAD_ROOT . event_id ! ) +
1708
- "/" +
1709
- encodeURIComponent ( THREAD_RELATION_TYPE . name ) +
1710
- buildParams ( Direction . Forward , "end_token" ) ,
1711
- )
1712
- . respond ( 200 , function ( ) {
1713
- return {
1714
- original_event : THREAD_ROOT ,
1715
- chunk : [ THREAD_REPLY ] ,
1659
+ chunk : [ THREAD_ROOT ] ,
1716
1660
} ;
1717
1661
} ) ;
1718
1662
const timeline = await flushHttp ( client . getEventTimeline ( timelineSet , THREAD_ROOT . event_id ! ) ) ;
0 commit comments