Closes #427 - This is scaffold work for #427. Logic is done and some basic UI. - Logic that works with free disk space is in `DiskSpaceChecker`. Use `WrappedDiskSpaceChecker` to get live or mocked instances of `DiskSpaceChecker`. - You can either use `mockEmptyDisk` which mocks situation when there is enough space on disk. - Or you can use `mockFullDisk` to mock situation when there isn't enough space on disk.
This commit is contained in:
parent
d807f86d49
commit
ad575b8173
|
@ -51,9 +51,6 @@ playground.xcworkspace
|
|||
Carthage/Checkouts
|
||||
Carthage/Build
|
||||
Example/**/Carthage
|
||||
# Accio dependency management
|
||||
Dependencies/
|
||||
.accio/
|
||||
|
||||
# fastlane
|
||||
fastlane/report.xml
|
||||
|
|
|
@ -68,11 +68,15 @@
|
|||
2EDA07A027EDE18C00D6F09B /* TCATextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA079F27EDE18C00D6F09B /* TCATextField.swift */; };
|
||||
2EDA07A227EDE1AE00D6F09B /* TextFieldFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA07A127EDE1AE00D6F09B /* TextFieldFooter.swift */; };
|
||||
2EDA07A427EDE2A900D6F09B /* DebugFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA07A327EDE2A900D6F09B /* DebugFrame.swift */; };
|
||||
3448CB3228E47666006ADEDB /* NotEnoughFreeSpaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3128E47666006ADEDB /* NotEnoughFreeSpaceView.swift */; };
|
||||
3448CB3428E47787006ADEDB /* WrappedDiskSpaceChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3328E47787006ADEDB /* WrappedDiskSpaceChecker.swift */; };
|
||||
3448CB3728E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3628E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift */; };
|
||||
346715A528E2027D0035F7C4 /* CheckCircleStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346715A428E2027D0035F7C4 /* CheckCircleStore.swift */; };
|
||||
346715A828E20FE40035F7C4 /* TransactionConfirmationSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346715A728E20FE40035F7C4 /* TransactionConfirmationSnapshotTests.swift */; };
|
||||
346D41E428DF0B8600963F36 /* CheckCircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346D41E328DF0B8600963F36 /* CheckCircle.swift */; };
|
||||
34E0AF0F28DEE4C70034CF37 /* HoldToSendButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF0E28DEE4C70034CF37 /* HoldToSendButton.swift */; };
|
||||
34E0AF1128DEE5220034CF37 /* Wedge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF1028DEE5220034CF37 /* Wedge.swift */; };
|
||||
34E5F2F328E46DB700C17E5F /* DiskSpaceChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E5F2F228E46DB700C17E5F /* DiskSpaceChecker.swift */; };
|
||||
660558E9270C7A54009D6954 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 660558E8270C7A54009D6954 /* Colors.xcassets */; };
|
||||
660558F7270C862F009D6954 /* Fonts+Generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660558F5270C862F009D6954 /* Fonts+Generated.swift */; };
|
||||
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660558F6270C862F009D6954 /* XCAssets+Generated.swift */; };
|
||||
|
@ -307,11 +311,15 @@
|
|||
2EDA079F27EDE18C00D6F09B /* TCATextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TCATextField.swift; sourceTree = "<group>"; };
|
||||
2EDA07A127EDE1AE00D6F09B /* TextFieldFooter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldFooter.swift; sourceTree = "<group>"; };
|
||||
2EDA07A327EDE2A900D6F09B /* DebugFrame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugFrame.swift; sourceTree = "<group>"; };
|
||||
3448CB3128E47666006ADEDB /* NotEnoughFreeSpaceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotEnoughFreeSpaceView.swift; sourceTree = "<group>"; };
|
||||
3448CB3328E47787006ADEDB /* WrappedDiskSpaceChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrappedDiskSpaceChecker.swift; sourceTree = "<group>"; };
|
||||
3448CB3628E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotEnoughFeeSpaceSnapshots.swift; sourceTree = "<group>"; };
|
||||
346715A428E2027D0035F7C4 /* CheckCircleStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckCircleStore.swift; sourceTree = "<group>"; };
|
||||
346715A728E20FE40035F7C4 /* TransactionConfirmationSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionConfirmationSnapshotTests.swift; sourceTree = "<group>"; };
|
||||
346D41E328DF0B8600963F36 /* CheckCircle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckCircle.swift; sourceTree = "<group>"; };
|
||||
34E0AF0E28DEE4C70034CF37 /* HoldToSendButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HoldToSendButton.swift; sourceTree = "<group>"; };
|
||||
34E0AF1028DEE5220034CF37 /* Wedge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wedge.swift; sourceTree = "<group>"; };
|
||||
34E5F2F228E46DB700C17E5F /* DiskSpaceChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskSpaceChecker.swift; sourceTree = "<group>"; };
|
||||
660558E8270C7A54009D6954 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
|
||||
660558F5270C862F009D6954 /* Fonts+Generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Fonts+Generated.swift"; sourceTree = "<group>"; };
|
||||
660558F6270C862F009D6954 /* XCAssets+Generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "XCAssets+Generated.swift"; sourceTree = "<group>"; };
|
||||
|
@ -718,6 +726,14 @@
|
|||
path = Components;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3448CB3028E4764E006ADEDB /* NotEnoughFreeSpace */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3448CB3128E47666006ADEDB /* NotEnoughFreeSpaceView.swift */,
|
||||
);
|
||||
path = NotEnoughFreeSpace;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
346715A628E20FB30035F7C4 /* SendSnapshotTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -751,23 +767,24 @@
|
|||
6654C73B2715A3F000901167 /* Features */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9EAFEB8B2808174900199FC9 /* Sandbox */,
|
||||
0D0781C2278750C00083ACD7 /* Welcome */,
|
||||
F9971A4927680DC400A2DB75 /* App */,
|
||||
F93874EC273C4DE200F0E875 /* Home */,
|
||||
9E6713F2289BC51200A6796F /* BalanceBreakdown */,
|
||||
F9971A4F27680DD000A2DB75 /* Profile */,
|
||||
9E7CB61B2874140900A02233 /* AddressDetails */,
|
||||
F9971A4927680DC400A2DB75 /* App */,
|
||||
9E6713F2289BC51200A6796F /* BalanceBreakdown */,
|
||||
F93874EC273C4DE200F0E875 /* Home */,
|
||||
9E2DF99727CF704D00649636 /* ImportWallet */,
|
||||
3448CB3028E4764E006ADEDB /* NotEnoughFreeSpace */,
|
||||
6654C73C2715A3FA00901167 /* OnboardingFlow */,
|
||||
F9971A4F27680DD000A2DB75 /* Profile */,
|
||||
9E7FE0E4282E753700C374E8 /* RecoveryPhraseDisplay */,
|
||||
9E7FE0E3282E751A00C374E8 /* RecoveryPhraseValidationFlow */,
|
||||
F9971A5527680DDE00A2DB75 /* Request */,
|
||||
9EAFEB8B2808174900199FC9 /* Sandbox */,
|
||||
F9971A5B27680DF600A2DB75 /* Scan */,
|
||||
F9C165B62740403600592F76 /* SendFlow */,
|
||||
F9971A6127680DFE00A2DB75 /* Settings */,
|
||||
F96B41E2273B501F0021B49A /* WalletEventsFlow */,
|
||||
9E7FE0E4282E753700C374E8 /* RecoveryPhraseDisplay */,
|
||||
9E7FE0E3282E751A00C374E8 /* RecoveryPhraseValidationFlow */,
|
||||
6654C73C2715A3FA00901167 /* OnboardingFlow */,
|
||||
F9971A6727680E1000A2DB75 /* WalletInfo */,
|
||||
9E2DF99727CF704D00649636 /* ImportWallet */,
|
||||
0D0781C2278750C00083ACD7 /* Welcome */,
|
||||
);
|
||||
path = Features;
|
||||
sourceTree = "<group>";
|
||||
|
@ -837,23 +854,24 @@
|
|||
9E02B56827FED42D005B809B /* Wrappers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E02B56927FED43E005B809B /* WrappedFileManager.swift */,
|
||||
9EAFEB83280597B700199FC9 /* WrappedSecItem.swift */,
|
||||
9E02B5C2280458D2005B809B /* WrappedDerivationTool.swift */,
|
||||
9EAFEB872806E5AE00199FC9 /* WrappedSDKSynchronizer.swift */,
|
||||
9E5BF6452821028C00BA3F17 /* WrappedUserDefaults.swift */,
|
||||
9E5BF647282277BE00BA3F17 /* WrappedNotificationCenter.swift */,
|
||||
9E2AC10027D8EF0B0042AA47 /* WrappedMnemonic.swift */,
|
||||
9EF8139027F191BF0075AF48 /* WrappedWalletStorage.swift */,
|
||||
9E7FE0D8282D289B00C374E8 /* WrappedFeedbackGenerator.swift */,
|
||||
9E7FE0DA282D28F100C374E8 /* WrappedPasteboard.swift */,
|
||||
9E7FE0E7282E7B7C00C374E8 /* WrappedDatabaseFiles.swift */,
|
||||
9E01F81F2833861A000EFC57 /* WrappedCaptureDevice.swift */,
|
||||
9E01F8232833C0D8000EFC57 /* WrappedURIParser.swift */,
|
||||
9E87ADF028363DE400122FCC /* WrappedAudioServices.swift */,
|
||||
9E39113A2848D5180073DD9A /* WrappedNumberFormatter.swift */,
|
||||
9E39113E2848EC350073DD9A /* WrappedRecoveryPhraseRandomizer.swift */,
|
||||
9E01F81F2833861A000EFC57 /* WrappedCaptureDevice.swift */,
|
||||
9E7FE0E7282E7B7C00C374E8 /* WrappedDatabaseFiles.swift */,
|
||||
9EAB46692859F42E002904A0 /* WrappedDeeplinkHandler.swift */,
|
||||
9E02B5C2280458D2005B809B /* WrappedDerivationTool.swift */,
|
||||
3448CB3328E47787006ADEDB /* WrappedDiskSpaceChecker.swift */,
|
||||
9E7FE0D8282D289B00C374E8 /* WrappedFeedbackGenerator.swift */,
|
||||
9E02B56927FED43E005B809B /* WrappedFileManager.swift */,
|
||||
9E2AC10027D8EF0B0042AA47 /* WrappedMnemonic.swift */,
|
||||
9E5BF647282277BE00BA3F17 /* WrappedNotificationCenter.swift */,
|
||||
9E39113A2848D5180073DD9A /* WrappedNumberFormatter.swift */,
|
||||
9E7FE0DA282D28F100C374E8 /* WrappedPasteboard.swift */,
|
||||
9E39113E2848EC350073DD9A /* WrappedRecoveryPhraseRandomizer.swift */,
|
||||
9EAFEB872806E5AE00199FC9 /* WrappedSDKSynchronizer.swift */,
|
||||
9EAFEB83280597B700199FC9 /* WrappedSecItem.swift */,
|
||||
9E01F8232833C0D8000EFC57 /* WrappedURIParser.swift */,
|
||||
9E5BF6452821028C00BA3F17 /* WrappedUserDefaults.swift */,
|
||||
9EF8139027F191BF0075AF48 /* WrappedWalletStorage.swift */,
|
||||
);
|
||||
path = Wrappers;
|
||||
sourceTree = "<group>";
|
||||
|
@ -894,7 +912,6 @@
|
|||
9E391162284E3ECF0073DD9A /* SnapshotTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E92AF0728530EBF007367AD /* View+UIImage.swift */,
|
||||
9E94C62128AA7ECD008256E9 /* BalanceBreakdownSnapshotTests */,
|
||||
9E9ECC8B28589E150099D5A2 /* HomeSnapshotTests */,
|
||||
9E9ECC9328589E150099D5A2 /* ImportWalletSnapshotTests */,
|
||||
|
@ -904,6 +921,7 @@
|
|||
9E9ECC9128589E150099D5A2 /* RecoveryPhraseValidationFlowSnapshotTests */,
|
||||
346715A628E20FB30035F7C4 /* SendSnapshotTests */,
|
||||
9E7225EF2889537E00DF7F17 /* SettingsSnapshotTests */,
|
||||
9E92AF0728530EBF007367AD /* View+UIImage.swift */,
|
||||
9E7CB6102869881300A02233 /* WalletEventsSnapshotTests */,
|
||||
9E9ECC8D28589E150099D5A2 /* WelcomeSnapshotTests */,
|
||||
);
|
||||
|
@ -1086,15 +1104,16 @@
|
|||
9E7FE0BD282D1DE100C374E8 /* Dependencies */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E7CB6282875AC2D00A02233 /* AppVersionHandler.swift */,
|
||||
9E3911462848EEB90073DD9A /* DatabaseFiles.swift */,
|
||||
9EAB4670285A1C77002904A0 /* DeeplinkHandler.swift */,
|
||||
34E5F2F228E46DB700C17E5F /* DiskSpaceChecker.swift */,
|
||||
9E66129A28884BFB00C75B70 /* LocalAuthenticationHandler.swift */,
|
||||
9E3911422848EEB90073DD9A /* RecoveryPhraseRandomizer.swift */,
|
||||
9E3911432848EEB90073DD9A /* URIParser.swift */,
|
||||
9E3911442848EEB90073DD9A /* UserPreferencesStorage.swift */,
|
||||
9E3911472848EEB90073DD9A /* WalletStorage.swift */,
|
||||
9E3911452848EEB90073DD9A /* ZCashSDKEnvironment.swift */,
|
||||
9EAB4670285A1C77002904A0 /* DeeplinkHandler.swift */,
|
||||
9E7CB6282875AC2D00A02233 /* AppVersionHandler.swift */,
|
||||
9E66129A28884BFB00C75B70 /* LocalAuthenticationHandler.swift */,
|
||||
);
|
||||
path = Dependencies;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1202,8 +1221,9 @@
|
|||
9E9ECC8B28589E150099D5A2 /* HomeSnapshotTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E9ECC8C28589E150099D5A2 /* HomeSnapshotTests.swift */,
|
||||
9E661229287717A900C75B70 /* HomeCircularProgressSnapshotTests.swift */,
|
||||
9E9ECC8C28589E150099D5A2 /* HomeSnapshotTests.swift */,
|
||||
3448CB3628E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift */,
|
||||
);
|
||||
path = HomeSnapshotTests;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1663,6 +1683,7 @@
|
|||
9E3911482848EEB90073DD9A /* RecoveryPhraseRandomizer.swift in Sources */,
|
||||
0DF482BA2787ADA800EB37D6 /* ConditionalModifier.swift in Sources */,
|
||||
9E7225F3288AB6DD00DF7F17 /* MultipleLineTextField.swift in Sources */,
|
||||
3448CB3228E47666006ADEDB /* NotEnoughFreeSpaceView.swift in Sources */,
|
||||
9E7FE0EC282E7D9400C374E8 /* TransactionState.swift in Sources */,
|
||||
9E2F1C8F280EDE09004E65FE /* Drawer.swift in Sources */,
|
||||
665C963F272C26E600BC04FB /* CircularFrameBackground.swift in Sources */,
|
||||
|
@ -1707,6 +1728,7 @@
|
|||
34E0AF0F28DEE4C70034CF37 /* HoldToSendButton.swift in Sources */,
|
||||
F9C165C02740403600592F76 /* TransactionConfirmationView.swift in Sources */,
|
||||
0DF2DC5427235E3E00FA31E2 /* View+InnerShadow.swift in Sources */,
|
||||
3448CB3428E47787006ADEDB /* WrappedDiskSpaceChecker.swift in Sources */,
|
||||
9E39113F2848EC360073DD9A /* WrappedRecoveryPhraseRandomizer.swift in Sources */,
|
||||
9EAFEB84280597B700199FC9 /* WrappedSecItem.swift in Sources */,
|
||||
9E5BF6462821028C00BA3F17 /* WrappedUserDefaults.swift in Sources */,
|
||||
|
@ -1748,6 +1770,7 @@
|
|||
2E8719CB27FB09990082C926 /* TransactionAmountTextField.swift in Sources */,
|
||||
9E7CB6212874143800A02233 /* AddressDetailsView.swift in Sources */,
|
||||
9E6713FA289BE0E100A6796F /* ClearBackgroundView.swift in Sources */,
|
||||
34E5F2F328E46DB700C17E5F /* DiskSpaceChecker.swift in Sources */,
|
||||
F9C165C42740403600592F76 /* TransactionSentView.swift in Sources */,
|
||||
F9971A5927680DDE00A2DB75 /* RequestStore.swift in Sources */,
|
||||
);
|
||||
|
@ -1773,6 +1796,7 @@
|
|||
9EDDEAA32829610D00B4100C /* TransactionAmountInputTests.swift in Sources */,
|
||||
9E7CB6242874246800A02233 /* ProfileTests.swift in Sources */,
|
||||
9EAFEB862805A23100199FC9 /* WrappedSecItemTests.swift in Sources */,
|
||||
3448CB3728E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift in Sources */,
|
||||
9E9ECC9828589E150099D5A2 /* WelcomeSnapshotTests.swift in Sources */,
|
||||
9E7CB6122869882D00A02233 /* WalletEventsSnapshotTests.swift in Sources */,
|
||||
9E5BF644281FEC9900BA3F17 /* SendTests.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// FreeDiskSpaceChecker.swift
|
||||
// secant-testnet
|
||||
//
|
||||
// Created by Michal Fousek on 28.09.2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct DiskSpaceChecker {
|
||||
/// Free space on disk in bytes required to do sync
|
||||
func freeSpaceRequiredForSync() -> Int64 {
|
||||
return 1 * 1024 * 1024 * 1024 // 1GB converted to bytes
|
||||
}
|
||||
|
||||
func hasEnoughFreeSpaceForSync() -> Bool {
|
||||
return freeSpace() > freeSpaceRequiredForSync()
|
||||
}
|
||||
|
||||
func freeSpace() -> Int64 {
|
||||
do {
|
||||
let fileURL = URL(fileURLWithPath: NSHomeDirectory())
|
||||
let values = try fileURL.resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey])
|
||||
return values.volumeAvailableCapacityForImportantUsage ?? 0
|
||||
} catch {
|
||||
// If there is error getting information about free space from filesystem let's assume something is seriously wrong.
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,6 +68,7 @@ struct AppEnvironment {
|
|||
let databaseFiles: WrappedDatabaseFiles
|
||||
let deeplinkHandler: WrappedDeeplinkHandler
|
||||
let derivationTool: WrappedDerivationTool
|
||||
let diskSpaceChecker: WrappedDiskSpaceChecker
|
||||
let feedbackGenerator: WrappedFeedbackGenerator
|
||||
let mnemonic: WrappedMnemonic
|
||||
let recoveryPhraseRandomizer: WrappedRecoveryPhraseRandomizer
|
||||
|
@ -83,6 +84,7 @@ extension AppEnvironment {
|
|||
databaseFiles: .live(),
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(derivationTool: DerivationTool(networkType: .testnet)),
|
||||
diskSpaceChecker: .live,
|
||||
feedbackGenerator: .haptic,
|
||||
mnemonic: .live,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
@ -97,6 +99,7 @@ extension AppEnvironment {
|
|||
databaseFiles: .live(),
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(derivationTool: DerivationTool(networkType: .testnet)),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
@ -365,6 +368,7 @@ extension AppReducer {
|
|||
HomeEnvironment(
|
||||
audioServices: environment.audioServices,
|
||||
derivationTool: environment.derivationTool,
|
||||
diskSpaceChecker: environment.diskSpaceChecker,
|
||||
feedbackGenerator: environment.feedbackGenerator,
|
||||
mnemonic: environment.mnemonic,
|
||||
scheduler: environment.scheduler,
|
||||
|
|
|
@ -13,6 +13,7 @@ typealias HomeViewStore = ViewStore<HomeState, HomeAction>
|
|||
|
||||
struct HomeState: Equatable {
|
||||
enum Route: Equatable {
|
||||
case notEnoughFreeDiskSpace
|
||||
case profile
|
||||
case request
|
||||
case send
|
||||
|
@ -78,6 +79,7 @@ enum HomeAction: Equatable {
|
|||
struct HomeEnvironment {
|
||||
let audioServices: WrappedAudioServices
|
||||
let derivationTool: WrappedDerivationTool
|
||||
let diskSpaceChecker: WrappedDiskSpaceChecker
|
||||
let feedbackGenerator: WrappedFeedbackGenerator
|
||||
let mnemonic: WrappedMnemonic
|
||||
let scheduler: AnySchedulerOf<DispatchQueue>
|
||||
|
@ -90,6 +92,7 @@ extension HomeEnvironment {
|
|||
static let demo = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
|
@ -119,10 +122,17 @@ extension HomeReducer {
|
|||
switch action {
|
||||
case .onAppear:
|
||||
state.requiredTransactionConfirmations = environment.zcashSDKEnvironment.requiredTransactionConfirmations
|
||||
return environment.SDKSynchronizer.stateChanged
|
||||
.map(HomeAction.synchronizerStateChanged)
|
||||
.eraseToEffect()
|
||||
.cancellable(id: CancelId(), cancelInFlight: true)
|
||||
|
||||
if environment.diskSpaceChecker.hasEnoughFreeSpaceForSync() {
|
||||
let syncEffect = environment.SDKSynchronizer.stateChanged
|
||||
.map(HomeAction.synchronizerStateChanged)
|
||||
.eraseToEffect()
|
||||
.cancellable(id: CancelId(), cancelInFlight: true)
|
||||
|
||||
return .concatenate(Effect(value: .updateRoute(nil)), syncEffect)
|
||||
} else {
|
||||
return Effect(value: .updateRoute(.notEnoughFreeDiskSpace))
|
||||
}
|
||||
|
||||
case .onDisappear:
|
||||
return Effect.cancel(id: CancelId())
|
||||
|
@ -380,6 +390,7 @@ extension HomeStore {
|
|||
environment: HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .live,
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
|
|
|
@ -31,6 +31,10 @@ struct HomeView: View {
|
|||
BalanceBreakdown(store: store.balanceBreakdownStore())
|
||||
}
|
||||
}
|
||||
.navigationLinkEmpty(
|
||||
isActive: viewStore.bindingForRoute(.notEnoughFreeDiskSpace),
|
||||
destination: { NotEnoughFreeSpaceView(viewStore: viewStore) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// NotEnoughFreeSpace.swift
|
||||
// secant-testnet
|
||||
//
|
||||
// Created by Michal Fousek on 28.09.2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import ComposableArchitecture
|
||||
|
||||
struct NotEnoughFreeSpaceView: View {
|
||||
let viewStore: HomeViewStore
|
||||
|
||||
var body: some View {
|
||||
Text("Not enough space on disk to do synchronisation!")
|
||||
.applyScreenBackground()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct NotEnoughFreeSpaceView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
NotEnoughFreeSpaceView(viewStore: ViewStore(HomeStore.placeholder))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// WrappedDiskSpaceChecker.swift
|
||||
// secant-testnet
|
||||
//
|
||||
// Created by Michal Fousek on 28.09.2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct WrappedDiskSpaceChecker {
|
||||
let freeSpaceRequiredForSync: () -> Int64
|
||||
let hasEnoughFreeSpaceForSync: () -> Bool
|
||||
let freeSpace: () -> Int64
|
||||
}
|
||||
|
||||
extension WrappedDiskSpaceChecker {
|
||||
static let live: WrappedDiskSpaceChecker = {
|
||||
let diskSpaceChecker = DiskSpaceChecker()
|
||||
return WrappedDiskSpaceChecker(
|
||||
freeSpaceRequiredForSync: { diskSpaceChecker.freeSpaceRequiredForSync() },
|
||||
hasEnoughFreeSpaceForSync: { diskSpaceChecker.hasEnoughFreeSpaceForSync() },
|
||||
freeSpace: { diskSpaceChecker.freeSpace() }
|
||||
)
|
||||
}()
|
||||
|
||||
static let mockEmptyDisk = WrappedDiskSpaceChecker(
|
||||
freeSpaceRequiredForSync: { 1024 },
|
||||
hasEnoughFreeSpaceForSync: { true },
|
||||
freeSpace: { 2048 }
|
||||
)
|
||||
|
||||
static let mockFullDisk = WrappedDiskSpaceChecker(
|
||||
freeSpaceRequiredForSync: { 1024 },
|
||||
hasEnoughFreeSpaceForSync: { false },
|
||||
freeSpace: { 0 }
|
||||
)
|
||||
}
|
|
@ -111,6 +111,7 @@ class AppInitializationTests: XCTestCase {
|
|||
databaseFiles: dbFiles,
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: recoveryPhraseRandomizer,
|
||||
|
@ -186,6 +187,7 @@ class AppInitializationTests: XCTestCase {
|
|||
databaseFiles: dbFiles,
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
@ -229,6 +231,7 @@ class AppInitializationTests: XCTestCase {
|
|||
databaseFiles: .throwing,
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
|
|
@ -17,6 +17,7 @@ class AppTests: XCTestCase {
|
|||
databaseFiles: .throwing,
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
@ -32,6 +33,7 @@ class AppTests: XCTestCase {
|
|||
databaseFiles: .throwing,
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
@ -58,6 +60,7 @@ class AppTests: XCTestCase {
|
|||
databaseFiles: .live(databaseFiles: DatabaseFiles(fileManager: wfmMock)),
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
@ -84,6 +87,7 @@ class AppTests: XCTestCase {
|
|||
databaseFiles: .live(databaseFiles: DatabaseFiles(fileManager: wfmMock)),
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
|
|
@ -84,6 +84,7 @@ class DeeplinkTests: XCTestCase {
|
|||
databaseFiles: .live(),
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
@ -127,6 +128,7 @@ class DeeplinkTests: XCTestCase {
|
|||
databaseFiles: .live(),
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
@ -178,6 +180,7 @@ class DeeplinkTests: XCTestCase {
|
|||
databaseFiles: .live(),
|
||||
deeplinkHandler: .live,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
recoveryPhraseRandomizer: .live,
|
||||
|
|
|
@ -18,6 +18,7 @@ class HomeTests: XCTestCase {
|
|||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
|
@ -49,6 +50,7 @@ class HomeTests: XCTestCase {
|
|||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
|
@ -100,6 +102,7 @@ class HomeTests: XCTestCase {
|
|||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
|
@ -143,6 +146,7 @@ class HomeTests: XCTestCase {
|
|||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
|
@ -188,6 +192,7 @@ class HomeTests: XCTestCase {
|
|||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
|
@ -209,6 +214,7 @@ class HomeTests: XCTestCase {
|
|||
testScheduler.advance(by: 0.01)
|
||||
|
||||
// expected side effects as a result of .onAppear registration
|
||||
store.receive(.updateRoute(nil))
|
||||
store.receive(.synchronizerStateChanged(.unknown))
|
||||
store.receive(.updateSynchronizerStatus)
|
||||
|
||||
|
@ -216,6 +222,44 @@ class HomeTests: XCTestCase {
|
|||
// the .onDisappear action cancles the observer of the synchronizer status change.
|
||||
store.send(.onDisappear)
|
||||
}
|
||||
|
||||
func testOnAppear_notEnoughSpaceOnDisk() throws {
|
||||
// setup the store and environment to be fully mocked
|
||||
let testScheduler = DispatchQueue.test
|
||||
|
||||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockFullDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
SDKSynchronizer: MockWrappedSDKSynchronizer(),
|
||||
walletStorage: .throwing,
|
||||
zcashSDKEnvironment: .testnet
|
||||
)
|
||||
|
||||
let store = TestStore(
|
||||
initialState: .placeholder,
|
||||
reducer: HomeReducer.default,
|
||||
environment: testEnvironment
|
||||
)
|
||||
|
||||
store.send(.onAppear) { state in
|
||||
state.requiredTransactionConfirmations = 10
|
||||
}
|
||||
|
||||
testScheduler.advance(by: 0.01)
|
||||
|
||||
// expected side effects as a result of .onAppear registration
|
||||
store.receive(.updateRoute(.notEnoughFreeDiskSpace)) { state in
|
||||
state.route = .notEnoughFreeDiskSpace
|
||||
}
|
||||
|
||||
// long-living (cancelable) effects need to be properly canceled.
|
||||
// the .onDisappear action cancles the observer of the synchronizer status change.
|
||||
store.send(.onDisappear)
|
||||
}
|
||||
|
||||
func testQuickRescan_ResetToHomeScreen() throws {
|
||||
// setup the store and environment to be fully mocked
|
||||
|
@ -224,6 +268,7 @@ class HomeTests: XCTestCase {
|
|||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
|
@ -263,6 +308,7 @@ class HomeTests: XCTestCase {
|
|||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
|
|
|
@ -32,6 +32,7 @@ class HomeCircularProgressSnapshotTests: XCTestCase {
|
|||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
|
@ -80,6 +81,7 @@ class HomeCircularProgressSnapshotTests: XCTestCase {
|
|||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
|
@ -121,6 +123,7 @@ class HomeCircularProgressSnapshotTests: XCTestCase {
|
|||
let testEnvironment = HomeEnvironment(
|
||||
audioServices: .silent,
|
||||
derivationTool: .live(),
|
||||
diskSpaceChecker: .mockEmptyDisk,
|
||||
feedbackGenerator: .silent,
|
||||
mnemonic: .mock,
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// NotEnoughFeeSpaceViewSnapshots.swift
|
||||
// secantTests
|
||||
//
|
||||
// Created by Michal Fousek on 28.09.2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
import XCTest
|
||||
@testable import secant_testnet
|
||||
import ComposableArchitecture
|
||||
import ZcashLightClientKit
|
||||
|
||||
class NotEnoughFeeSpaceSnapshots: XCTestCase {
|
||||
func testNotEnoughFreeSpaceSnapshot() throws {
|
||||
addAttachments(NotEnoughFreeSpaceView(viewStore: ViewStore(HomeStore.placeholder)))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue