[#1045] Implement FetchUTXOsAction
- FetchUTXOsAction tests - UTXOFetcher mocks [#1045] Implement FetchUTXOsAction - enhanced with mocked values and more checks
This commit is contained in:
parent
4dc8d986ef
commit
95ab2a2047
|
@ -19,7 +19,7 @@ struct UTXOFetcherConfig {
|
||||||
protocol UTXOFetcher {
|
protocol UTXOFetcher {
|
||||||
func fetch(
|
func fetch(
|
||||||
at range: CompactBlockRange,
|
at range: CompactBlockRange,
|
||||||
didFetch: (Float) async -> Void
|
didFetch: @escaping (Float) async -> Void
|
||||||
) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity])
|
) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ struct UTXOFetcherImpl {
|
||||||
extension UTXOFetcherImpl: UTXOFetcher {
|
extension UTXOFetcherImpl: UTXOFetcher {
|
||||||
func fetch(
|
func fetch(
|
||||||
at range: CompactBlockRange,
|
at range: CompactBlockRange,
|
||||||
didFetch: (Float) async -> Void
|
didFetch: @escaping (Float) async -> Void
|
||||||
) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity]) {
|
) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity]) {
|
||||||
try Task.checkCancellation()
|
try Task.checkCancellation()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
//
|
||||||
|
// FetchUTXOsActionTests.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Lukáš Korba on 18.05.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
@testable import TestUtils
|
||||||
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
|
final class FetchUTXOsActionTests: ZcashTestCase {
|
||||||
|
func testFetchUTXOsAction_NextAction() async throws {
|
||||||
|
let loggerMock = LoggerMock()
|
||||||
|
let uTXOFetcherMock = UTXOFetcherMock()
|
||||||
|
|
||||||
|
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
|
||||||
|
let insertedEntity = UnspentTransactionOutputEntityMock(address: "addr", txid: Data(), index: 0, script: Data(), valueZat: 1, height: 2)
|
||||||
|
let skippedEntity = UnspentTransactionOutputEntityMock(address: "addr2", txid: Data(), index: 1, script: Data(), valueZat: 2, height: 3)
|
||||||
|
uTXOFetcherMock.fetchAtDidFetchReturnValue = (inserted: [insertedEntity], skipped: [skippedEntity])
|
||||||
|
|
||||||
|
mockContainer.mock(type: Logger.self, isSingleton: true) { _ in loggerMock }
|
||||||
|
mockContainer.mock(type: UTXOFetcher.self, isSingleton: true) { _ in uTXOFetcherMock }
|
||||||
|
|
||||||
|
let fetchUTXOsAction = FetchUTXOsAction(container: mockContainer)
|
||||||
|
|
||||||
|
let syncContext: ActionContext = .init(state: .fetchUTXO)
|
||||||
|
|
||||||
|
let syncRanges = SyncRanges(
|
||||||
|
latestBlockHeight: 0,
|
||||||
|
downloadedButUnscannedRange: nil,
|
||||||
|
downloadAndScanRange: nil,
|
||||||
|
enhanceRange: nil,
|
||||||
|
fetchUTXORange: CompactBlockRange(uncheckedBounds: (1000, 2000)),
|
||||||
|
latestScannedHeight: nil,
|
||||||
|
latestDownloadedBlockHeight: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
await syncContext.update(syncRanges: syncRanges)
|
||||||
|
|
||||||
|
do {
|
||||||
|
let nextContext = try await fetchUTXOsAction.run(with: syncContext) { event in
|
||||||
|
guard case .storedUTXOs(let result) = event else {
|
||||||
|
XCTFail("testFetchUTXOsAction_NextAction event expected to be .storedUTXOs but received \(event)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
XCTAssertEqual(result.inserted as! [UnspentTransactionOutputEntityMock], [insertedEntity])
|
||||||
|
XCTAssertEqual(result.skipped as! [UnspentTransactionOutputEntityMock], [skippedEntity])
|
||||||
|
}
|
||||||
|
XCTAssertTrue(loggerMock.debugFileFunctionLineCalled, "logger.debug(...) is expected to be called.")
|
||||||
|
XCTAssertTrue(uTXOFetcherMock.fetchAtDidFetchCalled, "utxoFetcher.fetch() is expected to be called.")
|
||||||
|
let nextState = await nextContext.state
|
||||||
|
XCTAssertTrue(
|
||||||
|
nextState == .handleSaplingParams,
|
||||||
|
"nextContext after .fetchUTXO is expected to be .handleSaplingParams but received \(nextState)"
|
||||||
|
)
|
||||||
|
} catch {
|
||||||
|
XCTFail("testFetchUTXOsAction_NextAction is not expected to fail. \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ extension LightWalletService { }
|
||||||
extension Logger { }
|
extension Logger { }
|
||||||
extension Synchronizer { }
|
extension Synchronizer { }
|
||||||
extension TransactionRepository { }
|
extension TransactionRepository { }
|
||||||
|
extension UTXOFetcher { }
|
||||||
extension ZcashRustBackendWelding { }
|
extension ZcashRustBackendWelding { }
|
||||||
|
|
||||||
// sourcery:end:
|
// sourcery:end:
|
||||||
|
|
|
@ -1355,6 +1355,38 @@ class TransactionRepositoryMock: TransactionRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
class UTXOFetcherMock: UTXOFetcher {
|
||||||
|
|
||||||
|
|
||||||
|
init(
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - fetch
|
||||||
|
|
||||||
|
var fetchAtDidFetchThrowableError: Error?
|
||||||
|
var fetchAtDidFetchCallsCount = 0
|
||||||
|
var fetchAtDidFetchCalled: Bool {
|
||||||
|
return fetchAtDidFetchCallsCount > 0
|
||||||
|
}
|
||||||
|
var fetchAtDidFetchReceivedArguments: (range: CompactBlockRange, didFetch: (Float) async -> Void)?
|
||||||
|
var fetchAtDidFetchReturnValue: (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity])!
|
||||||
|
var fetchAtDidFetchClosure: ((CompactBlockRange, @escaping (Float) async -> Void) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity]))?
|
||||||
|
|
||||||
|
func fetch(at range: CompactBlockRange, didFetch: @escaping (Float) async -> Void) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity]) {
|
||||||
|
if let error = fetchAtDidFetchThrowableError {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
fetchAtDidFetchCallsCount += 1
|
||||||
|
fetchAtDidFetchReceivedArguments = (range: range, didFetch: didFetch)
|
||||||
|
if let closure = fetchAtDidFetchClosure {
|
||||||
|
return try await closure(range, didFetch)
|
||||||
|
} else {
|
||||||
|
return fetchAtDidFetchReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue