Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PM-14632: Revert to legacy create account flow if updated environment doesn't support email verification #1161

Merged
merged 2 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,10 @@ extension IntroCarouselProcessor: StartRegistrationDelegate {
func didChangeRegion() async {
// No-op: the carousel doesn't show the region so there's nothing to do here.
}

func switchToLegacyCreateAccountFlow() {
coordinator.navigate(to: .dismissWithAction(DismissAction {
self.coordinator.navigate(to: .createAccount)
}))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,19 @@ class IntroCarouselProcessorTests: BitwardenTestCase {
subject.receive(.logIn)
XCTAssertEqual(coordinator.routes.last, .landing)
}

/// `switchToLegacyCreateAccountFlow()` dismisses the currently presented view and navigates to
/// create account.
@MainActor
func test_switchToLegacyCreateAccountFlow() throws {
subject.switchToLegacyCreateAccountFlow()

let dismissRoute = try XCTUnwrap(coordinator.routes.last)
guard case let .dismissWithAction(action) = dismissRoute else {
return XCTFail("Expected route `.dismissWithAction` not found.")
}
action?.action()

XCTAssertEqual(coordinator.routes, [.dismissWithAction(action), .createAccount])
}
}
6 changes: 6 additions & 0 deletions BitwardenShared/UI/Auth/Landing/LandingProcessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@ extension LandingProcessor: StartRegistrationDelegate {
func didChangeRegion() async {
await regionHelper.loadRegion()
}

func switchToLegacyCreateAccountFlow() {
coordinator.navigate(to: .dismissWithAction(DismissAction {
self.coordinator.navigate(to: .createAccount)
}))
}
}

// MARK: - RegionDelegate
Expand Down
15 changes: 15 additions & 0 deletions BitwardenShared/UI/Auth/Landing/LandingProcessorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -875,4 +875,19 @@ class LandingProcessorTests: BitwardenTestCase { // swiftlint:disable:this type_
subject.receive(.toastShown(nil))
XCTAssertNil(subject.state.toast)
}

/// `switchToLegacyCreateAccountFlow()` dismisses the currently presented view and navigates to
/// create account.
@MainActor
func test_switchToLegacyCreateAccountFlow() throws {
subject.switchToLegacyCreateAccountFlow()

let dismissRoute = try XCTUnwrap(coordinator.routes.last)
guard case let .dismissWithAction(action) = dismissRoute else {
return XCTFail("Expected route `.dismissWithAction` not found.")
}
action?.action()

XCTAssertEqual(coordinator.routes, [.dismissWithAction(action), .createAccount])
}
} // swiftlint:disable:this file_length
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
/// Actions that can be processed by a `StartRegistrationProcessor`.
///
enum StartRegistrationAction: Equatable {
/// The `StartRegistrationView` was dismissed.
case dismiss

/// The user edited the email text field.
case emailTextChanged(String)

/// The start registration appeared on screen.
case disappeared

/// The `StartRegistrationView` was dismissed.
case dismiss

/// The user edited the name text field.
case nameTextChanged(String)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ protocol StartRegistrationDelegate: AnyObject {
/// Called when the user changes regions.
///
func didChangeRegion() async

/// If the user changes environments and the environment doesn't support email verification,
/// the UI should switch to using the legacy create account flow.
///
func switchToLegacyCreateAccountFlow()
}

// MARK: - StartRegistrationError
Expand Down Expand Up @@ -69,6 +74,9 @@ class StartRegistrationProcessor: StateProcessor<
stateService: services.stateService
)

/// Whether the start registration view is visible in the view hierarchy.
private var viewIsVisible = false

// MARK: Initialization

