FIRAppCheckTests.m 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  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 FirebaseAppCheckInterop;
  19. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheck.h"
  20. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheckErrors.h"
  21. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheckProvider.h"
  22. #import "FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRAppCheckProviderFactory.h"
  23. #import "FirebaseAppCheck/Sources/Core/Errors/FIRAppCheckErrorUtil.h"
  24. #import "FirebaseAppCheck/Sources/Core/FIRAppCheckSettings.h"
  25. #import "FirebaseAppCheck/Sources/Core/FIRAppCheckToken+Internal.h"
  26. #import "FirebaseAppCheck/Sources/Core/FIRAppCheckTokenResult.h"
  27. #import "FirebaseCore/Extension/FirebaseCoreInternal.h"
  28. // The FAC token value returned when an error occurs.
  29. static NSString *const kDummyToken = @"eyJlcnJvciI6IlVOS05PV05fRVJST1IifQ==";
  30. @interface FIRAppCheck (Tests) <FIRAppCheckInterop, GACAppCheckTokenDelegate>
  31. - (instancetype)initWithAppName:(NSString *)appName
  32. appCheckCore:(GACAppCheck *)appCheckCore
  33. appCheckProvider:(id<FIRAppCheckProvider>)appCheckProvider
  34. notificationCenter:(NSNotificationCenter *)notificationCenter
  35. settings:(FIRAppCheckSettings *)settings;
  36. - (nullable instancetype)initWithApp:(FIRApp *)app;
  37. - (void)tokenDidUpdate:(nonnull GACAppCheckToken *)token
  38. serviceName:(nonnull NSString *)serviceName;
  39. @end
  40. @interface FIRAppCheckTests : XCTestCase
  41. @property(nonatomic) NSString *appName;
  42. @property(nonatomic) OCMockObject<FIRAppCheckProvider> *mockAppCheckProvider;
  43. @property(nonatomic) id mockSettings;
  44. @property(nonatomic) NSNotificationCenter *notificationCenter;
  45. @property(nonatomic) id mockAppCheckCore;
  46. @property(nonatomic) FIRAppCheck<FIRAppCheckInterop> *appCheck;
  47. @end
  48. @implementation FIRAppCheckTests
  49. - (void)setUp {
  50. [super setUp];
  51. self.appName = @"FIRAppCheckTests";
  52. self.mockAppCheckProvider = OCMStrictProtocolMock(@protocol(FIRAppCheckProvider));
  53. self.mockSettings = OCMStrictClassMock([FIRAppCheckSettings class]);
  54. self.notificationCenter = [[NSNotificationCenter alloc] init];
  55. self.mockAppCheckCore = OCMStrictClassMock([GACAppCheck class]);
  56. self.appCheck = [[FIRAppCheck alloc] initWithAppName:self.appName
  57. appCheckCore:self.mockAppCheckCore
  58. appCheckProvider:self.mockAppCheckProvider
  59. notificationCenter:self.notificationCenter
  60. settings:self.mockSettings];
  61. }
  62. - (void)tearDown {
  63. self.appCheck = nil;
  64. self.mockAppCheckCore = nil;
  65. self.mockAppCheckProvider = nil;
  66. [super tearDown];
  67. }
  68. - (void)disabled_testInitWithApp {
  69. NSString *projectID = @"testInitWithApp_projectID";
  70. NSString *googleAppID = @"testInitWithApp_googleAppID";
  71. NSString *appName = @"testInitWithApp_appName";
  72. NSString *appGroupID = @"testInitWithApp_appGroupID";
  73. // 1. Stub FIRApp and validate usage.
  74. id mockApp = OCMStrictClassMock([FIRApp class]);
  75. id mockAppOptions = OCMStrictClassMock([FIROptions class]);
  76. OCMStub([mockApp name]).andReturn(appName);
  77. // Prevent token auto-fetch on init.
  78. OCMStub([mockApp isDataCollectionDefaultEnabled]).andReturn(NO);
  79. OCMStub([(FIRApp *)mockApp options]).andReturn(mockAppOptions);
  80. OCMExpect([mockAppOptions projectID]).andReturn(projectID);
  81. OCMExpect([mockAppOptions googleAppID]).andReturn(googleAppID);
  82. OCMExpect([mockAppOptions appGroupID]).andReturn(appGroupID);
  83. // 2. Stub attestation provider.
  84. OCMockObject<FIRAppCheckProviderFactory> *mockProviderFactory =
  85. OCMStrictProtocolMock(@protocol(FIRAppCheckProviderFactory));
  86. OCMockObject<FIRAppCheckProvider> *mockProvider =
  87. OCMStrictProtocolMock(@protocol(FIRAppCheckProvider));
  88. OCMExpect([mockProviderFactory createProviderWithApp:mockApp]).andReturn(mockProvider);
  89. [FIRAppCheck setAppCheckProviderFactory:mockProviderFactory];
  90. // 3. Call init.
  91. FIRAppCheck *appCheck = [[FIRAppCheck alloc] initWithApp:mockApp];
  92. XCTAssert([appCheck isKindOfClass:[FIRAppCheck class]]);
  93. // 4. Verify mocks.
  94. OCMVerifyAll(mockApp);
  95. OCMVerifyAll(mockAppOptions);
  96. OCMVerifyAll(mockProviderFactory);
  97. OCMVerifyAll(mockProvider);
  98. // 5. Stop mocking real class mocks.
  99. [mockApp stopMocking];
  100. mockApp = nil;
  101. [mockAppOptions stopMocking];
  102. mockAppOptions = nil;
  103. }
  104. - (void)testAppCheckDefaultInstance {
  105. // Should throw an exception when the default app is not configured.
  106. XCTAssertThrows([FIRAppCheck appCheck]);
  107. // Configure default FIRApp.
  108. FIROptions *options =
  109. [[FIROptions alloc] initWithGoogleAppID:@"1:100000000000:ios:aaaaaaaaaaaaaaaaaaaaaaaa"
  110. GCMSenderID:@"sender_id"];
  111. options.APIKey = @"api_key";
  112. options.projectID = @"project_id";
  113. [FIRApp configureWithOptions:options];
  114. // Prevent token auto-fetch on init.
  115. [[FIRApp defaultApp] setDataCollectionDefaultEnabled:NO];
  116. // Check.
  117. XCTAssertNotNil([FIRAppCheck appCheck]);
  118. [FIRApp resetApps];
  119. }
  120. - (void)testAppCheckInstanceForApp {
  121. FIROptions *options =
  122. [[FIROptions alloc] initWithGoogleAppID:@"1:100000000000:ios:aaaaaaaaaaaaaaaaaaaaaaaa"
  123. GCMSenderID:@"sender_id"];
  124. options.APIKey = @"api_key";
  125. options.projectID = @"project_id";
  126. [FIRApp configureWithName:@"testAppCheckInstanceForApp" options:options];
  127. FIRApp *app = [FIRApp appNamed:@"testAppCheckInstanceForApp"];
  128. // Prevent token auto-fetch on init.
  129. [app setDataCollectionDefaultEnabled:NO];
  130. XCTAssertNotNil(app);
  131. XCTAssertNotNil([FIRAppCheck appCheckWithApp:app]);
  132. [FIRApp resetApps];
  133. }
  134. #pragma mark - Public Get Token
  135. - (void)testGetToken_Success {
  136. // 1. Create expected token and configure expectations.
  137. FIRAppCheckToken *expectedToken = [self validToken];
  138. NSArray * /*[tokenNotification, getToken]*/ expectations =
  139. [self configuredExpectations_TokenForcingRefresh_withExpectedToken:expectedToken];
  140. // 2. Request token and verify result.
  141. [self.appCheck
  142. tokenForcingRefresh:NO
  143. completion:^(FIRAppCheckToken *_Nullable token, NSError *_Nullable error) {
  144. [expectations.lastObject fulfill];
  145. XCTAssertNotNil(token);
  146. XCTAssertEqualObjects(token.token, expectedToken.token);
  147. XCTAssertNil(error);
  148. }];
  149. // 3. Wait for expectations and validate mocks.
  150. [self waitForExpectations:expectations timeout:0.5];
  151. [self verifyAllMocks];
  152. }
  153. - (void)testGetToken_AppCheckProviderError {
  154. // 1. Create expected token and error and configure expectations.
  155. FIRAppCheckToken *cachedToken = [self soonExpiringToken];
  156. NSError *providerError = [NSError errorWithDomain:@"FIRAppCheckTests" code:-1 userInfo:nil];
  157. NSArray * /*[tokenNotification, getToken]*/ expectations =
  158. [self configuredExpectations_GetTokenWhenError_withError:providerError andToken:cachedToken];
  159. // 2. Request token and verify result.
  160. [self.appCheck
  161. tokenForcingRefresh:NO
  162. completion:^(FIRAppCheckToken *_Nullable token, NSError *_Nullable error) {
  163. [expectations.lastObject fulfill];
  164. XCTAssertNil(token);
  165. XCTAssertNotNil(error);
  166. XCTAssertNotEqualObjects(error, providerError);
  167. XCTAssertEqualObjects(error.domain, FIRAppCheckErrorDomain);
  168. XCTAssertEqualObjects(error.userInfo[NSUnderlyingErrorKey], providerError);
  169. }];
  170. // 3. Wait for expectations and validate mocks.
  171. [self waitForExpectations:expectations timeout:0.5];
  172. [self verifyAllMocks];
  173. }
  174. - (void)testGetToken_ServerUnreachableError {
  175. // 1. Create expected error and configure expectations.
  176. NSError *serverError = [FIRAppCheckErrorUtil APIErrorWithNetworkError:[self internalError]];
  177. NSArray * /*[tokenNotification, getToken]*/ expectations =
  178. [self configuredExpectations_GetTokenWhenError_withError:serverError andToken:nil];
  179. // 2. Request token and verify result.
  180. [self.appCheck
  181. tokenForcingRefresh:NO
  182. completion:^(FIRAppCheckToken *_Nullable token, NSError *_Nullable error) {
  183. [expectations.lastObject fulfill];
  184. XCTAssertNil(token);
  185. XCTAssertNotNil(error);
  186. XCTAssertEqualObjects(error, serverError);
  187. XCTAssertEqualObjects(error.domain, FIRAppCheckErrorDomain);
  188. }];
  189. // 3. Wait for expectations and validate mocks.
  190. [self waitForExpectations:expectations timeout:0.5];
  191. [self verifyAllMocks];
  192. }
  193. - (void)testGetToken_UnsupportedError {
  194. // 1. Create expected error and configure expectations.
  195. NSError *providerError =
  196. [FIRAppCheckErrorUtil unsupportedAttestationProvider:@"AppAttestProvider"];
  197. NSArray * /*[tokenNotification, getToken]*/ expectations =
  198. [self configuredExpectations_GetTokenWhenError_withError:providerError andToken:nil];
  199. // 2. Request token and verify result.
  200. [self.appCheck
  201. tokenForcingRefresh:NO
  202. completion:^(FIRAppCheckToken *_Nullable token, NSError *_Nullable error) {
  203. [expectations.lastObject fulfill];
  204. XCTAssertNil(token);
  205. XCTAssertNotNil(error);
  206. XCTAssertEqualObjects(error, providerError);
  207. XCTAssertEqualObjects(error.domain, FIRAppCheckErrorDomain);
  208. }];
  209. // 3. Wait for expectations and validate mocks.
  210. [self waitForExpectations:expectations timeout:0.5];
  211. [self verifyAllMocks];
  212. }
  213. #pragma mark - FIRAppCheckInterop Get Token
  214. - (void)testInteropGetTokenForcingRefresh_Success {
  215. // 1. Create expected token and configure expectations.
  216. FIRAppCheckToken *expectedToken = [self validToken];
  217. NSArray * /*[tokenNotification, getToken]*/ expectations =
  218. [self configuredExpectations_TokenForcingRefresh_withExpectedToken:expectedToken];
  219. // 2. Request token and verify result.
  220. [self.appCheck getTokenForcingRefresh:NO
  221. completion:^(id<FIRAppCheckTokenResultInterop> tokenResult) {
  222. [expectations.lastObject fulfill];
  223. XCTAssertNotNil(tokenResult);
  224. XCTAssertEqualObjects(tokenResult.token, expectedToken.token);
  225. XCTAssertNil(tokenResult.error);
  226. }];
  227. // 3. Wait for expectations and validate mocks.
  228. [self waitForExpectations:expectations timeout:0.5];
  229. [self verifyAllMocks];
  230. }
  231. - (void)testInteropGetTokenForcingRefresh_AppCheckProviderError {
  232. // 1. Create expected tokens and errors and configure expectations.
  233. FIRAppCheckToken *cachedToken = [self soonExpiringToken];
  234. NSError *providerError = [NSError errorWithDomain:@"FIRAppCheckTests" code:-1 userInfo:nil];
  235. NSArray * /*[tokenNotification, getToken]*/ expectations =
  236. [self configuredExpectations_GetTokenWhenError_withError:providerError andToken:cachedToken];
  237. // 2. Request token and verify result.
  238. [self.appCheck
  239. getTokenForcingRefresh:NO
  240. completion:^(id<FIRAppCheckTokenResultInterop> result) {
  241. [expectations.lastObject fulfill];
  242. XCTAssertNotNil(result);
  243. XCTAssertEqualObjects(result.token, kDummyToken);
  244. XCTAssertEqualObjects(result.error, providerError);
  245. // Interop API does not wrap errors in public domain.
  246. XCTAssertNotEqualObjects(result.error.domain, FIRAppCheckErrorDomain);
  247. }];
  248. // 3. Wait for expectations and validate mocks.
  249. [self waitForExpectations:expectations timeout:15];
  250. [self verifyAllMocks];
  251. }
  252. - (void)testLimitedUseTokenWithSuccess {
  253. // 1. Expect token requested from app check provider.
  254. FIRAppCheckToken *expectedToken = [self validToken];
  255. GACAppCheckToken *expectedInternalToken = [expectedToken internalToken];
  256. GACAppCheckTokenResult *expectedTokenResult =
  257. [[GACAppCheckTokenResult alloc] initWithToken:expectedInternalToken];
  258. id completionArg = [OCMArg invokeBlockWithArgs:expectedTokenResult, nil];
  259. OCMStub([self.mockAppCheckCore limitedUseTokenWithCompletion:completionArg]);
  260. // 2. Don't expect token update notification to be sent.
  261. XCTestExpectation *notificationExpectation = [self tokenUpdateNotificationNotPosted];
  262. // 3. Expect token request to be completed.
  263. XCTestExpectation *getTokenExpectation = [self expectationWithDescription:@"getToken"];
  264. [self.appCheck
  265. limitedUseTokenWithCompletion:^(FIRAppCheckToken *_Nullable token, NSError *_Nullable error) {
  266. [getTokenExpectation fulfill];
  267. XCTAssertNotNil(token);
  268. XCTAssertEqualObjects(token.token, expectedToken.token);
  269. XCTAssertNil(error);
  270. }];
  271. [self waitForExpectations:@[ notificationExpectation, getTokenExpectation ] timeout:0.5];
  272. [self verifyAllMocks];
  273. }
  274. - (void)testLimitedUseToken_WhenTokenGenerationErrors {
  275. // 1. Expect error when requesting token from app check provider.
  276. NSError *providerError = [FIRAppCheckErrorUtil keychainErrorWithError:[self internalError]];
  277. GACAppCheckTokenResult *expectedTokenResult =
  278. [[GACAppCheckTokenResult alloc] initWithError:providerError];
  279. id completionArg = [OCMArg invokeBlockWithArgs:expectedTokenResult, nil];
  280. OCMStub([self.mockAppCheckCore limitedUseTokenWithCompletion:completionArg]);
  281. // 2. Don't expect token requested from app check provider.
  282. OCMReject([self.mockAppCheckProvider getTokenWithCompletion:[OCMArg any]]);
  283. // 3. Don't expect token update notification to be sent.
  284. XCTestExpectation *notificationExpectation = [self tokenUpdateNotificationNotPosted];
  285. // 4. Expect token request to be completed.
  286. XCTestExpectation *getTokenExpectation = [self expectationWithDescription:@"getToken"];
  287. [self.appCheck
  288. limitedUseTokenWithCompletion:^(FIRAppCheckToken *_Nullable token, NSError *_Nullable error) {
  289. [getTokenExpectation fulfill];
  290. XCTAssertNotNil(error);
  291. XCTAssertNil(token.token);
  292. XCTAssertEqualObjects(error, providerError);
  293. XCTAssertEqualObjects(error.domain, FIRAppCheckErrorDomain);
  294. }];
  295. [self waitForExpectations:@[ notificationExpectation, getTokenExpectation ] timeout:0.5];
  296. [self verifyAllMocks];
  297. }
  298. #pragma mark - Token update notifications
  299. - (void)testTokenUpdateNotificationKeys {
  300. XCTAssertEqualObjects([self.appCheck tokenDidChangeNotificationName],
  301. @"FIRAppCheckAppCheckTokenDidChangeNotification");
  302. XCTAssertEqualObjects([self.appCheck notificationAppNameKey],
  303. @"FIRAppCheckAppNameNotificationKey");
  304. XCTAssertEqualObjects([self.appCheck notificationTokenKey], @"FIRAppCheckTokenNotificationKey");
  305. }
  306. #pragma mark - Auto-refresh enabled
  307. - (void)testIsTokenAutoRefreshEnabled {
  308. // Expect value from settings to be used.
  309. [[[self.mockSettings expect] andReturnValue:@(NO)] isTokenAutoRefreshEnabled];
  310. XCTAssertFalse(self.appCheck.isTokenAutoRefreshEnabled);
  311. [[[self.mockSettings expect] andReturnValue:@(YES)] isTokenAutoRefreshEnabled];
  312. XCTAssertTrue(self.appCheck.isTokenAutoRefreshEnabled);
  313. OCMVerifyAll(self.mockSettings);
  314. }
  315. - (void)testSetIsTokenAutoRefreshEnabled {
  316. OCMExpect([self.mockSettings setIsTokenAutoRefreshEnabled:YES]);
  317. self.appCheck.isTokenAutoRefreshEnabled = YES;
  318. OCMExpect([self.mockSettings setIsTokenAutoRefreshEnabled:NO]);
  319. self.appCheck.isTokenAutoRefreshEnabled = NO;
  320. OCMVerifyAll(self.mockSettings);
  321. }
  322. #pragma mark - Helpers
  323. - (NSError *)internalError {
  324. return [NSError errorWithDomain:@"com.internal.error" code:-1 userInfo:nil];
  325. }
  326. - (FIRAppCheckToken *)validToken {
  327. return [[FIRAppCheckToken alloc] initWithToken:[NSUUID UUID].UUIDString
  328. expirationDate:[NSDate distantFuture]];
  329. }
  330. - (FIRAppCheckToken *)soonExpiringToken {
  331. NSDate *soonExpiringTokenDate = [NSDate dateWithTimeIntervalSinceNow:4.5 * 60];
  332. return [[FIRAppCheckToken alloc] initWithToken:@"valid" expirationDate:soonExpiringTokenDate];
  333. }
  334. - (XCTestExpectation *)tokenUpdateNotificationWithExpectedToken:(NSString *)expectedToken {
  335. XCTestExpectation *expectation =
  336. [self expectationForNotification:[self.appCheck tokenDidChangeNotificationName]
  337. object:nil
  338. notificationCenter:self.notificationCenter
  339. handler:^BOOL(NSNotification *_Nonnull notification) {
  340. XCTAssertEqualObjects(
  341. notification.userInfo[[self.appCheck notificationAppNameKey]],
  342. self.appName);
  343. XCTAssertEqualObjects(
  344. notification.userInfo[[self.appCheck notificationTokenKey]],
  345. expectedToken);
  346. XCTAssertEqualObjects(notification.object, self.appCheck);
  347. return YES;
  348. }];
  349. return expectation;
  350. }
  351. - (XCTestExpectation *)tokenUpdateNotificationNotPosted {
  352. XCTNSNotificationExpectation *expectation = [[XCTNSNotificationExpectation alloc]
  353. initWithName:[self.appCheck tokenDidChangeNotificationName]
  354. object:nil
  355. notificationCenter:self.notificationCenter];
  356. expectation.inverted = YES;
  357. return expectation;
  358. }
  359. - (NSArray<XCTestExpectation *> *)configuredExpectations_TokenForcingRefresh_withExpectedToken:
  360. (FIRAppCheckToken *)expectedToken {
  361. // 1. Expect token requested from app check core.
  362. GACAppCheckToken *expectedInternalToken = [expectedToken internalToken];
  363. GACAppCheckTokenResult *expectedTokenResult =
  364. [[GACAppCheckTokenResult alloc] initWithToken:expectedInternalToken];
  365. id completionArg = [OCMArg invokeBlockWithArgs:expectedTokenResult, nil];
  366. OCMExpect([self.mockAppCheckCore tokenForcingRefresh:NO completion:completionArg])
  367. .andDo(^(NSInvocation *invocation) {
  368. [self.appCheck tokenDidUpdate:expectedInternalToken serviceName:self.appName];
  369. })
  370. .ignoringNonObjectArgs();
  371. // 2. Expect token update notification to be sent.
  372. XCTestExpectation *tokenNotificationExpectation =
  373. [self tokenUpdateNotificationWithExpectedToken:expectedToken.token];
  374. // 3. Expect token request to be completed.
  375. XCTestExpectation *getTokenExpectation = [self expectationWithDescription:@"getToken"];
  376. return @[ tokenNotificationExpectation, getTokenExpectation ];
  377. }
  378. - (NSArray<XCTestExpectation *> *)
  379. configuredExpectations_GetTokenWhenError_withError:(NSError *_Nonnull)error
  380. andToken:(FIRAppCheckToken *_Nullable)token {
  381. // 1. Expect token requested from app check core.
  382. GACAppCheckTokenResult *expectedTokenResult =
  383. [[GACAppCheckTokenResult alloc] initWithError:error];
  384. id completionArg = [OCMArg invokeBlockWithArgs:expectedTokenResult, nil];
  385. OCMExpect([self.mockAppCheckCore tokenForcingRefresh:NO completion:completionArg])
  386. .ignoringNonObjectArgs();
  387. // 2. Don't expect token requested from app check provider.
  388. OCMReject([self.mockAppCheckProvider getTokenWithCompletion:[OCMArg any]]);
  389. // 3. Expect token update notification to be sent.
  390. XCTestExpectation *notificationExpectation = [self tokenUpdateNotificationNotPosted];
  391. // 4. Expect token request to be completed.
  392. XCTestExpectation *getTokenExpectation = [self expectationWithDescription:@"getToken"];
  393. return @[ notificationExpectation, getTokenExpectation ];
  394. }
  395. - (void)verifyAllMocks {
  396. OCMVerifyAll(self.mockAppCheckProvider);
  397. OCMVerifyAll(self.mockSettings);
  398. OCMVerifyAll(self.mockAppCheckCore);
  399. }
  400. @end