FIRAppCheckIntegrationTests.m 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright 2020 Google LLC
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import <XCTest/XCTest.h>
  17. #import <OCMock/OCMock.h>
  18. #import <TargetConditionals.h>
  19. #import "FirebaseAppCheck/Sources/Core/TokenRefresh/FIRAppCheckTokenRefresher.h"
  20. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheck.h"
  21. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheckProviderFactory.h"
  22. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheckToken.h"
  23. #import "FirebaseAppCheck/Interop/FIRAppCheckInterop.h"
  24. #import "FirebaseAppCheck/Interop/FIRAppCheckTokenResultInterop.h"
  25. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRDeviceCheckProvider.h"
  26. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRDeviceCheckProviderFactory.h"
  27. #import "FirebaseCore/Extension/FirebaseCoreInternal.h"
  28. NS_ASSUME_NONNULL_BEGIN
  29. #if FIR_DEVICE_CHECK_SUPPORTED_TARGETS
  30. @interface DummyAppCheckProvider : NSObject <FIRAppCheckProvider>
  31. @end
  32. @implementation DummyAppCheckProvider
  33. - (void)getTokenWithCompletion:(void (^)(FIRAppCheckToken *_Nullable, NSError *_Nullable))handler {
  34. FIRAppCheckToken *token = [[FIRAppCheckToken alloc] initWithToken:@"Token"
  35. expirationDate:[NSDate distantFuture]];
  36. handler(token, nil);
  37. }
  38. @end
  39. @interface AppCheckProviderFactory : NSObject <FIRAppCheckProviderFactory>
  40. @end
  41. @implementation AppCheckProviderFactory
  42. - (nullable id<FIRAppCheckProvider>)createProviderWithApp:(nonnull FIRApp *)app {
  43. return [[DummyAppCheckProvider alloc] init];
  44. }
  45. @end
  46. @interface FIRAppCheckIntegrationTests : XCTestCase
  47. @property(nonatomic, nullable) id mockProviderFactory;
  48. @property(nonatomic, nullable) id mockAppCheckProvider;
  49. @property(nonatomic, nullable) id mockTokenRefresher;
  50. - (void)testDefaultAppCheckProvider FIR_DEVICE_CHECK_PROVIDER_AVAILABILITY;
  51. @end
  52. @implementation FIRAppCheckIntegrationTests
  53. - (void)setUp {
  54. [super setUp];
  55. // Disable token refresher to avoid any unexpected async tasks being scheduled.
  56. [self disableTokenRefresher];
  57. self.mockAppCheckProvider = OCMProtocolMock(@protocol(FIRAppCheckProvider));
  58. self.mockProviderFactory = OCMProtocolMock(@protocol(FIRAppCheckProviderFactory));
  59. }
  60. - (void)tearDown {
  61. [FIRApp resetApps];
  62. if (@available(iOS 11.0, macOS 10.15, macCatalyst 13.0, tvOS 11.0, watchOS 9.0, *)) {
  63. // Recover default provider factory.
  64. [FIRAppCheck setAppCheckProviderFactory:[[FIRDeviceCheckProviderFactory alloc] init]];
  65. }
  66. [self.mockTokenRefresher stopMocking];
  67. self.mockTokenRefresher = nil;
  68. [self.mockProviderFactory stopMocking];
  69. self.mockProviderFactory = nil;
  70. [self.mockAppCheckProvider stopMocking];
  71. self.mockAppCheckProvider = nil;
  72. [super tearDown];
  73. }
  74. - (void)testDefaultAppCheckProvider {
  75. NSString *appName = @"testDefaultAppCheckProvider";
  76. // 1. Expect FIRDeviceCheckProvider to be instantiated.
  77. id deviceCheckProviderMock = OCMClassMock([FIRDeviceCheckProvider class]);
  78. id appValidationArg = [OCMArg checkWithBlock:^BOOL(FIRApp *app) {
  79. XCTAssertEqualObjects(app.name, appName);
  80. return YES;
  81. }];
  82. OCMStub([deviceCheckProviderMock alloc]).andReturn(deviceCheckProviderMock);
  83. OCMExpect([deviceCheckProviderMock initWithApp:appValidationArg])
  84. .andReturn(deviceCheckProviderMock);
  85. // 2. Configure Firebase
  86. [self configureAppWithName:appName];
  87. FIRApp *app = [FIRApp appNamed:appName];
  88. XCTAssertNotNil(FIR_COMPONENT(FIRAppCheckInterop, app.container));
  89. // 3. Verify
  90. OCMVerifyAll(deviceCheckProviderMock);
  91. // 4. Cleanup
  92. // Recover default provider factory.
  93. [FIRAppCheck setAppCheckProviderFactory:[[FIRDeviceCheckProviderFactory alloc] init]];
  94. [deviceCheckProviderMock stopMocking];
  95. }
  96. // Tests that use the Keychain require a host app and Swift Package Manager
  97. // does not support adding a host app to test targets.
  98. #if !SWIFT_PACKAGE
  99. // Skip keychain tests on Catalyst and macOS. Tests are skipped because they
  100. // involve interactions with the keychain that require a provisioning profile.
  101. // See go/firebase-macos-keychain-popups for more details.
  102. #if !TARGET_OS_MACCATALYST && !TARGET_OS_OSX
  103. - (void)testSetAppCheckProviderFactoryWithDefaultApp {
  104. NSString *appName = kFIRDefaultAppName;
  105. // 1. Set App Check Provider Factory.
  106. [FIRAppCheck setAppCheckProviderFactory:self.mockProviderFactory];
  107. // 2. Expect factory to be used on [FIRApp configure].
  108. id appValidationArg = [OCMArg checkWithBlock:^BOOL(FIRApp *app) {
  109. XCTAssertEqual(app.name, appName);
  110. return YES;
  111. }];
  112. OCMExpect([self.mockProviderFactory createProviderWithApp:appValidationArg])
  113. .andReturn(self.mockAppCheckProvider);
  114. // 3. Configure FIRApp.
  115. [self configureAppWithName:appName];
  116. // 4. Expect App Check Provider to be called on getToken.
  117. FIRAppCheckToken *fakeToken = [[FIRAppCheckToken alloc] initWithToken:@"token"
  118. expirationDate:[NSDate distantFuture]];
  119. id completionBlockArg = [OCMArg invokeBlockWithArgs:fakeToken, [NSNull null], nil];
  120. OCMExpect([self.mockAppCheckProvider getTokenWithCompletion:completionBlockArg]);
  121. // 5. Call getToken and check the result.
  122. FIRApp *app = [FIRApp appNamed:appName];
  123. id<FIRAppCheckInterop> appCheck = FIR_COMPONENT(FIRAppCheckInterop, app.container);
  124. XCTestExpectation *completionExpectation =
  125. [self expectationWithDescription:@"completionExpectation"];
  126. [appCheck getTokenForcingRefresh:YES
  127. completion:^(id<FIRAppCheckTokenResultInterop> tokenResult) {
  128. [completionExpectation fulfill];
  129. XCTAssertNil(tokenResult.error);
  130. XCTAssertNotNil(tokenResult);
  131. XCTAssertEqualObjects(tokenResult.token, fakeToken.token);
  132. XCTAssertNil(tokenResult.error);
  133. }];
  134. [self waitForExpectations:@[ completionExpectation ] timeout:0.5];
  135. // 6. Verify mocks
  136. OCMVerifyAll(self.mockProviderFactory);
  137. OCMVerifyAll(self.mockAppCheckProvider);
  138. }
  139. #endif // !TARGET_OS_MACCATALYST && !TARGET_OS_OSX
  140. #endif // !SWIFT_PACKAGE
  141. #pragma mark - Helpers
  142. - (void)configureAppWithName:(NSString *)appName {
  143. FIROptions *options =
  144. [[FIROptions alloc] initWithGoogleAppID:@"1:100000000000:ios:aaaaaaaaaaaaaaaaaaaaaaaa"
  145. GCMSenderID:@"sender_id"];
  146. [FIRApp configureWithName:appName options:options];
  147. }
  148. - (void)usageExample {
  149. // Set a custom app check provider factory for the default FIRApp.
  150. [FIRAppCheck setAppCheckProviderFactory:[[AppCheckProviderFactory alloc] init]];
  151. [FIRApp configure];
  152. FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:@"path"];
  153. [FIRApp configureWithName:@"AppName" options:options];
  154. FIRApp *defaultApp = [FIRApp defaultApp];
  155. id<FIRAppCheckInterop> defaultAppCheck = FIR_COMPONENT(FIRAppCheckInterop, defaultApp.container);
  156. [defaultAppCheck getTokenForcingRefresh:NO
  157. completion:^(id<FIRAppCheckTokenResultInterop> tokenResult) {
  158. NSLog(@"Token: %@", tokenResult.token);
  159. if (tokenResult.error) {
  160. NSLog(@"Error: %@", tokenResult.error);
  161. }
  162. }];
  163. }
  164. - (void)disableTokenRefresher {
  165. self.mockTokenRefresher = OCMClassMock([FIRAppCheckTokenRefresher class]);
  166. OCMStub([self.mockTokenRefresher alloc]).andReturn(self.mockTokenRefresher);
  167. OCMStub([self.mockTokenRefresher initWithRefreshResult:[OCMArg any] settings:[OCMArg any]])
  168. .andReturn(self.mockTokenRefresher);
  169. }
  170. @end
  171. #endif // FIR_DEVICE_CHECK_SUPPORTED_TARGETS
  172. NS_ASSUME_NONNULL_END