|
162 | 162 | "0invalid%2520or%2520does%2520not%2520match%2520the%2520specified%2520API%2520key.%2522%257D%26"
|
163 | 163 | "authType%3DverifyApp";
|
164 | 164 |
|
| 165 | +/** @var kFakeRedirectURLStringUnstructuredError |
| 166 | + @brief The format for a fake redirect URL string with unstructured error response. |
| 167 | + */ |
| 168 | +static NSString *const kFakeRedirectURLStringUnstructuredError = @"com.googleusercontent.apps.1" |
| 169 | + "23456://firebaseauth/link?deep_link_id=https%3A%2F%2Fexample.firebaseapp.com%2F__%2Fauth%2Fcal" |
| 170 | + "lback%3FfirebaseError%3D%257B%2522unstructuredcode%2522%253A%2522auth%252Funknown-error-id%2522%252" |
| 171 | + "C%2522unstructuredmessage%2522%253A%2522The%2520OAuth%2520client%2520ID%2520provided%2520is%2520either%252" |
| 172 | + "0invalid%2520or%2520does%2520not%2520match%2520the%2520specified%2520API%2520key.%2522%257D%26" |
| 173 | + "authType%3DverifyApp"; |
| 174 | + |
165 | 175 | /** @var kTestTimeout
|
166 | 176 | @brief A fake timeout value for waiting for push notification.
|
167 | 177 | */
|
@@ -721,6 +731,69 @@ - (void)testVerifyPhoneNumberUIDelegateUnexpectedError {
|
721 | 731 | OCMVerifyAll(_mockNotificationManager);
|
722 | 732 | }
|
723 | 733 |
|
| 734 | +/** @fn testVerifyPhoneNumberUIDelegateUnstructuredError |
| 735 | + @brief Tests a invocation of @c verifyPhoneNumber:UIDelegate:completion: which results in an error being surfaced due to an unexpected structure of the error response. |
| 736 | + */ |
| 737 | +- (void)testVerifyPhoneNumberUIDelegateUnstructuredError { |
| 738 | + id mockBundle = OCMClassMock([NSBundle class]); |
| 739 | + OCMStub(ClassMethod([mockBundle mainBundle])).andReturn(mockBundle); |
| 740 | + OCMStub([mockBundle objectForInfoDictionaryKey:@"CFBundleURLTypes"]) |
| 741 | + .andReturn(@[ @{ @"CFBundleURLSchemes" : @[ kFakeReverseClientID ] } ]); |
| 742 | + OCMStub([mockBundle bundleIdentifier]).andReturn(kFakeBundleID); |
| 743 | + |
| 744 | + // Simulate missing app token error. |
| 745 | + OCMExpect([_mockNotificationManager checkNotificationForwardingWithCallback:OCMOCK_ANY]) |
| 746 | + .andCallBlock1(^(FIRAuthNotificationForwardingCallback callback) { callback(YES); }); |
| 747 | + OCMExpect([_mockAppCredentialManager credential]).andReturn(nil); |
| 748 | + OCMExpect([_mockAPNSTokenManager getTokenWithCallback:OCMOCK_ANY]) |
| 749 | + .andCallBlock1(^(FIRAuthAPNSTokenCallback callback) { |
| 750 | + NSError *error = [NSError errorWithDomain:FIRAuthErrorDomain |
| 751 | + code:FIRAuthErrorCodeMissingAppToken |
| 752 | + userInfo:nil]; |
| 753 | + callback(nil, error); |
| 754 | + }); |
| 755 | + OCMExpect([_mockBackend getProjectConfig:[OCMArg any] callback:[OCMArg any]]) |
| 756 | + .andCallBlock2(^(FIRGetProjectConfigRequest *request, |
| 757 | + FIRGetProjectConfigResponseCallback callback) { |
| 758 | + XCTAssertNotNil(request); |
| 759 | + dispatch_async(FIRAuthGlobalWorkQueue(), ^() { |
| 760 | + id mockGetProjectConfigResponse = OCMClassMock([FIRGetProjectConfigResponse class]); |
| 761 | + OCMStub([mockGetProjectConfigResponse authorizedDomains]). |
| 762 | + andReturn(@[ kFakeAuthorizedDomain]); |
| 763 | + callback(mockGetProjectConfigResponse, nil); |
| 764 | + }); |
| 765 | + }); |
| 766 | + id mockUIDelegate = OCMProtocolMock(@protocol(FIRAuthUIDelegate)); |
| 767 | + |
| 768 | + // Expect view controller presentation by UIDelegate. |
| 769 | + OCMExpect([_mockURLPresenter presentURL:OCMOCK_ANY |
| 770 | + UIDelegate:mockUIDelegate |
| 771 | + callbackMatcher:OCMOCK_ANY |
| 772 | + completion:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) { |
| 773 | + __unsafe_unretained id unretainedArgument; |
| 774 | + // Indices 0 and 1 indicate the hidden arguments self and _cmd. |
| 775 | + // `completion` is at index 5 |
| 776 | + [invocation getArgument:&unretainedArgument atIndex:5]; |
| 777 | + FIRAuthURLPresentationCompletion completion = unretainedArgument; |
| 778 | + dispatch_async(FIRAuthGlobalWorkQueue(), ^() { |
| 779 | + completion([NSURL URLWithString:kFakeRedirectURLStringUnstructuredError], nil); |
| 780 | + }); |
| 781 | + }); |
| 782 | + |
| 783 | + XCTestExpectation *expectation = [self expectationWithDescription:@"callback"]; |
| 784 | + [_provider verifyPhoneNumber:kTestPhoneNumber |
| 785 | + UIDelegate:mockUIDelegate |
| 786 | + completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) { |
| 787 | + XCTAssertTrue([NSThread isMainThread]); |
| 788 | + XCTAssertEqual(error.code, FIRAuthErrorCodeAppVerificationUserInteractionFailure); |
| 789 | + XCTAssertNil(verificationID); |
| 790 | + [expectation fulfill]; |
| 791 | + }]; |
| 792 | + [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; |
| 793 | + OCMVerifyAll(_mockBackend); |
| 794 | + OCMVerifyAll(_mockNotificationManager); |
| 795 | +} |
| 796 | + |
724 | 797 | /** @fn testVerifyPhoneNumberUIDelegateRaiseException
|
725 | 798 | @brief Tests a invocation of @c verifyPhoneNumber:UIDelegate:completion: which results in an
|
726 | 799 | exception.
|
|
0 commit comments