From 9b46a4c9d32d9cf5c37015e64bc03e4936524d29 Mon Sep 17 00:00:00 2001 From: adam Date: Fri, 5 Nov 2021 07:26:20 -0500 Subject: [PATCH] Onboarding State Updates --- .../Features/Onboarding/OnboardingStore.swift | 9 ++- .../Onboarding/Views/Onboarding.swift | 1 + .../OnboardingStoreTests.swift | 75 ++++++++++++++----- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/secant/Features/Onboarding/OnboardingStore.swift b/secant/Features/Onboarding/OnboardingStore.swift index 645969c..d900c05 100644 --- a/secant/Features/Onboarding/OnboardingStore.swift +++ b/secant/Features/Onboarding/OnboardingStore.swift @@ -18,13 +18,18 @@ struct OnboardingStep: Equatable, Identifiable { struct OnboardingState: Equatable { var steps: IdentifiedArrayOf = Self.onboardingSteps var index = 0 - var offset: CGFloat = .zero var skippedAtindex: Int? var currentStep: OnboardingStep { steps[index] } var skipButtonDisabled: Bool { steps.count == index + 1 } var backButtonDisabled: Bool { index == 0 } var progress: Int { ((index + 1) * 100) / (steps.count) } + var offset: CGFloat { + let maxOffset = CGFloat(-60) + let stepOffset = CGFloat(maxOffset / CGFloat(steps.count - 1)) + guard index != 0 else { return .zero } + return stepOffset * CGFloat(index) + } } enum OnboardingAction: Equatable { @@ -43,14 +48,12 @@ let onboardingReducer = Reducer { state state.skippedAtindex = nil } else { state.index -= 1 - state.offset += 20.0 } return .none case .next: guard state.index < state.steps.count - 1 else { return .none } state.index += 1 - state.offset -= 20.0 return .none case .skip: diff --git a/secant/Features/Onboarding/Views/Onboarding.swift b/secant/Features/Onboarding/Views/Onboarding.swift index 16c38f0..d8fdf61 100644 --- a/secant/Features/Onboarding/Views/Onboarding.swift +++ b/secant/Features/Onboarding/Views/Onboarding.swift @@ -19,6 +19,7 @@ struct OnboardingView: View { .disabled(viewStore.backButtonDisabled) Spacer() + Button("Next") { viewStore.send(.next) } Button("Skip") { viewStore.send(.skip) } .disabled(viewStore.skipButtonDisabled) diff --git a/secantTests/OnboardingTests/OnboardingStoreTests.swift b/secantTests/OnboardingTests/OnboardingStoreTests.swift index 6ff7830..090056a 100644 --- a/secantTests/OnboardingTests/OnboardingStoreTests.swift +++ b/secantTests/OnboardingTests/OnboardingStoreTests.swift @@ -19,98 +19,139 @@ class OnboardingStoreTests: XCTestCase { store.send(.next) { $0.index += 1 - $0.offset -= 20.0 XCTAssertFalse($0.skipButtonDisabled) XCTAssertFalse($0.backButtonDisabled) XCTAssertEqual($0.currentStep, $0.steps[1]) + XCTAssertEqual($0.offset, -20.0) XCTAssertEqual($0.progress, 50) } store.send(.next) { $0.index += 1 - $0.offset -= 20.0 XCTAssertFalse($0.skipButtonDisabled) XCTAssertFalse($0.backButtonDisabled) XCTAssertEqual($0.currentStep, $0.steps[2]) + XCTAssertEqual($0.offset, -40.0) XCTAssertEqual($0.progress, 75) } store.send(.next) { $0.index += 1 - $0.offset -= 20.0 XCTAssertTrue($0.skipButtonDisabled) XCTAssertFalse($0.backButtonDisabled) XCTAssertEqual($0.currentStep, $0.steps[3]) + XCTAssertEqual($0.offset, -60.0) + XCTAssertEqual($0.progress, 100) + } + } + + func testIncrementingPastTotalStepsDoesNothing() { + let store = TestStore( + initialState: OnboardingState(index: 3), + reducer: onboardingReducer, + environment: () + ) + + store.send(.next) { + XCTAssertTrue($0.skipButtonDisabled) + XCTAssertFalse($0.backButtonDisabled) + XCTAssertEqual($0.currentStep, $0.steps[3]) + XCTAssertEqual($0.offset, -60.0) + XCTAssertEqual($0.progress, 100) + } + + store.send(.next) { + XCTAssertTrue($0.skipButtonDisabled) + XCTAssertFalse($0.backButtonDisabled) + XCTAssertEqual($0.currentStep, $0.steps[3]) + XCTAssertEqual($0.offset, -60.0) XCTAssertEqual($0.progress, 100) } } func testDecrementingOnboarding() { let store = TestStore( - initialState: OnboardingState( - index: 2, - offset: .zero - 20.0 - 20.0 - ), + initialState: OnboardingState(index: 2), reducer: onboardingReducer, environment: () ) store.send(.back) { $0.index -= 1 - $0.offset += 20.0 XCTAssertFalse($0.skipButtonDisabled) XCTAssertFalse($0.backButtonDisabled) XCTAssertEqual($0.currentStep, $0.steps[1]) + XCTAssertEqual($0.offset, -20.0) XCTAssertEqual($0.progress, 50) } store.send(.back) { $0.index -= 1 - $0.offset += 20.0 XCTAssertFalse($0.skipButtonDisabled) XCTAssertTrue($0.backButtonDisabled) XCTAssertEqual($0.currentStep, $0.steps[0]) + XCTAssertEqual($0.offset, 0.0) + XCTAssertEqual($0.progress, 25) + } + } + + func testDecrementingPastFirstStepDoesNothing() { + let store = TestStore( + initialState: OnboardingState(), + reducer: onboardingReducer, + environment: () + ) + + store.send(.back) { + XCTAssertFalse($0.skipButtonDisabled) + XCTAssertTrue($0.backButtonDisabled) + XCTAssertEqual($0.currentStep, $0.steps[0]) + XCTAssertEqual($0.offset, 0.0) + XCTAssertEqual($0.progress, 25) + } + + store.send(.back) { + XCTAssertFalse($0.skipButtonDisabled) + XCTAssertTrue($0.backButtonDisabled) + XCTAssertEqual($0.currentStep, $0.steps[0]) + XCTAssertEqual($0.offset, 0.0) XCTAssertEqual($0.progress, 25) } } func testSkipOnboarding() { let initialIndex = 1 - let initialOffset: CGFloat = .zero - 20.0 - + let store = TestStore( - initialState: OnboardingState( - index: initialIndex, - offset: initialOffset - ), + initialState: OnboardingState(index: initialIndex), reducer: onboardingReducer, environment: () ) store.send(.skip) { $0.index = $0.steps.count - 1 - $0.offset = initialOffset $0.skippedAtindex = initialIndex XCTAssertTrue($0.skipButtonDisabled) XCTAssertFalse($0.backButtonDisabled) XCTAssertEqual($0.currentStep, $0.steps[3]) + XCTAssertEqual($0.offset, -60.0) XCTAssertEqual($0.progress, 100) } store.send(.back) { $0.skippedAtindex = nil $0.index = initialIndex - $0.offset = initialOffset XCTAssertFalse($0.skipButtonDisabled) XCTAssertFalse($0.backButtonDisabled) XCTAssertEqual($0.currentStep, $0.steps[1]) + XCTAssertEqual($0.offset, -20.0) XCTAssertEqual($0.progress, 50) } }