FIRAppCheckTests.m 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  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 "FBLPromise+Testing.h"
  19. #import <FirebaseAppCheck/FirebaseAppCheck.h>
  20. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheck.h"
  21. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheckProvider.h"
  22. #import "FirebaseAppCheck/Sources/Interop/FIRAppCheckInterop.h"
  23. #import "FirebaseAppCheck/Sources/Interop/FIRAppCheckTokenResultInterop.h"
  24. #import "FirebaseAppCheck/Sources/Core/FIRAppCheckSettings.h"
  25. #import "FirebaseAppCheck/Sources/Core/FIRAppCheckTokenResult.h"
  26. #import "FirebaseAppCheck/Sources/Core/Storage/FIRAppCheckStorage.h"
  27. #import "FirebaseAppCheck/Sources/Core/TokenRefresh/FIRAppCheckTokenRefresher.h"
  28. #import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
  29. @interface FIRAppCheck (Tests) <FIRAppCheckInterop>
  30. - (instancetype)initWithAppName:(NSString *)appName
  31. appCheckProvider:(id<FIRAppCheckProvider>)appCheckProvider
  32. storage:(id<FIRAppCheckStorageProtocol>)storage
  33. tokenRefresher:(id<FIRAppCheckTokenRefresherProtocol>)tokenRefresher
  34. notificationCenter:(NSNotificationCenter *)notificationCenter
  35. settings:(id<FIRAppCheckSettingsProtocol>)settings;
  36. - (nullable instancetype)initWithApp:(FIRApp *)app;
  37. @end
  38. @interface FIRAppCheckTests : XCTestCase
  39. @property(nonatomic) NSString *appName;
  40. @property(nonatomic) OCMockObject<FIRAppCheckStorageProtocol> *mockStorage;
  41. @property(nonatomic) OCMockObject<FIRAppCheckProvider> *mockAppCheckProvider;
  42. @property(nonatomic) OCMockObject<FIRAppCheckTokenRefresherProtocol> *mockTokenRefresher;
  43. @property(nonatomic) OCMockObject<FIRAppCheckSettingsProtocol> *mockSettings;
  44. @property(nonatomic) NSNotificationCenter *notificationCenter;
  45. @property(nonatomic) FIRAppCheck<FIRAppCheckInterop> *appCheck;
  46. @property(nonatomic, copy, nullable) FIRAppCheckTokenRefreshBlock tokenRefreshHandler;
  47. @end
  48. @implementation FIRAppCheckTests
  49. - (void)setUp {
  50. [super setUp];
  51. self.appName = @"FIRAppCheckTests";
  52. self.mockStorage = OCMProtocolMock(@protocol(FIRAppCheckStorageProtocol));
  53. self.mockAppCheckProvider = OCMProtocolMock(@protocol(FIRAppCheckProvider));
  54. self.mockTokenRefresher = OCMProtocolMock(@protocol(FIRAppCheckTokenRefresherProtocol));
  55. self.mockSettings = OCMProtocolMock(@protocol(FIRAppCheckSettingsProtocol));
  56. self.notificationCenter = [[NSNotificationCenter alloc] init];
  57. [self stubSetTokenRefreshHandler];
  58. self.appCheck = [[FIRAppCheck alloc] initWithAppName:self.appName
  59. appCheckProvider:self.mockAppCheckProvider
  60. storage:self.mockStorage
  61. tokenRefresher:self.mockTokenRefresher
  62. notificationCenter:self.notificationCenter
  63. settings:self.mockSettings];
  64. }
  65. - (void)tearDown {
  66. self.appCheck = nil;
  67. [self.mockAppCheckProvider stopMocking];
  68. self.mockAppCheckProvider = nil;
  69. [self.mockStorage stopMocking];
  70. self.mockStorage = nil;
  71. [self.mockTokenRefresher stopMocking];
  72. self.mockTokenRefresher = nil;
  73. [super tearDown];
  74. }
  75. - (void)testInitWithApp {
  76. NSString *googleAppID = @"testInitWithApp_googleAppID";
  77. NSString *appName = @"testInitWithApp_appName";
  78. NSString *appGroupID = @"testInitWithApp_appGroupID";
  79. // 1. Stub FIRApp and validate usage.
  80. id mockApp = OCMStrictClassMock([FIRApp class]);
  81. id mockAppOptions = OCMStrictClassMock([FIROptions class]);
  82. OCMStub([mockApp name]).andReturn(appName);
  83. OCMStub([(FIRApp *)mockApp options]).andReturn(mockAppOptions);
  84. OCMExpect([mockAppOptions googleAppID]).andReturn(googleAppID);
  85. OCMExpect([mockAppOptions appGroupID]).andReturn(appGroupID);
  86. // 2. Stub FIRAppCheckTokenRefresher and validate usage.
  87. id mockTokenRefresher = OCMClassMock([FIRAppCheckTokenRefresher class]);
  88. OCMExpect([mockTokenRefresher alloc]).andReturn(mockTokenRefresher);
  89. id refresherDateValidator = [OCMArg checkWithBlock:^BOOL(NSDate *tokenExpirationDate) {
  90. NSTimeInterval accuracy = 1;
  91. XCTAssertLessThanOrEqual(ABS([tokenExpirationDate timeIntervalSinceNow]), accuracy);
  92. return YES;
  93. }];
  94. id settingsValidator = [OCMArg checkWithBlock:^BOOL(id obj) {
  95. XCTAssert([obj isKindOfClass:[FIRAppCheckSettings class]]);
  96. return YES;
  97. }];
  98. OCMExpect([mockTokenRefresher initWithTokenExpirationDate:refresherDateValidator
  99. tokenExpirationThreshold:5 * 60
  100. settings:settingsValidator])
  101. .andReturn(mockTokenRefresher);
  102. OCMExpect([mockTokenRefresher setTokenRefreshHandler:[OCMArg any]]);
  103. // 3. Stub FIRAppCheckStorage and validate usage.
  104. id mockStorage = OCMClassMock([FIRAppCheckStorage class]);
  105. OCMExpect([mockStorage alloc]).andReturn(mockStorage);
  106. OCMExpect([mockStorage initWithAppName:appName appID:googleAppID accessGroup:appGroupID])
  107. .andReturn(mockStorage);
  108. // 4. Stub attestation provider.
  109. OCMockObject<FIRAppCheckProviderFactory> *mockProviderFactory =
  110. OCMProtocolMock(@protocol(FIRAppCheckProviderFactory));
  111. OCMockObject<FIRAppCheckProvider> *mockProvider = OCMProtocolMock(@protocol(FIRAppCheckProvider));
  112. OCMExpect([mockProviderFactory createProviderWithApp:mockApp]).andReturn(mockProvider);
  113. [FIRAppCheck setAppCheckProviderFactory:mockProviderFactory];
  114. // 5. Call init.
  115. FIRAppCheck *appCheck = [[FIRAppCheck alloc] initWithApp:mockApp];
  116. XCTAssert([appCheck isKindOfClass:[FIRAppCheck class]]);
  117. // 6. Verify mocks.
  118. OCMVerifyAll(mockApp);
  119. OCMVerifyAll(mockAppOptions);
  120. OCMVerifyAll(mockTokenRefresher);
  121. OCMVerifyAll(mockStorage);
  122. OCMVerifyAll(mockProviderFactory);
  123. OCMVerifyAll(mockProvider);
  124. // 7. Stop mocking real class mocks.
  125. [mockApp stopMocking];
  126. mockApp = nil;
  127. [mockAppOptions stopMocking];
  128. mockAppOptions = nil;
  129. [mockTokenRefresher stopMocking];
  130. mockTokenRefresher = nil;
  131. [mockStorage stopMocking];
  132. mockStorage = nil;
  133. }
  134. - (void)testAppCheckDefaultInstance {
  135. // Should throw an exception when the default app is not configured.
  136. XCTAssertThrows([FIRAppCheck appCheck]);
  137. // Configure default FIRApp.
  138. FIROptions *options =
  139. [[FIROptions alloc] initWithGoogleAppID:@"1:100000000000:ios:aaaaaaaaaaaaaaaaaaaaaaaa"
  140. GCMSenderID:@"sender_id"];
  141. options.APIKey = @"api_key";
  142. options.projectID = @"project_id";
  143. [FIRApp configureWithOptions:options];
  144. // Check.
  145. XCTAssertNotNil([FIRAppCheck appCheck]);
  146. [FIRApp resetApps];
  147. }
  148. - (void)testAppCheckInstanceForApp {
  149. FIROptions *options =
  150. [[FIROptions alloc] initWithGoogleAppID:@"1:100000000000:ios:aaaaaaaaaaaaaaaaaaaaaaaa"
  151. GCMSenderID:@"sender_id"];
  152. options.APIKey = @"api_key";
  153. options.projectID = @"project_id";
  154. [FIRApp configureWithName:@"testAppCheckInstanceForApp" options:options];
  155. FIRApp *app = [FIRApp appNamed:@"testAppCheckInstanceForApp"];
  156. XCTAssertNotNil(app);
  157. XCTAssertNotNil([FIRAppCheck appCheckWithApp:app]);
  158. [FIRApp resetApps];
  159. }
  160. - (void)testGetToken_WhenNoCache_Success {
  161. // 1. Expect token to be requested from storage.
  162. OCMExpect([self.mockStorage getToken]).andReturn([FBLPromise resolvedWith:nil]);
  163. // 2. Expect token requested from app check provider.
  164. FIRAppCheckToken *tokenToReturn = [[FIRAppCheckToken alloc] initWithToken:@"valid"
  165. expirationDate:[NSDate distantFuture]];
  166. id completionArg = [OCMArg invokeBlockWithArgs:tokenToReturn, [NSNull null], nil];
  167. OCMExpect([self.mockAppCheckProvider getTokenWithCompletion:completionArg]);
  168. // 3. Expect new token to be stored.
  169. OCMExpect([self.mockStorage setToken:tokenToReturn])
  170. .andReturn([FBLPromise resolvedWith:tokenToReturn]);
  171. // 4. Expect token update notification to be sent.
  172. XCTestExpectation *notificationExpectation =
  173. [self tokenUpdateNotificationWithExpectedToken:tokenToReturn.token];
  174. // 5. Request token.
  175. XCTestExpectation *getTokenExpectation = [self expectationWithDescription:@"getToken"];
  176. [self.appCheck getTokenForcingRefresh:NO
  177. completion:^(id<FIRAppCheckTokenResultInterop> tokenResult) {
  178. [getTokenExpectation fulfill];
  179. XCTAssertNotNil(tokenResult);
  180. XCTAssertEqualObjects(tokenResult.token, tokenToReturn.token);
  181. XCTAssertNil(tokenResult.error);
  182. }];
  183. // 6. Wait for expectations and validate mocks.
  184. [self waitForExpectations:@[ notificationExpectation, getTokenExpectation ] timeout:0.5];
  185. OCMVerifyAll(self.mockStorage);
  186. OCMVerifyAll(self.mockAppCheckProvider);
  187. }
  188. - (void)testGetToken_WhenCachedTokenIsValid_Success {
  189. FIRAppCheckToken *cachedToken = [[FIRAppCheckToken alloc] initWithToken:@"valid"
  190. expirationDate:[NSDate distantFuture]];
  191. // 1. Expect token to be requested from storage.
  192. OCMExpect([self.mockStorage getToken]).andReturn([FBLPromise resolvedWith:cachedToken]);
  193. // 2. Don't expect token requested from app check provider.
  194. OCMReject([self.mockAppCheckProvider getTokenWithCompletion:[OCMArg any]]);
  195. // 3. Don't expect token update notification to be sent.
  196. XCTestExpectation *notificationExpectation = [self tokenUpdateNotificationWithExpectedToken:@""];
  197. notificationExpectation.inverted = YES;
  198. // 4. Request token.
  199. XCTestExpectation *getTokenExpectation = [self expectationWithDescription:@"getToken"];
  200. [self.appCheck getTokenForcingRefresh:NO
  201. completion:^(id<FIRAppCheckTokenResultInterop> tokenResult) {
  202. [getTokenExpectation fulfill];
  203. XCTAssertNotNil(tokenResult);
  204. XCTAssertEqualObjects(tokenResult.token, cachedToken.token);
  205. XCTAssertNil(tokenResult.error);
  206. }];
  207. // 5. Wait for expectations and validate mocks.
  208. [self waitForExpectations:@[ notificationExpectation, getTokenExpectation ] timeout:0.5];
  209. OCMVerifyAll(self.mockStorage);
  210. OCMVerifyAll(self.mockAppCheckProvider);
  211. }
  212. - (void)testGetTokenForcingRefresh_WhenCachedTokenIsValid_Success {
  213. // 1. Don't expect token to be requested from storage.
  214. OCMReject([self.mockStorage getToken]);
  215. // 2. Expect token requested from app check provider.
  216. FIRAppCheckToken *tokenToReturn = [[FIRAppCheckToken alloc] initWithToken:@"valid"
  217. expirationDate:[NSDate distantFuture]];
  218. id completionArg = [OCMArg invokeBlockWithArgs:tokenToReturn, [NSNull null], nil];
  219. OCMExpect([self.mockAppCheckProvider getTokenWithCompletion:completionArg]);
  220. // 3. Expect new token to be stored.
  221. OCMExpect([self.mockStorage setToken:tokenToReturn])
  222. .andReturn([FBLPromise resolvedWith:tokenToReturn]);
  223. // 4. Expect token update notification to be sent.
  224. XCTestExpectation *notificationExpectation =
  225. [self tokenUpdateNotificationWithExpectedToken:tokenToReturn.token];
  226. // 5. Request token.
  227. XCTestExpectation *getTokenExpectation = [self expectationWithDescription:@"getToken"];
  228. [self.appCheck getTokenForcingRefresh:YES
  229. completion:^(id<FIRAppCheckTokenResultInterop> tokenResult) {
  230. [getTokenExpectation fulfill];
  231. XCTAssertNotNil(tokenResult);
  232. XCTAssertEqualObjects(tokenResult.token, tokenToReturn.token);
  233. XCTAssertNil(tokenResult.error);
  234. }];
  235. // 6. Wait for expectations and validate mocks.
  236. [self waitForExpectations:@[ notificationExpectation, getTokenExpectation ] timeout:0.5];
  237. OCMVerifyAll(self.mockStorage);
  238. OCMVerifyAll(self.mockAppCheckProvider);
  239. }
  240. - (void)testGetToken_WhenCachedTokenExpired_Success {
  241. FIRAppCheckToken *cachedToken = [[FIRAppCheckToken alloc] initWithToken:@"valid"
  242. expirationDate:[NSDate date]];
  243. // 1. Expect token to be requested from storage.
  244. OCMExpect([self.mockStorage getToken]).andReturn([FBLPromise resolvedWith:cachedToken]);
  245. // 2. Expect token requested from app check provider.
  246. FIRAppCheckToken *tokenToReturn = [[FIRAppCheckToken alloc] initWithToken:@"valid"
  247. expirationDate:[NSDate distantFuture]];
  248. id completionArg = [OCMArg invokeBlockWithArgs:tokenToReturn, [NSNull null], nil];
  249. OCMExpect([self.mockAppCheckProvider getTokenWithCompletion:completionArg]);
  250. // 3. Expect new token to be stored.
  251. OCMExpect([self.mockStorage setToken:tokenToReturn])
  252. .andReturn([FBLPromise resolvedWith:tokenToReturn]);
  253. // 4. Expect token update notification to be sent.
  254. XCTestExpectation *notificationExpectation =
  255. [self tokenUpdateNotificationWithExpectedToken:tokenToReturn.token];
  256. // 5. Request token.
  257. XCTestExpectation *getTokenExpectation = [self expectationWithDescription:@"getToken"];
  258. [self.appCheck getTokenForcingRefresh:NO
  259. completion:^(id<FIRAppCheckTokenResultInterop> tokenResult) {
  260. [getTokenExpectation fulfill];
  261. XCTAssertNotNil(tokenResult);
  262. XCTAssertEqualObjects(tokenResult.token, tokenToReturn.token);
  263. XCTAssertNil(tokenResult.error);
  264. }];
  265. // 6. Wait for expectations and validate mocks.
  266. [self waitForExpectations:@[ notificationExpectation, getTokenExpectation ] timeout:0.5];
  267. OCMVerifyAll(self.mockStorage);
  268. OCMVerifyAll(self.mockAppCheckProvider);
  269. }
  270. - (void)testGetToken_AppCheckProviderError {
  271. NSDate *soonExpiringTokenDate = [NSDate dateWithTimeIntervalSinceNow:4.5 * 60];
  272. FIRAppCheckToken *cachedToken = [[FIRAppCheckToken alloc] initWithToken:@"valid"
  273. expirationDate:soonExpiringTokenDate];
  274. // 1. Expect token to be requested from storage.
  275. OCMExpect([self.mockStorage getToken]).andReturn([FBLPromise resolvedWith:cachedToken]);
  276. // 2. Expect token requested from app check provider.
  277. NSError *providerError = [NSError errorWithDomain:@"FIRAppCheckTests" code:-1 userInfo:nil];
  278. id completionArg = [OCMArg invokeBlockWithArgs:[NSNull null], providerError, nil];
  279. OCMExpect([self.mockAppCheckProvider getTokenWithCompletion:completionArg]);
  280. // 3. Don't expect token requested from app check provider.
  281. OCMReject([self.mockAppCheckProvider getTokenWithCompletion:[OCMArg any]]);
  282. // 4. Don't expect token update notification to be sent.
  283. XCTestExpectation *notificationExpectation = [self tokenUpdateNotificationWithExpectedToken:@""];
  284. notificationExpectation.inverted = YES;
  285. // 5. Request token.
  286. XCTestExpectation *getTokenExpectation = [self expectationWithDescription:@"getToken"];
  287. [self.appCheck
  288. getTokenForcingRefresh:NO
  289. completion:^(id<FIRAppCheckTokenResultInterop> result) {
  290. [getTokenExpectation fulfill];
  291. XCTAssertNotNil(result);
  292. XCTAssertEqualObjects(result.token, @"eyJlcnJvciI6IlVOS05PV05fRVJST1IifQ==");
  293. // TODO: Expect a public domain error to be returned - not the
  294. // internal one.
  295. XCTAssertEqualObjects(result.error, providerError);
  296. }];
  297. // 6. Wait for expectations and validate mocks.
  298. [self waitForExpectations:@[ notificationExpectation, getTokenExpectation ] timeout:0.5];
  299. OCMVerifyAll(self.mockStorage);
  300. OCMVerifyAll(self.mockAppCheckProvider);
  301. }
  302. #pragma mark - Token refresher
  303. - (void)testTokenRefreshTriggeredAndRefreshSuccess {
  304. // 1. Expect token to be requested from storage.
  305. OCMExpect([self.mockStorage getToken]).andReturn([FBLPromise resolvedWith:nil]);
  306. // 2. Expect token requested from app check provider.
  307. NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:10000];
  308. FIRAppCheckToken *tokenToReturn = [[FIRAppCheckToken alloc] initWithToken:@"valid"
  309. expirationDate:expirationDate];
  310. id completionArg = [OCMArg invokeBlockWithArgs:tokenToReturn, [NSNull null], nil];
  311. OCMExpect([self.mockAppCheckProvider getTokenWithCompletion:completionArg]);
  312. // 3. Expect new token to be stored.
  313. OCMExpect([self.mockStorage setToken:tokenToReturn])
  314. .andReturn([FBLPromise resolvedWith:tokenToReturn]);
  315. // 4. Expect token update notification to be sent.
  316. XCTestExpectation *notificationExpectation =
  317. [self tokenUpdateNotificationWithExpectedToken:tokenToReturn.token];
  318. // 5. Trigger refresh and expect the result.
  319. if (self.tokenRefreshHandler == nil) {
  320. XCTFail(@"`tokenRefreshHandler` must be not `nil`.");
  321. return;
  322. }
  323. XCTestExpectation *completionExpectation = [self expectationWithDescription:@"completion"];
  324. self.tokenRefreshHandler(^(BOOL success, NSDate *_Nullable tokenExpirationDate) {
  325. [completionExpectation fulfill];
  326. XCTAssertEqual(tokenExpirationDate, expirationDate);
  327. XCTAssertTrue(success);
  328. });
  329. [self waitForExpectations:@[ notificationExpectation, completionExpectation ] timeout:0.5];
  330. OCMVerifyAll(self.mockStorage);
  331. OCMVerifyAll(self.mockAppCheckProvider);
  332. }
  333. - (void)testTokenRefreshTriggeredAndRefreshError {
  334. // 1. Expect token to be requested from storage.
  335. OCMExpect([self.mockStorage getToken]).andReturn([FBLPromise resolvedWith:nil]);
  336. // 2. Expect token requested from app check provider.
  337. NSError *providerError = [NSError errorWithDomain:@"FIRAppCheckTests" code:-1 userInfo:nil];
  338. id completionArg = [OCMArg invokeBlockWithArgs:[NSNull null], providerError, nil];
  339. OCMExpect([self.mockAppCheckProvider getTokenWithCompletion:completionArg]);
  340. // 3. Don't expect token requested from app check provider.
  341. OCMReject([self.mockAppCheckProvider getTokenWithCompletion:[OCMArg any]]);
  342. // 4. Don't expect token update notification to be sent.
  343. XCTestExpectation *notificationExpectation = [self tokenUpdateNotificationWithExpectedToken:@""];
  344. notificationExpectation.inverted = YES;
  345. // 5. Trigger refresh and expect the result.
  346. if (self.tokenRefreshHandler == nil) {
  347. XCTFail(@"`tokenRefreshHandler` must be not `nil`.");
  348. return;
  349. }
  350. XCTestExpectation *completionExpectation = [self expectationWithDescription:@"completion"];
  351. self.tokenRefreshHandler(^(BOOL success, NSDate *_Nullable tokenExpirationDate) {
  352. [completionExpectation fulfill];
  353. XCTAssertNil(tokenExpirationDate);
  354. XCTAssertFalse(success);
  355. });
  356. [self waitForExpectations:@[ notificationExpectation, completionExpectation ] timeout:0.5];
  357. OCMVerifyAll(self.mockStorage);
  358. OCMVerifyAll(self.mockAppCheckProvider);
  359. }
  360. #pragma mark - Token update notifications
  361. - (void)testTokenUpdateNotificationKeys {
  362. XCTAssertEqualObjects([self.appCheck tokenDidChangeNotificationName],
  363. @"FIRAppCheckAppCheckTokenDidChangeNotification");
  364. XCTAssertEqualObjects([self.appCheck notificationAppNameKey],
  365. @"FIRAppCheckAppNameNotificationKey");
  366. XCTAssertEqualObjects([self.appCheck notificationTokenKey], @"FIRAppCheckTokenNotificationKey");
  367. }
  368. #pragma mark - Auto-refresh enabled
  369. - (void)testIsTokenAutoRefreshEnabled {
  370. // Expect value from settings to be used.
  371. [[[self.mockSettings expect] andReturnValue:@(NO)] isTokenAutoRefreshEnabled];
  372. XCTAssertFalse(self.appCheck.isTokenAutoRefreshEnabled);
  373. [[[self.mockSettings expect] andReturnValue:@(YES)] isTokenAutoRefreshEnabled];
  374. XCTAssertTrue(self.appCheck.isTokenAutoRefreshEnabled);
  375. OCMVerifyAll(self.mockSettings);
  376. }
  377. - (void)testSetIsTokenAutoRefreshEnabled {
  378. OCMExpect([self.mockSettings setIsTokenAutoRefreshEnabled:YES]);
  379. self.appCheck.isTokenAutoRefreshEnabled = YES;
  380. OCMExpect([self.mockSettings setIsTokenAutoRefreshEnabled:NO]);
  381. self.appCheck.isTokenAutoRefreshEnabled = NO;
  382. OCMVerifyAll(self.mockSettings);
  383. }
  384. #pragma mark - Helpers
  385. - (void)stubSetTokenRefreshHandler {
  386. id arg = [OCMArg checkWithBlock:^BOOL(id handler) {
  387. self.tokenRefreshHandler = handler;
  388. return YES;
  389. }];
  390. OCMExpect([self.mockTokenRefresher setTokenRefreshHandler:arg]);
  391. }
  392. - (XCTestExpectation *)tokenUpdateNotificationWithExpectedToken:(NSString *)expectedToken {
  393. XCTestExpectation *expectation =
  394. [self expectationForNotification:[self.appCheck tokenDidChangeNotificationName]
  395. object:nil
  396. notificationCenter:self.notificationCenter
  397. handler:^BOOL(NSNotification *_Nonnull notification) {
  398. XCTAssertEqualObjects(
  399. notification.userInfo[[self.appCheck notificationAppNameKey]],
  400. self.appName);
  401. XCTAssertEqualObjects(
  402. notification.userInfo[[self.appCheck notificationTokenKey]],
  403. expectedToken);
  404. XCTAssertEqualObjects(notification.object, self.appCheck);
  405. return YES;
  406. }];
  407. return expectation;
  408. }
  409. @end