@@ -490,6 +490,35 @@ describe('SecurityRulesApiClient', () => {
490
490
} ) ;
491
491
} ) ;
492
492
493
+ describe ( 'updateOrCreateRelease' , ( ) => {
494
+ it ( 'should propagate API errors' , ( ) => {
495
+ const EXPECTED_ERROR = new FirebaseSecurityRulesError ( 'internal-error' , 'message' ) ;
496
+ const stub = sinon
497
+ . stub ( SecurityRulesApiClient . prototype , 'updateRelease' )
498
+ . rejects ( EXPECTED_ERROR ) ;
499
+ stubs . push ( stub ) ;
500
+ return apiClient . updateOrCreateRelease ( RELEASE_NAME , RULESET_NAME )
501
+ . should . eventually . be . rejected . and . deep . include ( EXPECTED_ERROR ) ;
502
+ } ) ;
503
+
504
+ it ( 'should create a new ruleset when update fails with a not-found error' , ( ) => {
505
+ const NOT_FOUND_ERROR = new FirebaseSecurityRulesError ( 'not-found' , 'message' ) ;
506
+ const updateRelease = sinon
507
+ . stub ( SecurityRulesApiClient . prototype , 'updateRelease' )
508
+ . rejects ( NOT_FOUND_ERROR ) ;
509
+ const createRelease = sinon
510
+ . stub ( SecurityRulesApiClient . prototype , 'createRelease' )
511
+ . resolves ( ) ;
512
+ stubs . push ( updateRelease , createRelease ) ;
513
+
514
+ return apiClient . updateOrCreateRelease ( RELEASE_NAME , RULESET_NAME )
515
+ . then ( ( ) => {
516
+ expect ( updateRelease ) . to . have . been . calledOnce . and . calledWith ( RELEASE_NAME , RULESET_NAME ) ;
517
+ expect ( createRelease ) . to . have . been . called . calledOnce . and . calledWith ( RELEASE_NAME , RULESET_NAME ) ;
518
+ } ) ;
519
+ } ) ;
520
+ } ) ;
521
+
493
522
describe ( 'updateRelease' , ( ) => {
494
523
it ( 'should reject when project id is not available' , ( ) => {
495
524
return clientWithoutProjectId . updateRelease ( RELEASE_NAME , RULESET_NAME )
@@ -560,6 +589,74 @@ describe('SecurityRulesApiClient', () => {
560
589
} ) ;
561
590
} ) ;
562
591
592
+ describe ( 'createRelease' , ( ) => {
593
+ it ( 'should reject when project id is not available' , ( ) => {
594
+ return clientWithoutProjectId . createRelease ( RELEASE_NAME , RULESET_NAME )
595
+ . should . eventually . be . rejectedWith ( noProjectId ) ;
596
+ } ) ;
597
+
598
+ it ( 'should resolve with the created release on success' , ( ) => {
599
+ const stub = sinon
600
+ . stub ( HttpClient . prototype , 'send' )
601
+ . resolves ( utils . responseFrom ( { name : 'bar' } ) ) ;
602
+ stubs . push ( stub ) ;
603
+ return apiClient . createRelease ( RELEASE_NAME , RULESET_NAME )
604
+ . then ( ( resp ) => {
605
+ expect ( resp . name ) . to . equal ( 'bar' ) ;
606
+ expect ( stub ) . to . have . been . calledOnce . and . calledWith ( {
607
+ method : 'POST' ,
608
+ url : 'https://firebaserules.googleapis.com/v1/projects/test-project/releases' ,
609
+ data : {
610
+ name : 'projects/test-project/releases/test.service' ,
611
+ rulesetName : 'projects/test-project/rulesets/ruleset-id' ,
612
+ } ,
613
+ headers : EXPECTED_HEADERS ,
614
+ } ) ;
615
+ } ) ;
616
+ } ) ;
617
+
618
+ it ( 'should throw when a full platform error response is received' , ( ) => {
619
+ const stub = sinon
620
+ . stub ( HttpClient . prototype , 'send' )
621
+ . rejects ( utils . errorFrom ( ERROR_RESPONSE , 404 ) ) ;
622
+ stubs . push ( stub ) ;
623
+ const expected = new FirebaseSecurityRulesError ( 'not-found' , 'Requested entity not found' ) ;
624
+ return apiClient . createRelease ( RELEASE_NAME , RULESET_NAME )
625
+ . should . eventually . be . rejected . and . deep . include ( expected ) ;
626
+ } ) ;
627
+
628
+ it ( 'should throw unknown-error when error code is not present' , ( ) => {
629
+ const stub = sinon
630
+ . stub ( HttpClient . prototype , 'send' )
631
+ . rejects ( utils . errorFrom ( { } , 404 ) ) ;
632
+ stubs . push ( stub ) ;
633
+ const expected = new FirebaseSecurityRulesError ( 'unknown-error' , 'Unknown server error: {}' ) ;
634
+ return apiClient . createRelease ( RELEASE_NAME , RULESET_NAME )
635
+ . should . eventually . be . rejected . and . deep . include ( expected ) ;
636
+ } ) ;
637
+
638
+ it ( 'should throw unknown-error for non-json response' , ( ) => {
639
+ const stub = sinon
640
+ . stub ( HttpClient . prototype , 'send' )
641
+ . rejects ( utils . errorFrom ( 'not json' , 404 ) ) ;
642
+ stubs . push ( stub ) ;
643
+ const expected = new FirebaseSecurityRulesError (
644
+ 'unknown-error' , 'Unexpected response with status: 404 and body: not json' ) ;
645
+ return apiClient . createRelease ( RELEASE_NAME , RULESET_NAME )
646
+ . should . eventually . be . rejected . and . deep . include ( expected ) ;
647
+ } ) ;
648
+
649
+ it ( 'should throw when rejected with a FirebaseAppError' , ( ) => {
650
+ const expected = new FirebaseAppError ( 'network-error' , 'socket hang up' ) ;
651
+ const stub = sinon
652
+ . stub ( HttpClient . prototype , 'send' )
653
+ . rejects ( expected ) ;
654
+ stubs . push ( stub ) ;
655
+ return apiClient . createRelease ( RELEASE_NAME , RULESET_NAME )
656
+ . should . eventually . be . rejected . and . deep . include ( expected ) ;
657
+ } ) ;
658
+ } ) ;
659
+
563
660
describe ( 'deleteRuleset' , ( ) => {
564
661
const INVALID_NAMES : any [ ] = [ null , undefined , '' , 1 , true , { } , [ ] ] ;
565
662
INVALID_NAMES . forEach ( ( invalidName ) => {
0 commit comments