- Added `WalletConfigProvider` object which handles loading and caching of feature flags. - Added `WalletConfig` which represents one configuration of all feature flags.
This commit is contained in:
parent
1988d30540
commit
a1104163f3
|
@ -13,6 +13,7 @@ disabled_rules:
|
||||||
- nesting # allow for types to be nested, common pattern in Swift
|
- nesting # allow for types to be nested, common pattern in Swift
|
||||||
- multiple_closures_with_trailing_closure
|
- multiple_closures_with_trailing_closure
|
||||||
- generic_type_name # allow for arbitrarily long generic type names
|
- generic_type_name # allow for arbitrarily long generic type names
|
||||||
|
- empty_parentheses_with_trailing_closure
|
||||||
|
|
||||||
opt_in_rules:
|
opt_in_rules:
|
||||||
- mark
|
- mark
|
||||||
|
|
|
@ -330,6 +330,19 @@
|
||||||
34E0AF0F28DEE4C70034CF37 /* HoldToSendButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF0E28DEE4C70034CF37 /* HoldToSendButton.swift */; };
|
34E0AF0F28DEE4C70034CF37 /* HoldToSendButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF0E28DEE4C70034CF37 /* HoldToSendButton.swift */; };
|
||||||
34E0AF1128DEE5220034CF37 /* Wedge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF1028DEE5220034CF37 /* Wedge.swift */; };
|
34E0AF1128DEE5220034CF37 /* Wedge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF1028DEE5220034CF37 /* Wedge.swift */; };
|
||||||
34E5F2F328E46DB700C17E5F /* DiskSpaceChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E5F2F228E46DB700C17E5F /* DiskSpaceChecker.swift */; };
|
34E5F2F328E46DB700C17E5F /* DiskSpaceChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E5F2F228E46DB700C17E5F /* DiskSpaceChecker.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 */; };
|
||||||
|
34F682ED29A763FD0022C079 /* WalletConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682EB29A763FD0022C079 /* WalletConfigProvider.swift */; };
|
||||||
|
34F682EF29A7640A0022C079 /* WalletConfigProviderInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682EE29A7640A0022C079 /* WalletConfigProviderInterface.swift */; };
|
||||||
|
34F682F029A7640A0022C079 /* WalletConfigProviderInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682EE29A7640A0022C079 /* WalletConfigProviderInterface.swift */; };
|
||||||
|
34F682F229A764120022C079 /* WalletConfigProviderLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F129A764120022C079 /* WalletConfigProviderLiveKey.swift */; };
|
||||||
|
34F682F329A764120022C079 /* WalletConfigProviderLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F129A764120022C079 /* WalletConfigProviderLiveKey.swift */; };
|
||||||
|
34F682F529A7641B0022C079 /* WalletConfigProviderTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F429A7641B0022C079 /* WalletConfigProviderTestKey.swift */; };
|
||||||
|
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 */; };
|
660558E9270C7A54009D6954 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 660558E8270C7A54009D6954 /* Colors.xcassets */; };
|
||||||
660558F7270C862F009D6954 /* Fonts+Generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660558F5270C862F009D6954 /* Fonts+Generated.swift */; };
|
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 */; };
|
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660558F6270C862F009D6954 /* XCAssets+Generated.swift */; };
|
||||||
|
@ -644,6 +657,13 @@
|
||||||
34E0AF0E28DEE4C70034CF37 /* HoldToSendButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HoldToSendButton.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>"; };
|
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>"; };
|
34E5F2F228E46DB700C17E5F /* DiskSpaceChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskSpaceChecker.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>"; };
|
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>"; };
|
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>"; };
|
660558F6270C862F009D6954 /* XCAssets+Generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "XCAssets+Generated.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -983,26 +1003,27 @@
|
||||||
0D4E7A1926B364180058B01E /* secantTests */ = {
|
0D4E7A1926B364180058B01E /* secantTests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9E391162284E3ECF0073DD9A /* SnapshotTests */,
|
0D4E7A1C26B364180058B01E /* Info.plist */,
|
||||||
|
0D4E7A1A26B364180058B01E /* secantTests.swift */,
|
||||||
9E207C372966EF6E003E2C9B /* AddressDetailsTests */,
|
9E207C372966EF6E003E2C9B /* AddressDetailsTests */,
|
||||||
|
0DFE93DD272C6D4B000FCCA5 /* BackupFlowTests */,
|
||||||
9E94C61E28AA7DD5008256E9 /* BalanceBreakdownTests */,
|
9E94C61E28AA7DD5008256E9 /* BalanceBreakdownTests */,
|
||||||
9E6713EF2897F80A00A6796F /* MultiLineTextFieldTests */,
|
|
||||||
9E7CB6222874245400A02233 /* ProfileTests */,
|
|
||||||
9EAB4674285B5C68002904A0 /* DeeplinkTests */,
|
9EAB4674285B5C68002904A0 /* DeeplinkTests */,
|
||||||
|
34F682FA29A784580022C079 /* WalletConfigProvider */,
|
||||||
9E3911372848AD3A0073DD9A /* HomeTests */,
|
9E3911372848AD3A0073DD9A /* HomeTests */,
|
||||||
9E391122283E4C970073DD9A /* ImportWalletTests */,
|
9E391122283E4C970073DD9A /* ImportWalletTests */,
|
||||||
9E612C7729913F2300D09B09 /* SensitiveDataTests */,
|
9E6713EF2897F80A00A6796F /* MultiLineTextFieldTests */,
|
||||||
9E66129C2889388C00C75B70 /* SettingsTests */,
|
6654C7422715A48E00901167 /* OnboardingTests */,
|
||||||
|
9E7CB6222874245400A02233 /* ProfileTests */,
|
||||||
|
0DFE93E4272CB6D0000FCCA5 /* RecoveryPhraseValidationTests */,
|
||||||
|
9EAFEB802805791400199FC9 /* RootTests */,
|
||||||
9E01F8262833CD84000EFC57 /* ScanTests */,
|
9E01F8262833CD84000EFC57 /* ScanTests */,
|
||||||
9E5BF642281FEC8700BA3F17 /* SendTests */,
|
9E5BF642281FEC8700BA3F17 /* SendTests */,
|
||||||
9E5BF63D281953F900BA3F17 /* WalletEventsTests */,
|
9E612C7729913F2300D09B09 /* SensitiveDataTests */,
|
||||||
9EAFEB802805791400199FC9 /* RootTests */,
|
9E66129C2889388C00C75B70 /* SettingsTests */,
|
||||||
|
9E391162284E3ECF0073DD9A /* SnapshotTests */,
|
||||||
9EF8135927ECC25E0075AF48 /* UtilTests */,
|
9EF8135927ECC25E0075AF48 /* UtilTests */,
|
||||||
0DFE93E4272CB6D0000FCCA5 /* RecoveryPhraseValidationTests */,
|
9E5BF63D281953F900BA3F17 /* WalletEventsTests */,
|
||||||
0DFE93DD272C6D4B000FCCA5 /* BackupFlowTests */,
|
|
||||||
6654C7422715A48E00901167 /* OnboardingTests */,
|
|
||||||
0D4E7A1A26B364180058B01E /* secantTests.swift */,
|
|
||||||
0D4E7A1C26B364180058B01E /* Info.plist */,
|
|
||||||
);
|
);
|
||||||
path = secantTests;
|
path = secantTests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1060,15 +1081,16 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9EF8135F27F043CC0075AF48 /* AppDelegate.swift */,
|
9EF8135F27F043CC0075AF48 /* AppDelegate.swift */,
|
||||||
9EF8139B27F47AED0075AF48 /* InitializationState.swift */,
|
|
||||||
0D6D628A276A528D002FB4CC /* DropDelegate.swift */,
|
0D6D628A276A528D002FB4CC /* DropDelegate.swift */,
|
||||||
9E5BF63B2818305D00BA3F17 /* TransactionState.swift */,
|
34F682E429A75EB60022C079 /* WalletConfig.swift */,
|
||||||
|
9EF8139B27F47AED0075AF48 /* InitializationState.swift */,
|
||||||
9E7FE0D6282D286500C374E8 /* RecoveryPhrase.swift */,
|
9E7FE0D6282D286500C374E8 /* RecoveryPhrase.swift */,
|
||||||
9E7FE0DC282D298900C374E8 /* ValidationWord.swift */,
|
|
||||||
9E612C7C2991476F00D09B09 /* SensitiveData.swift */,
|
9E612C7C2991476F00D09B09 /* SensitiveData.swift */,
|
||||||
9E7FE0E5282E7B1100C374E8 /* StoredWallet.swift */,
|
9E7FE0E5282E7B1100C374E8 /* StoredWallet.swift */,
|
||||||
9EAB46772860A1D2002904A0 /* WalletEvent.swift */,
|
|
||||||
9E66122B2877188700C75B70 /* SyncStatusSnapshot.swift */,
|
9E66122B2877188700C75B70 /* SyncStatusSnapshot.swift */,
|
||||||
|
9E5BF63B2818305D00BA3F17 /* TransactionState.swift */,
|
||||||
|
9E7FE0DC282D298900C374E8 /* ValidationWord.swift */,
|
||||||
|
9EAB46772860A1D2002904A0 /* WalletEvent.swift */,
|
||||||
);
|
);
|
||||||
path = Models;
|
path = Models;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1167,6 +1189,26 @@
|
||||||
path = CheckCircle;
|
path = CheckCircle;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
34F682EA29A763F00022C079 /* FeatureFlagsManager */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
34F682EB29A763FD0022C079 /* WalletConfigProvider.swift */,
|
||||||
|
34F682F729A775C10022C079 /* UserDefaultsWalletConfigStorage.swift */,
|
||||||
|
34F682EE29A7640A0022C079 /* WalletConfigProviderInterface.swift */,
|
||||||
|
34F682F129A764120022C079 /* WalletConfigProviderLiveKey.swift */,
|
||||||
|
34F682F429A7641B0022C079 /* WalletConfigProviderTestKey.swift */,
|
||||||
|
);
|
||||||
|
path = FeatureFlagsManager;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
34F682FA29A784580022C079 /* WalletConfigProvider */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
34F682FB29A784660022C079 /* WalletConfigProviderTests.swift */,
|
||||||
|
);
|
||||||
|
path = WalletConfigProvider;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
663FAB9A271D873300E495F8 /* Buttons */ = {
|
663FAB9A271D873300E495F8 /* Buttons */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1602,6 +1644,7 @@
|
||||||
9EBDF959291E654F000A1A05 /* Deeplink */,
|
9EBDF959291E654F000A1A05 /* Deeplink */,
|
||||||
9EBDF971291F79C9000A1A05 /* DerivationTool */,
|
9EBDF971291F79C9000A1A05 /* DerivationTool */,
|
||||||
9EBDF945291D759B000A1A05 /* DiskSpaceChecker */,
|
9EBDF945291D759B000A1A05 /* DiskSpaceChecker */,
|
||||||
|
34F682EA29A763F00022C079 /* FeatureFlagsManager */,
|
||||||
9EB863882922CC0E003D0F8B /* FeedbackGenerator */,
|
9EB863882922CC0E003D0F8B /* FeedbackGenerator */,
|
||||||
9EB863B52923C4ED003D0F8B /* FileManager */,
|
9EB863B52923C4ED003D0F8B /* FileManager */,
|
||||||
9EBDF981291F91B1000A1A05 /* LocalAuthentication */,
|
9EBDF981291F91B1000A1A05 /* LocalAuthentication */,
|
||||||
|
@ -1990,13 +2033,13 @@
|
||||||
9EF8135927ECC25E0075AF48 /* UtilTests */ = {
|
9EF8135927ECC25E0075AF48 /* UtilTests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */,
|
9E02B56B27FED475005B809B /* DatabaseFilesTests.swift */,
|
||||||
|
9E0F574A2980260D005304FA /* LoggerTests.swift */,
|
||||||
9EAFEB852805A23100199FC9 /* SecItemClientTests.swift */,
|
9EAFEB852805A23100199FC9 /* SecItemClientTests.swift */,
|
||||||
9EF8135B27ECC25E0075AF48 /* UserPreferencesStorageTests.swift */,
|
9EF8135B27ECC25E0075AF48 /* UserPreferencesStorageTests.swift */,
|
||||||
9E02B56B27FED475005B809B /* DatabaseFilesTests.swift */,
|
|
||||||
9E39112D283F91600073DD9A /* ZatoshiTests.swift */,
|
|
||||||
0DB4E0B02881F2DB00947B78 /* WalletBalance+testing.swift */,
|
0DB4E0B02881F2DB00947B78 /* WalletBalance+testing.swift */,
|
||||||
9E0F574A2980260D005304FA /* LoggerTests.swift */,
|
9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */,
|
||||||
|
9E39112D283F91600073DD9A /* ZatoshiTests.swift */,
|
||||||
);
|
);
|
||||||
path = UtilTests;
|
path = UtilTests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2510,6 +2553,7 @@
|
||||||
files = (
|
files = (
|
||||||
0D26AE9B299E8196005260EE /* OnboardingFlowView.swift in Sources */,
|
0D26AE9B299E8196005260EE /* OnboardingFlowView.swift in Sources */,
|
||||||
0D26AE9C299E8196005260EE /* ZcashBadge.swift in Sources */,
|
0D26AE9C299E8196005260EE /* ZcashBadge.swift in Sources */,
|
||||||
|
34F682F329A764120022C079 /* WalletConfigProviderLiveKey.swift in Sources */,
|
||||||
0D26AE9D299E8196005260EE /* CrashReporterTestKey.swift in Sources */,
|
0D26AE9D299E8196005260EE /* CrashReporterTestKey.swift in Sources */,
|
||||||
0D26AE9E299E8196005260EE /* DerivationToolInterface.swift in Sources */,
|
0D26AE9E299E8196005260EE /* DerivationToolInterface.swift in Sources */,
|
||||||
0D26AE9F299E8196005260EE /* XCAssets+Generated.swift in Sources */,
|
0D26AE9F299E8196005260EE /* XCAssets+Generated.swift in Sources */,
|
||||||
|
@ -2526,6 +2570,7 @@
|
||||||
0D26AEAA299E8196005260EE /* CrashReporterLiveKey.swift in Sources */,
|
0D26AEAA299E8196005260EE /* CrashReporterLiveKey.swift in Sources */,
|
||||||
0D26AEAB299E8196005260EE /* RecoveryPhraseRandomizerLiveKey.swift in Sources */,
|
0D26AEAB299E8196005260EE /* RecoveryPhraseRandomizerLiveKey.swift in Sources */,
|
||||||
0D26AEAC299E8196005260EE /* TCATextField.swift in Sources */,
|
0D26AEAC299E8196005260EE /* TCATextField.swift in Sources */,
|
||||||
|
34F682F029A7640A0022C079 /* WalletConfigProviderInterface.swift in Sources */,
|
||||||
0D26AEAD299E8196005260EE /* DeeplinkInterface.swift in Sources */,
|
0D26AEAD299E8196005260EE /* DeeplinkInterface.swift in Sources */,
|
||||||
0D26AEAE299E8196005260EE /* DerivationToolTestKey.swift in Sources */,
|
0D26AEAE299E8196005260EE /* DerivationToolTestKey.swift in Sources */,
|
||||||
0D26AEAF299E8196005260EE /* TransactionAmountTextFieldStore.swift in Sources */,
|
0D26AEAF299E8196005260EE /* TransactionAmountTextFieldStore.swift in Sources */,
|
||||||
|
@ -2533,6 +2578,7 @@
|
||||||
0D26AEB1299E8196005260EE /* AppDelegate.swift in Sources */,
|
0D26AEB1299E8196005260EE /* AppDelegate.swift in Sources */,
|
||||||
0D26AEB2299E8196005260EE /* LogsHandlerInterface.swift in Sources */,
|
0D26AEB2299E8196005260EE /* LogsHandlerInterface.swift in Sources */,
|
||||||
0D26AEB3299E8196005260EE /* DeeplinkTestKey.swift in Sources */,
|
0D26AEB3299E8196005260EE /* DeeplinkTestKey.swift in Sources */,
|
||||||
|
34F682F929A775C10022C079 /* UserDefaultsWalletConfigStorage.swift in Sources */,
|
||||||
0D26AEB4299E8196005260EE /* Wedge.swift in Sources */,
|
0D26AEB4299E8196005260EE /* Wedge.swift in Sources */,
|
||||||
0D26AEB5299E8196005260EE /* TransactionDetailView.swift in Sources */,
|
0D26AEB5299E8196005260EE /* TransactionDetailView.swift in Sources */,
|
||||||
0D26AEB6299E8196005260EE /* NumberFormatterLiveKey.swift in Sources */,
|
0D26AEB6299E8196005260EE /* NumberFormatterLiveKey.swift in Sources */,
|
||||||
|
@ -2613,6 +2659,7 @@
|
||||||
0D26AF01299E8196005260EE /* RecoveryPhraseDisplayView.swift in Sources */,
|
0D26AF01299E8196005260EE /* RecoveryPhraseDisplayView.swift in Sources */,
|
||||||
0D26AF02299E8196005260EE /* URIParser.swift in Sources */,
|
0D26AF02299E8196005260EE /* URIParser.swift in Sources */,
|
||||||
0D26AF03299E8196005260EE /* URIParserLive.swift in Sources */,
|
0D26AF03299E8196005260EE /* URIParserLive.swift in Sources */,
|
||||||
|
34F682ED29A763FD0022C079 /* WalletConfigProvider.swift in Sources */,
|
||||||
0D26AF04299E8196005260EE /* LocalAuthenticationTestKey.swift in Sources */,
|
0D26AF04299E8196005260EE /* LocalAuthenticationTestKey.swift in Sources */,
|
||||||
0D26AF05299E8196005260EE /* ScanView.swift in Sources */,
|
0D26AF05299E8196005260EE /* ScanView.swift in Sources */,
|
||||||
0D26AF06299E8196005260EE /* DatabaseFiles.swift in Sources */,
|
0D26AF06299E8196005260EE /* DatabaseFiles.swift in Sources */,
|
||||||
|
@ -2636,6 +2683,7 @@
|
||||||
0D26AF18299E8196005260EE /* WalletEventsFlowStore.swift in Sources */,
|
0D26AF18299E8196005260EE /* WalletEventsFlowStore.swift in Sources */,
|
||||||
0D26AF19299E8196005260EE /* StoredWallet.swift in Sources */,
|
0D26AF19299E8196005260EE /* StoredWallet.swift in Sources */,
|
||||||
0D26AF1A299E8196005260EE /* UserDefaultsInterface.swift in Sources */,
|
0D26AF1A299E8196005260EE /* UserDefaultsInterface.swift in Sources */,
|
||||||
|
34F682E629A75EB60022C079 /* WalletConfig.swift in Sources */,
|
||||||
0D26AF1B299E8196005260EE /* HomeStore.swift in Sources */,
|
0D26AF1B299E8196005260EE /* HomeStore.swift in Sources */,
|
||||||
0D26AF1C299E8196005260EE /* AppVersionMocks.swift in Sources */,
|
0D26AF1C299E8196005260EE /* AppVersionMocks.swift in Sources */,
|
||||||
0D26AF1D299E8196005260EE /* RequestView.swift in Sources */,
|
0D26AF1D299E8196005260EE /* RequestView.swift in Sources */,
|
||||||
|
@ -2664,6 +2712,7 @@
|
||||||
0D26AF34299E8196005260EE /* SecItemInterface.swift in Sources */,
|
0D26AF34299E8196005260EE /* SecItemInterface.swift in Sources */,
|
||||||
0D26AF35299E8196005260EE /* WalletInfoStore.swift in Sources */,
|
0D26AF35299E8196005260EE /* WalletInfoStore.swift in Sources */,
|
||||||
0D26AF36299E8196005260EE /* DatabaseFilesTestKey.swift in Sources */,
|
0D26AF36299E8196005260EE /* DatabaseFilesTestKey.swift in Sources */,
|
||||||
|
34F682F629A7641B0022C079 /* WalletConfigProviderTestKey.swift in Sources */,
|
||||||
0D26AF37299E8196005260EE /* ScanUIView.swift in Sources */,
|
0D26AF37299E8196005260EE /* ScanUIView.swift in Sources */,
|
||||||
0D26AF38299E8196005260EE /* AppVersionLiveKey.swift in Sources */,
|
0D26AF38299E8196005260EE /* AppVersionLiveKey.swift in Sources */,
|
||||||
0D26AF39299E8196005260EE /* ColoredChip.swift in Sources */,
|
0D26AF39299E8196005260EE /* ColoredChip.swift in Sources */,
|
||||||
|
@ -2730,6 +2779,7 @@
|
||||||
files = (
|
files = (
|
||||||
2EB660E02747EAB900A06A07 /* OnboardingFlowView.swift in Sources */,
|
2EB660E02747EAB900A06A07 /* OnboardingFlowView.swift in Sources */,
|
||||||
9E7FE0DF282D2DD600C374E8 /* ZcashBadge.swift in Sources */,
|
9E7FE0DF282D2DD600C374E8 /* ZcashBadge.swift in Sources */,
|
||||||
|
34F682F229A764120022C079 /* WalletConfigProviderLiveKey.swift in Sources */,
|
||||||
0D261040298C406F00CC9DE9 /* CrashReporterTestKey.swift in Sources */,
|
0D261040298C406F00CC9DE9 /* CrashReporterTestKey.swift in Sources */,
|
||||||
9EBDF975291F79F9000A1A05 /* DerivationToolInterface.swift in Sources */,
|
9EBDF975291F79F9000A1A05 /* DerivationToolInterface.swift in Sources */,
|
||||||
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */,
|
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */,
|
||||||
|
@ -2746,6 +2796,7 @@
|
||||||
0D26103E298C3FA600CC9DE9 /* CrashReporterLiveKey.swift in Sources */,
|
0D26103E298C3FA600CC9DE9 /* CrashReporterLiveKey.swift in Sources */,
|
||||||
9EB863A829239DCB003D0F8B /* RecoveryPhraseRandomizerLiveKey.swift in Sources */,
|
9EB863A829239DCB003D0F8B /* RecoveryPhraseRandomizerLiveKey.swift in Sources */,
|
||||||
2EDA07A027EDE18C00D6F09B /* TCATextField.swift in Sources */,
|
2EDA07A027EDE18C00D6F09B /* TCATextField.swift in Sources */,
|
||||||
|
34F682EF29A7640A0022C079 /* WalletConfigProviderInterface.swift in Sources */,
|
||||||
9EBDF961291E657B000A1A05 /* DeeplinkInterface.swift in Sources */,
|
9EBDF961291E657B000A1A05 /* DeeplinkInterface.swift in Sources */,
|
||||||
9EBDF977291F79F9000A1A05 /* DerivationToolTestKey.swift in Sources */,
|
9EBDF977291F79F9000A1A05 /* DerivationToolTestKey.swift in Sources */,
|
||||||
2EB7758727FC67FD00269373 /* TransactionAmountTextFieldStore.swift in Sources */,
|
2EB7758727FC67FD00269373 /* TransactionAmountTextFieldStore.swift in Sources */,
|
||||||
|
@ -2753,6 +2804,7 @@
|
||||||
9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */,
|
9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */,
|
||||||
9E612C7229880E9200D09B09 /* LogsHandlerInterface.swift in Sources */,
|
9E612C7229880E9200D09B09 /* LogsHandlerInterface.swift in Sources */,
|
||||||
9EBDF960291E657B000A1A05 /* DeeplinkTestKey.swift in Sources */,
|
9EBDF960291E657B000A1A05 /* DeeplinkTestKey.swift in Sources */,
|
||||||
|
34F682F829A775C10022C079 /* UserDefaultsWalletConfigStorage.swift in Sources */,
|
||||||
34E0AF1128DEE5220034CF37 /* Wedge.swift in Sources */,
|
34E0AF1128DEE5220034CF37 /* Wedge.swift in Sources */,
|
||||||
F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */,
|
F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */,
|
||||||
9EB863942922D036003D0F8B /* NumberFormatterLiveKey.swift in Sources */,
|
9EB863942922D036003D0F8B /* NumberFormatterLiveKey.swift in Sources */,
|
||||||
|
@ -2833,6 +2885,7 @@
|
||||||
0D3D04082728B3440032ABC1 /* RecoveryPhraseDisplayView.swift in Sources */,
|
0D3D04082728B3440032ABC1 /* RecoveryPhraseDisplayView.swift in Sources */,
|
||||||
9EB863A2292398A8003D0F8B /* URIParser.swift in Sources */,
|
9EB863A2292398A8003D0F8B /* URIParser.swift in Sources */,
|
||||||
9EB863C12923C779003D0F8B /* URIParserLive.swift in Sources */,
|
9EB863C12923C779003D0F8B /* URIParserLive.swift in Sources */,
|
||||||
|
34F682EC29A763FD0022C079 /* WalletConfigProvider.swift in Sources */,
|
||||||
9EBDF987291F91EF000A1A05 /* LocalAuthenticationTestKey.swift in Sources */,
|
9EBDF987291F91EF000A1A05 /* LocalAuthenticationTestKey.swift in Sources */,
|
||||||
F9971A5F27680DF600A2DB75 /* ScanView.swift in Sources */,
|
F9971A5F27680DF600A2DB75 /* ScanView.swift in Sources */,
|
||||||
9E39114C2848EEB90073DD9A /* DatabaseFiles.swift in Sources */,
|
9E39114C2848EEB90073DD9A /* DatabaseFiles.swift in Sources */,
|
||||||
|
@ -2856,6 +2909,7 @@
|
||||||
F96B41E7273B501F0021B49A /* WalletEventsFlowStore.swift in Sources */,
|
F96B41E7273B501F0021B49A /* WalletEventsFlowStore.swift in Sources */,
|
||||||
9E7FE0E6282E7B1100C374E8 /* StoredWallet.swift in Sources */,
|
9E7FE0E6282E7B1100C374E8 /* StoredWallet.swift in Sources */,
|
||||||
9E153A7629216EFB00112F41 /* UserDefaultsInterface.swift in Sources */,
|
9E153A7629216EFB00112F41 /* UserDefaultsInterface.swift in Sources */,
|
||||||
|
34F682E529A75EB60022C079 /* WalletConfig.swift in Sources */,
|
||||||
9EAFEB9128081E9400199FC9 /* HomeStore.swift in Sources */,
|
9EAFEB9128081E9400199FC9 /* HomeStore.swift in Sources */,
|
||||||
9EBDF980291F8261000A1A05 /* AppVersionMocks.swift in Sources */,
|
9EBDF980291F8261000A1A05 /* AppVersionMocks.swift in Sources */,
|
||||||
F9971A5A27680DDE00A2DB75 /* RequestView.swift in Sources */,
|
F9971A5A27680DDE00A2DB75 /* RequestView.swift in Sources */,
|
||||||
|
@ -2884,6 +2938,7 @@
|
||||||
9EAFEB84280597B700199FC9 /* SecItemInterface.swift in Sources */,
|
9EAFEB84280597B700199FC9 /* SecItemInterface.swift in Sources */,
|
||||||
F9971A6B27680E1000A2DB75 /* WalletInfoStore.swift in Sources */,
|
F9971A6B27680E1000A2DB75 /* WalletInfoStore.swift in Sources */,
|
||||||
9EBDF953291E5E86000A1A05 /* DatabaseFilesTestKey.swift in Sources */,
|
9EBDF953291E5E86000A1A05 /* DatabaseFilesTestKey.swift in Sources */,
|
||||||
|
34F682F529A7641B0022C079 /* WalletConfigProviderTestKey.swift in Sources */,
|
||||||
9E7FE0F628327F6F00C374E8 /* ScanUIView.swift in Sources */,
|
9E7FE0F628327F6F00C374E8 /* ScanUIView.swift in Sources */,
|
||||||
9EBDF97D291F7EB0000A1A05 /* AppVersionLiveKey.swift in Sources */,
|
9EBDF97D291F7EB0000A1A05 /* AppVersionLiveKey.swift in Sources */,
|
||||||
0D185819272723FF0046B928 /* ColoredChip.swift in Sources */,
|
0D185819272723FF0046B928 /* ColoredChip.swift in Sources */,
|
||||||
|
@ -2991,6 +3046,7 @@
|
||||||
9E02B56C27FED475005B809B /* DatabaseFilesTests.swift in Sources */,
|
9E02B56C27FED475005B809B /* DatabaseFilesTests.swift in Sources */,
|
||||||
9E612C7929913F3600D09B09 /* SensitiveDataTests.swift in Sources */,
|
9E612C7929913F3600D09B09 /* SensitiveDataTests.swift in Sources */,
|
||||||
9EF8135D27ECC25E0075AF48 /* UserPreferencesStorageTests.swift in Sources */,
|
9EF8135D27ECC25E0075AF48 /* UserPreferencesStorageTests.swift in Sources */,
|
||||||
|
34F682FC29A784660022C079 /* WalletConfigProviderTests.swift in Sources */,
|
||||||
9E94C62028AA7DEE008256E9 /* BalanceBreakdownTests.swift in Sources */,
|
9E94C62028AA7DEE008256E9 /* BalanceBreakdownTests.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
//
|
||||||
|
// UserDefaultsWalletConfigStorage.swift
|
||||||
|
// secant
|
||||||
|
//
|
||||||
|
// Created by Michal Fousek on 23.02.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
typealias UserDefaultsWalletConfigProvider = UserDefaultsWalletConfigStorage
|
||||||
|
typealias UserDefaultsWalletConfigProviderCache = UserDefaultsWalletConfigStorage
|
||||||
|
|
||||||
|
struct UserDefaultsWalletConfigStorage {
|
||||||
|
private let userDefaults = UserDefaults.standard
|
||||||
|
|
||||||
|
enum InternalError: Error {
|
||||||
|
case noValueStored
|
||||||
|
case unableToDeserializeData
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Constants {
|
||||||
|
static let providerKey = "feature_flags_ud_config_provider"
|
||||||
|
static let cacheKey = "feature_flags_ud_config_cache"
|
||||||
|
}
|
||||||
|
|
||||||
|
private func load(key: String) async throws -> WalletConfig {
|
||||||
|
guard let data = userDefaults.data(forKey: key) else { throw InternalError.noValueStored }
|
||||||
|
do {
|
||||||
|
let rawFlags = try PropertyListDecoder().decode(WalletConfig.RawFlags.self, from: data)
|
||||||
|
return WalletConfig(flags: rawFlags)
|
||||||
|
} catch {
|
||||||
|
LoggerProxy.debug("Error when deocding feature flags from user defaults: \(error)")
|
||||||
|
throw InternalError.unableToDeserializeData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func store(flags: WalletConfig.RawFlags, key: String) async {
|
||||||
|
do {
|
||||||
|
let data = try PropertyListEncoder().encode(flags)
|
||||||
|
userDefaults.set(data, forKey: key)
|
||||||
|
} catch {
|
||||||
|
LoggerProxy.debug("Can't store/encode feature flags when updating user defaults: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is used only in debug menu to change configuration for specific flag
|
||||||
|
func store(featureFlag: FeatureFlag, isEnabled: Bool) async {
|
||||||
|
let currentConfig = (try? await load(key: Constants.providerKey)) ?? WalletConfig.default
|
||||||
|
var rawFlags = currentConfig.flags
|
||||||
|
rawFlags[featureFlag] = isEnabled
|
||||||
|
|
||||||
|
await store(flags: rawFlags, key: Constants.providerKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UserDefaultsWalletConfigStorage: WalletConfigSourceProvider {
|
||||||
|
func load() async throws -> WalletConfig {
|
||||||
|
return try await load(key: Constants.providerKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UserDefaultsWalletConfigStorage: WalletConfigProviderCache {
|
||||||
|
func load() async -> WalletConfig? {
|
||||||
|
do {
|
||||||
|
return try await load(key: Constants.cacheKey)
|
||||||
|
} catch {
|
||||||
|
LoggerProxy.debug("Can't load feature flags from cache: \(error)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func store(_ configuration: WalletConfig) async {
|
||||||
|
await store(flags: configuration.flags, key: Constants.cacheKey)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
//
|
||||||
|
// WalletConfigProvider.swift
|
||||||
|
// secant
|
||||||
|
//
|
||||||
|
// Created by Michal Fousek on 23.02.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct WalletConfigProvider {
|
||||||
|
/// Objects that fetches flags configuration from some source. It can be fetched from user defaults or some backend API for example. It depends
|
||||||
|
/// on implementation.
|
||||||
|
private let configSourceProvider: WalletConfigSourceProvider
|
||||||
|
/// Object that caches provided flags configuration.
|
||||||
|
private let cache: WalletConfigProviderCache
|
||||||
|
|
||||||
|
init(configSourceProvider: WalletConfigSourceProvider, cache: WalletConfigProviderCache) {
|
||||||
|
self.configSourceProvider = configSourceProvider
|
||||||
|
self.cache = cache
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Loads flags configuration.
|
||||||
|
///
|
||||||
|
/// First `configurationProvider` is used to fetch flags configuration. If that fails then `cache` is used to load flags configuration. And if
|
||||||
|
/// that fails `WalletConfig.default` is used.
|
||||||
|
///
|
||||||
|
/// Loaded configuration is merged with with `WalletConfig.default` to be sure that all recognized flags are always returned in
|
||||||
|
/// configuration.
|
||||||
|
///
|
||||||
|
/// Merged configuration is stored in cache.
|
||||||
|
func load() async -> WalletConfig {
|
||||||
|
let configuration: WalletConfig
|
||||||
|
do {
|
||||||
|
configuration = try await configSourceProvider.load()
|
||||||
|
} catch {
|
||||||
|
LoggerProxy.debug("Error when loading feature flags from configuration provider: \(error)")
|
||||||
|
if let cachedConfiguration = await cache.load() {
|
||||||
|
configuration = cachedConfiguration
|
||||||
|
} else {
|
||||||
|
configuration = WalletConfig.default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let finalConfiguration = merge(configuration: configuration, withDefaultConfiguration: WalletConfig.default)
|
||||||
|
|
||||||
|
await cache.store(finalConfiguration)
|
||||||
|
|
||||||
|
return finalConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is used only in debug menu to change configuration for specific flag
|
||||||
|
func update(featureFlag: FeatureFlag, isEnabled: Bool) async {
|
||||||
|
guard let provider = configSourceProvider as? UserDefaultsWalletConfigStorage else {
|
||||||
|
LoggerProxy.debug("This is now only support with UserDefaultsWalletConfigStorage as configurationProvider.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await provider.store(featureFlag: featureFlag, isEnabled: isEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func merge(
|
||||||
|
configuration: WalletConfig,
|
||||||
|
withDefaultConfiguration defaultConfiguration: WalletConfig
|
||||||
|
) -> WalletConfig {
|
||||||
|
var rawDefaultFlags = defaultConfiguration.flags
|
||||||
|
rawDefaultFlags.merge(configuration.flags, uniquingKeysWith: { $1 })
|
||||||
|
return WalletConfig(flags: rawDefaultFlags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol WalletConfigSourceProvider {
|
||||||
|
func load() async throws -> WalletConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol WalletConfigProviderCache {
|
||||||
|
func load() async -> WalletConfig?
|
||||||
|
func store(_ configuration: WalletConfig) async
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
//
|
||||||
|
// WalletConfigProviderInterface.swift
|
||||||
|
// secant
|
||||||
|
//
|
||||||
|
// Created by Michal Fousek on 23.02.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ComposableArchitecture
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension DependencyValues {
|
||||||
|
var walletConfigProvider: WalletConfigProviderClient {
|
||||||
|
get { self[WalletConfigProviderClient.self] }
|
||||||
|
set { self[WalletConfigProviderClient.self] = newValue }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WalletConfigProviderClient {
|
||||||
|
let load: () async -> WalletConfig
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
//
|
||||||
|
// WalletConfigProviderLiveKey.swift
|
||||||
|
// secant
|
||||||
|
//
|
||||||
|
// Created by Michal Fousek on 23.02.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ComposableArchitecture
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension WalletConfigProviderClient: DependencyKey {
|
||||||
|
static let liveValue = WalletConfigProviderClient.live()
|
||||||
|
|
||||||
|
private static var defaultWalletConfigProvider: WalletConfigProvider {
|
||||||
|
WalletConfigProvider(
|
||||||
|
configSourceProvider: UserDefaultsWalletConfigProvider(),
|
||||||
|
cache: UserDefaultsWalletConfigProviderCache()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func live(walletConfigProvider: WalletConfigProvider = WalletConfigProviderClient.defaultWalletConfigProvider) -> Self {
|
||||||
|
Self(load: { return await walletConfigProvider.load() })
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
//
|
||||||
|
// WalletConfigProviderTestKey.swift
|
||||||
|
// secant
|
||||||
|
//
|
||||||
|
// Created by Michal Fousek on 23.02.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ComposableArchitecture
|
||||||
|
import Foundation
|
||||||
|
import XCTestDynamicOverlay
|
||||||
|
|
||||||
|
extension WalletConfigProviderClient: TestDependencyKey {
|
||||||
|
static let testValue = Self(
|
||||||
|
load: XCTUnimplemented("\(Self.self).load", placeholder: WalletConfig.default)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
extension WalletConfigProviderClient {
|
||||||
|
static let `default` = Self(
|
||||||
|
load: { WalletConfig.default }
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
// WalletConfig.swift
|
||||||
|
// secant
|
||||||
|
//
|
||||||
|
// Created by Michal Fousek on 23.02.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
var enabledByDefault: Bool {
|
||||||
|
switch self {
|
||||||
|
case .testFlag1, .testFlag2:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WalletConfig: Equatable {
|
||||||
|
typealias RawFlags = [FeatureFlag: Bool]
|
||||||
|
|
||||||
|
let flags: RawFlags
|
||||||
|
|
||||||
|
func isEnabled(_ featureFlag: FeatureFlag) -> Bool {
|
||||||
|
return flags[featureFlag, default: false]
|
||||||
|
}
|
||||||
|
|
||||||
|
static var `default`: WalletConfig = {
|
||||||
|
let defaultSettings = FeatureFlag.allCases.map { ($0, $0.enabledByDefault) }
|
||||||
|
return WalletConfig(flags: Dictionary(uniqueKeysWithValues: defaultSettings))
|
||||||
|
}()
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
//
|
||||||
|
// WalletConfigProviderTests.swift
|
||||||
|
// secantTests
|
||||||
|
//
|
||||||
|
// Created by Michal Fousek on 23.02.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
@testable import secant_testnet
|
||||||
|
|
||||||
|
class WalletConfigProviderTests: XCTestCase {
|
||||||
|
override func setUp() {
|
||||||
|
super.setUp()
|
||||||
|
|
||||||
|
UserDefaultsWalletConfigStorage().clearAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLoadFlagsFromProvider() async {
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag1))
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag2))
|
||||||
|
|
||||||
|
let provider = WalletConfigSourceProviderMock() {
|
||||||
|
return WalletConfig(flags: [.testFlag1: true, .testFlag2: false])
|
||||||
|
}
|
||||||
|
|
||||||
|
let manager = WalletConfigProvider(configSourceProvider: provider, cache: UserDefaultsWalletConfigStorage())
|
||||||
|
let configuration = await manager.load()
|
||||||
|
|
||||||
|
XCTAssertTrue(configuration.isEnabled(.testFlag1))
|
||||||
|
XCTAssertFalse(configuration.isEnabled(.testFlag2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLoadFlagsFromCache() async {
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag1))
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag2))
|
||||||
|
|
||||||
|
let provider = WalletConfigSourceProviderMock() { throw NSError(domain: "whatever", code: 21) }
|
||||||
|
let cache = WalletConfigProviderCacheMock(cachedFlags: [.testFlag1: false, .testFlag2: true])
|
||||||
|
|
||||||
|
let manager = WalletConfigProvider(configSourceProvider: provider, cache: cache)
|
||||||
|
let configuration = await manager.load()
|
||||||
|
|
||||||
|
XCTAssertFalse(configuration.isEnabled(.testFlag1))
|
||||||
|
XCTAssertTrue(configuration.isEnabled(.testFlag2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLoadDefaultFlags() async {
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag1))
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag2))
|
||||||
|
|
||||||
|
let provider = WalletConfigSourceProviderMock() { throw NSError(domain: "whatever", code: 21) }
|
||||||
|
let cache = WalletConfigProviderCacheMock(cachedFlags: [:])
|
||||||
|
|
||||||
|
let manager = WalletConfigProvider(configSourceProvider: provider, cache: cache)
|
||||||
|
let configuration = await manager.load()
|
||||||
|
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag1))
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAllTheFlagsAreAlwaysReturned() async {
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag1))
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag2))
|
||||||
|
|
||||||
|
let provider = WalletConfigSourceProviderMock() {
|
||||||
|
return WalletConfig(flags: [.testFlag1: true])
|
||||||
|
}
|
||||||
|
|
||||||
|
let manager = WalletConfigProvider(configSourceProvider: provider, cache: UserDefaultsWalletConfigStorage())
|
||||||
|
let configuration = await manager.load()
|
||||||
|
|
||||||
|
XCTAssertTrue(configuration.isEnabled(.testFlag1))
|
||||||
|
XCTAssertFalse(configuration.isEnabled(.testFlag2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testProvidedFlagsAreCached() async {
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag1))
|
||||||
|
XCTAssertFalse(WalletConfig.default.isEnabled(.testFlag2))
|
||||||
|
|
||||||
|
let provider = WalletConfigSourceProviderMock() {
|
||||||
|
return WalletConfig(flags: [.testFlag1: true, .testFlag2: false])
|
||||||
|
}
|
||||||
|
let cache: WalletConfigProviderCache = UserDefaultsWalletConfigProviderCache()
|
||||||
|
|
||||||
|
let manager = WalletConfigProvider(configSourceProvider: provider, cache: cache)
|
||||||
|
_ = await manager.load()
|
||||||
|
|
||||||
|
guard let cachedConfiguration = await cache.load() else {
|
||||||
|
return XCTFail("No cached configuration.")
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertTrue(cachedConfiguration.isEnabled(.testFlag1))
|
||||||
|
XCTAssertFalse(cachedConfiguration.isEnabled(.testFlag2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WalletConfigSourceProviderMock: WalletConfigSourceProvider {
|
||||||
|
let provider: () async throws -> WalletConfig
|
||||||
|
|
||||||
|
func load() async throws -> WalletConfig {
|
||||||
|
return try await provider()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WalletConfigProviderCacheMock: WalletConfigProviderCache {
|
||||||
|
var cachedFlags: WalletConfig.RawFlags = [:]
|
||||||
|
|
||||||
|
init(cachedFlags: WalletConfig.RawFlags) {
|
||||||
|
self.cachedFlags = cachedFlags
|
||||||
|
}
|
||||||
|
|
||||||
|
func load() async -> WalletConfig? {
|
||||||
|
guard !cachedFlags.isEmpty else { return nil }
|
||||||
|
return WalletConfig(flags: cachedFlags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func store(_ configuration: WalletConfig) async {
|
||||||
|
cachedFlags = configuration.flags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UserDefaultsWalletConfigStorage {
|
||||||
|
func clearAll() {
|
||||||
|
let userdef = UserDefaults.standard
|
||||||
|
userdef.removeObject(forKey: Constants.cacheKey)
|
||||||
|
userdef.removeObject(forKey: Constants.providerKey)
|
||||||
|
userdef.synchronize()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue