[#1039] Implement ChecksBeforeSyncAction
- ChecksBeforeSyncAction tests - all support functions in Action tests are set to private - let _ = -> _ = refactor - CompactBlockRepository mock added
This commit is contained in:
parent
15c069b914
commit
23f3e70cc5
|
@ -0,0 +1,153 @@
|
|||
//
|
||||
// ChecksBeforeSyncActionTests.swift
|
||||
//
|
||||
//
|
||||
// Created by Lukáš Korba on 22.05.2023.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
final class ChecksBeforeSyncActionTests: ZcashTestCase {
|
||||
var underlyingDownloadedButUnscannedRange: CompactBlockRange?
|
||||
var underlyingLatestScannedHeight: BlockHeight?
|
||||
var underlyingLatestDownloadedBlockHeight: BlockHeight?
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
|
||||
underlyingDownloadedButUnscannedRange = nil
|
||||
underlyingLatestScannedHeight = nil
|
||||
underlyingLatestDownloadedBlockHeight = nil
|
||||
}
|
||||
|
||||
func testChecksBeforeSyncAction_shouldClearBlockCacheAndUpdateInternalState_noDownloadedButUnscannedRange() async throws {
|
||||
let checksBeforeSyncAction = setupAction()
|
||||
|
||||
let syncRanges = setupSyncRanges()
|
||||
|
||||
let latestScannedHeight = checksBeforeSyncAction.shouldClearBlockCacheAndUpdateInternalState(syncRange: syncRanges)
|
||||
XCTAssertNil(latestScannedHeight, "latestScannedHeight is expected to be nil.")
|
||||
}
|
||||
|
||||
func testChecksBeforeSyncAction_shouldClearBlockCacheAndUpdateInternalState_nothingToClear() async throws {
|
||||
let checksBeforeSyncAction = setupAction()
|
||||
|
||||
underlyingDownloadedButUnscannedRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
|
||||
underlyingLatestScannedHeight = BlockHeight(2000)
|
||||
underlyingLatestDownloadedBlockHeight = BlockHeight(2000)
|
||||
|
||||
let syncRanges = setupSyncRanges()
|
||||
|
||||
let latestScannedHeight = checksBeforeSyncAction.shouldClearBlockCacheAndUpdateInternalState(syncRange: syncRanges)
|
||||
XCTAssertNil(latestScannedHeight, "latestScannedHeight is expected to be nil.")
|
||||
}
|
||||
|
||||
func testChecksBeforeSyncAction_shouldClearBlockCacheAndUpdateInternalState_somethingToClear() async throws {
|
||||
let checksBeforeSyncAction = setupAction()
|
||||
|
||||
underlyingDownloadedButUnscannedRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
|
||||
underlyingLatestScannedHeight = BlockHeight(2000)
|
||||
underlyingLatestDownloadedBlockHeight = BlockHeight(1000)
|
||||
|
||||
let syncRanges = setupSyncRanges()
|
||||
|
||||
let latestScannedHeight = checksBeforeSyncAction.shouldClearBlockCacheAndUpdateInternalState(syncRange: syncRanges)
|
||||
XCTAssertNotNil(latestScannedHeight, "latestScannedHeight is not expected to be nil.")
|
||||
}
|
||||
|
||||
func testChecksBeforeSyncAction_NextAction_ClearStorage() async throws {
|
||||
let compactBlockRepository = CompactBlockRepositoryMock()
|
||||
let internalSyncProgressStorageMock = InternalSyncProgressStorageMock()
|
||||
|
||||
compactBlockRepository.clearClosure = { }
|
||||
internalSyncProgressStorageMock.setForKeyClosure = { _, _ in }
|
||||
internalSyncProgressStorageMock.synchronizeClosure = { true }
|
||||
|
||||
let checksBeforeSyncAction = setupAction(
|
||||
compactBlockRepository,
|
||||
internalSyncProgressStorageMock
|
||||
)
|
||||
|
||||
underlyingDownloadedButUnscannedRange = CompactBlockRange(uncheckedBounds: (1000, 2000))
|
||||
underlyingLatestScannedHeight = BlockHeight(2000)
|
||||
underlyingLatestDownloadedBlockHeight = BlockHeight(1000)
|
||||
|
||||
let syncContext = await setupActionContext()
|
||||
|
||||
do {
|
||||
let nextContext = try await checksBeforeSyncAction.run(with: syncContext) { _ in }
|
||||
XCTAssertTrue(compactBlockRepository.clearCalled, "storage.clear() is expected to be called.")
|
||||
XCTAssertTrue(internalSyncProgressStorageMock.setForKeyCalled, "internalSyncProgress.set() is expected to be called.")
|
||||
let nextState = await nextContext.state
|
||||
XCTAssertTrue(
|
||||
nextState == .fetchUTXO,
|
||||
"nextContext after .checksBeforeSync is expected to be .fetchUTXO but received \(nextState)"
|
||||
)
|
||||
} catch {
|
||||
XCTFail("testChecksBeforeSyncAction_NextAction_ClearStorage is not expected to fail. \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func testChecksBeforeSyncAction_NextAction_CreateStorage() async throws {
|
||||
let compactBlockRepository = CompactBlockRepositoryMock()
|
||||
let internalSyncProgressStorageMock = InternalSyncProgressStorageMock()
|
||||
|
||||
compactBlockRepository.createClosure = { }
|
||||
|
||||
let checksBeforeSyncAction = setupAction(compactBlockRepository)
|
||||
|
||||
let syncContext = await setupActionContext()
|
||||
|
||||
do {
|
||||
let nextContext = try await checksBeforeSyncAction.run(with: syncContext) { _ in }
|
||||
XCTAssertTrue(compactBlockRepository.createCalled, "storage.create() is expected to be called.")
|
||||
XCTAssertFalse(internalSyncProgressStorageMock.setForKeyCalled, "internalSyncProgress.set() is not expected to be called.")
|
||||
let nextState = await nextContext.state
|
||||
XCTAssertTrue(
|
||||
nextState == .fetchUTXO,
|
||||
"nextContext after .checksBeforeSync is expected to be .fetchUTXO but received \(nextState)"
|
||||
)
|
||||
} catch {
|
||||
XCTFail("testChecksBeforeSyncAction_NextAction_CreateStorage is not expected to fail. \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private func setupAction(
|
||||
_ compactBlockRepositoryMock: CompactBlockRepositoryMock = CompactBlockRepositoryMock(),
|
||||
_ internalSyncProgressStorageMock: InternalSyncProgressStorageMock = InternalSyncProgressStorageMock(),
|
||||
_ loggerMock: LoggerMock = LoggerMock()
|
||||
) -> ChecksBeforeSyncAction {
|
||||
mockContainer.register(type: InternalSyncProgress.self, isSingleton: true) { di in
|
||||
InternalSyncProgress(alias: .default, storage: internalSyncProgressStorageMock, logger: loggerMock)
|
||||
}
|
||||
|
||||
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in compactBlockRepositoryMock }
|
||||
|
||||
return ChecksBeforeSyncAction(
|
||||
container: mockContainer
|
||||
)
|
||||
}
|
||||
|
||||
private func setupSyncRanges() -> SyncRanges {
|
||||
SyncRanges(
|
||||
latestBlockHeight: 0,
|
||||
downloadedButUnscannedRange: underlyingDownloadedButUnscannedRange,
|
||||
downloadAndScanRange: nil,
|
||||
enhanceRange: nil,
|
||||
fetchUTXORange: nil,
|
||||
latestScannedHeight: underlyingLatestScannedHeight,
|
||||
latestDownloadedBlockHeight: underlyingLatestDownloadedBlockHeight
|
||||
)
|
||||
}
|
||||
|
||||
private func setupActionContext() async -> ActionContext {
|
||||
let syncContext: ActionContext = .init(state: .checksBeforeSync)
|
||||
|
||||
await syncContext.update(syncRanges: setupSyncRanges())
|
||||
await syncContext.update(totalProgressRange: CompactBlockRange(uncheckedBounds: (1000, 2000)))
|
||||
|
||||
return syncContext
|
||||
}
|
||||
}
|
|
@ -242,7 +242,7 @@ final class EnhanceActionTests: ZcashTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
func setupActionContext() async -> ActionContext {
|
||||
private func setupActionContext() async -> ActionContext {
|
||||
let syncContext: ActionContext = .init(state: .enhance)
|
||||
|
||||
let syncRanges = SyncRanges(
|
||||
|
@ -261,7 +261,7 @@ final class EnhanceActionTests: ZcashTestCase {
|
|||
return syncContext
|
||||
}
|
||||
|
||||
func setupAction(
|
||||
private func setupAction(
|
||||
_ blockEnhancerMock: BlockEnhancerMock = BlockEnhancerMock(),
|
||||
_ transactionRepositoryMock: TransactionRepositoryMock = TransactionRepositoryMock(),
|
||||
_ internalSyncProgressStorageMock: InternalSyncProgressStorageMock = InternalSyncProgressStorageMock(),
|
||||
|
|
|
@ -86,7 +86,7 @@ final class ScanActionTests: ZcashTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
func setupAction(
|
||||
private func setupAction(
|
||||
_ blockScannerMock: BlockScannerMock,
|
||||
_ transactionRepositoryMock: TransactionRepositoryMock,
|
||||
_ loggerMock: LoggerMock
|
||||
|
@ -105,7 +105,7 @@ final class ScanActionTests: ZcashTestCase {
|
|||
)
|
||||
}
|
||||
|
||||
func setupActionContext() async -> ActionContext {
|
||||
private func setupActionContext() async -> ActionContext {
|
||||
let syncContext: ActionContext = .init(state: .scan)
|
||||
|
||||
let syncRanges = SyncRanges(
|
||||
|
|
|
@ -131,7 +131,7 @@ final class ValidateServerActionTests: ZcashTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
func setupAction() -> ValidateServerAction {
|
||||
private func setupAction() -> ValidateServerAction {
|
||||
let config: CompactBlockProcessor.Configuration = .standard(
|
||||
for: ZcashNetworkBuilder.network(for: underlyingNetworkType), walletBirthday: 0
|
||||
)
|
||||
|
|
|
@ -16,6 +16,7 @@ extension BlockDownloader { }
|
|||
extension BlockEnhancer { }
|
||||
extension BlockScanner { }
|
||||
extension BlockValidator { }
|
||||
extension CompactBlockRepository { }
|
||||
extension InternalSyncProgressStorage { }
|
||||
extension LightWalletdInfo { }
|
||||
extension LightWalletService { }
|
||||
|
|
|
@ -184,6 +184,123 @@ class BlockValidatorMock: BlockValidator {
|
|||
try await validateClosure!()
|
||||
}
|
||||
|
||||
}
|
||||
class CompactBlockRepositoryMock: CompactBlockRepository {
|
||||
|
||||
|
||||
init(
|
||||
) {
|
||||
}
|
||||
|
||||
// MARK: - create
|
||||
|
||||
var createThrowableError: Error?
|
||||
var createCallsCount = 0
|
||||
var createCalled: Bool {
|
||||
return createCallsCount > 0
|
||||
}
|
||||
var createClosure: (() async throws -> Void)?
|
||||
|
||||
func create() async throws {
|
||||
if let error = createThrowableError {
|
||||
throw error
|
||||
}
|
||||
createCallsCount += 1
|
||||
try await createClosure!()
|
||||
}
|
||||
|
||||
// MARK: - latestHeight
|
||||
|
||||
var latestHeightCallsCount = 0
|
||||
var latestHeightCalled: Bool {
|
||||
return latestHeightCallsCount > 0
|
||||
}
|
||||
var latestHeightReturnValue: BlockHeight!
|
||||
var latestHeightClosure: (() async -> BlockHeight)?
|
||||
|
||||
func latestHeight() async -> BlockHeight {
|
||||
latestHeightCallsCount += 1
|
||||
if let closure = latestHeightClosure {
|
||||
return await closure()
|
||||
} else {
|
||||
return latestHeightReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - write
|
||||
|
||||
var writeBlocksThrowableError: Error?
|
||||
var writeBlocksCallsCount = 0
|
||||
var writeBlocksCalled: Bool {
|
||||
return writeBlocksCallsCount > 0
|
||||
}
|
||||
var writeBlocksReceivedBlocks: [ZcashCompactBlock]?
|
||||
var writeBlocksClosure: (([ZcashCompactBlock]) async throws -> Void)?
|
||||
|
||||
func write(blocks: [ZcashCompactBlock]) async throws {
|
||||
if let error = writeBlocksThrowableError {
|
||||
throw error
|
||||
}
|
||||
writeBlocksCallsCount += 1
|
||||
writeBlocksReceivedBlocks = blocks
|
||||
try await writeBlocksClosure!(blocks)
|
||||
}
|
||||
|
||||
// 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: - clear
|
||||
|
||||
var clearUpToThrowableError: Error?
|
||||
var clearUpToCallsCount = 0
|
||||
var clearUpToCalled: Bool {
|
||||
return clearUpToCallsCount > 0
|
||||
}
|
||||
var clearUpToReceivedHeight: BlockHeight?
|
||||
var clearUpToClosure: ((BlockHeight) async throws -> Void)?
|
||||
|
||||
func clear(upTo height: BlockHeight) async throws {
|
||||
if let error = clearUpToThrowableError {
|
||||
throw error
|
||||
}
|
||||
clearUpToCallsCount += 1
|
||||
clearUpToReceivedHeight = height
|
||||
try await clearUpToClosure!(height)
|
||||
}
|
||||
|
||||
// MARK: - clear
|
||||
|
||||
var clearThrowableError: Error?
|
||||
var clearCallsCount = 0
|
||||
var clearCalled: Bool {
|
||||
return clearCallsCount > 0
|
||||
}
|
||||
var clearClosure: (() async throws -> Void)?
|
||||
|
||||
func clear() async throws {
|
||||
if let error = clearThrowableError {
|
||||
throw error
|
||||
}
|
||||
clearCallsCount += 1
|
||||
try await clearClosure!()
|
||||
}
|
||||
|
||||
}
|
||||
class InternalSyncProgressStorageMock: InternalSyncProgressStorage {
|
||||
|
||||
|
|
Loading…
Reference in New Issue