From 55d2d2d8be0b99f03da003f06cf4cd5c961c8637 Mon Sep 17 00:00:00 2001 From: Xiangtian Dai Date: Wed, 6 Sep 2017 09:24:28 -0700 Subject: Fixes Auth URL presenter: (#239) - kinda works on iOS 8-; - calls back with cancellation error correctly on 'Done' button; - cleans up upon completion. --- Example/Auth/Tests/FIRAuthURLPresenterTests.m | 163 ++++++++++---------------- 1 file changed, 61 insertions(+), 102 deletions(-) (limited to 'Example') diff --git a/Example/Auth/Tests/FIRAuthURLPresenterTests.m b/Example/Auth/Tests/FIRAuthURLPresenterTests.m index 602c54a..5d42e5f 100644 --- a/Example/Auth/Tests/FIRAuthURLPresenterTests.m +++ b/Example/Auth/Tests/FIRAuthURLPresenterTests.m @@ -15,12 +15,12 @@ */ #import +#import #import #import -#import "FIRAuthURLPresenter.h" #import "FIRAuthUIDelegate.h" -#import +#import "FIRAuthURLPresenter.h" /** @var kExpectationTimeout @brief The maximum time waiting for expectations to fulfill. @@ -45,28 +45,49 @@ static NSTimeInterval kExpectationTimeout = 1; @brief Tests @c FIRAuthURLPresenter class showing UI with a non-nil UIDelegate. */ - (void)testFIRAuthURLPresenterNonNilUIDelegate { - id mockUIDelegate = OCMProtocolMock(@protocol(FIRAuthUIDelegate)); + [self testFIRAuthURLPresenterUsingDefaultUIDelegate:NO]; +} + +/** @fn testFIRAuthURLPresenterNilUIDelegate + @brief Tests @c FIRAuthURLPresenter class showing UI with a nil UIDelegate. + */ +- (void)testFIRAuthURLPresenterNilUIDelegate { + [self testFIRAuthURLPresenterUsingDefaultUIDelegate:YES]; +} + +/** @fn testFIRAuthURLPresenterUsingDefaultUIDelegate: + @brief Tests @c FIRAuthURLPresenter class showing UIe. + @param usesDefaultUIDelegate Whether or not to test the default UI delegate. + */ +- (void)testFIRAuthURLPresenterUsingDefaultUIDelegate:(BOOL)usesDefaultUIDelegate { + id mockUIDelegate = OCMProtocolMock(@protocol(FIRAuthUIDelegate)); + id mockUIApplication = OCMPartialMock([UIApplication sharedApplication]); NSURL *presenterURL = [NSURL URLWithString:@"https://presenter.url"]; FIRAuthURLPresenter *presenter = [[FIRAuthURLPresenter alloc] init]; - if ([SFSafariViewController class]) { - XCTestExpectation *callbackMatcherExpectation = - [self expectationWithDescription:@"callbackMatcher callback"]; - FIRAuthURLCallbackMatcher callbackMatcher = ^BOOL(NSURL *_Nonnull callbackURL) { - XCTAssertEqualObjects(callbackURL, presenterURL); - [callbackMatcherExpectation fulfill]; - return YES; - }; - - XCTestExpectation *completionBlockExpectation = - [self expectationWithDescription:@"completion callback"]; - FIRAuthURLPresentationCompletion completionBlock = ^(NSURL *_Nullable callbackURL, - NSError *_Nullable error) { - XCTAssertEqualObjects(callbackURL, presenterURL); - XCTAssertNil(error); - [completionBlockExpectation fulfill]; - }; + if (usesDefaultUIDelegate) { + id mockDefaultUIDelegateClass = OCMClassMock([FIRAuthDefaultUIDelegate class]); + OCMStub(ClassMethod([mockDefaultUIDelegateClass defaultUIDelegate])).andReturn(mockUIDelegate); + } + + XCTestExpectation *callbackMatcherExpectation = + [self expectationWithDescription:@"callbackMatcher callback"]; + FIRAuthURLCallbackMatcher callbackMatcher = ^BOOL(NSURL *_Nonnull callbackURL) { + XCTAssertEqualObjects(callbackURL, presenterURL); + [callbackMatcherExpectation fulfill]; + return YES; + }; + + XCTestExpectation *completionBlockExpectation = + [self expectationWithDescription:@"completion callback"]; + FIRAuthURLPresentationCompletion completionBlock = ^(NSURL *_Nullable callbackURL, + NSError *_Nullable error) { + XCTAssertEqualObjects(callbackURL, presenterURL); + XCTAssertNil(error); + [completionBlockExpectation fulfill]; + }; + if ([SFSafariViewController class]) { id presenterArg = [OCMArg isKindOfClass:[SFSafariViewController class]]; OCMExpect([mockUIDelegate presentViewController:presenterArg animated:YES @@ -80,85 +101,29 @@ static NSTimeInterval kExpectationTimeout = 1; XCTAssertEqual(viewController.delegate, presenter); XCTAssertTrue([viewController isKindOfClass:[SFSafariViewController class]]); }); - [presenter presentURL:presenterURL - UIDelegate:mockUIDelegate - callbackMatcher:callbackMatcher - completion:completionBlock]; - OCMVerifyAll(mockUIDelegate); - OCMExpect([mockUIDelegate dismissViewControllerAnimated:OCMOCK_ANY - completion:OCMOCK_ANY]). - andDo(^(NSInvocation *invocation) { + } else { + id mockUIApplicationClass = OCMClassMock([UIApplication class]); + OCMStub(ClassMethod([mockUIApplicationClass sharedApplication])).andReturn(mockUIApplication); + OCMExpect([mockUIApplication openURL: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(); + // `openURL` is at index 2. + [invocation getArgument:&unretainedArgument atIndex:2]; + XCTAssertEqualObjects(presenterURL, unretainedArgument); }); - [presenter canHandleURL:presenterURL]; - [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; - OCMVerifyAll(mockUIDelegate); } -} - -/** @fn testFIRAuthURLPresenterNilUIDelegate - @brief Tests @c FIRAuthURLPresenter class showing UI with a nil UIDelegate. - */ -- (void)testFIRAuthURLPresenterNilUIDelegate { - NSURL *presenterURL = [NSURL URLWithString:@"https://presenter.url"]; - FIRAuthURLPresenter *presenter = [[FIRAuthURLPresenter alloc] init]; + // Present the content. + [presenter presentURL:presenterURL + UIDelegate:usesDefaultUIDelegate ? nil : mockUIDelegate + callbackMatcher:callbackMatcher + completion:completionBlock]; + OCMVerifyAll(mockUIDelegate); + OCMVerifyAll(mockUIApplication); if ([SFSafariViewController class]) { - XCTestExpectation *callbackMatcherExpectation = - [self expectationWithDescription:@"callbackMatcher callback"]; - FIRAuthURLCallbackMatcher callbackMatcher = ^BOOL(NSURL *_Nonnull callbackURL) { - XCTAssertEqualObjects(callbackURL, presenterURL); - [callbackMatcherExpectation fulfill]; - return YES; - }; - XCTestExpectation *completionBlockExpectation = - [self expectationWithDescription:@"completion callback"]; - FIRAuthURLPresentationCompletion completionBlock = ^(NSURL *_Nullable callbackURL, - NSError *_Nullable error) { - XCTAssertEqualObjects(callbackURL, presenterURL); - XCTAssertNil(error); - [completionBlockExpectation fulfill]; - }; - - id mockUIDelegate = OCMProtocolMock(@protocol(FIRAuthUIDelegate)); - - // Swizzle default UIDelegate - Method method = class_getClassMethod([FIRAuthDefaultUIDelegate class], - @selector(defaultUIDelegate)); - __block IMP originalImplementation; - IMP newImplmentation = imp_implementationWithBlock(^id(id object) { - return mockUIDelegate; - }); - originalImplementation = method_setImplementation(method, newImplmentation); - if ([SFSafariViewController class]) { - id presenterArg = [OCMArg isKindOfClass:[SFSafariViewController class]]; - OCMExpect([mockUIDelegate presentViewController:presenterArg - animated:[OCMArg any] - completion:[OCMArg any]]). - 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, presenter); - XCTAssertTrue([viewController isKindOfClass:[SFSafariViewController class]]); - }); - } - [presenter presentURL:presenterURL - UIDelegate:nil - callbackMatcher:callbackMatcher - completion:completionBlock]; - OCMVerifyAll(mockUIDelegate); - OCMExpect([mockUIDelegate dismissViewControllerAnimated:OCMOCK_ANY - completion:OCMOCK_ANY]). - andDo(^(NSInvocation *invocation) { + 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. @@ -166,18 +131,12 @@ static NSTimeInterval kExpectationTimeout = 1; void (^finishBlock)() = unretainedArgument; finishBlock(); }); - [presenter canHandleURL:presenterURL]; - [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; - OCMVerifyAll(mockUIDelegate); - // Unswizzle. - imp_removeBlock(method_setImplementation(method, originalImplementation)); } -} - -#pragma mark - Method Swizzling -+ (id)mockDefaultUIDelegate { - return OCMProtocolMock(@protocol(FIRAuthUIDelegate)); + // Close the presented content. + XCTAssertTrue([presenter canHandleURL:presenterURL]); + [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; + OCMVerifyAll(mockUIDelegate); } @end -- cgit v1.2.3