[323] Unit/Integration tests for Home (#335)
- integration test for the .onAppear action - unit tests for the synchronizer status change - unit tests for the drawer and tracsation history
This commit is contained in:
parent
b2ae82ce1b
commit
21806c737f
|
@ -102,6 +102,7 @@
|
|||
9E391124283E4CAC0073DD9A /* ImportWalletTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E391123283E4CAC0073DD9A /* ImportWalletTests.swift */; };
|
||||
9E391129283F74590073DD9A /* Zatoshi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E391128283F74590073DD9A /* Zatoshi.swift */; };
|
||||
9E39112E283F91600073DD9A /* ZatoshiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E39112D283F91600073DD9A /* ZatoshiTests.swift */; };
|
||||
9E3911392848AD500073DD9A /* HomeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911382848AD500073DD9A /* HomeTests.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 */; };
|
||||
|
@ -128,7 +129,7 @@
|
|||
9E7FE0F92832824C00C374E8 /* QRCodeScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0F82832824C00C374E8 /* QRCodeScanView.swift */; };
|
||||
9E80B47227E4B34B008FF493 /* UserPreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */; };
|
||||
9E87ADF128363DE400122FCC /* WrappedAudioServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E87ADF028363DE400122FCC /* WrappedAudioServices.swift */; };
|
||||
9EAFEB822805793200199FC9 /* AppReducerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB812805793200199FC9 /* AppReducerTests.swift */; };
|
||||
9EAFEB822805793200199FC9 /* AppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB812805793200199FC9 /* AppTests.swift */; };
|
||||
9EAFEB84280597B700199FC9 /* WrappedSecItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB83280597B700199FC9 /* WrappedSecItem.swift */; };
|
||||
9EAFEB862805A23100199FC9 /* WrappedSecItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB852805A23100199FC9 /* WrappedSecItemTests.swift */; };
|
||||
9EAFEB882806E5AE00199FC9 /* WrappedSDKSynchronizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB872806E5AE00199FC9 /* WrappedSDKSynchronizer.swift */; };
|
||||
|
@ -292,6 +293,7 @@
|
|||
9E391123283E4CAC0073DD9A /* ImportWalletTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportWalletTests.swift; sourceTree = "<group>"; };
|
||||
9E391128283F74590073DD9A /* Zatoshi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Zatoshi.swift; sourceTree = "<group>"; };
|
||||
9E39112D283F91600073DD9A /* ZatoshiTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZatoshiTests.swift; sourceTree = "<group>"; };
|
||||
9E3911382848AD500073DD9A /* HomeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTests.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>"; };
|
||||
|
@ -318,7 +320,7 @@
|
|||
9E7FE0F82832824C00C374E8 /* QRCodeScanView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeScanView.swift; sourceTree = "<group>"; };
|
||||
9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorage.swift; sourceTree = "<group>"; };
|
||||
9E87ADF028363DE400122FCC /* WrappedAudioServices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrappedAudioServices.swift; sourceTree = "<group>"; };
|
||||
9EAFEB812805793200199FC9 /* AppReducerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppReducerTests.swift; sourceTree = "<group>"; };
|
||||
9EAFEB812805793200199FC9 /* AppTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTests.swift; sourceTree = "<group>"; };
|
||||
9EAFEB83280597B700199FC9 /* WrappedSecItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrappedSecItem.swift; sourceTree = "<group>"; };
|
||||
9EAFEB852805A23100199FC9 /* WrappedSecItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrappedSecItemTests.swift; sourceTree = "<group>"; };
|
||||
9EAFEB872806E5AE00199FC9 /* WrappedSDKSynchronizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrappedSDKSynchronizer.swift; sourceTree = "<group>"; };
|
||||
|
@ -478,11 +480,12 @@
|
|||
0D4E7A1926B364180058B01E /* secantTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E3911372848AD3A0073DD9A /* HomeTests */,
|
||||
9E391122283E4C970073DD9A /* ImportWalletTests */,
|
||||
9E01F8262833CD84000EFC57 /* ScanTests */,
|
||||
9E5BF642281FEC8700BA3F17 /* SendTests */,
|
||||
9E5BF63D281953F900BA3F17 /* TransactionHistoryTests */,
|
||||
9EAFEB802805791400199FC9 /* AppReducerTests */,
|
||||
9EAFEB802805791400199FC9 /* AppTests */,
|
||||
9EF8135927ECC25E0075AF48 /* UtilTests */,
|
||||
0DFE93E4272CB6D0000FCCA5 /* RecoveryPhraseValidationTests */,
|
||||
0DFE93DD272C6D4B000FCCA5 /* BackupFlowTests */,
|
||||
|
@ -757,6 +760,14 @@
|
|||
path = ImportWalletTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E3911372848AD3A0073DD9A /* HomeTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E3911382848AD500073DD9A /* HomeTests.swift */,
|
||||
);
|
||||
path = HomeTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E5BF63D281953F900BA3F17 /* TransactionHistoryTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -931,12 +942,12 @@
|
|||
path = UIKitBridge;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9EAFEB802805791400199FC9 /* AppReducerTests */ = {
|
||||
9EAFEB802805791400199FC9 /* AppTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9EAFEB812805793200199FC9 /* AppReducerTests.swift */,
|
||||
9EAFEB812805793200199FC9 /* AppTests.swift */,
|
||||
);
|
||||
path = AppReducerTests;
|
||||
path = AppTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9EAFEB8B2808174900199FC9 /* Sandbox */ = {
|
||||
|
@ -1407,11 +1418,12 @@
|
|||
9EAFEB862805A23100199FC9 /* WrappedSecItemTests.swift in Sources */,
|
||||
9E5BF644281FEC9900BA3F17 /* SendTests.swift in Sources */,
|
||||
0D1C1AA327611EFD0004AF6A /* RecoveryPhraseDisplayReducerTests.swift in Sources */,
|
||||
9EAFEB822805793200199FC9 /* AppReducerTests.swift in Sources */,
|
||||
9EAFEB822805793200199FC9 /* AppTests.swift in Sources */,
|
||||
9E391124283E4CAC0073DD9A /* ImportWalletTests.swift in Sources */,
|
||||
9E5BF63F2819542C00BA3F17 /* TransactionHistoryTests.swift in Sources */,
|
||||
0D4E7A1B26B364180058B01E /* secantTests.swift in Sources */,
|
||||
0DFE93E6272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift in Sources */,
|
||||
9E3911392848AD500073DD9A /* HomeTests.swift in Sources */,
|
||||
9EF8135C27ECC25E0075AF48 /* WalletStorageTests.swift in Sources */,
|
||||
9E02B56C27FED475005B809B /* DatabaseFilesTests.swift in Sources */,
|
||||
9EF8135D27ECC25E0075AF48 /* UserPreferencesStorageTests.swift in Sources */,
|
||||
|
|
|
@ -301,11 +301,11 @@ class MockWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
|
||||
func getAllClearedTransactions() -> Effect<[TransactionState], Never> {
|
||||
let mocked: [TransactionStateMockHelper] = [
|
||||
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))
|
||||
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(amount: 1), status: .paid(success: false), uuid: "1"),
|
||||
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(amount: 2), uuid: "2"),
|
||||
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(amount: 3), status: .paid(success: true), uuid: "3"),
|
||||
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(amount: 4), uuid: "4"),
|
||||
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(amount: 5), uuid: "5")
|
||||
]
|
||||
|
||||
return Effect(
|
||||
|
@ -316,7 +316,8 @@ class MockWrappedSDKSynchronizer: WrappedSDKSynchronizer {
|
|||
amount: $0.amount,
|
||||
shielded: $0.shielded,
|
||||
status: $0.status,
|
||||
subtitle: $0.subtitle
|
||||
subtitle: $0.subtitle,
|
||||
uuid: $0.uuid
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// AppReducerTests.swift
|
||||
// AppTests.swift
|
||||
// secantTests
|
||||
//
|
||||
// Created by Lukáš Korba on 12.04.2022.
|
||||
|
@ -9,7 +9,7 @@ import XCTest
|
|||
@testable import secant_testnet
|
||||
import ComposableArchitecture
|
||||
|
||||
class AppReducerTests: XCTestCase {
|
||||
class AppTests: XCTestCase {
|
||||
static let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = AppEnvironment(
|
|
@ -0,0 +1,217 @@
|
|||
//
|
||||
// HomeTests.swift
|
||||
// secantTests
|
||||
//
|
||||
// Created by Lukáš Korba on 02.06.2022.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import secant_testnet
|
||||
import ComposableArchitecture
|
||||
|
||||
class HomeTests: XCTestCase {
|
||||
func testSynchronizerStateChanged_AnyButSynced() throws {
|
||||
// setup the store and environment to be fully mocked
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
SDKSynchronizer: MockWrappedSDKSynchronizer(),
|
||||
walletStorage: .throwing
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
initialState: .placeholder,
|
||||
reducer: HomeReducer.default,
|
||||
environment: testEnvironment
|
||||
)
|
||||
|
||||
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
|
||||
/// 3. the side effect to update the balance is called
|
||||
func testSynchronizerStateChanged_Synced() throws {
|
||||
// setup the store and environment to be fully mocked
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
SDKSynchronizer: MockWrappedSDKSynchronizer(),
|
||||
walletStorage: .throwing
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
initialState: .placeholder,
|
||||
reducer: HomeReducer.default,
|
||||
environment: testEnvironment
|
||||
)
|
||||
|
||||
store.send(.synchronizerStateChanged(.synced))
|
||||
|
||||
testScheduler.advance(by: 0.01)
|
||||
|
||||
// ad 1.
|
||||
store.receive(.updateSynchronizerStatus)
|
||||
|
||||
// ad 2.
|
||||
let transactionsHelper: [TransactionStateMockHelper] = [
|
||||
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(amount: 1), status: .paid(success: false), uuid: "1"),
|
||||
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(amount: 2), uuid: "2"),
|
||||
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(amount: 3), status: .paid(success: true), uuid: "3"),
|
||||
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(amount: 4), uuid: "4"),
|
||||
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(amount: 5), uuid: "5")
|
||||
]
|
||||
let transactions = transactionsHelper.map {
|
||||
TransactionState.placeholder(
|
||||
date: Date.init(timeIntervalSince1970: $0.date),
|
||||
amount: $0.amount,
|
||||
shielded: $0.shielded,
|
||||
status: $0.status,
|
||||
subtitle: $0.subtitle,
|
||||
uuid: $0.uuid
|
||||
)
|
||||
}
|
||||
|
||||
store.receive(.updateTransactions(transactions))
|
||||
|
||||
// ad 3.
|
||||
let balance = Balance(verified: 12_345_000, total: 12_345_000)
|
||||
|
||||
store.receive(.updateBalance(balance)) { state in
|
||||
state.verifiedBalance = Zatoshi(amount: 12_345_000)
|
||||
state.totalBalance = Zatoshi(amount: 12_345_000)
|
||||
}
|
||||
}
|
||||
|
||||
func testTransactionHistoryPartial_to_FullDrawer() throws {
|
||||
// setup the store and environment to be fully mocked
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
SDKSynchronizer: MockWrappedSDKSynchronizer(),
|
||||
walletStorage: .throwing
|
||||
)
|
||||
|
||||
let homeState = HomeState(
|
||||
drawerOverlay: .partial,
|
||||
profileState: .placeholder,
|
||||
requestState: .placeholder,
|
||||
sendState: .placeholder,
|
||||
scanState: .placeholder,
|
||||
synchronizerStatus: "",
|
||||
totalBalance: Zatoshi.zero,
|
||||
transactionHistoryState: .emptyPlaceHolder,
|
||||
verifiedBalance: Zatoshi.zero
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
initialState: homeState,
|
||||
reducer: HomeReducer.default,
|
||||
environment: testEnvironment
|
||||
)
|
||||
|
||||
store.send(.transactionHistory(.updateRoute(.all))) { state in
|
||||
state.transactionHistoryState.route = .all
|
||||
}
|
||||
|
||||
store.receive(.updateDrawer(.full)) { state in
|
||||
state.drawerOverlay = .full
|
||||
state.transactionHistoryState.isScrollable = true
|
||||
}
|
||||
}
|
||||
|
||||
func testTransactionHistoryFull_to_PartialDrawer() throws {
|
||||
// setup the store and environment to be fully mocked
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
SDKSynchronizer: MockWrappedSDKSynchronizer(),
|
||||
walletStorage: .throwing
|
||||
)
|
||||
|
||||
let homeState = HomeState(
|
||||
drawerOverlay: .full,
|
||||
profileState: .placeholder,
|
||||
requestState: .placeholder,
|
||||
sendState: .placeholder,
|
||||
scanState: .placeholder,
|
||||
synchronizerStatus: "",
|
||||
totalBalance: Zatoshi.zero,
|
||||
transactionHistoryState: .emptyPlaceHolder,
|
||||
verifiedBalance: Zatoshi.zero
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
initialState: homeState,
|
||||
reducer: HomeReducer.default,
|
||||
environment: testEnvironment
|
||||
)
|
||||
|
||||
store.send(.transactionHistory(.updateRoute(.latest))) { state in
|
||||
state.transactionHistoryState.route = .latest
|
||||
}
|
||||
|
||||
store.receive(.updateDrawer(.partial)) { state in
|
||||
state.drawerOverlay = .partial
|
||||
state.transactionHistoryState.isScrollable = false
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
// setup the store and environment to be fully mocked
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
SDKSynchronizer: MockWrappedSDKSynchronizer(),
|
||||
walletStorage: .throwing
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
initialState: .placeholder,
|
||||
reducer: HomeReducer.default,
|
||||
environment: testEnvironment
|
||||
)
|
||||
|
||||
store.send(.onAppear)
|
||||
|
||||
testScheduler.advance(by: 0.01)
|
||||
|
||||
// expected side effects as a result of .onAppear registration
|
||||
store.receive(.synchronizerStateChanged(.unknown))
|
||||
store.receive(.updateSynchronizerStatus)
|
||||
|
||||
// long-living (cancelable) effects need to be properly canceled.
|
||||
// the .onDisappear action cancles the observer of the synchronizer status change.
|
||||
store.send(.onDisappear)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue