@@ -127,6 +127,7 @@ describe("Crypto", function() {
127127 describe ( 'Key requests' , function ( ) {
128128 let aliceClient ;
129129 let bobClient ;
130+ let realSetTimeout ;
130131
131132 beforeEach ( async function ( ) {
132133 aliceClient = ( new TestClient (
@@ -137,9 +138,15 @@ describe("Crypto", function() {
137138 ) ) . client ;
138139 await aliceClient . initCrypto ( ) ;
139140 await bobClient . initCrypto ( ) ;
141+ // clobber the setTimeout function to run 10x faster.
142+ realSetTimeout = global . setTimeout ;
143+ global . setTimeout = function ( f , n ) {
144+ return realSetTimeout ( f , n / 10 ) ;
145+ } ;
140146 } ) ;
141147
142148 afterEach ( async function ( ) {
149+ global . setTimeout = realSetTimeout ;
143150 aliceClient . stopClient ( ) ;
144151 bobClient . stopClient ( ) ;
145152 } ) ;
@@ -297,5 +304,50 @@ describe("Crypto", function() {
297304 expect ( await cryptoStore . getOutgoingRoomKeyRequest ( roomKeyRequestBody ) )
298305 . toExist ( ) ;
299306 } ) ;
307+
308+ it ( "uses a new txnid for re-requesting keys" , async function ( ) {
309+ const event = new MatrixEvent ( {
310+ sender : "@bob:example.com" ,
311+ room_id : "!someroom" ,
312+ content : {
313+ algorithm : olmlib . MEGOLM_ALGORITHM ,
314+ session_id : "sessionid" ,
315+ sender_key : "senderkey" ,
316+ } ,
317+ } ) ;
318+ /* return a promise and a function. When the function is called,
319+ * the promise will be resolved.
320+ */
321+ function awaitFunctionCall ( ) {
322+ let func ;
323+ const promise = new Promise ( ( resolve , reject ) => {
324+ func = function ( ...args ) {
325+ global . setTimeout ( ( ) => resolve ( args ) , 10 ) ;
326+ return Promise . resolve ( ) ;
327+ } ;
328+ } ) ;
329+ return { func, promise} ;
330+ }
331+
332+ aliceClient . startClient ( ) ;
333+
334+ let promise ;
335+ // make a room key request, and record the transaction ID for the
336+ // sendToDevice call
337+ ( { promise, func : aliceClient . sendToDevice } = awaitFunctionCall ( ) ) ;
338+ await aliceClient . cancelAndResendEventRoomKeyRequest ( event ) ;
339+ let args = await promise ;
340+ const txnId = args [ 2 ] ;
341+
342+ // cancel and resend the room key request
343+ ( { promise, func : aliceClient . sendToDevice } = awaitFunctionCall ( ) ) ;
344+ await aliceClient . cancelAndResendEventRoomKeyRequest ( event ) ;
345+ // the first call to sendToDevice will be the cancellation
346+ args = await promise ;
347+ // the second call to sendToDevice will be the key request
348+ ( { promise, func : aliceClient . sendToDevice } = awaitFunctionCall ( ) ) ;
349+ args = await promise ;
350+ expect ( args [ 2 ] ) . toNotBe ( txnId ) ;
351+ } ) ;
300352 } ) ;
301353} ) ;
0 commit comments