Skip to content

Commit 6b1b1cb

Browse files
committed
Avoid encoding custom fields when updating products
1 parent e716e33 commit 6b1b1cb

File tree

2 files changed

+64
-16
lines changed

2 files changed

+64
-16
lines changed

Modules/Sources/Networking/Model/Product/Product.swift

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -766,12 +766,9 @@ public struct Product: Codable, GeneratedCopiable, Equatable, GeneratedFakeable
766766
try container.encode(password, forKey: .password)
767767

768768
// Metadata
769-
var metaDataValuePairs = buildMetaDataValuePairs()
770-
771-
// Add custom fields to metadata
772-
let customFields = buildCustomFields()
773-
metaDataValuePairs.append(contentsOf: customFields)
774-
769+
let metaDataValuePairs = buildMetaDataValuePairs()
770+
// Custom fields will not be included in metadata - when updating products.
771+
// They are saved separately with `MetaDataStore`.
775772
// Encode metadata if it's not empty
776773
if metaDataValuePairs.isEmpty == false {
777774
try container.encode(metaDataValuePairs, forKey: .metadata)
@@ -785,16 +782,6 @@ public struct Product: Codable, GeneratedCopiable, Equatable, GeneratedFakeable
785782
}
786783
return metaDataArray
787784
}
788-
789-
// Function to get the custom fields
790-
private func buildCustomFields() -> [[String: String]] {
791-
var customFieldsArray: [[String: String]] = []
792-
for customField in customFields {
793-
customFieldsArray.append(["id": "\(customField.metadataID)", "key": customField.key, "value": customField.value.stringValue])
794-
}
795-
return customFieldsArray
796-
}
797-
798785
}
799786

800787
/// Defines all of the Product CodingKeys

Modules/Tests/NetworkingTests/Remote/ProductsRemoteTests.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,67 @@ final class ProductsRemoteTests: XCTestCase {
640640
}
641641
}
642642

643+
/// Verifies that updateProduct sends only subscription details in metadata and does not send custom fields.
644+
///
645+
func test_updateProduct_sends_only_subscription_in_metadata_not_custom_fields() throws {
646+
// Given
647+
let remote = ProductsRemote(network: network)
648+
network.simulateResponse(requestUrlSuffix: "products/\(sampleProductID)", filename: "product-update")
649+
650+
// Create a product with both custom fields and a subscription
651+
let customFields = [
652+
MetaData(metadataID: 1, key: "custom_field_1", value: "value_1"),
653+
MetaData(metadataID: 2, key: "custom_field_2", value: "value_2")
654+
]
655+
let subscription = ProductSubscription(
656+
length: "12",
657+
period: .month,
658+
periodInterval: "1",
659+
price: "9.99",
660+
signUpFee: "0",
661+
trialLength: "7",
662+
trialPeriod: .day,
663+
oneTimeShipping: false,
664+
paymentSyncDate: "0",
665+
paymentSyncMonth: ""
666+
)
667+
let product = sampleProduct().copy(subscription: subscription, customFields: customFields)
668+
669+
// When
670+
waitForExpectation { expectation in
671+
remote.updateProduct(product: product) { _ in
672+
expectation.fulfill()
673+
}
674+
}
675+
676+
// Then
677+
let parametersDictionary = try XCTUnwrap(network.queryParametersDictionary)
678+
679+
// Verify that metadata contains only subscription details, not custom fields
680+
if let metadata = parametersDictionary["meta_data"] as? [[String: Any]] {
681+
let metadataKeys = metadata.compactMap { $0["key"] as? String }
682+
683+
// Verify subscription metadata is present
684+
XCTAssertTrue(metadataKeys.contains("_subscription_length"), "Subscription length should be in metadata")
685+
XCTAssertTrue(metadataKeys.contains("_subscription_period"), "Subscription period should be in metadata")
686+
XCTAssertTrue(metadataKeys.contains("_subscription_period_interval"), "Subscription period interval should be in metadata")
687+
XCTAssertTrue(metadataKeys.contains("_subscription_price"), "Subscription price should be in metadata")
688+
XCTAssertTrue(metadataKeys.contains("_subscription_sign_up_fee"), "Subscription sign up fee should be in metadata")
689+
XCTAssertTrue(metadataKeys.contains("_subscription_trial_length"), "Subscription trial length should be in metadata")
690+
XCTAssertTrue(metadataKeys.contains("_subscription_trial_period"), "Subscription trial period should be in metadata")
691+
XCTAssertTrue(metadataKeys.contains("_subscription_one_time_shipping"), "Subscription one time shipping should be in metadata")
692+
693+
// Verify custom fields are NOT in metadata
694+
XCTAssertFalse(metadataKeys.contains("custom_field_1"), "Custom field 1 should not be sent in metadata")
695+
XCTAssertFalse(metadataKeys.contains("custom_field_2"), "Custom field 2 should not be sent in metadata")
696+
697+
// Verify metadata contains exactly 8 subscription fields and no custom fields
698+
XCTAssertEqual(metadata.count, 8, "Metadata should contain exactly 8 subscription fields")
699+
} else {
700+
XCTFail("Metadata should be present when product has subscription")
701+
}
702+
}
703+
643704
// MARK: - Update Product Images
644705

645706
/// Verifies that updateProductImages properly parses the `product-update` sample response.

0 commit comments

Comments
 (0)