@@ -17,24 +17,16 @@ limitations under the License.
17
17
import "fake-indexeddb/auto" ;
18
18
import { IDBFactory } from "fake-indexeddb" ;
19
19
import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js" ;
20
- import {
21
- KeysBackupRequest ,
22
- KeysClaimRequest ,
23
- KeysQueryRequest ,
24
- KeysUploadRequest ,
25
- OlmMachine ,
26
- SignatureUploadRequest ,
27
- } from "@matrix-org/matrix-sdk-crypto-js" ;
20
+ import { KeysQueryRequest , OlmMachine } from "@matrix-org/matrix-sdk-crypto-js" ;
28
21
import { Mocked } from "jest-mock" ;
29
- import MockHttpBackend from "matrix-mock-request" ;
30
22
31
- import { RustCrypto } from "../../src/rust-crypto/rust-crypto" ;
32
- import { initRustCrypto } from "../../src/rust-crypto" ;
33
- import { HttpApiEvent , HttpApiEventHandlerMap , IToDeviceEvent , MatrixClient , MatrixHttpApi } from "../../src" ;
34
- import { TypedEventEmitter } from "../../src/models/typed-event-emitter " ;
35
- import { mkEvent } from "../test-utils/test-utils " ;
36
- import { CryptoBackend } from "../../src/common-crypto/CryptoBackend " ;
37
- import { IEventDecryptionResult } from "../../src/@types/ crypto" ;
23
+ import { RustCrypto } from "../../../ src/rust-crypto/rust-crypto" ;
24
+ import { initRustCrypto } from "../../../ src/rust-crypto" ;
25
+ import { IToDeviceEvent , MatrixClient , MatrixHttpApi } from "../ ../../src" ;
26
+ import { mkEvent } from "../../test-utils/test-utils " ;
27
+ import { CryptoBackend } from "../../../src/common-crypto/CryptoBackend " ;
28
+ import { IEventDecryptionResult } from "../../../ src/@types/crypto " ;
29
+ import { OutgoingRequestProcessor } from "../../../ src/rust- crypto/OutgoingRequestProcessor " ;
38
30
39
31
afterEach ( ( ) => {
40
32
// reset fake-indexeddb after each test, to make sure we don't leak connections
@@ -106,8 +98,8 @@ describe("RustCrypto", () => {
106
98
/** the RustCrypto implementation under test */
107
99
let rustCrypto : RustCrypto ;
108
100
109
- /** A mock http backend which rustCrypto is connected to */
110
- let httpBackend : MockHttpBackend ;
101
+ /** A mock OutgoingRequestProcessor which rustCrypto is connected to */
102
+ let outgoingRequestProcessor : Mocked < OutgoingRequestProcessor > ;
111
103
112
104
/** a mocked-up OlmMachine which rustCrypto is connected to */
113
105
let olmMachine : Mocked < RustSdkCryptoJs . OlmMachine > ;
@@ -116,120 +108,81 @@ describe("RustCrypto", () => {
116
108
* the front of the queue, until it is empty. */
117
109
let outgoingRequestQueue : Array < Array < any > > ;
118
110
119
- /** wait for a call to olmMachine.markRequestAsSent */
120
- function awaitCallToMarkAsSent ( ) : Promise < void > {
121
- return new Promise ( ( resolve , _reject ) => {
122
- olmMachine . markRequestAsSent . mockImplementationOnce ( async ( ) => {
123
- resolve ( undefined ) ;
111
+ /** wait for a call to outgoingRequestProcessor.makeOutgoingRequest.
112
+ *
113
+ * The promise resolves to a callback: the makeOutgoingRequest call will not complete until the returned
114
+ * callback is called.
115
+ */
116
+ function awaitCallToMakeOutgoingRequest ( ) : Promise < ( ) => void > {
117
+ return new Promise < ( ) => void > ( ( resolveCalledPromise , _reject ) => {
118
+ outgoingRequestProcessor . makeOutgoingRequest . mockImplementationOnce ( async ( ) => {
119
+ const completePromise = new Promise < void > ( ( resolveCompletePromise , _reject ) => {
120
+ resolveCalledPromise ( resolveCompletePromise ) ;
121
+ } ) ;
122
+ return completePromise ;
124
123
} ) ;
125
124
} ) ;
126
125
}
127
126
128
127
beforeEach ( async ( ) => {
129
- httpBackend = new MockHttpBackend ( ) ;
130
-
131
128
await RustSdkCryptoJs . initAsync ( ) ;
132
129
133
- const dummyEventEmitter = new TypedEventEmitter < HttpApiEvent , HttpApiEventHandlerMap > ( ) ;
134
- const httpApi = new MatrixHttpApi ( dummyEventEmitter , {
135
- baseUrl : "https://example.com" ,
136
- prefix : "/_matrix" ,
137
- fetchFn : httpBackend . fetchFn as typeof global . fetch ,
138
- onlyData : true ,
139
- } ) ;
140
-
141
130
// for these tests we use a mock OlmMachine, with an implementation of outgoingRequests that
142
131
// returns objects from outgoingRequestQueue
143
132
outgoingRequestQueue = [ ] ;
144
133
olmMachine = {
145
134
outgoingRequests : jest . fn ( ) . mockImplementation ( ( ) => {
146
135
return Promise . resolve ( outgoingRequestQueue . shift ( ) ?? [ ] ) ;
147
136
} ) ,
148
- markRequestAsSent : jest . fn ( ) ,
149
137
close : jest . fn ( ) ,
150
138
} as unknown as Mocked < RustSdkCryptoJs . OlmMachine > ;
151
139
152
- rustCrypto = new RustCrypto ( olmMachine , httpApi , TEST_USER , TEST_DEVICE_ID ) ;
153
- } ) ;
140
+ outgoingRequestProcessor = {
141
+ makeOutgoingRequest : jest . fn ( ) ,
142
+ } as unknown as Mocked < OutgoingRequestProcessor > ;
154
143
155
- it ( "should poll for outgoing messages" , ( ) => {
156
- rustCrypto . onSyncCompleted ( { } ) ;
157
- expect ( olmMachine . outgoingRequests ) . toHaveBeenCalled ( ) ;
144
+ rustCrypto = new RustCrypto ( olmMachine , { } as MatrixHttpApi < any > , TEST_USER , TEST_DEVICE_ID ) ;
145
+ rustCrypto [ "outgoingRequestProcessor" ] = outgoingRequestProcessor ;
158
146
} ) ;
159
147
160
- /* simple requests that map directly to the request body */
161
- const tests : Array < [ any , "POST" | "PUT" , string ] > = [
162
- [ KeysUploadRequest , "POST" , "https://example.com/_matrix/client/v3/keys/upload" ] ,
163
- [ KeysQueryRequest , "POST" , "https://example.com/_matrix/client/v3/keys/query" ] ,
164
- [ KeysClaimRequest , "POST" , "https://example.com/_matrix/client/v3/keys/claim" ] ,
165
- [ SignatureUploadRequest , "POST" , "https://example.com/_matrix/client/v3/keys/signatures/upload" ] ,
166
- [ KeysBackupRequest , "PUT" , "https://example.com/_matrix/client/v3/room_keys/keys" ] ,
167
- ] ;
168
-
169
- for ( const [ RequestClass , expectedMethod , expectedPath ] of tests ) {
170
- it ( `should handle ${ RequestClass . name } s` , async ( ) => {
171
- const testBody = '{ "foo": "bar" }' ;
172
- const outgoingRequest = new RequestClass ( "1234" , testBody ) ;
173
- outgoingRequestQueue . push ( [ outgoingRequest ] ) ;
174
-
175
- const testResponse = '{ "result": 1 }' ;
176
- httpBackend
177
- . when ( expectedMethod , "/_matrix" )
178
- . check ( ( req ) => {
179
- expect ( req . path ) . toEqual ( expectedPath ) ;
180
- expect ( req . rawData ) . toEqual ( testBody ) ;
181
- expect ( req . headers [ "Accept" ] ) . toEqual ( "application/json" ) ;
182
- expect ( req . headers [ "Content-Type" ] ) . toEqual ( "application/json" ) ;
183
- } )
184
- . respond ( 200 , testResponse , true ) ;
185
-
186
- rustCrypto . onSyncCompleted ( { } ) ;
187
-
188
- expect ( olmMachine . outgoingRequests ) . toHaveBeenCalledTimes ( 1 ) ;
189
-
190
- const markSentCallPromise = awaitCallToMarkAsSent ( ) ;
191
- await httpBackend . flushAllExpected ( ) ;
192
-
193
- await markSentCallPromise ;
194
- expect ( olmMachine . markRequestAsSent ) . toHaveBeenCalledWith ( "1234" , outgoingRequest . type , testResponse ) ;
195
- httpBackend . verifyNoOutstandingRequests ( ) ;
196
- } ) ;
197
- }
198
-
199
- it ( "does not explode with unknown requests" , async ( ) => {
200
- const outgoingRequest = { id : "5678" , type : 987 } ;
201
- outgoingRequestQueue . push ( [ outgoingRequest ] ) ;
148
+ it ( "should poll for outgoing messages and send them" , async ( ) => {
149
+ const testReq = new KeysQueryRequest ( "1234" , "{}" ) ;
150
+ outgoingRequestQueue . push ( [ testReq ] ) ;
202
151
152
+ const makeRequestPromise = awaitCallToMakeOutgoingRequest ( ) ;
203
153
rustCrypto . onSyncCompleted ( { } ) ;
204
154
205
- await awaitCallToMarkAsSent ( ) ;
206
- expect ( olmMachine . markRequestAsSent ) . toHaveBeenCalledWith ( "5678" , 987 , "" ) ;
155
+ await makeRequestPromise ;
156
+ expect ( olmMachine . outgoingRequests ) . toHaveBeenCalled ( ) ;
157
+ expect ( outgoingRequestProcessor . makeOutgoingRequest ) . toHaveBeenCalledWith ( testReq ) ;
207
158
} ) ;
208
159
209
160
it ( "stops looping when stop() is called" , async ( ) => {
210
- const testResponse = '{ "result": 1 }' ;
211
-
212
161
for ( let i = 0 ; i < 5 ; i ++ ) {
213
162
outgoingRequestQueue . push ( [ new KeysQueryRequest ( "1234" , "{}" ) ] ) ;
214
- httpBackend . when ( "POST" , "/_matrix" ) . respond ( 200 , testResponse , true ) ;
215
163
}
216
164
165
+ let makeRequestPromise = awaitCallToMakeOutgoingRequest ( ) ;
166
+
217
167
rustCrypto . onSyncCompleted ( { } ) ;
218
168
219
169
expect ( rustCrypto [ "outgoingRequestLoopRunning" ] ) . toBeTruthy ( ) ;
220
170
221
171
// go a couple of times round the loop
222
- await httpBackend . flush ( "/_matrix" , 1 ) ;
223
- await awaitCallToMarkAsSent ( ) ;
172
+ let resolveMakeRequest = await makeRequestPromise ;
173
+ makeRequestPromise = awaitCallToMakeOutgoingRequest ( ) ;
174
+ resolveMakeRequest ( ) ;
224
175
225
- await httpBackend . flush ( "/_matrix" , 1 ) ;
226
- await awaitCallToMarkAsSent ( ) ;
176
+ resolveMakeRequest = await makeRequestPromise ;
177
+ makeRequestPromise = awaitCallToMakeOutgoingRequest ( ) ;
178
+ resolveMakeRequest ( ) ;
227
179
228
180
// a second sync while this is going on shouldn't make any difference
229
181
rustCrypto . onSyncCompleted ( { } ) ;
230
182
231
- await httpBackend . flush ( "/_matrix" , 1 ) ;
232
- await awaitCallToMarkAsSent ( ) ;
183
+ resolveMakeRequest = await makeRequestPromise ;
184
+ outgoingRequestProcessor . makeOutgoingRequest . mockReset ( ) ;
185
+ resolveMakeRequest ( ) ;
233
186
234
187
// now stop...
235
188
rustCrypto . stop ( ) ;
@@ -241,7 +194,7 @@ describe("RustCrypto", () => {
241
194
setTimeout ( resolve , 100 ) ;
242
195
} ) ;
243
196
expect ( rustCrypto [ "outgoingRequestLoopRunning" ] ) . toBeFalsy ( ) ;
244
- httpBackend . verifyNoOutstandingRequests ( ) ;
197
+ expect ( outgoingRequestProcessor . makeOutgoingRequest ) . not . toHaveBeenCalled ( ) ;
245
198
expect ( olmMachine . outgoingRequests ) . not . toHaveBeenCalled ( ) ;
246
199
247
200
// we sent three, so there should be 2 left
0 commit comments