EmailLinkSignInTests.swift 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright 2023 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. import Foundation
  15. import XCTest
  16. @testable import FirebaseAuth
  17. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  18. class EmailLinkSignInTests: RPCBaseTests {
  19. /** @var kTestEmail
  20. @brief The key for the "email" value in the request.
  21. */
  22. let kTestEmail = "TestEmail@email.com"
  23. /** @var kTestOOBCode
  24. @brief The test value for the "oobCode" in the request.
  25. */
  26. let kTestOOBCode = "TestOOBCode"
  27. /** @var kExpectedAPIURL
  28. @brief The expected URL for the test calls.
  29. */
  30. let kExpectedAPIURL =
  31. "https://www.googleapis.com/identitytoolkit/v3/relyingparty/emailLinkSignin?key=APIKey"
  32. /** @var kEmailKey
  33. @brief The key for the "identifier" value in the request.
  34. */
  35. let kEmailKey = "email"
  36. /** @var kEmailLinkKey
  37. @brief The key for the "oobCode" value in the request.
  38. */
  39. let kOOBCodeKey = "oobCode"
  40. /** @var kIDTokenKey
  41. @brief The key for the "IDToken" value in the request.
  42. */
  43. let kIDTokenKey = "idToken"
  44. /** @fn testEmailLinkRequestCreation
  45. @brief Tests the email link sign-in request with mandatory parameters.
  46. */
  47. func testEmailLinkRequest() {
  48. AuthBackend.post(with: makeEmailLinkSignInRequest()) { response, error in
  49. XCTFail("No explicit response from the fake backend.")
  50. }
  51. XCTAssertEqual(rpcIssuer?.requestURL?.absoluteString, kExpectedAPIURL)
  52. guard let requestDictionary = rpcIssuer?.decodedRequest as? [AnyHashable: String] else {
  53. XCTFail("decodedRequest is not a dictionary")
  54. return
  55. }
  56. XCTAssertEqual(requestDictionary[kEmailKey], kTestEmail)
  57. XCTAssertEqual(requestDictionary[kOOBCodeKey], kTestOOBCode)
  58. XCTAssertNil(requestDictionary[kIDTokenKey])
  59. }
  60. /** @fn testEmailLinkRequestCreationOptional
  61. @brief Tests the email link sign-in request with mandatory parameters and optional ID token.
  62. */
  63. func testEmailLinkRequestCreationOptional() {
  64. let kTestIDToken = "testIDToken"
  65. let request = makeEmailLinkSignInRequest()
  66. request.idToken = kTestIDToken
  67. AuthBackend.post(with: request) { response, error in
  68. XCTFail("No explicit response from the fake backend.")
  69. }
  70. XCTAssertEqual(rpcIssuer?.requestURL?.absoluteString, kExpectedAPIURL)
  71. guard let requestDictionary = rpcIssuer?.decodedRequest as? [AnyHashable: String] else {
  72. XCTFail("decodedRequest is not a dictionary")
  73. return
  74. }
  75. XCTAssertEqual(requestDictionary[kEmailKey], kTestEmail)
  76. XCTAssertEqual(requestDictionary[kOOBCodeKey], kTestOOBCode)
  77. XCTAssertEqual(requestDictionary[kIDTokenKey], kTestIDToken)
  78. }
  79. func testEmailLinkSignInErrors() throws {
  80. let kInvalidEmailErrorMessage = "INVALID_EMAIL"
  81. try checkBackendError(
  82. request: makeEmailLinkSignInRequest(),
  83. message: kInvalidEmailErrorMessage,
  84. errorCode: AuthErrorCode.invalidEmail
  85. )
  86. }
  87. /** @fn testSuccessfulEmailLinkSignInResponse
  88. @brief Tests a successful email link sign-in response.
  89. */
  90. func testSuccessfulEmailLinkSignInResponse() throws {
  91. let kTestIDTokenResponse = "fakeToken"
  92. let kTestEmailResponse = "fakeEmail@example.com"
  93. let kTestTokenExpirationTimeInterval: Double = 55 * 60
  94. let kTestRefreshToken = "testRefreshToken"
  95. var callbackInvoked = false
  96. var rpcResponse: EmailLinkSignInResponse?
  97. var rpcError: NSError?
  98. AuthBackend.post(with: makeEmailLinkSignInRequest()) { response, error in
  99. callbackInvoked = true
  100. rpcResponse = response
  101. rpcError = error as? NSError
  102. }
  103. try rpcIssuer?.respond(withJSON: ["idToken": kTestIDTokenResponse,
  104. "email": kTestEmailResponse,
  105. "isNewUser": true,
  106. "expiresIn": "\(kTestTokenExpirationTimeInterval)",
  107. "refreshToken": kTestRefreshToken])
  108. XCTAssert(callbackInvoked)
  109. XCTAssertNil(rpcError)
  110. let response = try XCTUnwrap(rpcResponse)
  111. XCTAssertEqual(response.idToken, kTestIDTokenResponse)
  112. XCTAssertEqual(response.email, kTestEmailResponse)
  113. XCTAssertEqual(response.refreshToken, kTestRefreshToken)
  114. XCTAssertTrue(response.isNewUser)
  115. XCTAssertEqual(response.idToken, kTestIDTokenResponse)
  116. let expirationTimeInterval = try XCTUnwrap(response.approximateExpirationDate)
  117. .timeIntervalSinceNow
  118. let testTimeInterval = Date(timeIntervalSinceNow: kTestTokenExpirationTimeInterval)
  119. .timeIntervalSinceNow
  120. let timeIntervalDifference = abs(expirationTimeInterval - testTimeInterval)
  121. XCTAssertLessThan(timeIntervalDifference, 0.001)
  122. }
  123. private func makeEmailLinkSignInRequest() -> EmailLinkSignInRequest {
  124. return EmailLinkSignInRequest(email: kTestEmail,
  125. oobCode: kTestOOBCode,
  126. requestConfiguration: makeRequestConfiguration())
  127. }
  128. }