@@ -12,6 +12,7 @@ import TestClient from '../TestClient';
1212import { MatrixEvent } from '../../lib/models/event' ;
1313import Room from '../../lib/models/room' ;
1414import olmlib from '../../lib/crypto/olmlib' ;
15+ import lolex from 'lolex' ;
1516
1617const EventEmitter = require ( "events" ) . EventEmitter ;
1718
@@ -297,5 +298,69 @@ describe("Crypto", function() {
297298 expect ( await cryptoStore . getOutgoingRoomKeyRequest ( roomKeyRequestBody ) )
298299 . toExist ( ) ;
299300 } ) ;
301+
302+ it ( "uses a new txnid for re-requesting keys" , async function ( ) {
303+ const event = new MatrixEvent ( {
304+ sender : "@bob:example.com" ,
305+ room_id : "!someroom" ,
306+ content : {
307+ algorithm : olmlib . MEGOLM_ALGORITHM ,
308+ session_id : "sessionid" ,
309+ sender_key : "senderkey" ,
310+ } ,
311+ } ) ;
312+ /* return a promise and a function. When the function is called,
313+ * the promise will be resolved.
314+ */
315+ function awaitFunctionCall ( ) {
316+ let func ;
317+ const promise = new Promise ( ( resolve , reject ) => {
318+ func = function ( ...args ) {
319+ resolve ( args ) ;
320+ return new Promise ( ( resolve , reject ) => {
321+ // give us some time to process the result before
322+ // continuing
323+ global . setTimeout ( resolve , 1 ) ;
324+ } ) ;
325+ } ;
326+ } ) ;
327+ return { func, promise} ;
328+ }
329+
330+ aliceClient . startClient ( ) ;
331+
332+ const clock = lolex . install ( ) ;
333+
334+ try {
335+ let promise ;
336+ // make a room key request, and record the transaction ID for the
337+ // sendToDevice call
338+ ( { promise, func : aliceClient . sendToDevice } = awaitFunctionCall ( ) ) ;
339+ await aliceClient . cancelAndResendEventRoomKeyRequest ( event ) ;
340+ clock . runToLast ( ) ;
341+ let args = await promise ;
342+ const txnId = args [ 2 ] ;
343+ clock . runToLast ( ) ;
344+
345+ // give the room key request manager time to update the state
346+ // of the request
347+ await Promise . resolve ( ) ;
348+
349+ // cancel and resend the room key request
350+ ( { promise, func : aliceClient . sendToDevice } = awaitFunctionCall ( ) ) ;
351+ await aliceClient . cancelAndResendEventRoomKeyRequest ( event ) ;
352+ clock . runToLast ( ) ;
353+ // the first call to sendToDevice will be the cancellation
354+ args = await promise ;
355+ // the second call to sendToDevice will be the key request
356+ ( { promise, func : aliceClient . sendToDevice } = awaitFunctionCall ( ) ) ;
357+ clock . runToLast ( ) ;
358+ args = await promise ;
359+ clock . runToLast ( ) ;
360+ expect ( args [ 2 ] ) . toNotBe ( txnId ) ;
361+ } finally {
362+ clock . uninstall ( ) ;
363+ }
364+ } ) ;
300365 } ) ;
301366} ) ;
0 commit comments