[#448] Migrate ImportWallet to ReducerProtocol (#454)

- ImportWallet migrated
- unit and snapshot tests fixed
- syntax cleanup
This commit is contained in:
Lukas Korba 2022-11-03 18:40:40 +01:00 committed by GitHub
parent d44eb5ef1b
commit 85bf0c4224
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 237 additions and 290 deletions

View File

@ -145,6 +145,8 @@
9E6713FA289BE0E100A6796F /* ClearBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F9289BE0E100A6796F /* ClearBackgroundView.swift */; }; 9E6713FA289BE0E100A6796F /* ClearBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F9289BE0E100A6796F /* ClearBackgroundView.swift */; };
9E69A24D27FB002800A55317 /* WelcomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E69A24C27FB002800A55317 /* WelcomeStore.swift */; }; 9E69A24D27FB002800A55317 /* WelcomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E69A24C27FB002800A55317 /* WelcomeStore.swift */; };
9E6EF2CB291287BB00CA007B /* FeedbackGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6EF2CA291287BB00CA007B /* FeedbackGenerator.swift */; }; 9E6EF2CB291287BB00CA007B /* FeedbackGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6EF2CA291287BB00CA007B /* FeedbackGenerator.swift */; };
9E6EF2D12913B75400CA007B /* MnemonicKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6EF2D02913B75400CA007B /* MnemonicKey.swift */; };
9E6EF2D32913B79A00CA007B /* WalletStorageKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6EF2D22913B79A00CA007B /* WalletStorageKey.swift */; };
9E7225F12889539300DF7F17 /* SettingsSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F02889539300DF7F17 /* SettingsSnapshotTests.swift */; }; 9E7225F12889539300DF7F17 /* SettingsSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F02889539300DF7F17 /* SettingsSnapshotTests.swift */; };
9E7225F3288AB6DD00DF7F17 /* MultipleLineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F2288AB6DD00DF7F17 /* MultipleLineTextField.swift */; }; 9E7225F3288AB6DD00DF7F17 /* MultipleLineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F2288AB6DD00DF7F17 /* MultipleLineTextField.swift */; };
9E7225F6288AC71A00DF7F17 /* MultiLineTextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F5288AC71A00DF7F17 /* MultiLineTextFieldStore.swift */; }; 9E7225F6288AC71A00DF7F17 /* MultiLineTextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F5288AC71A00DF7F17 /* MultiLineTextFieldStore.swift */; };
@ -391,6 +393,8 @@
9E6713F9289BE0E100A6796F /* ClearBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearBackgroundView.swift; sourceTree = "<group>"; }; 9E6713F9289BE0E100A6796F /* ClearBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearBackgroundView.swift; sourceTree = "<group>"; };
9E69A24C27FB002800A55317 /* WelcomeStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeStore.swift; sourceTree = "<group>"; }; 9E69A24C27FB002800A55317 /* WelcomeStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeStore.swift; sourceTree = "<group>"; };
9E6EF2CA291287BB00CA007B /* FeedbackGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbackGenerator.swift; sourceTree = "<group>"; }; 9E6EF2CA291287BB00CA007B /* FeedbackGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbackGenerator.swift; sourceTree = "<group>"; };
9E6EF2D02913B75400CA007B /* MnemonicKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MnemonicKey.swift; sourceTree = "<group>"; };
9E6EF2D22913B79A00CA007B /* WalletStorageKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletStorageKey.swift; sourceTree = "<group>"; };
9E7225F02889539300DF7F17 /* SettingsSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSnapshotTests.swift; sourceTree = "<group>"; }; 9E7225F02889539300DF7F17 /* SettingsSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSnapshotTests.swift; sourceTree = "<group>"; };
9E7225F2288AB6DD00DF7F17 /* MultipleLineTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipleLineTextField.swift; sourceTree = "<group>"; }; 9E7225F2288AB6DD00DF7F17 /* MultipleLineTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipleLineTextField.swift; sourceTree = "<group>"; };
9E7225F5288AC71A00DF7F17 /* MultiLineTextFieldStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiLineTextFieldStore.swift; sourceTree = "<group>"; }; 9E7225F5288AC71A00DF7F17 /* MultiLineTextFieldStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiLineTextFieldStore.swift; sourceTree = "<group>"; };
@ -1131,6 +1135,8 @@
9EF1082A29114B93003D8097 /* Pasteboard.swift */, 9EF1082A29114B93003D8097 /* Pasteboard.swift */,
9EF1082C29114BCD003D8097 /* NewRecoveryPhrase.swift */, 9EF1082C29114BCD003D8097 /* NewRecoveryPhrase.swift */,
9E6EF2CA291287BB00CA007B /* FeedbackGenerator.swift */, 9E6EF2CA291287BB00CA007B /* FeedbackGenerator.swift */,
9E6EF2D02913B75400CA007B /* MnemonicKey.swift */,
9E6EF2D22913B79A00CA007B /* WalletStorageKey.swift */,
); );
path = Dependencies; path = Dependencies;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1664,6 +1670,7 @@
9E02B56A27FED43E005B809B /* WrappedFileManager.swift in Sources */, 9E02B56A27FED43E005B809B /* WrappedFileManager.swift in Sources */,
663FABA2271D876C00E495F8 /* SecondaryButton.swift in Sources */, 663FABA2271D876C00E495F8 /* SecondaryButton.swift in Sources */,
9E7CB6202874143800A02233 /* AddressDetailsStore.swift in Sources */, 9E7CB6202874143800A02233 /* AddressDetailsStore.swift in Sources */,
9E6EF2D12913B75400CA007B /* MnemonicKey.swift in Sources */,
0DC487C32772574C00BE6A63 /* RecoveryPhraseBackupSucceededView.swift in Sources */, 0DC487C32772574C00BE6A63 /* RecoveryPhraseBackupSucceededView.swift in Sources */,
2EB1C5E827D77F6100BC43D7 /* TCATextFieldStore.swift in Sources */, 2EB1C5E827D77F6100BC43D7 /* TCATextFieldStore.swift in Sources */,
9E5BF648282277BE00BA3F17 /* WrappedNotificationCenter.swift in Sources */, 9E5BF648282277BE00BA3F17 /* WrappedNotificationCenter.swift in Sources */,
@ -1791,6 +1798,7 @@
9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */, 9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */,
0D0781C9278776D20083ACD7 /* ZcashSymbol.swift in Sources */, 0D0781C9278776D20083ACD7 /* ZcashSymbol.swift in Sources */,
2E8719CB27FB09990082C926 /* TransactionAmountTextField.swift in Sources */, 2E8719CB27FB09990082C926 /* TransactionAmountTextField.swift in Sources */,
9E6EF2D32913B79A00CA007B /* WalletStorageKey.swift in Sources */,
9E7CB6212874143800A02233 /* AddressDetailsView.swift in Sources */, 9E7CB6212874143800A02233 /* AddressDetailsView.swift in Sources */,
9E6713FA289BE0E100A6796F /* ClearBackgroundView.swift in Sources */, 9E6713FA289BE0E100A6796F /* ClearBackgroundView.swift in Sources */,
34E5F2F328E46DB700C17E5F /* DiskSpaceChecker.swift in Sources */, 34E5F2F328E46DB700C17E5F /* DiskSpaceChecker.swift in Sources */,

