@@ -235,4 +235,133 @@ describe('AppCheckApiClient', () => {
235
235
} ) ;
236
236
} ) ;
237
237
} ) ;
238
+
239
+ describe ( 'verifyReplayProtection' , ( ) => {
240
+ it ( 'should reject when project id is not available' , ( ) => {
241
+ return clientWithoutProjectId . verifyReplayProtection ( TEST_TOKEN_TO_EXCHANGE )
242
+ . should . eventually . be . rejectedWith ( noProjectId ) ;
243
+ } ) ;
244
+
245
+ it ( 'should throw given no token' , ( ) => {
246
+ expect ( ( ) => {
247
+ ( apiClient as any ) . verifyReplayProtection ( undefined ) ;
248
+ } ) . to . throw ( '`token` must be a non-empty string.' ) ;
249
+ } ) ;
250
+
251
+ [ null , NaN , 0 , 1 , true , false , [ ] , { } , { a : 1 } , _ . noop ] . forEach ( ( invalidToken ) => {
252
+ it ( 'should throw given a non-string token: ' + JSON . stringify ( invalidToken ) , ( ) => {
253
+ expect ( ( ) => {
254
+ apiClient . verifyReplayProtection ( invalidToken as any ) ;
255
+ } ) . to . throw ( '`token` must be a non-empty string.' ) ;
256
+ } ) ;
257
+ } ) ;
258
+
259
+ it ( 'should throw given an empty string token' , ( ) => {
260
+ expect ( ( ) => {
261
+ apiClient . verifyReplayProtection ( '' ) ;
262
+ } ) . to . throw ( '`token` must be a non-empty string.' ) ;
263
+ } ) ;
264
+
265
+ it ( 'should reject when a full platform error response is received' , ( ) => {
266
+ const stub = sinon
267
+ . stub ( HttpClient . prototype , 'send' )
268
+ . rejects ( utils . errorFrom ( ERROR_RESPONSE , 404 ) ) ;
269
+ stubs . push ( stub ) ;
270
+ const expected = new FirebaseAppCheckError ( 'not-found' , 'Requested entity not found' ) ;
271
+ return apiClient . verifyReplayProtection ( TEST_TOKEN_TO_EXCHANGE )
272
+ . should . eventually . be . rejected . and . deep . include ( expected ) ;
273
+ } ) ;
274
+
275
+ it ( 'should reject with unknown-error when error code is not present' , ( ) => {
276
+ const stub = sinon
277
+ . stub ( HttpClient . prototype , 'send' )
278
+ . rejects ( utils . errorFrom ( { } , 404 ) ) ;
279
+ stubs . push ( stub ) ;
280
+ const expected = new FirebaseAppCheckError ( 'unknown-error' , 'Unknown server error: {}' ) ;
281
+ return apiClient . verifyReplayProtection ( TEST_TOKEN_TO_EXCHANGE )
282
+ . should . eventually . be . rejected . and . deep . include ( expected ) ;
283
+ } ) ;
284
+
285
+ it ( 'should reject with unknown-error for non-json response' , ( ) => {
286
+ const stub = sinon
287
+ . stub ( HttpClient . prototype , 'send' )
288
+ . rejects ( utils . errorFrom ( 'not json' , 404 ) ) ;
289
+ stubs . push ( stub ) ;
290
+ const expected = new FirebaseAppCheckError (
291
+ 'unknown-error' , 'Unexpected response with status: 404 and body: not json' ) ;
292
+ return apiClient . verifyReplayProtection ( TEST_TOKEN_TO_EXCHANGE )
293
+ . should . eventually . be . rejected . and . deep . include ( expected ) ;
294
+ } ) ;
295
+
296
+ it ( 'should reject when rejected with a FirebaseAppError' , ( ) => {
297
+ const expected = new FirebaseAppError ( 'network-error' , 'socket hang up' ) ;
298
+ const stub = sinon
299
+ . stub ( HttpClient . prototype , 'send' )
300
+ . rejects ( expected ) ;
301
+ stubs . push ( stub ) ;
302
+ return apiClient . verifyReplayProtection ( TEST_TOKEN_TO_EXCHANGE )
303
+ . should . eventually . be . rejected . and . deep . include ( expected ) ;
304
+ } ) ;
305
+
306
+ [ '' , 'abc' , '3s2' , 'sssa' , '3.000000001' , '3.2' , null , NaN , [ ] , { } , 100 , 1.2 , - 200 , - 2.4 ]
307
+ . forEach ( ( invalidAlreadyConsumed ) => {
308
+ it ( `should throw if the returned alreadyConsumed value is: ${ invalidAlreadyConsumed } ` , ( ) => {
309
+ const response = { alreadyConsumed : invalidAlreadyConsumed } ;
310
+ const stub = sinon
311
+ . stub ( HttpClient . prototype , 'send' )
312
+ . resolves ( utils . responseFrom ( response , 200 ) ) ;
313
+ stubs . push ( stub ) ;
314
+ const expected = new FirebaseAppCheckError (
315
+ 'invalid-argument' , '`alreadyConsumed` must be a boolean value.' ) ;
316
+ return apiClient . verifyReplayProtection ( TEST_TOKEN_TO_EXCHANGE )
317
+ . should . eventually . be . rejected . and . deep . include ( expected ) ;
318
+ } ) ;
319
+ } ) ;
320
+
321
+ it ( 'should resolve with the alreadyConsumed status on success' , ( ) => {
322
+ const stub = sinon
323
+ . stub ( HttpClient . prototype , 'send' )
324
+ . resolves ( utils . responseFrom ( { alreadyConsumed : true } , 200 ) ) ;
325
+ stubs . push ( stub ) ;
326
+ return apiClient . verifyReplayProtection ( TEST_TOKEN_TO_EXCHANGE )
327
+ . then ( ( alreadyConsumed ) => {
328
+ expect ( alreadyConsumed ) . to . equal ( true ) ;
329
+ expect ( stub ) . to . have . been . calledOnce . and . calledWith ( {
330
+ method : 'POST' ,
331
+ url : 'https://firebaseappcheck.googleapis.com/v1beta/projects/test-project:verifyAppCheckToken' ,
332
+ headers : EXPECTED_HEADERS ,
333
+ data : { app_check_token : TEST_TOKEN_TO_EXCHANGE }
334
+ } ) ;
335
+ } ) ;
336
+ } ) ;
337
+
338
+ [ true , false ] . forEach ( ( expectedAlreadyConsumed ) => {
339
+ it ( `should resolve with alreadyConsumed as ${ expectedAlreadyConsumed } when alreadyConsumed
340
+ from server is: ${ expectedAlreadyConsumed } ` , ( ) => {
341
+ const response = { alreadyConsumed : expectedAlreadyConsumed } ;
342
+ const stub = sinon
343
+ . stub ( HttpClient . prototype , 'send' )
344
+ . resolves ( utils . responseFrom ( response , 200 ) ) ;
345
+ stubs . push ( stub ) ;
346
+ return apiClient . verifyReplayProtection ( TEST_TOKEN_TO_EXCHANGE )
347
+ . then ( ( alreadyConsumed ) => {
348
+ expect ( alreadyConsumed ) . to . equal ( expectedAlreadyConsumed ) ;
349
+ } ) ;
350
+ } ) ;
351
+ } ) ;
352
+
353
+ it ( `should resolve with alreadyConsumed as false when alreadyConsumed
354
+ from server is: undefined` , ( ) => {
355
+ const response = { } ;
356
+ const stub = sinon
357
+ . stub ( HttpClient . prototype , 'send' )
358
+ . resolves ( utils . responseFrom ( response , 200 ) ) ;
359
+ stubs . push ( stub ) ;
360
+ return apiClient . verifyReplayProtection ( TEST_TOKEN_TO_EXCHANGE )
361
+ . then ( ( alreadyConsumed ) => {
362
+ expect ( alreadyConsumed ) . to . equal ( false ) ;
363
+ } ) ;
364
+ } ) ;
365
+ } ) ;
366
+
238
367
} ) ;
0 commit comments