- Int64+Zcash.swift and Double+Zcash.swift removed - Balances and amounts updated to use Zatoshi - Remove TODOs - Tests updated - FIXED: Send amount being in Zatoshi is clamping $ value to 21M max -> send amount input is no longer Zatoshi typed [329] Update wallet to use Zatoshi type (333) - alphabetical order(s) [329] Update wallet to use Zatoshi type (333) - static .zero for the Zatoshi - conformance to Equatable moved to extension [329] Update wallet to use Zatoshi type (333) - small improvement by reducing code duplicity
This commit is contained in:
parent
bab1dc6f82
commit
b2ae82ce1b
|
@ -95,14 +95,12 @@
|
|||
9E2DF99C27CF704D00649636 /* ImportWalletStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99827CF704D00649636 /* ImportWalletStore.swift */; };
|
||||
9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */; };
|
||||
9E2DF99E27CF704D00649636 /* ImportWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99B27CF704D00649636 /* ImportWalletView.swift */; };
|
||||
9E2F1C8228095AFE004E65FE /* Int64+Zcash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2F1C8128095AFE004E65FE /* Int64+Zcash.swift */; };
|
||||
9E2F1C842809B606004E65FE /* DebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2F1C832809B606004E65FE /* DebugMenu.swift */; };
|
||||
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 */; };
|
||||
9E391129283F74590073DD9A /* Zatoshi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E391128283F74590073DD9A /* Zatoshi.swift */; };
|
||||
9E39112A283F90F10073DD9A /* Double+Zcash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDDEA8B28250F9C00B4100C /* Double+Zcash.swift */; };
|
||||
9E39112E283F91600073DD9A /* ZatoshiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E39112D283F91600073DD9A /* ZatoshiTests.swift */; };
|
||||
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */; };
|
||||
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; };
|
||||
|
@ -287,7 +285,6 @@
|
|||
9E2DF99827CF704D00649636 /* ImportWalletStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletStore.swift; sourceTree = "<group>"; };
|
||||
9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportSeedEditor.swift; sourceTree = "<group>"; };
|
||||
9E2DF99B27CF704D00649636 /* ImportWalletView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletView.swift; sourceTree = "<group>"; };
|
||||
9E2F1C8128095AFE004E65FE /* Int64+Zcash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Int64+Zcash.swift"; sourceTree = "<group>"; };
|
||||
9E2F1C832809B606004E65FE /* DebugMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugMenu.swift; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
|
@ -330,7 +327,6 @@
|
|||
9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SandboxStore.swift; sourceTree = "<group>"; };
|
||||
9EBEF87927CE369800B4F343 /* RecoveryPhraseValidationFlowView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseValidationFlowView.swift; sourceTree = "<group>"; };
|
||||
9ECAE56727FC713C0089A0EF /* DatabaseFiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseFiles.swift; sourceTree = "<group>"; };
|
||||
9EDDEA8B28250F9C00B4100C /* Double+Zcash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+Zcash.swift"; sourceTree = "<group>"; };
|
||||
9EDDEA9F2829610D00B4100C /* CurrencySelectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrencySelectionTests.swift; sourceTree = "<group>"; };
|
||||
9EDDEAA02829610D00B4100C /* TransactionAmountInputTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionAmountInputTests.swift; sourceTree = "<group>"; };
|
||||
9EDDEAA12829610D00B4100C /* TransactionAddressInputTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionAddressInputTests.swift; sourceTree = "<group>"; };
|
||||
|
@ -824,12 +820,10 @@
|
|||
children = (
|
||||
F96B41EA273B50520021B49A /* Strings.swift */,
|
||||
9E7FE0D4282D281800C374E8 /* Array+Chunked.swift */,
|
||||
9E2F1C8128095AFE004E65FE /* Int64+Zcash.swift */,
|
||||
0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */,
|
||||
0D7CE63327349B5D0020E050 /* View+WhenDraggable.swift */,
|
||||
9E7FE0D2282D274E00C374E8 /* Date+Readable.swift */,
|
||||
9E7FE0CE282D257400C374E8 /* SDKSynchronizer+SyncStatus.swift */,
|
||||
9EDDEA8B28250F9C00B4100C /* Double+Zcash.swift */,
|
||||
0DACFA7E27208CE00039EEA5 /* Clamped.swift */,
|
||||
F9322DBF273B555C00C105B5 /* NavigationLinks.swift */,
|
||||
F9C165B3274031F600592F76 /* Bindings.swift */,
|
||||
|
@ -1286,7 +1280,6 @@
|
|||
9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */,
|
||||
9E80B47227E4B34B008FF493 /* UserPreferencesStorage.swift in Sources */,
|
||||
F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */,
|
||||
9E2F1C8228095AFE004E65FE /* Int64+Zcash.swift in Sources */,
|
||||
9E02B56A27FED43E005B809B /* WrappedFileManager.swift in Sources */,
|
||||
663FABA2271D876C00E495F8 /* SecondaryButton.swift in Sources */,
|
||||
0DC487C32772574C00BE6A63 /* RecoveryPhraseBackupSucceededView.swift in Sources */,
|
||||
|
@ -1310,7 +1303,6 @@
|
|||
0DDB6A5127737D4A0012A410 /* RecoveryPhraseBackupFailedView.swift in Sources */,
|
||||
9E391129283F74590073DD9A /* Zatoshi.swift in Sources */,
|
||||
0D6D628B276A528E002FB4CC /* DropDelegate.swift in Sources */,
|
||||
9E39112A283F90F10073DD9A /* Double+Zcash.swift in Sources */,
|
||||
9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */,
|
||||
F9971A5327680DD000A2DB75 /* ProfileStore.swift in Sources */,
|
||||
669FDAEB272C23C2007B9422 /* CircularFrameBadge.swift in Sources */,
|
||||
|
|
|
@ -27,9 +27,9 @@ struct HomeState: Equatable {
|
|||
var sendState: SendFlowState
|
||||
var scanState: ScanState
|
||||
var synchronizerStatus: String
|
||||
var totalBalance: Int64
|
||||
var totalBalance: Zatoshi
|
||||
var transactionHistoryState: TransactionHistoryFlowState
|
||||
var verifiedBalance: Int64
|
||||
var verifiedBalance: Zatoshi
|
||||
}
|
||||
|
||||
// MARK: Action
|
||||
|
@ -110,8 +110,8 @@ extension HomeReducer {
|
|||
return Effect(value: .updateSynchronizerStatus)
|
||||
|
||||
case .updateBalance(let balance):
|
||||
state.totalBalance = balance.total
|
||||
state.verifiedBalance = balance.verified
|
||||
state.totalBalance = Zatoshi(amount: balance.total)
|
||||
state.verifiedBalance = Zatoshi(amount: balance.verified)
|
||||
return .none
|
||||
|
||||
case .updateDrawer(let drawerOverlay):
|
||||
|
@ -179,11 +179,11 @@ extension HomeReducer {
|
|||
action: /HomeAction.send,
|
||||
environment: { environment in
|
||||
SendFlowEnvironment(
|
||||
mnemonic: environment.mnemonic,
|
||||
scheduler: environment.scheduler,
|
||||
walletStorage: environment.walletStorage,
|
||||
derivationTool: environment.derivationTool,
|
||||
SDKSynchronizer: environment.SDKSynchronizer
|
||||
mnemonic: environment.mnemonic,
|
||||
SDKSynchronizer: environment.SDKSynchronizer,
|
||||
scheduler: environment.scheduler,
|
||||
walletStorage: environment.walletStorage
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -282,9 +282,9 @@ extension HomeState {
|
|||
sendState: .placeholder,
|
||||
scanState: .placeholder,
|
||||
synchronizerStatus: "",
|
||||
totalBalance: 0,
|
||||
totalBalance: Zatoshi.zero,
|
||||
transactionHistoryState: .emptyPlaceHolder,
|
||||
verifiedBalance: 0
|
||||
verifiedBalance: Zatoshi.zero
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ struct HomeView: View {
|
|||
Text("\(viewStore.synchronizerStatus)")
|
||||
.padding(.top, 60)
|
||||
|
||||
Text("balance \(viewStore.totalBalance.asZecString()) ZEC")
|
||||
Text("balance \(viewStore.totalBalance.decimalString()) ZEC")
|
||||
.accessDebugMenuWithHiddenGesture {
|
||||
viewStore.send(.debugMenuStartup)
|
||||
}
|
||||
|
|
|
@ -32,11 +32,11 @@ struct SandboxView: View {
|
|||
)
|
||||
.debug(),
|
||||
environment: SendFlowEnvironment(
|
||||
mnemonic: .live,
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
walletStorage: .live(),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: LiveWrappedSDKSynchronizer()
|
||||
mnemonic: .live,
|
||||
SDKSynchronizer: LiveWrappedSDKSynchronizer(),
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
walletStorage: .live()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -23,11 +23,10 @@ struct SendFlowState: Equatable {
|
|||
case done
|
||||
}
|
||||
|
||||
var route: Route?
|
||||
|
||||
var isSendingTransaction = false
|
||||
var memo = ""
|
||||
var totalBalance: Int64 = 0
|
||||
var route: Route?
|
||||
var totalBalance = Zatoshi.zero
|
||||
var transaction: SendFlowTransaction
|
||||
var transactionAddressInputState: TransactionAddressTextFieldState
|
||||
var transactionAmountInputState: TransactionAmountTextFieldState
|
||||
|
@ -52,8 +51,8 @@ struct SendFlowState: Equatable {
|
|||
transactionAmountInputState.amount > transactionAmountInputState.maxValue
|
||||
}
|
||||
|
||||
var totalCurrencyBalance: Int64 {
|
||||
(totalBalance.asHumanReadableZecBalance() * transactionAmountInputState.zecPrice).asZec()
|
||||
var totalCurrencyBalance: Zatoshi {
|
||||
Zatoshi.from(decimal: totalBalance.decimalValue.decimalValue * transactionAmountInputState.zecPrice)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +66,7 @@ enum SendFlowAction: Equatable {
|
|||
case synchronizerStateChanged(WrappedSDKSynchronizerState)
|
||||
case transactionAddressInput(TransactionAddressTextFieldAction)
|
||||
case transactionAmountInput(TransactionAmountTextFieldAction)
|
||||
case updateBalance(Int64)
|
||||
case updateBalance(Zatoshi)
|
||||
case updateMemo(String)
|
||||
case updateTransaction(SendFlowTransaction)
|
||||
case updateRoute(SendFlowState.Route?)
|
||||
|
@ -76,11 +75,11 @@ enum SendFlowAction: Equatable {
|
|||
// MARK: - Environment
|
||||
|
||||
struct SendFlowEnvironment {
|
||||
let derivationTool: WrappedDerivationTool
|
||||
let mnemonic: WrappedMnemonic
|
||||
let SDKSynchronizer: WrappedSDKSynchronizer
|
||||
let scheduler: AnySchedulerOf<DispatchQueue>
|
||||
let walletStorage: WrappedWalletStorage
|
||||
let derivationTool: WrappedDerivationTool
|
||||
let SDKSynchronizer: WrappedSDKSynchronizer
|
||||
}
|
||||
|
||||
// MARK: - Reducer
|
||||
|
@ -109,7 +108,7 @@ extension SendFlowReducer {
|
|||
return .none
|
||||
|
||||
case .updateRoute(.confirmation):
|
||||
state.transaction.amount = state.transactionAmountInputState.amount
|
||||
state.transaction.amount = Zatoshi(amount: state.transactionAmountInputState.amount)
|
||||
state.transaction.toAddress = state.transactionAddressInputState.textFieldState.text
|
||||
return .none
|
||||
|
||||
|
@ -133,7 +132,7 @@ extension SendFlowReducer {
|
|||
|
||||
return environment.SDKSynchronizer.sendTransaction(
|
||||
with: spendingKey,
|
||||
zatoshi: Int64(state.transaction.amount),
|
||||
zatoshi: state.transaction.amount,
|
||||
to: state.transaction.toAddress,
|
||||
memo: state.transaction.memo,
|
||||
from: 0
|
||||
|
@ -172,7 +171,7 @@ extension SendFlowReducer {
|
|||
case .synchronizerStateChanged(.synced):
|
||||
return environment.SDKSynchronizer.getShieldedBalance()
|
||||
.receive(on: environment.scheduler)
|
||||
.map({ $0.total })
|
||||
.map({ Zatoshi(amount: $0.total) })
|
||||
.map(SendFlowAction.updateBalance)
|
||||
.eraseToEffect()
|
||||
|
||||
|
@ -181,7 +180,7 @@ extension SendFlowReducer {
|
|||
|
||||
case .updateBalance(let balance):
|
||||
state.totalBalance = balance
|
||||
state.transactionAmountInputState.maxValue = balance
|
||||
state.transactionAmountInputState.maxValue = balance.amount
|
||||
return .none
|
||||
|
||||
case .updateMemo(let memo):
|
||||
|
@ -287,7 +286,7 @@ extension SendFlowState {
|
|||
.init(
|
||||
route: nil,
|
||||
transaction: .init(
|
||||
amount: 0,
|
||||
amount: Zatoshi.zero,
|
||||
memo: "",
|
||||
toAddress: ""
|
||||
),
|
||||
|
@ -309,11 +308,11 @@ extension SendFlowStore {
|
|||
),
|
||||
reducer: .default,
|
||||
environment: SendFlowEnvironment(
|
||||
mnemonic: .live,
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
walletStorage: .live(),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: LiveWrappedSDKSynchronizer()
|
||||
mnemonic: .live,
|
||||
SDKSynchronizer: LiveWrappedSDKSynchronizer(),
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
walletStorage: .live()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -41,11 +41,11 @@ struct SendFLowView_Previews: PreviewProvider {
|
|||
),
|
||||
reducer: .default,
|
||||
environment: SendFlowEnvironment(
|
||||
mnemonic: .live,
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
walletStorage: .live(),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: LiveWrappedSDKSynchronizer()
|
||||
mnemonic: .live,
|
||||
SDKSynchronizer: LiveWrappedSDKSynchronizer(),
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
walletStorage: .live()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -10,8 +10,8 @@ struct CreateTransaction: View {
|
|||
return WithViewStore(store) { viewStore in
|
||||
VStack {
|
||||
VStack(spacing: 0) {
|
||||
Text("Balance \(viewStore.totalBalance.asZecString()) ZEC")
|
||||
Text("($\(viewStore.totalCurrencyBalance.asZecString()))")
|
||||
Text("Balance \(viewStore.totalBalance.decimalString()) ZEC")
|
||||
Text("($\(viewStore.totalCurrencyBalance.decimalString()))")
|
||||
.font(.system(size: 13))
|
||||
.opacity(0.6)
|
||||
}
|
||||
|
@ -32,9 +32,7 @@ struct CreateTransaction: View {
|
|||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
|
||||
if viewStore.isInsufficientFunds {
|
||||
} else if viewStore.isInsufficientFunds {
|
||||
HStack {
|
||||
Text("insufficient funds")
|
||||
.foregroundColor(.red)
|
||||
|
|
|
@ -6,7 +6,7 @@ struct TransactionConfirmation: View {
|
|||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Text("Send \(viewStore.transaction.amount.asZecString()) ZEC")
|
||||
Text("Send \(viewStore.transaction.amount.decimalString()) ZEC")
|
||||
.padding()
|
||||
|
||||
Text("To \(viewStore.transaction.toAddress)")
|
||||
|
|
|
@ -101,7 +101,7 @@ extension TransactionState {
|
|||
id: "2",
|
||||
status: .paid(success: true),
|
||||
subtitle: "",
|
||||
zecAmount: 25
|
||||
zecAmount: Zatoshi(amount: 25)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ extension IdentifiedArrayOf where Element == TransactionState {
|
|||
id: String($0),
|
||||
status: .paid(success: true),
|
||||
subtitle: "",
|
||||
zecAmount: 25
|
||||
zecAmount: Zatoshi(amount: 25)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -52,7 +52,7 @@ extension TransactionHistoryFlowView {
|
|||
Spacer()
|
||||
|
||||
Text(transaction.status == .received ? "+" : "")
|
||||
+ Text("\(transaction.zecAmount.asZecString()) ZEC")
|
||||
+ Text("\(transaction.zecAmount.decimalString()) ZEC")
|
||||
}
|
||||
}
|
||||
.navigationLink(
|
||||
|
|
|
@ -9,7 +9,7 @@ import Foundation
|
|||
|
||||
/// Simple model that holds data throughout the `SendFlow` feature
|
||||
struct SendFlowTransaction: Equatable {
|
||||
var amount: Int64
|
||||
var amount: Zatoshi
|
||||
var memo: String
|
||||
var toAddress: String
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ struct SendFlowTransaction: Equatable {
|
|||
extension SendFlowTransaction {
|
||||
static var placeholder: Self {
|
||||
.init(
|
||||
amount: 0,
|
||||
amount: Zatoshi.zero,
|
||||
memo: "",
|
||||
toAddress: ""
|
||||
)
|
||||
|
|
|
@ -25,7 +25,7 @@ struct TransactionState: Equatable, Identifiable {
|
|||
var id: String
|
||||
var status: Status
|
||||
var subtitle: String
|
||||
var zecAmount: Int64
|
||||
var zecAmount: Zatoshi
|
||||
}
|
||||
|
||||
extension TransactionState {
|
||||
|
@ -36,7 +36,7 @@ extension TransactionState {
|
|||
status = sent ? .paid(success: confirmedTransaction.minedHeight > 0) : .received
|
||||
subtitle = "sent"
|
||||
zAddress = confirmedTransaction.toAddress
|
||||
zecAmount = (sent ? -Int64(confirmedTransaction.value) : Int64(confirmedTransaction.value))
|
||||
zecAmount = sent ? Zatoshi(amount: -Int64(confirmedTransaction.value)) : Zatoshi(amount: Int64(confirmedTransaction.value))
|
||||
if let memo = confirmedTransaction.memo {
|
||||
self.memo = memo.asZcashTransactionMemo()
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ extension TransactionState {
|
|||
expirationHeight = pendingTransaction.expiryHeight
|
||||
subtitle = "pending"
|
||||
zAddress = pendingTransaction.toAddress
|
||||
zecAmount = -Int64(pendingTransaction.value)
|
||||
zecAmount = Zatoshi(amount: -Int64(pendingTransaction.value))
|
||||
if let memo = pendingTransaction.memo {
|
||||
self.memo = memo.asZcashTransactionMemo()
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ extension TransactionState {
|
|||
extension TransactionState {
|
||||
static func placeholder(
|
||||
date: Date,
|
||||
amount: Int64,
|
||||
amount: Zatoshi,
|
||||
shielded: Bool = true,
|
||||
status: Status = .received,
|
||||
subtitle: String = "",
|
||||
|
@ -80,14 +80,14 @@ extension TransactionState {
|
|||
id: uuid,
|
||||
status: status,
|
||||
subtitle: subtitle,
|
||||
zecAmount: status == .received ? amount : -amount
|
||||
zecAmount: status == .received ? amount : Zatoshi(amount: -amount.amount)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct TransactionStateMockHelper {
|
||||
var date: TimeInterval
|
||||
var amount: Int64
|
||||
var amount: Zatoshi
|
||||
var shielded = true
|
||||
var status: TransactionState.Status = .received
|
||||
var subtitle = "cleared"
|
||||
|
|
|
@ -17,8 +17,8 @@ typealias TransactionAddressTextFieldReducer = Reducer<
|
|||
typealias TransactionAddressTextFieldStore = Store<TransactionAddressTextFieldState, TransactionAddressTextFieldAction>
|
||||
|
||||
struct TransactionAddressTextFieldState: Equatable {
|
||||
var textFieldState: TCATextFieldState
|
||||
var isValidAddress = false
|
||||
var textFieldState: TCATextFieldState
|
||||
}
|
||||
|
||||
enum TransactionAddressTextFieldAction: Equatable {
|
||||
|
|
|
@ -59,11 +59,11 @@ struct TransactionAmountTextField_Previews: PreviewProvider {
|
|||
TransactionAmountTextField(
|
||||
store: TransactionAmountTextFieldStore(
|
||||
initialState: .init(
|
||||
currencySelectionState: .init(currencyType: .usd),
|
||||
textFieldState: .init(
|
||||
validationType: .floatingPoint,
|
||||
text: ""
|
||||
),
|
||||
currencySelectionState: .init(currencyType: .usd)
|
||||
)
|
||||
),
|
||||
reducer: .default,
|
||||
environment: .init()
|
||||
|
|
|
@ -16,29 +16,12 @@ typealias TransactionAmountTextFieldReducer = Reducer<
|
|||
typealias TransactionAmountTextFieldStore = Store<TransactionAmountTextFieldState, TransactionAmountTextFieldAction>
|
||||
|
||||
struct TransactionAmountTextFieldState: Equatable {
|
||||
var textFieldState: TCATextFieldState
|
||||
var amount: Int64 = 0
|
||||
var currencySelectionState: CurrencySelectionState
|
||||
var maxValue: Int64 = 0
|
||||
var textFieldState: TCATextFieldState
|
||||
// TODO: - Get the ZEC price from the SDK, issue 311, https://github.com/zcash/secant-ios-wallet/issues/311
|
||||
var zecPrice = 140.0
|
||||
|
||||
var amount: Int64 {
|
||||
switch currencySelectionState.currencyType {
|
||||
case .zec:
|
||||
return (textFieldState.text.doubleValue ?? 0.0).asZec()
|
||||
case .usd:
|
||||
return ((textFieldState.text.doubleValue ?? 0.0) / zecPrice).asZec()
|
||||
}
|
||||
}
|
||||
|
||||
var maxCurrencyConvertedValue: Int64 {
|
||||
switch currencySelectionState.currencyType {
|
||||
case .zec:
|
||||
return maxValue
|
||||
case .usd:
|
||||
return (maxValue.asHumanReadableZecBalance() * zecPrice).asZec()
|
||||
}
|
||||
}
|
||||
var zecPrice = Decimal(140.0)
|
||||
|
||||
var isMax: Bool {
|
||||
return amount == maxValue
|
||||
|
@ -47,9 +30,10 @@ struct TransactionAmountTextFieldState: Equatable {
|
|||
|
||||
enum TransactionAmountTextFieldAction: Equatable {
|
||||
case clearValue
|
||||
case currencySelection(CurrencySelectionAction)
|
||||
case setMax
|
||||
case textField(TCATextFieldAction)
|
||||
case currencySelection(CurrencySelectionAction)
|
||||
case updateAmount
|
||||
}
|
||||
|
||||
struct TransactionAmountTextFieldEnvironment: Equatable {}
|
||||
|
@ -59,43 +43,65 @@ extension TransactionAmountTextFieldReducer {
|
|||
[
|
||||
textFieldReducer,
|
||||
currencySelectionReducer,
|
||||
maxOverride,
|
||||
currencyUpdate
|
||||
amountTextFieldReducer
|
||||
]
|
||||
)
|
||||
|
||||
static let maxOverride = TransactionAmountTextFieldReducer { state, action, _ in
|
||||
static let amountTextFieldReducer = TransactionAmountTextFieldReducer { state, action, _ in
|
||||
switch action {
|
||||
case .setMax:
|
||||
state.textFieldState.text = "\(state.maxCurrencyConvertedValue.asZecString())"
|
||||
let maxValueAsZec = Decimal(state.maxValue) / Decimal(Zatoshi.Constants.oneZecInZatoshi)
|
||||
let currencyType = state.currencySelectionState.currencyType
|
||||
let maxCurrencyConvertedValue: NSDecimalNumber = currencyType == .zec ?
|
||||
NSDecimalNumber(decimal: maxValueAsZec).roundedZec :
|
||||
NSDecimalNumber(decimal: maxValueAsZec * state.zecPrice).roundedZec
|
||||
|
||||
// TODO: these test will be updated with the NumberFormater dependency to handle locale, issue #312 (https://github.com/zcash/secant-ios-wallet/issues/312)
|
||||
let decimalString = NumberFormatter.zcashNumberFormatter.string(from: maxCurrencyConvertedValue) ?? ""
|
||||
|
||||
state.textFieldState.text = "\(decimalString)"
|
||||
return Effect(value: .updateAmount)
|
||||
|
||||
case .clearValue:
|
||||
state.textFieldState.text = ""
|
||||
return .none
|
||||
|
||||
case .textField(.set(let amount)):
|
||||
return Effect(value: .updateAmount)
|
||||
|
||||
default: break
|
||||
}
|
||||
|
||||
return .none
|
||||
}
|
||||
|
||||
static let currencyUpdate = TransactionAmountTextFieldReducer { state, action, _ in
|
||||
switch action {
|
||||
case .currencySelection:
|
||||
guard let currentDoubleValue = state.textFieldState.text.doubleValue else {
|
||||
case .updateAmount:
|
||||
// TODO: these test will be updated with the NumberFormater dependency to handle locale, issue #312 (https://github.com/zcash/secant-ios-wallet/issues/312)
|
||||
guard var number = NumberFormatter.zcashNumberFormatter.number(from: state.textFieldState.text) else {
|
||||
state.amount = 0
|
||||
return .none
|
||||
}
|
||||
|
||||
switch state.currencySelectionState.currencyType {
|
||||
case .zec:
|
||||
state.amount = NSDecimalNumber(decimal: number.decimalValue * Decimal(Zatoshi.Constants.oneZecInZatoshi)).roundedZec.int64Value
|
||||
case .usd:
|
||||
let decimal = (number.decimalValue / state.zecPrice) * Decimal(Zatoshi.Constants.oneZecInZatoshi)
|
||||
state.amount = NSDecimalNumber(decimal: decimal).roundedZec.int64Value
|
||||
}
|
||||
return .none
|
||||
|
||||
case .currencySelection:
|
||||
// TODO: these test will be updated with the NumberFormater dependency to handle locale, issue #312 (https://github.com/zcash/secant-ios-wallet/issues/312)
|
||||
guard let number = NumberFormatter.zcashNumberFormatter.number(from: state.textFieldState.text) else {
|
||||
state.amount = 0
|
||||
return .none
|
||||
}
|
||||
|
||||
let currencyType = state.currencySelectionState.currencyType
|
||||
|
||||
|
||||
let newValue = currencyType == .zec ?
|
||||
currentDoubleValue / state.zecPrice :
|
||||
currentDoubleValue * state.zecPrice
|
||||
state.textFieldState.text = "\(newValue.asZecString())"
|
||||
|
||||
default: break
|
||||
number.decimalValue / state.zecPrice :
|
||||
number.decimalValue * state.zecPrice
|
||||
|
||||
// TODO: these test will be updated with the NumberFormater dependency to handle locale, issue #312 (https://github.com/zcash/secant-ios-wallet/issues/312)
|
||||
let decimalString = NumberFormatter.zcashNumberFormatter.string(from: NSDecimalNumber(decimal: newValue)) ?? ""
|
||||
state.textFieldState.text = "\(decimalString)"
|
||||
return Effect(value: .updateAmount)
|
||||
}
|
||||
|
||||
return .none
|
||||
}
|
||||
|
||||
private static let textFieldReducer: TransactionAmountTextFieldReducer = TCATextFieldReducer.default.pullback(
|
||||
|
@ -113,13 +119,13 @@ extension TransactionAmountTextFieldReducer {
|
|||
|
||||
extension TransactionAmountTextFieldState {
|
||||
static let placeholder = TransactionAmountTextFieldState(
|
||||
textFieldState: .placeholder,
|
||||
currencySelectionState: CurrencySelectionState()
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
textFieldState: .placeholder
|
||||
)
|
||||
|
||||
static let amount = TransactionAmountTextFieldState(
|
||||
textFieldState: .amount,
|
||||
currencySelectionState: CurrencySelectionState()
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
textFieldState: .amount
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// Double+Zcash.swift
|
||||
// secant-testnet
|
||||
//
|
||||
// Created by Lukáš Korba on 06.05.2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// TODO: Improve with decimals and zatoshi type, issue #272 (https://github.com/zcash/secant-ios-wallet/issues/272)
|
||||
extension Double {
|
||||
func asZec() -> Int64 {
|
||||
return Int64((self * 100_000_000).rounded())
|
||||
}
|
||||
|
||||
func asZecString() -> String {
|
||||
NumberFormatter.zcashNumberFormatter.string(from: NSNumber(value: self)) ?? ""
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// Int64+Zcash.swift
|
||||
// secant-testnet
|
||||
//
|
||||
// Created by Lukáš Korba on 15.04.2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// TODO: Improve with decimals and zatoshi type, issue #272 (https://github.com/zcash/secant-ios-wallet/issues/272)
|
||||
extension Int64 {
|
||||
func asHumanReadableZecBalance() -> Double {
|
||||
Double(self) / Double(100_000_000)
|
||||
}
|
||||
|
||||
func asZecString() -> String {
|
||||
NumberFormatter.zcashNumberFormatter.string(from: NSNumber(value: self.asHumanReadableZecBalance())) ?? ""
|
||||
}
|
||||
}
|
|
@ -14,6 +14,8 @@ struct Zatoshi {
|
|||
static let maxZatoshi: Int64 = Constants.oneZecInZatoshi * Constants.maxZecSupply
|
||||
}
|
||||
|
||||
static var zero: Zatoshi { Zatoshi() }
|
||||
|
||||
static var decimalHandler = NSDecimalNumberHandler(
|
||||
roundingMode: NSDecimalNumber.RoundingMode.bankers,
|
||||
scale: 8,
|
||||
|
@ -32,8 +34,8 @@ struct Zatoshi {
|
|||
}
|
||||
|
||||
/// Converts `Zatoshi` to human readable format, up to 8 fraction digits
|
||||
var decimalString: String {
|
||||
decimalValue.roundedZec.stringValue
|
||||
func decimalString(formatter: NumberFormatter = NumberFormatter.zcashNumberFormatter) -> String {
|
||||
formatter.string(from: decimalValue.roundedZec) ?? ""
|
||||
}
|
||||
|
||||
/// Converts `Decimal` to `Zatoshi`
|
||||
|
@ -61,14 +63,20 @@ struct Zatoshi {
|
|||
}
|
||||
}
|
||||
|
||||
extension NSDecimalNumber {
|
||||
/// Converts `NSDecimalNumber` to human readable format, up to 8 fraction digits
|
||||
var decimalString: String {
|
||||
self.rounding(accordingToBehavior: Zatoshi.decimalHandler).stringValue
|
||||
extension Zatoshi: Equatable {
|
||||
static func == (lhs: Zatoshi, rhs: Zatoshi) -> Bool {
|
||||
lhs.amount == rhs.amount
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension NSDecimalNumber {
|
||||
/// Round the decimal to 8 fraction digits
|
||||
var roundedZec: NSDecimalNumber {
|
||||
self.rounding(accordingToBehavior: Zatoshi.decimalHandler)
|
||||
}
|
||||
|
||||
/// Converts `NSDecimalNumber` to human readable format, up to 8 fraction digits
|
||||
var decimalString: String {
|
||||
self.roundedZec.stringValue
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ protocol WrappedSDKSynchronizer {
|
|||
|
||||
func sendTransaction(
|
||||
with spendingKey: String,
|
||||
zatoshi: Int64,
|
||||
zatoshi: Zatoshi,
|
||||
to recipientAddress: String,
|
||||
memo: String?,
|
||||
from account: Int
|
||||
|
@ -220,7 +220,7 @@ class LiveWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
|
||||
func sendTransaction(
|
||||
with spendingKey: String,
|
||||
zatoshi: Int64,
|
||||
zatoshi: Zatoshi,
|
||||
to recipientAddress: String,
|
||||
memo: String?,
|
||||
from account: Int
|
||||
|
@ -229,7 +229,7 @@ class LiveWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
Future { [weak self] promise in
|
||||
self?.synchronizer?.sendToAddress(
|
||||
spendingKey: spendingKey,
|
||||
zatoshi: zatoshi,
|
||||
zatoshi: zatoshi.amount,
|
||||
toAddress: recipientAddress,
|
||||
memo: memo,
|
||||
from: account) { result in
|
||||
|
@ -301,11 +301,11 @@ class MockWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
|
||||
func getAllClearedTransactions() -> Effect<[TransactionState], Never> {
|
||||
let mocked: [TransactionStateMockHelper] = [
|
||||
TransactionStateMockHelper(date: 1651039202, amount: 1, status: .paid(success: false)),
|
||||
TransactionStateMockHelper(date: 1651039101, amount: 2),
|
||||
TransactionStateMockHelper(date: 1651039000, amount: 3, status: .paid(success: true)),
|
||||
TransactionStateMockHelper(date: 1651039505, amount: 4),
|
||||
TransactionStateMockHelper(date: 1651039404, amount: 5)
|
||||
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(amount: 1), status: .paid(success: false)),
|
||||
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(amount: 2)),
|
||||
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(amount: 3), status: .paid(success: true)),
|
||||
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(amount: 4)),
|
||||
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(amount: 5))
|
||||
]
|
||||
|
||||
return Effect(
|
||||
|
@ -324,10 +324,10 @@ class MockWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
|
||||
func getAllPendingTransactions() -> Effect<[TransactionState], Never> {
|
||||
let mocked: [TransactionStateMockHelper] = [
|
||||
TransactionStateMockHelper(date: 1651039606, amount: 6, status: .paid(success: false), subtitle: "pending"),
|
||||
TransactionStateMockHelper(date: 1651039303, amount: 7, subtitle: "pending"),
|
||||
TransactionStateMockHelper(date: 1651039707, amount: 8, status: .paid(success: true), subtitle: "pending"),
|
||||
TransactionStateMockHelper(date: 1651039808, amount: 9, subtitle: "pending")
|
||||
TransactionStateMockHelper(date: 1651039606, amount: Zatoshi(amount: 6), status: .paid(success: false), subtitle: "pending"),
|
||||
TransactionStateMockHelper(date: 1651039303, amount: Zatoshi(amount: 7), subtitle: "pending"),
|
||||
TransactionStateMockHelper(date: 1651039707, amount: Zatoshi(amount: 8), status: .paid(success: true), subtitle: "pending"),
|
||||
TransactionStateMockHelper(date: 1651039808, amount: Zatoshi(amount: 9), subtitle: "pending")
|
||||
]
|
||||
|
||||
return Effect(
|
||||
|
@ -360,7 +360,7 @@ class MockWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
|
||||
func sendTransaction(
|
||||
with spendingKey: String,
|
||||
zatoshi: Int64,
|
||||
zatoshi: Zatoshi,
|
||||
to recipientAddress: String,
|
||||
memo: String?,
|
||||
from account: Int
|
||||
|
@ -375,7 +375,7 @@ class MockWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
id: "id",
|
||||
status: .paid(success: true),
|
||||
subtitle: "sub",
|
||||
zecAmount: 10
|
||||
zecAmount: Zatoshi(amount: 10)
|
||||
)
|
||||
|
||||
return Effect(value: Result.success(transactionState))
|
||||
|
@ -408,11 +408,11 @@ class TestWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
|
||||
func getAllClearedTransactions() -> Effect<[TransactionState], Never> {
|
||||
let mocked: [TransactionStateMockHelper] = [
|
||||
TransactionStateMockHelper(date: 1651039202, amount: 1, status: .paid(success: false), uuid: "aa11"),
|
||||
TransactionStateMockHelper(date: 1651039101, amount: 2, uuid: "bb22"),
|
||||
TransactionStateMockHelper(date: 1651039000, amount: 3, status: .paid(success: true), uuid: "cc33"),
|
||||
TransactionStateMockHelper(date: 1651039505, amount: 4, uuid: "dd44"),
|
||||
TransactionStateMockHelper(date: 1651039404, amount: 5, uuid: "ee55")
|
||||
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(amount: 1), status: .paid(success: false), uuid: "aa11"),
|
||||
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(amount: 2), uuid: "bb22"),
|
||||
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(amount: 3), status: .paid(success: true), uuid: "cc33"),
|
||||
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(amount: 4), uuid: "dd44"),
|
||||
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(amount: 5), uuid: "ee55")
|
||||
]
|
||||
|
||||
return Effect(
|
||||
|
@ -432,10 +432,16 @@ class TestWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
|
||||
func getAllPendingTransactions() -> Effect<[TransactionState], Never> {
|
||||
let mocked: [TransactionStateMockHelper] = [
|
||||
TransactionStateMockHelper(date: 1651039606, amount: 6, status: .paid(success: false), subtitle: "pending", uuid: "ff66"),
|
||||
TransactionStateMockHelper(date: 1651039303, amount: 7, subtitle: "pending", uuid: "gg77"),
|
||||
TransactionStateMockHelper(date: 1651039707, amount: 8, status: .paid(success: true), subtitle: "pending", uuid: "hh88"),
|
||||
TransactionStateMockHelper(date: 1651039808, amount: 9, subtitle: "pending", uuid: "ii99")
|
||||
TransactionStateMockHelper(
|
||||
date: 1651039606,
|
||||
amount: Zatoshi(amount: 6),
|
||||
status: .paid(success: false),
|
||||
subtitle: "pending",
|
||||
uuid: "ff66"
|
||||
),
|
||||
TransactionStateMockHelper(date: 1651039303, amount: Zatoshi(amount: 7), subtitle: "pending", uuid: "gg77"),
|
||||
TransactionStateMockHelper(date: 1651039707, amount: Zatoshi(amount: 8), status: .paid(success: true), subtitle: "pending", uuid: "hh88"),
|
||||
TransactionStateMockHelper(date: 1651039808, amount: Zatoshi(amount: 9), subtitle: "pending", uuid: "ii99")
|
||||
]
|
||||
|
||||
return Effect(
|
||||
|
@ -469,7 +475,7 @@ class TestWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
|
||||
func sendTransaction(
|
||||
with spendingKey: String,
|
||||
zatoshi: Int64,
|
||||
zatoshi: Zatoshi,
|
||||
to recipientAddress: String,
|
||||
memo: String?,
|
||||
from account: Int
|
||||
|
|
|
@ -10,8 +10,6 @@ import XCTest
|
|||
import ComposableArchitecture
|
||||
import ZcashLightClientKit
|
||||
|
||||
// TODO: these tests will be updated with the Zatoshi/Balance representative once done, issue #272 https://github.com/zcash/secant-ios-wallet/issues/272
|
||||
|
||||
// TODO: these test will be updated with the NumberFormater dependency to handle locale, issue #312 (https://github.com/zcash/secant-ios-wallet/issues/312)
|
||||
|
||||
// swiftlint:disable type_body_length
|
||||
|
@ -32,11 +30,11 @@ class SendTests: XCTestCase {
|
|||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: storage),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: MockWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: MockWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: storage)
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -64,7 +62,7 @@ class SendTests: XCTestCase {
|
|||
id: "id",
|
||||
status: .paid(success: true),
|
||||
subtitle: "sub",
|
||||
zecAmount: 10
|
||||
zecAmount: Zatoshi(amount: 10)
|
||||
)
|
||||
|
||||
// check the success transaction to be received back
|
||||
|
@ -88,11 +86,11 @@ class SendTests: XCTestCase {
|
|||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: storage),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: storage)
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -127,11 +125,11 @@ class SendTests: XCTestCase {
|
|||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live)),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live))
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -169,11 +167,11 @@ class SendTests: XCTestCase {
|
|||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live)),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live))
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -185,17 +183,19 @@ class SendTests: XCTestCase {
|
|||
// Checks the computed property `isInvalidAmountFormat` which controls the error message to be shown on the screen
|
||||
// With empty input it must be false
|
||||
store.send(.transactionAmountInput(.textField(.set(""))))
|
||||
|
||||
store.receive(.transactionAmountInput(.updateAmount))
|
||||
}
|
||||
|
||||
func testInvalidAddressFormatEmptyInput() throws {
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live)),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live))
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -226,20 +226,20 @@ class SendTests: XCTestCase {
|
|||
transactionAddressInputState: .placeholder,
|
||||
transactionAmountInputState:
|
||||
TransactionAmountTextFieldState(
|
||||
textFieldState: .amount,
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_300
|
||||
maxValue: 501_300,
|
||||
textFieldState: .amount
|
||||
)
|
||||
)
|
||||
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live)),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live))
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -257,9 +257,21 @@ class SendTests: XCTestCase {
|
|||
)
|
||||
}
|
||||
|
||||
store.receive(.transactionAmountInput(.updateAmount)) { state in
|
||||
state.transactionAmountInputState.amount = 501_299
|
||||
}
|
||||
|
||||
store.send(.transactionAmountInput(.textField(.set("0.00501301")))) { state in
|
||||
state.transactionAmountInputState.textFieldState.text = "0.00501301"
|
||||
state.transactionAmountInputState.textFieldState.valid = true
|
||||
XCTAssertFalse(
|
||||
state.isInsufficientFunds,
|
||||
"Send Tests: `testFundsSufficiency` is expected to be false but it's \(state.isInsufficientFunds)"
|
||||
)
|
||||
}
|
||||
|
||||
store.receive(.transactionAmountInput(.updateAmount)) { state in
|
||||
state.transactionAmountInputState.amount = 501_301
|
||||
XCTAssertTrue(
|
||||
state.isInsufficientFunds,
|
||||
"Send Tests: `testFundsSufficiency` is expected to be true but it's \(state.isInsufficientFunds)"
|
||||
|
@ -273,11 +285,11 @@ class SendTests: XCTestCase {
|
|||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live)),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live))
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -286,18 +298,18 @@ class SendTests: XCTestCase {
|
|||
environment: testEnvironment
|
||||
)
|
||||
|
||||
try amountFormatTest("1.234", true, 123_400_000, store)
|
||||
try amountFormatTest("1,234", true, 123_400_000_000, store)
|
||||
try amountFormatTest("1 234", true, 123_400_000_000, store)
|
||||
try amountFormatTest("1,234.567", true, 123_456_700_000, store)
|
||||
try amountFormatTest("1.", true, 100_000_000, store)
|
||||
try amountFormatTest("1..", false, 0, store)
|
||||
try amountFormatTest("1,.", false, 0, store)
|
||||
try amountFormatTest("1.,", false, 0, store)
|
||||
try amountFormatTest("1,,", false, 0, store)
|
||||
try amountFormatTest("1,23", false, 0, store)
|
||||
try amountFormatTest("1 23", false, 0, store)
|
||||
try amountFormatTest("1.2.3", false, 0, store)
|
||||
try amountFormatTest("1.234", true, 123_400_000, false, store)
|
||||
try amountFormatTest("1,234", true, 123_400_000_000, false, store)
|
||||
try amountFormatTest("1 234", true, 123_400_000_000, true, store)
|
||||
try amountFormatTest("1,234.567", true, 123_456_700_000, false, store)
|
||||
try amountFormatTest("1.", true, 100_000_000, false, store)
|
||||
try amountFormatTest("1..", false, 0, false, store)
|
||||
try amountFormatTest("1,.", false, 0, true, store)
|
||||
try amountFormatTest("1.,", false, 0, true, store)
|
||||
try amountFormatTest("1,,", false, 0, true, store)
|
||||
try amountFormatTest("1,23", false, 0, true, store)
|
||||
try amountFormatTest("1 23", false, 0, true, store)
|
||||
try amountFormatTest("1.2.3", false, 0, true, store)
|
||||
}
|
||||
|
||||
func testValidForm() throws {
|
||||
|
@ -308,24 +320,25 @@ class SendTests: XCTestCase {
|
|||
transactionAddressInputState: .placeholder,
|
||||
transactionAmountInputState:
|
||||
TransactionAmountTextFieldState(
|
||||
amount: 501_301,
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_302,
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "0.00501301"
|
||||
),
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_302
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live)),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live))
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -353,24 +366,24 @@ class SendTests: XCTestCase {
|
|||
transactionAddressInputState: .placeholder,
|
||||
transactionAmountInputState:
|
||||
TransactionAmountTextFieldState(
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_300,
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "0.00501301"
|
||||
),
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_300
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live)),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live))
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -398,24 +411,24 @@ class SendTests: XCTestCase {
|
|||
transactionAddressInputState: .placeholder,
|
||||
transactionAmountInputState:
|
||||
TransactionAmountTextFieldState(
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_302,
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "0.00501301"
|
||||
),
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_302
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live)),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live))
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -443,24 +456,24 @@ class SendTests: XCTestCase {
|
|||
transactionAddressInputState: .placeholder,
|
||||
transactionAmountInputState:
|
||||
TransactionAmountTextFieldState(
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_302,
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "0.0.0501301"
|
||||
),
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_302
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = SendFlowEnvironment(
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live)),
|
||||
derivationTool: .live(),
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer()
|
||||
mnemonic: .mock,
|
||||
SDKSynchronizer: TestWrappedSDKSynchronizer(),
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
walletStorage: .live(walletStorage: WalletStorage(secItem: .live))
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
|
@ -488,16 +501,20 @@ private extension SendTests {
|
|||
_ amount: String,
|
||||
_ expectedValidationResult: Bool,
|
||||
_ expectedAmount: Int64,
|
||||
_ expectedToReceive: Bool,
|
||||
_ store: TestStore<SendFlowState, SendFlowState, SendFlowAction, SendFlowAction, SendFlowEnvironment>
|
||||
) throws {
|
||||
store.send(.transactionAmountInput(.textField(.set(amount)))) { state in
|
||||
state.transactionAmountInputState.textFieldState.text = amount
|
||||
state.transactionAmountInputState.textFieldState.valid = expectedValidationResult
|
||||
XCTAssertEqual(
|
||||
expectedAmount,
|
||||
state.transactionAmountInputState.amount,
|
||||
"Send Tests: `amountFormatTest` expected amount is \(expectedAmount) but result is \(state.isInvalidAddressFormat)"
|
||||
)
|
||||
}
|
||||
|
||||
if expectedToReceive {
|
||||
store.receive(.transactionAmountInput(.updateAmount))
|
||||
} else {
|
||||
store.receive(.transactionAmountInput(.updateAmount)) { state in
|
||||
state.transactionAmountInputState.amount = expectedAmount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,6 @@ import XCTest
|
|||
@testable import secant_testnet
|
||||
import ComposableArchitecture
|
||||
|
||||
// TODO: these tests will be updated with the Zatoshi/Balance representative once done, issue #272 https://github.com/zcash/secant-ios-wallet/issues/272
|
||||
|
||||
// TODO: these test will be updated with the NumberFormater dependency to handle locale, issue #312 (https://github.com/zcash/secant-ios-wallet/issues/312)
|
||||
|
||||
class TransactionAmountTextFieldTests: XCTestCase {
|
||||
|
@ -20,13 +18,13 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
let store = TestStore(
|
||||
initialState:
|
||||
TransactionAmountTextFieldState(
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_301,
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "0.002"
|
||||
),
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_301
|
||||
)
|
||||
),
|
||||
reducer: TransactionAmountTextFieldReducer.default,
|
||||
environment: TransactionAmountTextFieldEnvironment()
|
||||
|
@ -34,7 +32,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
|
||||
store.send(.setMax) { state in
|
||||
state.textFieldState.text = "0.00501301"
|
||||
XCTAssertEqual(501_301, state.amount, "AmountInput Tests: `testMaxValue` expected \(501_301) but received \(state.amount)")
|
||||
}
|
||||
|
||||
store.receive(.updateAmount) { state in
|
||||
state.amount = 501_301
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,13 +43,13 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
let store = TestStore(
|
||||
initialState:
|
||||
TransactionAmountTextFieldState(
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_301,
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "0.002"
|
||||
),
|
||||
currencySelectionState: CurrencySelectionState(),
|
||||
maxValue: 501_301
|
||||
)
|
||||
),
|
||||
reducer: TransactionAmountTextFieldReducer.default,
|
||||
environment: TransactionAmountTextFieldEnvironment()
|
||||
|
@ -60,21 +61,21 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
func testZecUsdConvertedAmount() throws {
|
||||
try XCTSkipUnless(Locale.current.regionCode == "US", "testZecUsdConvertedAmount is designed to test US locale only")
|
||||
func testZec_to_UsdConvertedAmount() throws {
|
||||
try XCTSkipUnless(Locale.current.regionCode == "US", "testZec_to_UsdConvertedAmount is designed to test US locale only")
|
||||
|
||||
let store = TestStore(
|
||||
initialState:
|
||||
TransactionAmountTextFieldState(
|
||||
currencySelectionState:
|
||||
CurrencySelectionState(
|
||||
currencyType: .zec
|
||||
),
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "1.0"
|
||||
),
|
||||
currencySelectionState:
|
||||
CurrencySelectionState(
|
||||
currencyType: .zec
|
||||
),
|
||||
zecPrice: 1000.0
|
||||
),
|
||||
reducer: TransactionAmountTextFieldReducer.default,
|
||||
|
@ -84,29 +85,59 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
store.send(.currencySelection(.swapCurrencyType)) { state in
|
||||
state.textFieldState.text = "1,000"
|
||||
state.currencySelectionState.currencyType = .usd
|
||||
XCTAssertEqual(
|
||||
100_000_000,
|
||||
state.amount,
|
||||
"AmountInput Tests: `testZecUsdConvertedAmount` expected \(100_000_000) but received \(state.amount)"
|
||||
)
|
||||
}
|
||||
|
||||
store.receive(.updateAmount) { state in
|
||||
state.amount = 100_000_000
|
||||
}
|
||||
}
|
||||
|
||||
func testUsdZecConvertedAmount() throws {
|
||||
try XCTSkipUnless(Locale.current.regionCode == "US", "testUsdZecConvertedAmount is designed to test US locale only")
|
||||
func testBigZecAmount_to_UsdConvertedAmount() throws {
|
||||
try XCTSkipUnless(Locale.current.regionCode == "US", "testBigZecAmount_to_UsdConvertedAmount is designed to test US locale only")
|
||||
|
||||
let store = TestStore(
|
||||
initialState:
|
||||
TransactionAmountTextFieldState(
|
||||
currencySelectionState:
|
||||
CurrencySelectionState(
|
||||
currencyType: .zec
|
||||
),
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "25000"
|
||||
),
|
||||
zecPrice: 1000.0
|
||||
),
|
||||
reducer: TransactionAmountTextFieldReducer.default,
|
||||
environment: TransactionAmountTextFieldEnvironment()
|
||||
)
|
||||
|
||||
store.send(.currencySelection(.swapCurrencyType)) { state in
|
||||
state.textFieldState.text = "25,000,000"
|
||||
state.currencySelectionState.currencyType = .usd
|
||||
}
|
||||
|
||||
store.receive(.updateAmount) { state in
|
||||
state.amount = 2_500_000_000_000
|
||||
}
|
||||
}
|
||||
|
||||
func testUsd_to_ZecConvertedAmount() throws {
|
||||
try XCTSkipUnless(Locale.current.regionCode == "US", "testUsd_to_ZecConvertedAmount is designed to test US locale only")
|
||||
|
||||
let store = TestStore(
|
||||
initialState:
|
||||
TransactionAmountTextFieldState(
|
||||
currencySelectionState:
|
||||
CurrencySelectionState(
|
||||
currencyType: .usd
|
||||
),
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "1 000"
|
||||
),
|
||||
currencySelectionState:
|
||||
CurrencySelectionState(
|
||||
currencyType: .usd
|
||||
),
|
||||
zecPrice: 1000.0
|
||||
),
|
||||
reducer: TransactionAmountTextFieldReducer.default,
|
||||
|
@ -116,11 +147,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
store.send(.currencySelection(.swapCurrencyType)) { state in
|
||||
state.textFieldState.text = "1"
|
||||
state.currencySelectionState.currencyType = .zec
|
||||
XCTAssertEqual(
|
||||
100_000_000,
|
||||
state.amount,
|
||||
"AmountInput Tests: `testZecUsdConvertedAmount` expected \(100_000_000) but received \(state.amount)"
|
||||
)
|
||||
}
|
||||
|
||||
store.receive(.updateAmount) { state in
|
||||
state.amount = 100_000_000
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,16 +160,16 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
let store = TestStore(
|
||||
initialState:
|
||||
TransactionAmountTextFieldState(
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "5"
|
||||
),
|
||||
currencySelectionState:
|
||||
CurrencySelectionState(
|
||||
currencyType: .usd
|
||||
),
|
||||
maxValue: 100_000_000,
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "5"
|
||||
),
|
||||
zecPrice: 1000.0
|
||||
),
|
||||
reducer: TransactionAmountTextFieldReducer.default,
|
||||
|
@ -150,6 +180,14 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
state.textFieldState.text = "1 000"
|
||||
state.textFieldState.valid = true
|
||||
state.currencySelectionState.currencyType = .usd
|
||||
XCTAssertFalse(
|
||||
state.isMax,
|
||||
"AmountInput Tests: `testIfAmountIsMax` is expected to be false but it's \(state.isMax)"
|
||||
)
|
||||
}
|
||||
|
||||
store.receive(.updateAmount) { state in
|
||||
state.amount = 100_000_000
|
||||
XCTAssertTrue(
|
||||
state.isMax,
|
||||
"AmountInput Tests: `testIfAmountIsMax` is expected to be true but it's \(state.isMax)"
|
||||
|
@ -163,16 +201,16 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
let store = TestStore(
|
||||
initialState:
|
||||
TransactionAmountTextFieldState(
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "5"
|
||||
),
|
||||
currencySelectionState:
|
||||
CurrencySelectionState(
|
||||
currencyType: .zec
|
||||
),
|
||||
maxValue: 200_000_000,
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "5"
|
||||
),
|
||||
zecPrice: 1000.0
|
||||
),
|
||||
reducer: TransactionAmountTextFieldReducer.default,
|
||||
|
@ -181,11 +219,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
|
||||
store.send(.setMax) { state in
|
||||
state.textFieldState.text = "2"
|
||||
XCTAssertEqual(
|
||||
200_000_000,
|
||||
state.maxCurrencyConvertedValue,
|
||||
"AmountInput Tests: `testMaxZecValue` expected \(200_000_000) but received \(state.maxCurrencyConvertedValue)"
|
||||
)
|
||||
}
|
||||
|
||||
store.receive(.updateAmount) { state in
|
||||
state.amount = 200_000_000
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,16 +232,16 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
let store = TestStore(
|
||||
initialState:
|
||||
TransactionAmountTextFieldState(
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "5"
|
||||
),
|
||||
currencySelectionState:
|
||||
CurrencySelectionState(
|
||||
currencyType: .usd
|
||||
),
|
||||
maxValue: 200_000_000,
|
||||
textFieldState:
|
||||
TCATextFieldState(
|
||||
validationType: .floatingPoint,
|
||||
text: "5"
|
||||
),
|
||||
zecPrice: 1000.0
|
||||
),
|
||||
reducer: TransactionAmountTextFieldReducer.default,
|
||||
|
@ -213,11 +250,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
|
|||
|
||||
store.send(.setMax) { state in
|
||||
state.textFieldState.text = "2,000"
|
||||
XCTAssertEqual(
|
||||
200_000_000_000,
|
||||
state.maxCurrencyConvertedValue,
|
||||
"AmountInput Tests: `testMaxUsdValue` expected \(200_000_000_000) but received \(state.maxCurrencyConvertedValue)"
|
||||
)
|
||||
}
|
||||
|
||||
store.receive(.updateAmount) { state in
|
||||
state.amount = 200_000_000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,15 +38,21 @@ class TransactionHistoryTests: XCTestCase {
|
|||
|
||||
func testSynchronizerStateChanged2Synced() throws {
|
||||
let mocked: [TransactionStateMockHelper] = [
|
||||
TransactionStateMockHelper(date: 1651039202, amount: 1, status: .paid(success: false), uuid: "aa11"),
|
||||
TransactionStateMockHelper(date: 1651039101, amount: 2, uuid: "bb22"),
|
||||
TransactionStateMockHelper(date: 1651039000, amount: 3, status: .paid(success: true), uuid: "cc33"),
|
||||
TransactionStateMockHelper(date: 1651039505, amount: 4, uuid: "dd44"),
|
||||
TransactionStateMockHelper(date: 1651039404, amount: 5, uuid: "ee55"),
|
||||
TransactionStateMockHelper(date: 1651039606, amount: 6, status: .paid(success: false), subtitle: "pending", uuid: "ff66"),
|
||||
TransactionStateMockHelper(date: 1651039303, amount: 7, subtitle: "pending", uuid: "gg77"),
|
||||
TransactionStateMockHelper(date: 1651039707, amount: 8, status: .paid(success: true), subtitle: "pending", uuid: "hh88"),
|
||||
TransactionStateMockHelper(date: 1651039808, amount: 9, subtitle: "pending", uuid: "ii99")
|
||||
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(amount: 1), status: .paid(success: false), uuid: "aa11"),
|
||||
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(amount: 2), uuid: "bb22"),
|
||||
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(amount: 3), status: .paid(success: true), uuid: "cc33"),
|
||||
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(amount: 4), uuid: "dd44"),
|
||||
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(amount: 5), uuid: "ee55"),
|
||||
TransactionStateMockHelper(
|
||||
date: 1651039606,
|
||||
amount: Zatoshi(amount: 6),
|
||||
status: .paid(success: false),
|
||||
subtitle: "pending",
|
||||
uuid: "ff66"
|
||||
),
|
||||
TransactionStateMockHelper(date: 1651039303, amount: Zatoshi(amount: 7), subtitle: "pending", uuid: "gg77"),
|
||||
TransactionStateMockHelper(date: 1651039707, amount: Zatoshi(amount: 8), status: .paid(success: true), subtitle: "pending", uuid: "hh88"),
|
||||
TransactionStateMockHelper(date: 1651039808, amount: Zatoshi(amount: 9), subtitle: "pending", uuid: "ii99")
|
||||
]
|
||||
|
||||
let transactions = mocked.map {
|
||||
|
|
|
@ -122,9 +122,9 @@ class ZatoshiTests: XCTestCase {
|
|||
// so we convert it to string, in that case we are prooving it to be rendered
|
||||
// to the user exactly the way we want
|
||||
XCTAssertEqual(
|
||||
number.decimalString,
|
||||
number.decimalString(),
|
||||
"1.42857143",
|
||||
"Zatoshi tests: the value is expected to be 1.42857143 but it's \(number.decimalString)"
|
||||
"Zatoshi tests: the value is expected to be 1.42857143 but it's \(number.decimalString())"
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -151,9 +151,9 @@ class ZatoshiTests: XCTestCase {
|
|||
func testStringToZatoshi() throws {
|
||||
if let number = Zatoshi.from(decimalString: "200.0") {
|
||||
XCTAssertEqual(
|
||||
number.decimalString,
|
||||
number.decimalString(),
|
||||
"200",
|
||||
"Zatoshi tests: `testStringToZec` the value is expected to be 200 but it's \(number.decimalString)"
|
||||
"Zatoshi tests: `testStringToZec` the value is expected to be 200 but it's \(number.decimalString())"
|
||||
)
|
||||
} else {
|
||||
XCTFail("Zatoshi tests: `testStringToZatoshi` failed to convert number.")
|
||||
|
|
Loading…
Reference in New Issue