Skip to content

Commit

Permalink
No phone Auth flow (#801)
Browse files Browse the repository at this point in the history
  • Loading branch information
GhenadieVP committed Sep 28, 2023
1 parent a7e49d6 commit 5ce8833
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 65 deletions.
3 changes: 0 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,6 @@ package.addModules([
"MainFeature",
"OnboardingFeature",
"OverlayWindowClient",
"CreateAccountFeature",
"NetworkSwitchingClient",
"GatewaysClient",
"SplashFeature",
],
tests: .yes()
Expand Down
45 changes: 11 additions & 34 deletions Sources/Features/AppFeature/App+Reducer.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import AppPreferencesClient
import CreateAccountFeature
import EngineKit
import FeaturePrelude
import GatewaysClient
import MainFeature
import NetworkSwitchingClient
import OnboardingClient
import OnboardingFeature
import SecureStorageClient
import SplashFeature

// MARK: - App
Expand All @@ -21,8 +16,6 @@ public struct App: Sendable, FeatureReducer {

public var root: Root

public var isOnMainnet = true

@PresentationState
public var alert: Alerts.State?

Expand All @@ -43,7 +36,6 @@ public struct App: Sendable, FeatureReducer {
case incompatibleProfileDeleted
case toMain(isAccountRecoveryNeeded: Bool)
case toOnboarding
case currentGatewayChanged(to: Radix.Gateway)
}

public enum ChildAction: Sendable, Equatable {
Expand Down Expand Up @@ -71,8 +63,6 @@ public struct App: Sendable, FeatureReducer {
}

@Dependency(\.continuousClock) var clock
@Dependency(\.networkSwitchingClient) var networkSwitchingClient
@Dependency(\.gatewaysClient) var gatewaysClient
@Dependency(\.errorQueue) var errorQueue
@Dependency(\.appPreferencesClient) var appPreferencesClient

Expand Down Expand Up @@ -103,28 +93,19 @@ public struct App: Sendable, FeatureReducer {
case .task:
let retBuildInfo = buildInformation()
loggerGlobal.info("EngineToolkit commit hash: \(retBuildInfo.version)")
return .merge(
.run { send in
for try await gateways in await gatewaysClient.gatewaysValues() {
guard !Task.isCancelled else { return }
loggerGlobal.notice("Changed network to: \(gateways.current)")
await send(.internal(.currentGatewayChanged(to: gateways.current)))
}
},
.run { send in
for try await error in errorQueue.errors() {
guard !Task.isCancelled else { return }
// Maybe instead we should listen here for the Profile.State change,
// and when it switches to `.ephemeral` we navigate to onboarding.
// For now, we react to the specific error, since the Profile.State is meant to be private.
if error is Profile.ProfileIsUsedOnAnotherDeviceError {
await send(.internal(.toOnboarding))
// A slight delay to allow any modal that may be shown to be dismissed.
try? await clock.sleep(for: .seconds(0.5))
}
return .run { send in
for try await error in errorQueue.errors() {
guard !Task.isCancelled else { return }
// Maybe instead we should listen here for the Profile.State change,
// and when it switches to `.ephemeral` we navigate to onboarding.
// For now, we react to the specific error, since the Profile.State is meant to be private.
if error is Profile.ProfileIsUsedOnAnotherDeviceError {
await send(.internal(.toOnboarding))
// A slight delay to allow any modal that may be shown to be dismissed.
try? await clock.sleep(for: .seconds(0.5))
}
}
)
}

case .alert(.presented(.incompatibleProfileErrorAlert(.deleteWalletDataButtonTapped))):
return .run { send in
Expand All @@ -150,10 +131,6 @@ public struct App: Sendable, FeatureReducer {

case .toOnboarding:
return goToOnboarding(state: &state)

case let .currentGatewayChanged(currentGateway):
state.isOnMainnet = currentGateway.network == .mainnet
return .none
}
}

Expand Down
12 changes: 0 additions & 12 deletions Sources/Features/AppFeature/App+View.swift
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import AssetTransferFeature
import CreateAccountFeature
import FeaturePrelude
import MainFeature
import OnboardingFeature
import SplashFeature

extension App.State {
public var showIsUsingTestnetBanner: Bool {
!isOnMainnet
}
}

// MARK: - App.View
extension App {
@MainActor
Expand All @@ -22,7 +15,6 @@ extension App {
}

public var body: some SwiftUI.View {
let bannerStore = store.scope(state: \.showIsUsingTestnetBanner, action: actionless)
SwitchStore(store.scope(state: \.root, action: Action.child)) { state in
switch state {
case .main:
Expand Down Expand Up @@ -53,10 +45,6 @@ extension App {
state: /App.Alerts.State.incompatibleProfileErrorAlert,
action: App.Alerts.Action.incompatibleProfileErrorAlert
)
.task { @MainActor in
await store.send(.view(.task)).finish()
}
.showDeveloperDisclaimerBanner(bannerStore)
.presentsLoadingViewOverlay()
}
}
Expand Down
34 changes: 33 additions & 1 deletion Sources/Features/MainFeature/Main+Reducer.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import AppPreferencesClient
import FeaturePrelude
import GatewaysClient
import HomeFeature
import SettingsFeature

Expand All @@ -8,6 +9,8 @@ public struct Main: Sendable, FeatureReducer {
// MARK: - Components
public var home: Home.State

public var isOnMainnet = true

// MARK: - Destinations
@PresentationState
public var destination: Destinations.State?
Expand All @@ -17,6 +20,10 @@ public struct Main: Sendable, FeatureReducer {
}
}

public enum ViewAction: Sendable, Equatable {
case task
}

public enum ChildAction: Sendable, Equatable {
case home(Home.Action)
case destination(PresentationAction<Destinations.Action>)
Expand All @@ -26,6 +33,10 @@ public struct Main: Sendable, FeatureReducer {
case removedWallet
}

public enum InternalAction: Sendable, Equatable {
case currentGatewayChanged(to: Radix.Gateway)
}

public struct Destinations: Sendable, Reducer {
public enum State: Sendable, Hashable {
case settings(Settings.State)
Expand All @@ -42,8 +53,8 @@ public struct Main: Sendable, FeatureReducer {
}
}

@Dependency(\.keychainClient) var keychainClient
@Dependency(\.appPreferencesClient) var appPreferencesClient
@Dependency(\.gatewaysClient) var gatewaysClient

public init() {}

Expand All @@ -57,6 +68,19 @@ public struct Main: Sendable, FeatureReducer {
}
}

public func reduce(into state: inout State, viewAction: ViewAction) -> Effect<Action> {
switch viewAction {
case .task:
return .run { send in
for try await gateways in await gatewaysClient.gatewaysValues() {
guard !Task.isCancelled else { return }
loggerGlobal.notice("Changed network to: \(gateways.current)")
await send(.internal(.currentGatewayChanged(to: gateways.current)))
}
}
}
}

public func reduce(into state: inout State, childAction: ChildAction) -> Effect<Action> {
switch childAction {
case .home(.delegate(.displaySettings)):
Expand All @@ -75,4 +99,12 @@ public struct Main: Sendable, FeatureReducer {
return .none
}
}

public func reduce(into state: inout State, internalAction: InternalAction) -> Effect<Action> {
switch internalAction {
case let .currentGatewayChanged(currentGateway):
state.isOnMainnet = currentGateway.network == .mainnet
return .none
}
}
}
11 changes: 11 additions & 0 deletions Sources/Features/MainFeature/Main+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import FeaturePrelude
import HomeFeature
import SettingsFeature

extension Main.State {
public var showIsUsingTestnetBanner: Bool {
!isOnMainnet
}
}

// MARK: - Main.View
extension Main {
@MainActor
Expand All @@ -14,6 +20,7 @@ extension Main {
}

public var body: some SwiftUI.View {
let bannerStore = store.scope(state: \.showIsUsingTestnetBanner, action: actionless)
NavigationStack {
Home.View(
store: store.scope(
Expand All @@ -33,6 +40,10 @@ extension Main {
)
#endif
}
.task { @MainActor in
await store.send(.view(.task)).finish()
}
.showDeveloperDisclaimerBanner(bannerStore)
.presentsDappInteractions()
}
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/Features/SplashFeature/Splash.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ public struct Splash: Sendable, FeatureReducer {

case .didTapToUnlock:
state.biometricsCheckFailed = false
return .run { send in
await send(.internal(.loadProfileOutcome(loadProfile())))
}
return verifyPasscode()

case let .passcodeCheckFailedAlert(.presented(action)):
switch action {
Expand All @@ -91,6 +89,7 @@ public struct Splash: Sendable, FeatureReducer {
let config = try? result.value

guard config?.isPasscodeSetUp == true else {
state.biometricsCheckFailed = true
state.passcodeCheckFailedAlert = .init(
title: { .init(L10n.Splash.PasscodeCheckFailedAlert.title) },
actions: {
Expand Down Expand Up @@ -121,8 +120,9 @@ public struct Splash: Sendable, FeatureReducer {
}
return delegateCompleted(loadProfileOutcome: outcome, accountRecoveryNeeded: false)

case .accountRecoveryNeeded(_, .failure):
case let .accountRecoveryNeeded(_, .failure(error)):
state.biometricsCheckFailed = true
errorQueue.schedule(error)
return .none

case let .accountRecoveryNeeded(outcome, .success(recoveryNeeded)):
Expand Down
11 changes: 0 additions & 11 deletions Tests/Features/AppFeatureTests/AppFeatureTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ final class AppFeatureTests: TestCase {
await store.send(.child(.main(.delegate(.removedWallet)))) {
$0.root = .onboardingCoordinator(.init())
}
XCTAssertFalse(store.state.showIsUsingTestnetBanner)
}

func test_splash__GIVEN__an_existing_profile__WHEN__existing_profile_loaded__THEN__we_navigate_to_main() async throws {
Expand Down Expand Up @@ -65,14 +64,11 @@ final class AppFeatureTests: TestCase {
) {
$0.errorQueue = .liveValue
$0.continuousClock = clock
$0.gatewaysClient.gatewaysValues = { AsyncLazySequence([.init(current: .default)]).eraseToAnyAsyncSequence() }
}

let viewTask = await store.send(.view(.task))

// then
await store.receive(.internal(.currentGatewayChanged(to: .default)))
XCTAssertFalse(store.state.showIsUsingTestnetBanner)
await store.send(.child(.splash(.delegate(.completed(.newUser, accountRecoveryNeeded: false))))) {
$0.root = .onboardingCoordinator(.init())
}
Expand All @@ -90,7 +86,6 @@ final class AppFeatureTests: TestCase {
) {
$0.errorQueue = .liveValue
$0.continuousClock = clock
$0.gatewaysClient.gatewaysValues = { AsyncLazySequence([.init(current: .default)]).eraseToAnyAsyncSequence() }
}

let viewTask = await store.send(.view(.task))
Expand All @@ -104,8 +99,6 @@ final class AppFeatureTests: TestCase {
let outcome = LoadProfileOutcome.usersExistingProfileCouldNotBeLoaded(failure: failure)

// then
await store.receive(.internal(.currentGatewayChanged(to: .default)))
XCTAssertFalse(store.state.showIsUsingTestnetBanner)
await store.send(.child(.splash(.delegate(.completed(outcome, accountRecoveryNeeded: false))))) {
$0.root = .onboardingCoordinator(.init())
}
Expand All @@ -125,7 +118,6 @@ final class AppFeatureTests: TestCase {
) {
$0.errorQueue = .liveValue
$0.continuousClock = clock
$0.gatewaysClient.gatewaysValues = { AsyncLazySequence([.init(current: .default)]).eraseToAnyAsyncSequence() }
}
store.exhaustivity = .off
let viewTask = await store.send(.view(.task))
Expand Down Expand Up @@ -166,7 +158,6 @@ final class AppFeatureTests: TestCase {
) {
$0.errorQueue = .liveValue
$0.continuousClock = clock
$0.gatewaysClient.gatewaysValues = { AsyncLazySequence([.init(current: .default)]).eraseToAnyAsyncSequence() }
$0.appPreferencesClient.deleteProfileAndFactorSources = { _ in
profileDeletedExpectation.fulfill()
}
Expand All @@ -180,8 +171,6 @@ final class AppFeatureTests: TestCase {

let outcome = LoadProfileOutcome.usersExistingProfileCouldNotBeLoaded(failure: .profileVersionOutdated(json: Data([0xDE, 0xAD]), version: badVersion))

await store.receive(.internal(.currentGatewayChanged(to: .default)))
XCTAssertFalse(store.state.showIsUsingTestnetBanner)
await store.send(.child(.splash(.delegate(.completed(outcome, accountRecoveryNeeded: false))))) {
$0.alert = .incompatibleProfileErrorAlert(
.init(
Expand Down
18 changes: 18 additions & 0 deletions Tests/Features/MainFeatureTests/MainFeatureTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,22 @@ final class MainFeatureTests: TestCase {
$0.destination = nil
}
}

func test_displayTestBanner() async {
// given
let store = TestStore(initialState: Main.State(home: .previewValue)) {
Main()
.dependency(\.userDefaultsClient, .noop)
.dependency(\.gatewaysClient.gatewaysValues) { AsyncLazySequence([.init(current: .stokenet)]).eraseToAnyAsyncSequence() }
}

XCTAssertFalse(store.state.showIsUsingTestnetBanner)

await store.send(.view(.task))

await store.receive(.internal(.currentGatewayChanged(to: .stokenet))) {
$0.isOnMainnet = false
}
XCTAssertTrue(store.state.showIsUsingTestnetBanner)
}
}
1 change: 1 addition & 0 deletions Tests/Features/SplashFeatureTests/SplashFeatureTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ final class SplashFeatureTests: TestCase {

await clock.advance(by: .seconds(0.4))
await store.receive(.internal(.passcodeConfigResult(.success(authBiometricsConfig)))) {
$0.biometricsCheckFailed = true
$0.passcodeCheckFailedAlert = .init(
title: { .init(L10n.Splash.PasscodeCheckFailedAlert.title) },
actions: {
Expand Down

0 comments on commit 5ce8833

Please sign in to comment.