@@ -41,6 +41,7 @@ import {
41
41
import { HttpClient } from '../../../src/utils/api-request' ;
42
42
import { Agent } from 'https' ;
43
43
import { FirebaseAppError } from '../../../src/utils/error' ;
44
+ import { deepCopy } from '../../../src/utils/deep-copy' ;
44
45
45
46
chai . should ( ) ;
46
47
chai . use ( sinonChai ) ;
@@ -420,6 +421,75 @@ describe('Credential', () => {
420
421
} ) ;
421
422
} ) ;
422
423
424
+ describe ( 'ImpersonatedServiceAccountCredential' , ( ) => {
425
+ it ( 'should throw if called with the path to an invalid file' , ( ) => {
426
+ const invalidPath = path . resolve ( __dirname , '../../resources/unparsable.key.json' ) ;
427
+ expect ( ( ) => new ImpersonatedServiceAccountCredential ( invalidPath ) )
428
+ . to . throw ( 'Failed to parse impersonated service account file' ) ;
429
+ } ) ;
430
+
431
+ it ( 'should throw given an object without a "clientId" property' , ( ) => {
432
+ const invalidCredential = deepCopy ( MOCK_IMPERSONATED_TOKEN_CONFIG ) ;
433
+ invalidCredential . source_credentials . client_id = '' ;
434
+ expect ( ( ) => new ImpersonatedServiceAccountCredential ( invalidCredential as any ) )
435
+ . to . throw ( 'Impersonated Service Account must contain a "source_credentials.client_id" property.' ) ;
436
+ } ) ;
437
+
438
+ it ( 'should throw given an object without a "clientSecret" property' , ( ) => {
439
+ const invalidCredential = deepCopy ( MOCK_IMPERSONATED_TOKEN_CONFIG ) ;
440
+ invalidCredential . source_credentials . client_secret = '' ;
441
+ expect ( ( ) => new ImpersonatedServiceAccountCredential ( invalidCredential as any ) )
442
+ . to . throw ( 'Impersonated Service Account must contain a "source_credentials.client_secret" property.' ) ;
443
+ } ) ;
444
+
445
+ it ( 'should throw given an object without a "refreshToken" property' , ( ) => {
446
+ const invalidCredential = deepCopy ( MOCK_IMPERSONATED_TOKEN_CONFIG ) ;
447
+ invalidCredential . source_credentials . refresh_token = '' ;
448
+ expect ( ( ) => new ImpersonatedServiceAccountCredential ( invalidCredential as any ) )
449
+ . to . throw ( 'Impersonated Service Account must contain a "source_credentials.refresh_token" property.' ) ;
450
+ } ) ;
451
+
452
+ it ( 'should throw given an object without a "type" property' , ( ) => {
453
+ const invalidCredential = deepCopy ( MOCK_IMPERSONATED_TOKEN_CONFIG ) ;
454
+ invalidCredential . source_credentials . type = '' ;
455
+ expect ( ( ) => new ImpersonatedServiceAccountCredential ( invalidCredential as any ) )
456
+ . to . throw ( 'Impersonated Service Account must contain a "source_credentials.type" property.' ) ;
457
+ } ) ;
458
+
459
+ it ( 'should return a Credential' , ( ) => {
460
+ const c = new ImpersonatedServiceAccountCredential ( MOCK_IMPERSONATED_TOKEN_CONFIG ) ;
461
+ expect ( c ) . to . deep . include ( {
462
+ implicit : false ,
463
+ } ) ;
464
+ } ) ;
465
+
466
+ it ( 'should return an implicit Credential' , ( ) => {
467
+ const c = new ImpersonatedServiceAccountCredential ( MOCK_IMPERSONATED_TOKEN_CONFIG , undefined , true ) ;
468
+ expect ( c ) . to . deep . include ( {
469
+ implicit : true ,
470
+ } ) ;
471
+ } ) ;
472
+
473
+ it ( 'should create access tokens' , ( ) => {
474
+ const scope = nock ( 'https://www.googleapis.com' )
475
+ . post ( '/oauth2/v4/token' )
476
+ . reply ( 200 , {
477
+ access_token : 'token' ,
478
+ token_type : 'Bearer' ,
479
+ expires_in : 60 * 60 ,
480
+ } , {
481
+ 'cache-control' : 'no-cache, no-store, max-age=0, must-revalidate' ,
482
+ } ) ;
483
+ mockedRequests . push ( scope ) ;
484
+
485
+ const c = new ImpersonatedServiceAccountCredential ( MOCK_IMPERSONATED_TOKEN_CONFIG ) ;
486
+ return c . getAccessToken ( ) . then ( ( token ) => {
487
+ expect ( token . access_token ) . to . be . a ( 'string' ) . and . to . not . be . empty ;
488
+ expect ( token . expires_in ) . to . greaterThan ( FIVE_MINUTES_IN_SECONDS ) ;
489
+ } ) ;
490
+ } ) ;
491
+ } ) ;
492
+
423
493
describe ( 'getApplicationDefault()' , ( ) => {
424
494
let fsStub : sinon . SinonStub ;
425
495
0 commit comments