@@ -811,6 +811,182 @@ - (void)testDefaultToken_maxRetries {
811
811
XCTAssertEqual (newTokenFetchCount, [FIRInstanceID maxRetryCountForDefaultToken ]);
812
812
}
813
813
814
+ - (void )testInstanceIDWithHandler_WhileRequesting_Success {
815
+ [self stubKeyPairStoreToReturnValidKeypair ];
816
+ [self mockAuthServiceToAlwaysReturnValidCheckin ];
817
+
818
+ // Expect `fetchNewTokenWithAuthorizedEntity` to be called once
819
+ XCTestExpectation *fetchNewTokenExpectation =
820
+ [self expectationWithDescription: @" fetchNewTokenExpectation" ];
821
+ __block FIRInstanceIDTokenHandler tokenHandler;
822
+
823
+ [[[self .mockTokenManager stub ] andDo: ^(NSInvocation *invocation) {
824
+ [invocation getArgument: &tokenHandler atIndex: 6 ];
825
+ [fetchNewTokenExpectation fulfill ];
826
+ }] fetchNewTokenWithAuthorizedEntity: kAuthorizedEntity
827
+ scope: kFIRInstanceIDDefaultTokenScope
828
+ keyPair: [OCMArg any ]
829
+ options: [OCMArg any ]
830
+ handler: [OCMArg any ]];
831
+
832
+ // Make 1st call
833
+ XCTestExpectation *handlerExpectation1 = [self expectationWithDescription: @" handlerExpectation1" ];
834
+ FIRInstanceIDResultHandler handler1 =
835
+ ^(FIRInstanceIDResult *_Nullable result, NSError *_Nullable error) {
836
+ [handlerExpectation1 fulfill ];
837
+ XCTAssertNotNil (result);
838
+ XCTAssertEqual (result.token , kToken );
839
+ XCTAssertNil (error);
840
+ };
841
+
842
+ [self .mockInstanceID instanceIDWithHandler: handler1];
843
+
844
+ // Make 2nd call
845
+ XCTestExpectation *handlerExpectation2 = [self expectationWithDescription: @" handlerExpectation1" ];
846
+ FIRInstanceIDResultHandler handler2 =
847
+ ^(FIRInstanceIDResult *_Nullable result, NSError *_Nullable error) {
848
+ [handlerExpectation2 fulfill ];
849
+ XCTAssertNotNil (result);
850
+ XCTAssertEqual (result.token , kToken );
851
+ XCTAssertNil (error);
852
+ };
853
+
854
+ [self .mockInstanceID instanceIDWithHandler: handler2];
855
+
856
+ // Wait for `fetchNewTokenWithAuthorizedEntity` to be performed
857
+ [self waitForExpectations: @[ fetchNewTokenExpectation ] timeout: 1 enforceOrder: false ];
858
+ // Finish token fetch request
859
+ tokenHandler (kToken , nil );
860
+
861
+ // Wait for completion handlers for both calls to be performed
862
+ [self waitForExpectationsWithTimeout: 1 handler: NULL ];
863
+ }
864
+
865
+ - (void )testInstanceIDWithHandler_WhileRequesting_RetrySuccess {
866
+ [self stubKeyPairStoreToReturnValidKeypair ];
867
+ [self mockAuthServiceToAlwaysReturnValidCheckin ];
868
+
869
+ // Expect `fetchNewTokenWithAuthorizedEntity` to be called twice
870
+ XCTestExpectation *fetchNewTokenExpectation1 =
871
+ [self expectationWithDescription: @" fetchNewTokenExpectation1" ];
872
+ XCTestExpectation *fetchNewTokenExpectation2 =
873
+ [self expectationWithDescription: @" fetchNewTokenExpectation2" ];
874
+ NSArray *fetchNewTokenExpectations = @[ fetchNewTokenExpectation1, fetchNewTokenExpectation2 ];
875
+
876
+ __block NSInteger fetchNewTokenCallCount = 0 ;
877
+ __block FIRInstanceIDTokenHandler tokenHandler;
878
+
879
+ [[[self .mockTokenManager stub ] andDo: ^(NSInvocation *invocation) {
880
+ [invocation getArgument: &tokenHandler atIndex: 6 ];
881
+ [fetchNewTokenExpectations[fetchNewTokenCallCount] fulfill ];
882
+ fetchNewTokenCallCount += 1 ;
883
+ }] fetchNewTokenWithAuthorizedEntity: kAuthorizedEntity
884
+ scope: kFIRInstanceIDDefaultTokenScope
885
+ keyPair: [OCMArg any ]
886
+ options: [OCMArg any ]
887
+ handler: [OCMArg any ]];
888
+
889
+ // Mock Instance ID's retry interval to 0, to vastly speed up this test.
890
+ [[[self .mockInstanceID stub ] andReturnValue: @(0 )] retryIntervalToFetchDefaultToken ];
891
+
892
+ // Make 1st call
893
+ XCTestExpectation *handlerExpectation1 = [self expectationWithDescription: @" handlerExpectation1" ];
894
+ FIRInstanceIDResultHandler handler1 =
895
+ ^(FIRInstanceIDResult *_Nullable result, NSError *_Nullable error) {
896
+ [handlerExpectation1 fulfill ];
897
+ XCTAssertNotNil (result);
898
+ XCTAssertEqual (result.token , kToken );
899
+ XCTAssertNil (error);
900
+ };
901
+
902
+ [self .mockInstanceID instanceIDWithHandler: handler1];
903
+
904
+ // Make 2nd call
905
+ XCTestExpectation *handlerExpectation2 = [self expectationWithDescription: @" handlerExpectation1" ];
906
+ FIRInstanceIDResultHandler handler2 =
907
+ ^(FIRInstanceIDResult *_Nullable result, NSError *_Nullable error) {
908
+ [handlerExpectation2 fulfill ];
909
+ XCTAssertNotNil (result);
910
+ XCTAssertEqual (result.token , kToken );
911
+ XCTAssertNil (error);
912
+ };
913
+
914
+ [self .mockInstanceID instanceIDWithHandler: handler2];
915
+
916
+ // Wait for the 1st `fetchNewTokenWithAuthorizedEntity` to be performed
917
+ [self waitForExpectations: @[ fetchNewTokenExpectation1 ] timeout: 1 enforceOrder: false ];
918
+ // Fail for the 1st time
919
+ tokenHandler (nil , [NSError errorWithFIRInstanceIDErrorCode: kFIRInstanceIDErrorCodeUnknown ]);
920
+
921
+ // Wait for the 2nd token feth
922
+ [self waitForExpectations: @[ fetchNewTokenExpectation2 ] timeout: 1 enforceOrder: false ];
923
+ // Finish with success
924
+ tokenHandler (kToken , nil );
925
+
926
+ // Wait for completion handlers for both calls to be performed
927
+ [self waitForExpectationsWithTimeout: 1 handler: NULL ];
928
+ }
929
+
930
+ - (void )testInstanceIDWithHandler_WhileRequesting_RetryFailure {
931
+ [self stubKeyPairStoreToReturnValidKeypair ];
932
+ [self mockAuthServiceToAlwaysReturnValidCheckin ];
933
+
934
+ // Expect `fetchNewTokenWithAuthorizedEntity` to be called once
935
+ NSMutableArray <XCTestExpectation *> *fetchNewTokenExpectations = [NSMutableArray array ];
936
+ for (NSInteger i = 0 ; i < [[self .instanceID class ] maxRetryCountForDefaultToken ]; ++i) {
937
+ NSString *name = [NSString stringWithFormat: @" fetchNewTokenExpectation-%ld " , (long )i];
938
+ [fetchNewTokenExpectations addObject: [self expectationWithDescription: name]];
939
+ }
940
+
941
+ __block NSInteger fetchNewTokenCallCount = 0 ;
942
+ __block FIRInstanceIDTokenHandler tokenHandler;
943
+
944
+ [[[self .mockTokenManager stub ] andDo: ^(NSInvocation *invocation) {
945
+ [invocation getArgument: &tokenHandler atIndex: 6 ];
946
+ [fetchNewTokenExpectations[fetchNewTokenCallCount] fulfill ];
947
+ fetchNewTokenCallCount += 1 ;
948
+ }] fetchNewTokenWithAuthorizedEntity: kAuthorizedEntity
949
+ scope: kFIRInstanceIDDefaultTokenScope
950
+ keyPair: [OCMArg any ]
951
+ options: [OCMArg any ]
952
+ handler: [OCMArg any ]];
953
+
954
+ // Mock Instance ID's retry interval to 0, to vastly speed up this test.
955
+ [[[self .mockInstanceID stub ] andReturnValue: @(0 )] retryIntervalToFetchDefaultToken ];
956
+
957
+ // Make 1st call
958
+ XCTestExpectation *handlerExpectation1 = [self expectationWithDescription: @" handlerExpectation1" ];
959
+ FIRInstanceIDResultHandler handler1 =
960
+ ^(FIRInstanceIDResult *_Nullable result, NSError *_Nullable error) {
961
+ [handlerExpectation1 fulfill ];
962
+ XCTAssertNil (result);
963
+ XCTAssertNotNil (error);
964
+ };
965
+
966
+ [self .mockInstanceID instanceIDWithHandler: handler1];
967
+
968
+ // Make 2nd call
969
+ XCTestExpectation *handlerExpectation2 = [self expectationWithDescription: @" handlerExpectation1" ];
970
+ FIRInstanceIDResultHandler handler2 =
971
+ ^(FIRInstanceIDResult *_Nullable result, NSError *_Nullable error) {
972
+ [handlerExpectation2 fulfill ];
973
+ XCTAssertNil (result);
974
+ XCTAssertNotNil (error);
975
+ };
976
+
977
+ [self .mockInstanceID instanceIDWithHandler: handler2];
978
+
979
+ for (NSInteger i = 0 ; i < [[self .instanceID class ] maxRetryCountForDefaultToken ]; ++i) {
980
+ // Wait for the i `fetchNewTokenWithAuthorizedEntity` to be performed
981
+ [self waitForExpectations: @[ fetchNewTokenExpectations[i] ] timeout: 1 enforceOrder: false ];
982
+ // Fail for the i time
983
+ tokenHandler (nil , [NSError errorWithFIRInstanceIDErrorCode: kFIRInstanceIDErrorCodeUnknown ]);
984
+ }
985
+
986
+ // Wait for completion handlers for both calls to be performed
987
+ [self waitForExpectationsWithTimeout: 1 handler: NULL ];
988
+ }
989
+
814
990
/* *
815
991
* Tests a Keychain read failure while we try to fetch a new InstanceID token. If the Keychain
816
992
* read fails we won't be able to fetch the public key which is required while fetching a new
0 commit comments