diff --git a/novawallet.xcodeproj/project.pbxproj b/novawallet.xcodeproj/project.pbxproj index a90267000..ca5a829e0 100644 --- a/novawallet.xcodeproj/project.pbxproj +++ b/novawallet.xcodeproj/project.pbxproj @@ -1089,6 +1089,10 @@ 2D20F1BE2D351936003E9CF2 /* DAppListBannerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F1BD2D351936003E9CF2 /* DAppListBannerViewModel.swift */; }; 2D20F1C02D351B28003E9CF2 /* DAppListBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F1BF2D351B28003E9CF2 /* DAppListBannerView.swift */; }; 2D20F1C22D353495003E9CF2 /* DAppIconViewModelFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F1C12D353495003E9CF2 /* DAppIconViewModelFactory.swift */; }; + 2D20F1C42D364879003E9CF2 /* WalletStorageCleaning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F1C32D364879003E9CF2 /* WalletStorageCleaning.swift */; }; + 2D20F1C72D364938003E9CF2 /* WalletBrowserStateCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F1C62D364938003E9CF2 /* WalletBrowserStateCleaner.swift */; }; + 2D20F1C92D36BD5C003E9CF2 /* WalletDeleteStorageCleanerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F1C82D36BD5C003E9CF2 /* WalletDeleteStorageCleanerFactory.swift */; }; + 2D20F1CC2D36C5D8003E9CF2 /* RemovedWalletStorageCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D20F1CB2D36C5D8003E9CF2 /* RemovedWalletStorageCleaner.swift */; }; 2D2F6F522C50E52D005020EF /* VotingCurveTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D2F6F512C50E52D005020EF /* VotingCurveTests.swift */; }; 2D31D3062D149F74004BF46B /* ModalCardPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D31D3052D149F74004BF46B /* ModalCardPresentationController.swift */; }; 2D32BE122C6A49900047F520 /* ExtrinsicAssetConversionFeeEstimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32BE052C6A49900047F520 /* ExtrinsicAssetConversionFeeEstimator.swift */; }; @@ -1162,6 +1166,8 @@ 2D5A61C92C0E5C68006D58E3 /* NetworksListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A61C82C0E5C68006D58E3 /* NetworksListTableViewCell.swift */; }; 2D5A61CD2C0F58DD006D58E3 /* NetworksEmptyPlaceholderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A61CC2C0F58DD006D58E3 /* NetworksEmptyPlaceholderView.swift */; }; 2D5A61D02C0FAC5B006D58E3 /* IntegrateNetworksBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A61CF2C0FAC5B006D58E3 /* IntegrateNetworksBanner.swift */; }; + 2D5EBEB02D37D4090016AC4E /* WalletStorageCleanerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5EBEAF2D37D4090016AC4E /* WalletStorageCleanerFactory.swift */; }; + 2D5EBEB22D37DE440016AC4E /* DAppSettingsCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5EBEB12D37DE440016AC4E /* DAppSettingsCleaner.swift */; }; 2D5FC1A42C5220900013352B /* AccountVoteFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5FC1A32C5220900013352B /* AccountVoteFactory.swift */; }; 2D60C9BD2D1AA97C00027EC6 /* ModalCardPresentationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D60C9BC2D1AA97C00027EC6 /* ModalCardPresentationConfiguration.swift */; }; 2D60C9BF2D1AA9E500027EC6 /* ModalCardPresentationStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D60C9BE2D1AA9E500027EC6 /* ModalCardPresentationStyle.swift */; }; @@ -6515,6 +6521,10 @@ 2D20F1BD2D351936003E9CF2 /* DAppListBannerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppListBannerViewModel.swift; sourceTree = ""; }; 2D20F1BF2D351B28003E9CF2 /* DAppListBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppListBannerView.swift; sourceTree = ""; }; 2D20F1C12D353495003E9CF2 /* DAppIconViewModelFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppIconViewModelFactory.swift; sourceTree = ""; }; + 2D20F1C32D364879003E9CF2 /* WalletStorageCleaning.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletStorageCleaning.swift; sourceTree = ""; }; + 2D20F1C62D364938003E9CF2 /* WalletBrowserStateCleaner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletBrowserStateCleaner.swift; sourceTree = ""; }; + 2D20F1C82D36BD5C003E9CF2 /* WalletDeleteStorageCleanerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletDeleteStorageCleanerFactory.swift; sourceTree = ""; }; + 2D20F1CB2D36C5D8003E9CF2 /* RemovedWalletStorageCleaner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemovedWalletStorageCleaner.swift; sourceTree = ""; }; 2D2F6F512C50E52D005020EF /* VotingCurveTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VotingCurveTests.swift; sourceTree = ""; }; 2D31D3052D149F74004BF46B /* ModalCardPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalCardPresentationController.swift; sourceTree = ""; }; 2D32BE052C6A49900047F520 /* ExtrinsicAssetConversionFeeEstimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtrinsicAssetConversionFeeEstimator.swift; sourceTree = ""; }; @@ -6587,6 +6597,8 @@ 2D5A61C82C0E5C68006D58E3 /* NetworksListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworksListTableViewCell.swift; sourceTree = ""; }; 2D5A61CC2C0F58DD006D58E3 /* NetworksEmptyPlaceholderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworksEmptyPlaceholderView.swift; sourceTree = ""; }; 2D5A61CF2C0FAC5B006D58E3 /* IntegrateNetworksBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrateNetworksBanner.swift; sourceTree = ""; }; + 2D5EBEAF2D37D4090016AC4E /* WalletStorageCleanerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletStorageCleanerFactory.swift; sourceTree = ""; }; + 2D5EBEB12D37DE440016AC4E /* DAppSettingsCleaner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAppSettingsCleaner.swift; sourceTree = ""; }; 2D5FC1A32C5220900013352B /* AccountVoteFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountVoteFactory.swift; sourceTree = ""; }; 2D60C9BC2D1AA97C00027EC6 /* ModalCardPresentationConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalCardPresentationConfiguration.swift; sourceTree = ""; }; 2D60C9BE2D1AA9E500027EC6 /* ModalCardPresentationStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalCardPresentationStyle.swift; sourceTree = ""; }; @@ -13294,6 +13306,26 @@ path = IconRetrieve; sourceTree = ""; }; + 2D20F1C52D3648F5003E9CF2 /* WalletStorageCleaning */ = { + isa = PBXGroup; + children = ( + 2D20F1C32D364879003E9CF2 /* WalletStorageCleaning.swift */, + 2D20F1CB2D36C5D8003E9CF2 /* RemovedWalletStorageCleaner.swift */, + 2D20F1C82D36BD5C003E9CF2 /* WalletDeleteStorageCleanerFactory.swift */, + 2D20F1CA2D36C579003E9CF2 /* Cleaners */, + ); + path = WalletStorageCleaning; + sourceTree = ""; + }; + 2D20F1CA2D36C579003E9CF2 /* Cleaners */ = { + isa = PBXGroup; + children = ( + 2D20F1C62D364938003E9CF2 /* WalletBrowserStateCleaner.swift */, + 2D5EBEB12D37DE440016AC4E /* DAppSettingsCleaner.swift */, + ); + path = Cleaners; + sourceTree = ""; + }; 2D32BE112C6A49900047F520 /* FeeManaging */ = { isa = PBXGroup; children = ( @@ -17668,6 +17700,7 @@ 8467FD5B24EFDCC9005D486C /* UserDataStorageTestFacade.swift */, 84F4387E25D9D61300AEDA56 /* SubstrateStorageTestFacade.swift */, 84FACB1625F559F200F32ED4 /* WestendStub.swift */, + 2D5EBEAF2D37D4090016AC4E /* WalletStorageCleanerFactory.swift */, 845C7F05263C45EC0024E797 /* AnyProviderAutoCleaner.swift */, 845B822426EFE03E00D25C72 /* AccountGenerator.swift */, 84F13F0F26F1DC43006725FF /* ChainModelGenerator.swift */, @@ -17696,6 +17729,7 @@ 841AAC2E26F73E0C00F0A25E /* LocalStorageKeyFactory.swift */, 84D8753928EB0A93004065BD /* GovernanceChainSettings.swift */, 0C90C6C12B4FA9FB0084B5C2 /* WalletsUpdateMediator.swift */, + 2D20F1C52D3648F5003E9CF2 /* WalletStorageCleaning */, ); path = Storage; sourceTree = ""; @@ -25347,7 +25381,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "#! /bin/sh\n# Define output file. Change \"$PROJECT_DIR/${PROJECT_NAME}Tests\" to your test's root source folder, if it's not the default name.\nOUTPUT_FILE=\"${PROJECT_NAME}Tests/Mocks/ModuleMocks.swift\"\necho \"Generated Mocks File = $OUTPUT_FILE\"\n\n# Define input directory. Change \"${PROJECT_DIR}/${PROJECT_NAME}\" to your project's root source folder, if it's not the default name.\nINPUT_DIR=\"${PROJECT_NAME}\"\necho \"Mocks Input Directory = $INPUT_DIR\"\n\n# Generate mock files, include as many input files as you'd like to create mocks for.\n\"Pods/Cuckoo/run\" generate --no-header --testable \"${PROJECT_NAME}\" \\\n--exclude \"RootPresenterFactoryProtocol, UsernameSetupViewFactoryProtocol, OnboardingMainViewFactoryProtocol, AccountCreateViewFactoryProtocol, AccountImportViewFactoryProtocol, AccountConfirmViewFactoryProtocol, PinViewFactoryProtocol, ProfileViewFactoryProtocol, AccountManagementViewFactoryProtocol, AccountInfoViewFactoryProtocol, NetworkManagementViewFactoryProtocol, NetworkInfoViewFactoryProtocol, AddConnectionViewFactoryProtocol, AccountExportPasswordViewFactoryProtocol, ExportRestoreJsonViewFactoryProtocol, ExportMnemonicViewFactoryProtocol, StakingMainViewFactoryProtocol, SelectValidatorsStartViewFactoryProtocol, SelectValidatorsConfirmViewFactoryProtocol, RecommendedValidatorListViewFactoryProtocol, SelectedValidatorListViewFactoryProtocol, CustomValidatorListViewFactoryProtocol, ValidatorInfoViewFactoryProtocol, WalletHistoryFilterViewFactoryProtocol, StakingPayoutConfirmationViewFactoryProtocol, StakingRewardDetailsViewFactoryProtocol, StakingRewardPayoutsViewFactoryProtocol, StakingPayoutConfirmViewModelFactoryProtocol, YourValidatorListViewFactoryProtocol, StakingUnbondSetupViewFactoryProtocol, StakingUnbondConfirmViewFactoryProtocol, StakingRedeemViewFactoryProtocol, StakingBondMoreViewFactoryProtocol, StakingRebondSetupViewFactoryProtocol, ValidatorListFilterViewFactoryProtocol, ValidatorSearchViewFactoryProtocol\" \\\n--output \"${OUTPUT_FILE}\" \\\n\"$INPUT_DIR/../Pods/SoraFoundation/SoraFoundation/Classes/Localization/Localizable.swift\" \\\n\"$INPUT_DIR/Common/Services/ApplicationService.swift\" \\\n\"$INPUT_DIR/Common/Protocols/LoadableViewProtocol.swift\" \\\n\"$INPUT_DIR/Common/Protocols/ControllerBackedProtocol.swift\" \\\n\"$INPUT_DIR/Common/Protocols/WebPresentable.swift\" \\\n\"$INPUT_DIR/Common/Protocols/AlertPresentable.swift\" \\\n\"$INPUT_DIR/Common/Protocols/ModalAlertPresenting.swift\" \\\n\"$INPUT_DIR/Common/Protocols/SharingPresentable.swift\" \\\n\"$INPUT_DIR/Common/Protocols/AccountSelectionPresentable.swift\" \\\n\"$INPUT_DIR/Common/Protocols/AuthorizationPresentable.swift\" \\\n\"$INPUT_DIR/Common/ViewController/SearchController/TableSearchProtocols.swift\" \\\n\"$INPUT_DIR/Common/Services/Proxy/ProxySyncService.swift\" \\\n\"$INPUT_DIR/Common/Protocols/WalletSwitchPresentable.swift\" \\\n\"$INPUT_DIR/Common/Services/Web3AlertService/PushNotificationsServiceFacade.swift\" \\\n\"$INPUT_DIR/Common/Currency/CurrencyRepositoryProtocol.swift\" \\\n\"$INPUT_DIR/Modules/Root/RootProtocol.swift\" \\\n\"$INPUT_DIR/Modules/Onboarding/UsernameSetup/UsernameSetupProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Onboarding/Start/OnboardingMainProtocol.swift\" \\\n\"$INPUT_DIR/Modules/Onboarding/AccountCreate/AccountCreateProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ImportWallet/AccountImport/AccountImportProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Onboarding/AccountConfirm/AccountConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Pincode/PinSetup/PinSetupProtocol.swift\" \\\n\"$INPUT_DIR/Modules/Settings/SettingsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ManageWallets/AccountManagement/AccountManagementProtocols.swift\" \\\n\"$INPUT_DIR/Modules/AccountInfo/AccountInfoProtocols.swift\" \\\n\"$INPUT_DIR/Modules/NetworkManagement/NetworkManagementProtocols.swift\" \\\n\"$INPUT_DIR/Modules/NetworkInfo/NetworkInfoProtocols.swift\" \\\n\"$INPUT_DIR/Modules/AddConnection/AddConnectionProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ExportWallet/AccountExportPassword/AccountExportPasswordProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ExportWallet/ExportGenericView/ExportGenericProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ExportWallet/ExportMnemonic/ExportMnemonicProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ExportWallet/ExportRestoreJson/ExportRestoreJsonProtocols.swift\" \\\n\"$INPUT_DIR/Modules/TransactionHistory/HistoryFilter/WalletHistoryFilterProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/Operations/ValidatorOperationFactory/ValidatorOperationFactoryProtocol.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingMain/StakingMainProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingMain/Relaychain/StakingRelaychainProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/Operations/NetworkStakingInfoOperationFactory.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingPayoutConfirmation/StakingPayoutConfirmationProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRewardDetails/StakingRewardDetailsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRewardPayouts/StakingRewardPayoutsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingBalance/StakingBalanceProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingUnbondSetup/StakingUnbondSetupProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingUnbondConfirm/StakingUnbondConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRedeem/StakingRedeemProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingBondMore/StakingBondMoreProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingBondMoreConfirmation/StakingBondMoreConfirmationProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRebondSetup/StakingRebondSetupProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRebondConfirmation/StakingRebondConfirmationProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/ControllerAccount/ControllerAccountProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRewardDestinationSetup/StakingRewardDestSetupProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRewardDestConfirm/StakingRewardDestConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/SelectValidatorsStart/SelectValidatorsStartProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/YourValidatorList/YourValidatorListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/ValidatorListFilter/ValidatorListFilterProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/ValidatorSearch/ValidatorSearchProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/SelectValidatorsConfirm/SelectValidatorsConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/RecommendedValidatorList/RecommendedValidatorListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/SelectedValidatorList/SelectedValidatorListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/CustomValidatorList/CustomValidatorListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/ValidatorInfo/ValidatorInfoProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CrowdloanList/CrowdloanListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CrowdloanContribution/CrowdloanContributionProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CrowdloanContributionSetup/CrowdloanContributionSetupProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CrowdloanContributionConfirm/CrowdloanContributionConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CustomCrowdloan/CustomCrowdloanDelegate.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/ReferralCrowdloan/ReferralCrowdloanProtocols.swift\" \\\n\"$INPUT_DIR/Common/ViewController/SelectionListViewController/SelectionListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ChainAssetSelection/ChainAssetSelectionProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ImportWallet/AdvancedWallet/AdvancedWalletProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/DAppAuthConfirm/DAppAuthConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/DAppList/DAppListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/DAppBrowser/DAppBrowserProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/DAppOperationConfirm/DAppOperationConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/DAppSearch/DAppSearchProtocols.swift\" \\\n\"$INPUT_DIR/Modules/AssetsSettings/AssetsSettingsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/OperationDetails/OperationDetailsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CrowdloanYourContributions/CrowdloanYourContributionsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/SecurityLayer/SecurityLayerProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/WalletConnect/Service/WalletConnectProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ManualBackup/BackupAttention/CheckboxListPresenter/CheckboxListPresenterTrait.swift\" \\\n\"$INPUT_DIR/Modules/TokensManage/List/TokensManageProtocols.swift\" \\\n"; + shellScript = "#! /bin/sh\n# Define output file. Change \"$PROJECT_DIR/${PROJECT_NAME}Tests\" to your test's root source folder, if it's not the default name.\nOUTPUT_FILE=\"${PROJECT_NAME}Tests/Mocks/ModuleMocks.swift\"\necho \"Generated Mocks File = $OUTPUT_FILE\"\n\n# Define input directory. Change \"${PROJECT_DIR}/${PROJECT_NAME}\" to your project's root source folder, if it's not the default name.\nINPUT_DIR=\"${PROJECT_NAME}\"\necho \"Mocks Input Directory = $INPUT_DIR\"\n\n# Generate mock files, include as many input files as you'd like to create mocks for.\n\"Pods/Cuckoo/run\" generate --no-header --testable \"${PROJECT_NAME}\" \\\n--exclude \"RootPresenterFactoryProtocol, UsernameSetupViewFactoryProtocol, OnboardingMainViewFactoryProtocol, AccountCreateViewFactoryProtocol, AccountImportViewFactoryProtocol, AccountConfirmViewFactoryProtocol, PinViewFactoryProtocol, ProfileViewFactoryProtocol, AccountManagementViewFactoryProtocol, AccountInfoViewFactoryProtocol, NetworkManagementViewFactoryProtocol, NetworkInfoViewFactoryProtocol, AddConnectionViewFactoryProtocol, AccountExportPasswordViewFactoryProtocol, ExportRestoreJsonViewFactoryProtocol, ExportMnemonicViewFactoryProtocol, StakingMainViewFactoryProtocol, SelectValidatorsStartViewFactoryProtocol, SelectValidatorsConfirmViewFactoryProtocol, RecommendedValidatorListViewFactoryProtocol, SelectedValidatorListViewFactoryProtocol, CustomValidatorListViewFactoryProtocol, ValidatorInfoViewFactoryProtocol, WalletHistoryFilterViewFactoryProtocol, StakingPayoutConfirmationViewFactoryProtocol, StakingRewardDetailsViewFactoryProtocol, StakingRewardPayoutsViewFactoryProtocol, StakingPayoutConfirmViewModelFactoryProtocol, YourValidatorListViewFactoryProtocol, StakingUnbondSetupViewFactoryProtocol, StakingUnbondConfirmViewFactoryProtocol, StakingRedeemViewFactoryProtocol, StakingBondMoreViewFactoryProtocol, StakingRebondSetupViewFactoryProtocol, ValidatorListFilterViewFactoryProtocol, ValidatorSearchViewFactoryProtocol\" \\\n--output \"${OUTPUT_FILE}\" \\\n\"$INPUT_DIR/../Pods/SoraFoundation/SoraFoundation/Classes/Localization/Localizable.swift\" \\\n\"$INPUT_DIR/Common/Services/ApplicationService.swift\" \\\n\"$INPUT_DIR/Common/Protocols/LoadableViewProtocol.swift\" \\\n\"$INPUT_DIR/Common/Protocols/ControllerBackedProtocol.swift\" \\\n\"$INPUT_DIR/Common/Protocols/WebPresentable.swift\" \\\n\"$INPUT_DIR/Common/Protocols/AlertPresentable.swift\" \\\n\"$INPUT_DIR/Common/Protocols/ModalAlertPresenting.swift\" \\\n\"$INPUT_DIR/Common/Protocols/SharingPresentable.swift\" \\\n\"$INPUT_DIR/Common/Protocols/AccountSelectionPresentable.swift\" \\\n\"$INPUT_DIR/Common/Protocols/AuthorizationPresentable.swift\" \\\n\"$INPUT_DIR/Common/ViewController/SearchController/TableSearchProtocols.swift\" \\\n\"$INPUT_DIR/Common/Services/Proxy/ProxySyncService.swift\" \\\n\"$INPUT_DIR/Common/Protocols/WalletSwitchPresentable.swift\" \\\n\"$INPUT_DIR/Common/Services/Web3AlertService/PushNotificationsServiceFacade.swift\" \\\n\"$INPUT_DIR/Common/Currency/CurrencyRepositoryProtocol.swift\" \\\n\"$INPUT_DIR/Common/Storage/WalletStorageCleaning/WalletStorageCleaning.swift\" \\\n\"$INPUT_DIR/Modules/Root/RootProtocol.swift\" \\\n\"$INPUT_DIR/Modules/Onboarding/UsernameSetup/UsernameSetupProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Onboarding/Start/OnboardingMainProtocol.swift\" \\\n\"$INPUT_DIR/Modules/Onboarding/AccountCreate/AccountCreateProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ImportWallet/AccountImport/AccountImportProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Onboarding/AccountConfirm/AccountConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Pincode/PinSetup/PinSetupProtocol.swift\" \\\n\"$INPUT_DIR/Modules/Settings/SettingsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ManageWallets/AccountManagement/AccountManagementProtocols.swift\" \\\n\"$INPUT_DIR/Modules/AccountInfo/AccountInfoProtocols.swift\" \\\n\"$INPUT_DIR/Modules/NetworkManagement/NetworkManagementProtocols.swift\" \\\n\"$INPUT_DIR/Modules/NetworkInfo/NetworkInfoProtocols.swift\" \\\n\"$INPUT_DIR/Modules/AddConnection/AddConnectionProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ExportWallet/AccountExportPassword/AccountExportPasswordProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ExportWallet/ExportGenericView/ExportGenericProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ExportWallet/ExportMnemonic/ExportMnemonicProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ExportWallet/ExportRestoreJson/ExportRestoreJsonProtocols.swift\" \\\n\"$INPUT_DIR/Modules/TransactionHistory/HistoryFilter/WalletHistoryFilterProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/Operations/ValidatorOperationFactory/ValidatorOperationFactoryProtocol.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingMain/StakingMainProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingMain/Relaychain/StakingRelaychainProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/Operations/NetworkStakingInfoOperationFactory.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingPayoutConfirmation/StakingPayoutConfirmationProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRewardDetails/StakingRewardDetailsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRewardPayouts/StakingRewardPayoutsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingBalance/StakingBalanceProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingUnbondSetup/StakingUnbondSetupProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingUnbondConfirm/StakingUnbondConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRedeem/StakingRedeemProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingBondMore/StakingBondMoreProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingBondMoreConfirmation/StakingBondMoreConfirmationProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRebondSetup/StakingRebondSetupProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRebondConfirmation/StakingRebondConfirmationProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/ControllerAccount/ControllerAccountProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRewardDestinationSetup/StakingRewardDestSetupProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/StakingRewardDestConfirm/StakingRewardDestConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/SelectValidatorsStart/SelectValidatorsStartProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/YourValidatorList/YourValidatorListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/ValidatorListFilter/ValidatorListFilterProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/ValidatorSearch/ValidatorSearchProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/SelectValidatorsConfirm/SelectValidatorsConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/RecommendedValidatorList/RecommendedValidatorListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/SelectedValidatorList/SelectedValidatorListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/CustomValidatorList/CustomValidatorListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Staking/SelectValidatorsFlow/ValidatorInfo/ValidatorInfoProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CrowdloanList/CrowdloanListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CrowdloanContribution/CrowdloanContributionProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CrowdloanContributionSetup/CrowdloanContributionSetupProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CrowdloanContributionConfirm/CrowdloanContributionConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CustomCrowdloan/CustomCrowdloanDelegate.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/ReferralCrowdloan/ReferralCrowdloanProtocols.swift\" \\\n\"$INPUT_DIR/Common/ViewController/SelectionListViewController/SelectionListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ChainAssetSelection/ChainAssetSelectionProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ImportWallet/AdvancedWallet/AdvancedWalletProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/DAppAuthConfirm/DAppAuthConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/DAppList/DAppListProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/DAppBrowser/DAppBrowserProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/DAppOperationConfirm/DAppOperationConfirmProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/DAppSearch/DAppSearchProtocols.swift\" \\\n\"$INPUT_DIR/Modules/AssetsSettings/AssetsSettingsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/OperationDetails/OperationDetailsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/Vote/Crowdloan/CrowdloanYourContributions/CrowdloanYourContributionsProtocols.swift\" \\\n\"$INPUT_DIR/Modules/SecurityLayer/SecurityLayerProtocols.swift\" \\\n\"$INPUT_DIR/Modules/DApp/WalletConnect/Service/WalletConnectProtocols.swift\" \\\n\"$INPUT_DIR/Modules/ManualBackup/BackupAttention/CheckboxListPresenter/CheckboxListPresenterTrait.swift\" \\\n\"$INPUT_DIR/Modules/TokensManage/List/TokensManageProtocols.swift\" \\\n"; }; 842D1E8924D207D900C30A7A /* Common Mock */ = { isa = PBXShellScriptBuildPhase; @@ -27575,6 +27609,7 @@ 84D911AA292C923D0032EF33 /* Data+Fill.swift in Sources */, F4B39C4E27326E8400BB6E10 /* AcalaContributionSetupViewController.swift in Sources */, 84E63C1728FFC69A0093534A /* DiscreteGradientSlider.swift in Sources */, + 2D20F1C92D36BD5C003E9CF2 /* WalletDeleteStorageCleanerFactory.swift in Sources */, 2D62874F2C95C1F500060814 /* ReferendumsObservableState.swift in Sources */, 84EC2D18276B9DBC009B0BE1 /* PolkadotExtensionAccount.swift in Sources */, 0C63908B2BF073C20015D467 /* CloudBackupSyncMonitoring.swift in Sources */, @@ -27597,6 +27632,7 @@ 847A25C628D84BE2006AC9F5 /* Referenda.swift in Sources */, 0C17BD9B2A43025E004AF9E7 /* Pagination.swift in Sources */, 88D02FE82942EB1A00E26390 /* AssetDetailsModel.swift in Sources */, + 2D20F1C72D364938003E9CF2 /* WalletBrowserStateCleaner.swift in Sources */, 0C0E0A9B2B3E8C8A00865F10 /* ExtrinsicSigningContext.swift in Sources */, 77F033A22A84E00F006BC67E /* StakingPoolView.swift in Sources */, 77E304A92AEB9F76006FD6F0 /* SwapConfirmInitState.swift in Sources */, @@ -27949,6 +27985,7 @@ 84B018AC26E01A4100C75E28 /* StakingStateView.swift in Sources */, 842A737C27DCC489006EE1EA /* OperationDetailsTransferView.swift in Sources */, 84880C4429026C3E00CADB06 /* ReferendumDelegatingLocal.swift in Sources */, + 2D20F1CC2D36C5D8003E9CF2 /* RemovedWalletStorageCleaner.swift in Sources */, 8472C5B2265CF9C500E2481B /* StakingRewardDestConfirmInteractor.swift in Sources */, 88F9F696297B082F00F6550D /* SelectableTitleTableViewCell.swift in Sources */, 882C29AE28DC7CB4009CA4B6 /* StorageMigrating+CheckVersion.swift in Sources */, @@ -28331,6 +28368,7 @@ 8498430926592E5D006BBB9F /* CrowdloansViewModel.swift in Sources */, 8482F62D280C5B040006C3A0 /* DAppsAuthSettingsWalletCell.swift in Sources */, 5DDD2206DF795CF205610455 /* AccountExportPasswordPresenter.swift in Sources */, + 2D5EBEB22D37DE440016AC4E /* DAppSettingsCleaner.swift in Sources */, 800FCAF66DC8A24020D16A9C /* AccountExportPasswordInteractor.swift in Sources */, 841E553A282D23AE00C8438F /* StakingRelaychainWireframe.swift in Sources */, 0C3205BB2A8679F0002EB914 /* EvmGasPriceProvider.swift in Sources */, @@ -29928,6 +29966,7 @@ 0075488169C69B97C0630EB8 /* AssetReceiveProtocols.swift in Sources */, 2D1C5D102C242FF800E2DBDD /* NetworkNodeBaseInteractor.swift in Sources */, 0DACB56C0BDD4C984FE3C15C /* AssetReceiveWireframe.swift in Sources */, + 2D20F1C42D364879003E9CF2 /* WalletStorageCleaning.swift in Sources */, D264B2A8A516396051016CAB /* AssetReceivePresenter.swift in Sources */, D3B74ED2525DE12423722DE2 /* AssetReceiveInteractor.swift in Sources */, E6D05825C7512E3CD560B39F /* AssetReceiveViewController.swift in Sources */, @@ -30679,6 +30718,7 @@ buildActionMask = 2147483647; files = ( 0C846B872BE48998000EBFC2 /* MockPreferredValidatorsProvider.swift in Sources */, + 2D5EBEB02D37D4090016AC4E /* WalletStorageCleanerFactory.swift in Sources */, 8410562E27AF22DA004F5CA3 /* EthereumAddressChecksum.swift in Sources */, 84B66A1826FE05B00038B963 /* ChainRegistryStub.swift in Sources */, 8467FD3924EACE08005D486C /* AccountCreationHelper.swift in Sources */, diff --git a/novawallet/Common/Services/CloudBackup/Operations/CloudBackupUpdateApplicationFactory+Create.swift b/novawallet/Common/Services/CloudBackup/Operations/CloudBackupUpdateApplicationFactory+Create.swift index 18943c2be..0c1a6ef63 100644 --- a/novawallet/Common/Services/CloudBackup/Operations/CloudBackupUpdateApplicationFactory+Create.swift +++ b/novawallet/Common/Services/CloudBackup/Operations/CloudBackupUpdateApplicationFactory+Create.swift @@ -17,9 +17,12 @@ extension CloudBackupUpdateApplicationFactory { sortDescriptors: [] ) + let walletStorageCleaner = WalletStorageCleanerFactory.createWalletStorageCleaner(using: operationQueue) + let walletsUpdater = WalletUpdateMediator( selectedWalletSettings: SelectedWalletSettings.shared, repository: walletsRepository, + removedWalletsCleaner: walletStorageCleaner, operationQueue: operationQueue ) diff --git a/novawallet/Common/Services/ServiceCoordinator.swift b/novawallet/Common/Services/ServiceCoordinator.swift index 65e322b29..aa820b251 100644 --- a/novawallet/Common/Services/ServiceCoordinator.swift +++ b/novawallet/Common/Services/ServiceCoordinator.swift @@ -179,10 +179,15 @@ extension ServiceCoordinator { logger: logger ) + let operationQueue = OperationManagerFacade.sharedDefaultQueue + + let walletStorageCleaner = WalletStorageCleanerFactory.createWalletStorageCleaner(using: operationQueue) + let walletUpdateMediator = WalletUpdateMediator( selectedWalletSettings: SelectedWalletSettings.shared, repository: metaAccountsRepository, - operationQueue: OperationManagerFacade.sharedDefaultQueue + removedWalletsCleaner: walletStorageCleaner, + operationQueue: operationQueue ) let proxySyncService = ProxySyncService( diff --git a/novawallet/Common/Storage/WalletStorageCleaning/Cleaners/DAppSettingsCleaner.swift b/novawallet/Common/Storage/WalletStorageCleaning/Cleaners/DAppSettingsCleaner.swift new file mode 100644 index 000000000..5525571b8 --- /dev/null +++ b/novawallet/Common/Storage/WalletStorageCleaning/Cleaners/DAppSettingsCleaner.swift @@ -0,0 +1,42 @@ +import Foundation +import Operation_iOS + +final class DAppSettingsCleaner { + private let authorizedDAppRepository: AnyDataProviderRepository + + init(authorizedDAppRepository: AnyDataProviderRepository) { + self.authorizedDAppRepository = authorizedDAppRepository + } +} + +// MARK: WalletStorageCleaning + +extension DAppSettingsCleaner: WalletStorageCleaning { + func cleanStorage( + for removedItems: @escaping () throws -> [MetaAccountModel] + ) -> CompoundOperationWrapper { + let fetchOptions = RepositoryFetchOptions() + let fetchSettingsOperation = authorizedDAppRepository.fetchAllOperation(with: fetchOptions) + + let deletionBlock: () throws -> [String] = { + let removedWallets = Set(try removedItems().map(\.metaId)) + let dappSettingsIds = try fetchSettingsOperation.extractNoCancellableResultData() + .compactMap(\.metaId) + .filter { removedWallets.contains($0) } + + return dappSettingsIds + } + + let removeSettingsOperation = authorizedDAppRepository.saveOperation( + { [] }, + deletionBlock + ) + + removeSettingsOperation.addDependency(fetchSettingsOperation) + + return CompoundOperationWrapper( + targetOperation: removeSettingsOperation, + dependencies: [fetchSettingsOperation] + ) + } +} diff --git a/novawallet/Common/Storage/WalletStorageCleaning/Cleaners/WalletBrowserStateCleaner.swift b/novawallet/Common/Storage/WalletStorageCleaning/Cleaners/WalletBrowserStateCleaner.swift new file mode 100644 index 000000000..49e3bf9ff --- /dev/null +++ b/novawallet/Common/Storage/WalletStorageCleaning/Cleaners/WalletBrowserStateCleaner.swift @@ -0,0 +1,70 @@ +import Foundation +import Operation_iOS + +final class WalletBrowserStateCleaner { + private let browserTabManager: DAppBrowserTabManagerProtocol + private let webViewPoolEraser: WebViewPoolEraserProtocol + private let operationQueue: OperationQueue + + init( + browserTabManager: DAppBrowserTabManagerProtocol, + webViewPoolEraser: WebViewPoolEraserProtocol, + operationQueue: OperationQueue + ) { + self.browserTabManager = browserTabManager + self.webViewPoolEraser = webViewPoolEraser + self.operationQueue = operationQueue + } +} + +// MARK: Private + +private extension WalletBrowserStateCleaner { + func createTabsCleaningWrapper( + for removedItems: @escaping () throws -> [MetaAccountModel] + ) -> CompoundOperationWrapper> { + OperationCombiningService.compoundNonOptionalWrapper( + operationQueue: operationQueue + ) { [weak self] in + guard let self else { + throw BaseOperationError.parentOperationCancelled + } + + let metaIds = try removedItems().map(\.metaId) + + return browserTabManager.removeAllWrapper(for: Set(metaIds)) + } + } + + func createWebViewCleaningOperation( + dependingOn tabIdsOperation: BaseOperation> + ) -> ClosureOperation { + ClosureOperation { [weak self] in + let tabIds = try tabIdsOperation.extractNoCancellableResultData() + + tabIds.forEach { tabId in + DispatchQueue.main.async { + self?.webViewPoolEraser.removeWebView(for: tabId) + } + } + } + } +} + +// MARK: WalletStorageCleaning + +extension WalletBrowserStateCleaner: WalletStorageCleaning { + func cleanStorage( + for removedItems: @escaping () throws -> [MetaAccountModel] + ) -> CompoundOperationWrapper { + let tabsCleaningWrapper = createTabsCleaningWrapper(for: removedItems) + + let webViewPoolCleaningOperation = createWebViewCleaningOperation( + dependingOn: tabsCleaningWrapper.targetOperation + ) + + webViewPoolCleaningOperation.addDependency(tabsCleaningWrapper.targetOperation) + + return tabsCleaningWrapper.insertingTail(operation: webViewPoolCleaningOperation) + } +} diff --git a/novawallet/Common/Storage/WalletStorageCleaning/RemovedWalletStorageCleaner.swift b/novawallet/Common/Storage/WalletStorageCleaning/RemovedWalletStorageCleaner.swift new file mode 100644 index 000000000..92b788ebd --- /dev/null +++ b/novawallet/Common/Storage/WalletStorageCleaning/RemovedWalletStorageCleaner.swift @@ -0,0 +1,35 @@ +import Foundation +import Operation_iOS + +final class RemovedWalletStorageCleaner { + private let cleanersCascade: [WalletStorageCleaning] + + init(cleanersCascade: [WalletStorageCleaning]) { + self.cleanersCascade = cleanersCascade + } +} + +// MARK: WalletStorageCleaning + +extension RemovedWalletStorageCleaner: WalletStorageCleaning { + func cleanStorage( + for removedItems: @escaping () throws -> [MetaAccountModel] + ) -> CompoundOperationWrapper { + let wrappers = cleanersCascade.map { $0.cleanStorage(for: removedItems) } + + let mergeOperation = ClosureOperation { + _ = try wrappers.map { try $0.targetOperation.extractNoCancellableResultData() } + + return + } + + wrappers.forEach { mergeOperation.addDependency($0.targetOperation) } + + let dependencies = wrappers.flatMap(\.allOperations) + + return CompoundOperationWrapper( + targetOperation: mergeOperation, + dependencies: dependencies + ) + } +} diff --git a/novawallet/Common/Storage/WalletStorageCleaning/WalletDeleteStorageCleanerFactory.swift b/novawallet/Common/Storage/WalletStorageCleaning/WalletDeleteStorageCleanerFactory.swift new file mode 100644 index 000000000..aaf341725 --- /dev/null +++ b/novawallet/Common/Storage/WalletStorageCleaning/WalletDeleteStorageCleanerFactory.swift @@ -0,0 +1,51 @@ +import Foundation +import Operation_iOS + +final class WalletStorageCleanerFactory { + static func createWalletStorageCleaner(using operationQueue: OperationQueue) -> WalletStorageCleaning { + let browserStateCleaner = createBrowserStateCleaner(using: operationQueue) + let dAppSettingsCleaner = createDAppSettingsCleaner() + + // Add every cleaner to the array + // in the same order it should get called + let cleaners = [ + browserStateCleaner, + dAppSettingsCleaner + ] + + let mainCleaner = RemovedWalletStorageCleaner(cleanersCascade: cleaners) + + return mainCleaner + } + + private static func createBrowserStateCleaner( + using operationQueue: OperationQueue + ) -> WalletStorageCleaning { + let browserTabManager = DAppBrowserTabManager.shared + let webViewPoolEraser = WebViewPool.shared + + let browserStateCleaner = WalletBrowserStateCleaner( + browserTabManager: browserTabManager, + webViewPoolEraser: webViewPoolEraser, + operationQueue: operationQueue + ) + + return browserStateCleaner + } + + private static func createDAppSettingsCleaner() -> WalletStorageCleaning { + let mapper = DAppSettingsMapper() + let storageFacade = UserDataStorageFacade.shared + + let repository = storageFacade.createRepository( + filter: nil, + sortDescriptors: [], + mapper: AnyCoreDataMapper(mapper) + ) + let authorizedDAppRepository = AnyDataProviderRepository(repository) + + let dappSettingsCleaner = DAppSettingsCleaner(authorizedDAppRepository: authorizedDAppRepository) + + return dappSettingsCleaner + } +} diff --git a/novawallet/Common/Storage/WalletStorageCleaning/WalletStorageCleaning.swift b/novawallet/Common/Storage/WalletStorageCleaning/WalletStorageCleaning.swift new file mode 100644 index 000000000..d36acfaff --- /dev/null +++ b/novawallet/Common/Storage/WalletStorageCleaning/WalletStorageCleaning.swift @@ -0,0 +1,8 @@ +import Foundation +import Operation_iOS + +protocol WalletStorageCleaning { + func cleanStorage( + for removedItems: @escaping () throws -> [MetaAccountModel] + ) -> CompoundOperationWrapper +} diff --git a/novawallet/Common/Storage/WalletsUpdateMediator.swift b/novawallet/Common/Storage/WalletsUpdateMediator.swift index 24e31d6a3..acda0e7de 100644 --- a/novawallet/Common/Storage/WalletsUpdateMediator.swift +++ b/novawallet/Common/Storage/WalletsUpdateMediator.swift @@ -22,15 +22,18 @@ final class WalletUpdateMediator { let selectedWalletSettings: SelectedWalletSettings let repository: AnyDataProviderRepository + let removedWalletsCleaner: WalletStorageCleaning let operationQueue: OperationQueue init( selectedWalletSettings: SelectedWalletSettings, repository: AnyDataProviderRepository, + removedWalletsCleaner: WalletStorageCleaning, operationQueue: OperationQueue ) { self.selectedWalletSettings = selectedWalletSettings self.repository = repository + self.removedWalletsCleaner = removedWalletsCleaner self.operationQueue = operationQueue } @@ -210,6 +213,14 @@ extension WalletUpdateMediator: WalletUpdateMediating { newSelectedWalletOperation.addDependency(proxiedsRemovalOperation) + let walletsStateCleaningWrapper = removedWalletsCleaner.cleanStorage { + let changesResult = try newSelectedWalletOperation.extractNoCancellableResultData() + + return changesResult.changes.removedItems.map(\.info) + } + + walletsStateCleaningWrapper.addDependency(operations: [newSelectedWalletOperation]) + let saveOperation = repository.saveOperation({ let changesResult = try newSelectedWalletOperation.extractNoCancellableResultData() @@ -231,6 +242,7 @@ extension WalletUpdateMediator: WalletUpdateMediating { let resultOperation = ClosureOperation { try saveOperation.extractNoCancellableResultData() + try walletsStateCleaningWrapper.targetOperation.extractNoCancellableResultData() let isWalletSwitched = try selectedWalletUpdateOperation.extractNoCancellableResultData() let currentWallet = try newSelectedWalletOperation.extractNoCancellableResultData().selectedWallet @@ -238,17 +250,24 @@ extension WalletUpdateMediator: WalletUpdateMediating { } resultOperation.addDependency(saveOperation) + resultOperation.addDependency(walletsStateCleaningWrapper.targetOperation) resultOperation.addDependency(selectedWalletUpdateOperation) resultOperation.addDependency(newSelectedWalletOperation) let dependencies = [ allWalletsOperation, proxiedsRemovalOperation, - newSelectedWalletOperation, - saveOperation, - selectedWalletUpdateOperation + newSelectedWalletOperation ] - - return CompoundOperationWrapper(targetOperation: resultOperation, dependencies: dependencies) + + walletsStateCleaningWrapper.allOperations + + [ + saveOperation, + selectedWalletUpdateOperation + ] + + return CompoundOperationWrapper( + targetOperation: resultOperation, + dependencies: dependencies + ) } } diff --git a/novawallet/Common/ViewController/ModalCard/UIViewController+PresentCardLayout.swift b/novawallet/Common/ViewController/ModalCard/UIViewController+PresentCardLayout.swift index 85fe26ddf..4355555bd 100644 --- a/novawallet/Common/ViewController/ModalCard/UIViewController+PresentCardLayout.swift +++ b/novawallet/Common/ViewController/ModalCard/UIViewController+PresentCardLayout.swift @@ -11,8 +11,6 @@ extension UIViewController { guard let contextRootViewController else { return } - viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] - let appearanceAnimator = BlockViewAnimator( duration: 0.25, delay: 0.0, diff --git a/novawallet/Modules/DApp/DAppBrowser/Tabs/DAppBrowserTabManager/DAppBrowserTabManager.swift b/novawallet/Modules/DApp/DAppBrowser/Tabs/DAppBrowserTabManager/DAppBrowserTabManager.swift index 9212317c5..b54e5ca11 100644 --- a/novawallet/Modules/DApp/DAppBrowser/Tabs/DAppBrowserTabManager/DAppBrowserTabManager.swift +++ b/novawallet/Modules/DApp/DAppBrowser/Tabs/DAppBrowserTabManager/DAppBrowserTabManager.swift @@ -151,7 +151,7 @@ private extension DAppBrowserTabManager { return wrapper.insertingHead(operations: [renderDataOperation]) } - func removeTabWrapper(for tabId: UUID) -> CompoundOperationWrapper { + func removeWrapper(for tabId: UUID) -> CompoundOperationWrapper { let deleteOperation = repository.saveOperation( { [] }, { [tabId.uuidString] } @@ -163,22 +163,18 @@ private extension DAppBrowserTabManager { return renderRemoveWrapper.insertingHead(operations: [deleteOperation]) } - func removeAllWrapper() -> CompoundOperationWrapper { - let tabIds = observableTabs.state - .fetchAllValues() - .map(\.uuid) - + func removeWrapper(for tabIds: [UUID]) -> CompoundOperationWrapper> { let rendersClearWrapper = fileRepository.removeRenders(for: tabIds) let deleteOperation = repository.saveOperation( { [] }, { tabIds.map(\.uuidString) } ) - let mappingOperation = ClosureOperation { + let mappingOperation = ClosureOperation> { _ = try rendersClearWrapper.targetOperation.extractNoCancellableResultData() _ = try deleteOperation.extractNoCancellableResultData() - return + return Set(tabIds) } mappingOperation.addDependency(rendersClearWrapper.targetOperation) @@ -190,6 +186,59 @@ private extension DAppBrowserTabManager { ) } + func removeAllWrapper(_ metaIds: Set?) -> CompoundOperationWrapper> { + let tabsWrapper: CompoundOperationWrapper<[DAppBrowserTab]> = if let metaIds { + tabsFetchWrapper(for: metaIds) + } else { + .createWithResult( + observableTabs + .state + .fetchAllValues() + ) + } + + let wrapper: CompoundOperationWrapper> = OperationCombiningService.compoundNonOptionalWrapper( + operationQueue: operationQueue + ) { [weak self] in + guard let self else { + return .createWithError(BaseOperationError.parentOperationCancelled) + } + + let tabIds = try tabsWrapper.targetOperation.extractNoCancellableResultData().map(\.uuid) + + return removeWrapper(for: tabIds) + } + + wrapper.addDependency(wrapper: tabsWrapper) + + return wrapper.insertingHead(operations: tabsWrapper.allOperations) + } + + func tabsFetchWrapper(for metaIds: Set) -> CompoundOperationWrapper<[DAppBrowserTab]> { + let fetchTabsOperation = repository.fetchAllOperation(with: RepositoryFetchOptions()) + + let resultOperaton = ClosureOperation { [weak self] in + guard let self else { + throw BaseOperationError.parentOperationCancelled + } + + let persistedTabs = try fetchTabsOperation.extractNoCancellableResultData() + + let tabs = persistedTabs + .filter { metaIds.contains($0.metaId) } + .map { self.map(persistenceModel: $0) } + + return sorted(tabs) + } + + resultOperaton.addDependency(fetchTabsOperation) + + return CompoundOperationWrapper( + targetOperation: resultOperaton, + dependencies: [fetchTabsOperation] + ) + } + func sorted(_ tabs: [DAppBrowserTab]) -> [DAppBrowserTab] { tabs.sorted { $0.createdAt < $1.createdAt } } @@ -291,32 +340,11 @@ extension DAppBrowserTabManager: DAppBrowserTabManagerProtocol { return .createWithResult([]) } - let fetchTabsOperation = repository.fetchAllOperation(with: RepositoryFetchOptions()) - - let resultOperaton = ClosureOperation { [weak self] in - guard let self else { - throw BaseOperationError.parentOperationCancelled - } - - let persistedTabs = try fetchTabsOperation.extractNoCancellableResultData() - - let tabs = persistedTabs - .filter { $0.metaId == metaAccount.metaId } - .map { self.map(persistenceModel: $0) } - - return sorted(tabs) - } - - resultOperaton.addDependency(fetchTabsOperation) - - return CompoundOperationWrapper( - targetOperation: resultOperaton, - dependencies: [fetchTabsOperation] - ) + return tabsFetchWrapper(for: [metaAccount.metaId]) } func removeTab(with id: UUID) { - let wrapper = removeTabWrapper(for: id) + let wrapper = removeWrapper(for: id) execute( wrapper: wrapper, @@ -362,8 +390,8 @@ extension DAppBrowserTabManager: DAppBrowserTabManagerProtocol { return resultWrapper.insertingTail(operation: voidResultOperation) } - func removeAll() { - let wrapper = removeAllWrapper() + func removeAll(for metaIds: Set?) { + let wrapper = removeAllWrapper(for: metaIds) execute( wrapper: wrapper, @@ -379,6 +407,10 @@ extension DAppBrowserTabManager: DAppBrowserTabManagerProtocol { } } + func removeAllWrapper(for metaIds: Set?) -> CompoundOperationWrapper> { + removeAllWrapper(metaIds) + } + func addObserver( _ observer: DAppBrowserTabsObserver, sendOnSubscription: Bool diff --git a/novawallet/Modules/DApp/DAppBrowser/Tabs/DAppBrowserTabManager/DAppBrowserTabManagerProtocol.swift b/novawallet/Modules/DApp/DAppBrowser/Tabs/DAppBrowserTabManager/DAppBrowserTabManagerProtocol.swift index b0022160f..6d345f064 100644 --- a/novawallet/Modules/DApp/DAppBrowser/Tabs/DAppBrowserTabManager/DAppBrowserTabManagerProtocol.swift +++ b/novawallet/Modules/DApp/DAppBrowser/Tabs/DAppBrowserTabManager/DAppBrowserTabManagerProtocol.swift @@ -7,6 +7,7 @@ protocol DAppBrowserTabsObserver: AnyObject { protocol DAppBrowserTabManagerProtocol { func retrieveTab(with id: UUID) -> CompoundOperationWrapper + func getAllTabs() -> CompoundOperationWrapper<[DAppBrowserTab]> func updateTab(_ tab: DAppBrowserTab) -> CompoundOperationWrapper @@ -18,10 +19,22 @@ protocol DAppBrowserTabManagerProtocol { func removeTab(with id: UUID) - func removeAll() + func removeAll(for metaIds: Set?) + + func removeAllWrapper(for metaIds: Set?) -> CompoundOperationWrapper> func addObserver( _ observer: DAppBrowserTabsObserver, sendOnSubscription: Bool ) } + +extension DAppBrowserTabManagerProtocol { + func removeAll() { + removeAll(for: nil) + } + + func removeAllWrapper() -> CompoundOperationWrapper> { + removeAllWrapper(for: nil) + } +} diff --git a/novawallet/Modules/WalletsList/Manage/WalletManageViewFactory.swift b/novawallet/Modules/WalletsList/Manage/WalletManageViewFactory.swift index 42347dec1..f46cb67e4 100644 --- a/novawallet/Modules/WalletsList/Manage/WalletManageViewFactory.swift +++ b/novawallet/Modules/WalletsList/Manage/WalletManageViewFactory.swift @@ -53,10 +53,15 @@ final class WalletManageViewFactory { sortDescriptors: [NSSortDescriptor.accountsByOrder] ) + let operationQueue = OperationManagerFacade.sharedDefaultQueue + + let walletStorageCleaner = WalletStorageCleanerFactory.createWalletStorageCleaner(using: operationQueue) + let walletUpdateMediator = WalletUpdateMediator( selectedWalletSettings: SelectedWalletSettings.shared, repository: repository, - operationQueue: OperationManagerFacade.sharedDefaultQueue + removedWalletsCleaner: walletStorageCleaner, + operationQueue: operationQueue ) return WalletManageInteractor( diff --git a/novawalletIntegrationTests/Proxy/ProxySyncIntegrationTests.swift b/novawalletIntegrationTests/Proxy/ProxySyncIntegrationTests.swift index 4b4c76a9a..f968616e9 100644 --- a/novawalletIntegrationTests/Proxy/ProxySyncIntegrationTests.swift +++ b/novawalletIntegrationTests/Proxy/ProxySyncIntegrationTests.swift @@ -33,9 +33,12 @@ final class ProxySyncIntegrationTests: XCTestCase { operationQueue.addOperations([saveWalletOperation], waitUntilFinished: true) + let walletStorageCleaner = WalletStorageCleanerFactory.createWalletStorageCleaner(using: operationQueue) + let walletUpdateMediator = WalletUpdateMediator( selectedWalletSettings: SelectedWalletSettings(storageFacade: userStorageFacade, operationQueue: operationQueue), repository: managedAccountRepository, + removedWalletsCleaner: walletStorageCleaner, operationQueue: operationQueue ) diff --git a/novawalletTests/Common/Services/CloudBackup/CloudBackupSyncTests.swift b/novawalletTests/Common/Services/CloudBackup/CloudBackupSyncTests.swift index d47c0e6a2..6bd985732 100644 --- a/novawalletTests/Common/Services/CloudBackup/CloudBackupSyncTests.swift +++ b/novawalletTests/Common/Services/CloudBackup/CloudBackupSyncTests.swift @@ -852,9 +852,15 @@ final class CloudBackupSyncTests: XCTestCase { sortDescriptors: [] ) + let walletStorageCleaner = WalletStorageCleanerFactory.createTestCleaner( + operationQueue: operationQueue, + storageFacade: storageFacade + ) + let walletsUpdater = WalletUpdateMediator( selectedWalletSettings: walletSettingsManager, repository: walletsRepository, + removedWalletsCleaner: walletStorageCleaner, operationQueue: operationQueue ) diff --git a/novawalletTests/Common/Storage/WalletUpdateMediatorTests.swift b/novawalletTests/Common/Storage/WalletUpdateMediatorTests.swift index b614aa7f2..d2eb06cfa 100644 --- a/novawalletTests/Common/Storage/WalletUpdateMediatorTests.swift +++ b/novawalletTests/Common/Storage/WalletUpdateMediatorTests.swift @@ -1,15 +1,17 @@ import XCTest @testable import novawallet import Operation_iOS +import Cuckoo final class WalletUpdateMediatorTests: XCTestCase { struct Common { let operationQueue: OperationQueue let selectedAccountSettings: SelectedWalletSettings let repository: AnyDataProviderRepository + let walletStorageCleaner: WalletStorageCleaning let walletUpdateMediator: WalletUpdateMediating - init() { + init(storageCleaner: WalletStorageCleaning? = nil) { operationQueue = OperationQueue() let facade = UserDataStorageTestFacade() @@ -21,9 +23,18 @@ final class WalletUpdateMediatorTests: XCTestCase { let mapper = ManagedMetaAccountMapper() let coreDataRepository = facade.createRepository(mapper: AnyCoreDataMapper(mapper)) repository = AnyDataProviderRepository(coreDataRepository) + walletStorageCleaner = if let storageCleaner { + storageCleaner + } else { + WalletStorageCleanerFactory.createTestCleaner( + operationQueue: operationQueue, + storageFacade: facade + ) + } walletUpdateMediator = WalletUpdateMediator( selectedWalletSettings: selectedAccountSettings, repository: repository, + removedWalletsCleaner: walletStorageCleaner, operationQueue: operationQueue ) } @@ -227,14 +238,6 @@ final class WalletUpdateMediatorTests: XCTestCase { XCTAssertTrue(common.selectedAccountSettings.value.identifier == selectedWallet.identifier) - // when - - let wrapper = common.walletUpdateMediator.saveChanges { - .init(newOrUpdatedItems: [], removedItems: [removedWallet]) - } - - common.operationQueue.addOperations(wrapper.allOperations, waitUntilFinished: true) - // then do { @@ -406,4 +409,45 @@ final class WalletUpdateMediatorTests: XCTestCase { XCTFail("Selected wallet expected") } } + + func testBrowserStateClearingCalledAndOtherOperationsCompleted() throws { + // given + + let storageCleaner = MockWalletStorageCleaning() + let common = Common(storageCleaner: storageCleaner) + + let wallets = (0..<10).map { index in + ManagedMetaAccountModel( + info: AccountGenerator.generateMetaAccount(generatingChainAccounts: 2), + isSelected: index == 0, + order: index + ) + } + + common.setup(with: wallets) + + let removedWallet = wallets[0] + + let walletStorageCleanerExpectation = XCTestExpectation() + + stub(storageCleaner) { stub in + when(stub).cleanStorage(for: any()).then { _ in + walletStorageCleanerExpectation.fulfill() + + return .createWithResult(()) + } + } + + // when + + let result = try common.update(with: [], remove: [removedWallet]) + + wait(for: [walletStorageCleanerExpectation], timeout: 5) + + // then + + XCTAssertTrue(result.isWalletSwitched) + XCTAssertTrue(result.selectedWallet != nil) + XCTAssertTrue(common.selectedAccountSettings.value.identifier != removedWallet.identifier) + } } diff --git a/novawalletTests/Helper/WalletStorageCleanerFactory.swift b/novawalletTests/Helper/WalletStorageCleanerFactory.swift new file mode 100644 index 000000000..258052f67 --- /dev/null +++ b/novawalletTests/Helper/WalletStorageCleanerFactory.swift @@ -0,0 +1,89 @@ +import Foundation +@testable import novawallet +import Operation_iOS + +extension WalletStorageCleanerFactory { + static func createTestCleaner( + operationQueue: OperationQueue, + storageFacade: UserDataStorageTestFacade + ) -> WalletStorageCleaning { + let browserStateCleaner = createBrowserStateCleaner( + operationQueue: operationQueue, + storageFacade: storageFacade + ) + let dAppSettingsCleaner = createDAppSettingsCleaner(storageFacade: storageFacade) + + let cleaners = [ + browserStateCleaner, + dAppSettingsCleaner + ] + + let mainCleaner = RemovedWalletStorageCleaner(cleanersCascade: cleaners) + + return mainCleaner + } + + private static func createBrowserStateCleaner( + operationQueue: OperationQueue, + storageFacade: StorageFacadeProtocol + ) -> WalletStorageCleaning { + let mapper = DAppBrowserTabMapper() + + let coreDataRepository = storageFacade.createRepository( + filter: nil, + sortDescriptors: [], + mapper: AnyCoreDataMapper(mapper) + ) + + let renderFilesRepository = WebViewRenderFilesOperationFactory( + repository: FileRepository(), + directoryPath: ApplicationConfig.shared.webPageRenderCachePath + ) + + let logger = Logger.shared + + let tabsSubscriptionFactory = PersistentTabLocalSubscriptionFactory( + storageFacade: storageFacade, + operationQueue: operationQueue, + logger: logger + ) + + let walletListLocalSubscriptionFactory = WalletListLocalSubscriptionFactory( + storageFacade: storageFacade, + operationManager: OperationManager(operationQueue: operationQueue), + logger: logger + ) + + let tabManager = DAppBrowserTabManager( + fileRepository: renderFilesRepository, + tabsSubscriptionFactory: tabsSubscriptionFactory, + walletListLocalSubscriptionFactory: walletListLocalSubscriptionFactory, + repository: AnyDataProviderRepository(coreDataRepository), + operationQueue: operationQueue, + logger: logger + ) + + let browserStateCleaner = WalletBrowserStateCleaner( + browserTabManager: tabManager, + webViewPoolEraser: WebViewPool.shared, + operationQueue: operationQueue + ) + + return browserStateCleaner + } + + private static func createDAppSettingsCleaner(storageFacade: StorageFacadeProtocol) -> WalletStorageCleaning { + let mapper = DAppSettingsMapper() + + let repository = storageFacade.createRepository( + filter: nil, + sortDescriptors: [], + mapper: AnyCoreDataMapper(mapper) + ) + let authorizedDAppRepository = AnyDataProviderRepository(repository) + + let dappSettingsCleaner = DAppSettingsCleaner(authorizedDAppRepository: authorizedDAppRepository) + + return dappSettingsCleaner + } +} diff --git a/novawalletTests/Mocks/ModuleMocks.swift b/novawalletTests/Mocks/ModuleMocks.swift index 05fd25eb8..16312479c 100644 --- a/novawalletTests/Mocks/ModuleMocks.swift +++ b/novawalletTests/Mocks/ModuleMocks.swift @@ -2193,6 +2193,105 @@ import SoraKeystore } +import Cuckoo +@testable import novawallet + +import Foundation +import Operation_iOS + + + class MockWalletStorageCleaning: WalletStorageCleaning, Cuckoo.ProtocolMock { + + typealias MocksType = WalletStorageCleaning + + typealias Stubbing = __StubbingProxy_WalletStorageCleaning + typealias Verification = __VerificationProxy_WalletStorageCleaning + + let cuckoo_manager = Cuckoo.MockManager.preconfiguredManager ?? Cuckoo.MockManager(hasParent: false) + + + private var __defaultImplStub: WalletStorageCleaning? + + func enableDefaultImplementation(_ stub: WalletStorageCleaning) { + __defaultImplStub = stub + cuckoo_manager.enableDefaultStubImplementation() + } + + + + + + + + + + func cleanStorage(for removedItems: @escaping () throws -> [MetaAccountModel]) -> CompoundOperationWrapper { + + return cuckoo_manager.call("cleanStorage(for: @escaping () throws -> [MetaAccountModel]) -> CompoundOperationWrapper", + parameters: (removedItems), + escapingParameters: (removedItems), + superclassCall: + + Cuckoo.MockManager.crashOnProtocolSuperclassCall() + , + defaultCall: __defaultImplStub!.cleanStorage(for: removedItems)) + + } + + + struct __StubbingProxy_WalletStorageCleaning: Cuckoo.StubbingProxy { + private let cuckoo_manager: Cuckoo.MockManager + + init(manager: Cuckoo.MockManager) { + self.cuckoo_manager = manager + } + + + func cleanStorage(for removedItems: M1) -> Cuckoo.ProtocolStubFunction<(() throws -> [MetaAccountModel]), CompoundOperationWrapper> where M1.MatchedType == () throws -> [MetaAccountModel] { + let matchers: [Cuckoo.ParameterMatcher<(() throws -> [MetaAccountModel])>] = [wrap(matchable: removedItems) { $0 }] + return .init(stub: cuckoo_manager.createStub(for: MockWalletStorageCleaning.self, method: "cleanStorage(for: @escaping () throws -> [MetaAccountModel]) -> CompoundOperationWrapper", parameterMatchers: matchers)) + } + + } + + struct __VerificationProxy_WalletStorageCleaning: Cuckoo.VerificationProxy { + private let cuckoo_manager: Cuckoo.MockManager + private let callMatcher: Cuckoo.CallMatcher + private let sourceLocation: Cuckoo.SourceLocation + + init(manager: Cuckoo.MockManager, callMatcher: Cuckoo.CallMatcher, sourceLocation: Cuckoo.SourceLocation) { + self.cuckoo_manager = manager + self.callMatcher = callMatcher + self.sourceLocation = sourceLocation + } + + + + + @discardableResult + func cleanStorage(for removedItems: M1) -> Cuckoo.__DoNotUse<(() throws -> [MetaAccountModel]), CompoundOperationWrapper> where M1.MatchedType == () throws -> [MetaAccountModel] { + let matchers: [Cuckoo.ParameterMatcher<(() throws -> [MetaAccountModel])>] = [wrap(matchable: removedItems) { $0 }] + return cuckoo_manager.verify("cleanStorage(for: @escaping () throws -> [MetaAccountModel]) -> CompoundOperationWrapper", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation) + } + + } +} + + class WalletStorageCleaningStub: WalletStorageCleaning { + + + + + + + + func cleanStorage(for removedItems: @escaping () throws -> [MetaAccountModel]) -> CompoundOperationWrapper { + return DefaultValueRegistry.defaultValue(for: (CompoundOperationWrapper).self) + } + +} + + import Cuckoo @testable import novawallet @@ -4884,6 +4983,21 @@ import Operation_iOS } + + + func willDismissInteractive(stateRender: DAppBrowserTabRenderProtocol) { + + return cuckoo_manager.call("willDismissInteractive(stateRender: DAppBrowserTabRenderProtocol)", + parameters: (stateRender), + escapingParameters: (stateRender), + superclassCall: + + Cuckoo.MockManager.crashOnProtocolSuperclassCall() + , + defaultCall: __defaultImplStub!.willDismissInteractive(stateRender: stateRender)) + + } + struct __StubbingProxy_DAppBrowserPresenterProtocol: Cuckoo.StubbingProxy { private let cuckoo_manager: Cuckoo.MockManager @@ -4943,6 +5057,11 @@ import Operation_iOS return .init(stub: cuckoo_manager.createStub(for: MockDAppBrowserPresenterProtocol.self, method: "showTabs(stateRender: DAppBrowserTabRenderProtocol)", parameterMatchers: matchers)) } + func willDismissInteractive(stateRender: M1) -> Cuckoo.ProtocolStubNoReturnFunction<(DAppBrowserTabRenderProtocol)> where M1.MatchedType == DAppBrowserTabRenderProtocol { + let matchers: [Cuckoo.ParameterMatcher<(DAppBrowserTabRenderProtocol)>] = [wrap(matchable: stateRender) { $0 }] + return .init(stub: cuckoo_manager.createStub(for: MockDAppBrowserPresenterProtocol.self, method: "willDismissInteractive(stateRender: DAppBrowserTabRenderProtocol)", parameterMatchers: matchers)) + } + } struct __VerificationProxy_DAppBrowserPresenterProtocol: Cuckoo.VerificationProxy { @@ -5019,6 +5138,12 @@ import Operation_iOS return cuckoo_manager.verify("showTabs(stateRender: DAppBrowserTabRenderProtocol)", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation) } + @discardableResult + func willDismissInteractive(stateRender: M1) -> Cuckoo.__DoNotUse<(DAppBrowserTabRenderProtocol), Void> where M1.MatchedType == DAppBrowserTabRenderProtocol { + let matchers: [Cuckoo.ParameterMatcher<(DAppBrowserTabRenderProtocol)>] = [wrap(matchable: stateRender) { $0 }] + return cuckoo_manager.verify("willDismissInteractive(stateRender: DAppBrowserTabRenderProtocol)", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation) + } + } } @@ -5088,6 +5213,12 @@ import Operation_iOS return DefaultValueRegistry.defaultValue(for: (Void).self) } + + + func willDismissInteractive(stateRender: DAppBrowserTabRenderProtocol) { + return DefaultValueRegistry.defaultValue(for: (Void).self) + } + }