diff --git a/GdeiAssistant-iOS.xcodeproj/project.pbxproj b/GdeiAssistant-iOS.xcodeproj/project.pbxproj index c6d4229..b4f02f4 100644 --- a/GdeiAssistant-iOS.xcodeproj/project.pbxproj +++ b/GdeiAssistant-iOS.xcodeproj/project.pbxproj @@ -7,35 +7,9 @@ objects = { /* Begin PBXBuildFile section */ - 0A177ECCDC40F719D4D9F46F /* AuthTestDoubles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373B47CAADB5B3CE84F0601F /* AuthTestDoubles.swift */; }; - 1C7A3D8E4F5B6A7091827364 /* AppLanguageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B8C4D9E5F6A7B8091C27364 /* AppLanguageTests.swift */; }; - 23FC56E702BCF7B97FD9012D /* RemoteMapperSupportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346C4708A3C31E844BBF2625 /* RemoteMapperSupportTests.swift */; }; 3E24033623B018F07571CC25 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 452569A4EA1E4E426F6F3E6D /* Foundation.framework */; }; - 44DC59BFABA1496DA3AE9B6D /* RemoteLostFoundRepositoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FD844E948974FF8A18A0A3D /* RemoteLostFoundRepositoryTests.swift */; }; - 45CD090CF159FFACA7D91AD4 /* ProfileFormSupportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6DA9CD705BD14A1B1E9BD1C /* ProfileFormSupportTests.swift */; }; - 5081118454BD4B94AC5EBB51 /* APIClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98C5CC023B26463B8EAE2B9A /* APIClientTests.swift */; }; - 5C8E7A3D1B2F4C6D8E9A0B1C /* MockFeatureSmokeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C8E7A3D1B2F4C6D8E9A0B1B /* MockFeatureSmokeTests.swift */; }; - 6F8A9B0C1D2E3F4051627384 /* CertificatePinningDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B9C0D1E2F30415263748596 /* CertificatePinningDelegateTests.swift */; }; - 7A8B9C0D1E2F304152637485 /* SettingsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C0D1E2F30415263748596A7 /* SettingsViewModelTests.swift */; }; - C8F4A2B6D9E14035A7C2F912 /* ChargeRemoteMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F4A2B6D9E14035A7C2F911 /* ChargeRemoteMapperTests.swift */; }; - A2B3C4D5E6F708192A3B4C5D /* TestLifetimeRetainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2C3D4E5F60718293A4B5C6D /* TestLifetimeRetainer.swift */; }; A7F100000000000000000001 /* MockUISmokeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F100000000000000000003 /* MockUISmokeTests.swift */; }; A7F100000000000000000010 /* MockRuntimePerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F100000000000000000011 /* MockRuntimePerformanceTests.swift */; }; - 8219886478DFDC9042AE3AA9 /* RequestBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD63BDDF16EB5C5E56111AC4 /* RequestBuilderTests.swift */; }; - A1B2C3D4E5F60718A9B0D1E1 /* SecretDetailNoDuplicateFetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B2C3D4E5F60718A9B0D1E2 /* SecretDetailNoDuplicateFetchTests.swift */; }; - B15D1954479F46BEB294065B /* RequestIDTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 359A61E15F1A4C11A7429225 /* RequestIDTests.swift */; }; - B1A2C3D4E5F60718A9B0C1D2 /* AppContainerBootstrapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A2C3D4E5F60718A9B0C1D3 /* AppContainerBootstrapTests.swift */; }; - C64B15DF5C6F7CCC0E32B37B /* DatingRemoteMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AF4619A3864805033BE080 /* DatingRemoteMapperTests.swift */; }; - E21B05F43CAE6846A9EC26D1 /* AuthManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB26C35E7E8F8EDFD881C69F /* AuthManagerTests.swift */; }; - E9FC3B2241EB8C322C48A5EF /* MultipartFormDataBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3112842602259B0422B1CBD1 /* MultipartFormDataBuilderTests.swift */; }; - EC5349E40F96411FB2E8629A /* RemoteMarketplaceRepositoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 082E49E4E09F453AB6EF6772 /* RemoteMarketplaceRepositoryTests.swift */; }; - F90E561DD371D29335422B59 /* LibraryRemoteMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17F3CF56F76606E1257E386 /* LibraryRemoteMapperTests.swift */; }; - FFDDE89AE80431D0303BCEB4 /* MessagesRemoteMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D03C8887D96BBA87D07972B /* MessagesRemoteMapperTests.swift */; }; - F1A2B3C4D5E60718293A4B5C /* SocialRemoteMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A2B3C4D5E60718293A4B5D /* SocialRemoteMapperTests.swift */; }; - F2A3B4C5D6E708192A3B4C5D /* MockSocialRepositoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2A3B4C5D6E708192A3B4C5E /* MockSocialRepositoryTests.swift */; }; - F3A4B5C6D7E8091A2B3C4D5E /* AuthenticatedImageLoaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3A4B5C6D7E8091A2B3C4D5F /* AuthenticatedImageLoaderTests.swift */; }; - F4B5C6D7E8F90A2B3C4D5E6F /* ChatMessageMergeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4B5C6D7E8F90A2B3C4D5E70 /* ChatMessageMergeTests.swift */; }; - F5C6D7E8F901A2B3C4D5E6F7 /* PublicAuthorIdMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5C6D7E8F901A2B3C4D5E6F8 /* PublicAuthorIdMapperTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -56,44 +30,23 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 082E49E4E09F453AB6EF6772 /* RemoteMarketplaceRepositoryTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RemoteMarketplaceRepositoryTests.swift; path = "GdeiAssistant-iOSTests/Marketplace/RemoteMarketplaceRepositoryTests.swift"; sourceTree = ""; }; - 2D03C8887D96BBA87D07972B /* MessagesRemoteMapperTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessagesRemoteMapperTests.swift; path = "GdeiAssistant-iOSTests/Messages/MessagesRemoteMapperTests.swift"; sourceTree = ""; }; - 2B8C4D9E5F6A7B8091C27364 /* AppLanguageTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AppLanguageTests.swift; path = "GdeiAssistant-iOSTests/Localization/AppLanguageTests.swift"; sourceTree = ""; }; - 3112842602259B0422B1CBD1 /* MultipartFormDataBuilderTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormDataBuilderTests.swift; path = "GdeiAssistant-iOSTests/Networking/MultipartFormDataBuilderTests.swift"; sourceTree = ""; }; - 346C4708A3C31E844BBF2625 /* RemoteMapperSupportTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RemoteMapperSupportTests.swift; path = "GdeiAssistant-iOSTests/Utils/RemoteMapperSupportTests.swift"; sourceTree = ""; }; - 359A61E15F1A4C11A7429225 /* RequestIDTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestIDTests.swift; path = "GdeiAssistant-iOSTests/Networking/RequestIDTests.swift"; sourceTree = ""; }; - 373B47CAADB5B3CE84F0601F /* AuthTestDoubles.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthTestDoubles.swift; path = "GdeiAssistant-iOSTests/Support/AuthTestDoubles.swift"; sourceTree = ""; }; - B2C3D4E5F60718293A4B5C6D /* TestLifetimeRetainer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TestLifetimeRetainer.swift; path = "GdeiAssistant-iOSTests/Support/TestLifetimeRetainer.swift"; sourceTree = ""; }; 452569A4EA1E4E426F6F3E6D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 5F0A1B2C3D4E5F6071829301 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 5F0A1B2C3D4E5F6071829302 /* Staging.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Staging.xcconfig; sourceTree = ""; }; 5F0A1B2C3D4E5F6071829303 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - 5C8E7A3D1B2F4C6D8E9A0B1B /* MockFeatureSmokeTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MockFeatureSmokeTests.swift; path = "GdeiAssistant-iOSTests/Contract/MockFeatureSmokeTests.swift"; sourceTree = ""; }; 69DC5B58D2579C0F23D05428 /* GdeiAssistant-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "GdeiAssistant-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 7FD844E948974FF8A18A0A3D /* RemoteLostFoundRepositoryTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RemoteLostFoundRepositoryTests.swift; path = "GdeiAssistant-iOSTests/LostFound/RemoteLostFoundRepositoryTests.swift"; sourceTree = ""; }; - 8B9C0D1E2F30415263748596 /* CertificatePinningDelegateTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CertificatePinningDelegateTests.swift; path = "GdeiAssistant-iOSTests/Networking/CertificatePinningDelegateTests.swift"; sourceTree = ""; }; - 98C5CC023B26463B8EAE2B9A /* APIClientTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = APIClientTests.swift; path = "GdeiAssistant-iOSTests/Networking/APIClientTests.swift"; sourceTree = ""; }; - 9C0D1E2F30415263748596A7 /* SettingsViewModelTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SettingsViewModelTests.swift; path = "GdeiAssistant-iOSTests/Profile/SettingsViewModelTests.swift"; sourceTree = ""; }; A7F100000000000000000003 /* MockUISmokeTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MockUISmokeTests.swift; path = "GdeiAssistant-iOSUITests/MockUISmokeTests.swift"; sourceTree = ""; }; A7F100000000000000000011 /* MockRuntimePerformanceTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MockRuntimePerformanceTests.swift; path = "GdeiAssistant-iOSUITests/MockRuntimePerformanceTests.swift"; sourceTree = ""; }; A7F100000000000000000004 /* GdeiAssistant-iOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "GdeiAssistant-iOSUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - A17F3CF56F76606E1257E386 /* LibraryRemoteMapperTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LibraryRemoteMapperTests.swift; path = "GdeiAssistant-iOSTests/Library/LibraryRemoteMapperTests.swift"; sourceTree = ""; }; - A1B2C3D4E5F60718A9B0D1E2 /* SecretDetailNoDuplicateFetchTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SecretDetailNoDuplicateFetchTests.swift; path = "GdeiAssistant-iOSTests/Contract/SecretDetailNoDuplicateFetchTests.swift"; sourceTree = ""; }; - A6DA9CD705BD14A1B1E9BD1C /* ProfileFormSupportTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ProfileFormSupportTests.swift; path = "GdeiAssistant-iOSTests/Profile/ProfileFormSupportTests.swift"; sourceTree = ""; }; - B1A2C3D4E5F60718A9B0C1D3 /* AppContainerBootstrapTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AppContainerBootstrapTests.swift; path = "GdeiAssistant-iOSTests/Container/AppContainerBootstrapTests.swift"; sourceTree = ""; }; - CD63BDDF16EB5C5E56111AC4 /* RequestBuilderTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestBuilderTests.swift; path = "GdeiAssistant-iOSTests/Networking/RequestBuilderTests.swift"; sourceTree = ""; }; - C8F4A2B6D9E14035A7C2F911 /* ChargeRemoteMapperTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChargeRemoteMapperTests.swift; path = "GdeiAssistant-iOSTests/Charge/ChargeRemoteMapperTests.swift"; sourceTree = ""; }; - D0AF4619A3864805033BE080 /* DatingRemoteMapperTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DatingRemoteMapperTests.swift; path = "GdeiAssistant-iOSTests/Dating/DatingRemoteMapperTests.swift"; sourceTree = ""; }; D72127102F5D506E00AE6A6F /* GdeiAssistant-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "GdeiAssistant-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - EB26C35E7E8F8EDFD881C69F /* AuthManagerTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthManagerTests.swift; path = "GdeiAssistant-iOSTests/Auth/AuthManagerTests.swift"; sourceTree = ""; }; - F1A2B3C4D5E60718293A4B5D /* SocialRemoteMapperTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SocialRemoteMapperTests.swift; path = "GdeiAssistant-iOSTests/Social/SocialRemoteMapperTests.swift"; sourceTree = ""; }; - F2A3B4C5D6E708192A3B4C5E /* MockSocialRepositoryTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MockSocialRepositoryTests.swift; path = "GdeiAssistant-iOSTests/Social/MockSocialRepositoryTests.swift"; sourceTree = ""; }; - F3A4B5C6D7E8091A2B3C4D5F /* AuthenticatedImageLoaderTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticatedImageLoaderTests.swift; path = "GdeiAssistant-iOSTests/Social/AuthenticatedImageLoaderTests.swift"; sourceTree = ""; }; - F4B5C6D7E8F90A2B3C4D5E70 /* ChatMessageMergeTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChatMessageMergeTests.swift; path = "GdeiAssistant-iOSTests/Social/ChatMessageMergeTests.swift"; sourceTree = ""; }; - F5C6D7E8F901A2B3C4D5E6F8 /* PublicAuthorIdMapperTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PublicAuthorIdMapperTests.swift; path = "GdeiAssistant-iOSTests/Social/PublicAuthorIdMapperTests.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ + DEECEB8674DE18A2B5A46637 /* GdeiAssistant-iOSTests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = "GdeiAssistant-iOSTests"; + sourceTree = ""; + }; D72127122F5D506E00AE6A6F /* GdeiAssistant-iOS */ = { isa = PBXFileSystemSynchronizedRootGroup; path = "GdeiAssistant-iOS"; @@ -184,39 +137,6 @@ name = "GdeiAssistant-iOSUITests"; sourceTree = ""; }; - DEECEB8674DE18A2B5A46637 /* GdeiAssistant-iOSTests */ = { - isa = PBXGroup; - children = ( - B1A2C3D4E5F60718A9B0C1D3 /* AppContainerBootstrapTests.swift */, - 2B8C4D9E5F6A7B8091C27364 /* AppLanguageTests.swift */, - EB26C35E7E8F8EDFD881C69F /* AuthManagerTests.swift */, - 373B47CAADB5B3CE84F0601F /* AuthTestDoubles.swift */, - C8F4A2B6D9E14035A7C2F911 /* ChargeRemoteMapperTests.swift */, - B2C3D4E5F60718293A4B5C6D /* TestLifetimeRetainer.swift */, - D0AF4619A3864805033BE080 /* DatingRemoteMapperTests.swift */, - A17F3CF56F76606E1257E386 /* LibraryRemoteMapperTests.swift */, - 2D03C8887D96BBA87D07972B /* MessagesRemoteMapperTests.swift */, - 5C8E7A3D1B2F4C6D8E9A0B1B /* MockFeatureSmokeTests.swift */, - 3112842602259B0422B1CBD1 /* MultipartFormDataBuilderTests.swift */, - A6DA9CD705BD14A1B1E9BD1C /* ProfileFormSupportTests.swift */, - 9C0D1E2F30415263748596A7 /* SettingsViewModelTests.swift */, - 346C4708A3C31E844BBF2625 /* RemoteMapperSupportTests.swift */, - CD63BDDF16EB5C5E56111AC4 /* RequestBuilderTests.swift */, - 359A61E15F1A4C11A7429225 /* RequestIDTests.swift */, - 8B9C0D1E2F30415263748596 /* CertificatePinningDelegateTests.swift */, - 98C5CC023B26463B8EAE2B9A /* APIClientTests.swift */, - 082E49E4E09F453AB6EF6772 /* RemoteMarketplaceRepositoryTests.swift */, - 7FD844E948974FF8A18A0A3D /* RemoteLostFoundRepositoryTests.swift */, - A1B2C3D4E5F60718A9B0D1E2 /* SecretDetailNoDuplicateFetchTests.swift */, - F1A2B3C4D5E60718293A4B5D /* SocialRemoteMapperTests.swift */, - F2A3B4C5D6E708192A3B4C5E /* MockSocialRepositoryTests.swift */, - F3A4B5C6D7E8091A2B3C4D5F /* AuthenticatedImageLoaderTests.swift */, - F4B5C6D7E8F90A2B3C4D5E70 /* ChatMessageMergeTests.swift */, - F5C6D7E8F901A2B3C4D5E6F8 /* PublicAuthorIdMapperTests.swift */, - ); - name = "GdeiAssistant-iOSTests"; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -251,6 +171,9 @@ dependencies = ( 2382F97AB1D9F89C03F48BC2 /* PBXTargetDependency */, ); + fileSystemSynchronizedGroups = ( + DEECEB8674DE18A2B5A46637 /* GdeiAssistant-iOSTests */, + ); name = "GdeiAssistant-iOSTests"; productName = "GdeiAssistant-iOSTests"; productReference = 69DC5B58D2579C0F23D05428 /* GdeiAssistant-iOSTests.xctest */; @@ -363,32 +286,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B1A2C3D4E5F60718A9B0C1D2 /* AppContainerBootstrapTests.swift in Sources */, - 1C7A3D8E4F5B6A7091827364 /* AppLanguageTests.swift in Sources */, - E21B05F43CAE6846A9EC26D1 /* AuthManagerTests.swift in Sources */, - 0A177ECCDC40F719D4D9F46F /* AuthTestDoubles.swift in Sources */, - C8F4A2B6D9E14035A7C2F912 /* ChargeRemoteMapperTests.swift in Sources */, - A2B3C4D5E6F708192A3B4C5D /* TestLifetimeRetainer.swift in Sources */, - C64B15DF5C6F7CCC0E32B37B /* DatingRemoteMapperTests.swift in Sources */, - F90E561DD371D29335422B59 /* LibraryRemoteMapperTests.swift in Sources */, - FFDDE89AE80431D0303BCEB4 /* MessagesRemoteMapperTests.swift in Sources */, - E9FC3B2241EB8C322C48A5EF /* MultipartFormDataBuilderTests.swift in Sources */, - 45CD090CF159FFACA7D91AD4 /* ProfileFormSupportTests.swift in Sources */, - 23FC56E702BCF7B97FD9012D /* RemoteMapperSupportTests.swift in Sources */, - 8219886478DFDC9042AE3AA9 /* RequestBuilderTests.swift in Sources */, - B15D1954479F46BEB294065B /* RequestIDTests.swift in Sources */, - 5081118454BD4B94AC5EBB51 /* APIClientTests.swift in Sources */, - 5C8E7A3D1B2F4C6D8E9A0B1C /* MockFeatureSmokeTests.swift in Sources */, - 6F8A9B0C1D2E3F4051627384 /* CertificatePinningDelegateTests.swift in Sources */, - EC5349E40F96411FB2E8629A /* RemoteMarketplaceRepositoryTests.swift in Sources */, - 44DC59BFABA1496DA3AE9B6D /* RemoteLostFoundRepositoryTests.swift in Sources */, - A1B2C3D4E5F60718A9B0D1E1 /* SecretDetailNoDuplicateFetchTests.swift in Sources */, - 7A8B9C0D1E2F304152637485 /* SettingsViewModelTests.swift in Sources */, - F1A2B3C4D5E60718293A4B5C /* SocialRemoteMapperTests.swift in Sources */, - F2A3B4C5D6E708192A3B4C5D /* MockSocialRepositoryTests.swift in Sources */, - F3A4B5C6D7E8091A2B3C4D5E /* AuthenticatedImageLoaderTests.swift in Sources */, - F4B5C6D7E8F90A2B3C4D5E6F /* ChatMessageMergeTests.swift in Sources */, - F5C6D7E8F901A2B3C4D5E6F7 /* PublicAuthorIdMapperTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/GdeiAssistant-iOS/Features/Express/Models/ExpressModels.swift b/GdeiAssistant-iOS/Features/Express/Models/ExpressModels.swift index 008f603..ddfbdc9 100644 --- a/GdeiAssistant-iOS/Features/Express/Models/ExpressModels.swift +++ b/GdeiAssistant-iOS/Features/Express/Models/ExpressModels.swift @@ -58,3 +58,32 @@ struct ExpressDraft: Codable { let content: String let targetGender: ExpressGender } + +extension ExpressPost { + /// A copy with only the given counters changed. Both the mock repository and the view + /// model apply the same optimistic updates, so adding a field must not require editing + /// six full memberwise constructions. + func with( + likeCount: Int? = nil, + commentCount: Int? = nil, + guessCount: Int? = nil, + correctGuessCount: Int? = nil, + isLiked: Bool? = nil + ) -> ExpressPost { + ExpressPost( + id: id, + nickname: nickname, + targetName: targetName, + contentPreview: contentPreview, + publishTime: publishTime, + likeCount: likeCount ?? self.likeCount, + commentCount: commentCount ?? self.commentCount, + guessCount: guessCount ?? self.guessCount, + correctGuessCount: correctGuessCount ?? self.correctGuessCount, + isLiked: isLiked ?? self.isLiked, + canGuess: canGuess, + selfGender: selfGender, + targetGender: targetGender + ) + } +} diff --git a/GdeiAssistant-iOS/Features/Express/Repositories/MockExpressRepository.swift b/GdeiAssistant-iOS/Features/Express/Repositories/MockExpressRepository.swift index 42fd578..2f242ff 100644 --- a/GdeiAssistant-iOS/Features/Express/Repositories/MockExpressRepository.swift +++ b/GdeiAssistant-iOS/Features/Express/Repositories/MockExpressRepository.swift @@ -102,63 +102,22 @@ final class MockExpressRepository: ExpressRepository { comments[postID, default: []].insert(item, at: 0) if let index = posts.firstIndex(where: { $0.id == postID }) { let post = posts[index] - posts[index] = ExpressPost( - id: post.id, - nickname: post.nickname, - targetName: post.targetName, - contentPreview: post.contentPreview, - publishTime: post.publishTime, - likeCount: post.likeCount, - commentCount: post.commentCount + 1, - guessCount: post.guessCount, - correctGuessCount: post.correctGuessCount, - isLiked: post.isLiked, - canGuess: post.canGuess, - selfGender: post.selfGender, - targetGender: post.targetGender - ) + posts[index] = post.with(commentCount: post.commentCount + 1) } } func like(postID: String) async throws { guard let index = posts.firstIndex(where: { $0.id == postID }) else { return } let post = posts[index] - posts[index] = ExpressPost( - id: post.id, - nickname: post.nickname, - targetName: post.targetName, - contentPreview: post.contentPreview, - publishTime: post.publishTime, - likeCount: post.likeCount + (post.isLiked ? 0 : 1), - commentCount: post.commentCount, - guessCount: post.guessCount, - correctGuessCount: post.correctGuessCount, - isLiked: true, - canGuess: post.canGuess, - selfGender: post.selfGender, - targetGender: post.targetGender - ) + posts[index] = post.with(likeCount: post.likeCount + (post.isLiked ? 0 : 1), isLiked: true) } func guess(postID: String, name: String) async throws -> Bool { let matched = name.trimmingCharacters(in: .whitespacesAndNewlines) == localizedString("mock.express.detail.realName") if let index = posts.firstIndex(where: { $0.id == postID }) { let post = posts[index] - posts[index] = ExpressPost( - id: post.id, - nickname: post.nickname, - targetName: post.targetName, - contentPreview: post.contentPreview, - publishTime: post.publishTime, - likeCount: post.likeCount, - commentCount: post.commentCount, - guessCount: post.guessCount + 1, - correctGuessCount: post.correctGuessCount + (matched ? 1 : 0), - isLiked: post.isLiked, - canGuess: post.canGuess, - selfGender: post.selfGender, - targetGender: post.targetGender - ) + posts[index] = post.with(guessCount: post.guessCount + 1, + correctGuessCount: post.correctGuessCount + (matched ? 1 : 0)) } return matched } diff --git a/GdeiAssistant-iOS/Features/Express/ViewModels/ExpressViewModel.swift b/GdeiAssistant-iOS/Features/Express/ViewModels/ExpressViewModel.swift index da5d65c..7870cec 100644 --- a/GdeiAssistant-iOS/Features/Express/ViewModels/ExpressViewModel.swift +++ b/GdeiAssistant-iOS/Features/Express/ViewModels/ExpressViewModel.swift @@ -46,21 +46,7 @@ final class ExpressViewModel: ObservableObject { func submitComment(postID: String, content: String) async throws { try await repository.submitComment(postID: postID, content: content) updatePost(postID: postID) { post in - ExpressPost( - id: post.id, - nickname: post.nickname, - targetName: post.targetName, - contentPreview: post.contentPreview, - publishTime: post.publishTime, - likeCount: post.likeCount, - commentCount: post.commentCount + 1, - guessCount: post.guessCount, - correctGuessCount: post.correctGuessCount, - isLiked: post.isLiked, - canGuess: post.canGuess, - selfGender: post.selfGender, - targetGender: post.targetGender - ) + post.with(commentCount: post.commentCount + 1) } } @@ -68,42 +54,15 @@ final class ExpressViewModel: ObservableObject { try await repository.like(postID: postID) if let index = posts.firstIndex(where: { $0.id == postID }) { let post = posts[index] - posts[index] = ExpressPost( - id: post.id, - nickname: post.nickname, - targetName: post.targetName, - contentPreview: post.contentPreview, - publishTime: post.publishTime, - likeCount: post.likeCount + (post.isLiked ? 0 : 1), - commentCount: post.commentCount, - guessCount: post.guessCount, - correctGuessCount: post.correctGuessCount, - isLiked: true, - canGuess: post.canGuess, - selfGender: post.selfGender, - targetGender: post.targetGender - ) + posts[index] = post.with(likeCount: post.likeCount + (post.isLiked ? 0 : 1), isLiked: true) } } func guess(postID: String, name: String) async throws -> Bool { let matched = try await repository.guess(postID: postID, name: name) updatePost(postID: postID) { post in - ExpressPost( - id: post.id, - nickname: post.nickname, - targetName: post.targetName, - contentPreview: post.contentPreview, - publishTime: post.publishTime, - likeCount: post.likeCount, - commentCount: post.commentCount, - guessCount: post.guessCount + 1, - correctGuessCount: post.correctGuessCount + (matched ? 1 : 0), - isLiked: post.isLiked, - canGuess: post.canGuess, - selfGender: post.selfGender, - targetGender: post.targetGender - ) + post.with(guessCount: post.guessCount + 1, + correctGuessCount: post.correctGuessCount + (matched ? 1 : 0)) } return matched } diff --git a/GdeiAssistant-iOS/Features/Marketplace/Models/MarketplaceModels.swift b/GdeiAssistant-iOS/Features/Marketplace/Models/MarketplaceModels.swift index 9086c83..c3f955a 100644 --- a/GdeiAssistant-iOS/Features/Marketplace/Models/MarketplaceModels.swift +++ b/GdeiAssistant-iOS/Features/Marketplace/Models/MarketplaceModels.swift @@ -101,3 +101,68 @@ struct MarketplaceUpdateDraft: Codable { let qq: String let phone: String? } + +extension MarketplaceItem { + /// The single place that enumerates every stored field when copying an item. + /// `nil` means "keep the current value"; optional fields can only be replaced with a + /// non-nil value here. Reconstructing the struct by hand silently dropped `typeID`, + /// so an edited item kept showing its old category. + func with( + title: String? = nil, + price: Double? = nil, + summary: String? = nil, + sellerName: String? = nil, + sellerAvatarURL: String? = nil, + authorId: String? = nil, + postedAt: String? = nil, + location: String? = nil, + state: MarketplaceItemState? = nil, + tags: [String]? = nil, + previewImageURL: String? = nil, + typeID: Int? = nil + ) -> MarketplaceItem { + MarketplaceItem( + id: id, + title: title ?? self.title, + price: price ?? self.price, + summary: summary ?? self.summary, + sellerName: sellerName ?? self.sellerName, + sellerAvatarURL: sellerAvatarURL ?? self.sellerAvatarURL, + authorId: authorId ?? self.authorId, + postedAt: postedAt ?? self.postedAt, + location: location ?? self.location, + state: state ?? self.state, + tags: tags ?? self.tags, + previewImageURL: previewImageURL ?? self.previewImageURL, + typeID: typeID ?? self.typeID + ) + } +} + +extension MarketplaceDetail { + /// The single place that enumerates every stored field when copying a detail. + /// `nil` means "keep the current value". Reconstructing by hand silently reset + /// `ownedByCurrentUser`, which controls whether the owner sees the edit actions. + func with( + item: MarketplaceItem? = nil, + condition: String? = nil, + description: String? = nil, + contactHint: String? = nil, + imageURLs: [String]? = nil, + ownedByCurrentUser: Bool? = nil + ) -> MarketplaceDetail { + MarketplaceDetail( + item: item ?? self.item, + condition: condition ?? self.condition, + description: description ?? self.description, + contactHint: contactHint ?? self.contactHint, + sellerUsername: sellerUsername, + sellerNickname: sellerNickname, + sellerCollege: sellerCollege, + sellerMajor: sellerMajor, + sellerGrade: sellerGrade, + imageURLs: imageURLs ?? self.imageURLs, + ownedByCurrentUser: ownedByCurrentUser ?? self.ownedByCurrentUser + ) + } +} diff --git a/GdeiAssistant-iOS/Features/Marketplace/Repositories/MockMarketplaceRepository.swift b/GdeiAssistant-iOS/Features/Marketplace/Repositories/MockMarketplaceRepository.swift index 0f74530..f910ebb 100644 --- a/GdeiAssistant-iOS/Features/Marketplace/Repositories/MockMarketplaceRepository.swift +++ b/GdeiAssistant-iOS/Features/Marketplace/Repositories/MockMarketplaceRepository.swift @@ -107,67 +107,32 @@ final class MockMarketplaceRepository: MarketplaceRepository { throw NetworkError.server(code: 404, message: localizedString("marketplace.itemNotFound")) } let contactHintParts = contactHintParts(qq: draft.qq, phone: draft.phone) - let updatedItem = MarketplaceItem( - id: detail.item.id, + let category = MarketplaceRemoteMapper.displayName(forType: draft.typeID) + let updatedItem = detail.item.with( title: draft.title, price: draft.price, summary: RemoteMapperSupport.truncated(draft.description, limit: 28), - sellerName: detail.item.sellerName, - sellerAvatarURL: detail.item.sellerAvatarURL, - authorId: detail.item.authorId, postedAt: "刚刚修改", location: draft.location, - state: detail.item.state, - tags: [MarketplaceRemoteMapper.displayName(forType: draft.typeID)], - previewImageURL: detail.item.previewImageURL + tags: [category], + typeID: draft.typeID ) - detailsByID[itemID] = MarketplaceDetail( + detailsByID[itemID] = detail.with( item: updatedItem, - condition: MarketplaceRemoteMapper.displayName(forType: draft.typeID), + condition: category, description: draft.description, - contactHint: contactHintParts.joined(separator: " / "), - sellerUsername: detail.sellerUsername, - sellerNickname: detail.sellerNickname, - sellerCollege: detail.sellerCollege, - sellerMajor: detail.sellerMajor, - sellerGrade: detail.sellerGrade, - imageURLs: detail.imageURLs + contactHint: contactHintParts.joined(separator: " / ") ) syncItem(updatedItem) } func updateItemState(itemID: String, state: MarketplaceItemState) async throws { - guard var detail = detailsByID[itemID] else { + guard let detail = detailsByID[itemID] else { throw NetworkError.server(code: 404, message: localizedString("marketplace.itemNotFound")) } - let updatedItem = MarketplaceItem( - id: detail.item.id, - title: detail.item.title, - price: detail.item.price, - summary: detail.item.summary, - sellerName: detail.item.sellerName, - sellerAvatarURL: detail.item.sellerAvatarURL, - authorId: detail.item.authorId, - postedAt: detail.item.postedAt, - location: detail.item.location, - state: state, - tags: detail.item.tags, - previewImageURL: detail.item.previewImageURL - ) - detail = MarketplaceDetail( - item: updatedItem, - condition: detail.condition, - description: detail.description, - contactHint: detail.contactHint, - sellerUsername: detail.sellerUsername, - sellerNickname: detail.sellerNickname, - sellerCollege: detail.sellerCollege, - sellerMajor: detail.sellerMajor, - sellerGrade: detail.sellerGrade, - imageURLs: detail.imageURLs - ) - detailsByID[itemID] = detail + let updatedItem = detail.item.with(state: state) + detailsByID[itemID] = detail.with(item: updatedItem) syncItem(updatedItem) } diff --git a/GdeiAssistant-iOS/Features/Marketplace/Repositories/RemoteMarketplaceRepository.swift b/GdeiAssistant-iOS/Features/Marketplace/Repositories/RemoteMarketplaceRepository.swift index 7eb6275..3d8e0f9 100644 --- a/GdeiAssistant-iOS/Features/Marketplace/Repositories/RemoteMarketplaceRepository.swift +++ b/GdeiAssistant-iOS/Features/Marketplace/Repositories/RemoteMarketplaceRepository.swift @@ -38,32 +38,9 @@ final class RemoteMarketplaceRepository: MarketplaceRepository { return detail } - return MarketplaceDetail( - item: MarketplaceItem( - id: detail.item.id, - title: detail.item.title, - price: detail.item.price, - summary: detail.item.summary, - sellerName: detail.item.sellerName, - sellerAvatarURL: detail.item.sellerAvatarURL, - authorId: detail.item.authorId, - postedAt: detail.item.postedAt, - location: detail.item.location, - state: detail.item.state, - tags: detail.item.tags, - previewImageURL: detail.item.previewImageURL ?? previewURL, - typeID: detail.item.typeID - ), - condition: detail.condition, - description: detail.description, - contactHint: detail.contactHint, - sellerUsername: detail.sellerUsername, - sellerNickname: detail.sellerNickname, - sellerCollege: detail.sellerCollege, - sellerMajor: detail.sellerMajor, - sellerGrade: detail.sellerGrade, - imageURLs: [previewURL], - ownedByCurrentUser: detail.ownedByCurrentUser + return detail.with( + item: detail.item.with(previewImageURL: detail.item.previewImageURL ?? previewURL), + imageURLs: [previewURL] ) } diff --git a/GdeiAssistant-iOSTests/Express/ExpressPostCopyHelperTests.swift b/GdeiAssistant-iOSTests/Express/ExpressPostCopyHelperTests.swift new file mode 100644 index 0000000..028b513 --- /dev/null +++ b/GdeiAssistant-iOSTests/Express/ExpressPostCopyHelperTests.swift @@ -0,0 +1,80 @@ +import XCTest +@testable import GdeiAssistant_iOS + +/// The optimistic like / comment / guess counters used to be rebuilt with six full +/// memberwise constructions. This test keeps the single `with(...)` helper honest: +/// a new stored field changes the Mirror labels and fails the first assertion. +final class ExpressPostCopyHelperTests: XCTestCase { + + private func labels(_ value: Any) -> [String] { + Mirror(reflecting: value).children.compactMap { $0.label } + } + + private func fields(_ value: Any) -> [String: String] { + Dictionary(uniqueKeysWithValues: Mirror(reflecting: value).children.compactMap { child in + child.label.map { ($0, String(describing: child.value)) } + }) + } + + private func makePost() -> ExpressPost { + ExpressPost( + id: "express_test_001", + nickname: "小明", + targetName: "小红", + contentPreview: "内容预览", + publishTime: "昨天 20:00", + likeCount: 5, + commentCount: 2, + guessCount: 3, + correctGuessCount: 1, + isLiked: false, + canGuess: true, + selfGender: .male, + targetGender: .female + ) + } + + func testHelperNamesEveryStoredField() { + XCTAssertEqual(labels(makePost()), [ + "id", "nickname", "targetName", "contentPreview", "publishTime", + "likeCount", "commentCount", "guessCount", "correctGuessCount", + "isLiked", "canGuess", "selfGender", "targetGender" + ], "A new stored field must also be added to ExpressPost.with(...)") + } + + func testCopyKeepsEveryFieldItDoesNotChange() { + let original = makePost() + let copy = original.with(likeCount: 6, isLiked: true) + let before = fields(original) + let after = fields(copy) + let changed: Set = ["likeCount", "isLiked"] + + for (label, value) in before where !changed.contains(label) { + XCTAssertEqual(after[label], value, "\(label) was dropped by with(...)") + } + XCTAssertEqual(copy.likeCount, 6) + XCTAssertTrue(copy.isLiked) + XCTAssertEqual(original.likeCount, 5, "with(...) must not mutate the original") + XCTAssertFalse(original.isLiked) + } + + func testCounterUpdatesComposeWithoutLosingOtherCounters() { + let original = makePost() + let commented = original.with(commentCount: original.commentCount + 1) + let liked = commented.with(likeCount: commented.likeCount + 1, isLiked: true) + let guessed = liked.with( + guessCount: liked.guessCount + 1, + correctGuessCount: liked.correctGuessCount + 1 + ) + + XCTAssertEqual(guessed.commentCount, 3) + XCTAssertEqual(guessed.likeCount, 6) + XCTAssertEqual(guessed.guessCount, 4) + XCTAssertEqual(guessed.correctGuessCount, 2) + XCTAssertTrue(guessed.isLiked) + XCTAssertTrue(guessed.canGuess) + XCTAssertEqual(guessed.selfGender, .male) + XCTAssertEqual(guessed.targetGender, .female) + XCTAssertEqual(guessed.id, original.id) + } +} diff --git a/GdeiAssistant-iOSTests/Marketplace/MarketplaceCopyHelperTests.swift b/GdeiAssistant-iOSTests/Marketplace/MarketplaceCopyHelperTests.swift new file mode 100644 index 0000000..9e9ca7c --- /dev/null +++ b/GdeiAssistant-iOSTests/Marketplace/MarketplaceCopyHelperTests.swift @@ -0,0 +1,156 @@ +import XCTest +@testable import GdeiAssistant_iOS + +/// These tests pin the hidden link between a model's stored fields and its copy helper. +/// Adding a stored field changes the Mirror labels, so the label test fails until +/// `with(...)` is extended to carry the new field across. +final class MarketplaceCopyHelperTests: XCTestCase { + + private func labels(_ value: Any) -> [String] { + Mirror(reflecting: value).children.compactMap { $0.label } + } + + private func fields(_ value: Any) -> [String: String] { + Dictionary(uniqueKeysWithValues: Mirror(reflecting: value).children.compactMap { child in + child.label.map { ($0, String(describing: child.value)) } + }) + } + + private func makeItem(typeID: Int? = 4) -> MarketplaceItem { + MarketplaceItem( + id: "market_test_001", + title: "二手车", + price: 42.5, + summary: "九成新", + sellerName: "小明", + sellerAvatarURL: "https://example.com/avatar.png", + authorId: "user-demo-0001", + postedAt: "昨天", + location: "海珠校区", + state: .selling, + tags: ["交通工具"], + previewImageURL: "https://example.com/preview.png", + typeID: typeID + ) + } + + private func makeDetail() -> MarketplaceDetail { + MarketplaceDetail( + item: makeItem(), + condition: "交通工具", + description: "描述", + contactHint: "QQ 123456", + sellerUsername: "demo", + sellerNickname: "小明", + sellerCollege: "学院", + sellerMajor: "专业", + sellerGrade: "2023", + imageURLs: ["https://example.com/1.png"], + ownedByCurrentUser: true + ) + } + + func testItemHelperNamesEveryStoredField() { + XCTAssertEqual(labels(makeItem()), [ + "id", "title", "price", "summary", "sellerName", "sellerAvatarURL", + "authorId", "postedAt", "location", "state", "tags", "previewImageURL", "typeID" + ], "A new stored field must also be added to MarketplaceItem.with(...)") + } + + func testItemCopyKeepsEveryFieldItDoesNotChange() { + let original = makeItem() + let copy = original.with(state: .sold) + let before = fields(original) + let after = fields(copy) + + for (label, value) in before where label != "state" { + XCTAssertEqual(after[label], value, "\(label) was dropped by with(...)") + } + XCTAssertEqual(copy.state, .sold) + XCTAssertEqual(original.state, .selling, "with(...) must not mutate the original") + } + + func testItemCopyCanChangeTheCategory() { + let item = makeItem(typeID: 4) + + XCTAssertEqual(item.with(typeID: 9).typeID, 9) + XCTAssertEqual(item.typeID, 4) + } + + func testDetailHelperNamesEveryStoredField() { + XCTAssertEqual(labels(makeDetail()), [ + "item", "condition", "description", "contactHint", "sellerUsername", + "sellerNickname", "sellerCollege", "sellerMajor", "sellerGrade", + "imageURLs", "ownedByCurrentUser" + ], "A new stored field must also be added to MarketplaceDetail.with(...)") + } + + func testDetailCopyKeepsOwnershipAndSellerFields() { + let detail = makeDetail() + let copy = detail.with( + item: detail.item.with(state: .sold), + condition: "已售出", + imageURLs: [] + ) + + XCTAssertTrue(copy.ownedByCurrentUser) + XCTAssertEqual(copy.sellerUsername, "demo") + XCTAssertEqual(copy.sellerGrade, "2023") + XCTAssertEqual(copy.description, detail.description) + XCTAssertEqual(copy.contactHint, detail.contactHint) + XCTAssertEqual(copy.item.typeID, 4) + XCTAssertEqual(copy.item.state, .sold) + XCTAssertEqual(copy.condition, "已售出") + XCTAssertEqual(copy.imageURLs, []) + XCTAssertTrue(detail.ownedByCurrentUser, "with(...) must not mutate the original") + } +} + +@MainActor +final class MarketplaceCopyIntegrationTests: XCTestCase { + + private func editDraft(typeID: Int) -> MarketplaceUpdateDraft { + MarketplaceUpdateDraft( + title: "改过的标题", + price: 99, + description: "改过的描述", + location: "新地点", + typeID: typeID, + qq: "123456", + phone: nil + ) + } + + func testEditingAnItemAppliesTheNewCategory() async throws { + let repository = MockMarketplaceRepository() + let items = try await repository.fetchItems(typeID: nil) + guard let target = items.first(where: { $0.state == .selling }) else { + XCTFail("Expected a selling seed item") + return + } + + try await repository.updateItem(itemID: target.id, draft: editDraft(typeID: 3)) + + let updated = try await repository.fetchItems(typeID: nil).first { $0.id == target.id } + XCTAssertEqual(updated?.typeID, 3, "Editing must not silently drop the item category") + XCTAssertEqual(updated?.title, "改过的标题") + XCTAssertEqual(updated?.previewImageURL, target.previewImageURL) + } + + func testChangingStateKeepsTheEditedCategory() async throws { + let repository = MockMarketplaceRepository() + let items = try await repository.fetchItems(typeID: nil) + guard let target = items.first(where: { $0.state == .selling }) else { + XCTFail("Expected a selling seed item") + return + } + + try await repository.updateItem(itemID: target.id, draft: editDraft(typeID: 5)) + try await repository.updateItemState(itemID: target.id, state: .sold) + + let detail = try await repository.fetchItemDetail(itemID: target.id) + XCTAssertEqual(detail.item.typeID, 5) + XCTAssertEqual(detail.item.state, .sold) + XCTAssertEqual(detail.item.previewImageURL, target.previewImageURL) + } +} diff --git a/GdeiAssistant-iOSTests/Marketplace/MarketplaceViewModelTests.swift b/GdeiAssistant-iOSTests/Marketplace/MarketplaceViewModelTests.swift index 6c6fe00..e334cec 100644 --- a/GdeiAssistant-iOSTests/Marketplace/MarketplaceViewModelTests.swift +++ b/GdeiAssistant-iOSTests/Marketplace/MarketplaceViewModelTests.swift @@ -4,7 +4,7 @@ import XCTest @MainActor final class MarketplaceViewModelTests: XCTestCase { - func testInitialStateIsEmpty() { + func testInitialStateIsEmpty() async { let vm = MarketplaceViewModel(repository: MockMarketplaceRepository()) XCTAssertTrue(vm.items.isEmpty) diff --git a/GdeiAssistant-iOSTests/Profile/ProfileViewModelTests.swift b/GdeiAssistant-iOSTests/Profile/ProfileViewModelTests.swift index 1f45351..1e1b13f 100644 --- a/GdeiAssistant-iOSTests/Profile/ProfileViewModelTests.swift +++ b/GdeiAssistant-iOSTests/Profile/ProfileViewModelTests.swift @@ -277,7 +277,8 @@ final class ProfileViewModelTests: XCTestCase { XCTAssertEqual(viewModel.major, "软件工程") XCTAssertEqual(viewModel.location, "中国 广东 广州") - XCTAssertTrue(await viewModel.saveProfile()) + let saved = await viewModel.saveProfile() + XCTAssertTrue(saved) XCTAssertEqual(repository.updateRequests.last?.location?.cityCode, "1") XCTAssertEqual(repository.updateRequests.last?.hometown?.cityCode, "5") }