View File

@ -0,0 +1,20 @@
//
// MnemonicKey.swift
// secant-testnet
//
// Created by Lukáš Korba on 03.11.2022.
//
import ComposableArchitecture
private enum MnemonicKey: DependencyKey {
static let liveValue = WrappedMnemonic.live
static let testValue = WrappedMnemonic.mock
}
extension DependencyValues {
var mnemonic: WrappedMnemonic {
get { self[MnemonicKey.self] }
set { self[MnemonicKey.self] = newValue }
}
}

View File

@ -6,6 +6,7 @@
// //
import Foundation import Foundation
import ComposableArchitecture
struct RecoveryPhraseRandomizer { struct RecoveryPhraseRandomizer {
func random(phrase: RecoveryPhrase) -> RecoveryPhraseValidationFlow.State { func random(phrase: RecoveryPhrase) -> RecoveryPhraseValidationFlow.State {
@ -27,8 +28,6 @@ struct RecoveryPhraseRandomizer {
} }
} }
import ComposableArchitecture
private enum RecoveryPhraseRandomKey: DependencyKey { private enum RecoveryPhraseRandomKey: DependencyKey {
static let liveValue = WrappedRecoveryPhraseRandomizer.live static let liveValue = WrappedRecoveryPhraseRandomizer.live
} }

View File

@ -0,0 +1,20 @@
//
// WalletStorageKey.swift
// secant-testnet
//
// Created by Lukáš Korba on 03.11.2022.
//
import ComposableArchitecture
private enum WalletStorageKey: DependencyKey {
static let liveValue = WrappedWalletStorage.live()
static let testValue = WrappedWalletStorage.throwing
}
extension DependencyValues {
var walletStorage: WrappedWalletStorage {
get { self[WalletStorageKey.self] }
set { self[WalletStorageKey.self] = newValue }
}
}

View File

@ -7,6 +7,7 @@
import Foundation import Foundation
import ZcashLightClientKit import ZcashLightClientKit
import ComposableArchitecture
// swiftlint:disable:next private_over_fileprivate strict_fileprivate // swiftlint:disable:next private_over_fileprivate strict_fileprivate
fileprivate enum ZcashSDKConstants { fileprivate enum ZcashSDKConstants {
@ -80,3 +81,15 @@ extension ZCashSDKEnvironment {
sdkVersion: "0.16.5-beta" sdkVersion: "0.16.5-beta"
) )
} }
private enum ZCashSDKEnvironmentKey: DependencyKey {
static let liveValue = ZCashSDKEnvironment.mainnet
static let testValue = ZCashSDKEnvironment.testnet
}
extension DependencyValues {
var zcashSDKEnvironment: ZCashSDKEnvironment {
get { self[ZCashSDKEnvironmentKey.self] }
set { self[ZCashSDKEnvironmentKey.self] = newValue }
}
}

