From ecbe50a1d0b9cf6f7593a5a8f94d141efe6e0deb Mon Sep 17 00:00:00 2001 From: Matt Czech Date: Mon, 5 Aug 2024 10:38:17 -0500 Subject: [PATCH] PM-10517: Add feature flag for intro carousel --- .../Core/Platform/Models/Enum/FeatureFlag.swift | 4 ++++ BitwardenShared/UI/Auth/AuthRouter.swift | 1 + BitwardenShared/UI/Auth/AuthRouterTests.swift | 15 +++++++++++++++ .../UI/Auth/Extensions/AuthRouter+Redirects.swift | 5 +++-- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/BitwardenShared/Core/Platform/Models/Enum/FeatureFlag.swift b/BitwardenShared/Core/Platform/Models/Enum/FeatureFlag.swift index 7104820415..417347a453 100644 --- a/BitwardenShared/Core/Platform/Models/Enum/FeatureFlag.swift +++ b/BitwardenShared/Core/Platform/Models/Enum/FeatureFlag.swift @@ -5,5 +5,9 @@ import Foundation /// An enum to represent a feature flag sent by the server /// enum FeatureFlag: String, Codable { + /// A feature flag for the intro carousel flow. + case nativeCarouselFlow = "native-carousel-flow" + + /// A feature flag for showing the unassigned items banner. case unassignedItemsBanner = "unassigned-items-banner" } diff --git a/BitwardenShared/UI/Auth/AuthRouter.swift b/BitwardenShared/UI/Auth/AuthRouter.swift index e794ec6c3d..15c5106728 100644 --- a/BitwardenShared/UI/Auth/AuthRouter.swift +++ b/BitwardenShared/UI/Auth/AuthRouter.swift @@ -7,6 +7,7 @@ final class AuthRouter: NSObject, Router { typealias Services = HasAuthRepository & HasClientService + & HasConfigService & HasErrorReporter & HasStateService & HasVaultTimeoutService diff --git a/BitwardenShared/UI/Auth/AuthRouterTests.swift b/BitwardenShared/UI/Auth/AuthRouterTests.swift index b2e32251a7..d32bd85b93 100644 --- a/BitwardenShared/UI/Auth/AuthRouterTests.swift +++ b/BitwardenShared/UI/Auth/AuthRouterTests.swift @@ -8,6 +8,7 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ // MARK: Properties var authRepository: MockAuthRepository! + var configService: MockConfigService! var errorReporter: MockErrorReporter! var stateService: MockStateService! var subject: AuthRouter! @@ -19,6 +20,7 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ super.setUp() authRepository = MockAuthRepository() + configService = MockConfigService() errorReporter = MockErrorReporter() stateService = MockStateService() vaultTimeoutService = MockVaultTimeoutService() @@ -26,6 +28,7 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ subject = AuthRouter( services: ServiceContainer.withMocks( authRepository: authRepository, + configService: configService, errorReporter: errorReporter, stateService: stateService, vaultTimeoutService: vaultTimeoutService @@ -36,6 +39,8 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ override func tearDown() { super.tearDown() + authRepository = nil + configService = nil errorReporter = nil stateService = nil subject = nil @@ -767,6 +772,16 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ XCTAssertTrue(authRepository.logoutCalled) } + /// `handleAndRoute(_ :)` redirects `.didStart` to `.introCarousel` if there's no accounts and + /// the carousel flow is enabled. + func test_handleAndRoute_didStart_createAccountFlow() async { + configService.featureFlagsBool[.nativeCarouselFlow] = true + + let route = await subject.handleAndRoute(.didStart) + + XCTAssertEqual(route, .introCarousel) + } + /// `handleAndRoute(_ :)` redirects `.didTimeout` to `.complete` /// if the account has never lock enabled. func test_handleAndRoute_didTimeout_neverLock() async { diff --git a/BitwardenShared/UI/Auth/Extensions/AuthRouter+Redirects.swift b/BitwardenShared/UI/Auth/Extensions/AuthRouter+Redirects.swift index 9d4ef2ee4b..64154f59a4 100644 --- a/BitwardenShared/UI/Auth/Extensions/AuthRouter+Redirects.swift +++ b/BitwardenShared/UI/Auth/Extensions/AuthRouter+Redirects.swift @@ -204,8 +204,9 @@ extension AuthRouter { /// func preparedStartRoute() async -> AuthRoute { guard let activeAccount = try? await configureActiveAccount(shouldSwitchAutomatically: true) else { - // If no account can be set to active, go to the landing screen. - return .landing + // If no account can be set to active, go to the landing or carousel screen. + let isCarouselEnabled: Bool = await services.configService.getFeatureFlag(.nativeCarouselFlow) + return isCarouselEnabled ? .introCarousel : .landing } // Check for a `logout` timeout action.