/// Creates a new `StartRegistrationProcessor`.
Expand All @@ -95,6 +103,7 @@ class StartRegistrationProcessor: StateProcessor<
override func perform(_ effect: StartRegistrationEffect) async {
switch effect {
case .appeared:
viewIsVisible = true
await regionHelper.loadRegion()
state.isReceiveMarketingToggleOn = state.region == .unitedStates
await loadFeatureFlags()
Expand All @@ -112,6 +121,8 @@ class StartRegistrationProcessor: StateProcessor<
switch action {
case let .emailTextChanged(text):
state.emailText = text
case .disappeared:
viewIsVisible = false
case .dismiss:
coordinator.navigate(to: .dismiss)
case let .nameTextChanged(text):
Expand Down Expand Up @@ -229,5 +240,16 @@ extension StartRegistrationProcessor: RegionDelegate {
state.region = region
state.showReceiveMarketingToggle = state.region != .selfHosted
await delegate?.didChangeRegion()

if await !services.configService.getFeatureFlag(
.emailVerification,
defaultValue: false,
forceRefresh: true,
isPreAuth: true
), viewIsVisible {
// If email verification isn't enabled in the selected environment, switch to the
// legacy create account flow.
delegate?.switchToLegacyCreateAccountFlow()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ class StartRegistrationProcessorTests: BitwardenTestCase { // swiftlint:disable:
var clientAuth: MockClientAuth!
var configService: MockConfigService!
var coordinator: MockCoordinator<AuthRoute, AuthEvent>!
var delegate: MockStartRegistrationDelegate!
var errorReporter: MockErrorReporter!
var subject: StartRegistrationProcessor!
var delegate: MockStartRegistrationDelegate!
var stateService: MockStateService!
var environmentService: MockEnvironmentService!

Expand All @@ -31,6 +31,7 @@ class StartRegistrationProcessorTests: BitwardenTestCase { // swiftlint:disable:
clientAuth = MockClientAuth()
configService = MockConfigService()
coordinator = MockCoordinator<AuthRoute, AuthEvent>()
delegate = MockStartRegistrationDelegate()
environmentService = MockEnvironmentService()
errorReporter = MockErrorReporter()
stateService = MockStateService()
Expand Down Expand Up @@ -629,12 +630,54 @@ class StartRegistrationProcessorTests: BitwardenTestCase { // swiftlint:disable:
XCTAssertEqual(environmentService.setPreAuthEnvironmentUrlsData, .defaultEU)
XCTAssertFalse(subject.state.isReceiveMarketingToggleOn)
}

/// `setRegion(_:_:)` doesn't notify the delegate to switch to the legacy create account flow
/// if the selected region supports email verification.
@MainActor
func test_setRegion_emailVerificationEnabled() async {
configService.featureFlagsBoolPreAuth[.emailVerification] = true

await subject.setRegion(.unitedStates, .defaultUS)

XCTAssertFalse(delegate.switchToLegacyCreateAccountFlowCalled)
}

/// `setRegion(_:_:)` notifies the delegate to switch to the legacy create account flow if the
/// selected region doesn't support email verification.
@MainActor
func test_setRegion_emailVerificationDisabled() async {
await subject.perform(.appeared)

configService.featureFlagsBoolPreAuth[.emailVerification] = false
await subject.setRegion(.unitedStates, .defaultUS)

XCTAssertTrue(delegate.switchToLegacyCreateAccountFlowCalled)
}

/// `setRegion(_:_:)` doesn't notify the delete if the selected region doesn't support email
/// verification but the view is no longer visible.
@MainActor
func test_setRegion_emailVerificationDisabled_viewNotVisible() async {
configService.featureFlagsBoolPreAuth[.emailVerification] = true
await subject.perform(.appeared)
subject.receive(.disappeared)

configService.featureFlagsBoolPreAuth[.emailVerification] = false
await subject.setRegion(.unitedStates, .defaultUS)

XCTAssertFalse(delegate.switchToLegacyCreateAccountFlowCalled)
}
}

class MockStartRegistrationDelegate: StartRegistrationDelegate {
var didChangeRegionCalled: Bool = false
var switchToLegacyCreateAccountFlowCalled = false

func didChangeRegion() async {
didChangeRegionCalled = true
}

func switchToLegacyCreateAccountFlow() {
switchToLegacyCreateAccountFlowCalled = true
}
} // swiftlint:disable:this file_length
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ struct StartRegistrationView: View {
title: Localizations.createAccount,
titleDisplayMode: .inline
)
.onDisappear {
store.send(.disappeared)
}
.task {
await store.perform(.appeared)
}
Expand Down
Loading