View File

@ -8,171 +8,148 @@
import ComposableArchitecture import ComposableArchitecture
import ZcashLightClientKit import ZcashLightClientKit
typealias ImportWalletReducer = Reducer<ImportWalletState, ImportWalletAction, ImportWalletEnvironment> typealias ImportWalletStore = Store<ImportWallet.State, ImportWallet.Action>
typealias ImportWalletStore = Store<ImportWalletState, ImportWalletAction> typealias ImportWalletViewStore = ViewStore<ImportWallet.State, ImportWallet.Action>
typealias ImportWalletViewStore = ViewStore<ImportWalletState, ImportWalletAction>
// MARK: - State struct ImportWallet: ReducerProtocol {
struct State: Equatable {
struct ImportWalletState: Equatable { @BindableState var alert: AlertState<ImportWallet.Action>?
@BindableState var alert: AlertState<ImportWalletAction>? @BindableState var importedSeedPhrase: String = ""
@BindableState var importedSeedPhrase: String = "" @BindableState var birthdayHeight: String = ""
@BindableState var birthdayHeight: String = "" var wordsCount = 0
var wordsCount = 0 var maxWordsCount = 0
var maxWordsCount = 0 var isValidMnemonic = false
var isValidMnemonic = false var isValidNumberOfWords = false
var isValidNumberOfWords = false var birthdayHeightValue: BlockHeight?
var birthdayHeightValue: BlockHeight?
var mnemonicStatus: String {
var mnemonicStatus: String { if isValidMnemonic {
if isValidMnemonic { return "VALID SEED PHRASE"
return "VALID SEED PHRASE" } else {
} else { return "\(wordsCount)/\(maxWordsCount)"
return "\(wordsCount)/\(maxWordsCount)" }
}
var isValidForm: Bool {
isValidMnemonic &&
(birthdayHeight.isEmpty ||
(!birthdayHeight.isEmpty && birthdayHeightValue != nil))
} }
} }
var isValidForm: Bool { @Dependency(\.zcashSDKEnvironment) var zcashSDKEnvironment
isValidMnemonic && @Dependency(\.mnemonic) var mnemonic
(birthdayHeight.isEmpty || @Dependency(\.walletStorage) var walletStorage
(!birthdayHeight.isEmpty && birthdayHeightValue != nil))
enum Action: Equatable, BindableAction {
case binding(BindingAction<ImportWallet.State>)
case dismissAlert
case restoreWallet
case importPrivateOrViewingKey
case initializeSDK
case onAppear
case successfullyRecovered
} }
}
var body: some ReducerProtocol<State, Action> {
// MARK: - Action BindingReducer()
enum ImportWalletAction: Equatable, BindableAction { Reduce { state, action in
case binding(BindingAction<ImportWalletState>) switch action {
case dismissAlert case .onAppear:
case restoreWallet state.maxWordsCount = zcashSDKEnvironment.mnemonicWordsMaxCount
case importPrivateOrViewingKey return .none
case initializeSDK
case onAppear case .binding(\.$importedSeedPhrase):
case successfullyRecovered state.wordsCount = state.importedSeedPhrase.split(separator: " ").count
} state.isValidNumberOfWords = state.wordsCount == state.maxWordsCount
// is the mnemonic valid one?
// MARK: - Environment do {
try mnemonic.isValid(state.importedSeedPhrase)
struct ImportWalletEnvironment { } catch {
let mnemonic: WrappedMnemonic state.isValidMnemonic = false
let walletStorage: WrappedWalletStorage return .none
let zcashSDKEnvironment: ZCashSDKEnvironment }
} state.isValidMnemonic = true
return .none
extension ImportWalletEnvironment {
static let live = ImportWalletEnvironment( case .binding(\.$birthdayHeight):
mnemonic: .live, if let birthdayHeight = BlockHeight(state.birthdayHeight), birthdayHeight >= zcashSDKEnvironment.defaultBirthday {
walletStorage: .live(), state.birthdayHeightValue = birthdayHeight
zcashSDKEnvironment: .mainnet } else {
) state.birthdayHeightValue = nil
}
static let demo = ImportWalletEnvironment( return .none
mnemonic: .mock,
walletStorage: .live(), case .binding:
zcashSDKEnvironment: .testnet return .none
)
} case .dismissAlert:
state.alert = nil
// MARK: - Reducer return .none
extension ImportWalletReducer { case .restoreWallet:
static let `default` = ImportWalletReducer { state, action, environment in do {
switch action { // validate the seed
case .onAppear: try mnemonic.isValid(state.importedSeedPhrase)
state.maxWordsCount = environment.zcashSDKEnvironment.mnemonicWordsMaxCount
return .none // store it to the keychain
let birthday = state.birthdayHeightValue ?? zcashSDKEnvironment.defaultBirthday
case .binding(\.$importedSeedPhrase): try walletStorage.importWallet(state.importedSeedPhrase, birthday, .english, false)
state.wordsCount = state.importedSeedPhrase.split(separator: " ").count
state.isValidNumberOfWords = state.wordsCount == state.maxWordsCount // update the backup phrase validation flag
// is the mnemonic valid one? try walletStorage.markUserPassedPhraseBackupTest()
do {
try environment.mnemonic.isValid(state.importedSeedPhrase) // notify user
} catch { // TODO [#221]: Proper Error/Success handling (https://github.com/zcash/secant-ios-wallet/issues/221)
state.isValidMnemonic = false state.alert = AlertState(
title: TextState("Success"),
message: TextState("The wallet has been successfully recovered."),
dismissButton: .default(
TextState("Ok"),
action: .send(.successfullyRecovered)
)
)
return Effect(value: .initializeSDK)
} catch {
// TODO [#221]: Proper Error/Success handling (https://github.com/zcash/secant-ios-wallet/issues/221)
state.alert = AlertState(
title: TextState("Wrong Seed Phrase"),
message: TextState("The seed phrase must be 24 words separated by space."),
dismissButton: .default(
TextState("Ok"),
action: .send(.dismissAlert)
)
)
}
return .none
case .importPrivateOrViewingKey:
return .none
case .successfullyRecovered:
return Effect(value: .dismissAlert)
case .initializeSDK:
return .none return .none
} }
state.isValidMnemonic = true
return .none
case .binding(\.$birthdayHeight):
if let birthdayHeight = BlockHeight(state.birthdayHeight), birthdayHeight >= environment.zcashSDKEnvironment.defaultBirthday {
state.birthdayHeightValue = birthdayHeight
} else {
state.birthdayHeightValue = nil
}
return .none
case .binding:
return .none
case .dismissAlert:
state.alert = nil
return .none
case .restoreWallet:
do {
// validate the seed
try environment.mnemonic.isValid(state.importedSeedPhrase)
// store it to the keychain
var birthday = state.birthdayHeightValue ?? environment.zcashSDKEnvironment.defaultBirthday
try environment.walletStorage.importWallet(state.importedSeedPhrase, birthday, .english, false)
// update the backup phrase validation flag
try environment.walletStorage.markUserPassedPhraseBackupTest()
// notify user
// TODO [#221]: Proper Error/Success handling (https://github.com/zcash/secant-ios-wallet/issues/221)
state.alert = AlertState(
title: TextState("Success"),
message: TextState("The wallet has been successfully recovered."),
dismissButton: .default(
TextState("Ok"),
action: .send(.successfullyRecovered)
)
)
return Effect(value: .initializeSDK)
} catch {
// TODO [#221]: Proper Error/Success handling (https://github.com/zcash/secant-ios-wallet/issues/221)
state.alert = AlertState(
title: TextState("Wrong Seed Phrase"),
message: TextState("The seed phrase must be 24 words separated by space."),
dismissButton: .default(
TextState("Ok"),
action: .send(.dismissAlert)
)
)
}
return .none
case .importPrivateOrViewingKey:
return .none
case .successfullyRecovered:
return Effect(value: .dismissAlert)
case .initializeSDK:
return .none
} }
} }
.binding()
} }
// MARK: - Placeholders // MARK: - Placeholders
extension ImportWalletState { extension ImportWallet.State {
static let placeholder = ImportWalletState() static let placeholder = ImportWallet.State()
static let live = ImportWalletState() static let live = ImportWallet.State()
} }
extension ImportWalletStore { extension ImportWalletStore {
static let demo = Store( static let demo = Store(
initialState: .placeholder, initialState: .placeholder,
reducer: .default, reducer: ImportWallet()
environment: .demo
) )
} }

