Merge pull request #1120 from LukasKorba/1042-Implement-ComputeSyncRangesAction

- ComputeSyncRangesAction tests
- fixed all tests after merge of latest SDK changes related InternalSyncProgress
- all actions marked as final class
- Custom LatestBlocksDataProviderMock removed from the project
This commit is contained in:
Lukas Korba 2023-05-23 13:39:49 +02:00 committed by GitHub
commit 454afaf2e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 546 additions and 79 deletions

View File

@ -7,7 +7,7 @@
import Foundation
class ChecksBeforeSyncAction {
final class ChecksBeforeSyncAction {
let internalSyncProgress: InternalSyncProgress
let storage: CompactBlockRepository
init(container: DIContainer) {

View File

@ -7,7 +7,7 @@
import Foundation
class ClearAlreadyScannedBlocksAction {
final class ClearAlreadyScannedBlocksAction {
let storage: CompactBlockRepository
let transactionRepository: TransactionRepository
init(container: DIContainer) {

View File

@ -7,7 +7,7 @@
import Foundation
class ClearCacheAction {
final class ClearCacheAction {
let storage: CompactBlockRepository
init(container: DIContainer) {
storage = container.resolve(CompactBlockRepository.self)

View File

@ -7,7 +7,7 @@
import Foundation
class ComputeSyncRangesAction {
final class ComputeSyncRangesAction {
let config: CompactBlockProcessor.Configuration
let downloaderService: BlockDownloaderService
let internalSyncProgress: InternalSyncProgress
@ -24,7 +24,7 @@ class ComputeSyncRangesAction {
/// It may happen that sync process start with syncing blocks that were downloaded but not synced in previous run of the sync process. This
/// methods analyses what must be done and computes range that should be used to compute reported progress.
private func computeTotalProgressRange(from syncRanges: SyncRanges) -> CompactBlockRange {
func computeTotalProgressRange(from syncRanges: SyncRanges) -> CompactBlockRange {
guard syncRanges.downloadRange != nil || syncRanges.scanRange != nil else {
// In this case we are sure that no downloading or scanning happens so this returned range won't be even used. And it's easier to return
// this "fake" range than to handle nil.

View File

@ -7,7 +7,7 @@
import Foundation
class DownloadAction {
final class DownloadAction {
let config: CompactBlockProcessor.Configuration
let downloader: BlockDownloader
let transactionRepository: TransactionRepository

View File

@ -7,7 +7,7 @@
import Foundation
class EnhanceAction {
final class EnhanceAction {
let blockEnhancer: BlockEnhancer
let config: CompactBlockProcessor.Configuration
let internalSyncProgress: InternalSyncProgress

View File

@ -7,7 +7,7 @@
import Foundation
class FetchUTXOsAction {
final class FetchUTXOsAction {
let utxoFetcher: UTXOFetcher
let logger: Logger

View File

@ -7,7 +7,7 @@
import Foundation
class MigrateLegacyCacheDBAction {
final class MigrateLegacyCacheDBAction {
private let config: CompactBlockProcessor.Configuration
private let internalSyncProgress: InternalSyncProgress
private let storage: CompactBlockRepository

View File

@ -7,7 +7,7 @@
import Foundation
class SaplingParamsAction {
final class SaplingParamsAction {
let saplingParametersHandler: SaplingParametersHandler
let logger: Logger

View File

@ -7,7 +7,7 @@
import Foundation
class ScanAction {
final class ScanAction {
let config: CompactBlockProcessor.Configuration
let blockScanner: BlockScanner
let logger: Logger

View File

@ -7,7 +7,7 @@
import Foundation
class ValidateAction {
final class ValidateAction {
let validator: BlockValidator
init(container: DIContainer) {

View File

@ -7,7 +7,7 @@
import Foundation
class ValidateServerAction {
final class ValidateServerAction {
let config: CompactBlockProcessor.Configuration
let rustBackend: ZcashRustBackendWelding
let service: LightWalletService

View File

@ -10,19 +10,21 @@ import XCTest
@testable import ZcashLightClientKit
final class ChecksBeforeSyncActionTests: ZcashTestCase {
var underlyingDownloadedButUnscannedRange: CompactBlockRange?
var underlyingDownloadRange: CompactBlockRange?
var underlyingScanRange: CompactBlockRange?
var underlyingLatestScannedHeight: BlockHeight?
var underlyingLatestDownloadedBlockHeight: BlockHeight?
override func setUp() {
super.setUp()
underlyingDownloadedButUnscannedRange = nil
underlyingDownloadRange = nil
underlyingScanRange = nil
underlyingLatestScannedHeight = nil
underlyingLatestDownloadedBlockHeight = nil
}
func testChecksBeforeSyncAction_shouldClearBlockCacheAndUpdateInternalState_noDownloadedButUnscannedRange() async throws {
func testChecksBeforeSyncAction_shouldClearBlockCacheAndUpdateInternalState_noDownloadNoScanRange() async throws {
let checksBeforeSyncAction = setupAction()
let syncRanges = setupSyncRanges()
@ -34,7 +36,8 @@ final class ChecksBeforeSyncActionTests: ZcashTestCase {
func testChecksBeforeSyncAction_shouldClearBlockCacheAndUpdateInternalState_nothingToClear() async throws {
let checksBeforeSyncAction = setupAction()
underlyingDownloadedButUnscannedRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingDownloadRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingLatestScannedHeight = BlockHeight(2000)
underlyingLatestDownloadedBlockHeight = BlockHeight(2000)
@ -47,7 +50,8 @@ final class ChecksBeforeSyncActionTests: ZcashTestCase {
func testChecksBeforeSyncAction_shouldClearBlockCacheAndUpdateInternalState_somethingToClear() async throws {
let checksBeforeSyncAction = setupAction()
underlyingDownloadedButUnscannedRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingDownloadRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingLatestScannedHeight = BlockHeight(2000)
underlyingLatestDownloadedBlockHeight = BlockHeight(1000)
@ -70,7 +74,8 @@ final class ChecksBeforeSyncActionTests: ZcashTestCase {
internalSyncProgressStorageMock
)
underlyingDownloadedButUnscannedRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingDownloadRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingLatestScannedHeight = BlockHeight(2000)
underlyingLatestDownloadedBlockHeight = BlockHeight(1000)
@ -133,8 +138,8 @@ final class ChecksBeforeSyncActionTests: ZcashTestCase {
private func setupSyncRanges() -> SyncRanges {
SyncRanges(
latestBlockHeight: 0,
downloadedButUnscannedRange: underlyingDownloadedButUnscannedRange,
downloadAndScanRange: nil,
downloadRange: underlyingDownloadRange,
scanRange: underlyingScanRange,
enhanceRange: nil,
fetchUTXORange: nil,
latestScannedHeight: underlyingLatestScannedHeight,

View File

@ -0,0 +1,225 @@
//
// ComputeSyncRangesActionTests.swift
//
//
// Created by Lukáš Korba on 22.05.2023.
//
import XCTest
@testable import TestUtils
@testable import ZcashLightClientKit
final class ComputeSyncRangesActionTests: ZcashTestCase {
var underlyingDownloadRange: CompactBlockRange?
var underlyingScanRange: CompactBlockRange?
override func setUp() {
super.setUp()
underlyingDownloadRange = nil
underlyingScanRange = nil
}
func testComputeSyncRangesActionTests_computeTotalProgressRange_noDownloadNoScanRange() async throws {
let computeSyncRangesAction = setupAction()
let syncRanges = setupSyncRanges()
let totalProgressRange = computeSyncRangesAction.computeTotalProgressRange(from: syncRanges)
XCTAssertTrue(
totalProgressRange == 0...0,
"testComputeSyncRangesActionTests_computeTotalProgressRange_A is expected to be 0...0 but received \(totalProgressRange)"
)
}
func testComputeSyncRangesActionTests_computeTotalProgressRange_ValidRange() async throws {
let computeSyncRangesAction = setupAction()
underlyingDownloadRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
let syncRanges = setupSyncRanges()
let totalProgressRange = computeSyncRangesAction.computeTotalProgressRange(from: syncRanges)
let expectedRange = 1000...2000
XCTAssertTrue(
totalProgressRange == expectedRange,
"testComputeSyncRangesActionTests_computeTotalProgressRange_ValidRange is expected to be \(expectedRange) but received \(totalProgressRange)"
)
}
func testComputeSyncRangesActionTests_finishProcessingCase() async throws {
let blockDownloaderServiceMock = BlockDownloaderServiceMock()
let latestBlocksDataProviderMock = LatestBlocksDataProviderMock()
let internalSyncProgressStorageMock = InternalSyncProgressStorageMock()
let loggerMock = LoggerMock()
let computeSyncRangesAction = setupDefaultMocksAndReturnAction(
blockDownloaderServiceMock,
latestBlocksDataProviderMock,
internalSyncProgressStorageMock,
loggerMock
)
let syncContext = await setupActionContext()
do {
let nextContext = try await computeSyncRangesAction.run(with: syncContext) { _ in }
XCTAssertTrue(blockDownloaderServiceMock.lastDownloadedBlockHeightCalled, "downloaderService.lastDownloadedBlockHeight() is expected to be called.")
XCTAssertTrue(latestBlocksDataProviderMock.updateScannedDataCalled, "latestBlocksDataProvider.updateScannedData() is expected to be called.")
XCTAssertTrue(latestBlocksDataProviderMock.updateBlockDataCalled, "latestBlocksDataProvider.updateBlockData() is expected to be called.")
XCTAssertFalse(loggerMock.infoFileFunctionLineCalled, "logger.info() is not expected to be called.")
let nextState = await nextContext.state
XCTAssertTrue(
nextState == .finished,
"nextContext after .computeSyncRanges is expected to be .finished but received \(nextState)"
)
} catch {
XCTFail("testComputeSyncRangesActionTests_FinishProcessing is not expected to fail. \(error)")
}
}
func testComputeSyncRangesActionTests_checksBeforeSyncCase() async throws {
let blockDownloaderServiceMock = BlockDownloaderServiceMock()
let latestBlocksDataProviderMock = LatestBlocksDataProviderMock()
let internalSyncProgressStorageMock = InternalSyncProgressStorageMock()
let loggerMock = LoggerMock()
let computeSyncRangesAction = setupDefaultMocksAndReturnAction(
blockDownloaderServiceMock,
latestBlocksDataProviderMock,
internalSyncProgressStorageMock,
loggerMock
)
latestBlocksDataProviderMock.underlyingLatestBlockHeight = 10
let syncContext = await setupActionContext()
do {
let nextContext = try await computeSyncRangesAction.run(with: syncContext) { _ in }
XCTAssertTrue(blockDownloaderServiceMock.lastDownloadedBlockHeightCalled, "downloaderService.lastDownloadedBlockHeight() is expected to be called.")
XCTAssertTrue(latestBlocksDataProviderMock.updateScannedDataCalled, "latestBlocksDataProvider.updateScannedData() is expected to be called.")
XCTAssertTrue(latestBlocksDataProviderMock.updateBlockDataCalled, "latestBlocksDataProvider.updateBlockData() is expected to be called.")
XCTAssertFalse(loggerMock.infoFileFunctionLineCalled, "logger.info() is not expected to be called.")
let nextState = await nextContext.state
XCTAssertTrue(
nextState == .checksBeforeSync,
"nextContext after .computeSyncRanges is expected to be .checksBeforeSync but received \(nextState)"
)
} catch {
XCTFail("testComputeSyncRangesActionTests_checksBeforeSyncCase is not expected to fail. \(error)")
}
}
func testComputeSyncRangesActionTests_waitCase() async throws {
let blockDownloaderServiceMock = BlockDownloaderServiceMock()
let latestBlocksDataProviderMock = LatestBlocksDataProviderMock()
let internalSyncProgressStorageMock = InternalSyncProgressStorageMock()
let loggerMock = LoggerMock()
let computeSyncRangesAction = setupDefaultMocksAndReturnAction(
blockDownloaderServiceMock,
latestBlocksDataProviderMock,
internalSyncProgressStorageMock,
loggerMock
)
blockDownloaderServiceMock.lastDownloadedBlockHeightReturnValue = 10
latestBlocksDataProviderMock.underlyingLatestScannedHeight = 10
internalSyncProgressStorageMock.integerForKeyReturnValue = 10
loggerMock.infoFileFunctionLineClosure = { _, _, _, _ in }
let syncContext = await setupActionContext()
do {
let nextContext = try await computeSyncRangesAction.run(with: syncContext) { _ in }
XCTAssertTrue(blockDownloaderServiceMock.lastDownloadedBlockHeightCalled, "downloaderService.lastDownloadedBlockHeight() is expected to be called.")
XCTAssertTrue(latestBlocksDataProviderMock.updateScannedDataCalled, "latestBlocksDataProvider.updateScannedData() is expected to be called.")
XCTAssertTrue(latestBlocksDataProviderMock.updateBlockDataCalled, "latestBlocksDataProvider.updateBlockData() is expected to be called.")
XCTAssertTrue(loggerMock.infoFileFunctionLineCalled, "logger.info() is expected to be called.")
let nextState = await nextContext.state
XCTAssertTrue(
nextState == .finished,
"nextContext after .computeSyncRanges is expected to be .finished but received \(nextState)"
)
} catch {
XCTFail("testComputeSyncRangesActionTests_waitCase is not expected to fail. \(error)")
}
}
private func setupSyncRanges() -> SyncRanges {
SyncRanges(
latestBlockHeight: 0,
downloadRange: underlyingDownloadRange,
scanRange: underlyingScanRange,
enhanceRange: nil,
fetchUTXORange: nil,
latestScannedHeight: nil,
latestDownloadedBlockHeight: nil
)
}
private func setupActionContext() async -> ActionContext {
let syncContext: ActionContext = .init(state: .computeSyncRanges)
await syncContext.update(syncRanges: setupSyncRanges())
await syncContext.update(totalProgressRange: CompactBlockRange(uncheckedBounds: (1000, 2000)))
return syncContext
}
private func setupAction(
_ blockDownloaderServiceMock: BlockDownloaderServiceMock = BlockDownloaderServiceMock(),
_ latestBlocksDataProviderMock: LatestBlocksDataProviderMock = LatestBlocksDataProviderMock(),
_ internalSyncProgressStorageMock: InternalSyncProgressStorageMock = InternalSyncProgressStorageMock(),
_ loggerMock: LoggerMock = LoggerMock()
) -> ComputeSyncRangesAction {
mockContainer.register(type: InternalSyncProgress.self, isSingleton: true) { di in
InternalSyncProgress(alias: .default, storage: internalSyncProgressStorageMock, logger: loggerMock)
}
mockContainer.mock(type: BlockDownloaderService.self, isSingleton: true) { _ in blockDownloaderServiceMock }
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in latestBlocksDataProviderMock }
mockContainer.mock(type: Logger.self, isSingleton: true) { _ in loggerMock }
let config: CompactBlockProcessor.Configuration = .standard(
for: ZcashNetworkBuilder.network(for: .testnet), walletBirthday: 0
)
return ComputeSyncRangesAction(
container: mockContainer,
config: config
)
}
private func setupDefaultMocksAndReturnAction(
_ blockDownloaderServiceMock: BlockDownloaderServiceMock = BlockDownloaderServiceMock(),
_ latestBlocksDataProviderMock: LatestBlocksDataProviderMock = LatestBlocksDataProviderMock(),
_ internalSyncProgressStorageMock: InternalSyncProgressStorageMock = InternalSyncProgressStorageMock(),
_ loggerMock: LoggerMock = LoggerMock()
) -> ComputeSyncRangesAction {
blockDownloaderServiceMock.lastDownloadedBlockHeightReturnValue = 1
latestBlocksDataProviderMock.underlyingLatestBlockHeight = 1
latestBlocksDataProviderMock.underlyingLatestScannedHeight = 1
latestBlocksDataProviderMock.updateScannedDataClosure = { }
latestBlocksDataProviderMock.updateBlockDataClosure = { }
internalSyncProgressStorageMock.integerForKeyReturnValue = 1
internalSyncProgressStorageMock.boolForKeyReturnValue = true
internalSyncProgressStorageMock.setBoolClosure = { _, _ in }
internalSyncProgressStorageMock.synchronizeClosure = { true }
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
return setupAction(
blockDownloaderServiceMock,
latestBlocksDataProviderMock,
internalSyncProgressStorageMock,
loggerMock
)
}
}

View File

@ -10,8 +10,9 @@ import XCTest
@testable import ZcashLightClientKit
final class DownloadActionTests: ZcashTestCase {
var underlyingDownloadAndScanRange: CompactBlockRange?
var underlyingDownloadRange: CompactBlockRange?
var underlyingScanRange: CompactBlockRange?
func testDownloadAction_NextAction() async throws {
let blockDownloaderMock = BlockDownloaderMock()
let transactionRepositoryMock = TransactionRepositoryMock()
@ -27,8 +28,9 @@ final class DownloadActionTests: ZcashTestCase {
transactionRepositoryMock
)
underlyingDownloadAndScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingDownloadRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
let syncContext = await setupActionContext()
do {
@ -97,7 +99,8 @@ final class DownloadActionTests: ZcashTestCase {
transactionRepositoryMock
)
underlyingDownloadAndScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingDownloadRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
let syncContext = await setupActionContext()
@ -139,11 +142,11 @@ final class DownloadActionTests: ZcashTestCase {
private func setupActionContext() async -> ActionContext {
let syncContext: ActionContext = .init(state: .download)
let syncRanges = SyncRanges(
latestBlockHeight: 0,
downloadedButUnscannedRange: nil,
downloadAndScanRange: underlyingDownloadAndScanRange,
downloadRange: underlyingDownloadRange,
scanRange: underlyingScanRange,
enhanceRange: nil,
fetchUTXORange: nil,
latestScannedHeight: nil,

View File

@ -10,13 +10,15 @@ import XCTest
@testable import ZcashLightClientKit
final class EnhanceActionTests: ZcashTestCase {
var underlyingDownloadAndScanRange: CompactBlockRange?
var underlyingDownloadRange: CompactBlockRange?
var underlyingScanRange: CompactBlockRange?
var underlyingEnhanceRange: CompactBlockRange?
override func setUp() {
super.setUp()
underlyingDownloadAndScanRange = nil
underlyingDownloadRange = nil
underlyingScanRange = nil
underlyingEnhanceRange = nil
}
@ -35,8 +37,9 @@ final class EnhanceActionTests: ZcashTestCase {
func testEnhanceAction_decideWhatToDoNext_NothingToDownloadAndScanLeft() async throws {
let enhanceAction = setupAction()
underlyingDownloadAndScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingDownloadRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
let syncContext = await setupActionContext()
let nextContext = await enhanceAction.decideWhatToDoNext(context: syncContext, lastScannedHeight: 2000)
let nextState = await nextContext.state
@ -49,8 +52,9 @@ final class EnhanceActionTests: ZcashTestCase {
func testEnhanceAction_decideWhatToDoNext_DownloadExpected() async throws {
let enhanceAction = setupAction()
underlyingDownloadAndScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingDownloadRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
underlyingScanRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
let syncContext = await setupActionContext()
let nextContext = await enhanceAction.decideWhatToDoNext(context: syncContext, lastScannedHeight: 1500)
let nextState = await nextContext.state
@ -247,8 +251,8 @@ final class EnhanceActionTests: ZcashTestCase {
let syncRanges = SyncRanges(
latestBlockHeight: 0,
downloadRange: underlyingDownloadAndScanRange,
scanRange: underlyingDownloadAndScanRange,
downloadRange: underlyingDownloadRange,
scanRange: underlyingScanRange,
enhanceRange: underlyingEnhanceRange,
fetchUTXORange: nil,
latestScannedHeight: nil,

View File

@ -28,8 +28,8 @@ final class SaplingParamsActionTests: ZcashTestCase {
XCTAssertTrue(saplingParametersHandlerMock.handleIfNeededCalled, "saplingParametersHandler.handleIfNeeded() is expected to be called.")
let nextState = await nextContext.state
XCTAssertTrue(
nextState == .scanDownloaded,
"nextContext after .handleSaplingParams is expected to be .scanDownloaded but received \(nextState)"
nextState == .download,
"nextContext after .handleSaplingParams is expected to be .download but received \(nextState)"
)
} catch {
XCTFail("testSaplingParamsAction_NextAction is not expected to fail. \(error)")

View File

@ -61,8 +61,8 @@ class InternalSyncProgressTests: XCTestCase {
switch nextState {
case let .processNewBlocks(ranges):
XCTAssertEqual(ranges.downloadedButUnscannedRange, 620001...630000)
XCTAssertEqual(ranges.downloadAndScanRange, 630001...640000)
XCTAssertEqual(ranges.downloadRange, 630001...640000)
XCTAssertEqual(ranges.scanRange, 620001...640000)
XCTAssertEqual(ranges.enhanceRange, 630001...640000)
XCTAssertEqual(ranges.fetchUTXORange, 630001...640000)

View File

@ -1,38 +0,0 @@
//
// LatestBlocksDataProviderMock.swift
//
//
// Created by Lukáš Korba on 12.04.2023.
//
import Foundation
@testable import ZcashLightClientKit
actor LatestBlocksDataProviderMock: LatestBlocksDataProvider {
private(set) var latestScannedHeight: BlockHeight = .zero
private(set) var latestScannedTime: TimeInterval = 0.0
private(set) var latestBlockHeight: BlockHeight = .zero
private(set) var walletBirthday: BlockHeight = .zero
init(
latestScannedHeight: BlockHeight = .zero,
latestScannedTime: TimeInterval = 0,
latestBlockHeight: BlockHeight = .zero,
walletBirthday: BlockHeight = .zero
) {
self.latestScannedHeight = latestScannedHeight
self.latestScannedTime = latestScannedTime
self.latestBlockHeight = latestBlockHeight
self.walletBirthday = walletBirthday
}
func updateScannedData() async { }
func updateBlockData() async { }
func updateWalletBirthday(_ walletBirthday: BlockHeight) async { }
func updateLatestScannedHeight(_ latestScannedHeight: BlockHeight) async { }
func updateLatestScannedTime(_ latestScannedTime: TimeInterval) async { }
}

View File

@ -13,11 +13,13 @@
@testable import ZcashLightClientKit
extension BlockDownloader { }
extension BlockDownloaderService { }
extension BlockEnhancer { }
extension BlockScanner { }
extension BlockValidator { }
extension CompactBlockRepository { }
extension InternalSyncProgressStorage { }
extension LatestBlocksDataProvider { }
extension LightWalletdInfo { }
extension LightWalletService { }
extension Logger { }

View File

@ -95,6 +95,177 @@ class BlockDownloaderMock: BlockDownloader {
try await waitUntilRequestedBlocksAreDownloadedInClosure!(range)
}
}
class BlockDownloaderServiceMock: BlockDownloaderService {
init(
) {
}
var storage: CompactBlockRepository {
get { return underlyingStorage }
}
var underlyingStorage: CompactBlockRepository!
// MARK: - downloadBlockRange
var downloadBlockRangeThrowableError: Error?
var downloadBlockRangeCallsCount = 0
var downloadBlockRangeCalled: Bool {
return downloadBlockRangeCallsCount > 0
}
var downloadBlockRangeReceivedHeightRange: CompactBlockRange?
var downloadBlockRangeClosure: ((CompactBlockRange) async throws -> Void)?
func downloadBlockRange(_ heightRange: CompactBlockRange) async throws {
if let error = downloadBlockRangeThrowableError {
throw error
}
downloadBlockRangeCallsCount += 1
downloadBlockRangeReceivedHeightRange = heightRange
try await downloadBlockRangeClosure!(heightRange)
}
// MARK: - rewind
var rewindToThrowableError: Error?
var rewindToCallsCount = 0
var rewindToCalled: Bool {
return rewindToCallsCount > 0
}
var rewindToReceivedHeight: BlockHeight?
var rewindToClosure: ((BlockHeight) async throws -> Void)?
func rewind(to height: BlockHeight) async throws {
if let error = rewindToThrowableError {
throw error
}
rewindToCallsCount += 1
rewindToReceivedHeight = height
try await rewindToClosure!(height)
}
// MARK: - lastDownloadedBlockHeight
var lastDownloadedBlockHeightThrowableError: Error?
var lastDownloadedBlockHeightCallsCount = 0
var lastDownloadedBlockHeightCalled: Bool {
return lastDownloadedBlockHeightCallsCount > 0
}
var lastDownloadedBlockHeightReturnValue: BlockHeight!
var lastDownloadedBlockHeightClosure: (() async throws -> BlockHeight)?
func lastDownloadedBlockHeight() async throws -> BlockHeight {
if let error = lastDownloadedBlockHeightThrowableError {
throw error
}
lastDownloadedBlockHeightCallsCount += 1
if let closure = lastDownloadedBlockHeightClosure {
return try await closure()
} else {
return lastDownloadedBlockHeightReturnValue
}
}
// MARK: - latestBlockHeight
var latestBlockHeightThrowableError: Error?
var latestBlockHeightCallsCount = 0
var latestBlockHeightCalled: Bool {
return latestBlockHeightCallsCount > 0
}
var latestBlockHeightReturnValue: BlockHeight!
var latestBlockHeightClosure: (() async throws -> BlockHeight)?
func latestBlockHeight() async throws -> BlockHeight {
if let error = latestBlockHeightThrowableError {
throw error
}
latestBlockHeightCallsCount += 1
if let closure = latestBlockHeightClosure {
return try await closure()
} else {
return latestBlockHeightReturnValue
}
}
// MARK: - fetchTransaction
var fetchTransactionTxIdThrowableError: Error?
var fetchTransactionTxIdCallsCount = 0
var fetchTransactionTxIdCalled: Bool {
return fetchTransactionTxIdCallsCount > 0
}
var fetchTransactionTxIdReceivedTxId: Data?
var fetchTransactionTxIdReturnValue: ZcashTransaction.Fetched!
var fetchTransactionTxIdClosure: ((Data) async throws -> ZcashTransaction.Fetched)?
func fetchTransaction(txId: Data) async throws -> ZcashTransaction.Fetched {
if let error = fetchTransactionTxIdThrowableError {
throw error
}
fetchTransactionTxIdCallsCount += 1
fetchTransactionTxIdReceivedTxId = txId
if let closure = fetchTransactionTxIdClosure {
return try await closure(txId)
} else {
return fetchTransactionTxIdReturnValue
}
}
// MARK: - fetchUnspentTransactionOutputs
var fetchUnspentTransactionOutputsTAddressStartHeightCallsCount = 0
var fetchUnspentTransactionOutputsTAddressStartHeightCalled: Bool {
return fetchUnspentTransactionOutputsTAddressStartHeightCallsCount > 0
}
var fetchUnspentTransactionOutputsTAddressStartHeightReceivedArguments: (tAddress: String, startHeight: BlockHeight)?
var fetchUnspentTransactionOutputsTAddressStartHeightReturnValue: AsyncThrowingStream<UnspentTransactionOutputEntity, Error>!
var fetchUnspentTransactionOutputsTAddressStartHeightClosure: ((String, BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error>)?
func fetchUnspentTransactionOutputs(tAddress: String, startHeight: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
fetchUnspentTransactionOutputsTAddressStartHeightCallsCount += 1
fetchUnspentTransactionOutputsTAddressStartHeightReceivedArguments = (tAddress: tAddress, startHeight: startHeight)
if let closure = fetchUnspentTransactionOutputsTAddressStartHeightClosure {
return closure(tAddress, startHeight)
} else {
return fetchUnspentTransactionOutputsTAddressStartHeightReturnValue
}
}
// MARK: - fetchUnspentTransactionOutputs
var fetchUnspentTransactionOutputsTAddressesStartHeightCallsCount = 0
var fetchUnspentTransactionOutputsTAddressesStartHeightCalled: Bool {
return fetchUnspentTransactionOutputsTAddressesStartHeightCallsCount > 0
}
var fetchUnspentTransactionOutputsTAddressesStartHeightReceivedArguments: (tAddresses: [String], startHeight: BlockHeight)?
var fetchUnspentTransactionOutputsTAddressesStartHeightReturnValue: AsyncThrowingStream<UnspentTransactionOutputEntity, Error>!
var fetchUnspentTransactionOutputsTAddressesStartHeightClosure: (([String], BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error>)?
func fetchUnspentTransactionOutputs(tAddresses: [String], startHeight: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
fetchUnspentTransactionOutputsTAddressesStartHeightCallsCount += 1
fetchUnspentTransactionOutputsTAddressesStartHeightReceivedArguments = (tAddresses: tAddresses, startHeight: startHeight)
if let closure = fetchUnspentTransactionOutputsTAddressesStartHeightClosure {
return closure(tAddresses, startHeight)
} else {
return fetchUnspentTransactionOutputsTAddressesStartHeightReturnValue
}
}
// MARK: - closeConnection
var closeConnectionCallsCount = 0
var closeConnectionCalled: Bool {
return closeConnectionCallsCount > 0
}
var closeConnectionClosure: (() -> Void)?
func closeConnection() {
closeConnectionCallsCount += 1
closeConnectionClosure!()
}
}
class BlockEnhancerMock: BlockEnhancer {
@ -397,6 +568,101 @@ class InternalSyncProgressStorageMock: InternalSyncProgressStorage {
}
}
}
class LatestBlocksDataProviderMock: LatestBlocksDataProvider {
init(
) {
}
var latestScannedHeight: BlockHeight {
get { return underlyingLatestScannedHeight }
}
var underlyingLatestScannedHeight: BlockHeight!
var latestScannedTime: TimeInterval {
get { return underlyingLatestScannedTime }
}
var underlyingLatestScannedTime: TimeInterval!
var latestBlockHeight: BlockHeight {
get { return underlyingLatestBlockHeight }
}
var underlyingLatestBlockHeight: BlockHeight!
var walletBirthday: BlockHeight {
get { return underlyingWalletBirthday }
}
var underlyingWalletBirthday: BlockHeight!
// MARK: - updateScannedData
var updateScannedDataCallsCount = 0
var updateScannedDataCalled: Bool {
return updateScannedDataCallsCount > 0
}
var updateScannedDataClosure: (() async -> Void)?
func updateScannedData() async {
updateScannedDataCallsCount += 1
await updateScannedDataClosure!()
}
// MARK: - updateBlockData
var updateBlockDataCallsCount = 0
var updateBlockDataCalled: Bool {
return updateBlockDataCallsCount > 0
}
var updateBlockDataClosure: (() async -> Void)?
func updateBlockData() async {
updateBlockDataCallsCount += 1
await updateBlockDataClosure!()
}
// MARK: - updateWalletBirthday
var updateWalletBirthdayCallsCount = 0
var updateWalletBirthdayCalled: Bool {
return updateWalletBirthdayCallsCount > 0
}
var updateWalletBirthdayReceivedWalletBirthday: BlockHeight?
var updateWalletBirthdayClosure: ((BlockHeight) async -> Void)?
func updateWalletBirthday(_ walletBirthday: BlockHeight) async {
updateWalletBirthdayCallsCount += 1
updateWalletBirthdayReceivedWalletBirthday = walletBirthday
await updateWalletBirthdayClosure!(walletBirthday)
}
// MARK: - updateLatestScannedHeight
var updateLatestScannedHeightCallsCount = 0
var updateLatestScannedHeightCalled: Bool {
return updateLatestScannedHeightCallsCount > 0
}
var updateLatestScannedHeightReceivedLatestScannedHeight: BlockHeight?
var updateLatestScannedHeightClosure: ((BlockHeight) async -> Void)?
func updateLatestScannedHeight(_ latestScannedHeight: BlockHeight) async {
updateLatestScannedHeightCallsCount += 1
updateLatestScannedHeightReceivedLatestScannedHeight = latestScannedHeight
await updateLatestScannedHeightClosure!(latestScannedHeight)
}
// MARK: - updateLatestScannedTime
var updateLatestScannedTimeCallsCount = 0
var updateLatestScannedTimeCalled: Bool {
return updateLatestScannedTimeCallsCount > 0
}
var updateLatestScannedTimeReceivedLatestScannedTime: TimeInterval?
var updateLatestScannedTimeClosure: ((TimeInterval) async -> Void)?
func updateLatestScannedTime(_ latestScannedTime: TimeInterval) async {
updateLatestScannedTimeCallsCount += 1
updateLatestScannedTimeReceivedLatestScannedTime = latestScannedTime
await updateLatestScannedTimeClosure!(latestScannedTime)
}
}
class LightWalletServiceMock: LightWalletService {