diff options
author | Zsika Phillip <protocol86@users.noreply.github.com> | 2017-09-04 17:37:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-04 17:37:46 -0700 |
commit | 85e81371801f9cd3e94a1505ce3b2f4f66086b08 (patch) | |
tree | 220fdf17ff9aed20e865bf019dd7dad805458fab /Example | |
parent | 540e21c0cc3206a8e911554227cc1f081ef40dda (diff) |
Adds app verification alternative (#228)
* Adds app verification alternative
Diffstat (limited to 'Example')
-rw-r--r-- | Example/Auth/Tests/FIRApp+FIRAuthUnitTests.m | 3 | ||||
-rw-r--r-- | Example/Auth/Tests/FIRPhoneAuthProviderTests.m | 110 |
2 files changed, 111 insertions, 2 deletions
diff --git a/Example/Auth/Tests/FIRApp+FIRAuthUnitTests.m b/Example/Auth/Tests/FIRApp+FIRAuthUnitTests.m index 7159452..b6d34bb 100644 --- a/Example/Auth/Tests/FIRApp+FIRAuthUnitTests.m +++ b/Example/Auth/Tests/FIRApp+FIRAuthUnitTests.m @@ -28,7 +28,8 @@ return [[FIROptions alloc] initInternalWithOptionsDictionary:@{ @"GOOGLE_APP_ID" : @"1:1085102361755:ios:f790a919483d5bdf", @"API_KEY" : @"FAKE_API_KEY", - @"GCM_SENDER_ID": @"217397612173" + @"GCM_SENDER_ID": @"217397612173", + @"CLIENT_ID" : @"123456.apps.googleusercontent.com", }]; } diff --git a/Example/Auth/Tests/FIRPhoneAuthProviderTests.m b/Example/Auth/Tests/FIRPhoneAuthProviderTests.m index 9a0a219..5b29b02 100644 --- a/Example/Auth/Tests/FIRPhoneAuthProviderTests.m +++ b/Example/Auth/Tests/FIRPhoneAuthProviderTests.m @@ -20,6 +20,8 @@ #import "FIRPhoneAuthProvider.h" #import "Phone/FIRPhoneAuthCredential_Internal.h" #import "Phone/NSString+FIRAuth.h" +#import "FIRApp.h" +#import "FIRApp+FIRAuthUnitTests.h" #import "FIRAuthAPNSToken.h" #import "FIRAuthAPNSTokenManager.h" #import "FIRAuthAppCredential.h" @@ -30,14 +32,20 @@ #import "FIRAuthErrorUtils.h" #import "FIRAuthGlobalWorkQueue.h" #import "FIRAuthBackend.h" +#import "FIRAuthURLPresenter.h" +#import "FIRGetProjectConfigRequest.h" +#import "FIRGetProjectConfigResponse.h" #import "FIRSendVerificationCodeRequest.h" #import "FIRSendVerificationCodeResponse.h" +#import "FIRAuthUIDelegate.h" #import "FIRVerifyClientRequest.h" #import "FIRVerifyClientResponse.h" #import "FIRApp+FIRAuthUnitTests.h" #import "OCMStubRecorder+FIRAuthUnitTests.h" #import <OCMock/OCMock.h> +@import SafariServices; + NS_ASSUME_NONNULL_BEGIN /** @var kTestPhoneNumber @@ -75,12 +83,23 @@ static NSString *const kTestOldReceipt = @"old_receipt"; */ static NSString *const kTestOldSecret = @"old_secret"; - /** @var kTestVerificationCode @brief A fake verfication code. */ static NSString *const kTestVerificationCode = @"verificationCode"; +/** @var kFakeReCAPTCHAToken + @brief A fake reCAPTCHA token. + */ +static NSString *const kFakeReCAPTCHAToken = @"fakeReCAPTCHAToken"; + +/** @var kFakeRedirectURLStringFormat + @brief The format for a fake redirect URL string. + */ +static NSString *const kFakeRedirectURLStringWithoutReCAPTCHAToken = @"com.googleusercontent.apps.1" + "23456://firebaseauth/link?deep_link_id=https%3A%2F%2Fexample.firebaseapp.com%2F__%2Fauth%2Fcal" + "lback%3FauthType%3DverifyApp%26recaptchaToken%3D"; + /** @var kTestTimeout @brief A fake timeout value for waiting for push notification. */ @@ -141,6 +160,7 @@ static const NSTimeInterval kExpectationTimeout = 1; _mockNotificationManager = OCMClassMock([FIRAuthNotificationManager class]); OCMStub([_mockAuth notificationManager]).andReturn(_mockNotificationManager); _provider = [FIRPhoneAuthProvider providerWithAuth:_mockAuth]; + OCMStub([_mockAuth authURLPresenter]).andReturn([FIRAuthURLPresenter new]); } - (void)tearDown { @@ -248,6 +268,94 @@ static const NSTimeInterval kExpectationTimeout = 1; OCMVerifyAll(_mockAppCredentialManager); } +/** @fn testVerifyPhoneNumberUIDelegate + @brief Tests a successful invocation of @c verifyPhoneNumber:UIDelegate:completion:. + */ +- (void)testVerifyPhoneNumberUIDelegate { + if ([SFSafariViewController class]) { + FIRApp *app = [FIRApp appForAuthUnitTestsWithName:@"testApp"]; + OCMStub([_mockAuth app]).andReturn(app); + // Simulate missing app token error. + OCMExpect([_mockNotificationManager checkNotificationForwardingWithCallback:OCMOCK_ANY]) + .andCallBlock1(^(FIRAuthNotificationForwardingCallback callback) { callback(YES); }); + OCMExpect([_mockAppCredentialManager credential]).andReturn(nil); + OCMExpect([_mockAPNSTokenManager getTokenWithCallback:OCMOCK_ANY]) + .andCallBlock1(^(FIRAuthAPNSTokenCallback callback) { + NSError *error = [NSError errorWithDomain:FIRAuthErrorDomain + code:FIRAuthErrorCodeMissingAppToken + userInfo:nil]; + callback(nil, error); + }); + OCMExpect([_mockBackend getProjectConfig:[OCMArg any] callback:[OCMArg any]]) + .andCallBlock2(^(FIRGetProjectConfigRequest *request, + FIRGetProjectConfigResponseCallback callback) { + XCTAssertNotNil(request); + dispatch_async(FIRAuthGlobalWorkQueue(), ^() { + id mockGetProjectConfigResponse = OCMClassMock([FIRGetProjectConfigResponse class]); + OCMStub([mockGetProjectConfigResponse authorizedDomains]). + andReturn(@[ @"test.firebaseapp.com"]); + callback(mockGetProjectConfigResponse, nil); + }); + }); + // Mock UIDelegate. + id mockUIDelegate = OCMProtocolMock(@protocol(FIRAuthUIDelegate)); + // Expect view controller presentation by UIDelegate. + id presenterArg = [OCMArg isKindOfClass:[SFSafariViewController class]]; + OCMExpect([mockUIDelegate presentViewController:presenterArg + animated:YES + completion:nil]).andDo(^(NSInvocation *invocation) { + __unsafe_unretained id unretainedArgument; + // Indices 0 and 1 indicate the hidden arguments self and _cmd. + // `presentViewController` is at index 2. + [invocation getArgument:&unretainedArgument atIndex:2]; + SFSafariViewController *viewController = unretainedArgument; + XCTAssertEqual(viewController.delegate, [_mockAuth authURLPresenter]); + XCTAssertTrue([viewController isKindOfClass:[SFSafariViewController class]]); + NSMutableString *fakeRedirectURLString = + [NSMutableString stringWithString:kFakeRedirectURLStringWithoutReCAPTCHAToken]; + [fakeRedirectURLString appendString:kFakeReCAPTCHAToken]; + [[_mockAuth authURLPresenter] canHandleURL:[NSURL URLWithString:fakeRedirectURLString]]; + }); + // Expect view controller dismissal by UIDelegate. + OCMExpect([mockUIDelegate dismissViewControllerAnimated:OCMOCK_ANY completion:OCMOCK_ANY]). + andDo(^(NSInvocation *invocation) { + __unsafe_unretained id unretainedArgument; + // Indices 0 and 1 indicate the hidden arguments self and _cmd. + // `completion` is at index 3. + [invocation getArgument:&unretainedArgument atIndex:3]; + void (^finishBlock)() = unretainedArgument; + finishBlock(); + }); + + OCMExpect([_mockBackend sendVerificationCode:[OCMArg any] callback:[OCMArg any]]) + .andCallBlock2(^(FIRSendVerificationCodeRequest *request, + FIRSendVerificationCodeResponseCallback callback) { + XCTAssertEqualObjects(request.phoneNumber, kTestPhoneNumber); + XCTAssertNil(request.appCredential); + XCTAssertEqualObjects(request.reCAPTCHAToken, kFakeReCAPTCHAToken); + dispatch_async(FIRAuthGlobalWorkQueue(), ^() { + id mockSendVerificationCodeResponse = OCMClassMock([FIRSendVerificationCodeResponse class]); + OCMStub([mockSendVerificationCodeResponse verificationID]).andReturn(kTestVerificationID); + callback(mockSendVerificationCodeResponse, nil); + }); + }); + + XCTestExpectation *expectation = [self expectationWithDescription:@"callback"]; + [_provider verifyPhoneNumber:kTestPhoneNumber + UIDelegate:mockUIDelegate + completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) { + XCTAssertTrue([NSThread isMainThread]); + XCTAssertNil(error); + XCTAssertEqualObjects(verificationID, kTestVerificationID); + XCTAssertEqualObjects(verificationID.fir_authPhoneNumber, kTestPhoneNumber); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; + OCMVerifyAll(_mockBackend); + OCMVerifyAll(_mockNotificationManager); + } +} + /** @fn testNotForwardingNotification @brief Tests returning an error for the app failing to forward notification. */ |