Files
firebase-ios-sdk/FirebaseAppCheck/Tests/Unit/Core/FIRAppCheckIntegrationTests.m
T

232 lines
8.1 KiB
Objective-C

/*
* Copyright 2020 Google LLC
*
* 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 <XCTest/XCTest.h>
#import <OCMock/OCMock.h>
#import <TargetConditionals.h>
#import "FirebaseAppCheck/Sources/Core/TokenRefresh/FIRAppCheckTokenRefresher.h"
#import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheck.h"
#import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheckProviderFactory.h"
#import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheckToken.h"
#import "FirebaseAppCheck/Interop/FIRAppCheckInterop.h"
#import "FirebaseAppCheck/Interop/FIRAppCheckTokenResultInterop.h"
#import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRDeviceCheckProvider.h"
#import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRDeviceCheckProviderFactory.h"
#import "FirebaseCore/Extension/FirebaseCoreInternal.h"
NS_ASSUME_NONNULL_BEGIN
#if FIR_DEVICE_CHECK_SUPPORTED_TARGETS
@interface DummyAppCheckProvider : NSObject <FIRAppCheckProvider>
@end
@implementation DummyAppCheckProvider
- (void)getTokenWithCompletion:(void (^)(FIRAppCheckToken *_Nullable, NSError *_Nullable))handler {
FIRAppCheckToken *token = [[FIRAppCheckToken alloc] initWithToken:@"Token"
expirationDate:[NSDate distantFuture]];
handler(token, nil);
}
@end
@interface AppCheckProviderFactory : NSObject <FIRAppCheckProviderFactory>
@end
@implementation AppCheckProviderFactory
- (nullable id<FIRAppCheckProvider>)createProviderWithApp:(nonnull FIRApp *)app {
return [[DummyAppCheckProvider alloc] init];
}
@end
@interface FIRAppCheckIntegrationTests : XCTestCase
@property(nonatomic, nullable) id mockProviderFactory;
@property(nonatomic, nullable) id mockAppCheckProvider;
@property(nonatomic, nullable) id mockTokenRefresher;
- (void)testDefaultAppCheckProvider FIR_DEVICE_CHECK_PROVIDER_AVAILABILITY;
@end
@implementation FIRAppCheckIntegrationTests
- (void)setUp {
[super setUp];
// Disable token refresher to avoid any unexpected async tasks being scheduled.
[self disableTokenRefresher];
self.mockAppCheckProvider = OCMProtocolMock(@protocol(FIRAppCheckProvider));
self.mockProviderFactory = OCMProtocolMock(@protocol(FIRAppCheckProviderFactory));
}
- (void)tearDown {
[FIRApp resetApps];
if (@available(iOS 11.0, macOS 10.15, macCatalyst 13.0, tvOS 11.0, watchOS 9.0, *)) {
// Recover default provider factory.
[FIRAppCheck setAppCheckProviderFactory:[[FIRDeviceCheckProviderFactory alloc] init]];
}
[self.mockTokenRefresher stopMocking];
self.mockTokenRefresher = nil;
[self.mockProviderFactory stopMocking];
self.mockProviderFactory = nil;
[self.mockAppCheckProvider stopMocking];
self.mockAppCheckProvider = nil;
[super tearDown];
}
- (void)testDefaultAppCheckProvider {
NSString *appName = @"testDefaultAppCheckProvider";
// 1. Expect FIRDeviceCheckProvider to be instantiated.
id deviceCheckProviderMock = OCMClassMock([FIRDeviceCheckProvider class]);
id appValidationArg = [OCMArg checkWithBlock:^BOOL(FIRApp *app) {
XCTAssertEqualObjects(app.name, appName);
return YES;
}];
OCMStub([deviceCheckProviderMock alloc]).andReturn(deviceCheckProviderMock);
OCMExpect([deviceCheckProviderMock initWithApp:appValidationArg])
.andReturn(deviceCheckProviderMock);
// 2. Configure Firebase
[self configureAppWithName:appName];
FIRApp *app = [FIRApp appNamed:appName];
XCTAssertNotNil(FIR_COMPONENT(FIRAppCheckInterop, app.container));
// 3. Verify
OCMVerifyAll(deviceCheckProviderMock);
// 4. Cleanup
// Recover default provider factory.
[FIRAppCheck setAppCheckProviderFactory:[[FIRDeviceCheckProviderFactory alloc] init]];
[deviceCheckProviderMock stopMocking];
}
// Tests that use the Keychain require a host app and Swift Package Manager
// does not support adding a host app to test targets.
#if !SWIFT_PACKAGE
// Skip keychain tests on Catalyst and macOS. Tests are skipped because they
// involve interactions with the keychain that require a provisioning profile.
// See go/firebase-macos-keychain-popups for more details.
#if !TARGET_OS_MACCATALYST && !TARGET_OS_OSX
- (void)testSetAppCheckProviderFactoryWithDefaultApp {
NSString *appName = kFIRDefaultAppName;
// 1. Set App Check Provider Factory.
[FIRAppCheck setAppCheckProviderFactory:self.mockProviderFactory];
// 2. Expect factory to be used on [FIRApp configure].
id appValidationArg = [OCMArg checkWithBlock:^BOOL(FIRApp *app) {
XCTAssertEqual(app.name, appName);
return YES;
}];
OCMExpect([self.mockProviderFactory createProviderWithApp:appValidationArg])
.andReturn(self.mockAppCheckProvider);
// 3. Configure FIRApp.
[self configureAppWithName:appName];
// 4. Expect App Check Provider to be called on getToken.
FIRAppCheckToken *fakeToken = [[FIRAppCheckToken alloc] initWithToken:@"token"
expirationDate:[NSDate distantFuture]];
id completionBlockArg = [OCMArg invokeBlockWithArgs:fakeToken, [NSNull null], nil];
OCMExpect([self.mockAppCheckProvider getTokenWithCompletion:completionBlockArg]);
// 5. Call getToken and check the result.
FIRApp *app = [FIRApp appNamed:appName];
id<FIRAppCheckInterop> appCheck = FIR_COMPONENT(FIRAppCheckInterop, app.container);
XCTestExpectation *completionExpectation =
[self expectationWithDescription:@"completionExpectation"];
[appCheck getTokenForcingRefresh:YES
completion:^(id<FIRAppCheckTokenResultInterop> tokenResult) {
[completionExpectation fulfill];
XCTAssertNil(tokenResult.error);
XCTAssertNotNil(tokenResult);
XCTAssertEqualObjects(tokenResult.token, fakeToken.token);
XCTAssertNil(tokenResult.error);
}];
[self waitForExpectations:@[ completionExpectation ] timeout:0.5];
// 6. Verify mocks
OCMVerifyAll(self.mockProviderFactory);
OCMVerifyAll(self.mockAppCheckProvider);
}
#endif // !TARGET_OS_MACCATALYST && !TARGET_OS_OSX
#endif // !SWIFT_PACKAGE
#pragma mark - Helpers
- (void)configureAppWithName:(NSString *)appName {
FIROptions *options =
[[FIROptions alloc] initWithGoogleAppID:@"1:100000000000:ios:aaaaaaaaaaaaaaaaaaaaaaaa"
GCMSenderID:@"sender_id"];
[FIRApp configureWithName:appName options:options];
}
- (void)usageExample {
// Set a custom app check provider factory for the default FIRApp.
[FIRAppCheck setAppCheckProviderFactory:[[AppCheckProviderFactory alloc] init]];
[FIRApp configure];
FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:@"path"];
[FIRApp configureWithName:@"AppName" options:options];
FIRApp *defaultApp = [FIRApp defaultApp];
id<FIRAppCheckInterop> defaultAppCheck = FIR_COMPONENT(FIRAppCheckInterop, defaultApp.container);
[defaultAppCheck getTokenForcingRefresh:NO
completion:^(id<FIRAppCheckTokenResultInterop> tokenResult) {
NSLog(@"Token: %@", tokenResult.token);
if (tokenResult.error) {
NSLog(@"Error: %@", tokenResult.error);
}
}];
}
- (void)disableTokenRefresher {
self.mockTokenRefresher = OCMClassMock([FIRAppCheckTokenRefresher class]);
OCMStub([self.mockTokenRefresher alloc]).andReturn(self.mockTokenRefresher);
OCMStub([self.mockTokenRefresher initWithRefreshResult:[OCMArg any] settings:[OCMArg any]])
.andReturn(self.mockTokenRefresher);
}
@end
#endif // FIR_DEVICE_CHECK_SUPPORTED_TARGETS
NS_ASSUME_NONNULL_END