PasswordResetTests.swift 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. // Copyright 2020 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 Combine
  16. import XCTest
  17. import FirebaseAuth
  18. class PasswordResetTests: XCTestCase {
  19. override class func setUp() {
  20. FirebaseApp.configureForTests()
  21. }
  22. override class func tearDown() {
  23. FirebaseApp.app()?.delete { success in
  24. if success {
  25. print("Shut down app successfully.")
  26. } else {
  27. print("💥 There was a problem when shutting down the app..")
  28. }
  29. }
  30. }
  31. override func setUp() {
  32. do {
  33. try Auth.auth().signOut()
  34. } catch {}
  35. }
  36. static let apiKey = Credentials.apiKey
  37. static let fakeEmail = "fakeEmail"
  38. static let fakeNewEmail = "fakeNewEmail"
  39. static let fakeCode = "fakeCode"
  40. static let fakeNewPassword = "fakeNewPassword"
  41. static let passwordResetRequestType = "PASSWORD_RESET"
  42. static let verifyEmailRequestType = "VERIFY_EMAIL"
  43. func testResetPassword() {
  44. // given
  45. class MockResetPasswordResponse: FIRResetPasswordResponse {
  46. override var email: String { return PasswordResetTests.fakeEmail }
  47. }
  48. class MockAuthBackend: AuthBackendImplementationMock {
  49. override func resetPassword(_ request: FIRResetPasswordRequest,
  50. callback: @escaping FIRResetPasswordCallback) {
  51. XCTAssertEqual(request.apiKey, PasswordResetTests.apiKey)
  52. XCTAssertEqual(request.oobCode, PasswordResetTests.fakeCode)
  53. XCTAssertEqual(request.updatedPassword, PasswordResetTests.fakeNewPassword)
  54. callback(MockResetPasswordResponse(), nil)
  55. }
  56. }
  57. FIRAuthBackend.setBackendImplementation(MockAuthBackend())
  58. var cancellables = Set<AnyCancellable>()
  59. let confirmPasswordResetExpectation = expectation(description: "Password reset confirmed")
  60. // when
  61. Auth.auth()
  62. .confirmPasswordReset(
  63. withCode: PasswordResetTests.fakeCode,
  64. newPassword: PasswordResetTests.fakeNewPassword
  65. )
  66. .sink(receiveCompletion: { completion in
  67. switch completion {
  68. case .finished:
  69. print("Finished")
  70. case let .failure(error):
  71. XCTFail("💥 Something went wrong: \(error)")
  72. }
  73. }, receiveValue: {
  74. confirmPasswordResetExpectation.fulfill()
  75. })
  76. .store(in: &cancellables)
  77. // then
  78. wait(for: [confirmPasswordResetExpectation], timeout: expectationTimeout)
  79. }
  80. func testVerifyPasswordResetCode() {
  81. // given
  82. class MockResetPasswordResponse: FIRResetPasswordResponse {
  83. override var email: String { return PasswordResetTests.fakeEmail }
  84. override var requestType: String { return PasswordResetTests.passwordResetRequestType }
  85. }
  86. class MockAuthBackend: AuthBackendImplementationMock {
  87. override func resetPassword(_ request: FIRResetPasswordRequest,
  88. callback: @escaping FIRResetPasswordCallback) {
  89. XCTAssertEqual(request.apiKey, PasswordResetTests.apiKey)
  90. XCTAssertEqual(request.oobCode, PasswordResetTests.fakeCode)
  91. callback(MockResetPasswordResponse(), nil)
  92. }
  93. }
  94. FIRAuthBackend.setBackendImplementation(MockAuthBackend())
  95. var cancellables = Set<AnyCancellable>()
  96. let verifyPasswordResetCodeExpectation =
  97. expectation(description: "Password reset code verified")
  98. // when
  99. Auth.auth()
  100. .verifyPasswordResetCode(PasswordResetTests.fakeCode)
  101. .sink { completion in
  102. switch completion {
  103. case .finished:
  104. print("Finished")
  105. case let .failure(error):
  106. XCTFail("💥 Something went wrong: \(error)")
  107. }
  108. } receiveValue: { email in
  109. verifyPasswordResetCodeExpectation.fulfill()
  110. }
  111. .store(in: &cancellables)
  112. // then
  113. wait(for: [verifyPasswordResetCodeExpectation], timeout: expectationTimeout)
  114. }
  115. func testCheckActionCode() {
  116. // given
  117. class MockResetPasswordResponse: FIRResetPasswordResponse {
  118. override var email: String { return PasswordResetTests.fakeEmail }
  119. override var verifiedEmail: String { return PasswordResetTests.fakeNewEmail }
  120. override var requestType: String { return PasswordResetTests.verifyEmailRequestType }
  121. }
  122. class MockAuthBackend: AuthBackendImplementationMock {
  123. override func resetPassword(_ request: FIRResetPasswordRequest,
  124. callback: @escaping FIRResetPasswordCallback) {
  125. XCTAssertEqual(request.apiKey, PasswordResetTests.apiKey)
  126. XCTAssertEqual(request.oobCode, PasswordResetTests.fakeCode)
  127. callback(MockResetPasswordResponse(), nil)
  128. }
  129. }
  130. FIRAuthBackend.setBackendImplementation(MockAuthBackend())
  131. var cancellables = Set<AnyCancellable>()
  132. let checkActionCodeExpectation = expectation(description: "Action code checked")
  133. // when
  134. Auth.auth()
  135. .checkActionCode(code: PasswordResetTests.fakeCode)
  136. .sink { completion in
  137. switch completion {
  138. case .finished:
  139. print("Finished")
  140. case let .failure(error):
  141. XCTFail("💥 Something went wrong: \(error)")
  142. }
  143. } receiveValue: { actionCodeInfo in
  144. XCTAssertEqual(actionCodeInfo.operation, ActionCodeOperation.verifyEmail)
  145. XCTAssertEqual(actionCodeInfo.email, PasswordResetTests.fakeNewEmail)
  146. checkActionCodeExpectation.fulfill()
  147. }
  148. .store(in: &cancellables)
  149. // then
  150. wait(for: [checkActionCodeExpectation], timeout: expectationTimeout)
  151. }
  152. public func testApplyActionCode() {
  153. // given
  154. class MockSetAccountInfoResponse: FIRSetAccountInfoResponse {}
  155. class MockAuthBackend: AuthBackendImplementationMock {
  156. override func setAccountInfo(_ request: FIRSetAccountInfoRequest,
  157. callback: @escaping FIRSetAccountInfoResponseCallback) {
  158. callback(MockSetAccountInfoResponse(), nil)
  159. }
  160. }
  161. FIRAuthBackend.setBackendImplementation(MockAuthBackend())
  162. var cancellables = Set<AnyCancellable>()
  163. let applyActionCodeExpectation = expectation(description: "Action code applied")
  164. // when
  165. Auth.auth()
  166. .applyActionCode(code: PasswordResetTests.fakeCode)
  167. .sink { completion in
  168. switch completion {
  169. case .finished:
  170. print("Finished")
  171. case let .failure(error):
  172. XCTFail("💥 Something went wrong: \(error)")
  173. }
  174. } receiveValue: {
  175. applyActionCodeExpectation.fulfill()
  176. }
  177. .store(in: &cancellables)
  178. // then
  179. wait(for: [applyActionCodeExpectation], timeout: expectationTimeout)
  180. }
  181. func testSendPasswordResetEmail() {
  182. // given
  183. class MockAuthBackend: AuthBackendImplementationMock {
  184. override func getOOBConfirmationCode(_ request: FIRGetOOBConfirmationCodeRequest,
  185. callback: @escaping FIRGetOOBConfirmationCodeResponseCallback) {
  186. XCTAssertEqual(request.apiKey, PasswordResetTests.apiKey)
  187. XCTAssertEqual(request.email, PasswordResetTests.fakeEmail)
  188. callback(FIRGetOOBConfirmationCodeResponse(), nil)
  189. }
  190. }
  191. FIRAuthBackend.setBackendImplementation(MockAuthBackend())
  192. var cancellables = Set<AnyCancellable>()
  193. let sendPasswordResetExpectation = expectation(description: "Password reset sent")
  194. // when
  195. Auth.auth()
  196. .sendPasswordReset(withEmail: PasswordResetTests.fakeEmail)
  197. .sink { completion in
  198. switch completion {
  199. case .finished:
  200. print("Finished")
  201. case let .failure(error):
  202. XCTFail("💥 Something went wrong: \(error)")
  203. }
  204. } receiveValue: {
  205. sendPasswordResetExpectation.fulfill()
  206. }
  207. .store(in: &cancellables)
  208. // then
  209. wait(for: [sendPasswordResetExpectation], timeout: expectationTimeout)
  210. }
  211. }