From 6de9db0edd154d855a648bd1ea2113893ce5cb89 Mon Sep 17 00:00:00 2001 From: borisprimer <137198782+borisprimer@users.noreply.github.com> Date: Mon, 29 Apr 2024 12:42:02 +0200 Subject: [PATCH] fix: Fix parsing of the API response (#850) * Fix LinkedCardsComponent leaked continuation * Add parsing of simple response (String) * Add success response factory + add tests to cover redirect api * swiftlint fixes * Use same pattern for api client in linked cards component as in other components * inline init * remove custom string decoding * Update Sources/PrimerSDK/Classes/Services/Network/PrimerAPIClient.swift --------- Co-authored-by: Boris Nikolic Co-authored-by: Jack Newcombe Co-authored-by: Jack Newcombe --- .../project.pbxproj | 190 ------------------ .../Merchant Helpers/MerchantHelpers.swift | 2 +- .../NolPay/NolPayLinkedCardsComponent.swift | 4 +- .../Composable/PrimerHeadlessComposable.swift | 2 +- .../PCI/Services/DefaultNetworkService.swift | 1 + .../Factories/NetworkResponseFactory.swift | 52 +++-- .../Network/Legacy/URLSessionStack.swift | 2 +- .../Network/NetworkReportingService.swift | 6 +- .../Services/Network/SuccessResponse.swift | 3 +- .../HUC_TokenizationViewModelTests.swift | 2 +- .../PrimerAPIConfigurationModuleTests.swift | 2 +- .../NetworkResponseFactoryTests.swift | 22 ++ .../Services/DefaultNetworkServiceTests.swift | 48 ++++- Tests/Unit Tests/v2/MockAPIClient.swift | 2 +- 14 files changed, 116 insertions(+), 222 deletions(-) diff --git a/Debug App/Primer.io Debug App SPM.xcodeproj/project.pbxproj b/Debug App/Primer.io Debug App SPM.xcodeproj/project.pbxproj index 82cb62e269..df88c207d5 100644 --- a/Debug App/Primer.io Debug App SPM.xcodeproj/project.pbxproj +++ b/Debug App/Primer.io Debug App SPM.xcodeproj/project.pbxproj @@ -70,7 +70,6 @@ /* Begin PBXFileReference section */ 00E3C8FE62D22147335F2455 /* MerchantResultViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantResultViewController.swift; sourceTree = ""; }; 01C09DEAB07F42004B26A278 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/LaunchScreen.strings"; sourceTree = ""; }; - 021A00DEB01A46C876592575 /* ThreeDSProtocolVersionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeDSProtocolVersionTests.swift; sourceTree = ""; }; 0442C4062B7CE1E900EAD8EE /* TapGestureRecognizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TapGestureRecognizer.swift; sourceTree = ""; }; 049A055B2B4BF044002CEEBA /* MerchantHeadlessVaultManagerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MerchantHeadlessVaultManagerViewController.swift; sourceTree = ""; }; 04DFAADB2AAA01E60030FECE /* Debug App Tests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Debug App Tests-Info.plist"; sourceTree = ""; }; @@ -79,33 +78,19 @@ 0FD08B8CE57A11D1E35A8684 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/LaunchScreen.strings; sourceTree = ""; }; 13FA89917603E4BA5BB66AFC /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/LaunchScreen.strings; sourceTree = ""; }; 1594BC5C96ECC3F46C811B2F /* Data+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Extensions.swift"; sourceTree = ""; }; - 17476BFBED51F389FCE82F16 /* MockAPIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockAPIClient.swift; sourceTree = ""; }; - 1B8CB5A11A44AA9F3D7FE356 /* UserInterfaceModuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInterfaceModuleTests.swift; sourceTree = ""; }; 1D05E65C196E6715D7D8B0C6 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Main.strings; sourceTree = ""; }; 1F23211288F9B61390C0BF8D /* Pods_Debug_App_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Debug_App_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 229849A3DBE0858EE90673B9 /* CreateClientToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateClientToken.swift; sourceTree = ""; }; - 25FD540BEA16ABBDFE7DE182 /* PayPalService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayPalService.swift; sourceTree = ""; }; 2A328E38DA586FFE0ED2894B /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = ""; }; 2E64F057A39A91CA01CCB57F /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Main.strings; sourceTree = ""; }; - 2E8F69253D85350BB7A1A761 /* TokenizationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenizationService.swift; sourceTree = ""; }; - 31CFA93A373A7DB78DA77283 /* ApplePayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplePayTests.swift; sourceTree = ""; }; 33E18D5B5190C64631309D1B /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LaunchScreen.strings; sourceTree = ""; }; - 38DD0A9535544D446514124A /* CreateResumePaymentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateResumePaymentService.swift; sourceTree = ""; }; 39CCCB917D1881082ED75975 /* ViewController+Primer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ViewController+Primer.swift"; sourceTree = ""; }; 404E173A513B986A36F835F7 /* MerchantHeadlessCheckoutRawPhoneNumberDataViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantHeadlessCheckoutRawPhoneNumberDataViewController.swift; sourceTree = ""; }; - 49DFB1ACD5014BF28ED283B3 /* PollingModuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollingModuleTests.swift; sourceTree = ""; }; - 4A5E3ACDA26D44F66B55766B /* HUC_TokenizationViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUC_TokenizationViewModelTests.swift; sourceTree = ""; }; 4ACFB17A73AB7240BED98585 /* ExampleApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ExampleApp.entitlements; sourceTree = ""; }; 4C353D84EABA4990DAB4DD28 /* MerchantHeadlessCheckoutRawRetailDataViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantHeadlessCheckoutRawRetailDataViewController.swift; sourceTree = ""; }; 4E79C93EA805E87E1137A513 /* PaymentMethodCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethodCell.swift; sourceTree = ""; }; 52F54EC3C1ACE19DF48BD6E2 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/LaunchScreen.strings; sourceTree = ""; }; - 5AA706A14BACFDB8E5715788 /* HeadlessVaultManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlessVaultManagerTests.swift; sourceTree = ""; }; - 5D7EC742DEB5BE12252E3E5B /* PayPalServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayPalServiceTests.swift; sourceTree = ""; }; - 5DB3B88857B810440CDA881E /* DropInUI_TokenizationViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropInUI_TokenizationViewModelTests.swift; sourceTree = ""; }; - 5E8D7F3C53F8CCE4A03C975E /* VaultService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VaultService.swift; sourceTree = ""; }; - 5F8DC3341BDBB9AEDBE8D6DD /* DecodedClientToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecodedClientToken.swift; sourceTree = ""; }; 6493EA8D95DDA066DE982B24 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Main.strings; sourceTree = ""; }; - 6C690FB7E6E8C942C87B1A1B /* PrimerAPIConfigurationModuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimerAPIConfigurationModuleTests.swift; sourceTree = ""; }; 6D2261DDEE5DC5D2ED518037 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 6D665EEA8106E51925C3CF2B /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Main.strings; sourceTree = ""; }; 70D3D6CF0F006A06B7CEC71B /* TransactionResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionResponse.swift; sourceTree = ""; }; @@ -113,52 +98,29 @@ 72845A3010F10A88F2EC7849 /* CheckoutTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckoutTheme.swift; sourceTree = ""; }; 72E691B9A6A8EBB9F6A6B266 /* MerchantHeadlessCheckoutAvailablePaymentMethodsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantHeadlessCheckoutAvailablePaymentMethodsViewController.swift; sourceTree = ""; }; 743E00065B4A8D6C95092A23 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/LaunchScreen.strings; sourceTree = ""; }; - 743F107C464526926A34A433 /* PaymentMethodConfigServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethodConfigServiceTests.swift; sourceTree = ""; }; 7480FE5F665CC66C092BC95A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 752785ACCF65527C239391A8 /* PaymentMethodConfigTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethodConfigTests.swift; sourceTree = ""; }; 77E08473D1DF8C47A6EB61B2 /* Networking+Models.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Networking+Models.swift"; sourceTree = ""; }; - 7A3E75CD834937EF85DE1C14 /* MockVaultCheckoutViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockVaultCheckoutViewModel.swift; sourceTree = ""; }; - 7A5E6F7A9C12C69CB66032E3 /* IPay88Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPay88Tests.swift; sourceTree = ""; }; - 7EA7D2BB0AC0A1877DB2E6CE /* MockModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockModule.swift; sourceTree = ""; }; 8723ADDC2B8E0F5100A5FE23 /* MerchantHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MerchantHelpers.swift; sourceTree = ""; }; 8723ADDF2B8E0FAB00A5FE23 /* MerchantHeadlessKlarnaInitializationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MerchantHeadlessKlarnaInitializationView.swift; sourceTree = ""; }; 8723ADE02B8E0FAB00A5FE23 /* MerchantHeadlessKlarnaInitializationViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MerchantHeadlessKlarnaInitializationViewModel.swift; sourceTree = ""; }; 8723ADE12B8E0FAB00A5FE23 /* MerchantHeadlessKlarnaInitializationView+Elements.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MerchantHeadlessKlarnaInitializationView+Elements.swift"; sourceTree = ""; }; 8723ADE22B8E0FAB00A5FE23 /* MerchantHeadlessCheckoutKlarnaViewController+Klarna.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MerchantHeadlessCheckoutKlarnaViewController+Klarna.swift"; sourceTree = ""; }; 8723ADE32B8E0FAB00A5FE23 /* MerchantHeadlessCheckoutKlarnaViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MerchantHeadlessCheckoutKlarnaViewController.swift; sourceTree = ""; }; - 872A0647D4136E27365FB7F8 /* StringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringTests.swift; sourceTree = ""; }; - 8A23886804B13FA754E775D0 /* MockPaymentMethodTokenizationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPaymentMethodTokenizationViewModel.swift; sourceTree = ""; }; 8A3FDC6FE0EB5AB5828D4D80 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/LaunchScreen.strings; sourceTree = ""; }; - 8C7C082270CF1C6B7810F9B3 /* RawDataManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawDataManagerTests.swift; sourceTree = ""; }; 9128566126AA7F571FFECA3A /* Range+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Range+Extensions.swift"; sourceTree = ""; }; 92BE0A1A904DCEA405A11CC1 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Main.strings; sourceTree = ""; }; - 9314E0A4E884A8228611A030 /* IntExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntExtensionTests.swift; sourceTree = ""; }; 93F15C1E46C70C3D73B50F31 /* UIStackViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStackViewExtensions.swift; sourceTree = ""; }; 942332BD921CBCAFBC77BD6D /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Main.strings; sourceTree = ""; }; - 952364FBFD6FA09653ECA37E /* TokenizationServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenizationServiceTests.swift; sourceTree = ""; }; 98079137F3DE1FE6221DA7EC /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Main.strings; sourceTree = ""; }; 9874F439DA3EA5854A454687 /* MerchantDropInUIViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantDropInUIViewController.swift; sourceTree = ""; }; - 994AE6760B506D02499AEC90 /* CardComponentManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardComponentManagerTests.swift; sourceTree = ""; }; - 9D122A0B71B707C2110AB7F5 /* PayPalConfirmBillingAgreementTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayPalConfirmBillingAgreementTests.swift; sourceTree = ""; }; A1604A656AF654D7422A2A5E /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Main.strings; sourceTree = ""; }; A6AEF11B151368BF993C3EA9 /* TestScenario.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestScenario.swift; sourceTree = ""; }; - AD381E7E16D01D8D743232F7 /* ThemeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeTests.swift; sourceTree = ""; }; B18D7E7738BF86467B0F1465 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; B1FD8065D40A2D691F643F3B /* UIViewController+API.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+API.swift"; sourceTree = ""; }; - B266F9E1651BD20E45DCCF68 /* PrimerRawRetailerDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimerRawRetailerDataTests.swift; sourceTree = ""; }; B866FF13033A5CB8B4C3388E /* MerchantHeadlessCheckoutRawDataViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantHeadlessCheckoutRawDataViewController.swift; sourceTree = ""; }; - B9813BD518AC7C3F442B5075 /* PrimerCheckoutTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimerCheckoutTheme.swift; sourceTree = ""; }; - BA0B2BEE5C389FD13E210847 /* DateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTests.swift; sourceTree = ""; }; - BD26E8C6074BB89ACBD5B8B9 /* MaskTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MaskTests.swift; sourceTree = ""; }; - BF8639891B79E2FCCE10A510 /* ThreeDSErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeDSErrorTests.swift; sourceTree = ""; }; C18C9664115CFDEB59FED19A /* MerchantSessionAndSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantSessionAndSettingsViewController.swift; sourceTree = ""; }; C4DFE77F28AB538220A0F6EE /* ka */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ka; path = ka.lproj/Main.strings; sourceTree = ""; }; - C7D8E1E91CA11EC6831ADEE4 /* EncodingDecodingContainerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncodingDecodingContainerTests.swift; sourceTree = ""; }; C7EB86C62BA46BF51C64ABC2 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/LaunchScreen.strings; sourceTree = ""; }; - CA30891B2D5F9B6B97E56B99 /* WebViewUtilTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewUtilTests.swift; sourceTree = ""; }; - D038BDB23C062D362AAA09BE /* Networking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Networking.swift; sourceTree = ""; }; - D0A003705AFF7F922BCFE75F /* TokenizationResponseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenizationResponseTests.swift; sourceTree = ""; }; - D3D9154BF1E011FED6799CD5 /* CardData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardData.swift; sourceTree = ""; }; D4139D8F153BB399DA67F2EE /* ViewController+PrimerUIHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ViewController+PrimerUIHelpers.swift"; sourceTree = ""; }; D5C1B1F65A9382606A25CE77 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Main.strings; sourceTree = ""; }; DAC5687FF32E8661F1A00CE5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -170,19 +132,14 @@ E11F475B2B06C5A40091C31F /* ImageViewWithUrl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageViewWithUrl.swift; sourceTree = ""; }; E1AB44CF2AFE139600639DC5 /* URL+NetworkHeaders.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+NetworkHeaders.swift"; sourceTree = ""; }; E1C3EF0BA039C0A50EDE13A5 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Main.strings; sourceTree = ""; }; - E63F5C5C1FD2F3E6CB02EC5A /* HeadlessUniversalCheckoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlessUniversalCheckoutTests.swift; sourceTree = ""; }; E7640DB186F9638C2F556F77 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Main.strings; sourceTree = ""; }; E8DE1E4FB055B60582977315 /* Networking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Networking.swift; sourceTree = ""; }; - E9899972360BCA5992CEE5BC /* PrimerBancontactCardDataManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimerBancontactCardDataManagerTests.swift; sourceTree = ""; }; EB6C18F747AEC20B8C63164C /* Pods_Debug_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Debug_App.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - EEB1E1B37192BF739461AFF1 /* PrimerRawCardDataManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimerRawCardDataManagerTests.swift; sourceTree = ""; }; F00C661E2ACC67FA00187028 /* Debug App SPM.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Debug App SPM.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - F03699582AC2E63700E4179D /* VersionUtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionUtilsTests.swift; sourceTree = ""; }; F04510DE2ACD4EA500A0A48C /* primer-sdk-ios */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "primer-sdk-ios"; path = ..; sourceTree = ""; }; F08F63DF2BA0BE83006EF9A9 /* SessionConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SessionConfiguration.swift; sourceTree = ""; }; F08F63E12BA0BEAD006EF9A9 /* AppetizeConfigProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppetizeConfigProvider.swift; sourceTree = ""; }; F08F63E22BA0BEAD006EF9A9 /* MetadataParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetadataParser.swift; sourceTree = ""; }; - F4AC1EC0F98CB56DA4D075CA /* Mocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mocks.swift; sourceTree = ""; }; F816A2444633C4336A7CB071 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = ""; }; F9023841AFCE8E3205CB713A /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = ""; }; FB1F71737862EF5D0F4FE5AB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; @@ -260,13 +217,6 @@ path = "Localized Views"; sourceTree = ""; }; - 2F23D3C9CC9CBC1B95329B1C /* Network */ = { - isa = PBXGroup; - children = ( - ); - path = Network; - sourceTree = ""; - }; 553A7EDE72B8249F55A0E6B9 /* Extension */ = { isa = PBXGroup; children = ( @@ -281,27 +231,6 @@ path = Extension; sourceTree = ""; }; - 5836043C1C4E5A1CF7B81CDD /* Services */ = { - isa = PBXGroup; - children = ( - 994AE6760B506D02499AEC90 /* CardComponentManagerTests.swift */, - 743F107C464526926A34A433 /* PaymentMethodConfigServiceTests.swift */, - 5D7EC742DEB5BE12252E3E5B /* PayPalServiceTests.swift */, - 952364FBFD6FA09653ECA37E /* TokenizationServiceTests.swift */, - ); - path = Services; - sourceTree = ""; - }; - 5CC7BF9D8A0A9D8490C48151 /* Primer */ = { - isa = PBXGroup; - children = ( - E9899972360BCA5992CEE5BC /* PrimerBancontactCardDataManagerTests.swift */, - EEB1E1B37192BF739461AFF1 /* PrimerRawCardDataManagerTests.swift */, - B266F9E1651BD20E45DCCF68 /* PrimerRawRetailerDataTests.swift */, - ); - path = Primer; - sourceTree = ""; - }; 5E99BB590FD6521F2D5403BB /* Sources */ = { isa = PBXGroup; children = ( @@ -325,25 +254,6 @@ name = Frameworks; sourceTree = ""; }; - 61C1263B3C114C5B0A1E5AB4 /* Services */ = { - isa = PBXGroup; - children = ( - 38DD0A9535544D446514124A /* CreateResumePaymentService.swift */, - 25FD540BEA16ABBDFE7DE182 /* PayPalService.swift */, - 2E8F69253D85350BB7A1A761 /* TokenizationService.swift */, - 5E8D7F3C53F8CCE4A03C975E /* VaultService.swift */, - ); - path = Services; - sourceTree = ""; - }; - 626776D8EFEF24D5C5A36307 /* Extensions */ = { - isa = PBXGroup; - children = ( - C7D8E1E91CA11EC6831ADEE4 /* EncodingDecodingContainerTests.swift */, - ); - path = Extensions; - sourceTree = ""; - }; 64FB843527A1671D550B536F /* Network */ = { isa = PBXGroup; children = ( @@ -375,87 +285,6 @@ path = KlarnaHeadless; sourceTree = ""; }; - 9EE81958BB2BB34183F6C0AB /* Modules */ = { - isa = PBXGroup; - children = ( - 5DB3B88857B810440CDA881E /* DropInUI_TokenizationViewModelTests.swift */, - 4A5E3ACDA26D44F66B55766B /* HUC_TokenizationViewModelTests.swift */, - 49DFB1ACD5014BF28ED283B3 /* PollingModuleTests.swift */, - 6C690FB7E6E8C942C87B1A1B /* PrimerAPIConfigurationModuleTests.swift */, - 1B8CB5A11A44AA9F3D7FE356 /* UserInterfaceModuleTests.swift */, - ); - path = Modules; - sourceTree = ""; - }; - A95565BDB7031F41ECD023D7 /* Helpers */ = { - isa = PBXGroup; - children = ( - D3D9154BF1E011FED6799CD5 /* CardData.swift */, - D038BDB23C062D362AAA09BE /* Networking.swift */, - ); - path = Helpers; - sourceTree = ""; - }; - ACC4CBBD9744630CB46A5EE4 /* v2 */ = { - isa = PBXGroup; - children = ( - E63F5C5C1FD2F3E6CB02EC5A /* HeadlessUniversalCheckoutTests.swift */, - 5AA706A14BACFDB8E5715788 /* HeadlessVaultManagerTests.swift */, - 17476BFBED51F389FCE82F16 /* MockAPIClient.swift */, - 7EA7D2BB0AC0A1877DB2E6CE /* MockModule.swift */, - 8C7C082270CF1C6B7810F9B3 /* RawDataManagerTests.swift */, - ); - path = v2; - sourceTree = ""; - }; - C8A971C6C0021F0115DF44CC /* Utils */ = { - isa = PBXGroup; - children = ( - BA0B2BEE5C389FD13E210847 /* DateTests.swift */, - 9314E0A4E884A8228611A030 /* IntExtensionTests.swift */, - BD26E8C6074BB89ACBD5B8B9 /* MaskTests.swift */, - 872A0647D4136E27365FB7F8 /* StringTests.swift */, - CA30891B2D5F9B6B97E56B99 /* WebViewUtilTests.swift */, - F03699582AC2E63700E4179D /* VersionUtilsTests.swift */, - ); - path = Utils; - sourceTree = ""; - }; - D83EED4C1249B62B908781B0 /* Data Models */ = { - isa = PBXGroup; - children = ( - 31CFA93A373A7DB78DA77283 /* ApplePayTests.swift */, - 5F8DC3341BDBB9AEDBE8D6DD /* DecodedClientToken.swift */, - 7A5E6F7A9C12C69CB66032E3 /* IPay88Tests.swift */, - 752785ACCF65527C239391A8 /* PaymentMethodConfigTests.swift */, - 9D122A0B71B707C2110AB7F5 /* PayPalConfirmBillingAgreementTests.swift */, - B9813BD518AC7C3F442B5075 /* PrimerCheckoutTheme.swift */, - AD381E7E16D01D8D743232F7 /* ThemeTests.swift */, - BF8639891B79E2FCCE10A510 /* ThreeDSErrorTests.swift */, - 021A00DEB01A46C876592575 /* ThreeDSProtocolVersionTests.swift */, - D0A003705AFF7F922BCFE75F /* TokenizationResponseTests.swift */, - ); - path = "Data Models"; - sourceTree = ""; - }; - D99811C39E1808A948623732 /* Unit Tests */ = { - isa = PBXGroup; - children = ( - D83EED4C1249B62B908781B0 /* Data Models */, - 626776D8EFEF24D5C5A36307 /* Extensions */, - A95565BDB7031F41ECD023D7 /* Helpers */, - E4C8DBB82E4149A7C4D26467 /* Mocks */, - 9EE81958BB2BB34183F6C0AB /* Modules */, - 2F23D3C9CC9CBC1B95329B1C /* Network */, - 5CC7BF9D8A0A9D8490C48151 /* Primer */, - 5836043C1C4E5A1CF7B81CDD /* Services */, - C8A971C6C0021F0115DF44CC /* Utils */, - ACC4CBBD9744630CB46A5EE4 /* v2 */, - F4AC1EC0F98CB56DA4D075CA /* Mocks.swift */, - ); - path = "Unit Tests"; - sourceTree = ""; - }; D9AC6F54A87D432982864A63 /* Model */ = { isa = PBXGroup; children = ( @@ -472,19 +301,10 @@ isa = PBXGroup; children = ( 04DFAADB2AAA01E60030FECE /* Debug App Tests-Info.plist */, - D99811C39E1808A948623732 /* Unit Tests */, ); path = Tests; sourceTree = ""; }; - DAAB90DB09F0793B3580DE69 /* ViewModels */ = { - isa = PBXGroup; - children = ( - 7A3E75CD834937EF85DE1C14 /* MockVaultCheckoutViewModel.swift */, - ); - path = ViewModels; - sourceTree = ""; - }; DF30711EB149C64C364BB79A /* Products */ = { isa = PBXGroup; children = ( @@ -504,16 +324,6 @@ path = FormWithRedirect; sourceTree = ""; }; - E4C8DBB82E4149A7C4D26467 /* Mocks */ = { - isa = PBXGroup; - children = ( - 61C1263B3C114C5B0A1E5AB4 /* Services */, - DAAB90DB09F0793B3580DE69 /* ViewModels */, - 8A23886804B13FA754E775D0 /* MockPaymentMethodTokenizationViewModel.swift */, - ); - path = Mocks; - sourceTree = ""; - }; EF5FBE3673FBCB40F55F4DC0 /* New UI */ = { isa = PBXGroup; children = ( diff --git a/Debug App/Sources/View Controllers/Merchant Helpers/MerchantHelpers.swift b/Debug App/Sources/View Controllers/Merchant Helpers/MerchantHelpers.swift index 447e5290ac..c12c2633a7 100644 --- a/Debug App/Sources/View Controllers/Merchant Helpers/MerchantHelpers.swift +++ b/Debug App/Sources/View Controllers/Merchant Helpers/MerchantHelpers.swift @@ -81,7 +81,7 @@ struct MerchantMockDataManager { static var genericPaymentMethod = ClientSessionRequestBody.PaymentMethod( vaultOnSuccess: false, options: nil, - descriptor: nil, + descriptor: "Random descriptor", paymentType: nil ) diff --git a/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Composable/NolPay/NolPayLinkedCardsComponent.swift b/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Composable/NolPay/NolPayLinkedCardsComponent.swift index 805bc098b1..2cb89f4965 100644 --- a/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Composable/NolPay/NolPayLinkedCardsComponent.swift +++ b/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Composable/NolPay/NolPayLinkedCardsComponent.swift @@ -22,7 +22,6 @@ public class NolPayLinkedCardsComponent { var mobileNumber: String? var countryCode: String? var phoneMetadataService: NolPayPhoneMetadataProviding? - var apiClient: PrimerAPIClientProtocol? public init() {} @@ -96,8 +95,9 @@ public class NolPayLinkedCardsComponent { phoneVendor: "Apple", phoneModel: UIDevice.modelIdentifier!) + let client = PrimerAPIClient() return try await withCheckedThrowingContinuation { continuation in - self.apiClient?.fetchNolSdkSecret(clientToken: clientToken, paymentRequestBody: requestBody) { result in + client.fetchNolSdkSecret(clientToken: clientToken, paymentRequestBody: requestBody) { result in switch result { case .success(let appSecret): continuation.resume(returning: appSecret.sdkSecret) diff --git a/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Composable/PrimerHeadlessComposable.swift b/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Composable/PrimerHeadlessComposable.swift index ef2eedfc8a..a9c3c42a71 100644 --- a/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Composable/PrimerHeadlessComposable.swift +++ b/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Composable/PrimerHeadlessComposable.swift @@ -76,7 +76,7 @@ extension PrimerHeadlessCollectDataComponent { let error = PrimerError.invalidValue(key: key, value: nil, userInfo: .errorUserInfoDictionary(), - diagnosticsId: UUID().uuidString) + diagnosticsId: UUID().uuidString) ErrorHandler.handle(error: error) self.errorDelegate?.didReceiveError(error: error) } diff --git a/Sources/PrimerSDK/Classes/PCI/Services/DefaultNetworkService.swift b/Sources/PrimerSDK/Classes/PCI/Services/DefaultNetworkService.swift index d6dbd375bc..3ff9b5aff8 100644 --- a/Sources/PrimerSDK/Classes/PCI/Services/DefaultNetworkService.swift +++ b/Sources/PrimerSDK/Classes/PCI/Services/DefaultNetworkService.swift @@ -97,6 +97,7 @@ class DefaultNetworkService: NetworkService, LogReporter { } catch { completion(.failure(error)) } + } } catch { ErrorHandler.handle(error: error) diff --git a/Sources/PrimerSDK/Classes/PCI/Services/Network/Factories/NetworkResponseFactory.swift b/Sources/PrimerSDK/Classes/PCI/Services/Network/Factories/NetworkResponseFactory.swift index 36d38482cf..a824ec03db 100644 --- a/Sources/PrimerSDK/Classes/PCI/Services/Network/Factories/NetworkResponseFactory.swift +++ b/Sources/PrimerSDK/Classes/PCI/Services/Network/Factories/NetworkResponseFactory.swift @@ -13,10 +13,26 @@ protocol NetworkResponseFactory: AnyObject { extension Endpoint { var responseFactory: NetworkResponseFactory { - switch self { - default: - return JSONNetworkResponseFactory() + if let endpoint = self as? PrimerAPI { + switch endpoint { + case .redirect: + return SuccessResponseFactory() + default: + break + } } + return JSONNetworkResponseFactory() + } +} + +class SuccessResponseFactory: NetworkResponseFactory { + func model(for response: Data, forMetadata metadata: any ResponseMetadata) throws -> T where T: Decodable { + if let response = SuccessResponse() as? T { + return response + } + throw InternalError.failedToDecode(message: "SuccessResponse model must be used with this endpoint", + userInfo: .errorUserInfoDictionary(), + diagnosticsId: UUID().uuidString) } } @@ -25,7 +41,6 @@ class JSONNetworkResponseFactory: NetworkResponseFactory, LogReporter { let decoder = JSONDecoder() func model(for response: Data, forMetadata metadata: ResponseMetadata) throws -> T where T: Decodable { - log(data: response, metadata: metadata) switch metadata.statusCode { @@ -33,24 +48,27 @@ class JSONNetworkResponseFactory: NetworkResponseFactory, LogReporter { do { return try decoder.decode(T.self, from: response) } catch { - throw InternalError.failedToDecode(message: "Failed to decode response of type '\(T.self)' from URL: \(metadata.responseUrl ?? "Unknown")", - userInfo: .errorUserInfoDictionary(), - diagnosticsId: UUID().uuidString) + throw InternalError.failedToDecode( + message: "Failed to decode response of type '\(T.self)' from URL: \(metadata.responseUrl ?? "Unknown")", + userInfo: .errorUserInfoDictionary(), + diagnosticsId: UUID().uuidString + ) } case 400...599: let serverError = try? decoder.decode(PrimerServerErrorResponse.self, from: response) - throw InternalError.serverError(status: metadata.statusCode, - response: serverError?.error, - userInfo: .errorUserInfoDictionary(), - diagnosticsId: UUID().uuidString) + throw InternalError.serverError( + status: metadata.statusCode, + response: serverError?.error, + userInfo: .errorUserInfoDictionary(), + diagnosticsId: UUID().uuidString + ) default: - break + throw InternalError.failedToDecode( + message: "Failed to determine response from URL: \(metadata.responseUrl ?? "Unknown")", + userInfo: .errorUserInfoDictionary(), + diagnosticsId: UUID().uuidString + ) } - - throw InternalError.failedToDecode(message: "Failed to determine response from URL: \(metadata.responseUrl ?? "Unknown")", - userInfo: .errorUserInfoDictionary(), - diagnosticsId: UUID().uuidString) - } func log(data: Data, metadata: ResponseMetadata) { diff --git a/Sources/PrimerSDK/Classes/PCI/Services/Network/Legacy/URLSessionStack.swift b/Sources/PrimerSDK/Classes/PCI/Services/Network/Legacy/URLSessionStack.swift index 854eb67774..c6075ebbeb 100644 --- a/Sources/PrimerSDK/Classes/PCI/Services/Network/Legacy/URLSessionStack.swift +++ b/Sources/PrimerSDK/Classes/PCI/Services/Network/Legacy/URLSessionStack.swift @@ -180,7 +180,7 @@ internal class URLSessionStack: NetworkService, LogReporter { #endif if endpoint.shouldParseResponseBody == false, httpResponse?.statusCode == 200 { - guard let dummyRes: T = DummySuccess(success: true) as? T + guard let dummyRes: T = DummySuccess() as? T else { fatalError() } diff --git a/Sources/PrimerSDK/Classes/PCI/Services/Network/NetworkReportingService.swift b/Sources/PrimerSDK/Classes/PCI/Services/Network/NetworkReportingService.swift index 82f25b23cd..e1c4dfb0a8 100644 --- a/Sources/PrimerSDK/Classes/PCI/Services/Network/NetworkReportingService.swift +++ b/Sources/PrimerSDK/Classes/PCI/Services/Network/NetworkReportingService.swift @@ -15,8 +15,8 @@ enum NetworkEventType { var endpoint: Endpoint { switch self { case .requestStart(_, let endpoint, _), - .requestEnd(_, let endpoint, _), - .networkConnectivity(let endpoint): + .requestEnd(_, let endpoint, _), + .networkConnectivity(let endpoint): return endpoint } } @@ -78,7 +78,7 @@ class DefaultNetworkReportingService: NetworkReportingService { return false } guard let baseURL = primerAPI.baseURL, let url = URL(string: baseURL), - !disallowedTrackingPaths.contains(url.path) else { + !disallowedTrackingPaths.contains(url.path) else { return false } return true diff --git a/Sources/PrimerSDK/Classes/Services/Network/SuccessResponse.swift b/Sources/PrimerSDK/Classes/Services/Network/SuccessResponse.swift index 5568db94d2..43fe0627f3 100644 --- a/Sources/PrimerSDK/Classes/Services/Network/SuccessResponse.swift +++ b/Sources/PrimerSDK/Classes/Services/Network/SuccessResponse.swift @@ -9,6 +9,5 @@ import Foundation typealias DummySuccess = SuccessResponse -internal struct SuccessResponse: Codable { - let success: Bool +internal struct SuccessResponse: Codable, Equatable { } diff --git a/Tests/Unit Tests/Modules/HUC_TokenizationViewModelTests.swift b/Tests/Unit Tests/Modules/HUC_TokenizationViewModelTests.swift index 141239cfe8..a8ffdacfe7 100644 --- a/Tests/Unit Tests/Modules/HUC_TokenizationViewModelTests.swift +++ b/Tests/Unit Tests/Modules/HUC_TokenizationViewModelTests.swift @@ -295,7 +295,7 @@ final class HUC_TokenizationViewModelTests: XCTestCase { PrimerAPIConfigurationModule.apiConfiguration = apiConfiguration let mockApiClient = MockPrimerAPIClient() - mockApiClient.validateClientTokenResult = (SuccessResponse(success: true), nil) + mockApiClient.validateClientTokenResult = (SuccessResponse(), nil) mockApiClient.pollingResults = [ (PollingResponse(status: .pending, id: "0", source: "src"), nil), (nil, NSError(domain: "dummy-network-error", code: 100)), diff --git a/Tests/Unit Tests/Modules/PrimerAPIConfigurationModuleTests.swift b/Tests/Unit Tests/Modules/PrimerAPIConfigurationModuleTests.swift index 2495673958..e6a6766253 100644 --- a/Tests/Unit Tests/Modules/PrimerAPIConfigurationModuleTests.swift +++ b/Tests/Unit Tests/Modules/PrimerAPIConfigurationModuleTests.swift @@ -26,7 +26,7 @@ class PrimerAPIConfigurationModuleTests: XCTestCase { checkoutModules: nil) let mockApiClient = MockPrimerAPIClient() - mockApiClient.validateClientTokenResult = (SuccessResponse(success: true), nil) + mockApiClient.validateClientTokenResult = (SuccessResponse(), nil) mockApiClient.fetchConfigurationResult = (mockPrimerAPIConfiguration, nil) PrimerAPIConfigurationModule.apiClient = mockApiClient diff --git a/Tests/Unit Tests/Network/Factories/NetworkResponseFactoryTests.swift b/Tests/Unit Tests/Network/Factories/NetworkResponseFactoryTests.swift index c32f37a01e..91d2115b6b 100644 --- a/Tests/Unit Tests/Network/Factories/NetworkResponseFactoryTests.swift +++ b/Tests/Unit Tests/Network/Factories/NetworkResponseFactoryTests.swift @@ -30,6 +30,28 @@ final class NetworkResponseFactoryTests: XCTestCase { XCTAssertEqual(model, responseModel) } + func testResponseCreation_Empty_Success() throws { + let model = SuccessResponse() + let metadata = ResponseMetadataModel(responseUrl: "a_url", statusCode: 200, headers: nil) + + let successResponseFactory = SuccessResponseFactory() + let responseModel: SuccessResponse = try successResponseFactory.model(for: Data(), + forMetadata: metadata) + XCTAssertEqual(model, responseModel) + } + + func testResponseCreation_NonJsonToEmpty_Success() throws { + let model = SuccessResponse() + let metadata = ResponseMetadataModel(responseUrl: "a_url", statusCode: 200, headers: nil) + + let jsonNetworkResponseFactory = SuccessResponseFactory() + let string = "test" + let responseModel: SuccessResponse = try jsonNetworkResponseFactory.model(for: string.data(using: .utf8)!, + forMetadata: metadata) + + XCTAssertEqual(model, responseModel) + } + func testResponseCreation_Empty_Failure() throws { let jsonNetworkResponseFactory = JSONNetworkResponseFactory() let metadata = ResponseMetadataModel(responseUrl: "a_url", statusCode: 200, headers: nil) diff --git a/Tests/Unit Tests/Network/Services/DefaultNetworkServiceTests.swift b/Tests/Unit Tests/Network/Services/DefaultNetworkServiceTests.swift index e98338d3ed..e3d556229e 100644 --- a/Tests/Unit Tests/Network/Services/DefaultNetworkServiceTests.swift +++ b/Tests/Unit Tests/Network/Services/DefaultNetworkServiceTests.swift @@ -50,7 +50,7 @@ final class DefaultNetworkServiceTests: XCTestCase { requestDispatcher = nil } - func testBasicRequest_success_sync() throws { + func testBasicRequest_jsonDecodingSuccess_sync() throws { let expectation = self.expectation(description: "Successful response") @@ -92,7 +92,7 @@ final class DefaultNetworkServiceTests: XCTestCase { waitForExpectations(timeout: 2.0) } - func testBasicRequest_decodingFailure_sync() throws { + func testBasicRequest_jsonDecodingFailure_sync() throws { let expectation = self.expectation(description: "Fails with decoding error") @@ -122,4 +122,48 @@ final class DefaultNetworkServiceTests: XCTestCase { } + func testRedirectRequest_successWithEmptyResponse_sync() { + let expectation = self.expectation(description: "Fails with decoding error") + + let metadata = ResponseMetadataModel(responseUrl: "https://response_url", statusCode: 200, headers: ["X-Test-Key": "X-Test-Value"]) + let data = Data() + requestDispatcher.responseModel = DispatcherResponseModel(metadata: metadata, data: data, error: nil) + + let endpoint = PrimerAPI.redirect(clientToken: Mocks.decodedJWTToken, url: URL(string: metadata.responseUrl!)!) + let cancellable = defaultNetworkService.request(endpoint) { (result: APIResult) in + switch result { + case .success(_): + expectation.fulfill() + case .failure(let error): + XCTFail(); return + } + } + + XCTAssertNil(cancellable) + + waitForExpectations(timeout: 2.0) + } + + func testRedirectRequest_successWithNonJsonResponse_sync() { + let expectation = self.expectation(description: "Fails with decoding error") + + let metadata = ResponseMetadataModel(responseUrl: "https://response_url", statusCode: 200, headers: ["X-Test-Key": "X-Test-Value"]) + let data = "test".data(using: .utf8) + requestDispatcher.responseModel = DispatcherResponseModel(metadata: metadata, data: data, error: nil) + + let endpoint = PrimerAPI.redirect(clientToken: Mocks.decodedJWTToken, url: URL(string: metadata.responseUrl!)!) + let cancellable = defaultNetworkService.request(endpoint) { (result: APIResult) in + switch result { + case .success(_): + expectation.fulfill() + case .failure(let error): + XCTFail(); return + } + } + + XCTAssertNil(cancellable) + + waitForExpectations(timeout: 2.0) + } + } diff --git a/Tests/Unit Tests/v2/MockAPIClient.swift b/Tests/Unit Tests/v2/MockAPIClient.swift index 3be803ad99..4c9112ca86 100644 --- a/Tests/Unit Tests/v2/MockAPIClient.swift +++ b/Tests/Unit Tests/v2/MockAPIClient.swift @@ -614,7 +614,7 @@ extension MockPrimerAPIClient { class Samples { - static let mockValidateClientToken: SuccessResponse = SuccessResponse(success: true) + static let mockValidateClientToken: SuccessResponse = SuccessResponse() static let mockPrimerAPIConfiguration = Response.Body.Configuration( coreUrl: "https://primer.io/core", pciUrl: "https://primer.io/pci",