[#682] Adopt removal of the Notification center on the SDK side (#687)

- secant is buildable again, notifications replaced by publishers
- tests WIP
- all unit tests fixed
- syntax of dependencies consolidated
- syntax of .send and .receive states consolidated
This commit is contained in:
Lukas Korba 2023-03-21 11:03:42 +01:00 committed by GitHub
parent c1847d4216
commit 702b71103b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 535 additions and 791 deletions

View File

@ -11,7 +11,6 @@
0D0781C9278776D20083ACD7 /* ZcashSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D0781C7278776D20083ACD7 /* ZcashSymbol.swift */; };
0D185819272723FF0046B928 /* ColoredChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D185818272723FF0046B928 /* ColoredChip.swift */; };
0D18581B272728D60046B928 /* PhraseChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D18581A272728D60046B928 /* PhraseChip.swift */; };
0D1C1AA327611EFD0004AF6A /* RecoveryPhraseDisplayReducerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1C1AA227611EFD0004AF6A /* RecoveryPhraseDisplayReducerTests.swift */; };
0D26103A298C3DCD00CC9DE9 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 0D261039298C3DCD00CC9DE9 /* FirebaseCrashlytics */; };
0D26103C298C3E4800CC9DE9 /* CrashReportingInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103B298C3E4800CC9DE9 /* CrashReportingInterface.swift */; };
0D26103E298C3FA600CC9DE9 /* CrashReporterLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103D298C3FA600CC9DE9 /* CrashReporterLiveKey.swift */; };
@ -30,7 +29,6 @@
0D26AEA6299E8196005260EE /* WalletEventsFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E6273B501F0021B49A /* WalletEventsFlowView.swift */; };
0D26AEA7299E8196005260EE /* CaptureDeviceLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBDF96B291ECED4000A1A05 /* CaptureDeviceLiveKey.swift */; };
0D26AEA8299E8196005260EE /* AudioServicesInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBDF965291ECDA2000A1A05 /* AudioServicesInterface.swift */; };
0D26AEA9299E8196005260EE /* NotificationCenterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863BC2923C704003D0F8B /* NotificationCenterTest.swift */; };
0D26AEAA299E8196005260EE /* CrashReporterLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103D298C3FA600CC9DE9 /* CrashReporterLiveKey.swift */; };
0D26AEAB299E8196005260EE /* RecoveryPhraseRandomizerLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863A529239DCB003D0F8B /* RecoveryPhraseRandomizerLiveKey.swift */; };
0D26AEAC299E8196005260EE /* TCATextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA079F27EDE18C00D6F09B /* TCATextField.swift */; };
@ -48,7 +46,6 @@
0D26AEBA299E8196005260EE /* AddressDetailsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB61F2874143800A02233 /* AddressDetailsStore.swift */; };
0D26AEBB299E8196005260EE /* RecoveryPhraseBackupSucceededView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DC487C22772574C00BE6A63 /* RecoveryPhraseBackupSucceededView.swift */; };
0D26AEBC299E8196005260EE /* TCATextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB1C5E727D77F6100BC43D7 /* TCATextFieldStore.swift */; };
0D26AEBD299E8196005260EE /* NotificationCenterInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF647282277BE00BA3F17 /* NotificationCenterInterface.swift */; };
0D26AEBE299E8196005260EE /* SecantTextStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D8A43C3272AEEDE005A6414 /* SecantTextStyles.swift */; };
0D26AEBF299E8196005260EE /* TransactionFailedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */; };
0D26AEC1299E8196005260EE /* Clamped.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DACFA7E27208CE00039EEA5 /* Clamped.swift */; };
@ -146,7 +143,6 @@
0D26AF22299E8196005260EE /* AudioServicesLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBDF963291ECDA2000A1A05 /* AudioServicesLiveKey.swift */; };
0D26AF23299E8196005260EE /* SendFlowStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B72740403600592F76 /* SendFlowStore.swift */; };
0D26AF24299E8196005260EE /* SecantApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0826B364170058B01E /* SecantApp.swift */; };
0D26AF25299E8196005260EE /* NotificationCenterLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863BA2923C6F8003D0F8B /* NotificationCenterLive.swift */; };
0D26AF26299E8196005260EE /* WalletStorageLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863992923935B003D0F8B /* WalletStorageLiveKey.swift */; };
0D26AF27299E8196005260EE /* WalletStorageInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863982923935B003D0F8B /* WalletStorageInterface.swift */; };
0D26AF28299E8196005260EE /* StandardButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */; };
@ -255,7 +251,6 @@
0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0826B364170058B01E /* SecantApp.swift */; };
0D4E7A0D26B364180058B01E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0C26B364180058B01E /* Assets.xcassets */; };
0D4E7A1026B364180058B01E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0F26B364180058B01E /* Preview Assets.xcassets */; };
0D4E7A1B26B364180058B01E /* secantTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A1A26B364180058B01E /* secantTests.swift */; };
0D535FDE271F4214009A9E3E /* Rubik-Italic-VariableFont_wght.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0D535FDC271F4214009A9E3E /* Rubik-Italic-VariableFont_wght.ttf */; };
0D535FDF271F4214009A9E3E /* Rubik-VariableFont_wght.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0D535FDD271F4214009A9E3E /* Rubik-VariableFont_wght.ttf */; };
0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D535FE1271F9476009A9E3E /* EnumeratedChip.swift */; };
@ -282,17 +277,14 @@
0DACFA9927209FA70039EEA5 /* Roboto-BlackItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8C27209FA70039EEA5 /* Roboto-BlackItalic.ttf */; };
0DACFA9A27209FA70039EEA5 /* Roboto-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8D27209FA70039EEA5 /* Roboto-Light.ttf */; };
0DACFA9C27209FA70039EEA5 /* Roboto-ThinItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8F27209FA70039EEA5 /* Roboto-ThinItalic.ttf */; };
0DB4E0B12881F2DB00947B78 /* WalletBalance+testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DB4E0B02881F2DB00947B78 /* WalletBalance+testing.swift */; };
0DB8AA81271DC7520035BC9D /* DesignGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DB8AA80271DC7520035BC9D /* DesignGuide.swift */; };
0DC487C32772574C00BE6A63 /* RecoveryPhraseBackupSucceededView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DC487C22772574C00BE6A63 /* RecoveryPhraseBackupSucceededView.swift */; };
0DDB6A5127737D4A0012A410 /* RecoveryPhraseBackupFailedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DDB6A5027737D4A0012A410 /* RecoveryPhraseBackupFailedView.swift */; };
0DF2DC51272344E400FA31E2 /* EmptyChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DF2DC50272344E400FA31E2 /* EmptyChip.swift */; };
0DF2DC5427235E3E00FA31E2 /* View+InnerShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DF2DC5327235E3E00FA31E2 /* View+InnerShadow.swift */; };
0DF482BA2787ADA800EB37D6 /* ConditionalModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DF482B92787ADA800EB37D6 /* ConditionalModifier.swift */; };
0DFE93DF272C6D4B000FCCA5 /* RecoveryPhraseBackupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93DE272C6D4B000FCCA5 /* RecoveryPhraseBackupTests.swift */; };
0DFE93E1272C9ECB000FCCA5 /* RecoveryPhraseBackupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93E0272C9ECB000FCCA5 /* RecoveryPhraseBackupView.swift */; };
0DFE93E3272CA1AA000FCCA5 /* RecoveryPhraseValidationFlowStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93E2272CA1AA000FCCA5 /* RecoveryPhraseValidationFlowStore.swift */; };
0DFE93E6272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93E5272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift */; };
2E35F99227B28E7600EB79CD /* SingleLineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E35F99127B28E7600EB79CD /* SingleLineTextField.swift */; };
2E35F99A27B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E35F99927B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift */; };
2E58E73B274679F000B2B84B /* OnboardingHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E58E73A274679F000B2B84B /* OnboardingHeaderView.swift */; };
@ -307,11 +299,8 @@
2EDA07A027EDE18C00D6F09B /* TCATextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA079F27EDE18C00D6F09B /* TCATextField.swift */; };
2EDA07A227EDE1AE00D6F09B /* TextFieldFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA07A127EDE1AE00D6F09B /* TextFieldFooter.swift */; };
2EDA07A427EDE2A900D6F09B /* DebugFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA07A327EDE2A900D6F09B /* DebugFrame.swift */; };
341B30BB29B78D1000697081 /* HomeFeatureFlagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341B30BA29B78D1000697081 /* HomeFeatureFlagTests.swift */; };
343CF3F629BB5A14009E44DF /* ZcashLightClientKit in Frameworks */ = {isa = PBXBuildFile; productRef = 343CF3F529BB5A14009E44DF /* ZcashLightClientKit */; };
34429C6E28E703CD00F2B929 /* TransactionSendingSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34429C6D28E703CD00F2B929 /* TransactionSendingSnapshotTests.swift */; };
3448CB3228E47666006ADEDB /* NotEnoughFreeSpaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3128E47666006ADEDB /* NotEnoughFreeSpaceView.swift */; };
3448CB3728E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3628E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift */; };
346715A528E2027D0035F7C4 /* CheckCircleStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346715A428E2027D0035F7C4 /* CheckCircleStore.swift */; };
3467319529AE265300974482 /* SupportDataGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3467319429AE265300974482 /* SupportDataGenerator.swift */; };
3467319629AE265300974482 /* SupportDataGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3467319429AE265300974482 /* SupportDataGenerator.swift */; };
@ -323,7 +312,6 @@
346731A029AE375000974482 /* SupportDataGeneratorTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3467319E29AE375000974482 /* SupportDataGeneratorTestKey.swift */; };
346731A229AE3A5100974482 /* UIMailDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346731A129AE3A5100974482 /* UIMailDialog.swift */; };
346731A329AE3A5100974482 /* UIMailDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346731A129AE3A5100974482 /* UIMailDialog.swift */; };
3469F18229ACD70500A07146 /* OnboardingFlowFeatureFlagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3469F18129ACD70500A07146 /* OnboardingFlowFeatureFlagTests.swift */; };
346D41E428DF0B8600963F36 /* CheckCircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346D41E328DF0B8600963F36 /* CheckCircle.swift */; };
34BF09092927C98000222134 /* Memo+toString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BF09082927C98000222134 /* Memo+toString.swift */; };
34C4329029B62D8D00F74045 /* L10n.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C4328F29B62D8D00F74045 /* L10n.swift */; };
@ -337,7 +325,6 @@
34DA414928E439CD00F8CC61 /* sendingTransaction.json in Resources */ = {isa = PBXBuildFile; fileRef = 34DA414828E439CD00F8CC61 /* sendingTransaction.json */; };
34E0AF1128DEE5220034CF37 /* Wedge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF1028DEE5220034CF37 /* Wedge.swift */; };
34E5F2F328E46DB700C17E5F /* DiskSpaceChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E5F2F228E46DB700C17E5F /* DiskSpaceChecker.swift */; };
34F039B329ABCE8500CF0053 /* WalletConfigProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F039B229ABCE8500CF0053 /* WalletConfigProviderTests.swift */; };
34F682E529A75EB60022C079 /* WalletConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682E429A75EB60022C079 /* WalletConfig.swift */; };
34F682E629A75EB60022C079 /* WalletConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682E429A75EB60022C079 /* WalletConfig.swift */; };
34F682EC29A763FD0022C079 /* WalletConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682EB29A763FD0022C079 /* WalletConfigProvider.swift */; };
@ -356,17 +343,13 @@
663FAB9C271D874D00E495F8 /* ActiveButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 663FAB9B271D874D00E495F8 /* ActiveButton.swift */; };
6654C73A2715A38000901167 /* ComposableArchitecture in Frameworks */ = {isa = PBXBuildFile; productRef = 6654C7392715A38000901167 /* ComposableArchitecture */; };
6654C73E2715A41300901167 /* OnboardingFlowStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6654C73D2715A41300901167 /* OnboardingFlowStore.swift */; };
6654C7442715A4AC00901167 /* OnboardingStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6654C7432715A4AC00901167 /* OnboardingStoreTests.swift */; };
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */; };
66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */; };
9E01F8282833CDA0000EFC57 /* ScanTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E01F8272833CDA0000EFC57 /* ScanTests.swift */; };
9E02B56A27FED43E005B809B /* FileManagerInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E02B56927FED43E005B809B /* FileManagerInterface.swift */; };
9E02B56C27FED475005B809B /* DatabaseFilesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E02B56B27FED475005B809B /* DatabaseFilesTests.swift */; };
9E0F5741297E7F1D005304FA /* TCALogging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F5740297E7F1C005304FA /* TCALogging.swift */; };
9E0F5743297EB96C005304FA /* TCALoggerReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F5742297EB96C005304FA /* TCALoggerReducer.swift */; };
9E0F5745297EBA1B005304FA /* LogStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F5744297EBA1B005304FA /* LogStore.swift */; };
9E0F5747297EE5F3005304FA /* WalletLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F5746297EE5F3005304FA /* WalletLogger.swift */; };
9E0F574B2980260D005304FA /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F574A2980260D005304FA /* LoggerTests.swift */; };
9E153A5F2920CE2700112F41 /* MnemonicInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E153A5E2920CD5100112F41 /* MnemonicInterface.swift */; };
9E153A602920CE2700112F41 /* MnemonicLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E153A5C2920CD5100112F41 /* MnemonicLiveKey.swift */; };
9E153A612920CE2700112F41 /* MnemonicMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E153A5B2920CD5100112F41 /* MnemonicMocks.swift */; };
@ -380,23 +363,65 @@
9E153A7529216EFB00112F41 /* UserDefaultsLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E153A7229216EFB00112F41 /* UserDefaultsLiveKey.swift */; };
9E153A7629216EFB00112F41 /* UserDefaultsInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E153A7329216EFB00112F41 /* UserDefaultsInterface.swift */; };
9E153A7729216EFB00112F41 /* UserDefaultsTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E153A7429216EFB00112F41 /* UserDefaultsTestKey.swift */; };
9E207C362966EC77003E2C9B /* AddressDetailsSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E207C352966EC77003E2C9B /* AddressDetailsSnapshotTests.swift */; };
9E207C392966EF87003E2C9B /* AddressDetailsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E207C382966EF87003E2C9B /* AddressDetailsTests.swift */; };
9E2AC0FF27D8EC120042AA47 /* MnemonicSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9E2AC0FE27D8EC120042AA47 /* MnemonicSwift */; };
9E2DF99C27CF704D00649636 /* ImportWalletStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99827CF704D00649636 /* ImportWalletStore.swift */; };
9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */; };
9E2DF99E27CF704D00649636 /* ImportWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99B27CF704D00649636 /* ImportWalletView.swift */; };
9E2E097B29ADEFDA00018C2A /* AppInitializationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E391131284644580073DD9A /* AppInitializationTests.swift */; };
9E2F1C842809B606004E65FE /* DebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2F1C832809B606004E65FE /* DebugMenu.swift */; };
9E2F1C8C280ED6A7004E65FE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9E2F1C8B280ED6A7004E65FE /* LaunchScreen.storyboard */; };
9E2F1C8F280EDE09004E65FE /* Drawer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2F1C8E280EDE09004E65FE /* Drawer.swift */; };
9E34519529C4A4BF00177D16 /* AddressDetailsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E207C382966EF87003E2C9B /* AddressDetailsTests.swift */; };
9E34519629C4A4D800177D16 /* secantUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A2526B364180058B01E /* secantUITests.swift */; };
9E34519729C4A51100177D16 /* RecoveryPhraseBackupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93DE272C6D4B000FCCA5 /* RecoveryPhraseBackupTests.swift */; };
9E34519829C4A51100177D16 /* RecoveryPhraseDisplayReducerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1C1AA227611EFD0004AF6A /* RecoveryPhraseDisplayReducerTests.swift */; };
9E34519929C4A52800177D16 /* secantTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A1A26B364180058B01E /* secantTests.swift */; };
9E34519A29C4A52F00177D16 /* BalanceBreakdownTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E94C61F28AA7DEE008256E9 /* BalanceBreakdownTests.swift */; };
9E34519B29C4A90700177D16 /* DeeplinkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAB4675285B5C7C002904A0 /* DeeplinkTests.swift */; };
9E34519C29C4A91A00177D16 /* HomeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911382848AD500073DD9A /* HomeTests.swift */; };
9E34519D29C8484D00177D16 /* HomeFeatureFlagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341B30BA29B78D1000697081 /* HomeFeatureFlagTests.swift */; };
9E34519E29C849B400177D16 /* WalletConfigProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F039B229ABCE8500CF0053 /* WalletConfigProviderTests.swift */; };
9E34519F29C849D300177D16 /* ImportWalletTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E391123283E4CAC0073DD9A /* ImportWalletTests.swift */; };
9E3451A029C84A2D00177D16 /* MultiLineTextFieldTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F02897F81B00A6796F /* MultiLineTextFieldTests.swift */; };
9E3451A129C84A4300177D16 /* OnboardingStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6654C7432715A4AC00901167 /* OnboardingStoreTests.swift */; };
9E3451A229C84A5300177D16 /* OnboardingFlowFeatureFlagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3469F18129ACD70500A07146 /* OnboardingFlowFeatureFlagTests.swift */; };
9E3451A329C84A6500177D16 /* ProfileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB6232874246800A02233 /* ProfileTests.swift */; };
9E3451A429C84B3E00177D16 /* RecoveryPhraseValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93E5272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift */; };
9E3451A529C84B3E00177D16 /* RecoveryPhraseValidationFlowFeatureFlagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E852D5B29AF8EB200CF4AC1 /* RecoveryPhraseValidationFlowFeatureFlagTests.swift */; };
9E3451A629C84B6600177D16 /* RootTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB812805793200199FC9 /* RootTests.swift */; };
9E3451A729C84E9900177D16 /* AppInitializationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E391131284644580073DD9A /* AppInitializationTests.swift */; };
9E3451A829C84EAF00177D16 /* DebugTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E852D6429B0A86300CF4AC1 /* DebugTests.swift */; };
9E3451A929C84EC000177D16 /* ScanTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E01F8272833CDA0000EFC57 /* ScanTests.swift */; };
9E3451AA29C84ED500177D16 /* CurrencySelectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDDEA9F2829610D00B4100C /* CurrencySelectionTests.swift */; };
9E3451AC29C84F0000177D16 /* TransactionAddressInputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDDEAA12829610D00B4100C /* TransactionAddressInputTests.swift */; };
9E3451AD29C84F0E00177D16 /* TransactionAmountInputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDDEAA02829610D00B4100C /* TransactionAmountInputTests.swift */; };
9E3451AE29C84F2800177D16 /* SendTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF643281FEC9900BA3F17 /* SendTests.swift */; };
9E3451AF29C855B200177D16 /* SensitiveDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E612C7829913F3600D09B09 /* SensitiveDataTests.swift */; };
9E3451B029C855E600177D16 /* SettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E66129D288938A300C75B70 /* SettingsTests.swift */; };
9E3451B129C8565500177D16 /* UserPreferencesStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135B27ECC25E0075AF48 /* UserPreferencesStorageTests.swift */; };
9E3451B229C8565500177D16 /* SecItemClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB852805A23100199FC9 /* SecItemClientTests.swift */; };
9E3451B329C8565500177D16 /* WalletBalance+testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DB4E0B02881F2DB00947B78 /* WalletBalance+testing.swift */; };
9E3451B429C8565500177D16 /* WalletStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */; };
9E3451B529C8565500177D16 /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F574A2980260D005304FA /* LoggerTests.swift */; };
9E3451B629C8565500177D16 /* ZatoshiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E39112D283F91600073DD9A /* ZatoshiTests.swift */; };
9E3451B729C8565500177D16 /* DatabaseFilesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E02B56B27FED475005B809B /* DatabaseFilesTests.swift */; };
9E3451B829C856E700177D16 /* WalletEventsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF63E2819542C00BA3F17 /* WalletEventsTests.swift */; };
9E3451B929C857C000177D16 /* AddressDetailsSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E207C352966EC77003E2C9B /* AddressDetailsSnapshotTests.swift */; };
9E3451BA29C857C500177D16 /* BalanceBreakdownSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E94C62228AA7EE0008256E9 /* BalanceBreakdownSnapshotTests.swift */; };
9E3451BB29C857C800177D16 /* HomeSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC8C28589E150099D5A2 /* HomeSnapshotTests.swift */; };
9E3451BC29C857C800177D16 /* NotEnoughFeeSpaceSnapshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3628E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift */; };
9E3451BD29C857CC00177D16 /* ImportWalletSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC9428589E150099D5A2 /* ImportWalletSnapshotTests.swift */; };
9E3451BE29C857CF00177D16 /* OnboardingSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC9628589E150099D5A2 /* OnboardingSnapshotTests.swift */; };
9E3451BF29C857D200177D16 /* ProfileSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB6262874269F00A02233 /* ProfileSnapshotTests.swift */; };
9E3451C029C857D400177D16 /* RecoveryPhraseDisplaySnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC9028589E150099D5A2 /* RecoveryPhraseDisplaySnapshotTests.swift */; };
9E3451C129C857D800177D16 /* RecoveryPhraseValidationFlowSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC9228589E150099D5A2 /* RecoveryPhraseValidationFlowSnapshotTests.swift */; };
9E3451C229C857DB00177D16 /* TransactionSendingSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34429C6D28E703CD00F2B929 /* TransactionSendingSnapshotTests.swift */; };
9E3451C329C857DD00177D16 /* SettingsSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F02889539300DF7F17 /* SettingsSnapshotTests.swift */; };
9E3451C429C857DF00177D16 /* View+UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E92AF0728530EBF007367AD /* View+UIImage.swift */; };
9E3451C529C857E400177D16 /* WalletEventsSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB6112869882D00A02233 /* WalletEventsSnapshotTests.swift */; };
9E3451C629C857E700177D16 /* WelcomeSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC8E28589E150099D5A2 /* WelcomeSnapshotTests.swift */; };
9E37A2B827C8F59F00AE57B3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9E37A2B727C8F59F00AE57B3 /* Localizable.strings */; };
9E391124283E4CAC0073DD9A /* ImportWalletTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E391123283E4CAC0073DD9A /* ImportWalletTests.swift */; };
9E39112E283F91600073DD9A /* ZatoshiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E39112D283F91600073DD9A /* ZatoshiTests.swift */; };
9E3911392848AD500073DD9A /* HomeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911382848AD500073DD9A /* HomeTests.swift */; };
9E39114A2848EEB90073DD9A /* UserPreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911442848EEB90073DD9A /* UserPreferencesStorage.swift */; };
9E39114C2848EEB90073DD9A /* DatabaseFiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911462848EEB90073DD9A /* DatabaseFiles.swift */; };
9E39115E284E3E350073DD9A /* secantUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A2526B364180058B01E /* secantUITests.swift */; };
9E486DE529B637AF003E6945 /* ImportBirthdayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E486DE429B637AF003E6945 /* ImportBirthdayView.swift */; };
9E486DE629B637AF003E6945 /* ImportBirthdayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E486DE429B637AF003E6945 /* ImportBirthdayView.swift */; };
9E486DF029B9EE84003E6945 /* KeyboardAdaptive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E486DEF29B9EE84003E6945 /* KeyboardAdaptive.swift */; };
@ -407,37 +432,27 @@
9E486DFA29BA09C2003E6945 /* UIKit+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E486DF829BA09C2003E6945 /* UIKit+Extensions.swift */; };
9E4AA4F829BF76BB00752BB3 /* About.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4AA4F729BF76BB00752BB3 /* About.swift */; };
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; };
9E5BF63F2819542C00BA3F17 /* WalletEventsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF63E2819542C00BA3F17 /* WalletEventsTests.swift */; };
9E5BF641281FD7B600BA3F17 /* TransactionFailedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */; };
9E5BF644281FEC9900BA3F17 /* SendTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF643281FEC9900BA3F17 /* SendTests.swift */; };
9E5BF648282277BE00BA3F17 /* NotificationCenterInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF647282277BE00BA3F17 /* NotificationCenterInterface.swift */; };
9E5BF64F2823E94900BA3F17 /* TransactionAddressTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF64D2823E94900BA3F17 /* TransactionAddressTextField.swift */; };
9E5BF6502823E94900BA3F17 /* TransactionAddressTextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF64E2823E94900BA3F17 /* TransactionAddressTextFieldStore.swift */; };
9E612C7229880E9200D09B09 /* LogsHandlerInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E612C7129880E9200D09B09 /* LogsHandlerInterface.swift */; };
9E612C7429880F2200D09B09 /* LogsHandlerLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E612C7329880F2200D09B09 /* LogsHandlerLive.swift */; };
9E612C7629880FC900D09B09 /* LogsHandlerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E612C7529880FC900D09B09 /* LogsHandlerTest.swift */; };
9E612C7929913F3600D09B09 /* SensitiveDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E612C7829913F3600D09B09 /* SensitiveDataTests.swift */; };
9E612C7E2991491200D09B09 /* SensitiveData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E612C7C2991476F00D09B09 /* SensitiveData.swift */; };
9E66122C2877188700C75B70 /* SyncStatusSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E66122B2877188700C75B70 /* SyncStatusSnapshot.swift */; };
9E6612312878337F00C75B70 /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 9E6612302878337F00C75B70 /* Lottie */; };
9E6612332878338C00C75B70 /* LottieAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6612322878338C00C75B70 /* LottieAnimation.swift */; };
9E6612362878345000C75B70 /* endlessCircleProgress.json in Resources */ = {isa = PBXBuildFile; fileRef = 9E6612352878345000C75B70 /* endlessCircleProgress.json */; };
9E66129E288938A300C75B70 /* SettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E66129D288938A300C75B70 /* SettingsTests.swift */; };
9E6713F12897F81B00A6796F /* MultiLineTextFieldTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F02897F81B00A6796F /* MultiLineTextFieldTests.swift */; };
9E6713F7289BC58C00A6796F /* BalanceBreakdownStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F6289BC58C00A6796F /* BalanceBreakdownStore.swift */; };
9E6713F8289BC58C00A6796F /* BalanceBreakdownView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F5289BC58C00A6796F /* BalanceBreakdownView.swift */; };
9E6713FA289BE0E100A6796F /* ClearBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F9289BE0E100A6796F /* ClearBackgroundView.swift */; };
9E69A24D27FB002800A55317 /* WelcomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E69A24C27FB002800A55317 /* WelcomeStore.swift */; };
9E7225F12889539300DF7F17 /* SettingsSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F02889539300DF7F17 /* SettingsSnapshotTests.swift */; };
9E7225F3288AB6DD00DF7F17 /* MultipleLineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F2288AB6DD00DF7F17 /* MultipleLineTextField.swift */; };
9E7225F6288AC71A00DF7F17 /* MultiLineTextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F5288AC71A00DF7F17 /* MultiLineTextFieldStore.swift */; };
9E7CB6122869882D00A02233 /* WalletEventsSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB6112869882D00A02233 /* WalletEventsSnapshotTests.swift */; };
9E7CB6152869E8C300A02233 /* CircularProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB6142869E8C300A02233 /* CircularProgress.swift */; };
9E7CB61A287310EC00A02233 /* QRCodeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB619287310EC00A02233 /* QRCodeGenerator.swift */; };
9E7CB6202874143800A02233 /* AddressDetailsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB61F2874143800A02233 /* AddressDetailsStore.swift */; };
9E7CB6212874143800A02233 /* AddressDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB61E2874143800A02233 /* AddressDetailsView.swift */; };
9E7CB6242874246800A02233 /* ProfileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB6232874246800A02233 /* ProfileTests.swift */; };
9E7CB6272874269F00A02233 /* ProfileSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB6262874269F00A02233 /* ProfileSnapshotTests.swift */; };
9E7FE0D3282D274E00C374E8 /* Date+Readable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0D2282D274E00C374E8 /* Date+Readable.swift */; };
9E7FE0D5282D281800C374E8 /* Array+Chunked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0D4282D281800C374E8 /* Array+Chunked.swift */; };
9E7FE0D7282D286500C374E8 /* RecoveryPhrase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0D6282D286500C374E8 /* RecoveryPhrase.swift */; };
@ -447,29 +462,15 @@
9E7FE0EC282E7D9400C374E8 /* TransactionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF63B2818305D00BA3F17 /* TransactionState.swift */; };
9E7FE0F628327F6F00C374E8 /* ScanUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0F528327F6F00C374E8 /* ScanUIView.swift */; };
9E7FE0F92832824C00C374E8 /* QRCodeScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0F82832824C00C374E8 /* QRCodeScanView.swift */; };
9E852D5C29AF8EB200CF4AC1 /* RecoveryPhraseValidationFlowFeatureFlagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E852D5B29AF8EB200CF4AC1 /* RecoveryPhraseValidationFlowFeatureFlagTests.swift */; };
9E852D6129B098F400CF4AC1 /* RootDebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E852D6029B098F400CF4AC1 /* RootDebug.swift */; };
9E852D6229B098F400CF4AC1 /* RootDebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E852D6029B098F400CF4AC1 /* RootDebug.swift */; };
9E852D6529B0A86300CF4AC1 /* DebugTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E852D6429B0A86300CF4AC1 /* DebugTests.swift */; };
9E92AF0828530EBF007367AD /* View+UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E92AF0728530EBF007367AD /* View+UIImage.swift */; };
9E94C62028AA7DEE008256E9 /* BalanceBreakdownTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E94C61F28AA7DEE008256E9 /* BalanceBreakdownTests.swift */; };
9E94C62328AA7EE0008256E9 /* BalanceBreakdownSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E94C62228AA7EE0008256E9 /* BalanceBreakdownSnapshotTests.swift */; };
9E9ADA7D2938F4C00071767B /* RootInitialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ADA7C2938F4C00071767B /* RootInitialization.swift */; };
9E9ADA7F2938F5EC0071767B /* RootDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ADA7E2938F5EC0071767B /* RootDestination.swift */; };
9E9ECC9728589E150099D5A2 /* HomeSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC8C28589E150099D5A2 /* HomeSnapshotTests.swift */; };
9E9ECC9828589E150099D5A2 /* WelcomeSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC8E28589E150099D5A2 /* WelcomeSnapshotTests.swift */; };
9E9ECC9928589E150099D5A2 /* RecoveryPhraseDisplaySnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC9028589E150099D5A2 /* RecoveryPhraseDisplaySnapshotTests.swift */; };
9E9ECC9A28589E150099D5A2 /* RecoveryPhraseValidationFlowSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC9228589E150099D5A2 /* RecoveryPhraseValidationFlowSnapshotTests.swift */; };
9E9ECC9B28589E150099D5A2 /* ImportWalletSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC9428589E150099D5A2 /* ImportWalletSnapshotTests.swift */; };
9E9ECC9C28589E150099D5A2 /* OnboardingSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC9628589E150099D5A2 /* OnboardingSnapshotTests.swift */; };
9EAB466D285A0468002904A0 /* Parsing in Frameworks */ = {isa = PBXBuildFile; productRef = 9EAB466C285A0468002904A0 /* Parsing */; };
9EAB4671285A1C77002904A0 /* Deeplink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAB4670285A1C77002904A0 /* Deeplink.swift */; };
9EAB4676285B5C7C002904A0 /* DeeplinkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAB4675285B5C7C002904A0 /* DeeplinkTests.swift */; };
9EAB46782860A1D2002904A0 /* WalletEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAB46772860A1D2002904A0 /* WalletEvent.swift */; };
9EAB467A2861EA6A002904A0 /* TransactionRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAB46792861EA6A002904A0 /* TransactionRowView.swift */; };
9EAFEB822805793200199FC9 /* RootTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB812805793200199FC9 /* RootTests.swift */; };
9EAFEB84280597B700199FC9 /* SecItemInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB83280597B700199FC9 /* SecItemInterface.swift */; };
9EAFEB862805A23100199FC9 /* SecItemClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB852805A23100199FC9 /* SecItemClientTests.swift */; };
9EAFEB882806E5AE00199FC9 /* SDKSynchronizerInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB872806E5AE00199FC9 /* SDKSynchronizerInterface.swift */; };
9EAFEB8F2808183D00199FC9 /* SandboxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB8D2808183D00199FC9 /* SandboxView.swift */; };
9EAFEB902808183D00199FC9 /* SandboxStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */; };
@ -492,8 +493,6 @@
9EB863A929239DCB003D0F8B /* RecoveryPhraseRandomizerInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863A629239DCB003D0F8B /* RecoveryPhraseRandomizerInterface.swift */; };
9EB863AA29239EB2003D0F8B /* RecoveryPhraseRandomizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911422848EEB90073DD9A /* RecoveryPhraseRandomizer.swift */; };
9EB863B92923C6D7003D0F8B /* FileManagerLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863B82923C6D7003D0F8B /* FileManagerLiveKey.swift */; };
9EB863BB2923C6F8003D0F8B /* NotificationCenterLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863BA2923C6F8003D0F8B /* NotificationCenterLive.swift */; };
9EB863BD2923C704003D0F8B /* NotificationCenterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863BC2923C704003D0F8B /* NotificationCenterTest.swift */; };
9EB863BF2923C72C003D0F8B /* SecItemLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863BE2923C72C003D0F8B /* SecItemLive.swift */; };
9EB863C12923C779003D0F8B /* URIParserLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C02923C779003D0F8B /* URIParserLive.swift */; };
9EB863C32923C807003D0F8B /* URIParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C22923C807003D0F8B /* URIParserTest.swift */; };
@ -530,11 +529,6 @@
9EBDF987291F91EF000A1A05 /* LocalAuthenticationTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBDF984291F91EF000A1A05 /* LocalAuthenticationTestKey.swift */; };
9EBDF989291F9428000A1A05 /* LocalAuthenticationMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBDF988291F9428000A1A05 /* LocalAuthenticationMocks.swift */; };
9EBEF87A27CE369800B4F343 /* RecoveryPhraseValidationFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBEF87927CE369800B4F343 /* RecoveryPhraseValidationFlowView.swift */; };
9EDDEAA22829610D00B4100C /* CurrencySelectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDDEA9F2829610D00B4100C /* CurrencySelectionTests.swift */; };
9EDDEAA32829610D00B4100C /* TransactionAmountInputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDDEAA02829610D00B4100C /* TransactionAmountInputTests.swift */; };
9EDDEAA42829610D00B4100C /* TransactionAddressInputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDDEAA12829610D00B4100C /* TransactionAddressInputTests.swift */; };
9EF8135C27ECC25E0075AF48 /* WalletStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */; };
9EF8135D27ECC25E0075AF48 /* UserPreferencesStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135B27ECC25E0075AF48 /* UserPreferencesStorageTests.swift */; };
9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135F27F043CC0075AF48 /* AppDelegate.swift */; };
9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8139B27F47AED0075AF48 /* InitializationState.swift */; };
F9322DC0273B555C00C105B5 /* NavigationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9322DBF273B555C00C105B5 /* NavigationLinks.swift */; };
@ -736,7 +730,6 @@
9E5BF63E2819542C00BA3F17 /* WalletEventsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletEventsTests.swift; sourceTree = "<group>"; };
9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionFailedView.swift; sourceTree = "<group>"; };
9E5BF643281FEC9900BA3F17 /* SendTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendTests.swift; sourceTree = "<group>"; };
9E5BF647282277BE00BA3F17 /* NotificationCenterInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationCenterInterface.swift; sourceTree = "<group>"; };
9E5BF64D2823E94900BA3F17 /* TransactionAddressTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionAddressTextField.swift; sourceTree = "<group>"; };
9E5BF64E2823E94900BA3F17 /* TransactionAddressTextFieldStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionAddressTextFieldStore.swift; sourceTree = "<group>"; };
9E612C7129880E9200D09B09 /* LogsHandlerInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogsHandlerInterface.swift; sourceTree = "<group>"; };
@ -810,8 +803,6 @@
9EB863A529239DCB003D0F8B /* RecoveryPhraseRandomizerLiveKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseRandomizerLiveKey.swift; sourceTree = "<group>"; };
9EB863A629239DCB003D0F8B /* RecoveryPhraseRandomizerInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseRandomizerInterface.swift; sourceTree = "<group>"; };
9EB863B82923C6D7003D0F8B /* FileManagerLiveKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManagerLiveKey.swift; sourceTree = "<group>"; };
9EB863BA2923C6F8003D0F8B /* NotificationCenterLive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationCenterLive.swift; sourceTree = "<group>"; };
9EB863BC2923C704003D0F8B /* NotificationCenterTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationCenterTest.swift; sourceTree = "<group>"; };
9EB863BE2923C72C003D0F8B /* SecItemLive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecItemLive.swift; sourceTree = "<group>"; };
9EB863C02923C779003D0F8B /* URIParserLive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URIParserLive.swift; sourceTree = "<group>"; };
9EB863C22923C807003D0F8B /* URIParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URIParserTest.swift; sourceTree = "<group>"; };
@ -1698,7 +1689,6 @@
9EBDF981291F91B1000A1A05 /* LocalAuthentication */,
9E612C7029880E6700D09B09 /* LogsHandler */,
9E153A5A2920CCE700112F41 /* Mnemonic */,
9EB863B42923C490003D0F8B /* NotificationCenter */,
9EB8638F2922D000003D0F8B /* NumberFormatter */,
9E153A6329210AF800112F41 /* Pasteboard */,
9EB863A329239D95003D0F8B /* RecoveryPhraseRandomizer */,
@ -1952,16 +1942,6 @@
path = SecItem;
sourceTree = "<group>";
};
9EB863B42923C490003D0F8B /* NotificationCenter */ = {
isa = PBXGroup;
children = (
9E5BF647282277BE00BA3F17 /* NotificationCenterInterface.swift */,
9EB863BA2923C6F8003D0F8B /* NotificationCenterLive.swift */,
9EB863BC2923C704003D0F8B /* NotificationCenterTest.swift */,
);
path = NotificationCenter;
sourceTree = "<group>";
};
9EB863B52923C4ED003D0F8B /* FileManager */ = {
isa = PBXGroup;
children = (
@ -2607,7 +2587,6 @@
0D26AEA7299E8196005260EE /* CaptureDeviceLiveKey.swift in Sources */,
3467319A29AE374300974482 /* SupportDataGeneratorInterface.swift in Sources */,
0D26AEA8299E8196005260EE /* AudioServicesInterface.swift in Sources */,
0D26AEA9299E8196005260EE /* NotificationCenterTest.swift in Sources */,
0D26AEAA299E8196005260EE /* CrashReporterLiveKey.swift in Sources */,
0D26AEAB299E8196005260EE /* RecoveryPhraseRandomizerLiveKey.swift in Sources */,
0D26AEAC299E8196005260EE /* TCATextField.swift in Sources */,
@ -2628,7 +2607,6 @@
0D26AEBA299E8196005260EE /* AddressDetailsStore.swift in Sources */,
0D26AEBB299E8196005260EE /* RecoveryPhraseBackupSucceededView.swift in Sources */,
0D26AEBC299E8196005260EE /* TCATextFieldStore.swift in Sources */,
0D26AEBD299E8196005260EE /* NotificationCenterInterface.swift in Sources */,
0D26AEBE299E8196005260EE /* SecantTextStyles.swift in Sources */,
0D26AEBF299E8196005260EE /* TransactionFailedView.swift in Sources */,
0D26AEC1299E8196005260EE /* Clamped.swift in Sources */,
@ -2740,7 +2718,6 @@
0D26AF22299E8196005260EE /* AudioServicesLiveKey.swift in Sources */,
0D26AF23299E8196005260EE /* SendFlowStore.swift in Sources */,
0D26AF24299E8196005260EE /* SecantApp.swift in Sources */,
0D26AF25299E8196005260EE /* NotificationCenterLive.swift in Sources */,
0D26AF26299E8196005260EE /* WalletStorageLiveKey.swift in Sources */,
0D26AF27299E8196005260EE /* WalletStorageInterface.swift in Sources */,
0D26AF28299E8196005260EE /* StandardButtonStyle.swift in Sources */,
@ -2835,7 +2812,6 @@
9EBDF96E291ECED4000A1A05 /* CaptureDeviceLiveKey.swift in Sources */,
3467319929AE374300974482 /* SupportDataGeneratorInterface.swift in Sources */,
9EBDF968291ECDA2000A1A05 /* AudioServicesInterface.swift in Sources */,
9EB863BD2923C704003D0F8B /* NotificationCenterTest.swift in Sources */,
0D26103E298C3FA600CC9DE9 /* CrashReporterLiveKey.swift in Sources */,
9EB863A829239DCB003D0F8B /* RecoveryPhraseRandomizerLiveKey.swift in Sources */,
2EDA07A027EDE18C00D6F09B /* TCATextField.swift in Sources */,
@ -2856,7 +2832,6 @@
9E7CB6202874143800A02233 /* AddressDetailsStore.swift in Sources */,
0DC487C32772574C00BE6A63 /* RecoveryPhraseBackupSucceededView.swift in Sources */,
2EB1C5E827D77F6100BC43D7 /* TCATextFieldStore.swift in Sources */,
9E5BF648282277BE00BA3F17 /* NotificationCenterInterface.swift in Sources */,
0D8A43C4272AEEDE005A6414 /* SecantTextStyles.swift in Sources */,
9E5BF641281FD7B600BA3F17 /* TransactionFailedView.swift in Sources */,
0DACFA7F27208CE00039EEA5 /* Clamped.swift in Sources */,
@ -2967,7 +2942,6 @@
9EBDF966291ECDA2000A1A05 /* AudioServicesLiveKey.swift in Sources */,
F9C165BF2740403600592F76 /* SendFlowStore.swift in Sources */,
0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */,
9EB863BB2923C6F8003D0F8B /* NotificationCenterLive.swift in Sources */,
9EB8639C2923935B003D0F8B /* WalletStorageLiveKey.swift in Sources */,
9EB8639B2923935B003D0F8B /* WalletStorageInterface.swift in Sources */,
66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */,
@ -3045,54 +3019,54 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9E7225F12889539300DF7F17 /* SettingsSnapshotTests.swift in Sources */,
3469F18229ACD70500A07146 /* OnboardingFlowFeatureFlagTests.swift in Sources */,
0DFE93DF272C6D4B000FCCA5 /* RecoveryPhraseBackupTests.swift in Sources */,
341B30BB29B78D1000697081 /* HomeFeatureFlagTests.swift in Sources */,
9EDDEAA22829610D00B4100C /* CurrencySelectionTests.swift in Sources */,
9E6713F12897F81B00A6796F /* MultiLineTextFieldTests.swift in Sources */,
9E01F8282833CDA0000EFC57 /* ScanTests.swift in Sources */,
9E66129E288938A300C75B70 /* SettingsTests.swift in Sources */,
9EDDEAA42829610D00B4100C /* TransactionAddressInputTests.swift in Sources */,
9E7CB6272874269F00A02233 /* ProfileSnapshotTests.swift in Sources */,
9E92AF0828530EBF007367AD /* View+UIImage.swift in Sources */,
34F039B329ABCE8500CF0053 /* WalletConfigProviderTests.swift in Sources */,
34429C6E28E703CD00F2B929 /* TransactionSendingSnapshotTests.swift in Sources */,
6654C7442715A4AC00901167 /* OnboardingStoreTests.swift in Sources */,
9E94C62328AA7EE0008256E9 /* BalanceBreakdownSnapshotTests.swift in Sources */,
9E39112E283F91600073DD9A /* ZatoshiTests.swift in Sources */,
9E9ECC9B28589E150099D5A2 /* ImportWalletSnapshotTests.swift in Sources */,
9EDDEAA32829610D00B4100C /* TransactionAmountInputTests.swift in Sources */,
9E7CB6242874246800A02233 /* ProfileTests.swift in Sources */,
9EAFEB862805A23100199FC9 /* SecItemClientTests.swift in Sources */,
3448CB3728E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift in Sources */,
9E9ECC9828589E150099D5A2 /* WelcomeSnapshotTests.swift in Sources */,
9E852D6529B0A86300CF4AC1 /* DebugTests.swift in Sources */,
9E7CB6122869882D00A02233 /* WalletEventsSnapshotTests.swift in Sources */,
9E5BF644281FEC9900BA3F17 /* SendTests.swift in Sources */,
9E852D5C29AF8EB200CF4AC1 /* RecoveryPhraseValidationFlowFeatureFlagTests.swift in Sources */,
0D1C1AA327611EFD0004AF6A /* RecoveryPhraseDisplayReducerTests.swift in Sources */,
9E9ECC9A28589E150099D5A2 /* RecoveryPhraseValidationFlowSnapshotTests.swift in Sources */,
9E0F574B2980260D005304FA /* LoggerTests.swift in Sources */,
9EAFEB822805793200199FC9 /* RootTests.swift in Sources */,
9E9ECC9928589E150099D5A2 /* RecoveryPhraseDisplaySnapshotTests.swift in Sources */,
9E391124283E4CAC0073DD9A /* ImportWalletTests.swift in Sources */,
9E5BF63F2819542C00BA3F17 /* WalletEventsTests.swift in Sources */,
0D4E7A1B26B364180058B01E /* secantTests.swift in Sources */,
0DFE93E6272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift in Sources */,
9EAB4676285B5C7C002904A0 /* DeeplinkTests.swift in Sources */,
9E207C362966EC77003E2C9B /* AddressDetailsSnapshotTests.swift in Sources */,
9E3911392848AD500073DD9A /* HomeTests.swift in Sources */,
9E9ECC9C28589E150099D5A2 /* OnboardingSnapshotTests.swift in Sources */,
9E2E097B29ADEFDA00018C2A /* AppInitializationTests.swift in Sources */,
9E9ECC9728589E150099D5A2 /* HomeSnapshotTests.swift in Sources */,
9E207C392966EF87003E2C9B /* AddressDetailsTests.swift in Sources */,
9EF8135C27ECC25E0075AF48 /* WalletStorageTests.swift in Sources */,
0DB4E0B12881F2DB00947B78 /* WalletBalance+testing.swift in Sources */,
9E02B56C27FED475005B809B /* DatabaseFilesTests.swift in Sources */,
9E612C7929913F3600D09B09 /* SensitiveDataTests.swift in Sources */,
9EF8135D27ECC25E0075AF48 /* UserPreferencesStorageTests.swift in Sources */,
9E94C62028AA7DEE008256E9 /* BalanceBreakdownTests.swift in Sources */,
9E3451B529C8565500177D16 /* LoggerTests.swift in Sources */,
9E3451C229C857DB00177D16 /* TransactionSendingSnapshotTests.swift in Sources */,
9E34519E29C849B400177D16 /* WalletConfigProviderTests.swift in Sources */,
9E3451C029C857D400177D16 /* RecoveryPhraseDisplaySnapshotTests.swift in Sources */,
9E3451B629C8565500177D16 /* ZatoshiTests.swift in Sources */,
9E3451B829C856E700177D16 /* WalletEventsTests.swift in Sources */,
9E3451BF29C857D200177D16 /* ProfileSnapshotTests.swift in Sources */,
9E34519529C4A4BF00177D16 /* AddressDetailsTests.swift in Sources */,
9E3451B929C857C000177D16 /* AddressDetailsSnapshotTests.swift in Sources */,
9E34519B29C4A90700177D16 /* DeeplinkTests.swift in Sources */,
9E3451BD29C857CC00177D16 /* ImportWalletSnapshotTests.swift in Sources */,
9E3451A329C84A6500177D16 /* ProfileTests.swift in Sources */,
9E3451B429C8565500177D16 /* WalletStorageTests.swift in Sources */,
9E34519929C4A52800177D16 /* secantTests.swift in Sources */,
9E3451C129C857D800177D16 /* RecoveryPhraseValidationFlowSnapshotTests.swift in Sources */,
9E3451A129C84A4300177D16 /* OnboardingStoreTests.swift in Sources */,
9E3451C429C857DF00177D16 /* View+UIImage.swift in Sources */,
9E34519729C4A51100177D16 /* RecoveryPhraseBackupTests.swift in Sources */,
9E3451BC29C857C800177D16 /* NotEnoughFeeSpaceSnapshots.swift in Sources */,
9E3451B229C8565500177D16 /* SecItemClientTests.swift in Sources */,
9E3451C629C857E700177D16 /* WelcomeSnapshotTests.swift in Sources */,
9E3451B329C8565500177D16 /* WalletBalance+testing.swift in Sources */,
9E3451AA29C84ED500177D16 /* CurrencySelectionTests.swift in Sources */,
9E3451C529C857E400177D16 /* WalletEventsSnapshotTests.swift in Sources */,
9E34519829C4A51100177D16 /* RecoveryPhraseDisplayReducerTests.swift in Sources */,
9E34519C29C4A91A00177D16 /* HomeTests.swift in Sources */,
9E3451BB29C857C800177D16 /* HomeSnapshotTests.swift in Sources */,
9E3451AF29C855B200177D16 /* SensitiveDataTests.swift in Sources */,
9E3451A729C84E9900177D16 /* AppInitializationTests.swift in Sources */,
9E3451B029C855E600177D16 /* SettingsTests.swift in Sources */,
9E34519F29C849D300177D16 /* ImportWalletTests.swift in Sources */,
9E3451A029C84A2D00177D16 /* MultiLineTextFieldTests.swift in Sources */,
9E3451B729C8565500177D16 /* DatabaseFilesTests.swift in Sources */,
9E3451B129C8565500177D16 /* UserPreferencesStorageTests.swift in Sources */,
9E3451BA29C857C500177D16 /* BalanceBreakdownSnapshotTests.swift in Sources */,
9E3451A529C84B3E00177D16 /* RecoveryPhraseValidationFlowFeatureFlagTests.swift in Sources */,
9E3451A629C84B6600177D16 /* RootTests.swift in Sources */,
9E3451BE29C857CF00177D16 /* OnboardingSnapshotTests.swift in Sources */,
9E3451AE29C84F2800177D16 /* SendTests.swift in Sources */,
9E34519A29C4A52F00177D16 /* BalanceBreakdownTests.swift in Sources */,
9E3451AD29C84F0E00177D16 /* TransactionAmountInputTests.swift in Sources */,
9E3451C329C857DD00177D16 /* SettingsSnapshotTests.swift in Sources */,
9E34519D29C8484D00177D16 /* HomeFeatureFlagTests.swift in Sources */,
9E3451A229C84A5300177D16 /* OnboardingFlowFeatureFlagTests.swift in Sources */,
9E3451AC29C84F0000177D16 /* TransactionAddressInputTests.swift in Sources */,
9E3451A429C84B3E00177D16 /* RecoveryPhraseValidationTests.swift in Sources */,
9E3451A929C84EC000177D16 /* ScanTests.swift in Sources */,
9E3451A829C84EAF00177D16 /* DebugTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3100,7 +3074,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9E39115E284E3E350073DD9A /* secantUITests.swift in Sources */,
9E34519629C4A4D800177D16 /* secantUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3304,7 +3278,7 @@
CURRENT_PROJECT_VERSION = 49;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "\"secant/Preview Content\"";
DEVELOPMENT_TEAM = RLPRR8CPQG;
DEVELOPMENT_TEAM = E7Q54GRN4K;
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = "secant/secant-testnet-Info.plist";
@ -3332,7 +3306,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 49;
DEVELOPMENT_ASSET_PATHS = "\"secant/Preview Content\"";
DEVELOPMENT_TEAM = RLPRR8CPQG;
DEVELOPMENT_TEAM = E7Q54GRN4K;
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = "secant/secant-testnet-Info.plist";
@ -3573,7 +3547,7 @@
repositoryURL = "https://github.com/zcash/ZcashLightClientKit.git";
requirement = {
kind = revision;
revision = b34ae033ae868f8abfa343a53ac6b0f2264047c8;
revision = c88fd684e8bea7f6c8c0ff799220a42361239af9;
};
};
6654C7382715A38000901167 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */ = {

View File

@ -338,7 +338,7 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash/ZcashLightClientKit.git",
"state" : {
"revision" : "b34ae033ae868f8abfa343a53ac6b0f2264047c8"
"revision" : "c88fd684e8bea7f6c8c0ff799220a42361239af9"
}
}
],

View File

@ -1,12 +0,0 @@
//
// NotificationCenter.swift
// secant-testnet
//
// Created by Lukáš Korba on 04.05.2022.
//
import Foundation
struct NotificationCenterClient {
let publisherFor: (Notification.Name) -> NotificationCenter.Publisher?
}

View File

@ -1,14 +0,0 @@
//
// NotificationCenterLive.swift
// secant-testnet
//
// Created by Lukáš Korba on 15.11.2022.
//
import Foundation
extension NotificationCenterClient {
static let live = NotificationCenterClient(
publisherFor: { NotificationCenter.default.publisher(for: $0) }
)
}

View File

@ -1,21 +0,0 @@
//
// NotificationCenterTest.swift
// secant-testnet
//
// Created by Lukáš Korba on 15.11.2022.
//
import ComposableArchitecture
import XCTestDynamicOverlay
extension NotificationCenterClient: TestDependencyKey {
static let testValue = Self(
publisherFor: XCTUnimplemented("\(Self.self).publisherFor", placeholder: nil)
)
}
extension NotificationCenterClient {
static let noOp = NotificationCenterClient(
publisherFor: { _ in nil }
)
}

View File

@ -17,23 +17,15 @@ extension DependencyValues {
}
}
enum SDKSynchronizerState: Equatable {
case progressUpdated
case started
case stopped
case synced
case unknown
}
struct SDKSynchronizerClient {
let stateChangedStream: () -> CurrentValueSubject<SDKSynchronizerState, Never>
let latestScannedSynchronizerState: () -> SDKSynchronizer.SynchronizerState?
let stateStream: () -> AnyPublisher<SynchronizerState, Never>
let eventStream: () -> AnyPublisher<SynchronizerEvent, Never>
let latestState: () -> SynchronizerState
let latestScannedHeight: () -> BlockHeight
let prepareWith: ([UInt8], UnifiedFullViewingKey, BlockHeight) throws -> Void
let start: (_ retry: Bool) throws -> Void
let stop: () -> Void
let statusSnapshot: () -> SyncStatusSnapshot
let isSyncing: () -> Bool
let isInitialized: () -> Bool

View File

@ -10,19 +10,13 @@ import Combine
import ComposableArchitecture
import ZcashLightClientKit
private class SDKSynchronizerLiveWrapper {
private var cancellables: [AnyCancellable] = []
let synchronizer: SDKSynchronizer
let stateChanged: CurrentValueSubject<SDKSynchronizerState, Never>
var latestScannedSynchronizerState: SDKSynchronizer.SynchronizerState?
extension SDKSynchronizerClient: DependencyKey {
static let liveValue: SDKSynchronizerClient = Self.live()
init(
notificationCenter: NotificationCenterClient = .live,
static func live(
databaseFiles: DatabaseFilesClient = .liveValue,
environment: ZcashSDKEnvironment = .liveValue
) {
self.stateChanged = CurrentValueSubject<SDKSynchronizerState, Never>(.unknown)
) -> Self {
let network = environment.network
let initializer = Initializer(
cacheDbURL: databaseFiles.cacheDbURLFor(network),
@ -36,80 +30,13 @@ private class SDKSynchronizerLiveWrapper {
saplingParamsSourceURL: SaplingParamsSourceURL.default,
loggerProxy: OSLogger(logLevel: .debug, category: LoggerConstants.sdkLogs)
)
synchronizer = SDKSynchronizer(initializer: initializer)
subscribeToNotifications(notificationCenter: notificationCenter)
}
deinit {
synchronizer.stop()
}
private func subscribeToNotifications(notificationCenter: NotificationCenterClient) {
notificationCenter.publisherFor(.synchronizerStarted)?
.receive(on: DispatchQueue.main)
.sink { [weak self] notif in
let synchronizerState = notif.userInfo?[SDKSynchronizer.NotificationKeys.synchronizerState] as? SDKSynchronizer.SynchronizerState
self?.synchronizerStarted(synchronizerState)
}
.store(in: &cancellables)
notificationCenter.publisherFor(.synchronizerSynced)?
.receive(on: DispatchQueue.main)
.sink { [weak self] output in
let synchronizerState = output.userInfo?[SDKSynchronizer.NotificationKeys.synchronizerState] as? SDKSynchronizer.SynchronizerState
self?.synchronizerSynced(synchronizerState)
}
.store(in: &cancellables)
notificationCenter.publisherFor(.synchronizerProgressUpdated)?
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in self?.synchronizerProgressUpdated() }
.store(in: &cancellables)
notificationCenter.publisherFor(.synchronizerStopped)?
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in self?.synchronizerStopped() }
.store(in: &cancellables)
}
private func synchronizerStarted(_ synchronizerState: SDKSynchronizer.SynchronizerState?) {
latestScannedSynchronizerState = synchronizerState
stateChanged.send(.started)
}
private func synchronizerSynced(_ synchronizerState: SDKSynchronizer.SynchronizerState?) {
latestScannedSynchronizerState = synchronizerState
stateChanged.send(.synced)
}
private func synchronizerProgressUpdated() {
stateChanged.send(.progressUpdated)
}
private func synchronizerStopped() {
stateChanged.send(.stopped)
}
}
extension SDKSynchronizerClient: DependencyKey {
static let liveValue: SDKSynchronizerClient = Self.live()
static func live(
notificationCenter: NotificationCenterClient = .live,
databaseFiles: DatabaseFilesClient = .liveValue,
environment: ZcashSDKEnvironment = .liveValue
) -> Self {
let sdkSynchronizerWrapper = SDKSynchronizerLiveWrapper(
notificationCenter: notificationCenter,
databaseFiles: databaseFiles,
environment: environment
)
let synchronizer = sdkSynchronizerWrapper.synchronizer
let synchronizer = SDKSynchronizer(initializer: initializer)
return SDKSynchronizerClient(
stateChangedStream: { sdkSynchronizerWrapper.stateChanged },
latestScannedSynchronizerState: { sdkSynchronizerWrapper.latestScannedSynchronizerState },
stateStream: { synchronizer.stateStream },
eventStream: { synchronizer.eventStream },
latestState: { synchronizer.latestState },
latestScannedHeight: { synchronizer.latestScannedHeight },
prepareWith: { seedBytes, viewingKey, walletBirtday in
let result = try synchronizer.prepare(with: seedBytes, viewingKeys: [viewingKey], walletBirthday: walletBirtday)
@ -120,12 +47,11 @@ extension SDKSynchronizerClient: DependencyKey {
},
start: { retry in try synchronizer.start(retry: retry) },
stop: { synchronizer.stop() },
statusSnapshot: { SyncStatusSnapshot.snapshotFor(state: synchronizer.status) },
isSyncing: { sdkSynchronizerWrapper.latestScannedSynchronizerState?.syncStatus.isSyncing ?? false },
isInitialized: { synchronizer.status != .unprepared },
isSyncing: { synchronizer.latestState.syncStatus.isSyncing },
isInitialized: { synchronizer.latestState.syncStatus != .unprepared },
rewind: { synchronizer.rewind($0) },
getShieldedBalance: { sdkSynchronizerWrapper.latestScannedSynchronizerState?.shieldedBalance },
getTransparentBalance: { sdkSynchronizerWrapper.latestScannedSynchronizerState?.transparentBalance },
getShieldedBalance: { synchronizer.latestState.shieldedBalance },
getTransparentBalance: { synchronizer.latestState.transparentBalance },
getAllSentTransactions: {
if let transactions = try? synchronizer.allSentTransactions() {
return EffectTask(value: transactions.map {

View File

@ -12,13 +12,13 @@ import ZcashLightClientKit
extension SDKSynchronizerClient: TestDependencyKey {
static let testValue = Self(
stateChangedStream: XCTUnimplemented("\(Self.self).stateChangedStream", placeholder: CurrentValueSubject(SDKSynchronizerState.unknown)),
latestScannedSynchronizerState: XCTUnimplemented("\(Self.self).latestScannedSynchronizerState", placeholder: .zero),
stateStream: XCTUnimplemented("\(Self.self).stateStream", placeholder: Empty().eraseToAnyPublisher()),
eventStream: XCTUnimplemented("\(Self.self).eventStream", placeholder: Empty().eraseToAnyPublisher()),
latestState: XCTUnimplemented("\(Self.self).latestState", placeholder: .zero),
latestScannedHeight: XCTUnimplemented("\(Self.self).latestScannedHeight", placeholder: 0),
prepareWith: XCTUnimplemented("\(Self.self).prepareWith"),
start: XCTUnimplemented("\(Self.self).start"),
stop: XCTUnimplemented("\(Self.self).stop"),
statusSnapshot: XCTUnimplemented("\(Self.self).statusSnapshot", placeholder: SyncStatusSnapshot.snapshotFor(state: .unprepared)),
isSyncing: XCTUnimplemented("\(Self.self).isSyncing", placeholder: false),
isInitialized: XCTUnimplemented("\(Self.self).isInitialized", placeholder: false),
rewind: XCTUnimplemented("\(Self.self).rewind", placeholder: Fail(error: "Error").eraseToAnyPublisher()),
@ -40,13 +40,13 @@ extension SDKSynchronizerClient: TestDependencyKey {
extension SDKSynchronizerClient {
static let noOp = Self(
stateChangedStream: { CurrentValueSubject<SDKSynchronizerState, Never>(.unknown) },
latestScannedSynchronizerState: { nil },
stateStream: { Empty().eraseToAnyPublisher() },
eventStream: { Empty().eraseToAnyPublisher() },
latestState: { .zero },
latestScannedHeight: { 0 },
prepareWith: { _, _, _ in },
start: { _ in },
stop: { },
statusSnapshot: { SyncStatusSnapshot.snapshotFor(state: .unprepared) },
isSyncing: { false },
isInitialized: { false },
rewind: { _ in return Empty<Void, Error>().eraseToAnyPublisher() },
@ -70,15 +70,13 @@ extension SDKSynchronizerClient {
extension SDKSynchronizerClient {
static func mocked(
stateChangedStream: @escaping () -> CurrentValueSubject<SDKSynchronizerState, Never> = {
CurrentValueSubject<SDKSynchronizerState, Never>(.synced)
},
latestScannedSynchronizerState: @escaping () -> SDKSynchronizer.SynchronizerState? = { nil },
stateStream: @escaping () -> AnyPublisher<SynchronizerState, Never> = { Just(.zero).eraseToAnyPublisher() },
eventStream: @escaping () -> AnyPublisher<SynchronizerEvent, Never> = { Empty().eraseToAnyPublisher() },
latestState: @escaping () -> SynchronizerState = { .zero },
latestScannedHeight: @escaping () -> BlockHeight = { 0 },
prepareWith: @escaping ([UInt8], UnifiedFullViewingKey, BlockHeight) throws -> Void = { _, _, _ in },
start: @escaping (_ retry: Bool) throws -> Void = { _ in },
stop: @escaping () -> Void = { },
statusSnapshot: @escaping () -> SyncStatusSnapshot = { SyncStatusSnapshot.snapshotFor(state: .unprepared) },
isSyncing: @escaping () -> Bool = { false },
isInitialized: @escaping () -> Bool = { false },
rewind: @escaping (RewindPolicy) -> AnyPublisher<Void, Error> = { _ in return Empty<Void, Error>().eraseToAnyPublisher() },
@ -298,13 +296,13 @@ extension SDKSynchronizerClient {
wipe: @escaping () -> AnyPublisher<Void, Error>? = { Fail(error: "Error").eraseToAnyPublisher() }
) -> SDKSynchronizerClient {
SDKSynchronizerClient(
stateChangedStream: stateChangedStream,
latestScannedSynchronizerState: latestScannedSynchronizerState,
stateStream: stateStream,
eventStream: eventStream,
latestState: latestState,
latestScannedHeight: latestScannedHeight,
prepareWith: prepareWith,
start: start,
stop: stop,
statusSnapshot: statusSnapshot,
isSyncing: isSyncing,
isInitialized: isInitialized,
rewind: rewind,

View File

@ -44,12 +44,12 @@ struct BalanceBreakdownReducer: ReducerProtocol {
case shieldFunds
case shieldFundsSuccess
case shieldFundsFailure(String)
case synchronizerStateChanged(SDKSynchronizerState)
case synchronizerStateChanged(SynchronizerState)
case updateLatestBlock
case updateSynchronizerStatus
}
@Dependency(\.derivationTool) var derivationTool
@Dependency(\.mainQueue) var mainQueue
@Dependency(\.mnemonic) var mnemonic
@Dependency(\.numberFormatter) var numberFormatter
@Dependency(\.sdkSynchronizer) var sdkSynchronizer
@ -68,7 +68,8 @@ struct BalanceBreakdownReducer: ReducerProtocol {
return .none
case .onAppear:
return sdkSynchronizer.stateChangedStream()
return sdkSynchronizer.stateStream()
.throttle(for: .seconds(0.2), scheduler: mainQueue, latest: true)
.map(BalanceBreakdownReducer.Action.synchronizerStateChanged)
.eraseToEffect()
.cancellable(id: CancelId.self, cancelInFlight: true)
@ -110,30 +111,15 @@ struct BalanceBreakdownReducer: ReducerProtocol {
)
return .none
case .synchronizerStateChanged(.synced):
return EffectTask(value: .updateSynchronizerStatus)
case .synchronizerStateChanged:
return EffectTask(value: .updateSynchronizerStatus)
case .updateSynchronizerStatus:
if let shieldedBalance = sdkSynchronizer.latestScannedSynchronizerState()?.shieldedBalance {
state.shieldedBalance = shieldedBalance.redacted
}
if let transparentBalance = sdkSynchronizer.latestScannedSynchronizerState()?.transparentBalance {
state.transparentBalance = transparentBalance.redacted
}
case .synchronizerStateChanged(let latestState):
state.shieldedBalance = latestState.shieldedBalance.redacted
state.transparentBalance = latestState.transparentBalance.redacted
return EffectTask(value: .updateLatestBlock)
case .updateLatestBlock:
guard
let latestBlockNumber = sdkSynchronizer.latestScannedSynchronizerState()?.latestScannedHeight,
let latestBlock = numberFormatter.string(NSDecimalNumber(value: latestBlockNumber))
else {
state.latestBlock = L10n.General.unknown
return .none
}
state.latestBlock = "\(latestBlock)"
let latestBlockNumber = sdkSynchronizer.latestScannedHeight()
let latestBlock = numberFormatter.string(NSDecimalNumber(value: latestBlockNumber))
state.latestBlock = "\(String(describing: latestBlock))"
return .none
}
}

View File

@ -70,10 +70,9 @@ struct HomeReducer: ReducerProtocol {
case profile(ProfileReducer.Action)
case send(SendFlowReducer.Action)
case settings(SettingsReducer.Action)
case synchronizerStateChanged(SDKSynchronizerState)
case synchronizerStateChanged(SynchronizerState)
case walletEvents(WalletEventsFlowReducer.Action)
case updateDestination(HomeReducer.State.Destination?)
case updateSynchronizerStatus
case showSynchronizerErrorAlert(SyncStatusSnapshot)
case retrySync
case updateWalletEvents([WalletEvent])
@ -112,7 +111,8 @@ struct HomeReducer: ReducerProtocol {
state.requiredTransactionConfirmations = zcashSDKEnvironment.requiredTransactionConfirmations
if diskSpaceChecker.hasEnoughFreeSpaceForSync() {
let syncEffect = sdkSynchronizer.stateChangedStream()
let syncEffect = sdkSynchronizer.stateStream()
.throttle(for: .seconds(0.2), scheduler: mainQueue, latest: true)
.map(HomeReducer.Action.synchronizerStateChanged)
.eraseToEffect()
.cancellable(id: CancelId.self, cancelInFlight: true)
@ -123,24 +123,19 @@ struct HomeReducer: ReducerProtocol {
case .onDisappear:
return .cancel(id: CancelId.self)
case .synchronizerStateChanged:
return EffectTask(value: .updateSynchronizerStatus)
case .updateWalletEvents:
return .none
case .updateSynchronizerStatus:
let snapshot = sdkSynchronizer.statusSnapshot()
case .synchronizerStateChanged(let latestState):
let snapshot = SyncStatusSnapshot.snapshotFor(state: latestState.syncStatus)
guard snapshot != state.synchronizerStatusSnapshot else {
return .none
}
state.synchronizerStatusSnapshot = snapshot
if let shieldedBalance = sdkSynchronizer.latestScannedSynchronizerState()?.shieldedBalance {
state.shieldedBalance = shieldedBalance.redacted
}
state.shieldedBalance = latestState.shieldedBalance.redacted
switch snapshot.syncStatus {
case .error:
@ -317,7 +312,7 @@ extension HomeStore {
settingsState: .placeholder,
shieldedBalance: Balance.zero,
synchronizerStatusSnapshot: .snapshotFor(
state: .error(SDKInitializationError.failed)
state: .error(SynchronizerError.syncFailed)
),
walletConfig: .default,
walletEventsState: .emptyPlaceHolder

View File

@ -77,7 +77,7 @@ extension RootReducer {
case .destination(.deeplink(let url)):
// get the latest synchronizer state
let synchronizerStatus = sdkSynchronizer.stateChangedStream().value
let synchronizerStatus = sdkSynchronizer.latestState().syncStatus
// process the deeplink only if app is initialized and synchronizer synced
guard state.appInitializationState == .initialized && synchronizerStatus == .synced else {

View File

@ -87,7 +87,7 @@ struct SendFlowReducer: ReducerProtocol {
case scan(ScanReducer.Action)
case sendPressed
case sendTransactionResult(Result<TransactionState, NSError>)
case synchronizerStateChanged(SDKSynchronizerState)
case synchronizerStateChanged(SynchronizerState)
case transactionAddressInput(TransactionAddressTextFieldReducer.Action)
case transactionAmountInput(TransactionAmountTextFieldReducer.Action)
case updateDestination(SendFlowReducer.State.Destination?)
@ -201,7 +201,8 @@ struct SendFlowReducer: ReducerProtocol {
case .onAppear:
state.memoState.charLimit = zcashSDKEnvironment.memoCharLimit
return sdkSynchronizer.stateChangedStream()
return sdkSynchronizer.stateStream()
.throttle(for: .seconds(0.2), scheduler: mainQueue, latest: true)
.map(SendFlowReducer.Action.synchronizerStateChanged)
.eraseToEffect()
.cancellable(id: SyncStatusUpdatesID.self, cancelInFlight: true)
@ -209,14 +210,10 @@ struct SendFlowReducer: ReducerProtocol {
case .onDisappear:
return .cancel(id: SyncStatusUpdatesID.self)
case .synchronizerStateChanged(.synced):
if let shieldedBalance = sdkSynchronizer.latestScannedSynchronizerState()?.shieldedBalance {
state.shieldedBalance = shieldedBalance.redacted
state.transactionAmountInputState.maxValue = shieldedBalance.total.amount.redacted
}
return .none
case .synchronizerStateChanged:
case .synchronizerStateChanged(let latestState):
let shieldedBalance = latestState.shieldedBalance
state.shieldedBalance = shieldedBalance.redacted
state.transactionAmountInputState.maxValue = shieldedBalance.total.amount.redacted
return .none
case .memo:

View File

@ -33,7 +33,7 @@ struct WalletEventsFlowReducer: ReducerProtocol {
case openBlockExplorer(URL?)
case updateDestination(WalletEventsFlowReducer.State.Destination?)
case replyTo(RedactableString)
case synchronizerStateChanged(SDKSynchronizerState)
case synchronizerStateChanged(SyncStatus)
case updateWalletEvents([WalletEvent])
case warnBeforeLeavingApp(URL?)
}
@ -48,8 +48,9 @@ struct WalletEventsFlowReducer: ReducerProtocol {
switch action {
case .onAppear:
state.requiredTransactionConfirmations = zcashSDKEnvironment.requiredTransactionConfirmations
return sdkSynchronizer.stateChangedStream()
.map(WalletEventsFlowReducer.Action.synchronizerStateChanged)
return sdkSynchronizer.stateStream()
.throttle(for: .seconds(0.2), scheduler: mainQueue, latest: true)
.map { WalletEventsFlowReducer.Action.synchronizerStateChanged($0.syncStatus) }
.eraseToEffect()
.cancellable(id: CancelId.self, cancelInFlight: true)

View File

@ -10,12 +10,10 @@ import ZcashLightClientKit
struct SyncStatusSnapshot: Equatable {
let message: String
let progress: Float
let syncStatus: SyncStatus
init(_ syncStatus: SyncStatus = .unprepared, _ message: String = "", _ progress: Float = 0) {
init(_ syncStatus: SyncStatus = .unprepared, _ message: String = "") {
self.message = message
self.progress = progress
self.syncStatus = syncStatus
}

View File

@ -21,9 +21,9 @@ class AddressDetailsTests: XCTestCase {
let store = TestStore(
initialState: AddressDetailsReducer.State(uAddress: uAddress),
reducer: AddressDetailsReducer()
) {
$0.pasteboard = testPasteboard
}
)
store.dependencies.pasteboard = testPasteboard
store.send(.copySaplingAddressToPastboard)
@ -43,9 +43,9 @@ class AddressDetailsTests: XCTestCase {
let store = TestStore(
initialState: AddressDetailsReducer.State(uAddress: uAddress),
reducer: AddressDetailsReducer()
) {
$0.pasteboard = testPasteboard
}
)
store.dependencies.pasteboard = testPasteboard
store.send(.copyTransparentAddressToPastboard)
@ -65,9 +65,9 @@ class AddressDetailsTests: XCTestCase {
let store = TestStore(
initialState: AddressDetailsReducer.State(uAddress: uAddress),
reducer: AddressDetailsReducer()
) {
$0.pasteboard = testPasteboard
}
)
store.dependencies.pasteboard = testPasteboard
store.send(.copyUnifiedAddressToPastboard)

View File

@ -16,13 +16,13 @@ class RecoveryPhraseDisplayReducerTests: XCTestCase {
let store = TestStore(
initialState: RecoveryPhraseDisplayStore.test,
reducer: RecoveryPhraseDisplayReducer()
) {
$0.pasteboard = testPasteboard
}
)
store.send(.copyToBufferPressed) {
$0.phrase = .placeholder
$0.showCopyToBufferAlert = true
store.dependencies.pasteboard = testPasteboard
store.send(.copyToBufferPressed) { state in
state.phrase = .placeholder
state.showCopyToBufferAlert = true
}
XCTAssertEqual(
@ -37,9 +37,9 @@ class RecoveryPhraseDisplayReducerTests: XCTestCase {
reducer: RecoveryPhraseDisplayReducer()
)
store.send(.phraseResponse(.placeholder)) {
$0.phrase = .placeholder
$0.showCopyToBufferAlert = false
store.send(.phraseResponse(.placeholder)) { state in
state.phrase = .placeholder
state.showCopyToBufferAlert = false
}
}
}

View File

@ -9,6 +9,7 @@ import XCTest
@testable import secant_testnet
import ComposableArchitecture
import ZcashLightClientKit
import Combine
class BalanceBreakdownTests: XCTestCase {
func testOnAppear() throws {
@ -16,15 +17,18 @@ class BalanceBreakdownTests: XCTestCase {
initialState: .placeholder,
reducer: BalanceBreakdownReducer()
)
store.dependencies.sdkSynchronizer = .noOp
store.dependencies.sdkSynchronizer = .mocked()
store.dependencies.mainQueue = .immediate
store.dependencies.numberFormatter = .noOp
store.send(.onAppear)
// expected side effects as a result of .onAppear registration
store.receive(.synchronizerStateChanged(.unknown))
store.receive(.updateSynchronizerStatus)
store.receive(.updateLatestBlock)
store.receive(.synchronizerStateChanged(.zero))
store.receive(.updateLatestBlock) { state in
state.latestBlock = "nil"
}
// long-living (cancelable) effects need to be properly canceled.
// the .onDisappear action cancels the observer of the synchronizer status change.
@ -109,8 +113,8 @@ class BalanceBreakdownTests: XCTestCase {
shieldingFunds: false,
transparentBalance: Balance(
WalletBalance(
verified: 1_000_000,
total: 1_000_000
verified: Zatoshi(1_000_000),
total: Zatoshi(1_000_000)
)
)
),
@ -131,8 +135,8 @@ class BalanceBreakdownTests: XCTestCase {
shieldingFunds: true,
transparentBalance: Balance(
WalletBalance(
verified: 1_000_000,
total: 1_000_000
verified: Zatoshi(1_000_000),
total: Zatoshi(1_000_000)
)
)
),

View File

@ -89,7 +89,11 @@ class DeeplinkTests: XCTestCase {
resolveDeeplinkURL: { _, _ in Deeplink.Destination.home }
)
store.dependencies.sdkSynchronizer = SDKSynchronizerClient.mocked(
stateChangedStream: { CurrentValueSubject<SDKSynchronizerState, Never>(.synced) }
latestState: {
var state = SynchronizerState.zero
state.syncStatus = .synced
return state
}
)
store.dependencies.walletConfigProvider = .noOp
@ -124,14 +128,18 @@ class DeeplinkTests: XCTestCase {
let store = TestStore(
initialState: appState,
reducer: RootReducer()
) { dependencies in
dependencies.deeplink = DeeplinkClient(
resolveDeeplinkURL: { _, _ in Deeplink.Destination.send(amount: 123_000_000, address: "address", memo: "some text") }
)
dependencies.sdkSynchronizer = SDKSynchronizerClient.mocked(
stateChangedStream: { CurrentValueSubject<SDKSynchronizerState, Never>(.synced) }
)
}
)
store.dependencies.deeplink = DeeplinkClient(
resolveDeeplinkURL: { _, _ in Deeplink.Destination.send(amount: 123_000_000, address: "address", memo: "some text") }
)
store.dependencies.sdkSynchronizer = SDKSynchronizerClient.mocked(
latestState: {
var state = SynchronizerState.zero
state.syncStatus = .synced
return state
}
)
guard let url = URL(string: "zcash:///home/send?address=address&memo=some%20text&amount=123000000") else {
return XCTFail("Deeplink: 'testDeeplinkRequest_sendURL_amount' URL is expected to be valid.")

View File

@ -12,45 +12,7 @@ import ComposableArchitecture
@testable import ZcashLightClientKit
class HomeTests: XCTestCase {
func testSynchronizerStateChanged_AnyButSynced() throws {
let store = TestStore(
initialState: .placeholder,
reducer: HomeReducer()
)
store.dependencies.sdkSynchronizer = .mocked(
stateChangedStream: { CurrentValueSubject<SDKSynchronizerState, Never>(.progressUpdated) },
statusSnapshot: { .default }
)
store.send(.synchronizerStateChanged(.progressUpdated))
store.receive(.updateSynchronizerStatus)
}
/// When the synchronizer status change to .synced, the .updateSynchronizerStatus is called
func testSynchronizerStateChanged_Synced() throws {
// setup the store and environment to be fully mocked
let testScheduler = DispatchQueue.test
let store = TestStore(
initialState: .placeholder,
reducer: HomeReducer()
) { dependencies in
dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
dependencies.sdkSynchronizer = SDKSynchronizerClient.mocked(statusSnapshot: { .default })
}
store.send(.synchronizerStateChanged(.synced))
testScheduler.advance(by: 0.01)
store.receive(.updateSynchronizerStatus)
}
func testSendButtonIsDisabledWhenSyncing() {
let testScheduler = DispatchQueue.test
let mockSnapshot = SyncStatusSnapshot.init(
.syncing(
.init(
@ -76,65 +38,10 @@ class HomeTests: XCTestCase {
reducer: HomeReducer()
)
store.dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
store.dependencies.sdkSynchronizer = SDKSynchronizerClient.mocked(statusSnapshot: { mockSnapshot })
store.send(.synchronizerStateChanged(.progressUpdated))
testScheduler.advance(by: 0.01)
store.receive(.updateSynchronizerStatus)
XCTAssertTrue(store.state.isSyncing)
XCTAssertTrue(store.state.isSendButtonDisabled)
}
func testSendButtonIsNotDisabledWhenSyncingWhileOnSendScreen() {
let testScheduler = DispatchQueue.test
let mockSnapshot = SyncStatusSnapshot.init(
.syncing(
.init(
startHeight: 1_700_000,
targetHeight: 1_800_000,
progressHeight: 1_770_000
)
)
)
let store = TestStore(
initialState: .init(
balanceBreakdownState: .placeholder,
profileState: .placeholder,
scanState: .placeholder,
sendState: .placeholder,
settingsState: .placeholder,
shieldedBalance: Balance.zero,
synchronizerStatusSnapshot: mockSnapshot,
walletConfig: .default,
walletEventsState: .emptyPlaceHolder
),
reducer: HomeReducer()
)
store.dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
store.dependencies.sdkSynchronizer = SDKSynchronizerClient.mocked(statusSnapshot: { mockSnapshot })
store.send(.updateDestination(.send)) {
$0.destination = .send
}
testScheduler.advance(by: 0.01)
store.send(.synchronizerStateChanged(.progressUpdated))
testScheduler.advance(by: 0.01)
store.receive(.updateSynchronizerStatus)
XCTAssertTrue(store.state.isSyncing)
XCTAssertFalse(store.state.isSendButtonDisabled)
}
/// The .onAppear action is important to register for the synchronizer state updates.
/// The integration tests make sure registrations and side effects are properly implemented.
func testOnAppear() throws {
@ -143,20 +50,19 @@ class HomeTests: XCTestCase {
reducer: HomeReducer()
)
store.dependencies.mainQueue = .immediate
store.dependencies.diskSpaceChecker = .mockEmptyDisk
store.dependencies.sdkSynchronizer = .mocked(
stateChangedStream: { CurrentValueSubject<SDKSynchronizerState, Never>(.unknown) },
statusSnapshot: { .default }
)
store.dependencies.sdkSynchronizer = .mocked()
store.send(.onAppear) { state in
state.requiredTransactionConfirmations = 10
}
// expected side effects as a result of .onAppear registration
store.receive(.updateDestination(nil))
store.receive(.synchronizerStateChanged(.unknown))
store.receive(.updateSynchronizerStatus)
store.receive(.synchronizerStateChanged(.zero)) { state in
state.synchronizerStatusSnapshot = SyncStatusSnapshot.snapshotFor(state: .unprepared)
}
// long-living (cancelable) effects need to be properly canceled.
// the .onDisappear action cancels the observer of the synchronizer status change.
@ -167,10 +73,10 @@ class HomeTests: XCTestCase {
let store = TestStore(
initialState: .placeholder,
reducer: HomeReducer()
) {
$0.diskSpaceChecker = .mockFullDisk
}
)
store.dependencies.diskSpaceChecker = .mockFullDisk
store.send(.onAppear) { state in
state.requiredTransactionConfirmations = 10
}
@ -186,24 +92,25 @@ class HomeTests: XCTestCase {
}
func testSynchronizerErrorBringsUpAlert() {
let testError = SDKInitializationError.failed
let testError = SynchronizerError.syncFailed
let errorSnapshot = SyncStatusSnapshot.snapshotFor(
state: .error(testError)
)
var state = SynchronizerState.zero
state.syncStatus = .error(testError)
let store = TestStore(
initialState: .placeholder,
reducer: HomeReducer()
) {
$0.sdkSynchronizer = SDKSynchronizerClient.mocked(statusSnapshot: { errorSnapshot })
)
store.send(.synchronizerStateChanged(state)) { state in
state.synchronizerStatusSnapshot = errorSnapshot
}
store.send(.updateSynchronizerStatus) {
$0.synchronizerStatusSnapshot = errorSnapshot
}
store.receive(.showSynchronizerErrorAlert(errorSnapshot)) {
$0.alert = HomeStore.syncErrorAlert(with: errorSnapshot)
store.receive(.showSynchronizerErrorAlert(errorSnapshot)) { state in
state.alert = HomeStore.syncErrorAlert(with: errorSnapshot)
}
}
}

View File

@ -26,10 +26,10 @@ class ImportWalletTests: XCTestCase {
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer()
) { dependencies in
dependencies.mnemonic = .noOp
dependencies.mnemonic.isValid = { _ in throw "invalid mnemonic" }
}
)
store.dependencies.mnemonic = .noOp
store.dependencies.mnemonic.isValid = { _ in throw "invalid mnemonic" }
let seedPhrase = "one two three".redacted
store.send(.seedPhraseInputChanged(seedPhrase)) { state in
@ -43,10 +43,10 @@ class ImportWalletTests: XCTestCase {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
) { dependencies in
dependencies.mnemonic = .noOp
dependencies.mnemonic.isValid = { _ in throw "invalid mnemonic" }
}
)
store.dependencies.mnemonic = .noOp
store.dependencies.mnemonic.isValid = { _ in throw "invalid mnemonic" }
let seedPhrase = "a a a a a a a a a a a a a a a a a a a a a a a a".redacted
store.send(.seedPhraseInputChanged(seedPhrase)) { state in
@ -61,9 +61,9 @@ class ImportWalletTests: XCTestCase {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
) {
$0.mnemonic = .noOp
}
)
store.dependencies.mnemonic = .noOp
let seedPhrase =
"""
@ -142,10 +142,10 @@ class ImportWalletTests: XCTestCase {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
) { dependencies in
dependencies.mnemonic = .noOp
dependencies.mnemonic.isValid = { _ in throw "invalid mnemonic" }
}
)
store.dependencies.mnemonic = .noOp
store.dependencies.mnemonic.isValid = { _ in throw "invalid mnemonic" }
let birthday = "1700000".redacted
store.send(.birthdayInputChanged(birthday)) { state in
@ -170,10 +170,10 @@ class ImportWalletTests: XCTestCase {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
) { dependencies in
dependencies.mnemonic = .noOp
dependencies.mnemonic.isValid = { _ in throw "invalid mnemonic" }
}
)
store.dependencies.mnemonic = .noOp
store.dependencies.mnemonic.isValid = { _ in throw "invalid mnemonic" }
let birthday = "200000".redacted
store.send(.birthdayInputChanged(birthday)) { state in
@ -197,9 +197,9 @@ class ImportWalletTests: XCTestCase {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
) {
$0.mnemonic = .noOp
}
)
store.dependencies.mnemonic = .noOp
let birthday = "200000".redacted
store.send(.birthdayInputChanged(birthday)) { state in
@ -229,9 +229,9 @@ class ImportWalletTests: XCTestCase {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
) {
$0.mnemonic = .noOp
}
)
store.dependencies.mnemonic = .noOp
let birthday = "1700000".redacted
store.send(.birthdayInputChanged(birthday)) { state in
@ -262,9 +262,9 @@ class ImportWalletTests: XCTestCase {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
) {
$0.mnemonic = .noOp
}
)
store.dependencies.mnemonic = .noOp
let seedPhrase =
"""
@ -303,10 +303,10 @@ class ImportWalletTests: XCTestCase {
wordsCount: 24
),
reducer: ImportWalletReducer()
) { dependencies in
dependencies.mnemonic = .noOp
dependencies.walletStorage = .noOp
}
)
store.dependencies.mnemonic = .noOp
store.dependencies.walletStorage = .noOp
store.send(.restoreWallet) { state in
state.alert = AlertState(

View File

@ -19,34 +19,34 @@ class OnboardingStoreTests: XCTestCase {
reducer: OnboardingFlowReducer()
)
store.send(.next) {
$0.index += 1
store.send(.next) { state in
state.index += 1
XCTAssertFalse($0.isFinalStep)
XCTAssertFalse($0.isInitialStep)
XCTAssertEqual($0.currentStep, $0.steps[1])
XCTAssertEqual($0.offset, -20.0)
XCTAssertEqual($0.progress, 50)
XCTAssertFalse(state.isFinalStep)
XCTAssertFalse(state.isInitialStep)
XCTAssertEqual(state.currentStep, state.steps[1])
XCTAssertEqual(state.offset, -20.0)
XCTAssertEqual(state.progress, 50)
}
store.send(.next) {
$0.index += 1
store.send(.next) { state in
state.index += 1
XCTAssertFalse($0.isFinalStep)
XCTAssertFalse($0.isInitialStep)
XCTAssertEqual($0.currentStep, $0.steps[2])
XCTAssertEqual($0.offset, -40.0)
XCTAssertEqual($0.progress, 75)
XCTAssertFalse(state.isFinalStep)
XCTAssertFalse(state.isInitialStep)
XCTAssertEqual(state.currentStep, state.steps[2])
XCTAssertEqual(state.offset, -40.0)
XCTAssertEqual(state.progress, 75)
}
store.send(.next) {
$0.index += 1
store.send(.next) { state in
state.index += 1
XCTAssertTrue($0.isFinalStep)
XCTAssertFalse($0.isInitialStep)
XCTAssertEqual($0.currentStep, $0.steps[3])
XCTAssertEqual($0.offset, -60.0)
XCTAssertEqual($0.progress, 100)
XCTAssertTrue(state.isFinalStep)
XCTAssertFalse(state.isInitialStep)
XCTAssertEqual(state.currentStep, state.steps[3])
XCTAssertEqual(state.offset, -60.0)
XCTAssertEqual(state.progress, 100)
}
}
@ -74,24 +74,24 @@ class OnboardingStoreTests: XCTestCase {
reducer: OnboardingFlowReducer()
)
store.send(.back) {
$0.index -= 1
store.send(.back) { state in
state.index -= 1
XCTAssertFalse($0.isFinalStep)
XCTAssertFalse($0.isInitialStep)
XCTAssertEqual($0.currentStep, $0.steps[1])
XCTAssertEqual($0.offset, -20.0)
XCTAssertEqual($0.progress, 50)
XCTAssertFalse(state.isFinalStep)
XCTAssertFalse(state.isInitialStep)
XCTAssertEqual(state.currentStep, state.steps[1])
XCTAssertEqual(state.offset, -20.0)
XCTAssertEqual(state.progress, 50)
}
store.send(.back) {
$0.index -= 1
store.send(.back) { state in
state.index -= 1
XCTAssertFalse($0.isFinalStep)
XCTAssertTrue($0.isInitialStep)
XCTAssertEqual($0.currentStep, $0.steps[0])
XCTAssertEqual($0.offset, 0.0)
XCTAssertEqual($0.progress, 25)
XCTAssertFalse(state.isFinalStep)
XCTAssertTrue(state.isInitialStep)
XCTAssertEqual(state.currentStep, state.steps[0])
XCTAssertEqual(state.offset, 0.0)
XCTAssertEqual(state.progress, 25)
}
}
@ -120,26 +120,26 @@ class OnboardingStoreTests: XCTestCase {
reducer: OnboardingFlowReducer()
)
store.send(.skip) {
$0.index = $0.steps.count - 1
$0.skippedAtindex = initialIndex
store.send(.skip) { state in
state.index = state.steps.count - 1
state.skippedAtindex = initialIndex
XCTAssertTrue($0.isFinalStep)
XCTAssertFalse($0.isInitialStep)
XCTAssertEqual($0.currentStep, $0.steps[3])
XCTAssertEqual($0.offset, -60.0)
XCTAssertEqual($0.progress, 100)
XCTAssertTrue(state.isFinalStep)
XCTAssertFalse(state.isInitialStep)
XCTAssertEqual(state.currentStep, state.steps[3])
XCTAssertEqual(state.offset, -60.0)
XCTAssertEqual(state.progress, 100)
}
store.send(.back) {
$0.skippedAtindex = nil
$0.index = initialIndex
store.send(.back) { state in
state.skippedAtindex = nil
state.index = initialIndex
XCTAssertFalse($0.isFinalStep)
XCTAssertFalse($0.isInitialStep)
XCTAssertEqual($0.currentStep, $0.steps[1])
XCTAssertEqual($0.offset, -20.0)
XCTAssertEqual($0.progress, 50)
XCTAssertFalse(state.isFinalStep)
XCTAssertFalse(state.isInitialStep)
XCTAssertEqual(state.currentStep, state.steps[1])
XCTAssertEqual(state.offset, -20.0)
XCTAssertEqual(state.progress, 50)
}
}
}

View File

@ -18,10 +18,10 @@ class ProfileTests: XCTestCase {
let store = TestStore(
initialState: .placeholder,
reducer: ProfileReducer()
) { dependencies in
dependencies.appVersion = .mock
dependencies.sdkSynchronizer = SDKSynchronizerClient.mocked(statusSnapshot: { .default })
}
)
store.dependencies.appVersion = .mock
store.dependencies.sdkSynchronizer = .mocked()
let uAddress = try UnifiedAddress(
encoding: uAddressEncoding,
@ -45,9 +45,9 @@ class ProfileTests: XCTestCase {
addressDetailsState: AddressDetailsReducer.State(uAddress: uAddress)
),
reducer: ProfileReducer()
) {
$0.pasteboard = testPasteboard
}
)
store.dependencies.pasteboard = testPasteboard
store.send(.copyUnifiedAddressToPastboard)

View File

@ -90,11 +90,11 @@ class RecoveryPhraseValidationTests: XCTestCase {
let expectedValidationWords = [ValidationWord(groupIndex: 1, word: "salute".redacted)]
store.send(.move(wordChip: .unassigned(word: "salute".redacted), intoGroup: 1)) {
$0.validationWords = expectedValidationWords
$0.missingWordChips = expectedMissingChips
store.send(.move(wordChip: .unassigned(word: "salute".redacted), intoGroup: 1)) { state in
state.validationWords = expectedValidationWords
state.missingWordChips = expectedMissingChips
XCTAssertFalse($0.isComplete)
XCTAssertFalse(state.isComplete)
}
}
@ -144,11 +144,11 @@ class RecoveryPhraseValidationTests: XCTestCase {
let expectedValidationWords = [ValidationWord(groupIndex: 0, word: "pizza".redacted)]
store.send(.move(wordChip: missingWordChips[3], intoGroup: 0)) {
$0.missingWordChips = expectedMissingChips
$0.validationWords = expectedValidationWords
store.send(.move(wordChip: missingWordChips[3], intoGroup: 0)) { state in
state.missingWordChips = expectedMissingChips
state.validationWords = expectedValidationWords
XCTAssertFalse($0.isComplete)
XCTAssertFalse(state.isComplete)
}
}
@ -200,11 +200,11 @@ class RecoveryPhraseValidationTests: XCTestCase {
ValidationWord(groupIndex: 1, word: "boil".redacted)
]
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "boil".redacted), intoGroup: 1)) {
$0.missingWordChips = expectedMissingWordChips
$0.validationWords = expectedValidationWords
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "boil".redacted), intoGroup: 1)) { state in
state.missingWordChips = expectedMissingWordChips
state.validationWords = expectedValidationWords
XCTAssertFalse($0.isComplete)
XCTAssertFalse(state.isComplete)
}
}
@ -260,11 +260,11 @@ class RecoveryPhraseValidationTests: XCTestCase {
ValidationWord(groupIndex: 2, word: "cancel".redacted)
]
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "cancel".redacted), intoGroup: 2)) {
$0.missingWordChips = expectedMissingWordChips
$0.validationWords = expectedValidationWords
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "cancel".redacted), intoGroup: 2)) { state in
state.missingWordChips = expectedMissingWordChips
state.validationWords = expectedValidationWords
XCTAssertFalse($0.isComplete)
XCTAssertFalse(state.isComplete)
}
}
@ -306,9 +306,9 @@ class RecoveryPhraseValidationTests: XCTestCase {
let store = TestStore(
initialState: currentStep,
reducer: RecoveryPhraseValidationFlowReducer()
) {
$0.mainQueue = Self.testScheduler.eraseToAnyScheduler()
}
)
store.dependencies.mainQueue = Self.testScheduler.eraseToAnyScheduler()
let expectedMissingWordChips = [
PhraseChip.Kind.empty,
@ -324,19 +324,19 @@ class RecoveryPhraseValidationTests: XCTestCase {
ValidationWord(groupIndex: 3, word: "pizza".redacted)
]
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "pizza".redacted), intoGroup: 3)) {
$0.missingWordChips = expectedMissingWordChips
$0.validationWords = expectedValidationWords
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "pizza".redacted), intoGroup: 3)) { state in
state.missingWordChips = expectedMissingWordChips
state.validationWords = expectedValidationWords
XCTAssertTrue($0.isComplete)
XCTAssertTrue($0.isValid)
XCTAssertTrue(state.isComplete)
XCTAssertTrue(state.isValid)
}
Self.testScheduler.advance(by: 2)
store.receive(.succeed) {
XCTAssertTrue($0.isComplete)
$0.destination = .success
store.receive(.succeed) { state in
XCTAssertTrue(state.isComplete)
state.destination = .success
}
}
@ -378,10 +378,10 @@ class RecoveryPhraseValidationTests: XCTestCase {
let store = TestStore(
initialState: currentStep,
reducer: RecoveryPhraseValidationFlowReducer()
) { dependencies in
dependencies.feedbackGenerator = .noOp
dependencies.mainQueue = Self.testScheduler.eraseToAnyScheduler()
}
)
store.dependencies.feedbackGenerator = .noOp
store.dependencies.mainQueue = Self.testScheduler.eraseToAnyScheduler()
let expectedMissingWordChips = [
PhraseChip.Kind.empty,
@ -397,20 +397,20 @@ class RecoveryPhraseValidationTests: XCTestCase {
ValidationWord(groupIndex: 3, word: "pizza".redacted)
]
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "pizza".redacted), intoGroup: 3)) {
$0.missingWordChips = expectedMissingWordChips
$0.validationWords = expectedValidationWords
store.send(.move(wordChip: PhraseChip.Kind.unassigned(word: "pizza".redacted), intoGroup: 3)) { state in
state.missingWordChips = expectedMissingWordChips
state.validationWords = expectedValidationWords
XCTAssertTrue($0.isComplete)
XCTAssertTrue(state.isComplete)
}
Self.testScheduler.advance(by: 2)
store.receive(.failureFeedback)
store.receive(.fail) {
$0.destination = .failure
XCTAssertFalse($0.isValid)
store.receive(.fail) { state in
state.destination = .failure
XCTAssertFalse(state.isValid)
}
}

View File

@ -104,9 +104,9 @@ class RootTests: XCTestCase {
Self.testScheduler.advance(by: 3)
store.receive(.destination(.updateDestination(.onboarding))) {
$0.destinationState.destination = .onboarding
$0.appInitializationState = .uninitialized
store.receive(.destination(.updateDestination(.onboarding))) { state in
state.destinationState.destination = .onboarding
state.appInitializationState = .uninitialized
}
}
@ -132,10 +132,10 @@ class RootTests: XCTestCase {
let store = TestStore(
initialState: .placeholder,
reducer: RootReducer()
) { dependencies in
dependencies.walletStorage = .noOp
dependencies.walletStorage.exportWallet = { throw walletStorageError }
}
)
store.dependencies.walletStorage = .noOp
store.dependencies.walletStorage.exportWallet = { throw walletStorageError }
store.send(.initialization(.respondToWalletInitializationState(.filesMissing))) { state in
state.appInitializationState = .filesMissing
@ -165,10 +165,10 @@ class RootTests: XCTestCase {
let store = TestStore(
initialState: .placeholder,
reducer: RootReducer()
) { dependencies in
dependencies.walletStorage = .noOp
dependencies.walletStorage.exportWallet = { throw walletStorageError }
}
)
store.dependencies.walletStorage = .noOp
store.dependencies.walletStorage.exportWallet = { throw walletStorageError }
store.send(.initialization(.respondToWalletInitializationState(.initialized)))

View File

@ -21,9 +21,9 @@ class ScanTests: XCTestCase {
scanStatus: .value("t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po".redacted)
),
reducer: ScanReducer()
) {
$0.captureDevice = .noOp
}
)
store.dependencies.captureDevice = .noOp
store.send(.onAppear) { state in
state.isTorchAvailable = false
@ -37,9 +37,9 @@ class ScanTests: XCTestCase {
let store = TestStore(
initialState: ScanReducer.State(),
reducer: ScanReducer()
) {
$0.captureDevice = .noOp
}
)
store.dependencies.captureDevice = .noOp
store.send(.torchPressed) { state in
state.isTorchOn = true
@ -52,9 +52,9 @@ class ScanTests: XCTestCase {
isTorchOn: true
),
reducer: ScanReducer()
) {
$0.captureDevice = .noOp
}
)
store.dependencies.captureDevice = .noOp
store.send(.torchPressed) { state in
state.isTorchOn = false
@ -65,9 +65,9 @@ class ScanTests: XCTestCase {
let store = TestStore(
initialState: ScanReducer.State(),
reducer: ScanReducer()
) {
$0.uriParser.isValidURI = { _ in false }
}
)
store.dependencies.uriParser.isValidURI = { _ in false }
let value = "test".redacted
store.send(.scan(value)) { state in
@ -82,10 +82,11 @@ class ScanTests: XCTestCase {
let store = TestStore(
initialState: ScanReducer.State(),
reducer: ScanReducer()
) { dependencies in
dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
dependencies.uriParser.isValidURI = { _ in true }
}
)
store.dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
store.dependencies.uriParser.isValidURI = { _ in true }
let address = "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po".redacted
store.send(.scan(address)) { state in

View File

@ -14,12 +14,12 @@ import ZcashLightClientKit
class SendTests: XCTestCase {
var storage = WalletStorage(secItem: .live)
let usNumberFormatter = NumberFormatter()
override func setUp() {
super.setUp()
storage.zcashStoredWalletPrefix = "test_send_"
storage.deleteData(forKey: WalletStorage.Constants.zcashStoredWallet)
usNumberFormatter.maximumFractionDigits = 8
usNumberFormatter.maximumIntegerDigits = 8
usNumberFormatter.numberStyle = .decimal
@ -46,14 +46,14 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: initialState,
reducer: SendFlowReducer()
) { dependencies in
dependencies.derivationTool = .liveValue
dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
dependencies.mnemonic = .liveValue
dependencies.sdkSynchronizer = SDKSynchronizerClient.mocked(statusSnapshot: { .default })
dependencies.walletStorage = .noOp
}
)
store.dependencies.derivationTool = .liveValue
store.dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
store.dependencies.mnemonic = .liveValue
store.dependencies.sdkSynchronizer = .mocked()
store.dependencies.walletStorage = .noOp
// simulate the sending confirmation button to be pressed
_ = await store.send(.sendPressed) { state in
// once sending is confirmed, the attempts to try to send again by pressing the button
@ -62,7 +62,7 @@ class SendTests: XCTestCase {
}
await testScheduler.advance(by: 0.01)
let transactionState = TransactionState(
expiryHeight: 40,
memos: [],
@ -87,7 +87,7 @@ class SendTests: XCTestCase {
// the 'isSendingTransaction' needs to be false again
state.isSendingTransaction = false
}
// all went well, the success screen is triggered
await store.receive(.updateDestination(.success)) { state in
state.destination = .success
@ -114,13 +114,13 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: state,
reducer: SendFlowReducer()
) { dependencies in
dependencies.derivationTool = .liveValue
dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
dependencies.mnemonic = .liveValue
dependencies.sdkSynchronizer = SDKSynchronizerClient.mocked(statusSnapshot: { .default })
dependencies.walletStorage = .noOp
}
)
store.dependencies.derivationTool = .liveValue
store.dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
store.dependencies.mnemonic = .liveValue
store.dependencies.sdkSynchronizer = .mocked()
store.dependencies.walletStorage = .noOp
// simulate the sending confirmation button to be pressed
_ = await store.send(.sendPressed) { state in
@ -161,11 +161,11 @@ class SendTests: XCTestCase {
state.destination = .success
}
}
@MainActor func testSendFailed() async throws {
// the test needs to pass the exportWallet() so we simulate some in the keychain
try storage.importWallet(bip39: "one two three", birthday: nil)
// setup the store and environment to be fully mocked
let testScheduler = DispatchQueue.test
@ -181,13 +181,13 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: initialState,
reducer: SendFlowReducer()
) { dependencies in
dependencies.derivationTool = .liveValue
dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
dependencies.mnemonic = .liveValue
dependencies.walletStorage = .noOp
dependencies.sdkSynchronizer = .noOp
}
)
store.dependencies.derivationTool = .liveValue
store.dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
store.dependencies.mnemonic = .liveValue
store.dependencies.walletStorage = .noOp
store.dependencies.sdkSynchronizer = .noOp
// simulate the sending confirmation button to be pressed
_ = await store.send(.sendPressed) { state in
@ -209,21 +209,21 @@ class SendTests: XCTestCase {
// the 'isSendingTransaction' needs to be false again
state.isSendingTransaction = false
}
// the failure screen is triggered as expected
await store.receive(.updateDestination(.failure)) { state in
state.destination = .failure
}
}
func testAddressValidation_Invalid() throws {
let store = TestStore(
initialState: .placeholder,
reducer: SendFlowReducer()
) { dependencies in
dependencies.derivationTool = .noOp
dependencies.derivationTool.isValidZcashAddress = { _ in false }
}
)
store.dependencies.derivationTool = .noOp
store.dependencies.derivationTool.isValidZcashAddress = { _ in false }
let address = "3HRG769ii3HDSJV5vNknQPzXqtL2mTSGnr".redacted
store.send(.transactionAddressInput(.textField(.set(address)))) { state in
@ -238,15 +238,15 @@ class SendTests: XCTestCase {
)
}
}
func testAddressValidation_Valid() throws {
let store = TestStore(
initialState: .placeholder,
reducer: SendFlowReducer()
) { dependencies in
dependencies.derivationTool = .noOp
dependencies.derivationTool.isValidZcashAddress = { _ in true }
}
)
store.dependencies.derivationTool = .noOp
store.dependencies.derivationTool.isValidZcashAddress = { _ in true }
let address = "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po".redacted
store.send(.transactionAddressInput(.textField(.set(address)))) { state in
@ -261,29 +261,29 @@ class SendTests: XCTestCase {
)
}
}
func testInvalidAmountFormatEmptyInput() throws {
let store = TestStore(
initialState: .placeholder,
reducer: SendFlowReducer()
) {
$0.numberFormatter = .noOp
}
)
store.dependencies.numberFormatter = .noOp
// Checks the computed property `isInvalidAmountFormat` which controls the error message to be shown on the screen
// With empty input it must be false
store.send(.transactionAmountInput(.textField(.set("".redacted))))
store.receive(.transactionAmountInput(.updateAmount))
}
func testInvalidAddressFormatEmptyInput() throws {
let store = TestStore(
initialState: .placeholder,
reducer: SendFlowReducer()
) {
$0.derivationTool = .noOp
}
)
store.dependencies.derivationTool = .noOp
// Checks the computed property `isInvalidAddressFormat` which controls the error message to be shown on the screen
// With empty input it must be false
@ -298,7 +298,7 @@ class SendTests: XCTestCase {
)
}
}
func testFundsSufficiency_SufficientAmount() throws {
let sendState = SendFlowReducer.State(
addMemoState: true,
@ -320,10 +320,10 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
) { dependencies in
dependencies.numberFormatter = .noOp
dependencies.numberFormatter.number = { _ in NSNumber(0.00501299) }
}
)
store.dependencies.numberFormatter = .noOp
store.dependencies.numberFormatter.number = { _ in NSNumber(0.00501299) }
let address = "0.00501299".redacted
store.send(.transactionAmountInput(.textField(.set(address)))) { state in
@ -334,12 +334,12 @@ class SendTests: XCTestCase {
"Send Tests: `testFundsSufficiency` is expected to be false but it's \(state.isInsufficientFunds)"
)
}
store.receive(.transactionAmountInput(.updateAmount)) { state in
state.transactionAmountInputState.amount = Int64(501_299).redacted
}
}
func testFundsSufficiency_InsufficientAmount() throws {
let sendState = SendFlowReducer.State(
addMemoState: true,
@ -361,10 +361,10 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
) { dependencies in
dependencies.numberFormatter = .noOp
dependencies.numberFormatter.number = { _ in NSNumber(0.00501301) }
}
)
store.dependencies.numberFormatter = .noOp
store.dependencies.numberFormatter.number = { _ in NSNumber(0.00501301) }
let value = "0.00501301".redacted
store.send(.transactionAmountInput(.textField(.set(value)))) { state in
@ -375,7 +375,7 @@ class SendTests: XCTestCase {
"Send Tests: `testFundsSufficiency` is expected to be false but it's \(state.isInsufficientFunds)"
)
}
store.receive(.transactionAmountInput(.updateAmount)) { state in
state.transactionAmountInputState.amount = Int64(501_301).redacted
XCTAssertTrue(
@ -384,7 +384,7 @@ class SendTests: XCTestCase {
)
}
}
func testDifferentNumberFormats_LiveNumberFormatter() throws {
try numberFormatTest("1.234", NSNumber(1.234))
try numberFormatTest("1,234", NSNumber(1_234))
@ -399,7 +399,7 @@ class SendTests: XCTestCase {
try numberFormatTest("1 23", nil)
try numberFormatTest("1.2.3", nil)
}
func testValidForm() throws {
let sendState = SendFlowReducer.State(
addMemoState: true,
@ -418,14 +418,14 @@ class SendTests: XCTestCase {
)
)
)
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
) { dependencies in
dependencies.derivationTool = .noOp
dependencies.derivationTool.isValidZcashAddress = { _ in true }
}
)
store.dependencies.derivationTool = .noOp
store.dependencies.derivationTool.isValidZcashAddress = { _ in true }
let address = "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po".redacted
store.send(.transactionAddressInput(.textField(.set(address)))) { state in
@ -440,7 +440,7 @@ class SendTests: XCTestCase {
)
}
}
func testInvalidForm_InsufficientFunds() throws {
let sendState = SendFlowReducer.State(
addMemoState: true,
@ -462,10 +462,10 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
) { dependencies in
dependencies.derivationTool = .noOp
dependencies.derivationTool.isValidZcashAddress = { _ in true }
}
)
store.dependencies.derivationTool = .noOp
store.dependencies.derivationTool.isValidZcashAddress = { _ in true }
let address = "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po".redacted
store.send(.transactionAddressInput(.textField(.set(address)))) { state in
@ -480,7 +480,7 @@ class SendTests: XCTestCase {
)
}
}
func testInvalidForm_AddressFormat() throws {
let sendState = SendFlowReducer.State(
addMemoState: true,
@ -498,13 +498,13 @@ class SendTests: XCTestCase {
)
)
)
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
) {
$0.derivationTool = .noOp
}
)
store.dependencies.derivationTool = .noOp
let address = "3HRG769ii3HDSJV5vNknQPzXqtL2mTSGnr".redacted
store.send(.transactionAddressInput(.textField(.set(address)))) { state in
@ -519,7 +519,7 @@ class SendTests: XCTestCase {
)
}
}
func testInvalidForm_AmountFormat() throws {
let sendState = SendFlowReducer.State(
addMemoState: true,
@ -541,10 +541,10 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
) { dependencies in
dependencies.derivationTool = .noOp
dependencies.derivationTool.isValidZcashAddress = { _ in true }
}
)
store.dependencies.derivationTool = .noOp
store.dependencies.derivationTool.isValidZcashAddress = { _ in true }
let address = "tmGh6ttAnQRJra81moqYcedFadW9XtUT5Eq".redacted
store.send(.transactionAddressInput(.textField(.set(address)))) { state in
@ -560,7 +560,7 @@ class SendTests: XCTestCase {
)
}
}
func testInvalidForm_ExceededMemoCharLimit() throws {
let sendState = SendFlowReducer.State(
addMemoState: true,
@ -588,7 +588,7 @@ class SendTests: XCTestCase {
)
)
)
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
@ -603,7 +603,7 @@ class SendTests: XCTestCase {
)
}
}
func testMemoCharLimitSet() throws {
let sendState = SendFlowReducer.State(
addMemoState: true,
@ -627,19 +627,20 @@ class SendTests: XCTestCase {
reducer: SendFlowReducer()
)
store.dependencies.mainQueue = .immediate
store.dependencies.sdkSynchronizer = .noOp
store.send(.onAppear) { state in
state.memoState.charLimit = 512
}
store.receive(.synchronizerStateChanged(.unknown))
//store.receive(.synchronizerStateChanged(.unknown))
// .onAppear action starts long living cancelable action .synchronizerStateChanged
// .onDisappear cancels it, must have for the test to pass
store.send(.onDisappear)
}
func testScannedAddress() throws {
let sendState = SendFlowReducer.State(
addMemoState: true,
@ -656,7 +657,7 @@ class SendTests: XCTestCase {
store.dependencies.audioServices = AudioServicesClient(systemSoundVibrate: { })
store.dependencies.derivationTool = .noOp
// We don't need to pass a valid address here, we just need to confirm some
// found string is received and the `isValidAddress` flag is set to `true`
let address = "address".redacted
@ -664,7 +665,7 @@ class SendTests: XCTestCase {
state.transactionAddressInputState.textFieldState.text = address
state.transactionAddressInputState.isValidAddress = true
}
store.receive(.updateDestination(nil))
}
}

View File

@ -34,10 +34,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
)
),
reducer: TransactionAmountTextFieldReducer()
) { dependencies in
dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
}
)
store.dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
store.dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
store.send(.setMax) { state in
state.textFieldState.text = "0.00501301".redacted
@ -85,10 +85,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
zecPrice: 1000.0
),
reducer: TransactionAmountTextFieldReducer()
) { dependencies in
dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
}
)
store.dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
store.dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
store.send(.currencySelection(.swapCurrencyType)) { state in
state.textFieldState.text = "1,000".redacted
@ -116,10 +116,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
zecPrice: 1000.0
),
reducer: TransactionAmountTextFieldReducer()
) { dependencies in
dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
}
)
store.dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
store.dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
store.send(.currencySelection(.swapCurrencyType)) { state in
state.textFieldState.text = "25,000,000".redacted
@ -147,10 +147,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
zecPrice: 1000.0
),
reducer: TransactionAmountTextFieldReducer()
) { dependencies in
dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
}
)
store.dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
store.dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
store.send(.currencySelection(.swapCurrencyType)) { state in
state.textFieldState.text = "1".redacted
@ -179,10 +179,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
zecPrice: 1000.0
),
reducer: TransactionAmountTextFieldReducer()
) { dependencies in
dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
}
)
store.dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
store.dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
let value = "1 000".redacted
store.send(.textField(.set(value))) { state in
@ -221,10 +221,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
zecPrice: 1000.0
),
reducer: TransactionAmountTextFieldReducer()
) { dependencies in
dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
}
)
store.dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
store.dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
store.send(.setMax) { state in
state.textFieldState.text = "2".redacted
@ -252,10 +252,10 @@ class TransactionAmountTextFieldTests: XCTestCase {
zecPrice: 1000.0
),
reducer: TransactionAmountTextFieldReducer()
) { dependencies in
dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
}
)
store.dependencies.numberFormatter.string = { self.usNumberFormatter.string(from: $0) }
store.dependencies.numberFormatter.number = { self.usNumberFormatter.number(from: $0) }
store.send(.setMax) { state in
state.textFieldState.text = "2,000".redacted

View File

@ -51,12 +51,12 @@ class SettingsTests: XCTestCase {
phraseDisplayState: RecoveryPhraseDisplayReducer.State(phrase: nil)
),
reducer: SettingsReducer()
) { dependencies in
dependencies.localAuthentication = .mockAuthenticationSucceeded
dependencies.mnemonic = .noOp
dependencies.mnemonic.asWords = { _ in mnemonic.components(separatedBy: " ") }
dependencies.walletStorage = mockedWalletStorage
}
)
store.dependencies.localAuthentication = .mockAuthenticationSucceeded
store.dependencies.mnemonic = .noOp
store.dependencies.mnemonic.asWords = { _ in mnemonic.components(separatedBy: " ") }
store.dependencies.walletStorage = mockedWalletStorage
await store.send(.backupWalletAccessRequest)
@ -72,9 +72,9 @@ class SettingsTests: XCTestCase {
let store = TestStore(
initialState: .placeholder,
reducer: SettingsReducer()
) {
$0.localAuthentication = .mockAuthenticationFailed
}
)
store.dependencies.localAuthentication = .mockAuthenticationFailed
await store.send(.backupWalletAccessRequest)

View File

@ -23,6 +23,7 @@ class BalanceBreakdownSnapshotTests: XCTestCase {
),
reducer: BalanceBreakdownReducer()
.dependency(\.sdkSynchronizer, .noOp)
.dependency(\.mainQueue, .immediate)
)
addAttachments(BalanceBreakdownView(store: store))

View File

@ -50,6 +50,7 @@ class HomeSnapshotTests: XCTestCase {
reducer: HomeReducer()
.dependency(\.diskSpaceChecker, .mockEmptyDisk)
.dependency(\.sdkSynchronizer, .noOp)
.dependency(\.mainQueue, .immediate)
)
// landing home screen

View File

@ -12,7 +12,7 @@ import ZcashLightClientKit
class WalletEventsTests: XCTestCase {
static let testScheduler = DispatchQueue.test
func testSynchronizerSubscription() throws {
let store = TestStore(
initialState: WalletEventsFlowReducer.State(
@ -23,13 +23,14 @@ class WalletEventsTests: XCTestCase {
reducer: WalletEventsFlowReducer()
)
store.dependencies.sdkSynchronizer = .noOp
store.dependencies.sdkSynchronizer = .mocked()
store.dependencies.mainQueue = .immediate
store.send(.onAppear) { state in
state.requiredTransactionConfirmations = 10
}
store.receive(.synchronizerStateChanged(.unknown))
store.receive(.synchronizerStateChanged(.unprepared))
// ending the subscription
store.send(.onDisappear)
@ -70,7 +71,7 @@ class WalletEventsTests: XCTestCase {
}
let identifiedWalletEvents = IdentifiedArrayOf(uniqueElements: walletEvents)
let store = TestStore(
initialState: WalletEventsFlowReducer.State(
destination: .latest,
@ -78,15 +79,15 @@ class WalletEventsTests: XCTestCase {
walletEvents: identifiedWalletEvents
),
reducer: WalletEventsFlowReducer()
) { dependencies in
dependencies.mainQueue = Self.testScheduler.eraseToAnyScheduler()
dependencies.sdkSynchronizer = SDKSynchronizerClient.mocked(statusSnapshot: { .default })
}
)
store.dependencies.mainQueue = Self.testScheduler.eraseToAnyScheduler()
store.dependencies.sdkSynchronizer = .mocked()
store.send(.synchronizerStateChanged(.synced)) { state in
state.latestMinedHeight = 0
}
Self.testScheduler.advance(by: 0.01)
store.receive(.updateWalletEvents(walletEvents)) { state in
@ -100,14 +101,14 @@ class WalletEventsTests: XCTestCase {
return lhsTimestamp > rhsTimestamp
})
)
state.walletEvents = receivedWalletEvents
}
}
func testCopyToPasteboard() throws {
let testPasteboard = PasteboardClient.testPasteboard
let store = TestStore(
initialState: WalletEventsFlowReducer.State(
destination: .latest,
@ -115,13 +116,13 @@ class WalletEventsTests: XCTestCase {
walletEvents: []
),
reducer: WalletEventsFlowReducer()
) {
$0.pasteboard = testPasteboard
}
)
store.dependencies.pasteboard = testPasteboard
let testText = "test text".redacted
store.send(.copyToPastboard(testText))
XCTAssertEqual(
testPasteboard.getString()?.data,
testText.data,