FIRGetOOBConfirmationCodeResponseTests.m 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. /*
  2. * Copyright 2017 Google
  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 FirebaseAuth;
  18. #import "FirebaseAuth/Sources/Backend/FIRAuthBackend.h"
  19. #import "FirebaseAuth/Tests/Unit/FIRFakeBackendRPCIssuer.h"
  20. /** @var kTestEmail
  21. @brief Testing user email adadress.
  22. */
  23. static NSString *const kTestEmail = @"test@gmail.com";
  24. /** @var kTestAccessToken
  25. @brief Testing access token.
  26. */
  27. static NSString *const kTestAccessToken = @"ACCESS_TOKEN";
  28. /** @var kTestAPIKey
  29. @brief Fake API key used for testing.
  30. */
  31. static NSString *const kTestAPIKey = @"APIKey";
  32. /** @var kTestFirebaseAppID
  33. @brief Fake Firebase app ID used for testing.
  34. */
  35. static NSString *const kTestFirebaseAppID = @"appID";
  36. /** @var kOOBCodeKey
  37. @brief The name of the field in the response JSON for the OOB code.
  38. */
  39. static NSString *const kOOBCodeKey = @"oobCode";
  40. /** @var kTestOOBCode
  41. @brief Fake OOB Code used for testing.
  42. */
  43. static NSString *const kTestOOBCode = @"OOBCode";
  44. /** @var kEmailNotFoundMessage
  45. @brief The value of the "message" field returned for an "email not found" error.
  46. */
  47. static NSString *const kEmailNotFoundMessage = @"EMAIL_NOT_FOUND: fake custom message";
  48. /** @var kMissingEmailErrorMessage
  49. @brief The value of the "message" field returned for a "missing email" error.
  50. */
  51. static NSString *const kMissingEmailErrorMessage = @"MISSING_EMAIL";
  52. /** @var kInvalidEmailErrorMessage
  53. @brief The error returned by the server if the email is invalid.
  54. */
  55. static NSString *const kInvalidEmailErrorMessage = @"INVALID_EMAIL:";
  56. /** @var kInvalidMessagePayloadErrorMessage
  57. @brief This is the prefix for the error message the server responds with if an invalid message
  58. payload was sent.
  59. */
  60. static NSString *const kInvalidMessagePayloadErrorMessage = @"INVALID_MESSAGE_PAYLOAD";
  61. /** @var kInvalidSenderErrorMessage
  62. @brief This is the prefix for the error message the server responds with if invalid sender is
  63. used to send the email for updating user's email address.
  64. */
  65. static NSString *const kInvalidSenderErrorMessage = @"INVALID_SENDER";
  66. /** @var kMissingIosBundleIDErrorMessage
  67. @brief This is the error message the server will respond with if iOS bundle ID is missing but
  68. the iOS App store ID is provided.
  69. */
  70. static NSString *const kMissingIosBundleIDErrorMessage = @"MISSING_IOS_BUNDLE_ID";
  71. /** @var kMissingAndroidPackageNameErrorMessage
  72. @brief This is the error message the server will respond with if Android Package Name is missing
  73. but the flag indicating the app should be installed is set to true.
  74. */
  75. static NSString *const kMissingAndroidPackageNameErrorMessage = @"MISSING_ANDROID_PACKAGE_NAME";
  76. /** @var kUnauthorizedDomainErrorMessage
  77. @brief This is the error message the server will respond with if the domain of the continue URL
  78. specified is not allowlisted in the Firebase console.
  79. */
  80. static NSString *const kUnauthorizedDomainErrorMessage = @"UNAUTHORIZED_DOMAIN";
  81. /** @var kInvalidRecipientEmailErrorMessage
  82. @brief This is the prefix for the error message the server responds with if the recipient email
  83. is invalid.
  84. */
  85. static NSString *const kInvalidRecipientEmailErrorMessage = @"INVALID_RECIPIENT_EMAIL";
  86. /** @var kInvalidContinueURIErrorMessage
  87. @brief This is the error returned by the backend if the continue URL provided in the request
  88. is invalid.
  89. */
  90. static NSString *const kInvalidContinueURIErrorMessage = @"INVALID_CONTINUE_URI";
  91. /** @var kMissingContinueURIErrorMessage
  92. @brief This is the error message the server will respond with if there was no continue URI
  93. present in a request that required one.
  94. */
  95. static NSString *const kMissingContinueURIErrorMessage = @"MISSING_CONTINUE_URI";
  96. /** @var kIosBundleID
  97. @brief Fake iOS bundle ID for testing.
  98. */
  99. static NSString *const kIosBundleID = @"testBundleID";
  100. /** @class FIRGetOOBConfirmationCodeResponseTests
  101. @brief Tests for @c FIRGetOOBConfirmationCodeResponse.
  102. */
  103. @interface FIRGetOOBConfirmationCodeResponseTests : XCTestCase
  104. @end
  105. @implementation FIRGetOOBConfirmationCodeResponseTests {
  106. /** @var _RPCIssuer
  107. @brief This backend RPC issuer is used to fake network responses for each test in the suite.
  108. In the @c setUp method we initialize this and set @c FIRAuthBackend's RPC issuer to it.
  109. */
  110. FIRFakeBackendRPCIssuer *_RPCIssuer;
  111. /** @var _requestConfiguration
  112. @brief This is the request configuration used for testing.
  113. */
  114. FIRAuthRequestConfiguration *_requestConfiguration;
  115. }
  116. - (void)setUp {
  117. [super setUp];
  118. FIRFakeBackendRPCIssuer *RPCIssuer = [[FIRFakeBackendRPCIssuer alloc] init];
  119. [FIRAuthBackend setDefaultBackendImplementationWithRPCIssuer:RPCIssuer];
  120. _RPCIssuer = RPCIssuer;
  121. _requestConfiguration = [[FIRAuthRequestConfiguration alloc] initWithAPIKey:kTestAPIKey
  122. appID:kTestFirebaseAppID];
  123. }
  124. - (void)tearDown {
  125. _requestConfiguration = nil;
  126. _RPCIssuer = nil;
  127. [FIRAuthBackend setDefaultBackendImplementationWithRPCIssuer:nil];
  128. [super tearDown];
  129. }
  130. /** @fn testSuccessfulPasswordResetResponse
  131. @brief This test simulates a complete password reset response (with OOB Code) and makes sure
  132. it succeeds, and we get the OOB Code decoded correctly.
  133. */
  134. - (void)testSuccessfulPasswordResetResponse {
  135. FIRGetOOBConfirmationCodeRequest *request =
  136. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  137. actionCodeSettings:[self fakeActionCodeSettings]
  138. requestConfiguration:_requestConfiguration];
  139. __block BOOL callbackInvoked;
  140. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  141. __block NSError *RPCError;
  142. [FIRAuthBackend getOOBConfirmationCode:request
  143. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  144. NSError *_Nullable error) {
  145. callbackInvoked = YES;
  146. RPCResponse = response;
  147. RPCError = error;
  148. }];
  149. [_RPCIssuer respondWithJSON:@{kOOBCodeKey : kTestOOBCode}];
  150. XCTAssert(callbackInvoked);
  151. XCTAssertNil(RPCError);
  152. XCTAssertNotNil(RPCResponse);
  153. XCTAssertEqualObjects(RPCResponse.OOBCode, kTestOOBCode);
  154. }
  155. /** @fn testSuccessfulPasswordResetResponseWithoutOOBCode
  156. @brief This test simulates a password reset request where we don't receive the optional OOBCode
  157. response value. It should still succeed.
  158. */
  159. - (void)testSuccessfulPasswordResetResponseWithoutOOBCode {
  160. FIRGetOOBConfirmationCodeRequest *request =
  161. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  162. actionCodeSettings:[self fakeActionCodeSettings]
  163. requestConfiguration:_requestConfiguration];
  164. __block BOOL callbackInvoked;
  165. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  166. __block NSError *RPCError;
  167. [FIRAuthBackend getOOBConfirmationCode:request
  168. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  169. NSError *_Nullable error) {
  170. callbackInvoked = YES;
  171. RPCResponse = response;
  172. RPCError = error;
  173. }];
  174. [_RPCIssuer respondWithJSON:@{}];
  175. XCTAssert(callbackInvoked);
  176. XCTAssertNil(RPCError);
  177. XCTAssertNotNil(RPCResponse);
  178. XCTAssertNil(RPCResponse.OOBCode);
  179. }
  180. /** @fn testEmailNotFoundError
  181. @brief This test checks for email not found responses, and makes sure they are decoded to the
  182. correct error response.
  183. */
  184. - (void)testEmailNotFoundError {
  185. FIRGetOOBConfirmationCodeRequest *request =
  186. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  187. actionCodeSettings:[self fakeActionCodeSettings]
  188. requestConfiguration:_requestConfiguration];
  189. __block BOOL callbackInvoked;
  190. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  191. __block NSError *RPCError;
  192. [FIRAuthBackend getOOBConfirmationCode:request
  193. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  194. NSError *_Nullable error) {
  195. callbackInvoked = YES;
  196. RPCResponse = response;
  197. RPCError = error;
  198. }];
  199. [_RPCIssuer respondWithServerErrorMessage:kEmailNotFoundMessage];
  200. XCTAssert(callbackInvoked);
  201. XCTAssertNotNil(RPCError);
  202. XCTAssertEqualObjects(RPCError.domain, [FIRAuthErrors FIRAuthErrorDomain]);
  203. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeUserNotFound);
  204. XCTAssertNil(RPCResponse);
  205. }
  206. /** @fn testMissingEmailError
  207. @brief This test checks for missing email responses, and makes sure they are decoded to the
  208. correct error response.
  209. */
  210. - (void)testMissingEmailError {
  211. FIRGetOOBConfirmationCodeRequest *request = [FIRGetOOBConfirmationCodeRequest
  212. verifyEmailRequestWithAccessToken:kTestAccessToken
  213. actionCodeSettings:[self fakeActionCodeSettings]
  214. requestConfiguration:_requestConfiguration];
  215. __block BOOL callbackInvoked;
  216. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  217. __block NSError *RPCError;
  218. [FIRAuthBackend getOOBConfirmationCode:request
  219. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  220. NSError *_Nullable error) {
  221. callbackInvoked = YES;
  222. RPCResponse = response;
  223. RPCError = error;
  224. }];
  225. [_RPCIssuer respondWithServerErrorMessage:kMissingEmailErrorMessage];
  226. XCTAssert(callbackInvoked);
  227. XCTAssertNotNil(RPCError);
  228. XCTAssertEqualObjects(RPCError.domain, [FIRAuthErrors FIRAuthErrorDomain]);
  229. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeMissingEmail);
  230. XCTAssertNil(RPCResponse);
  231. }
  232. /** @fn testInvalidEmailError
  233. @brief This test checks for the INVALID_EMAIL error message from the backend.
  234. */
  235. - (void)testInvalidEmailError {
  236. FIRGetOOBConfirmationCodeRequest *request =
  237. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  238. actionCodeSettings:[self fakeActionCodeSettings]
  239. requestConfiguration:_requestConfiguration];
  240. __block BOOL callbackInvoked;
  241. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  242. __block NSError *RPCError;
  243. [FIRAuthBackend getOOBConfirmationCode:request
  244. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  245. NSError *_Nullable error) {
  246. callbackInvoked = YES;
  247. RPCResponse = response;
  248. RPCError = error;
  249. }];
  250. [_RPCIssuer respondWithServerErrorMessage:kInvalidEmailErrorMessage];
  251. XCTAssert(callbackInvoked);
  252. XCTAssertNotNil(RPCError);
  253. XCTAssertEqualObjects(RPCError.domain, [FIRAuthErrors FIRAuthErrorDomain]);
  254. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeInvalidEmail);
  255. XCTAssertNil(RPCResponse);
  256. }
  257. /** @fn testInvalidMessagePayloadError
  258. @brief Tests for @c FIRAuthErrorCodeInvalidMessagePayload.
  259. */
  260. - (void)testInvalidMessagePayloadError {
  261. FIRGetOOBConfirmationCodeRequest *request =
  262. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  263. actionCodeSettings:[self fakeActionCodeSettings]
  264. requestConfiguration:_requestConfiguration];
  265. __block BOOL callbackInvoked;
  266. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  267. __block NSError *RPCError;
  268. [FIRAuthBackend getOOBConfirmationCode:request
  269. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  270. NSError *_Nullable error) {
  271. callbackInvoked = YES;
  272. RPCResponse = response;
  273. RPCError = error;
  274. }];
  275. [_RPCIssuer respondWithServerErrorMessage:kInvalidMessagePayloadErrorMessage];
  276. XCTAssert(callbackInvoked);
  277. XCTAssertNil(RPCResponse);
  278. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeInvalidMessagePayload);
  279. }
  280. /** @fn testInvalidSenderError
  281. @brief Tests for @c FIRAuthErrorCodeInvalidSender.
  282. */
  283. - (void)testInvalidSenderError {
  284. FIRGetOOBConfirmationCodeRequest *request =
  285. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  286. actionCodeSettings:[self fakeActionCodeSettings]
  287. requestConfiguration:_requestConfiguration];
  288. __block BOOL callbackInvoked;
  289. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  290. __block NSError *RPCError;
  291. [FIRAuthBackend getOOBConfirmationCode:request
  292. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  293. NSError *_Nullable error) {
  294. callbackInvoked = YES;
  295. RPCResponse = response;
  296. RPCError = error;
  297. }];
  298. [_RPCIssuer respondWithServerErrorMessage:kInvalidSenderErrorMessage];
  299. XCTAssert(callbackInvoked);
  300. XCTAssertNil(RPCResponse);
  301. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeInvalidSender);
  302. }
  303. /** @fn testMissingIosBundleIDError
  304. @brief Tests for @c FIRAuthErrorCodeMissingIosBundleID.
  305. */
  306. - (void)testMissingIosBundleIDError {
  307. FIRGetOOBConfirmationCodeRequest *request =
  308. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  309. actionCodeSettings:[self fakeActionCodeSettings]
  310. requestConfiguration:_requestConfiguration];
  311. __block BOOL callbackInvoked;
  312. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  313. __block NSError *RPCError;
  314. [FIRAuthBackend getOOBConfirmationCode:request
  315. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  316. NSError *_Nullable error) {
  317. callbackInvoked = YES;
  318. RPCResponse = response;
  319. RPCError = error;
  320. }];
  321. [_RPCIssuer respondWithServerErrorMessage:kMissingIosBundleIDErrorMessage];
  322. XCTAssert(callbackInvoked);
  323. XCTAssertNil(RPCResponse);
  324. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeMissingIosBundleID);
  325. }
  326. /** @fn testMissingAndroidPackageNameError
  327. @brief Tests for @c FIRAuthErrorCodeMissingAndroidPackageName.
  328. */
  329. - (void)testMissingAndroidPackageNameError {
  330. FIRGetOOBConfirmationCodeRequest *request =
  331. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  332. actionCodeSettings:[self fakeActionCodeSettings]
  333. requestConfiguration:_requestConfiguration];
  334. __block BOOL callbackInvoked;
  335. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  336. __block NSError *RPCError;
  337. [FIRAuthBackend getOOBConfirmationCode:request
  338. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  339. NSError *_Nullable error) {
  340. callbackInvoked = YES;
  341. RPCResponse = response;
  342. RPCError = error;
  343. }];
  344. [_RPCIssuer respondWithServerErrorMessage:kMissingAndroidPackageNameErrorMessage];
  345. XCTAssert(callbackInvoked);
  346. XCTAssertNil(RPCResponse);
  347. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeMissingAndroidPackageName);
  348. }
  349. /** @fn testUnauthorizedDomainError
  350. @brief Tests for @c FIRAuthErrorCodeUnauthorizedDomain.
  351. */
  352. - (void)testUnauthorizedDomainError {
  353. FIRGetOOBConfirmationCodeRequest *request =
  354. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  355. actionCodeSettings:[self fakeActionCodeSettings]
  356. requestConfiguration:_requestConfiguration];
  357. __block BOOL callbackInvoked;
  358. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  359. __block NSError *RPCError;
  360. [FIRAuthBackend getOOBConfirmationCode:request
  361. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  362. NSError *_Nullable error) {
  363. callbackInvoked = YES;
  364. RPCResponse = response;
  365. RPCError = error;
  366. }];
  367. [_RPCIssuer respondWithServerErrorMessage:kUnauthorizedDomainErrorMessage];
  368. XCTAssert(callbackInvoked);
  369. XCTAssertNil(RPCResponse);
  370. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeUnauthorizedDomain);
  371. }
  372. /** @fn testInvalidContinueURIError
  373. @brief Tests for @c FIRAuthErrorCodeInvalidContinueAuthURI.
  374. */
  375. - (void)testInvalidContinueURIError {
  376. FIRGetOOBConfirmationCodeRequest *request =
  377. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  378. actionCodeSettings:[self fakeActionCodeSettings]
  379. requestConfiguration:_requestConfiguration];
  380. __block BOOL callbackInvoked;
  381. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  382. __block NSError *RPCError;
  383. [FIRAuthBackend getOOBConfirmationCode:request
  384. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  385. NSError *_Nullable error) {
  386. callbackInvoked = YES;
  387. RPCResponse = response;
  388. RPCError = error;
  389. }];
  390. [_RPCIssuer respondWithServerErrorMessage:kInvalidContinueURIErrorMessage];
  391. XCTAssert(callbackInvoked);
  392. XCTAssertNil(RPCResponse);
  393. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeInvalidContinueURI);
  394. }
  395. /** @fn testMissingContinueURIError
  396. @brief Tests for @c FIRAuthErrorCodeMissingContinueURI.
  397. */
  398. - (void)testMissingContinueURIError {
  399. FIRGetOOBConfirmationCodeRequest *request =
  400. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  401. actionCodeSettings:[self fakeActionCodeSettings]
  402. requestConfiguration:_requestConfiguration];
  403. __block BOOL callbackInvoked;
  404. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  405. __block NSError *RPCError;
  406. [FIRAuthBackend getOOBConfirmationCode:request
  407. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  408. NSError *_Nullable error) {
  409. callbackInvoked = YES;
  410. RPCResponse = response;
  411. RPCError = error;
  412. }];
  413. [_RPCIssuer respondWithServerErrorMessage:kMissingContinueURIErrorMessage];
  414. XCTAssert(callbackInvoked);
  415. XCTAssertNil(RPCResponse);
  416. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeMissingContinueURI);
  417. }
  418. /** @fn testInvalidRecipientEmailError
  419. @brief Tests for @c FIRAuthErrorCodeInvalidRecipientEmail.
  420. */
  421. - (void)testInvalidRecipientEmailError {
  422. FIRGetOOBConfirmationCodeRequest *request =
  423. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  424. actionCodeSettings:[self fakeActionCodeSettings]
  425. requestConfiguration:_requestConfiguration];
  426. __block BOOL callbackInvoked;
  427. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  428. __block NSError *RPCError;
  429. [FIRAuthBackend getOOBConfirmationCode:request
  430. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  431. NSError *_Nullable error) {
  432. callbackInvoked = YES;
  433. RPCResponse = response;
  434. RPCError = error;
  435. }];
  436. [_RPCIssuer respondWithServerErrorMessage:kInvalidRecipientEmailErrorMessage];
  437. XCTAssert(callbackInvoked);
  438. XCTAssertNil(RPCResponse);
  439. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeInvalidRecipientEmail);
  440. }
  441. /** @fn testSuccessfulEmailVerificationResponse
  442. @brief This test is really not much different than the original test for password reset. But
  443. it's here for completeness sake.
  444. */
  445. - (void)testSuccessfulEmailVerificationResponse {
  446. FIRGetOOBConfirmationCodeRequest *request =
  447. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  448. actionCodeSettings:[self fakeActionCodeSettings]
  449. requestConfiguration:_requestConfiguration];
  450. __block BOOL callbackInvoked;
  451. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  452. __block NSError *RPCError;
  453. [FIRAuthBackend getOOBConfirmationCode:request
  454. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  455. NSError *_Nullable error) {
  456. callbackInvoked = YES;
  457. RPCResponse = response;
  458. RPCError = error;
  459. }];
  460. [_RPCIssuer respondWithJSON:@{kOOBCodeKey : kTestOOBCode}];
  461. XCTAssert(callbackInvoked);
  462. XCTAssertNil(RPCError);
  463. XCTAssertNotNil(RPCResponse);
  464. XCTAssertEqualObjects(RPCResponse.OOBCode, kTestOOBCode);
  465. }
  466. #pragma mark - Helpers
  467. /** @fn fakeActionCodeSettings
  468. @brief Constructs and returns a fake instance of @c FIRActionCodeSettings for testing.
  469. @return An instance of @c FIRActionCodeSettings for testing.
  470. */
  471. - (FIRActionCodeSettings *)fakeActionCodeSettings {
  472. FIRActionCodeSettings *actionCodeSettings = [[FIRActionCodeSettings alloc] init];
  473. [actionCodeSettings setIOSBundleID:kIosBundleID];
  474. return actionCodeSettings;
  475. }
  476. @end