[301] Import Wallet does not have a Birthday input field (#328)

- added words counter X/24
- added input for the birthday
- all kinds of validity check implemented
- unit tests for the whole import wallet business logic implemented

[301] Import Wallet does not have a Birthday input field (328)

- support for the birthday to be optional input

[301] Import Wallet does not have a Birthday input field (328)

- Int -> BlockHeight refactor
This commit is contained in:
Lukas Korba 2022-05-26 14:47:55 +02:00 committed by GitHub
parent 4cc7737b21
commit c40b9660e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 589 additions and 14 deletions

View File

@ -100,6 +100,7 @@
9E2F1C8C280ED6A7004E65FE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9E2F1C8B280ED6A7004E65FE /* LaunchScreen.storyboard */; };
9E2F1C8F280EDE09004E65FE /* Drawer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2F1C8E280EDE09004E65FE /* Drawer.swift */; };
9E37A2B827C8F59F00AE57B3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9E37A2B727C8F59F00AE57B3 /* Localizable.strings */; };
9E391124283E4CAC0073DD9A /* ImportWalletTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E391123283E4CAC0073DD9A /* ImportWalletTests.swift */; };
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */; };
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; };
9E5BF63F2819542C00BA3F17 /* TransactionHistoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF63E2819542C00BA3F17 /* TransactionHistoryTests.swift */; };
@ -289,6 +290,7 @@
9E2F1C8B280ED6A7004E65FE /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
9E2F1C8E280EDE09004E65FE /* Drawer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Drawer.swift; sourceTree = "<group>"; };
9E37A2B727C8F59F00AE57B3 /* Localizable.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = "<group>"; };
9E391123283E4CAC0073DD9A /* ImportWalletTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportWalletTests.swift; sourceTree = "<group>"; };
9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphicDesignModifier.swift; sourceTree = "<group>"; };
9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantButtonStyles.swift; sourceTree = "<group>"; };
9E5BF63B2818305D00BA3F17 /* TransactionState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionState.swift; sourceTree = "<group>"; };
@ -476,6 +478,7 @@
0D4E7A1926B364180058B01E /* secantTests */ = {
isa = PBXGroup;
children = (
9E391122283E4C970073DD9A /* ImportWalletTests */,
9E01F8262833CD84000EFC57 /* ScanTests */,
9E5BF642281FEC8700BA3F17 /* SendTests */,
9E5BF63D281953F900BA3F17 /* TransactionHistoryTests */,
@ -746,6 +749,14 @@
path = Drawer;
sourceTree = "<group>";
};
9E391122283E4C970073DD9A /* ImportWalletTests */ = {
isa = PBXGroup;
children = (
9E391123283E4CAC0073DD9A /* ImportWalletTests.swift */,
);
path = ImportWalletTests;
sourceTree = "<group>";
};
9E5BF63D281953F900BA3F17 /* TransactionHistoryTests */ = {
isa = PBXGroup;
children = (
@ -1397,6 +1408,7 @@
9E5BF644281FEC9900BA3F17 /* SendTests.swift in Sources */,
0D1C1AA327611EFD0004AF6A /* RecoveryPhraseDisplayReducerTests.swift in Sources */,
9EAFEB822805793200199FC9 /* AppReducerTests.swift in Sources */,
9E391124283E4CAC0073DD9A /* ImportWalletTests.swift in Sources */,
9E5BF63F2819542C00BA3F17 /* TransactionHistoryTests.swift in Sources */,
0D4E7A1B26B364180058B01E /* secantTests.swift in Sources */,
0DFE93E6272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift in Sources */,

View File

@ -14,6 +14,7 @@ fileprivate enum ZcashSDKConstants {
static let endpointTestnetAddress = "lightwalletd.testnet.electriccoin.co"
static let endpointPort = 9067
static let defaultBlockHeight = 1_629_724
static let mnemonicWordsMaxCount = 24
}
struct ZCashSDKEnvironment {
@ -21,6 +22,7 @@ struct ZCashSDKEnvironment {
let endpoint: LightWalletEndpoint
let lightWalletService: LightWalletService
let network: ZcashNetwork
let mnemonicWordsMaxCount: Int
let isMainnet: () -> Bool
}
@ -32,6 +34,7 @@ extension ZCashSDKEnvironment {
endpoint: LightWalletEndpoint(address: ZcashSDKConstants.endpointMainnetAddress, port: ZcashSDKConstants.endpointPort)
),
network: ZcashNetworkBuilder.network(for: .mainnet),
mnemonicWordsMaxCount: ZcashSDKConstants.mnemonicWordsMaxCount,
isMainnet: { true }
)
@ -42,6 +45,7 @@ extension ZCashSDKEnvironment {
endpoint: LightWalletEndpoint(address: ZcashSDKConstants.endpointTestnetAddress, port: ZcashSDKConstants.endpointPort)
),
network: ZcashNetworkBuilder.network(for: .testnet),
mnemonicWordsMaxCount: ZcashSDKConstants.mnemonicWordsMaxCount,
isMainnet: { false }
)
}

View File

@ -17,6 +17,26 @@ typealias ImportWalletViewStore = ViewStore<ImportWalletState, ImportWalletActio
struct ImportWalletState: Equatable {
@BindableState var alert: AlertState<ImportWalletAction>?
@BindableState var importedSeedPhrase: String = ""
@BindableState var birthdayHeight: String = ""
var wordsCount = 0
var maxWordsCount = 0
var isValidMnemonic = false
var isValidNumberOfWords = false
var birthdayHeightValue: BlockHeight?
var mnemonicStatus: String {
if isValidMnemonic {
return "VALID SEED PHRASE"
} else {
return "\(wordsCount)/\(maxWordsCount)"
}
}
var isValidForm: Bool {
isValidMnemonic &&
(birthdayHeight.isEmpty ||
(!birthdayHeight.isEmpty && birthdayHeightValue != nil))
}
}
// MARK: - Action
@ -24,9 +44,10 @@ struct ImportWalletState: Equatable {
enum ImportWalletAction: Equatable, BindableAction {
case binding(BindingAction<ImportWalletState>)
case dismissAlert
case importRecoveryPhrase
case restoreWallet
case importPrivateOrViewingKey
case initializeSDK
case onAppear
case successfullyRecovered
}
@ -57,6 +78,31 @@ extension ImportWalletEnvironment {
extension ImportWalletReducer {
static let `default` = ImportWalletReducer { state, action, environment in
switch action {
case .onAppear:
state.maxWordsCount = environment.zcashSDKEnvironment.mnemonicWordsMaxCount
return .none
case .binding(\.$importedSeedPhrase):
state.wordsCount = state.importedSeedPhrase.split(separator: " ").count
state.isValidNumberOfWords = state.wordsCount == state.maxWordsCount
// is the mnemonic valid one?
do {
try environment.mnemonic.isValid(state.importedSeedPhrase)
} catch {
state.isValidMnemonic = false
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
@ -64,13 +110,13 @@ extension ImportWalletReducer {
state.alert = nil
return .none
case .importRecoveryPhrase:
case .restoreWallet:
do {
// validate the seed
try environment.mnemonic.isValid(state.importedSeedPhrase)
// store it to the keychain
let birthday = environment.zcashSDKEnvironment.defaultBirthday
var birthday = state.birthdayHeightValue ?? environment.zcashSDKEnvironment.defaultBirthday
try environment.walletStorage.importWallet(state.importedSeedPhrase, birthday, .english, false)
// update the backup phrase validation flag
@ -118,9 +164,9 @@ extension ImportWalletReducer {
// MARK: - Placeholders
extension ImportWalletState {
static let placeholder = ImportWalletState(importedSeedPhrase: "")
static let placeholder = ImportWalletState()
static let live = ImportWalletState(importedSeedPhrase: "")
static let live = ImportWalletState()
}
extension ImportWalletStore {

View File

@ -33,14 +33,30 @@ struct ImportWalletView: View {
}
.padding(18)
ZStack {
ImportSeedEditor(store: store)
mnemonicStatus(viewStore)
}
.frame(width: nil, height: 200, alignment: .center)
Button("importWallet.button.importPhrase") {
viewStore.send(.importRecoveryPhrase)
VStack {
Text("importWallet.birthday.description")
.paragraphText()
TextField("importWallet.birthday.placeholder", text: viewStore.binding(\.$birthdayHeight))
.keyboardType(.numberPad)
.autocapitalization(.none)
.importSeedEditorModifier()
}
.padding(28)
Button("importWallet.button.restoreWallet") {
viewStore.send(.restoreWallet)
}
.activeButtonStyle
.importWalletButtonLayout()
.disabled(!viewStore.isValidForm)
Button("importWallet.button.importPrivateKey") {
viewStore.send(.importPrivateOrViewingKey)
@ -53,11 +69,33 @@ struct ImportWalletView: View {
.navigationBarHidden(true)
.applyScreenBackground()
.scrollableWhenScaledUp()
.onAppear(perform: { viewStore.send(.onAppear) })
.alert(self.store.scope(state: \.alert), dismiss: .dismissAlert)
}
}
}
extension ImportWalletView {
func mnemonicStatus(_ viewStore: ImportWalletViewStore) -> some View {
VStack {
Spacer()
HStack {
Spacer()
Text(viewStore.mnemonicStatus)
.font(.custom(FontFamily.Rubik.regular.name, size: 14))
.foregroundColor(
viewStore.isValidNumberOfWords ?
Asset.Colors.Text.validMnemonic.color :
Asset.Colors.Text.heading.color
)
.padding(.trailing, 35)
.padding(.bottom, 15)
.zIndex(1)
}
}
}
}
// swiftlint:disable:next private_over_fileprivate strict_fileprivate
fileprivate struct ImportWalletButtonLayout: ViewModifier {
func body(content: Content) -> some View {

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x16",
"green" : "0xAF",
"red" : "0x11"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x16",
"green" : "0xAF",
"red" : "0x11"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -111,6 +111,7 @@ internal enum Asset {
internal static let regular = ColorAsset(name: "Regular")
internal static let secondaryButtonText = ColorAsset(name: "SecondaryButtonText")
internal static let titleText = ColorAsset(name: "TitleText")
internal static let validMnemonic = ColorAsset(name: "ValidMnemonic")
internal static let captionText = ColorAsset(name: "captionText")
internal static let captionTextShadow = ColorAsset(name: "captionTextShadow")
internal static let highlightedSuperscriptText = ColorAsset(name: "highlightedSuperscriptText")

View File

@ -52,8 +52,11 @@
// MARK: - Import Wallet Screen
"importWallet.title" = "Wallet Import";
"importWallet.description" = "You can import your backed up wallet by entering your backup recovery phrase (aka seed phrase) now.";
"importWallet.button.importPhrase" = "Import Recovery Phrase";
"importWallet.button.restoreWallet" = "Restore wallet";
"importWallet.button.importPrivateKey" = "Import a private or viewing key";
"importWallet.birthday.description" = "Add your wallet's birthday to sync up quicker. Leave it blank if you don't know it.";
"importWallet.birthday.placeholder" = "Enter birthday height";
// MARK: - Home Screen
"home.request" = "Request ZEC";

View File

@ -22,7 +22,8 @@ struct ImportSeedEditor: View {
TextEditor(text: viewStore.binding(\.$importedSeedPhrase))
.autocapitalization(.none)
.importSeedEditorModifier()
.padding(28)
.padding(.horizontal, 28)
.padding(.vertical, 10)
}
}
}

View File

@ -0,0 +1,432 @@
//
// ImportWalletTests.swift
// secantTests
//
// Created by Lukáš Korba on 25.05.2022.
//
import XCTest
@testable import secant_testnet
import ComposableArchitecture
// swiftlint:disable type_body_length
class ImportWalletTests: XCTestCase {
func testOnAppear() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .mock,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.onAppear) { state in
state.maxWordsCount = 24
}
}
func testWordsCount() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$importedSeedPhrase, "one two three"))) { state in
state.importedSeedPhrase = "one two three"
state.wordsCount = 3
state.isValidMnemonic = false
}
}
func testMaxWordsInvalidMnemonic() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
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
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.isValidNumberOfWords = true
state.isValidMnemonic = false
}
}
func testValidMnemonic() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(
.binding(
.set(
\.$importedSeedPhrase,
"""
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
)
)
) { state in
state.importedSeedPhrase = """
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
state.wordsCount = 24
state.isValidNumberOfWords = true
state.isValidMnemonic = true
}
}
func testInvalidBirthdayHeight_lessThanDefault() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .mock,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$birthdayHeight, "1600000"))) { state in
state.birthdayHeight = "1600000"
}
}
func testInvalidBirthdayHeight_invalidInput() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .mock,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$birthdayHeight, "abc"))) { state in
state.birthdayHeight = "abc"
}
}
func testInvalidBirthdayHeight_validInput() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .mock,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$birthdayHeight, "1700000"))) { state in
state.birthdayHeight = "1700000"
state.birthdayHeightValue = 1_700_000
}
}
func testDismissAlert() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .mock,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState:
ImportWalletState(
alert: AlertState(
title: TextState("Success"),
message: TextState("The wallet has been successfully recovered."),
dismissButton: .default(
TextState("Ok"),
action: .send(.successfullyRecovered)
)
)
),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.dismissAlert) { state in
state.alert = nil
}
}
func testFormValidity_validBirthday_invalidMnemonic() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$birthdayHeight, "1700000"))) { state in
state.birthdayHeight = "1700000"
state.birthdayHeightValue = 1_700_000
}
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.wordsCount = 24
state.isValidNumberOfWords = true
state.isValidMnemonic = false
XCTAssertFalse(
state.isValidForm,
"Import Wallet tests: `testFormValidity_validBirthday_validMnemonic` is expected to be false but it is \(state.isValidForm)"
)
}
}
func testFormValidity_invalidBirthday_invalidMnemonic() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$birthdayHeight, "1600000"))) { state in
state.birthdayHeight = "1600000"
}
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.wordsCount = 24
state.isValidNumberOfWords = true
state.isValidMnemonic = false
XCTAssertFalse(
state.isValidForm,
"Import Wallet tests: `testFormValidity_validBirthday_validMnemonic` is expected to be false but it is \(state.isValidForm)"
)
}
}
func testFormValidity_invalidBirthday_validMnemonic() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$birthdayHeight, "1600000"))) { state in
state.birthdayHeight = "1600000"
}
store.send(
.binding(
.set(
\.$importedSeedPhrase,
"""
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
)
)
) { state in
state.importedSeedPhrase = """
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
state.wordsCount = 24
state.isValidNumberOfWords = true
state.isValidMnemonic = true
XCTAssertFalse(
state.isValidForm,
"Import Wallet tests: `testFormValidity_validBirthday_validMnemonic` is expected to be false but it is \(state.isValidForm)"
)
}
}
func testFormValidity_validBirthday_validMnemonic() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.binding(.set(\.$birthdayHeight, "1700000"))) { state in
state.birthdayHeight = "1700000"
state.birthdayHeightValue = 1_700_000
}
store.send(
.binding(
.set(
\.$importedSeedPhrase,
"""
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
)
)
) { state in
state.importedSeedPhrase = """
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
state.wordsCount = 24
state.isValidNumberOfWords = true
state.isValidMnemonic = true
XCTAssertTrue(
state.isValidForm,
"Import Wallet tests: `testFormValidity_validBirthday_validMnemonic` is expected to be true but it is \(state.isValidForm)"
)
}
}
func testFormValidity_noBirthday_validMnemonic() throws {
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .throwing,
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: ImportWalletState(maxWordsCount: 24),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(
.binding(
.set(
\.$importedSeedPhrase,
"""
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
)
)
) { state in
state.importedSeedPhrase = """
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
state.wordsCount = 24
state.isValidNumberOfWords = true
state.isValidMnemonic = true
XCTAssertTrue(
state.isValidForm,
"Import Wallet tests: `testFormValidity_validBirthday_validMnemonic` is expected to be true but it is \(state.isValidForm)"
)
}
}
func testRestoreWallet() throws {
var storage = WalletStorage(secItem: .live)
storage.zcashStoredWalletPrefix = "test_importWallet_"
storage.deleteData(forKey: WalletStorage.Constants.zcashStoredWallet)
let testEnvironment = ImportWalletEnvironment(
mnemonic: .live,
walletStorage: .live(walletStorage: storage),
zcashSDKEnvironment: .testnet
)
let store = TestStore(
initialState: ImportWalletState(
alert: nil,
importedSeedPhrase: """
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
""",
birthdayHeight: "1700000",
wordsCount: 24,
maxWordsCount: 24,
isValidMnemonic: true,
isValidNumberOfWords: true,
birthdayHeightValue: 1_700_000
),
reducer: ImportWalletReducer.default,
environment: testEnvironment
)
store.send(.restoreWallet) { state in
state.alert = AlertState(
title: TextState("Success"),
message: TextState("The wallet has been successfully recovered."),
dismissButton: .default(
TextState("Ok"),
action: .send(.successfullyRecovered)
)
)
}
store.receive(.initializeSDK)
}
}

View File

@ -20,7 +20,7 @@ class SendTests: XCTestCase {
override func setUp() {
super.setUp()
storage.zcashStoredWalletPrefix = "test_"
storage.zcashStoredWalletPrefix = "test_send_"
storage.deleteData(forKey: WalletStorage.Constants.zcashStoredWallet)
}

View File

@ -30,7 +30,7 @@ class WalletStorageTests: XCTestCase {
override func setUp() {
super.setUp()
storage.zcashStoredWalletPrefix = "test_"
storage.zcashStoredWalletPrefix = "test_walletStorage_"
deleteData(forKey: WalletStorage.Constants.zcashStoredWallet)
}