mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-09 22:36:01 +05:45
271 lines
11 KiB
Objective-C
271 lines
11 KiB
Objective-C
/*
|
|
* Copyright 2018 Google
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#import <OCMock/OCMock.h>
|
|
#import <XCTest/XCTest.h>
|
|
|
|
#import "FIRIAMActionURLFollower.h"
|
|
|
|
// since OCMock does support mocking respondsToSelector on mock object, we have to define
|
|
// different delegate classes with different coverages of certain delegate methods:
|
|
// FIRIAMActionURLFollower behavior depend on these method implementation coverages on the
|
|
// delegate
|
|
|
|
// this delegate only implements application:continueUserActivity:restorationHandler
|
|
@interface Delegate1 : NSObject <UIApplicationDelegate>
|
|
- (BOOL)application:(UIApplication *)application
|
|
continueUserActivity:(NSUserActivity *)userActivity
|
|
restorationHandler:(void (^)(NSArray *))restorationHandler;
|
|
@end
|
|
@implementation Delegate1
|
|
- (BOOL)application:(UIApplication *)application
|
|
continueUserActivity:(NSUserActivity *)userActivity
|
|
restorationHandler:(void (^)(NSArray *))restorationHandler {
|
|
return YES;
|
|
}
|
|
@end
|
|
|
|
// this delegate only implements application:openURL:options which is suitable for custom url scheme
|
|
// link handling
|
|
@interface Delegate2 : NSObject <UIApplicationDelegate>
|
|
- (BOOL)application:(UIApplication *)app
|
|
openURL:(NSURL *)url
|
|
options:(NSDictionary<NSString *, id> *)options;
|
|
@end
|
|
@implementation Delegate2
|
|
- (BOOL)application:(UIApplication *)app
|
|
openURL:(NSURL *)url
|
|
options:(NSDictionary<NSString *, id> *)options {
|
|
return YES;
|
|
}
|
|
@end
|
|
|
|
@interface FIRIAMActionURLFollowerTests : XCTestCase
|
|
@property FIRIAMActionURLFollower *actionFollower;
|
|
@property UIApplication *mockApplication;
|
|
@property id<UIApplicationDelegate> mockAppDelegate;
|
|
@end
|
|
|
|
@implementation FIRIAMActionURLFollowerTests
|
|
|
|
- (void)setUp {
|
|
[super setUp];
|
|
self.mockApplication = OCMClassMock([UIApplication class]);
|
|
}
|
|
|
|
- (void)tearDown {
|
|
// Put teardown code here. This method is called after the invocation of each test method in the
|
|
// class.
|
|
[super tearDown];
|
|
}
|
|
|
|
- (void)testUniversalLinkHandlingReturnYES {
|
|
self.mockAppDelegate = OCMClassMock([Delegate1 class]);
|
|
OCMStub([self.mockApplication delegate]).andReturn(self.mockAppDelegate);
|
|
|
|
// In this test case, app delegate's application:continueUserActivity:restorationHandler
|
|
// handles the url and returns YES
|
|
|
|
NSURL *url = [NSURL URLWithString:@"http://test.com"];
|
|
OCMExpect([self.mockAppDelegate application:[OCMArg isKindOfClass:[UIApplication class]]
|
|
continueUserActivity:[OCMArg checkWithBlock:^BOOL(id userActivity) {
|
|
// verifying the type and url field for the userActivity object
|
|
NSUserActivity *activity = (NSUserActivity *)userActivity;
|
|
return [activity.activityType
|
|
isEqualToString:NSUserActivityTypeBrowsingWeb] &&
|
|
[activity.webpageURL isEqual:url];
|
|
}]
|
|
restorationHandler:[OCMArg any]])
|
|
.andReturn(YES);
|
|
|
|
FIRIAMActionURLFollower *follower =
|
|
[[FIRIAMActionURLFollower alloc] initWithCustomURLSchemeArray:@[]
|
|
withApplication:self.mockApplication];
|
|
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Completion Callback Triggered"];
|
|
[follower followActionURL:url
|
|
withCompletionBlock:^(BOOL success) {
|
|
XCTAssertTrue(success);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithTimeout:5.0 handler:nil];
|
|
OCMVerifyAll((id)self.mockAppDelegate);
|
|
}
|
|
|
|
- (void)setupOpenURLViaIOSForUIApplicationWithReturnValue:(BOOL)returnValue {
|
|
// it would fallback to either openURL:options:completionHandler:
|
|
// or openURL: on the UIApplication object to follow the url
|
|
if ([self.mockApplication respondsToSelector:@selector(openURL:options:completionHandler:)]) {
|
|
// id types is needed for calling invokeBlockWithArgs
|
|
id yesOrNo = returnValue ? @YES : @NO;
|
|
OCMStub([self.mockApplication openURL:[OCMArg any]
|
|
options:[OCMArg any]
|
|
completionHandler:([OCMArg invokeBlockWithArgs:yesOrNo, nil])]);
|
|
} else {
|
|
OCMStub([self.mockApplication openURL:[OCMArg any]]).andReturn(returnValue);
|
|
}
|
|
}
|
|
|
|
- (void)testUniversalLinkHandlingReturnNo {
|
|
self.mockAppDelegate = OCMClassMock([Delegate1 class]);
|
|
OCMStub([self.mockApplication delegate]).andReturn(self.mockAppDelegate);
|
|
|
|
// In this test case, app delegate's application:continueUserActivity:restorationHandler
|
|
// tries to handle the url but returns NO. We should fallback to the do iOS OpenURL for
|
|
// this case
|
|
NSURL *url = [NSURL URLWithString:@"http://test.com"];
|
|
OCMExpect([self.mockAppDelegate application:[OCMArg isKindOfClass:[UIApplication class]]
|
|
continueUserActivity:[OCMArg any]
|
|
restorationHandler:[OCMArg any]])
|
|
.andReturn(NO);
|
|
|
|
[self setupOpenURLViaIOSForUIApplicationWithReturnValue:YES];
|
|
|
|
FIRIAMActionURLFollower *follower =
|
|
[[FIRIAMActionURLFollower alloc] initWithCustomURLSchemeArray:@[]
|
|
withApplication:self.mockApplication];
|
|
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Completion Callback Triggered"];
|
|
[follower followActionURL:url
|
|
withCompletionBlock:^(BOOL success) {
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithTimeout:5.0 handler:nil];
|
|
OCMVerifyAll((id)self.mockAppDelegate);
|
|
}
|
|
|
|
- (void)testCustomSchemeHandlingReturnYES {
|
|
self.mockAppDelegate = OCMClassMock([Delegate2 class]);
|
|
OCMStub([self.mockApplication delegate]).andReturn(self.mockAppDelegate);
|
|
|
|
// we support custom url scheme 'scheme1' and 'scheme2' in this setup
|
|
FIRIAMActionURLFollower *follower =
|
|
[[FIRIAMActionURLFollower alloc] initWithCustomURLSchemeArray:@[ @"scheme1", @"scheme2" ]
|
|
withApplication:self.mockApplication];
|
|
|
|
NSURL *customURL = [NSURL URLWithString:@"scheme1://test.com"];
|
|
OCMExpect([self.mockAppDelegate application:[OCMArg isKindOfClass:[UIApplication class]]
|
|
openURL:[OCMArg checkWithBlock:^BOOL(id urlId) {
|
|
// verifying url received by the app delegate is expected
|
|
NSURL *url = (NSURL *)urlId;
|
|
return [url isEqual:customURL];
|
|
}]
|
|
options:[OCMArg any]])
|
|
.andReturn(YES);
|
|
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Completion Callback Triggered"];
|
|
[follower followActionURL:customURL
|
|
withCompletionBlock:^(BOOL success) {
|
|
XCTAssertTrue(success);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithTimeout:5.0 handler:nil];
|
|
OCMVerifyAll((id)self.mockAppDelegate);
|
|
}
|
|
|
|
- (void)testCustomSchemeHandlingReturnNO {
|
|
self.mockAppDelegate = OCMClassMock([Delegate2 class]);
|
|
OCMStub([self.mockApplication delegate]).andReturn(self.mockAppDelegate);
|
|
|
|
// we support custom url scheme 'scheme1' and 'scheme2' in this setup
|
|
FIRIAMActionURLFollower *follower =
|
|
[[FIRIAMActionURLFollower alloc] initWithCustomURLSchemeArray:@[ @"scheme1", @"scheme2" ]
|
|
withApplication:self.mockApplication];
|
|
|
|
NSURL *customURL = [NSURL URLWithString:@"scheme1://test.com"];
|
|
OCMExpect([self.mockAppDelegate application:[OCMArg isKindOfClass:[UIApplication class]]
|
|
openURL:[OCMArg checkWithBlock:^BOOL(id urlId) {
|
|
// verifying url received by the app delegate is expected
|
|
NSURL *url = (NSURL *)urlId;
|
|
return [url isEqual:customURL];
|
|
}]
|
|
options:[OCMArg any]])
|
|
.andReturn(NO);
|
|
|
|
// it would fallback to Open URL with iOS System
|
|
[self setupOpenURLViaIOSForUIApplicationWithReturnValue:NO];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Completion Callback Triggered"];
|
|
[follower followActionURL:customURL
|
|
withCompletionBlock:^(BOOL success) {
|
|
// since both custom scheme url open and fallback iOS url open returns NO, we expect
|
|
// to get a NO here
|
|
XCTAssertFalse(success);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithTimeout:5.0 handler:nil];
|
|
OCMVerifyAll((id)self.mockAppDelegate);
|
|
}
|
|
|
|
- (void)testCustomSchemeNotMatching {
|
|
self.mockAppDelegate = OCMClassMock([Delegate2 class]);
|
|
OCMStub([self.mockApplication delegate]).andReturn(self.mockAppDelegate);
|
|
|
|
// we support custom url scheme 'scheme1' and 'scheme2' in this setup
|
|
FIRIAMActionURLFollower *follower =
|
|
[[FIRIAMActionURLFollower alloc] initWithCustomURLSchemeArray:@[ @"scheme1", @"scheme2" ]
|
|
withApplication:self.mockApplication];
|
|
|
|
NSURL *customURL = [NSURL URLWithString:@"unknown-scheme://test.com"];
|
|
|
|
// since custom scheme does not match, we should not expect app delegate's open URL method
|
|
// being triggered
|
|
OCMReject([self.mockAppDelegate application:[OCMArg any]
|
|
openURL:[OCMArg any]
|
|
options:[OCMArg any]]);
|
|
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Completion Callback Triggered"];
|
|
[self setupOpenURLViaIOSForUIApplicationWithReturnValue:YES];
|
|
|
|
[follower followActionURL:customURL
|
|
withCompletionBlock:^(BOOL success) {
|
|
XCTAssertTrue(success);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithTimeout:5.0 handler:nil];
|
|
OCMVerifyAll((id)self.mockAppDelegate);
|
|
}
|
|
|
|
- (void)testUniversalLinkWithoutContinueUserActivityDefined {
|
|
// Delegate2 does not define application:continueUserActivity:restorationHandler
|
|
self.mockAppDelegate = OCMClassMock([Delegate2 class]);
|
|
OCMStub([self.mockApplication delegate]).andReturn(self.mockAppDelegate);
|
|
|
|
FIRIAMActionURLFollower *follower =
|
|
[[FIRIAMActionURLFollower alloc] initWithCustomURLSchemeArray:@[]
|
|
withApplication:self.mockApplication];
|
|
|
|
// so for this url, even if it's a http or https link, we should fall back to openURL with
|
|
// iOS system
|
|
NSURL *url = [NSURL URLWithString:@"http://test.com"];
|
|
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Completion Callback Triggered"];
|
|
[self setupOpenURLViaIOSForUIApplicationWithReturnValue:YES];
|
|
|
|
[follower followActionURL:url
|
|
withCompletionBlock:^(BOOL success) {
|
|
XCTAssertTrue(success);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithTimeout:5.0 handler:nil];
|
|
}
|
|
@end
|