@@ -59,8 +59,35 @@ class MockWidgetApi extends EventEmitter {
5959 public requestCapabilityToReceiveState = jest . fn ( ) ;
6060 public requestCapabilityToSendToDevice = jest . fn ( ) ;
6161 public requestCapabilityToReceiveToDevice = jest . fn ( ) ;
62- public sendRoomEvent = jest . fn ( ( ) => ( { event_id : `$${ Math . random ( ) } ` } ) ) ;
63- public sendStateEvent = jest . fn ( ( ) => ( { event_id : `$${ Math . random ( ) } ` } ) ) ;
62+ public sendRoomEvent = jest . fn (
63+ ( eventType : string , content : unknown , roomId ?: string , futureTimeout ?: number , futureGroupId ?: string ) =>
64+ futureTimeout === undefined && futureGroupId === undefined
65+ ? { event_id : `$${ Math . random ( ) } ` }
66+ : {
67+ future_group_id : futureGroupId ?? `fg-${ Math . random ( ) } ` ,
68+ send_token : `st-${ Math . random ( ) } ` ,
69+ cancel_token : `ct-${ Math . random ( ) } ` ,
70+ refresh_token : `rt-${ Math . random ( ) } ` ,
71+ } ,
72+ ) ;
73+ public sendStateEvent = jest . fn (
74+ (
75+ eventType : string ,
76+ stateKey : string ,
77+ content : unknown ,
78+ roomId ?: string ,
79+ futureTimeout ?: number ,
80+ futureGroupId ?: string ,
81+ ) =>
82+ futureTimeout === undefined && futureGroupId === undefined
83+ ? { event_id : `$${ Math . random ( ) } ` }
84+ : {
85+ future_group_id : futureGroupId ?? `fg-${ Math . random ( ) } ` ,
86+ send_token : `st-${ Math . random ( ) } ` ,
87+ cancel_token : `ct-${ Math . random ( ) } ` ,
88+ refresh_token : `rt-${ Math . random ( ) } ` ,
89+ } ,
90+ ) ;
6491 public sendToDevice = jest . fn ( ) ;
6592 public requestOpenIDConnectToken = jest . fn ( ( ) => {
6693 return testOIDCToken ;
@@ -160,6 +187,106 @@ describe("RoomWidgetClient", () => {
160187 } ) ;
161188 } ) ;
162189
190+ describe ( "futures" , ( ) => {
191+ const doesServerSupportUnstableFeatureMock = jest . fn ( ( feature ) =>
192+ Promise . resolve ( feature === "org.matrix.msc4140" ) ,
193+ ) ;
194+
195+ beforeAll ( ( ) => {
196+ MatrixClient . prototype . doesServerSupportUnstableFeature = doesServerSupportUnstableFeatureMock ;
197+ } ) ;
198+
199+ afterAll ( ( ) => {
200+ doesServerSupportUnstableFeatureMock . mockClear ( ) ;
201+ } ) ;
202+
203+ it ( "sends futures in a new group for message events" , async ( ) => {
204+ await makeClient ( { sendEvent : [ "org.matrix.rageshake_request" ] } ) ;
205+ expect ( widgetApi . requestCapabilityForRoomTimeline ) . toHaveBeenCalledWith ( "!1:example.org" ) ;
206+ expect ( widgetApi . requestCapabilityToSendEvent ) . toHaveBeenCalledWith ( "org.matrix.rageshake_request" ) ;
207+ const futureOpts = {
208+ future_timeout : 2000 ,
209+ } ;
210+ await client . _unstable_sendFuture ( "!1:example.org" , futureOpts , null , "org.matrix.rageshake_request" , {
211+ request_id : 123 ,
212+ } ) ;
213+ expect ( widgetApi . sendRoomEvent ) . toHaveBeenCalledWith (
214+ "org.matrix.rageshake_request" ,
215+ { request_id : 123 } ,
216+ "!1:example.org" ,
217+ futureOpts . future_timeout ,
218+ undefined ,
219+ ) ;
220+ } ) ;
221+
222+ it ( "sends action futures in an existing group for message events" , async ( ) => {
223+ await makeClient ( { sendEvent : [ "org.matrix.rageshake_request" ] } ) ;
224+ expect ( widgetApi . requestCapabilityForRoomTimeline ) . toHaveBeenCalledWith ( "!1:example.org" ) ;
225+ expect ( widgetApi . requestCapabilityToSendEvent ) . toHaveBeenCalledWith ( "org.matrix.rageshake_request" ) ;
226+ const futureOpts = {
227+ future_group_id : "fg" ,
228+ } ;
229+ await client . _unstable_sendFuture ( "!1:example.org" , futureOpts , null , "org.matrix.rageshake_request" , {
230+ request_id : 123 ,
231+ } ) ;
232+ expect ( widgetApi . sendRoomEvent ) . toHaveBeenCalledWith (
233+ "org.matrix.rageshake_request" ,
234+ { request_id : 123 } ,
235+ "!1:example.org" ,
236+ undefined ,
237+ futureOpts . future_group_id ,
238+ ) ;
239+ } ) ;
240+
241+ it ( "sends futures in a new group for state events" , async ( ) => {
242+ await makeClient ( { sendState : [ { eventType : "org.example.foo" , stateKey : "bar" } ] } ) ;
243+ expect ( widgetApi . requestCapabilityForRoomTimeline ) . toHaveBeenCalledWith ( "!1:example.org" ) ;
244+ expect ( widgetApi . requestCapabilityToSendState ) . toHaveBeenCalledWith ( "org.example.foo" , "bar" ) ;
245+ const futureOpts = {
246+ future_timeout : 2000 ,
247+ } ;
248+ await client . _unstable_sendStateFuture (
249+ "!1:example.org" ,
250+ futureOpts ,
251+ "org.example.foo" ,
252+ { hello : "world" } ,
253+ "bar" ,
254+ ) ;
255+ expect ( widgetApi . sendStateEvent ) . toHaveBeenCalledWith (
256+ "org.example.foo" ,
257+ "bar" ,
258+ { hello : "world" } ,
259+ "!1:example.org" ,
260+ futureOpts . future_timeout ,
261+ undefined ,
262+ ) ;
263+ } ) ;
264+
265+ it ( "sends action futures in an existing group for state events" , async ( ) => {
266+ await makeClient ( { sendState : [ { eventType : "org.example.foo" , stateKey : "bar" } ] } ) ;
267+ expect ( widgetApi . requestCapabilityForRoomTimeline ) . toHaveBeenCalledWith ( "!1:example.org" ) ;
268+ expect ( widgetApi . requestCapabilityToSendState ) . toHaveBeenCalledWith ( "org.example.foo" , "bar" ) ;
269+ const futureOpts = {
270+ future_group_id : "fg" ,
271+ } ;
272+ await client . _unstable_sendStateFuture (
273+ "!1:example.org" ,
274+ futureOpts ,
275+ "org.example.foo" ,
276+ { hello : "world" } ,
277+ "bar" ,
278+ ) ;
279+ expect ( widgetApi . sendStateEvent ) . toHaveBeenCalledWith (
280+ "org.example.foo" ,
281+ "bar" ,
282+ { hello : "world" } ,
283+ "!1:example.org" ,
284+ undefined ,
285+ futureOpts . future_group_id ,
286+ ) ;
287+ } ) ;
288+ } ) ;
289+
163290 describe ( "initialization" , ( ) => {
164291 it ( "requests permissions for specific message types" , async ( ) => {
165292 await makeClient ( { sendMessage : [ MsgType . Text ] , receiveMessage : [ MsgType . Text ] } ) ;
0 commit comments