View File

@ -13,6 +13,8 @@ typealias OnboardingFlowReducer = Reducer<OnboardingFlowState, OnboardingFlowAct
typealias OnboardingFlowStore = Store<OnboardingFlowState, OnboardingFlowAction> typealias OnboardingFlowStore = Store<OnboardingFlowState, OnboardingFlowAction>
typealias OnboardingFlowViewStore = ViewStore<OnboardingFlowState, OnboardingFlowAction> typealias OnboardingFlowViewStore = ViewStore<OnboardingFlowState, OnboardingFlowAction>
typealias AnyImportWalletReducer = AnyReducer<ImportWallet.State, ImportWallet.Action, OnboardingFlowEnvironment>
// MARK: - State // MARK: - State
struct OnboardingFlowState: Equatable { struct OnboardingFlowState: Equatable {
@ -46,7 +48,7 @@ struct OnboardingFlowState: Equatable {
} }
/// Import Wallet /// Import Wallet
var importWalletState: ImportWalletState var importWalletState: ImportWallet.State
} }
extension OnboardingFlowState { extension OnboardingFlowState {
@ -93,7 +95,7 @@ enum OnboardingFlowAction: Equatable {
case updateRoute(OnboardingFlowState.Route?) case updateRoute(OnboardingFlowState.Route?)
case createNewWallet case createNewWallet
case importExistingWallet case importExistingWallet
case importWallet(ImportWalletAction) case importWallet(ImportWallet.Action)
} }
// MARK: - Environment // MARK: - Environment
@ -168,16 +170,13 @@ extension OnboardingFlowReducer {
} }
} }
private static let importWalletReducer: OnboardingFlowReducer = ImportWalletReducer.default.pullback( private static let importWalletReducer: OnboardingFlowReducer = AnyImportWalletReducer { _ in
ImportWallet()
}
.pullback(
state: \OnboardingFlowState.importWalletState, state: \OnboardingFlowState.importWalletState,
action: /OnboardingFlowAction.importWallet, action: /OnboardingFlowAction.importWallet,
environment: { environment in environment: { $0 }
ImportWalletEnvironment(
mnemonic: environment.mnemonic,
walletStorage: environment.walletStorage,
zcashSDKEnvironment: environment.zcashSDKEnvironment
)
}
) )
} }

