[#1045] Implement FetchUTXOsAction

- FetchUTXOsAction tests
- UTXOFetcher mocks

[#1045] Implement FetchUTXOsAction

- enhanced with mocked values and more checks
This commit is contained in:
Lukas Korba 2023-05-18 11:44:19 +02:00
parent 4dc8d986ef
commit 95ab2a2047
4 changed files with 96 additions and 2 deletions

View File

@ -19,7 +19,7 @@ struct UTXOFetcherConfig {
protocol UTXOFetcher {
func fetch(
at range: CompactBlockRange,
didFetch: (Float) async -> Void
didFetch: @escaping (Float) async -> Void
) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity])
}
@ -36,7 +36,7 @@ struct UTXOFetcherImpl {
extension UTXOFetcherImpl: UTXOFetcher {
func fetch(
at range: CompactBlockRange,
didFetch: (Float) async -> Void
didFetch: @escaping (Float) async -> Void
) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity]) {
try Task.checkCancellation()

View File

@ -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)")
}
}
}

View File

@ -19,6 +19,7 @@ extension LightWalletService { }
extension Logger { }
extension Synchronizer { }
extension TransactionRepository { }
extension UTXOFetcher { }
extension ZcashRustBackendWelding { }
// sourcery:end:

View File

@ -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 {