[#554] Use WalletConfigProvider and WalletConfig in the TCA (#582)

Closes #554

- WalletConfigProvider and WalletConfig are used in the Secant app.
- First feature flag (`onboarding`) is in use.

Co-authored-by: Lukas Korba <lukas.korba@seznam.cz>
This commit is contained in:
Michal Fousek 2023-02-27 13:55:47 +01:00 committed by GitHub
parent cc7da24732
commit 56e1364659
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 300 additions and 188 deletions

View File

@ -84,10 +84,10 @@
0D26AEDC299E8196005260EE /* CheckCircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346D41E328DF0B8600963F36 /* CheckCircle.swift */; };
0D26AEDD299E8196005260EE /* LogStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F5744297EBA1B005304FA /* LogStore.swift */; };
0D26AEDE299E8196005260EE /* RecoveryPhraseRandomizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911422848EEB90073DD9A /* RecoveryPhraseRandomizer.swift */; };
0D26AEDF299E8196005260EE /* FileManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C42923C8AF003D0F8B /* FileManagerTest.swift */; };
0D26AEDF299E8196005260EE /* FileManagerTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C42923C8AF003D0F8B /* FileManagerTestKey.swift */; };
0D26AEE0299E8196005260EE /* SecItemLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863BE2923C72C003D0F8B /* SecItemLive.swift */; };
0D26AEE1299E8196005260EE /* CircularFrameBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669FDAEA272C23C2007B9422 /* CircularFrameBadge.swift */; };
0D26AEE2299E8196005260EE /* FileManagerLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863B82923C6D7003D0F8B /* FileManagerLive.swift */; };
0D26AEE2299E8196005260EE /* FileManagerLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863B82923C6D7003D0F8B /* FileManagerLiveKey.swift */; };
0D26AEE3299E8196005260EE /* AppVersionTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBDF979291F7EB0000A1A05 /* AppVersionTestKey.swift */; };
0D26AEE4299E8196005260EE /* CurrencySelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E8719CC27FB0D3B0082C926 /* CurrencySelectionView.swift */; };
0D26AEE5299E8196005260EE /* RecoveryPhraseRandomizerTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863A429239DCB003D0F8B /* RecoveryPhraseRandomizerTestKey.swift */; };
@ -320,12 +320,15 @@
3448CB3228E47666006ADEDB /* NotEnoughFreeSpaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3128E47666006ADEDB /* NotEnoughFreeSpaceView.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 */; };
3469F18229ACD70500A07146 /* OnboardingFlowFeatureFlagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3469F18129ACD70500A07146 /* OnboardingFlowFeatureFlagTests.swift */; };
346D41E428DF0B8600963F36 /* CheckCircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346D41E328DF0B8600963F36 /* CheckCircle.swift */; };
34BF09092927C98000222134 /* Memo+toString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BF09082927C98000222134 /* Memo+toString.swift */; };
34DA414728E4385800F8CC61 /* TransactionSendingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DA414628E4385800F8CC61 /* TransactionSendingView.swift */; };
34DA414928E439CD00F8CC61 /* sendingTransaction.json in Resources */ = {isa = PBXBuildFile; fileRef = 34DA414828E439CD00F8CC61 /* sendingTransaction.json */; };
34E0AF1128DEE5220034CF37 /* Wedge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF1028DEE5220034CF37 /* Wedge.swift */; };
34E5F2F328E46DB700C17E5F /* DiskSpaceChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E5F2F228E46DB700C17E5F /* DiskSpaceChecker.swift */; };
34F039B329ABCE8500CF0053 /* WalletConfigProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F039B229ABCE8500CF0053 /* WalletConfigProviderTests.swift */; };
34F682E529A75EB60022C079 /* WalletConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682E429A75EB60022C079 /* WalletConfig.swift */; };
34F682E629A75EB60022C079 /* WalletConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682E429A75EB60022C079 /* WalletConfig.swift */; };
34F682EC29A763FD0022C079 /* WalletConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682EB29A763FD0022C079 /* WalletConfigProvider.swift */; };
@ -338,7 +341,6 @@
34F682F629A7641B0022C079 /* WalletConfigProviderTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F429A7641B0022C079 /* WalletConfigProviderTestKey.swift */; };
34F682F829A775C10022C079 /* UserDefaultsWalletConfigStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F729A775C10022C079 /* UserDefaultsWalletConfigStorage.swift */; };
34F682F929A775C10022C079 /* UserDefaultsWalletConfigStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F729A775C10022C079 /* UserDefaultsWalletConfigStorage.swift */; };
34F682FC29A784660022C079 /* WalletConfigProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682FB29A784660022C079 /* WalletConfigProviderTests.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 */; };
@ -475,13 +477,13 @@
9EB863A829239DCB003D0F8B /* RecoveryPhraseRandomizerLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863A529239DCB003D0F8B /* RecoveryPhraseRandomizerLiveKey.swift */; };
9EB863A929239DCB003D0F8B /* RecoveryPhraseRandomizerInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863A629239DCB003D0F8B /* RecoveryPhraseRandomizerInterface.swift */; };
9EB863AA29239EB2003D0F8B /* RecoveryPhraseRandomizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911422848EEB90073DD9A /* RecoveryPhraseRandomizer.swift */; };
9EB863B92923C6D7003D0F8B /* FileManagerLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863B82923C6D7003D0F8B /* FileManagerLive.swift */; };
9EB863B92923C6D7003D0F8B /* FileManagerLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863B82923C6D7003D0F8B /* FileManagerLiveKey.swift */; };
9EB863BB2923C6F8003D0F8B /* NotificationCenterLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863BA2923C6F8003D0F8B /* NotificationCenterLive.swift */; };
9EB863BD2923C704003D0F8B /* NotificationCenterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863BC2923C704003D0F8B /* NotificationCenterTest.swift */; };
9EB863BF2923C72C003D0F8B /* SecItemLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863BE2923C72C003D0F8B /* SecItemLive.swift */; };
9EB863C12923C779003D0F8B /* URIParserLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C02923C779003D0F8B /* URIParserLive.swift */; };
9EB863C32923C807003D0F8B /* URIParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C22923C807003D0F8B /* URIParserTest.swift */; };
9EB863C52923C8AF003D0F8B /* FileManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C42923C8AF003D0F8B /* FileManagerTest.swift */; };
9EB863C52923C8AF003D0F8B /* FileManagerTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C42923C8AF003D0F8B /* FileManagerTestKey.swift */; };
9EB863C72923C93B003D0F8B /* UserPreferencesStorageLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C62923C93B003D0F8B /* UserPreferencesStorageLive.swift */; };
9EB863C92923C953003D0F8B /* UserPreferencesStorageMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C82923C953003D0F8B /* UserPreferencesStorageMocks.swift */; };
9EB863CB2923CA20003D0F8B /* SDKSynchronizerLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863CA2923CA20003D0F8B /* SDKSynchronizerLive.swift */; };
@ -644,19 +646,21 @@
3448CB3128E47666006ADEDB /* NotEnoughFreeSpaceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotEnoughFreeSpaceView.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>"; };
3469F18129ACD70500A07146 /* OnboardingFlowFeatureFlagTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingFlowFeatureFlagTests.swift; sourceTree = "<group>"; };
346D41E328DF0B8600963F36 /* CheckCircle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckCircle.swift; sourceTree = "<group>"; };
34BF09082927C98000222134 /* Memo+toString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Memo+toString.swift"; sourceTree = "<group>"; };
34DA414628E4385800F8CC61 /* TransactionSendingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionSendingView.swift; sourceTree = "<group>"; };
34DA414828E439CD00F8CC61 /* sendingTransaction.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = sendingTransaction.json; 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>"; };
34F039B229ABCE8500CF0053 /* WalletConfigProviderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletConfigProviderTests.swift; sourceTree = "<group>"; };
34F682E429A75EB60022C079 /* WalletConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfig.swift; sourceTree = "<group>"; };
34F682EB29A763FD0022C079 /* WalletConfigProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfigProvider.swift; sourceTree = "<group>"; };
34F682EE29A7640A0022C079 /* WalletConfigProviderInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfigProviderInterface.swift; sourceTree = "<group>"; };
34F682F129A764120022C079 /* WalletConfigProviderLiveKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfigProviderLiveKey.swift; sourceTree = "<group>"; };
34F682F429A7641B0022C079 /* WalletConfigProviderTestKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfigProviderTestKey.swift; sourceTree = "<group>"; };
34F682F729A775C10022C079 /* UserDefaultsWalletConfigStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsWalletConfigStorage.swift; sourceTree = "<group>"; };
34F682FB29A784660022C079 /* WalletConfigProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfigProviderTests.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>"; };
@ -786,13 +790,13 @@
9EB863A429239DCB003D0F8B /* RecoveryPhraseRandomizerTestKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseRandomizerTestKey.swift; sourceTree = "<group>"; };
9EB863A529239DCB003D0F8B /* RecoveryPhraseRandomizerLiveKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseRandomizerLiveKey.swift; sourceTree = "<group>"; };
9EB863A629239DCB003D0F8B /* RecoveryPhraseRandomizerInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseRandomizerInterface.swift; sourceTree = "<group>"; };
9EB863B82923C6D7003D0F8B /* FileManagerLive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManagerLive.swift; sourceTree = "<group>"; };
9EB863B82923C6D7003D0F8B /* FileManagerLiveKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManagerLiveKey.swift; sourceTree = "<group>"; };
9EB863BA2923C6F8003D0F8B /* NotificationCenterLive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationCenterLive.swift; sourceTree = "<group>"; };
9EB863BC2923C704003D0F8B /* NotificationCenterTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationCenterTest.swift; sourceTree = "<group>"; };
9EB863BE2923C72C003D0F8B /* SecItemLive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecItemLive.swift; sourceTree = "<group>"; };
9EB863C02923C779003D0F8B /* URIParserLive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URIParserLive.swift; sourceTree = "<group>"; };
9EB863C22923C807003D0F8B /* URIParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URIParserTest.swift; sourceTree = "<group>"; };
9EB863C42923C8AF003D0F8B /* FileManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManagerTest.swift; sourceTree = "<group>"; };
9EB863C42923C8AF003D0F8B /* FileManagerTestKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManagerTestKey.swift; sourceTree = "<group>"; };
9EB863C62923C93B003D0F8B /* UserPreferencesStorageLive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorageLive.swift; sourceTree = "<group>"; };
9EB863C82923C953003D0F8B /* UserPreferencesStorageMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorageMocks.swift; sourceTree = "<group>"; };
9EB863CA2923CA20003D0F8B /* SDKSynchronizerLive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDKSynchronizerLive.swift; sourceTree = "<group>"; };
@ -1001,7 +1005,6 @@
0DFE93DD272C6D4B000FCCA5 /* BackupFlowTests */,
9E94C61E28AA7DD5008256E9 /* BalanceBreakdownTests */,
9EAB4674285B5C68002904A0 /* DeeplinkTests */,
34F682FA29A784580022C079 /* WalletConfigProvider */,
9E3911372848AD3A0073DD9A /* HomeTests */,
9E391122283E4C970073DD9A /* ImportWalletTests */,
9E6713EF2897F80A00A6796F /* MultiLineTextFieldTests */,
@ -1015,6 +1018,7 @@
9E66129C2889388C00C75B70 /* SettingsTests */,
9E391162284E3ECF0073DD9A /* SnapshotTests */,
9EF8135927ECC25E0075AF48 /* UtilTests */,
34F039B129ABCE8500CF0053 /* WalletConfigProviderTests */,
9E5BF63D281953F900BA3F17 /* WalletEventsTests */,
);
path = secantTests;
@ -1180,7 +1184,15 @@
path = CheckCircle;
sourceTree = "<group>";
};
34F682EA29A763F00022C079 /* FeatureFlagsManager */ = {
34F039B129ABCE8500CF0053 /* WalletConfigProviderTests */ = {
isa = PBXGroup;
children = (
34F039B229ABCE8500CF0053 /* WalletConfigProviderTests.swift */,
);
path = WalletConfigProviderTests;
sourceTree = "<group>";
};
34F682EA29A763F00022C079 /* WalletConfigProvider */ = {
isa = PBXGroup;
children = (
34F682EB29A763FD0022C079 /* WalletConfigProvider.swift */,
@ -1189,14 +1201,6 @@
34F682F129A764120022C079 /* WalletConfigProviderLiveKey.swift */,
34F682F429A7641B0022C079 /* WalletConfigProviderTestKey.swift */,
);
path = FeatureFlagsManager;
sourceTree = "<group>";
};
34F682FA29A784580022C079 /* WalletConfigProvider */ = {
isa = PBXGroup;
children = (
34F682FB29A784660022C079 /* WalletConfigProviderTests.swift */,
);
path = WalletConfigProvider;
sourceTree = "<group>";
};
@ -1262,6 +1266,7 @@
isa = PBXGroup;
children = (
6654C7432715A4AC00901167 /* OnboardingStoreTests.swift */,
3469F18129ACD70500A07146 /* OnboardingFlowFeatureFlagTests.swift */,
);
path = OnboardingTests;
sourceTree = "<group>";
@ -1635,7 +1640,6 @@
9EBDF959291E654F000A1A05 /* Deeplink */,
9EBDF971291F79C9000A1A05 /* DerivationTool */,
9EBDF945291D759B000A1A05 /* DiskSpaceChecker */,
34F682EA29A763F00022C079 /* FeatureFlagsManager */,
9EB863882922CC0E003D0F8B /* FeedbackGenerator */,
9EB863B52923C4ED003D0F8B /* FileManager */,
9EBDF981291F91B1000A1A05 /* LocalAuthentication */,
@ -1650,6 +1654,7 @@
9EB8639E29239891003D0F8B /* URIParser */,
9E153A7129216EBD00112F41 /* UserDefaults */,
9EB863B72923C55A003D0F8B /* UserPreferencesStorage */,
34F682EA29A763F00022C079 /* WalletConfigProvider */,
9EB86396292392F6003D0F8B /* WalletStorage */,
9E153A6A292167BF00112F41 /* ZcashSDKEnvironment */,
);
@ -1907,8 +1912,8 @@
isa = PBXGroup;
children = (
9E02B56927FED43E005B809B /* FileManagerInterface.swift */,
9EB863B82923C6D7003D0F8B /* FileManagerLive.swift */,
9EB863C42923C8AF003D0F8B /* FileManagerTest.swift */,
9EB863B82923C6D7003D0F8B /* FileManagerLiveKey.swift */,
9EB863C42923C8AF003D0F8B /* FileManagerTestKey.swift */,
);
path = FileManager;
sourceTree = "<group>";
@ -2611,10 +2616,10 @@
0D26AEDC299E8196005260EE /* CheckCircle.swift in Sources */,
0D26AEDD299E8196005260EE /* LogStore.swift in Sources */,
0D26AEDE299E8196005260EE /* RecoveryPhraseRandomizer.swift in Sources */,
0D26AEDF299E8196005260EE /* FileManagerTest.swift in Sources */,
0D26AEDF299E8196005260EE /* FileManagerTestKey.swift in Sources */,
0D26AEE0299E8196005260EE /* SecItemLive.swift in Sources */,
0D26AEE1299E8196005260EE /* CircularFrameBadge.swift in Sources */,
0D26AEE2299E8196005260EE /* FileManagerLive.swift in Sources */,
0D26AEE2299E8196005260EE /* FileManagerLiveKey.swift in Sources */,
0D26AEE3299E8196005260EE /* AppVersionTestKey.swift in Sources */,
0D26AEE4299E8196005260EE /* CurrencySelectionView.swift in Sources */,
0D26AEE5299E8196005260EE /* RecoveryPhraseRandomizerTestKey.swift in Sources */,
@ -2835,10 +2840,10 @@
346D41E428DF0B8600963F36 /* CheckCircle.swift in Sources */,
9E0F5745297EBA1B005304FA /* LogStore.swift in Sources */,
9EB863AA29239EB2003D0F8B /* RecoveryPhraseRandomizer.swift in Sources */,
9EB863C52923C8AF003D0F8B /* FileManagerTest.swift in Sources */,
9EB863C52923C8AF003D0F8B /* FileManagerTestKey.swift in Sources */,
9EB863BF2923C72C003D0F8B /* SecItemLive.swift in Sources */,
669FDAEB272C23C2007B9422 /* CircularFrameBadge.swift in Sources */,
9EB863B92923C6D7003D0F8B /* FileManagerLive.swift in Sources */,
9EB863B92923C6D7003D0F8B /* FileManagerLiveKey.swift in Sources */,
9EBDF97C291F7EB0000A1A05 /* AppVersionTestKey.swift in Sources */,
2E8719CD27FB0D3B0082C926 /* CurrencySelectionView.swift in Sources */,
9EB863A729239DCB003D0F8B /* RecoveryPhraseRandomizerTestKey.swift in Sources */,
@ -2989,6 +2994,7 @@
buildActionMask = 2147483647;
files = (
9E7225F12889539300DF7F17 /* SettingsSnapshotTests.swift in Sources */,
3469F18229ACD70500A07146 /* OnboardingFlowFeatureFlagTests.swift in Sources */,
0DFE93DF272C6D4B000FCCA5 /* RecoveryPhraseBackupTests.swift in Sources */,
9EDDEAA22829610D00B4100C /* CurrencySelectionTests.swift in Sources */,
9E6713F12897F81B00A6796F /* MultiLineTextFieldTests.swift in Sources */,
@ -2997,6 +3003,7 @@
9EDDEAA42829610D00B4100C /* TransactionAddressInputTests.swift in Sources */,
9E7CB6272874269F00A02233 /* ProfileSnapshotTests.swift in Sources */,
9E92AF0828530EBF007367AD /* View+UIImage.swift in Sources */,
34F039B329ABCE8500CF0053 /* WalletConfigProviderTests.swift in Sources */,
34429C6E28E703CD00F2B929 /* TransactionSendingSnapshotTests.swift in Sources */,
6654C7442715A4AC00901167 /* OnboardingStoreTests.swift in Sources */,
9E94C62328AA7EE0008256E9 /* BalanceBreakdownSnapshotTests.swift in Sources */,
@ -3030,7 +3037,6 @@
9E02B56C27FED475005B809B /* DatabaseFilesTests.swift in Sources */,
9E612C7929913F3600D09B09 /* SensitiveDataTests.swift in Sources */,
9EF8135D27ECC25E0075AF48 /* UserPreferencesStorageTests.swift in Sources */,
34F682FC29A784660022C079 /* WalletConfigProviderTests.swift in Sources */,
9E94C62028AA7DEE008256E9 /* BalanceBreakdownTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -3355,9 +3361,10 @@
);
PRODUCT_BUNDLE_IDENTIFIER = co.electriccoin.secantUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = secant;
TEST_TARGET_NAME = "secant-testnet";
};
name = Debug;
};
@ -3376,9 +3383,10 @@
);
PRODUCT_BUNDLE_IDENTIFIER = co.electriccoin.secantUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = secant;
TEST_TARGET_NAME = "secant-testnet";
};
name = Release;
};

View File

@ -1,5 +1,5 @@
//
// FileManagerLive.swift
// FileManagerLiveKey.swift
// secant-testnet
//
// Created by Lukáš Korba on 15.11.2022.

View File

@ -1,5 +1,5 @@
//
// FileManagerTest.swift
// FileManagerTestKey.swift
// secant-testnet
//
// Created by Lukáš Korba on 15.11.2022.

View File

@ -6,7 +6,6 @@
//
import ComposableArchitecture
import Foundation
import XCTestDynamicOverlay
extension WalletConfigProviderClient: TestDependencyKey {
@ -16,7 +15,7 @@ extension WalletConfigProviderClient: TestDependencyKey {
}
extension WalletConfigProviderClient {
static let `default` = Self(
static let noOp = Self(
load: { WalletConfig.default }
)
}

View File

@ -27,10 +27,12 @@ struct OnboardingFlowReducer: ReducerProtocol {
let badge: Badge
}
var steps: IdentifiedArrayOf<Step> = Self.onboardingSteps
var destination: Destination?
var walletConfig: WalletConfig
var importWalletState: ImportWalletReducer.State
var index = 0
var skippedAtindex: Int?
var destination: Destination?
var steps: IdentifiedArrayOf<Step> = Self.onboardingSteps
var currentStep: Step { steps[index] }
var isFinalStep: Bool { steps.count == index + 1 }
@ -42,19 +44,17 @@ struct OnboardingFlowReducer: ReducerProtocol {
guard index != 0 else { return .zero }
return stepOffset * CGFloat(index)
}
/// Import Wallet
var importWalletState: ImportWalletReducer.State
}
enum Action: Equatable {
case next
case back
case skip
case updateDestination(OnboardingFlowReducer.State.Destination?)
case createNewWallet
case importExistingWallet
case importWallet(ImportWalletReducer.Action)
case next
case onAppear
case skip
case updateDestination(OnboardingFlowReducer.State.Destination?)
}
var body: some ReducerProtocol<State, Action> {
@ -64,6 +64,12 @@ struct OnboardingFlowReducer: ReducerProtocol {
Reduce { state, action in
switch action {
case .onAppear:
if !state.walletConfig.isEnabled(.onboardingFlow) {
return EffectTask(value: .skip)
}
return .none
case .back:
guard state.index > 0 else { return .none }
if let skippedFrom = state.skippedAtindex {

View File

@ -9,38 +9,42 @@ import SwiftUI
import ComposableArchitecture
struct OnboardingScreen: View {
let store: Store<OnboardingFlowReducer.State, OnboardingFlowReducer.Action>
let store: OnboardingFlowStore
var body: some View {
VStack {
ZStack {
OnboardingHeaderView(
store: store.scope(
state: { state in
OnboardingHeaderView.ViewState(
isInitialStep: state.isInitialStep,
isFinalStep: state.isFinalStep
)
},
action: { action in
switch action {
case .back: return .back
case .skip: return .skip
WithViewStore(store) { viewStore in
VStack {
ZStack {
OnboardingHeaderView(
store: store.scope(
state: { state in
OnboardingHeaderView.ViewState(
walletConfig: state.walletConfig,
isInitialStep: state.isInitialStep,
isFinalStep: state.isFinalStep
)
},
action: { action in
switch action {
case .back: return .back
case .skip: return .skip
}
}
}
)
)
)
.zIndex(1)
.zIndex(1)
OnboardingContentView(store: store)
}
OnboardingContentView(store: store)
Spacer()
OnboardingFooterView(store: store)
}
Spacer()
OnboardingFooterView(store: store)
.navigationBarHidden(true)
.applyScreenBackground()
.onAppear { viewStore.send(.onAppear) }
}
.navigationBarHidden(true)
.applyScreenBackground()
}
}
@ -51,6 +55,7 @@ struct OnboardingScreen_Previews: PreviewProvider {
OnboardingScreen(
store: Store(
initialState: OnboardingFlowReducer.State(
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
@ -62,6 +67,7 @@ struct OnboardingScreen_Previews: PreviewProvider {
OnboardingScreen(
store: Store(
initialState: OnboardingFlowReducer.State(
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
@ -73,6 +79,7 @@ struct OnboardingScreen_Previews: PreviewProvider {
OnboardingScreen(
store: Store(
initialState: OnboardingFlowReducer.State(
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
@ -85,6 +92,7 @@ struct OnboardingScreen_Previews: PreviewProvider {
OnboardingScreen(
store: Store(
initialState: OnboardingFlowReducer.State(
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
@ -96,6 +104,7 @@ struct OnboardingScreen_Previews: PreviewProvider {
OnboardingScreen(
store: Store(
initialState: OnboardingFlowReducer.State(
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
@ -107,6 +116,7 @@ struct OnboardingScreen_Previews: PreviewProvider {
OnboardingScreen(
store: Store(
initialState: OnboardingFlowReducer.State(
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()

View File

@ -59,8 +59,9 @@ struct OnboardingContentView_Previews: PreviewProvider {
static var previews: some View {
let store = Store(
initialState: OnboardingFlowReducer.State(
index: 0,
importWalletState: .placeholder
walletConfig: .default,
importWalletState: .placeholder,
index: 0
),
reducer: OnboardingFlowReducer()
)
@ -85,6 +86,7 @@ extension OnboardingContentView_Previews {
store: store.scope(
state: { state in
OnboardingHeaderView.ViewState(
walletConfig: state.walletConfig,
isInitialStep: state.isInitialStep,
isFinalStep: state.isFinalStep
)

View File

@ -85,8 +85,9 @@ struct OnboardingFooterView_Previews: PreviewProvider {
static var previews: some View {
let store = Store<OnboardingFlowReducer.State, OnboardingFlowReducer.Action>(
initialState: OnboardingFlowReducer.State(
index: 3,
importWalletState: .placeholder
walletConfig: .default,
importWalletState: .placeholder,
index: 3
),
reducer: OnboardingFlowReducer()
)

View File

@ -10,6 +10,7 @@ import ComposableArchitecture
struct OnboardingHeaderView: View {
struct ViewState: Equatable {
let walletConfig: WalletConfig
let isInitialStep: Bool
let isFinalStep: Bool
}
@ -26,7 +27,7 @@ struct OnboardingHeaderView: View {
WithViewStore(self.store) { viewStore in
VStack {
HStack {
if !viewStore.isInitialStep {
if !viewStore.isInitialStep && viewStore.walletConfig.isEnabled(.onboardingFlow) {
Button("Back") {
viewStore.send(.back, animation: .easeInOut(duration: animationDuration))
}
@ -63,8 +64,9 @@ struct OnboardingHeaderView_Previews: PreviewProvider {
static var previews: some View {
let store = Store<OnboardingFlowReducer.State, OnboardingFlowReducer.Action>(
initialState: OnboardingFlowReducer.State(
index: 0,
importWalletState: .placeholder
walletConfig: .default,
importWalletState: .placeholder,
index: 0
),
reducer: OnboardingFlowReducer()
)
@ -73,6 +75,7 @@ struct OnboardingHeaderView_Previews: PreviewProvider {
store: store.scope(
state: { state in
OnboardingHeaderView.ViewState(
walletConfig: state.walletConfig,
isInitialStep: state.isInitialStep,
isFinalStep: state.isFinalStep
)

View File

@ -14,13 +14,13 @@ import ZcashLightClientKit
extension RootReducer {
struct DestinationState: Equatable {
enum Destination: Equatable {
case welcome
case startup
case onboarding
case sandbox
case home
case phraseValidation
case onboarding
case phraseDisplay
case phraseValidation
case sandbox
case startup
case welcome
}
var internalDestination: Destination = .welcome

View File

@ -6,6 +6,7 @@
//
import ComposableArchitecture
import Foundation
/// In this file is a collection of helpers that control all state and action related operations
/// for the `RootReducer` with a connection to the app/wallet initialization and erasure of the wallet.
@ -16,16 +17,39 @@ extension RootReducer {
case checkWalletInitialization
case configureCrashReporter
case createNewWallet
case checkWalletConfig
case initializeSDK
case initialSetups
case nukeWallet
case respondToWalletInitializationState(InitializationState)
case walletConfigChanged(WalletConfig)
}
// swiftlint:disable:next cyclomatic_complexity
// swiftlint:disable:next cyclomatic_complexity function_body_length
func initializationReduce() -> Reduce<RootReducer.State, RootReducer.Action> {
Reduce { state, action in
switch action {
case .initialization(.appDelegate(.didFinishLaunching)):
return EffectTask(value: .initialization(.checkWalletConfig))
.delay(for: 0.02, scheduler: mainQueue)
.eraseToEffect()
case .initialization(.checkWalletConfig):
return .run { send in
let walletConfig = await walletConfigProvider.load()
if walletConfig == WalletConfig.default {
await send(.initialization(.initialSetups))
} else {
await send(.initialization(.walletConfigChanged(walletConfig)))
}
}
case .initialization(.walletConfigChanged(let walletConfig)):
state.walletConfig = walletConfig
state.onboardingState.walletConfig = walletConfig
return EffectTask(value: .initialization(.initialSetups))
case .initialization(.initialSetups):
// TODO: [#524] finish all the wallet events according to definition, https://github.com/zcash/secant-ios-wallet/issues/524
LoggerProxy.event(".appDelegate(.didFinishLaunching)")
/// We need to fetch data from keychain, in order to be 100% sure the keychain can be read we delay the check a bit

View File

@ -10,6 +10,7 @@ struct RootReducer: ReducerProtocol {
struct State: Equatable {
var appInitializationState: InitializationState = .uninitialized
var destinationState: DestinationState
var walletConfig: WalletConfig
var homeState: HomeReducer.State
var onboardingState: OnboardingFlowReducer.State
var phraseValidationState: RecoveryPhraseValidationFlowReducer.State
@ -34,6 +35,7 @@ struct RootReducer: ReducerProtocol {
@Dependency(\.databaseFiles) var databaseFiles
@Dependency(\.deeplink) var deeplink
@Dependency(\.derivationTool) var derivationTool
@Dependency(\.walletConfigProvider) var walletConfigProvider
@Dependency(\.mainQueue) var mainQueue
@Dependency(\.mnemonic) var mnemonic
@Dependency(\.randomRecoveryPhrase) var randomRecoveryPhrase
@ -159,8 +161,10 @@ extension RootReducer.State {
static var placeholder: Self {
.init(
destinationState: .placeholder,
walletConfig: .default,
homeState: .placeholder,
onboardingState: .init(
walletConfig: .default,
importWalletState: .placeholder
),
phraseValidationState: .placeholder,

View File

@ -9,11 +9,12 @@ enum FeatureFlag: String, CaseIterable, Codable {
// These two flags should stay here because those are used in tests. It's not super nice but there is probably no other way.
case testFlag1
case testFlag2
case onboardingFlow
var enabledByDefault: Bool {
switch self {
case .testFlag1, .testFlag2:
return false
case .testFlag1, .testFlag2: return false
case .onboardingFlow: return false
}
}
}

View File

@ -82,20 +82,21 @@ class DeeplinkTests: XCTestCase {
let store = TestStore(
initialState: appState,
reducer: RootReducer()
) { dependencies in
dependencies.deeplink = DeeplinkClient(
resolveDeeplinkURL: { _, _ in Deeplink.Destination.home }
)
let synchronizer = NoopSDKSynchronizer()
synchronizer.updateStateChanged(.synced)
dependencies.sdkSynchronizer = synchronizer
}
)
store.dependencies.deeplink = DeeplinkClient(
resolveDeeplinkURL: { _, _ in Deeplink.Destination.home }
)
let synchronizer = NoopSDKSynchronizer()
synchronizer.updateStateChanged(.synced)
store.dependencies.sdkSynchronizer = synchronizer
store.dependencies.walletConfigProvider = .noOp
guard let url = URL(string: "zcash:///home") else {
return XCTFail("Deeplink: 'testDeeplinkRequest_homeURL' URL is expected to be valid.")
}
_ = await store.send(.destination(.deeplink(url)))
await store.send(.destination(.deeplink(url)))
await store.receive(.destination(.deeplinkHome)) { state in
state.destinationState.destination = .home
@ -136,7 +137,7 @@ class DeeplinkTests: XCTestCase {
return XCTFail("Deeplink: 'testDeeplinkRequest_sendURL_amount' URL is expected to be valid.")
}
_ = await store.send(.destination(.deeplink(url)))
await store.send(.destination(.deeplink(url)))
let amount = Zatoshi(123_000_000)
let address = "address"

View File

@ -106,7 +106,7 @@ class HomeTests: XCTestCase {
reducer: HomeReducer()
)
_ = await store.send(.profile(.settings(.quickRescan))) { state in
await store.send(.profile(.settings(.quickRescan))) { state in
state.destination = nil
}
@ -131,7 +131,7 @@ class HomeTests: XCTestCase {
reducer: HomeReducer()
)
_ = await store.send(.profile(.settings(.fullRescan))) { state in
await store.send(.profile(.settings(.fullRescan))) { state in
state.destination = nil
}

View File

@ -0,0 +1,64 @@
//
// OnboardingFlowFeatureFlagTests.swift
// secantTests
//
// Created by Lukáš Korba on 23.02.2023.
//
import XCTest
@testable import secant_testnet
import ComposableArchitecture
class OnboardingFlowFeatureFlagTests: XCTestCase {
override func setUp() {
super.setUp()
UserDefaultsWalletConfigStorage().clearAll()
}
func testOnboardingFlowOffByDefault() throws {
XCTAssertFalse(WalletConfig.default.isEnabled(.onboardingFlow))
}
func testOnboardingFlowOff_SkipEducation() {
let initialState = OnboardingFlowReducer.State(
walletConfig: .default,
importWalletState: .placeholder
)
let store = TestStore(
initialState: initialState,
reducer: OnboardingFlowReducer()
)
store.send(.onAppear)
store.receive(.skip) { state in
state.index = initialState.steps.count - 1
state.skippedAtindex = 0
}
}
func testOnboardingFlowOn_StartEducation() {
var defaultRawFlags = WalletConfig.default.flags
defaultRawFlags[.onboardingFlow] = false
let flags = WalletConfig(flags: defaultRawFlags)
let initialState = OnboardingFlowReducer.State(
walletConfig: flags,
importWalletState: .placeholder
)
let store = TestStore(
initialState: initialState,
reducer: OnboardingFlowReducer()
)
store.send(.onAppear)
store.receive(.skip) { state in
state.index = initialState.steps.count - 1
state.skippedAtindex = 0
}
}
}

View File

@ -13,6 +13,7 @@ class OnboardingStoreTests: XCTestCase {
func testIncrementingOnboarding() {
let store = TestStore(
initialState: OnboardingFlowReducer.State(
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
@ -52,8 +53,9 @@ class OnboardingStoreTests: XCTestCase {
func testIncrementingPastTotalStepsDoesNothing() {
let store = TestStore(
initialState: OnboardingFlowReducer.State(
index: 3,
importWalletState: .placeholder
walletConfig: .default,
importWalletState: .placeholder,
index: 3
),
reducer: OnboardingFlowReducer()
)
@ -65,8 +67,9 @@ class OnboardingStoreTests: XCTestCase {
func testDecrementingOnboarding() {
let store = TestStore(
initialState: OnboardingFlowReducer.State(
index: 2,
importWalletState: .placeholder
walletConfig: .default,
importWalletState: .placeholder,
index: 2
),
reducer: OnboardingFlowReducer()
)
@ -95,6 +98,7 @@ class OnboardingStoreTests: XCTestCase {
func testDecrementingPastFirstStepDoesNothing() {
let store = TestStore(
initialState: OnboardingFlowReducer.State(
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
@ -109,8 +113,9 @@ class OnboardingStoreTests: XCTestCase {
let store = TestStore(
initialState: OnboardingFlowReducer.State(
index: initialIndex,
importWalletState: .placeholder
walletConfig: .default,
importWalletState: .placeholder,
index: initialIndex
),
reducer: OnboardingFlowReducer()
)

View File

@ -26,7 +26,7 @@ class ProfileTests: XCTestCase {
network: .testnet
)
_ = await store.send(.onAppear) { state in
await store.send(.onAppear) { state in
state.addressDetailsState.uAddress = uAddress
state.appVersion = "0.0.1"
state.appBuild = "31"

View File

@ -11,15 +11,8 @@ import ComposableArchitecture
class AppInitializationTests: XCTestCase {
/// This integration test starts with finishing the app launch and triggering bunch of initialization procedures.
/// 1. The app calls .checkWalletInitialization delayed by 0.02 seconds to ensure keychain is successfully operational.
/// 2. The .respondToWalletInitializationState is triggered to decide the state of the wallet.
/// 3. The .initializeSDK is triggered to set the state of the app and preparing the synchronizer.
/// 4. The .checkBackupPhraseValidation is triggered to check the validation state.
/// 5. The user hasn't finished the backup phrase test so the display phrase is presented.
@MainActor func testDidFinishLaunching_to_InitializedWallet() async throws {
// setup the store and environment to be fully mocked
let testScheduler = DispatchQueue.test
let recoveryPhrase = RecoveryPhrase(words: try MnemonicClient.mock.randomMnemonicWords().map { $0.redacted })
let phraseValidationState = RecoveryPhraseValidationFlowReducer.State(
@ -72,8 +65,10 @@ class AppInitializationTests: XCTestCase {
let appState = RootReducer.State(
destinationState: .placeholder,
walletConfig: .default,
homeState: .placeholder,
onboardingState: .init(
walletConfig: .default,
importWalletState: .placeholder
),
phraseValidationState: phraseValidationState,
@ -87,123 +82,108 @@ class AppInitializationTests: XCTestCase {
let store = TestStore(
initialState: appState,
reducer: RootReducer()
) { dependencies in
dependencies.databaseFiles = .noOp
dependencies.databaseFiles.areDbFilesPresentFor = { _ in true }
dependencies.derivationTool = .liveValue
dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
dependencies.mnemonic = .mock
dependencies.randomRecoveryPhrase = recoveryPhraseRandomizer
dependencies.walletStorage.exportWallet = { .placeholder }
dependencies.walletStorage.areKeysPresent = { true }
}
)
store.dependencies.databaseFiles = .noOp
store.dependencies.databaseFiles.areDbFilesPresentFor = { _ in true }
store.dependencies.derivationTool = .liveValue
store.dependencies.mainQueue = .immediate
store.dependencies.mnemonic = .mock
store.dependencies.randomRecoveryPhrase = recoveryPhraseRandomizer
store.dependencies.walletStorage.exportWallet = { .placeholder }
store.dependencies.walletStorage.areKeysPresent = { true }
store.dependencies.walletConfigProvider = .noOp
// Root of the test, the app finished the launch process and triggers the checks and initializations.
_ = await store.send(.initialization(.appDelegate(.didFinishLaunching)))
await store.send(.initialization(.appDelegate(.didFinishLaunching)))
// the 0.02 delay ensures keychain is ready
await testScheduler.advance(by: 0.02)
await store.receive(.initialization(.checkWalletConfig))
await store.receive(.initialization(.initialSetups))
// ad 1.
await store.receive(.initialization(.configureCrashReporter))
// ad 2.
await store.receive(.initialization(.checkWalletInitialization))
// ad 3.
await store.receive(.initialization(.respondToWalletInitializationState(.initialized)))
// ad 4.
await store.receive(.initialization(.initializeSDK)) { state in
state.storedWallet = .placeholder
}
// ad 5.
await store.receive(.initialization(.checkBackupPhraseValidation)) { state in
state.appInitializationState = .initialized
}
// the 3.0 delay ensures the welcome screen is visible till the initialization is done
await testScheduler.advance(by: 3.00)
// ad 5.
await store.receive(.destination(.updateDestination(.phraseDisplay))) { state in
state.destinationState.previousDestination = .welcome
state.destinationState.internalDestination = .phraseDisplay
}
await store.finish()
}
/// Integration test validating the side effects work together properly when no wallet is stored but database files are present.
/// 1. The app calls .checkWalletInitialization delayed by 0.02 seconds to ensure keychain is successfully operational.
/// 2. The .respondToWalletInitializationState is triggered to decide the state of the wallet.
func testDidFinishLaunching_to_KeysMissing() throws {
// setup the store and environment to be fully mocked
let testScheduler = DispatchQueue.test
@MainActor func testDidFinishLaunching_to_KeysMissing() async throws {
let store = TestStore(
initialState: .placeholder,
reducer: RootReducer()
) { dependencies in
dependencies.databaseFiles = .noOp
dependencies.databaseFiles.areDbFilesPresentFor = { _ in true }
dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
dependencies.walletStorage = .noOp
}
)
store.dependencies.databaseFiles = .noOp
store.dependencies.databaseFiles.areDbFilesPresentFor = { _ in true }
store.dependencies.walletStorage = .noOp
store.dependencies.mainQueue = .immediate
store.dependencies.walletConfigProvider = .noOp
// Root of the test, the app finished the launch process and triggers the checks and initializations.
store.send(.initialization(.appDelegate(.didFinishLaunching)))
// the 0.02 delay ensures keychain is ready
testScheduler.advance(by: 0.02)
// ad 1.
store.receive(.initialization(.configureCrashReporter))
await store.send(.initialization(.appDelegate(.didFinishLaunching)))
// ad 2
store.receive(.initialization(.checkWalletInitialization))
await store.receive(.initialization(.checkWalletConfig))
await store.receive(.initialization(.initialSetups))
// ad 3.
store.receive(.initialization(.respondToWalletInitializationState(.keysMissing))) { state in
await store.receive(.initialization(.configureCrashReporter))
await store.receive(.initialization(.checkWalletInitialization))
await store.receive(.initialization(.respondToWalletInitializationState(.keysMissing))) { state in
state.appInitializationState = .keysMissing
}
await store.finish()
}
/// Integration test validating the side effects work together properly when no wallet is stored and no database files are present.
/// 1. The app calls .checkWalletInitialization delayed by 0.02 seconds to ensure keychain is successfully operational.
/// 2. The .respondToWalletInitializationState is triggered to decide the state of the wallet.
/// 3. The wallet is not present, onboarding flow is triggered.
func testDidFinishLaunching_to_Uninitialized() throws {
// setup the store and environment to be fully mocked
let testScheduler = DispatchQueue.test
@MainActor func testDidFinishLaunching_to_Uninitialized() async throws {
let store = TestStore(
initialState: .placeholder,
reducer: RootReducer()
) { dependencies in
dependencies.databaseFiles = .noOp
dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
dependencies.walletStorage = .noOp
}
)
store.dependencies.databaseFiles = .noOp
store.dependencies.mainQueue = .immediate
store.dependencies.walletStorage = .noOp
store.dependencies.walletConfigProvider = .noOp
// Root of the test, the app finished the launch process and triggers the checks and initializations.
store.send(.initialization(.appDelegate(.didFinishLaunching)))
await store.send(.initialization(.appDelegate(.didFinishLaunching)))
await store.receive(.initialization(.checkWalletConfig))
await store.receive(.initialization(.initialSetups))
await store.receive(.initialization(.configureCrashReporter))
await store.receive(.initialization(.checkWalletInitialization))
await store.receive(.initialization(.respondToWalletInitializationState(.uninitialized)))
// the 0.02 delay ensures keychain is ready
// the 3.0 delay ensures the welcome screen is visible till the initialization check is done
testScheduler.advance(by: 3.02)
// ad 1.
store.receive(.initialization(.configureCrashReporter))
// ad 2.
store.receive(.initialization(.checkWalletInitialization))
// ad 3.
store.receive(.initialization(.respondToWalletInitializationState(.uninitialized)))
// ad 4.
store.receive(.destination(.updateDestination(.onboarding))) { state in
await store.receive(.destination(.updateDestination(.onboarding))) { state in
state.destinationState.previousDestination = .welcome
state.destinationState.internalDestination = .onboarding
}
await store.finish()
}
}

View File

@ -57,7 +57,7 @@ class SettingsTests: XCTestCase {
dependencies.walletStorage = mockedWalletStorage
}
_ = await store.send(.backupWalletAccessRequest)
await store.send(.backupWalletAccessRequest)
await store.receive(.backupWallet) { state in
state.phraseDisplayState.phrase = RecoveryPhrase(words: mnemonic.components(separatedBy: " ").map { $0.redacted })
@ -75,7 +75,7 @@ class SettingsTests: XCTestCase {
$0.localAuthentication = .mockAuthenticationFailed
}
_ = await store.send(.backupWalletAccessRequest)
await store.send(.backupWalletAccessRequest)
await store.finish()
}
@ -86,7 +86,7 @@ class SettingsTests: XCTestCase {
reducer: SettingsReducer()
)
_ = await store.send(.rescanBlockchain) { state in
await store.send(.rescanBlockchain) { state in
state.rescanDialog = .init(
title: TextState("Rescan"),
message: TextState("Select the rescan you want"),
@ -118,7 +118,7 @@ class SettingsTests: XCTestCase {
reducer: SettingsReducer()
)
_ = await store.send(.cancelRescan) { state in
await store.send(.cancelRescan) { state in
state.rescanDialog = nil
}
}
@ -142,7 +142,7 @@ class SettingsTests: XCTestCase {
reducer: SettingsReducer()
)
_ = await store.send(.quickRescan) { state in
await store.send(.quickRescan) { state in
state.rescanDialog = nil
}
}
@ -166,7 +166,7 @@ class SettingsTests: XCTestCase {
reducer: SettingsReducer()
)
_ = await store.send(.fullRescan) { state in
await store.send(.fullRescan) { state in
state.rescanDialog = nil
}
}
@ -192,7 +192,7 @@ class SettingsTests: XCTestCase {
store.dependencies.logsHandler = LogsHandlerClient(exportAndStoreLogs: { _, _, _ in })
_ = await store.send(.exportLogs) { state in
await store.send(.exportLogs) { state in
state.exportLogsDisabled = true
}
@ -222,7 +222,7 @@ class SettingsTests: XCTestCase {
reducer: SettingsReducer()
)
_ = await store.send(.logsShareFinished) { state in
await store.send(.logsShareFinished) { state in
state.isSharingLogs = false
}
}

View File

@ -22,6 +22,7 @@ class AddressDetailsSnapshotTests: XCTestCase {
let store = Store(
initialState: AddressDetailsReducer.State(uAddress: uAddress),
reducer: AddressDetailsReducer()
.dependency(\.walletConfigProvider, .noOp)
)
addAttachments(AddressDetailsView(store: store))

View File

@ -12,7 +12,10 @@ import ComposableArchitecture
class OnboardingSnapshotTests: XCTestCase {
func testOnboardingFlowSnapshot() throws {
let store = OnboardingFlowStore(
initialState: OnboardingFlowReducer.State(importWalletState: .placeholder),
initialState: OnboardingFlowReducer.State(
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
)
let viewStore = ViewStore(store)