View File

@ -12,16 +12,9 @@ import ComposableArchitecture
// swiftlint:disable type_body_length // swiftlint:disable type_body_length
class ImportWalletTests: XCTestCase { class ImportWalletTests: XCTestCase {
func testOnAppear() throws { func testOnAppear() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .mock,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore( let store = TestStore(
initialState: .placeholder, initialState: .placeholder,
reducer: ImportWalletReducer.default, reducer: ImportWallet()
environment: testEnvironment
) )
store.send(.onAppear) { state in store.send(.onAppear) { state in
@ -30,16 +23,10 @@ class ImportWalletTests: XCTestCase {
} }
func testWordsCount() throws { func testWordsCount() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore( let store = TestStore(
initialState: .placeholder, initialState: .placeholder,
reducer: ImportWalletReducer.default, reducer: ImportWallet()
environment: testEnvironment .dependency(\.mnemonic, .live)
) )
store.send(.binding(.set(\.$importedSeedPhrase, "one two three"))) { state in store.send(.binding(.set(\.$importedSeedPhrase, "one two three"))) { state in
@ -50,18 +37,12 @@ class ImportWalletTests: XCTestCase {
} }
func testMaxWordsInvalidMnemonic() throws { func testMaxWordsInvalidMnemonic() throws {
let testEnvironment = ImportWalletEnvironment( let store = TestStore(
mnemonic: .live, initialState: ImportWallet.State(maxWordsCount: 24),
walletStorage: .throwing, reducer: ImportWallet()
zcashSDKEnvironment: .testnet .dependency(\.mnemonic, .live)
) )
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$importedSeedPhrase, "a a a a a a a a a a a a a a a a a a a a a a a a"))) { state in store.send(.binding(.set(\.$importedSeedPhrase, "a a a a a a a a a a a a a a a a a a a a a a a a"))) { state in
state.importedSeedPhrase = "a a a a a a a a a a a a a a a a a a a a a a a a" state.importedSeedPhrase = "a a a a a a a a a a a a a a a a a a a a a a a a"
state.wordsCount = 24 state.wordsCount = 24
@ -71,18 +52,12 @@ class ImportWalletTests: XCTestCase {
} }
func testValidMnemonic() throws { func testValidMnemonic() throws {
let testEnvironment = ImportWalletEnvironment( let store = TestStore(
mnemonic: .live, initialState: ImportWallet.State(maxWordsCount: 24),
walletStorage: .throwing, reducer: ImportWallet()
zcashSDKEnvironment: .testnet .dependency(\.mnemonic, .live)
) )
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send( store.send(
.binding( .binding(
.set( .set(
@ -109,16 +84,9 @@ class ImportWalletTests: XCTestCase {
} }
func testInvalidBirthdayHeight_lessThanDefault() throws { func testInvalidBirthdayHeight_lessThanDefault() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .mock,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore( let store = TestStore(
initialState: .placeholder, initialState: .placeholder,
reducer: ImportWalletReducer.default, reducer: ImportWallet()
environment: testEnvironment
) )
store.send(.binding(.set(\.$birthdayHeight, "1600000"))) { state in store.send(.binding(.set(\.$birthdayHeight, "1600000"))) { state in
@ -127,16 +95,9 @@ class ImportWalletTests: XCTestCase {
} }
func testInvalidBirthdayHeight_invalidInput() throws { func testInvalidBirthdayHeight_invalidInput() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .mock,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore( let store = TestStore(
initialState: .placeholder, initialState: .placeholder,
reducer: ImportWalletReducer.default, reducer: ImportWallet()
environment: testEnvironment
) )
store.send(.binding(.set(\.$birthdayHeight, "abc"))) { state in store.send(.binding(.set(\.$birthdayHeight, "abc"))) { state in
@ -145,16 +106,9 @@ class ImportWalletTests: XCTestCase {
} }
func testInvalidBirthdayHeight_validInput() throws { func testInvalidBirthdayHeight_validInput() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .mock,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore( let store = TestStore(
initialState: .placeholder, initialState: .placeholder,
reducer: ImportWalletReducer.default, reducer: ImportWallet()
environment: testEnvironment
) )
store.send(.binding(.set(\.$birthdayHeight, "1700000"))) { state in store.send(.binding(.set(\.$birthdayHeight, "1700000"))) { state in
@ -164,15 +118,9 @@ class ImportWalletTests: XCTestCase {
} }
func testDismissAlert() throws { func testDismissAlert() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .mock,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore( let store = TestStore(
initialState: initialState:
ImportWalletState( ImportWallet.State(
alert: AlertState( alert: AlertState(
title: TextState("Success"), title: TextState("Success"),
message: TextState("The wallet has been successfully recovered."), message: TextState("The wallet has been successfully recovered."),
@ -182,8 +130,7 @@ class ImportWalletTests: XCTestCase {
) )
) )
), ),
reducer: ImportWalletReducer.default, reducer: ImportWallet()
environment: testEnvironment
) )
store.send(.dismissAlert) { state in store.send(.dismissAlert) { state in
@ -192,16 +139,10 @@ class ImportWalletTests: XCTestCase {
} }
func testFormValidity_validBirthday_invalidMnemonic() throws { func testFormValidity_validBirthday_invalidMnemonic() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore( let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24), initialState: ImportWallet.State(maxWordsCount: 24),
reducer: ImportWalletReducer.default, reducer: ImportWallet()
environment: testEnvironment .dependency(\.mnemonic, .live)
) )
store.send(.binding(.set(\.$birthdayHeight, "1700000"))) { state in store.send(.binding(.set(\.$birthdayHeight, "1700000"))) { state in
@ -222,18 +163,12 @@ class ImportWalletTests: XCTestCase {
} }
func testFormValidity_invalidBirthday_invalidMnemonic() throws { func testFormValidity_invalidBirthday_invalidMnemonic() throws {
let testEnvironment = ImportWalletEnvironment( let store = TestStore(
mnemonic: .live, initialState: ImportWallet.State(maxWordsCount: 24),
walletStorage: .throwing, reducer: ImportWallet()
zcashSDKEnvironment: .testnet .dependency(\.mnemonic, .live)
) )
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$birthdayHeight, "1600000"))) { state in store.send(.binding(.set(\.$birthdayHeight, "1600000"))) { state in
state.birthdayHeight = "1600000" state.birthdayHeight = "1600000"
} }
@ -251,18 +186,12 @@ class ImportWalletTests: XCTestCase {
} }
func testFormValidity_invalidBirthday_validMnemonic() throws { func testFormValidity_invalidBirthday_validMnemonic() throws {
let testEnvironment = ImportWalletEnvironment( let store = TestStore(
mnemonic: .live, initialState: ImportWallet.State(maxWordsCount: 24),
walletStorage: .throwing, reducer: ImportWallet()
zcashSDKEnvironment: .testnet .dependency(\.mnemonic, .live)
) )
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$birthdayHeight, "1600000"))) { state in store.send(.binding(.set(\.$birthdayHeight, "1600000"))) { state in
state.birthdayHeight = "1600000" state.birthdayHeight = "1600000"
} }
@ -297,18 +226,12 @@ class ImportWalletTests: XCTestCase {
} }
func testFormValidity_validBirthday_validMnemonic() throws { func testFormValidity_validBirthday_validMnemonic() throws {
let testEnvironment = ImportWalletEnvironment( let store = TestStore(
mnemonic: .live, initialState: ImportWallet.State(maxWordsCount: 24),
walletStorage: .throwing, reducer: ImportWallet()
zcashSDKEnvironment: .testnet .dependency(\.mnemonic, .live)
) )
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$birthdayHeight, "1700000"))) { state in store.send(.binding(.set(\.$birthdayHeight, "1700000"))) { state in
state.birthdayHeight = "1700000" state.birthdayHeight = "1700000"
state.birthdayHeightValue = 1_700_000 state.birthdayHeightValue = 1_700_000
@ -344,18 +267,12 @@ class ImportWalletTests: XCTestCase {
} }
func testFormValidity_noBirthday_validMnemonic() throws { func testFormValidity_noBirthday_validMnemonic() throws {
let testEnvironment = ImportWalletEnvironment( let store = TestStore(
mnemonic: .live, initialState: ImportWallet.State(maxWordsCount: 24),
walletStorage: .throwing, reducer: ImportWallet()
zcashSDKEnvironment: .testnet .dependency(\.mnemonic, .live)
) )
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send( store.send(
.binding( .binding(
.set( .set(
@ -384,20 +301,14 @@ class ImportWalletTests: XCTestCase {
) )
} }
} }
func testRestoreWallet() throws { func testRestoreWallet() throws {
var storage = WalletStorage(secItem: .live) var storage = WalletStorage(secItem: .live)
storage.zcashStoredWalletPrefix = "test_importWallet_" storage.zcashStoredWalletPrefix = "test_importWallet_"
storage.deleteData(forKey: WalletStorage.Constants.zcashStoredWallet) storage.deleteData(forKey: WalletStorage.Constants.zcashStoredWallet)
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .live(walletStorage: storage),
zcashSDKEnvironment: .testnet
)
let store = TestStore( let store = TestStore(
initialState: ImportWalletState( initialState: ImportWallet.State(
alert: nil, alert: nil,
importedSeedPhrase: """ importedSeedPhrase: """
still champion voice habit trend flight \ still champion voice habit trend flight \
@ -412,8 +323,9 @@ class ImportWalletTests: XCTestCase {
isValidNumberOfWords: true, isValidNumberOfWords: true,
birthdayHeightValue: 1_700_000 birthdayHeightValue: 1_700_000
), ),
reducer: ImportWalletReducer.default, reducer: ImportWallet()
environment: testEnvironment .dependency(\.mnemonic, .live)
.dependency(\.walletStorage, .live(walletStorage: storage))
) )
store.send(.restoreWallet) { state in store.send(.restoreWallet) { state in

View File

@ -13,8 +13,7 @@ class ImportWalletSnapshotTests: XCTestCase {
func testImportWalletSnapshot() throws { func testImportWalletSnapshot() throws {
let store = ImportWalletStore( let store = ImportWalletStore(
initialState: .placeholder, initialState: .placeholder,
reducer: .default, reducer: ImportWallet()
environment: .demo
) )
addAttachments(ImportWalletView(store: store)) addAttachments(ImportWalletView(store: store))