FIRFADApiServiceTests.m 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  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. #import <Foundation/Foundation.h>
  16. #import <OCMock/OCMock.h>
  17. #import <XCTest/XCTest.h>
  18. #import "FirebaseAppDistribution/Sources/FIRFADApiService.h"
  19. #import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
  20. #import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h"
  21. NSString *const kFakeErrorDomain = @"test.failure.domain";
  22. @interface FIRFADApiServiceTests : XCTestCase
  23. @end
  24. @implementation FIRFADApiServiceTests {
  25. id _mockFIRAppClass;
  26. id _mockURLSession;
  27. id _mockFIRInstallations;
  28. id _mockInstallationToken;
  29. NSString *_mockAuthToken;
  30. NSString *_mockInstallationId;
  31. NSDictionary *_mockReleases;
  32. }
  33. - (void)setUp {
  34. [super setUp];
  35. _mockFIRAppClass = OCMClassMock([FIRApp class]);
  36. _mockURLSession = OCMClassMock([NSURLSession class]);
  37. _mockFIRInstallations = OCMClassMock([FIRInstallations class]);
  38. _mockInstallationToken = OCMClassMock([FIRInstallationsAuthTokenResult class]);
  39. _mockAuthToken = @"this-is-an-auth-token";
  40. OCMStub([_mockFIRAppClass defaultApp]).andReturn(_mockFIRAppClass);
  41. OCMStub([_mockURLSession sharedSession]).andReturn(_mockURLSession);
  42. OCMStub([_mockFIRInstallations installations]).andReturn(_mockFIRInstallations);
  43. OCMStub([_mockInstallationToken authToken]).andReturn(_mockAuthToken);
  44. _mockInstallationId = @"this-id-is-fake-ccccc";
  45. _mockReleases = @{
  46. @"releases" : @[
  47. @{
  48. @"displayVersion" : @"1.0.0",
  49. @"buildVersion" : @"111",
  50. @"releaseNotes" : @"This is a release",
  51. @"downloadURL" : @"http://faketyfakefake.download"
  52. },
  53. @{
  54. @"latest" : @YES,
  55. @"displayVersion" : @"1.0.1",
  56. @"buildVersion" : @"112",
  57. @"releaseNotes" : @"This is a release too",
  58. @"downloadURL" : @"http://faketyfakefake.download"
  59. }
  60. ]
  61. };
  62. }
  63. - (void)tearDown {
  64. [super tearDown];
  65. [_mockFIRAppClass stopMocking];
  66. [_mockFIRInstallations stopMocking];
  67. [_mockInstallationToken stopMocking];
  68. [_mockURLSession stopMocking];
  69. }
  70. - (void)mockInstallationAuthCompletion:(FIRInstallationsAuthTokenResult *_Nullable)token
  71. error:(NSError *_Nullable)error {
  72. [OCMStub([_mockFIRInstallations authTokenWithCompletion:OCMOCK_ANY])
  73. andDo:^(NSInvocation *invocation) {
  74. void (^handler)(FIRInstallationsAuthTokenResult *_Nullable authTokenResult,
  75. NSError *_Nullable error);
  76. [invocation getArgument:&handler atIndex:2];
  77. handler(token, error);
  78. }];
  79. }
  80. - (void)verifyInstallationAuthCompletion {
  81. OCMVerify([_mockFIRInstallations authTokenWithCompletion:[OCMArg isNotNil]]);
  82. }
  83. - (void)rejectInstallationAuthCompletion {
  84. OCMReject([_mockFIRInstallations authTokenWithCompletion:[OCMArg isNotNil]]);
  85. }
  86. - (void)mockInstallationIdCompletion:(NSString *_Nullable)identifier
  87. error:(NSError *_Nullable)error {
  88. [OCMStub([_mockFIRInstallations installationIDWithCompletion:OCMOCK_ANY])
  89. andDo:^(NSInvocation *invocation) {
  90. void (^handler)(NSString *identifier, NSError *_Nullable error);
  91. [invocation getArgument:&handler atIndex:2];
  92. handler(identifier, error);
  93. }];
  94. }
  95. - (void)verifyInstallationIdCompletion {
  96. OCMVerify([_mockFIRInstallations installationIDWithCompletion:[OCMArg isNotNil]]);
  97. }
  98. - (void)rejectInstallationIdCompletion {
  99. OCMReject([_mockFIRInstallations installationIDWithCompletion:[OCMArg isNotNil]]);
  100. }
  101. - (void)mockUrlSessionResponse:(NSDictionary *)dictionary
  102. response:(NSURLResponse *)response
  103. error:(NSError *)error {
  104. NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
  105. [self mockUrlSessionResponseWithData:data response:response error:error];
  106. }
  107. - (void)mockUrlSessionResponseWithData:(NSData *)data
  108. response:(NSURLResponse *)response
  109. error:(NSError *)error {
  110. [OCMStub([_mockURLSession dataTaskWithRequest:[OCMArg any]
  111. completionHandler:[OCMArg any]]) andDo:^(NSInvocation *invocation) {
  112. void (^handler)(NSData *data, NSURLResponse *response, NSError *error);
  113. [invocation getArgument:&handler atIndex:3];
  114. handler(data, response, error);
  115. }];
  116. }
  117. - (void)verifyUrlSessionResponseWithData {
  118. OCMVerify([_mockURLSession dataTaskWithRequest:[OCMArg isNotNil]
  119. completionHandler:[OCMArg isNotNil]]);
  120. }
  121. - (void)rejectUrlSessionResponseWithData {
  122. OCMReject([_mockURLSession dataTaskWithRequest:[OCMArg isNotNil]
  123. completionHandler:[OCMArg isNotNil]]);
  124. }
  125. - (void)testGenerateAuthTokenWithCompletionSuccess {
  126. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  127. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  128. XCTestExpectation *expectation =
  129. [self expectationWithDescription:@"Generate auth token succeeds."];
  130. [FIRFADApiService
  131. generateAuthTokenWithCompletion:^(NSString *_Nullable identifier,
  132. FIRInstallationsAuthTokenResult *_Nullable authTokenResult,
  133. NSError *_Nullable error) {
  134. XCTAssertNotNil(authTokenResult);
  135. XCTAssertNotNil(identifier);
  136. XCTAssertNil(error);
  137. XCTAssertEqual(identifier, self->_mockInstallationId);
  138. XCTAssertEqual([authTokenResult authToken], self -> _mockAuthToken);
  139. [expectation fulfill];
  140. }];
  141. [self waitForExpectations:@[ expectation ] timeout:5.0];
  142. [self verifyInstallationAuthCompletion];
  143. [self verifyInstallationIdCompletion];
  144. }
  145. - (void)testGenerateAuthTokenWithCompletionAuthTokenFailure {
  146. [self mockInstallationAuthCompletion:nil
  147. error:[NSError errorWithDomain:kFakeErrorDomain
  148. code:1
  149. userInfo:@{}]];
  150. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  151. XCTestExpectation *expectation =
  152. [self expectationWithDescription:@"Generate auth token fails to generate auth token."];
  153. [FIRFADApiService
  154. generateAuthTokenWithCompletion:^(NSString *_Nullable identifier,
  155. FIRInstallationsAuthTokenResult *_Nullable authTokenResult,
  156. NSError *_Nullable error) {
  157. XCTAssertNil(identifier);
  158. XCTAssertNil(authTokenResult);
  159. XCTAssertNotNil(error);
  160. XCTAssertEqual(error.code, FIRFADApiTokenGenerationFailure);
  161. [expectation fulfill];
  162. }];
  163. [self waitForExpectations:@[ expectation ] timeout:5.0];
  164. [self verifyInstallationAuthCompletion];
  165. [self rejectInstallationIdCompletion];
  166. }
  167. - (void)testGenerateAuthTokenWithCompletionIDFailure {
  168. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  169. [self mockInstallationIdCompletion:nil
  170. error:[NSError errorWithDomain:kFakeErrorDomain
  171. code:1
  172. userInfo:@{}]];
  173. XCTestExpectation *expectation =
  174. [self expectationWithDescription:@"Generate auth token fails to find ID."];
  175. [FIRFADApiService
  176. generateAuthTokenWithCompletion:^(NSString *_Nullable identifier,
  177. FIRInstallationsAuthTokenResult *_Nullable authTokenResult,
  178. NSError *_Nullable error) {
  179. XCTAssertNil(identifier);
  180. XCTAssertNil(authTokenResult);
  181. XCTAssertNotNil(error);
  182. XCTAssertEqual([error code], FIRFADApiInstallationIdentifierError);
  183. [expectation fulfill];
  184. }];
  185. [self waitForExpectations:@[ expectation ] timeout:5.0];
  186. [self verifyInstallationAuthCompletion];
  187. [self verifyInstallationIdCompletion];
  188. }
  189. - (void)testFetchReleasesWithCompletionSuccess {
  190. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  191. OCMStub([fakeResponse statusCode]).andReturn(200);
  192. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  193. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  194. [self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
  195. XCTestExpectation *expectation =
  196. [self expectationWithDescription:@"Fetch releases succeeds with two releases."];
  197. [FIRFADApiService
  198. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  199. XCTAssertNil(error);
  200. XCTAssertNotNil(releases);
  201. XCTAssertEqual([releases count], 2);
  202. [expectation fulfill];
  203. }];
  204. [self waitForExpectations:@[ expectation ] timeout:5.0];
  205. [self verifyInstallationAuthCompletion];
  206. [self verifyInstallationIdCompletion];
  207. [self verifyUrlSessionResponseWithData];
  208. OCMVerify([fakeResponse statusCode]);
  209. }
  210. - (void)testFetchReleasesWithCompletionUnknownFailure {
  211. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  212. OCMStub([fakeResponse statusCode]).andReturn(200);
  213. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  214. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  215. [self mockUrlSessionResponse:_mockReleases
  216. response:fakeResponse
  217. error:[NSError errorWithDomain:kFakeErrorDomain code:1 userInfo:@{}]];
  218. XCTestExpectation *expectation =
  219. [self expectationWithDescription:@"Fetch releases fails with unknown error."];
  220. [FIRFADApiService
  221. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  222. XCTAssertNil(releases);
  223. XCTAssertNotNil(error);
  224. XCTAssertEqual(error.code, FIRApiErrorUnknownFailure);
  225. [expectation fulfill];
  226. }];
  227. [self waitForExpectations:@[ expectation ] timeout:5.0];
  228. [self verifyInstallationAuthCompletion];
  229. [self verifyInstallationIdCompletion];
  230. [self verifyUrlSessionResponseWithData];
  231. OCMVerify([fakeResponse statusCode]);
  232. }
  233. - (void)testFetchReleasesWithCompletionUnauthenticatedFailure {
  234. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  235. OCMStub([fakeResponse statusCode]).andReturn(401);
  236. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  237. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  238. [self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
  239. XCTestExpectation *expectation =
  240. [self expectationWithDescription:@"Fetch releases fails with unknown error."];
  241. [FIRFADApiService
  242. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  243. XCTAssertNil(releases);
  244. XCTAssertNotNil(error);
  245. XCTAssertEqual(error.code, FIRFADApiErrorUnauthenticated);
  246. [expectation fulfill];
  247. }];
  248. [self waitForExpectations:@[ expectation ] timeout:5.0];
  249. [self verifyInstallationAuthCompletion];
  250. [self verifyInstallationIdCompletion];
  251. [self verifyUrlSessionResponseWithData];
  252. OCMVerify([fakeResponse statusCode]);
  253. }
  254. - (void)testFetchReleasesWithCompletionUnauthorized400Failure {
  255. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  256. OCMStub([fakeResponse statusCode]).andReturn(400);
  257. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  258. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  259. [self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
  260. XCTestExpectation *expectation =
  261. [self expectationWithDescription:@"Fetch releases rejects with a 400."];
  262. [FIRFADApiService
  263. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  264. XCTAssertNil(releases);
  265. XCTAssertNotNil(error);
  266. XCTAssertEqual([error code], FIRFADApiErrorUnauthorized);
  267. [expectation fulfill];
  268. }];
  269. [self waitForExpectations:@[ expectation ] timeout:5.0];
  270. [self verifyInstallationAuthCompletion];
  271. [self verifyInstallationIdCompletion];
  272. [self verifyUrlSessionResponseWithData];
  273. OCMVerify([fakeResponse statusCode]);
  274. }
  275. - (void)testFetchReleasesWithCompletionUnauthorized403Failure {
  276. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  277. OCMStub([fakeResponse statusCode]).andReturn(403);
  278. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  279. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  280. [self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
  281. XCTestExpectation *expectation =
  282. [self expectationWithDescription:@"Fetch releases rejects with a 403."];
  283. [FIRFADApiService
  284. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  285. XCTAssertNil(releases);
  286. XCTAssertNotNil(error);
  287. XCTAssertEqual([error code], FIRFADApiErrorUnauthorized);
  288. [expectation fulfill];
  289. }];
  290. [self waitForExpectations:@[ expectation ] timeout:5.0];
  291. [self verifyInstallationAuthCompletion];
  292. [self verifyInstallationIdCompletion];
  293. [self verifyUrlSessionResponseWithData];
  294. OCMVerify([fakeResponse statusCode]);
  295. }
  296. - (void)testFetchReleasesWithCompletionUnauthorized404Failure {
  297. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  298. OCMStub([fakeResponse statusCode]).andReturn(404);
  299. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  300. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  301. [self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
  302. XCTestExpectation *expectation =
  303. [self expectationWithDescription:@"Fetch releases rejects with a 404."];
  304. [FIRFADApiService
  305. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  306. XCTAssertNil(releases);
  307. XCTAssertNotNil(error);
  308. XCTAssertEqual([error code], FIRFADApiErrorUnauthorized);
  309. [expectation fulfill];
  310. }];
  311. [self waitForExpectations:@[ expectation ] timeout:5.0];
  312. [self verifyInstallationAuthCompletion];
  313. [self verifyInstallationIdCompletion];
  314. [self verifyUrlSessionResponseWithData];
  315. OCMVerify([fakeResponse statusCode]);
  316. }
  317. - (void)testFetchReleasesWithCompletionTimeout408Failure {
  318. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  319. OCMStub([fakeResponse statusCode]).andReturn(408);
  320. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  321. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  322. [self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
  323. XCTestExpectation *expectation =
  324. [self expectationWithDescription:@"Fetch releases rejects with 408."];
  325. [FIRFADApiService
  326. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  327. XCTAssertNil(releases);
  328. XCTAssertNotNil(error);
  329. XCTAssertEqual([error code], FIRFADApiErrorTimeout);
  330. [expectation fulfill];
  331. }];
  332. [self waitForExpectations:@[ expectation ] timeout:5.0];
  333. [self verifyInstallationAuthCompletion];
  334. [self verifyInstallationIdCompletion];
  335. [self verifyUrlSessionResponseWithData];
  336. OCMVerify([fakeResponse statusCode]);
  337. }
  338. - (void)testFetchReleasesWithCompletionTimeout504Failure {
  339. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  340. OCMStub([fakeResponse statusCode]).andReturn(504);
  341. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  342. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  343. [self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
  344. XCTestExpectation *expectation =
  345. [self expectationWithDescription:@"Fetch releases rejects with a 504."];
  346. [FIRFADApiService
  347. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  348. XCTAssertNil(releases);
  349. XCTAssertNotNil(error);
  350. XCTAssertEqual([error code], FIRFADApiErrorTimeout);
  351. [expectation fulfill];
  352. }];
  353. [self waitForExpectations:@[ expectation ] timeout:5.0];
  354. [self verifyInstallationAuthCompletion];
  355. [self verifyInstallationIdCompletion];
  356. [self verifyUrlSessionResponseWithData];
  357. OCMVerify([fakeResponse statusCode]);
  358. }
  359. - (void)testFetchReleasesWithCompletionUnknownStatusCodeFailure {
  360. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  361. OCMStub([fakeResponse statusCode]).andReturn(500);
  362. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  363. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  364. [self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
  365. XCTestExpectation *expectation =
  366. [self expectationWithDescription:@"Fetch releases rejects with a 500."];
  367. [FIRFADApiService
  368. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  369. XCTAssertNil(releases);
  370. XCTAssertNotNil(error);
  371. XCTAssertEqual([error code], FIRApiErrorUnknownFailure);
  372. [expectation fulfill];
  373. }];
  374. [self waitForExpectations:@[ expectation ] timeout:5.0];
  375. [self verifyInstallationAuthCompletion];
  376. [self verifyInstallationIdCompletion];
  377. [self verifyUrlSessionResponseWithData];
  378. OCMVerify([fakeResponse statusCode]);
  379. }
  380. - (void)testFetchReleasesWithCompletionNoReleasesFoundSuccess {
  381. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  382. OCMStub([fakeResponse statusCode]).andReturn(200);
  383. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  384. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  385. [self mockUrlSessionResponse:@{@"releases" : @[]} response:fakeResponse error:nil];
  386. XCTestExpectation *expectation =
  387. [self expectationWithDescription:@"Fetch releases rejects with a not found exception."];
  388. [FIRFADApiService
  389. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  390. XCTAssertNotNil(releases);
  391. XCTAssertNil(error);
  392. XCTAssertEqual([releases count], 0);
  393. [expectation fulfill];
  394. }];
  395. [self waitForExpectations:@[ expectation ] timeout:5.0];
  396. [self verifyInstallationAuthCompletion];
  397. [self verifyInstallationIdCompletion];
  398. [self verifyUrlSessionResponseWithData];
  399. OCMVerify([fakeResponse statusCode]);
  400. }
  401. - (void)testFetchReleasesWithCompletionParsingFailure {
  402. NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
  403. OCMStub([fakeResponse statusCode]).andReturn(200);
  404. [self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
  405. [self mockInstallationIdCompletion:_mockInstallationId error:nil];
  406. [self
  407. mockUrlSessionResponseWithData:[@"malformed{json[data" dataUsingEncoding:NSUTF8StringEncoding]
  408. response:fakeResponse
  409. error:nil];
  410. XCTestExpectation *expectation =
  411. [self expectationWithDescription:@"Fetch releases rejects with a parsing failure."];
  412. [FIRFADApiService
  413. fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
  414. XCTAssertNil(releases);
  415. XCTAssertNotNil(error);
  416. XCTAssertEqual([error code], FIRApiErrorParseFailure);
  417. [expectation fulfill];
  418. }];
  419. [self waitForExpectations:@[ expectation ] timeout:5.0];
  420. [self verifyInstallationAuthCompletion];
  421. [self verifyInstallationIdCompletion];
  422. [self verifyUrlSessionResponseWithData];
  423. OCMVerify([fakeResponse statusCode]);
  424. }
  425. @end