2022-06-03 04:27:18 -07:00
|
|
|
//
|
|
|
|
// HomeTests.swift
|
|
|
|
// secantTests
|
|
|
|
//
|
|
|
|
// Created by Lukáš Korba on 02.06.2022.
|
|
|
|
//
|
|
|
|
|
|
|
|
import XCTest
|
|
|
|
@testable import secant_testnet
|
|
|
|
import ComposableArchitecture
|
2022-07-19 11:56:46 -07:00
|
|
|
import ZcashLightClientKit
|
2022-06-03 04:27:18 -07:00
|
|
|
|
|
|
|
class HomeTests: XCTestCase {
|
|
|
|
func testSynchronizerStateChanged_AnyButSynced() throws {
|
|
|
|
let store = TestStore(
|
|
|
|
initialState: .placeholder,
|
2022-11-09 01:30:40 -08:00
|
|
|
reducer: HomeReducer()
|
2022-06-03 04:27:18 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
store.send(.synchronizerStateChanged(.downloading))
|
|
|
|
|
|
|
|
store.receive(.updateSynchronizerStatus)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// When the synchronizer status change to .synced, several things happen
|
|
|
|
/// 1. the .updateSynchronizerStatus is called
|
|
|
|
/// 2. the side effect to update the transactions history is called
|
|
|
|
func testSynchronizerStateChanged_Synced() throws {
|
|
|
|
// setup the store and environment to be fully mocked
|
|
|
|
let testScheduler = DispatchQueue.test
|
|
|
|
|
|
|
|
let store = TestStore(
|
|
|
|
initialState: .placeholder,
|
2022-11-09 01:30:40 -08:00
|
|
|
reducer: HomeReducer()
|
2022-11-18 02:34:33 -08:00
|
|
|
) { dependencies in
|
|
|
|
dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
|
|
|
|
dependencies.sdkSynchronizer = SDKSynchronizerDependency.mock
|
|
|
|
}
|
2022-11-17 03:25:55 -08:00
|
|
|
|
2022-06-03 04:27:18 -07:00
|
|
|
store.send(.synchronizerStateChanged(.synced))
|
|
|
|
|
|
|
|
testScheduler.advance(by: 0.01)
|
|
|
|
|
|
|
|
// ad 1.
|
|
|
|
store.receive(.updateSynchronizerStatus)
|
|
|
|
|
|
|
|
// ad 2.
|
|
|
|
let transactionsHelper: [TransactionStateMockHelper] = [
|
2022-11-17 03:25:55 -08:00
|
|
|
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(1), status: .paid(success: false), uuid: "aa11"),
|
|
|
|
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(2), uuid: "bb22"),
|
|
|
|
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(3), status: .paid(success: true), uuid: "cc33"),
|
|
|
|
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(4), uuid: "dd44"),
|
|
|
|
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(5), uuid: "ee55")
|
2022-06-03 04:27:18 -07:00
|
|
|
]
|
2022-06-23 02:05:34 -07:00
|
|
|
let walletEvents: [WalletEvent] = transactionsHelper.map {
|
|
|
|
let transaction = TransactionState.placeholder(
|
2022-06-03 04:27:18 -07:00
|
|
|
amount: $0.amount,
|
2022-07-19 11:56:46 -07:00
|
|
|
fee: Zatoshi(10),
|
2022-06-03 04:27:18 -07:00
|
|
|
shielded: $0.shielded,
|
|
|
|
status: $0.status,
|
2022-06-23 02:05:34 -07:00
|
|
|
timestamp: $0.date,
|
2022-06-03 04:27:18 -07:00
|
|
|
uuid: $0.uuid
|
|
|
|
)
|
2022-06-23 02:05:34 -07:00
|
|
|
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp)
|
2022-06-03 04:27:18 -07:00
|
|
|
}
|
|
|
|
|
2022-06-23 02:05:34 -07:00
|
|
|
store.receive(.updateWalletEvents(walletEvents))
|
2022-06-03 04:27:18 -07:00
|
|
|
}
|
|
|
|
|
2022-06-23 02:05:34 -07:00
|
|
|
func testWalletEventsPartial_to_FullDrawer() throws {
|
2022-11-09 01:30:40 -08:00
|
|
|
let homeState = HomeReducer.State(
|
|
|
|
balanceBreakdownState: .placeholder,
|
2022-06-03 04:27:18 -07:00
|
|
|
drawerOverlay: .partial,
|
|
|
|
profileState: .placeholder,
|
|
|
|
requestState: .placeholder,
|
|
|
|
scanState: .placeholder,
|
2022-08-17 06:22:35 -07:00
|
|
|
sendState: .placeholder,
|
|
|
|
shieldedBalance: WalletBalance.zero,
|
2022-07-08 07:49:31 -07:00
|
|
|
synchronizerStatusSnapshot: .default,
|
2022-08-17 06:22:35 -07:00
|
|
|
walletEventsState: .emptyPlaceHolder
|
2022-06-03 04:27:18 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
let store = TestStore(
|
|
|
|
initialState: homeState,
|
2022-11-09 01:30:40 -08:00
|
|
|
reducer: HomeReducer()
|
2022-06-03 04:27:18 -07:00
|
|
|
)
|
|
|
|
|
2022-06-23 02:05:34 -07:00
|
|
|
store.send(.walletEvents(.updateRoute(.all))) { state in
|
|
|
|
state.walletEventsState.route = .all
|
2022-06-03 04:27:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
store.receive(.updateDrawer(.full)) { state in
|
|
|
|
state.drawerOverlay = .full
|
2022-06-23 02:05:34 -07:00
|
|
|
state.walletEventsState.isScrollable = true
|
2022-06-03 04:27:18 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-23 02:05:34 -07:00
|
|
|
func testWalletEventsFull_to_PartialDrawer() throws {
|
2022-11-09 01:30:40 -08:00
|
|
|
let homeState = HomeReducer.State(
|
|
|
|
balanceBreakdownState: .placeholder,
|
2022-06-03 04:27:18 -07:00
|
|
|
drawerOverlay: .full,
|
|
|
|
profileState: .placeholder,
|
|
|
|
requestState: .placeholder,
|
|
|
|
scanState: .placeholder,
|
2022-08-17 06:22:35 -07:00
|
|
|
sendState: .placeholder,
|
|
|
|
shieldedBalance: WalletBalance.zero,
|
2022-07-08 07:49:31 -07:00
|
|
|
synchronizerStatusSnapshot: .default,
|
2022-08-17 06:22:35 -07:00
|
|
|
walletEventsState: .emptyPlaceHolder
|
2022-06-03 04:27:18 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
let store = TestStore(
|
|
|
|
initialState: homeState,
|
2022-11-09 01:30:40 -08:00
|
|
|
reducer: HomeReducer()
|
2022-06-03 04:27:18 -07:00
|
|
|
)
|
|
|
|
|
2022-06-23 02:05:34 -07:00
|
|
|
store.send(.walletEvents(.updateRoute(.latest))) { state in
|
|
|
|
state.walletEventsState.route = .latest
|
2022-06-03 04:27:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
store.receive(.updateDrawer(.partial)) { state in
|
|
|
|
state.drawerOverlay = .partial
|
2022-06-23 02:05:34 -07:00
|
|
|
state.walletEventsState.isScrollable = false
|
2022-06-03 04:27:18 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The .onAppear action is important to register for the synchronizer state updates.
|
|
|
|
/// The integration tests make sure registrations and side effects are properly implemented.
|
|
|
|
func testOnAppear() throws {
|
|
|
|
let store = TestStore(
|
|
|
|
initialState: .placeholder,
|
2022-11-09 01:30:40 -08:00
|
|
|
reducer: HomeReducer()
|
2022-11-18 02:34:33 -08:00
|
|
|
) {
|
|
|
|
$0.diskSpaceChecker = .mockEmptyDisk
|
|
|
|
}
|
2022-11-14 10:36:51 -08:00
|
|
|
|
2022-07-08 07:49:31 -07:00
|
|
|
store.send(.onAppear) { state in
|
|
|
|
state.requiredTransactionConfirmations = 10
|
|
|
|
}
|
2022-06-03 04:27:18 -07:00
|
|
|
|
|
|
|
// expected side effects as a result of .onAppear registration
|
2022-09-30 06:49:07 -07:00
|
|
|
store.receive(.updateRoute(nil))
|
2022-06-03 04:27:18 -07:00
|
|
|
store.receive(.synchronizerStateChanged(.unknown))
|
|
|
|
store.receive(.updateSynchronizerStatus)
|
2022-07-08 07:49:31 -07:00
|
|
|
|
2022-06-03 04:27:18 -07:00
|
|
|
// long-living (cancelable) effects need to be properly canceled.
|
|
|
|
// the .onDisappear action cancles the observer of the synchronizer status change.
|
|
|
|
store.send(.onDisappear)
|
|
|
|
}
|
2022-09-30 06:49:07 -07:00
|
|
|
|
|
|
|
func testOnAppear_notEnoughSpaceOnDisk() throws {
|
|
|
|
let store = TestStore(
|
|
|
|
initialState: .placeholder,
|
2022-11-09 01:30:40 -08:00
|
|
|
reducer: HomeReducer()
|
2022-11-18 02:34:33 -08:00
|
|
|
) {
|
|
|
|
$0.diskSpaceChecker = .mockFullDisk
|
|
|
|
}
|
2022-11-14 10:36:51 -08:00
|
|
|
|
2022-09-30 06:49:07 -07:00
|
|
|
store.send(.onAppear) { state in
|
|
|
|
state.requiredTransactionConfirmations = 10
|
|
|
|
}
|
|
|
|
|
|
|
|
// expected side effects as a result of .onAppear registration
|
|
|
|
store.receive(.updateRoute(.notEnoughFreeDiskSpace)) { state in
|
|
|
|
state.route = .notEnoughFreeDiskSpace
|
|
|
|
}
|
|
|
|
|
|
|
|
// long-living (cancelable) effects need to be properly canceled.
|
|
|
|
// the .onDisappear action cancles the observer of the synchronizer status change.
|
|
|
|
store.send(.onDisappear)
|
|
|
|
}
|
2022-07-21 10:30:02 -07:00
|
|
|
|
|
|
|
func testQuickRescan_ResetToHomeScreen() throws {
|
2022-11-09 01:30:40 -08:00
|
|
|
let homeState = HomeReducer.State(
|
2022-07-21 10:30:02 -07:00
|
|
|
route: .profile,
|
2022-11-09 01:30:40 -08:00
|
|
|
balanceBreakdownState: .placeholder,
|
2022-07-21 10:30:02 -07:00
|
|
|
drawerOverlay: .full,
|
|
|
|
profileState: .placeholder,
|
|
|
|
requestState: .placeholder,
|
|
|
|
scanState: .placeholder,
|
2022-08-17 06:22:35 -07:00
|
|
|
sendState: .placeholder,
|
|
|
|
shieldedBalance: WalletBalance.zero,
|
2022-07-21 10:30:02 -07:00
|
|
|
synchronizerStatusSnapshot: .default,
|
2022-08-17 06:22:35 -07:00
|
|
|
walletEventsState: .emptyPlaceHolder
|
2022-07-21 10:30:02 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
let store = TestStore(
|
|
|
|
initialState: homeState,
|
2022-11-09 01:30:40 -08:00
|
|
|
reducer: HomeReducer()
|
2022-07-21 10:30:02 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
store.send(.profile(.settings(.quickRescan))) { state in
|
|
|
|
state.route = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testFullRescan_ResetToHomeScreen() throws {
|
2022-11-09 01:30:40 -08:00
|
|
|
let homeState = HomeReducer.State(
|
2022-07-21 10:30:02 -07:00
|
|
|
route: .profile,
|
2022-11-09 01:30:40 -08:00
|
|
|
balanceBreakdownState: .placeholder,
|
2022-07-21 10:30:02 -07:00
|
|
|
drawerOverlay: .full,
|
|
|
|
profileState: .placeholder,
|
|
|
|
requestState: .placeholder,
|
|
|
|
scanState: .placeholder,
|
2022-08-17 06:22:35 -07:00
|
|
|
sendState: .placeholder,
|
|
|
|
shieldedBalance: WalletBalance.zero,
|
2022-07-21 10:30:02 -07:00
|
|
|
synchronizerStatusSnapshot: .default,
|
2022-08-17 06:22:35 -07:00
|
|
|
walletEventsState: .emptyPlaceHolder
|
2022-07-21 10:30:02 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
let store = TestStore(
|
|
|
|
initialState: homeState,
|
2022-11-09 01:30:40 -08:00
|
|
|
reducer: HomeReducer()
|
2022-07-21 10:30:02 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
store.send(.profile(.settings(.fullRescan))) { state in
|
|
|
|
state.route = nil
|
|
|
|
}
|
|
|
|
}
|
2022-06-03 04:27:18 -07:00
|
|
|
}
|