From 32553bde714a8da7e2249676b7e18d875f10c5fc Mon Sep 17 00:00:00 2001 From: RafaelKayumov Date: Mon, 7 Jul 2025 14:26:47 +0300 Subject: [PATCH 1/2] Decode and map addresses array as a fallback --- .../Shipments/WooShippingConfigResponse.swift | 36 +++++++++++++++---- ...WooShippingLabelData+mapDestinations.swift | 7 ++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Modules/Sources/Networking/Model/ShippingLabel/Shipments/WooShippingConfigResponse.swift b/Modules/Sources/Networking/Model/ShippingLabel/Shipments/WooShippingConfigResponse.swift index 8c61279cb7d..52844b93ef4 100644 --- a/Modules/Sources/Networking/Model/ShippingLabel/Shipments/WooShippingConfigResponse.swift +++ b/Modules/Sources/Networking/Model/ShippingLabel/Shipments/WooShippingConfigResponse.swift @@ -107,6 +107,7 @@ public struct WooShippingLabelData: Decodable, Equatable { public extension WooShippingLabelData { typealias WooShippingLabelAddressMap = [String: WooShippingAddress] + typealias WooShippingLabelAddressArray = [WooShippingAddress] struct StoredData: Decodable, Equatable { let selectedDestinations: WooShippingLabelAddressMap? @@ -119,15 +120,38 @@ public extension WooShippingLabelData { public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - selectedDestinations = try? container.decodeIfPresent( - WooShippingLabelAddressMap.self, - forKey: CodingKeys.selectedDestination + selectedDestinations = Self.decodeAddresses( + from: container, + for: .selectedDestination ) - selectedOrigins = try? container.decodeIfPresent( - WooShippingLabelAddressMap.self, - forKey: CodingKeys.selectedOrigin + + selectedOrigins = Self.decodeAddresses( + from: container, + for: .selectedOrigin ) } + + private static func decodeAddresses( + from container: KeyedDecodingContainer, + for key: CodingKeys + ) -> WooShippingLabelAddressMap? { + if let addressesMap = try? container.decodeIfPresent( + WooShippingLabelAddressMap.self, + forKey: key + ) { + return addressesMap + } else if let addressesArray = try? container.decodeIfPresent( + WooShippingLabelAddressArray.self, + forKey: key + ) { + return addressesArray.enumerated().reduce(into: [:]) { result, address in + let formattedIDKey = WooShippingLabelData.formattedShipmentIDFromArrayIndex(address.offset) + result[formattedIDKey] = address.element + } + } + + return nil + } } } diff --git a/Modules/Sources/Networking/Model/ShippingLabel/Shipments/WooShippingLabelData+mapDestinations.swift b/Modules/Sources/Networking/Model/ShippingLabel/Shipments/WooShippingLabelData+mapDestinations.swift index b857f7f77e0..8cfb2a215b0 100644 --- a/Modules/Sources/Networking/Model/ShippingLabel/Shipments/WooShippingLabelData+mapDestinations.swift +++ b/Modules/Sources/Networking/Model/ShippingLabel/Shipments/WooShippingLabelData+mapDestinations.swift @@ -21,4 +21,11 @@ extension WooShippingLabelData { ) } } + + static func formattedShipmentIDFromArrayIndex(_ index: Int) -> String { + /// ID indexing starts from `1`. So the ID would be the index incremented by `1`. + return WooShippingShipmentIDFormatter.formattedShipmentID( + String(index + 1) + ) + } } From 119e6913c5efc9bb32f2855a0ca397ae3f0e8321 Mon Sep 17 00:00:00 2001 From: RafaelKayumov Date: Mon, 7 Jul 2025 14:37:34 +0300 Subject: [PATCH 2/2] Add tests for addresses array --- .../Remote/WooShippingRemoteTests.swift | 25 ++++++++- ...oshipping-config-with-addresses-array.json | 52 +++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 Modules/Tests/NetworkingTests/Responses/wooshipping-config-with-addresses-array.json diff --git a/Modules/Tests/NetworkingTests/Remote/WooShippingRemoteTests.swift b/Modules/Tests/NetworkingTests/Remote/WooShippingRemoteTests.swift index 51c4fd1ae52..03b95e3ceab 100644 --- a/Modules/Tests/NetworkingTests/Remote/WooShippingRemoteTests.swift +++ b/Modules/Tests/NetworkingTests/Remote/WooShippingRemoteTests.swift @@ -855,9 +855,9 @@ final class WooShippingRemoteTests: XCTestCase { XCTAssertNotNil(result.failure) } - // MARK: - Load Config With Destinations + // MARK: - Load Config With Addresses - func test_load_config_with_addresses_parses_success_response() throws { + func test_load_config_with_addresses_map_parses_success_response() throws { // Given let remote = WooShippingRemote(network: network) network.simulateResponse(requestUrlSuffix: "config/label-purchase/\(sampleOrderID)", filename: "wooshipping-config-with-addresses") @@ -878,6 +878,27 @@ final class WooShippingRemoteTests: XCTestCase { XCTAssertEqual(label.originAddress.address1, "Test origin address line") } + func test_load_config_with_addresses_array_parses_success_response() throws { + // Given + let remote = WooShippingRemote(network: network) + network.simulateResponse(requestUrlSuffix: "config/label-purchase/\(sampleOrderID)", filename: "wooshipping-config-with-addresses-array") + + // When + let result: Result = waitFor { promise in + remote.loadConfig(siteID: self.sampleSiteID, orderID: self.sampleOrderID) { result in + promise(result) + } + } + + // Then + let config = try XCTUnwrap(result.get()) + let label = try XCTUnwrap(config.shippingLabelData?.currentOrderLabels.first) + XCTAssertNotNil(label.destinationAddress) + XCTAssertEqual(label.destinationAddress.address1, "200 N SPRING ST") + XCTAssertNotNil(label.originAddress) + XCTAssertEqual(label.originAddress.address1, "Test origin address line") + } + func test_load_config_without_addresses_parses_success_response() throws { // Given let remote = WooShippingRemote(network: network) diff --git a/Modules/Tests/NetworkingTests/Responses/wooshipping-config-with-addresses-array.json b/Modules/Tests/NetworkingTests/Responses/wooshipping-config-with-addresses-array.json new file mode 100644 index 00000000000..233680a5b2e --- /dev/null +++ b/Modules/Tests/NetworkingTests/Responses/wooshipping-config-with-addresses-array.json @@ -0,0 +1,52 @@ +{ + "data": { + "config": { + "shippingLabelData": { + "storedData": { + "selected_destination": [ + { + "address_1": "200 N SPRING ST", + "city": "LOS ANGELES", + "state": "CA", + "postcode": "90012-4801", + "country": "US" + } + ], + "selected_origin": [ + { + "address_1": "Test origin address line", + "city": "Test origin city", + "state": "CA", + "postcode": "90012-4801", + "country": "US" + } + ] + }, + "currentOrderLabels": [ + { + "label_id": 4871, + "tracking": null, + "refundable_amount": 0, + "created": 1742292110723, + "carrier_id": "usps", + "service_name": "USPS - Priority Mail", + "status": "PURCHASE_IN_PROGRESS", + "commercial_invoice_url": "", + "is_commercial_invoice_submitted_electronically": false, + "package_name": "Small Flat Rate Box", + "is_letter": false, + "product_names": [ + "BG upload" + ], + "product_ids": [ + 522 + ], + "id": "1", + "receipt_item_id": -1, + "created_date": 1742292110000 + } + ] + } + } + } +}