From a8d5a6c522f99c4dcd570e199bb4932b4490ac30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bispo?= Date: Thu, 19 Sep 2024 16:54:29 +0100 Subject: [PATCH] [PM-12012] Save region during account creation (#946) --- .../API/Auth/Fixtures/APITestData+Auth.swift | 1 + .../Core/Platform/Services/StateService.swift | 25 ++++++++ .../Platform/Services/StateServiceTests.swift | 23 ++++++++ .../Services/Stores/AppSettingsStore.swift | 29 ++++++++++ .../Stores/AppSettingsStoreTests.swift | 37 ++++++++++++ .../TestHelpers/MockAppSettingsStore.swift | 9 +++ .../TestHelpers/MockStateService.swift | 9 +++ .../CompleteRegistrationProcessor.swift | 27 +++++++-- .../CompleteRegistrationProcessorTests.swift | 41 ++++++++++--- .../StartRegistrationProcessor.swift | 13 +++++ .../StartRegistrationProcessorTests.swift | 58 +++++++++++++++++++ .../en.lproj/Localizable.strings | 2 + 12 files changed, 263 insertions(+), 11 deletions(-) diff --git a/BitwardenShared/Core/Auth/Services/API/Auth/Fixtures/APITestData+Auth.swift b/BitwardenShared/Core/Auth/Services/API/Auth/Fixtures/APITestData+Auth.swift index 186ec174f..c108fab03 100644 --- a/BitwardenShared/Core/Auth/Services/API/Auth/Fixtures/APITestData+Auth.swift +++ b/BitwardenShared/Core/Auth/Services/API/Auth/Fixtures/APITestData+Auth.swift @@ -4,6 +4,7 @@ extension APITestData { static let authRequestSuccess = loadFromJsonBundle(resource: "AuthRequest") static let authRequestsSuccess = loadFromJsonBundle(resource: "AuthRequests") static let emptyResponse = APITestData(data: "{}".data(using: .utf8)!) + static let nilResponse = APITestData(data: "".data(using: .utf8)!) static let identityTokenSuccess = loadFromJsonBundle(resource: "IdentityTokenSuccess") static let identityTokenWithMasterPasswordPolicy = loadFromJsonBundle( resource: "IdentityTokenWithMasterPasswordPolicy" diff --git a/BitwardenShared/Core/Platform/Services/StateService.swift b/BitwardenShared/Core/Platform/Services/StateService.swift index 5409945a9..e496600dc 100644 --- a/BitwardenShared/Core/Platform/Services/StateService.swift +++ b/BitwardenShared/Core/Platform/Services/StateService.swift @@ -231,6 +231,13 @@ protocol StateService: AnyObject { /// func getPreAuthEnvironmentUrls() async -> EnvironmentUrlData? + /// Gets the environment URLs for a given email during account creation. + /// + /// - Parameter email: The email used to start the account creation. + /// - Returns: The environment URLs used prior to start the account creation. + /// + func getAccountCreationEnvironmentUrls(email: String) async -> EnvironmentUrlData? + /// Gets the server config used by the app prior to the user authenticating. /// - Returns: The server config used prior to user authentication. func getPreAuthServerConfig() async -> ServerConfig? @@ -520,6 +527,13 @@ protocol StateService: AnyObject { /// func setPreAuthEnvironmentUrls(_ urls: EnvironmentUrlData) async + /// Sets the environment URLs for a given email during account creation. + /// - Parameters: + /// - urls: The environment urls used to start the account creation. + /// - email: The email used to start the account creation. + /// + func setAccountCreationEnvironmentUrls(urls: EnvironmentUrlData, email: String) async + /// Sets the server config used prior to user authentication /// - Parameter config: The server config to use prior to user authentication. func setPreAuthServerConfig(config: ServerConfig) async @@ -1290,6 +1304,10 @@ actor DefaultStateService: StateService { // swiftlint:disable:this type_body_le appSettingsStore.preAuthEnvironmentUrls } + func getAccountCreationEnvironmentUrls(email: String) async -> EnvironmentUrlData? { + appSettingsStore.accountCreationEnvironmentUrls(email: email) + } + func getPreAuthServerConfig() async -> ServerConfig? { appSettingsStore.preAuthServerConfig } @@ -1536,6 +1554,13 @@ actor DefaultStateService: StateService { // swiftlint:disable:this type_body_le appSettingsStore.preAuthEnvironmentUrls = urls } + func setAccountCreationEnvironmentUrls(urls: EnvironmentUrlData, email: String) async { + appSettingsStore.setAccountCreationEnvironmentUrls( + environmentUrlData: urls, + email: email + ) + } + func setPreAuthServerConfig(config: ServerConfig) async { appSettingsStore.preAuthServerConfig = config } diff --git a/BitwardenShared/Core/Platform/Services/StateServiceTests.swift b/BitwardenShared/Core/Platform/Services/StateServiceTests.swift index 047286aea..9968b3093 100644 --- a/BitwardenShared/Core/Platform/Services/StateServiceTests.swift +++ b/BitwardenShared/Core/Platform/Services/StateServiceTests.swift @@ -707,6 +707,21 @@ class StateServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body XCTAssertNil(urls) } + /// `getAccountCreationEnvironmentUrls` returns the saved pre-auth URLs for a given email. + func test_getAccountCreationEnvironmentUrls() async { + let email = "example@email.com" + let urls = EnvironmentUrlData(base: .example) + appSettingsStore.setAccountCreationEnvironmentUrls(environmentUrlData: urls, email: email) + let preAuthUrls = await subject.getAccountCreationEnvironmentUrls(email: email) + XCTAssertEqual(preAuthUrls, urls) + } + + /// `getAccountCreationEnvironmentUrls` returns `nil` if the URLs haven't been set for a given email. + func test_getAccountCreationEnvironmentUrls_notSet() async { + let urls = await subject.getAccountCreationEnvironmentUrls(email: "example@email.com") + XCTAssertNil(urls) + } + /// `getPreAuthServerConfig` returns the saved pre-auth server config. func test_getPreAuthServerConfig() async { let config = ServerConfig( @@ -1606,6 +1621,14 @@ class StateServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body XCTAssertEqual(appSettingsStore.preAuthEnvironmentUrls, urls) } + /// `test_setAccountCreationEnvironmentUrls` saves the pre-auth URLs for email for a given email. + func test_setAccountCreationEnvironmentUrls() async { + let email = "example@email.com" + let urls = EnvironmentUrlData(base: .example) + await subject.setAccountCreationEnvironmentUrls(urls: urls, email: email) + XCTAssertEqual(appSettingsStore.accountCreationEnvironmentUrls(email: email), urls) + } + /// `setPreAuthServerConfig(config:)` saves the pre-auth server config. func test_setPreAuthServerConfig() async { let config = ServerConfig( diff --git a/BitwardenShared/Core/Platform/Services/Stores/AppSettingsStore.swift b/BitwardenShared/Core/Platform/Services/Stores/AppSettingsStore.swift index 6ee2f449e..e90442866 100644 --- a/BitwardenShared/Core/Platform/Services/Stores/AppSettingsStore.swift +++ b/BitwardenShared/Core/Platform/Services/Stores/AppSettingsStore.swift @@ -190,6 +190,14 @@ protocol AppSettingsStore: AnyObject { /// func pinProtectedUserKey(userId: String) -> String? + /// Gets the environment URLs used to start the account creation flow. + /// + /// - Parameters: + /// - email: The email used to start the account creation. + /// - Returns: The environment URLs used prior to start the account creation. + /// + func accountCreationEnvironmentUrls(email: String) -> EnvironmentUrlData? + /// The server configuration. /// /// - Parameter userId: The user ID associated with the server config. @@ -344,6 +352,14 @@ protocol AppSettingsStore: AnyObject { /// func setPinProtectedUserKey(key: String?, userId: String) + /// Sets the environment URLs used to start the account creation flow. + /// + /// - Parameters: + /// - email: The user's email address. + /// - environmentUrlData: The environment data to be saved. + /// + func setAccountCreationEnvironmentUrls(environmentUrlData: EnvironmentUrlData, email: String) + /// Sets the server config. /// /// - Parameters: @@ -607,6 +623,7 @@ extension DefaultAppSettingsStore: AppSettingsStore { case passwordGenerationOptions(userId: String) case pinProtectedUserKey(userId: String) case preAuthEnvironmentUrls + case accountCreationEnvironmentUrls(email: String) case preAuthServerConfig case rememberedEmail case rememberedOrgIdentifier @@ -682,6 +699,8 @@ extension DefaultAppSettingsStore: AppSettingsStore { key = "pinKeyEncryptedUserKey_\(userId)" case .preAuthEnvironmentUrls: key = "preAuthEnvironmentUrls" + case let .accountCreationEnvironmentUrls(email): + key = "accountCreationEnvironmentUrls_\(email)" case .preAuthServerConfig: key = "preAuthServerConfig" case .rememberedEmail: @@ -870,6 +889,12 @@ extension DefaultAppSettingsStore: AppSettingsStore { fetch(for: .pinProtectedUserKey(userId: userId)) } + func accountCreationEnvironmentUrls(email: String) -> EnvironmentUrlData? { + fetch( + for: .accountCreationEnvironmentUrls(email: email) + ) + } + func serverConfig(userId: String) -> ServerConfig? { fetch(for: .serverConfig(userId: userId)) } @@ -952,6 +977,10 @@ extension DefaultAppSettingsStore: AppSettingsStore { store(key, for: .pinProtectedUserKey(userId: userId)) } + func setAccountCreationEnvironmentUrls(environmentUrlData: EnvironmentUrlData, email: String) { + store(environmentUrlData, for: .accountCreationEnvironmentUrls(email: email)) + } + func setServerConfig(_ config: ServerConfig?, userId: String) { store(config, for: .serverConfig(userId: userId)) } diff --git a/BitwardenShared/Core/Platform/Services/Stores/AppSettingsStoreTests.swift b/BitwardenShared/Core/Platform/Services/Stores/AppSettingsStoreTests.swift index e02bac120..7f51c2f12 100644 --- a/BitwardenShared/Core/Platform/Services/Stores/AppSettingsStoreTests.swift +++ b/BitwardenShared/Core/Platform/Services/Stores/AppSettingsStoreTests.swift @@ -616,6 +616,43 @@ class AppSettingsStoreTests: BitwardenTestCase { // swiftlint:disable:this type_ ) } + /// `accountCreationEnvironmentUrls` returns `nil` if there isn't a previously stored value. + func test_accountCreationEnvironmentUrls_isInitiallyNil() { + XCTAssertNil(subject.accountCreationEnvironmentUrls(email: "example@email.com")) + } + + /// `accountCreationEnvironmentUrls` can be used to get and set the persisted value in user defaults. + func test_accountCreationEnvironmentUrls_withValue() { + let email = "example@email.com" + subject.setAccountCreationEnvironmentUrls(environmentUrlData: .defaultUS, email: email) + XCTAssertEqual(subject.accountCreationEnvironmentUrls(email: email), .defaultUS) + try XCTAssertEqual( + JSONDecoder().decode( + EnvironmentUrlData.self, + from: XCTUnwrap( + userDefaults + .string(forKey: "bwPreferencesStorage:accountCreationEnvironmentUrls_\(email)")? + .data(using: .utf8) + ) + ), + .defaultUS + ) + + subject.setAccountCreationEnvironmentUrls(environmentUrlData: .defaultEU, email: email) + XCTAssertEqual(subject.accountCreationEnvironmentUrls(email: email), .defaultEU) + try XCTAssertEqual( + JSONDecoder().decode( + EnvironmentUrlData.self, + from: XCTUnwrap( + userDefaults + .string(forKey: "bwPreferencesStorage:accountCreationEnvironmentUrls_\(email)")? + .data(using: .utf8) + ) + ), + .defaultEU + ) + } + /// `preAuthServerConfig` is initially `nil` func test_preAuthServerConfig_isInitiallyNil() { XCTAssertNil(subject.preAuthServerConfig) diff --git a/BitwardenShared/Core/Platform/Services/Stores/TestHelpers/MockAppSettingsStore.swift b/BitwardenShared/Core/Platform/Services/Stores/TestHelpers/MockAppSettingsStore.swift index 8c58dbec8..3cd7d607a 100644 --- a/BitwardenShared/Core/Platform/Services/Stores/TestHelpers/MockAppSettingsStore.swift +++ b/BitwardenShared/Core/Platform/Services/Stores/TestHelpers/MockAppSettingsStore.swift @@ -37,6 +37,7 @@ class MockAppSettingsStore: AppSettingsStore { var notificationsLastRegistrationDates = [String: Date]() var passwordGenerationOptions = [String: PasswordGenerationOptions]() var pinProtectedUserKey = [String: String]() + var accountCreationEnvironmentUrls = [String: EnvironmentUrlData]() var serverConfig = [String: ServerConfig]() var shouldTrustDevice = [String: Bool?]() var timeoutAction = [String: Int]() @@ -118,6 +119,10 @@ class MockAppSettingsStore: AppSettingsStore { pinProtectedUserKey[userId] } + func accountCreationEnvironmentUrls(email: String) -> BitwardenShared.EnvironmentUrlData? { + accountCreationEnvironmentUrls[email] + } + func twoFactorToken(email: String) -> String? { twoFactorTokens[email] } @@ -202,6 +207,10 @@ class MockAppSettingsStore: AppSettingsStore { pinProtectedUserKey[userId] = key } + func setAccountCreationEnvironmentUrls(environmentUrlData: BitwardenShared.EnvironmentUrlData, email: String) { + accountCreationEnvironmentUrls[email] = environmentUrlData + } + func setServerConfig(_ config: ServerConfig?, userId: String) { serverConfig[userId] = config } diff --git a/BitwardenShared/Core/Platform/Services/TestHelpers/MockStateService.swift b/BitwardenShared/Core/Platform/Services/TestHelpers/MockStateService.swift index ee130b273..1f0b0254e 100644 --- a/BitwardenShared/Core/Platform/Services/TestHelpers/MockStateService.swift +++ b/BitwardenShared/Core/Platform/Services/TestHelpers/MockStateService.swift @@ -55,6 +55,7 @@ class MockStateService: StateService { // swiftlint:disable:this type_body_lengt var passwordGenerationOptions = [String: PasswordGenerationOptions]() var pinProtectedUserKeyValue = [String: String]() var preAuthEnvironmentUrls: EnvironmentUrlData? + var accountCreationEnvironmentUrls = [String: EnvironmentUrlData]() var preAuthServerConfig: ServerConfig? var rememberedOrgIdentifier: String? var showWebIcons = true @@ -255,6 +256,10 @@ class MockStateService: StateService { // swiftlint:disable:this type_body_lengt preAuthEnvironmentUrls } + func getAccountCreationEnvironmentUrls(email: String) async -> EnvironmentUrlData? { + accountCreationEnvironmentUrls[email] + } + func getPreAuthServerConfig() async -> BitwardenShared.ServerConfig? { preAuthServerConfig } @@ -479,6 +484,10 @@ class MockStateService: StateService { // swiftlint:disable:this type_body_lengt preAuthEnvironmentUrls = urls } + func setAccountCreationEnvironmentUrls(urls: BitwardenShared.EnvironmentUrlData, email: String) async { + accountCreationEnvironmentUrls[email] = urls + } + func setPreAuthServerConfig(config: BitwardenShared.ServerConfig) async { preAuthServerConfig = config } diff --git a/BitwardenShared/UI/Auth/CompleteRegistration/CompleteRegistrationProcessor.swift b/BitwardenShared/UI/Auth/CompleteRegistration/CompleteRegistrationProcessor.swift index c1532b4d9..678d11a4c 100644 --- a/BitwardenShared/UI/Auth/CompleteRegistration/CompleteRegistrationProcessor.swift +++ b/BitwardenShared/UI/Auth/CompleteRegistration/CompleteRegistrationProcessor.swift @@ -17,6 +17,9 @@ enum CompleteRegistrationError: Error { /// The password does not meet the minimum length requirement. case passwordIsTooShort + + /// The environment urls to complete the registration are empty + case preAuthUrlsEmpty } // MARK: - CompleteRegistrationProcessor @@ -244,13 +247,24 @@ class CompleteRegistrationProcessor: StateProcessor< } } - /// Sets the URLs to use. + /// Sets the URLs to use if user came from an email link. /// private func setRegion() async { - guard state.region != nil, - let urls = state.region?.defaultURLs else { return } + do { + guard state.fromEmail else { + return + } + + guard let urls = await services.stateService.getAccountCreationEnvironmentUrls(email: state.userEmail) else { + throw CompleteRegistrationError.preAuthUrlsEmpty + } - await services.environmentService.setPreAuthURLs(urls: urls) + await services.environmentService.setPreAuthURLs(urls: urls) + } catch let error as CompleteRegistrationError { + showCompleteRegistrationErrorAlert(error) + } catch { + coordinator.showAlert(.defaultAlert(title: Localizations.anErrorHasOccurred)) + } } /// Sets the feature flag value to be used. @@ -274,6 +288,11 @@ class CompleteRegistrationProcessor: StateProcessor< coordinator.showAlert(.validationFieldRequired(fieldName: Localizations.masterPassword)) case .passwordIsTooShort: coordinator.showAlert(.passwordIsTooShort) + case .preAuthUrlsEmpty: + coordinator.showAlert(.defaultAlert( + title: Localizations.anErrorHasOccurred, + message: Localizations.theRegionForTheGivenEmailCouldNotBeLoaded + )) } } diff --git a/BitwardenShared/UI/Auth/CompleteRegistration/CompleteRegistrationProcessorTests.swift b/BitwardenShared/UI/Auth/CompleteRegistration/CompleteRegistrationProcessorTests.swift index 94638d5e7..7e6ccba4e 100644 --- a/BitwardenShared/UI/Auth/CompleteRegistration/CompleteRegistrationProcessorTests.swift +++ b/BitwardenShared/UI/Auth/CompleteRegistration/CompleteRegistrationProcessorTests.swift @@ -19,6 +19,7 @@ class CompleteRegistrationProcessorTests: BitwardenTestCase { var environmentService: MockEnvironmentService! var errorReporter: MockErrorReporter! var subject: CompleteRegistrationProcessor! + var stateService: MockStateService! // MARK: Setup & Teardown @@ -32,6 +33,7 @@ class CompleteRegistrationProcessorTests: BitwardenTestCase { coordinator = MockCoordinator() environmentService = MockEnvironmentService() errorReporter = MockErrorReporter() + stateService = MockStateService() subject = CompleteRegistrationProcessor( coordinator: coordinator.asAnyCoordinator(), services: ServiceContainer.withMocks( @@ -41,7 +43,8 @@ class CompleteRegistrationProcessorTests: BitwardenTestCase { configService: configService, environmentService: environmentService, errorReporter: errorReporter, - httpClient: client + httpClient: client, + stateService: stateService ), state: CompleteRegistrationState( emailVerificationToken: "emailVerificationToken", @@ -60,6 +63,7 @@ class CompleteRegistrationProcessorTests: BitwardenTestCase { configService = nil errorReporter = nil subject = nil + stateService = nil } // MARK: Tests @@ -67,18 +71,41 @@ class CompleteRegistrationProcessorTests: BitwardenTestCase { /// `perform(.appeared)` with EU region in state. @MainActor func test_perform_appeared_setRegion_europe() async { - subject.state.region = .europe + let email = "email@example.com" + subject.state.userEmail = email + subject.state.fromEmail = true + await stateService.setAccountCreationEnvironmentUrls(urls: .defaultEU, email: email) await subject.perform(.appeared) - XCTAssertEqual(subject.state.region, .europe) XCTAssertEqual(environmentService.setPreAuthEnvironmentUrlsData, .defaultEU) } - /// `perform(.appeared)` with nil region in state. + /// `perform(.appeared)` fromEmail false returns. @MainActor - func test_perform_appeared_setRegion_return() async { - subject.state.region = nil + func test_perform_appeared_setRegion_notFromEmail_returns() async throws { + let email = "email@example.com" + subject.state.userEmail = email + subject.state.fromEmail = false + await stateService.setAccountCreationEnvironmentUrls(urls: .defaultEU, email: email) await subject.perform(.appeared) - XCTAssertEqual(subject.state.region, nil) + XCTAssertNil(coordinator.alertShown.last) + XCTAssertEqual(environmentService.setPreAuthEnvironmentUrlsData, nil) + } + + /// `perform(.appeared)` fromEmail true and no saved region for given email shows alert. + @MainActor + func test_perform_appeared_setRegion_noRegion_alert() async throws { + let email = "email@example.com" + subject.state.userEmail = email + subject.state.fromEmail = true + await stateService.setAccountCreationEnvironmentUrls(urls: .defaultEU, email: "another_email@example.com") + await subject.perform(.appeared) + XCTAssertEqual( + coordinator.alertShown[0], + .defaultAlert( + title: Localizations.anErrorHasOccurred, + message: Localizations.theRegionForTheGivenEmailCouldNotBeLoaded + ) + ) XCTAssertEqual(environmentService.setPreAuthEnvironmentUrlsData, nil) } diff --git a/BitwardenShared/UI/Auth/StartRegistration/StartRegistrationProcessor.swift b/BitwardenShared/UI/Auth/StartRegistration/StartRegistrationProcessor.swift index 5cd2a0e6f..2d2930178 100644 --- a/BitwardenShared/UI/Auth/StartRegistration/StartRegistrationProcessor.swift +++ b/BitwardenShared/UI/Auth/StartRegistration/StartRegistrationProcessor.swift @@ -27,6 +27,9 @@ enum StartRegistrationError: Error { /// The email is invalid. case invalidEmail + + /// The pre auth environment urls are nil. + case preAuthUrlsEmpty } // MARK: - StartRegistrationProcessor @@ -165,6 +168,11 @@ class StartRegistrationProcessor: StateProcessor< userEmail: state.emailText )) } else { + guard let preAuthUrls = await services.stateService.getPreAuthEnvironmentUrls() else { + throw StartRegistrationError.preAuthUrlsEmpty + } + + await services.stateService.setAccountCreationEnvironmentUrls(urls: preAuthUrls, email: email) coordinator.navigate(to: .checkEmail(email: state.emailText)) } } catch let error as StartRegistrationError { @@ -188,6 +196,11 @@ class StartRegistrationProcessor: StateProcessor< coordinator.showAlert(.validationFieldRequired(fieldName: Localizations.email)) case .invalidEmail: coordinator.showAlert(.invalidEmail) + case .preAuthUrlsEmpty: + coordinator.showAlert(.defaultAlert( + title: Localizations.anErrorHasOccurred, + message: Localizations.thePreAuthUrlsCouldNotBeLoadedToStartTheAccountCreation + )) } } } diff --git a/BitwardenShared/UI/Auth/StartRegistration/StartRegistrationProcessorTests.swift b/BitwardenShared/UI/Auth/StartRegistration/StartRegistrationProcessorTests.swift index 33ae8ee4d..411df2920 100644 --- a/BitwardenShared/UI/Auth/StartRegistration/StartRegistrationProcessorTests.swift +++ b/BitwardenShared/UI/Auth/StartRegistration/StartRegistrationProcessorTests.swift @@ -95,6 +95,64 @@ class StartRegistrationProcessorTests: BitwardenTestCase { // swiftlint:disable: XCTAssertEqual(coordinator.routes.last, .selfHosted(currentRegion: .europe)) } + /// `perform(_:)` with `.startRegistration` sets preAuthUrls for the given email and navigates to check email. + @MainActor + func test_perform_startRegistration_setPreAuthUrls_checkEmail() async throws { + subject.state = .fixture() + client.result = .httpSuccess(testData: .nilResponse) + stateService.preAuthEnvironmentUrls = .defaultEU + + await subject.perform(.startRegistration) + + XCTAssertEqual(client.requests.count, 1) + XCTAssertEqual( + client.requests[0].url, + URL(string: "https://example.com/identity/accounts/register/send-verification-email") + ) + XCTAssertEqual(coordinator.routes.last, .checkEmail( + email: "example@email.com" + )) + + XCTAssertFalse(coordinator.isLoadingOverlayShowing) + XCTAssertEqual( + coordinator.loadingOverlaysShown, + [ + LoadingOverlayState(title: Localizations.creatingAccount), + ] + ) + } + + /// `perform(_:)` with `.startRegistration` fails if preAuthUrls cannot be loaded. + @MainActor + func test_perform_startRegistration_setPreAuthUrls_checkEmail_noUrls() async throws { + subject.state = .fixture() + client.result = .httpSuccess(testData: .nilResponse) + stateService.preAuthEnvironmentUrls = nil + + await subject.perform(.startRegistration) + + XCTAssertEqual(client.requests.count, 1) + XCTAssertEqual( + client.requests[0].url, + URL(string: "https://example.com/identity/accounts/register/send-verification-email") + ) + XCTAssertEqual( + coordinator.alertShown.last, + .defaultAlert( + title: Localizations.anErrorHasOccurred, + message: Localizations.thePreAuthUrlsCouldNotBeLoadedToStartTheAccountCreation + ) + ) + + XCTAssertFalse(coordinator.isLoadingOverlayShowing) + XCTAssertEqual( + coordinator.loadingOverlaysShown, + [ + LoadingOverlayState(title: Localizations.creatingAccount), + ] + ) + } + /// `perform(_:)` with `.startRegistration` presents an alert when the email has already been taken. @MainActor func test_perform_startRegistration_emailExists() async { diff --git a/BitwardenShared/UI/Platform/Application/Support/Localizations/en.lproj/Localizable.strings b/BitwardenShared/UI/Platform/Application/Support/Localizations/en.lproj/Localizable.strings index ffa6ee128..f7a9916e5 100644 --- a/BitwardenShared/UI/Platform/Application/Support/Localizations/en.lproj/Localizable.strings +++ b/BitwardenShared/UI/Platform/Application/Support/Localizations/en.lproj/Localizable.strings @@ -975,6 +975,8 @@ "PleaseRestartRegistrationOrTryLoggingInYouMayAlreadyHaveAnAccount" = "Please restart registration or try logging in. You may already have an account."; "RemovePasskey" = "Remove passkey"; "PasskeyRemoved" = "Passkey removed"; +"TheRegionForTheGivenEmailCouldNotBeLoaded" = "The region for the given email could not be loaded."; "SetUpLaterQuestion" = "Set up later?"; "YouCanFinishSetupUnlockAnytimeDescriptionLong" = "You can finish setup anytime in Account Security under Settings. You’ll use your master password to unlock until you set up another method."; "Confirm" = "Confirm"; +"ThePreAuthUrlsCouldNotBeLoadedToStartTheAccountCreation" = "The Pre Auth Urls could not be loaded to start the account creation.";