Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions Networking/Networking/Model/Product/Product.swift
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,12 @@ public struct Product: Codable, GeneratedCopiable, Equatable, GeneratedFakeable

let fullDescription = try container.decodeIfPresent(String.self, forKey: .fullDescription)
let shortDescription = try container.decodeIfPresent(String.self, forKey: .shortDescription)
let sku = try container.decodeIfPresent(String.self, forKey: .sku)

// Even though a plain install of WooCommerce Core provides String values,
// some plugins alter the field value from String to Int or Decimal.
let sku = container.failsafeDecodeIfPresent(targetType: String.self,
forKey: .sku,
alternativeTypes: [.decimal(transform: { NSDecimalNumber(decimal: $0).stringValue })])

// Even though a plain install of WooCommerce Core provides string values,
// some plugins alter the field value from String to Int or Decimal.
Expand Down Expand Up @@ -424,7 +429,12 @@ public struct Product: Codable, GeneratedCopiable, Equatable, GeneratedFakeable
let backordered = try container.decode(Bool.self, forKey: .backordered)

let soldIndividually = try container.decodeIfPresent(Bool.self, forKey: .soldIndividually) ?? false
let weight = try container.decodeIfPresent(String.self, forKey: .weight)

// Even though a plain install of WooCommerce Core provides String values,
// some plugins alter the field value from String to Int or Decimal.
let weight = container.failsafeDecodeIfPresent(targetType: String.self,
forKey: .weight,
alternativeTypes: [.decimal(transform: { NSDecimalNumber(decimal: $0).stringValue })])
let dimensions = try container.decode(ProductDimensions.self, forKey: .dimensions)

let shippingRequired = try container.decode(Bool.self, forKey: .shippingRequired)
Expand Down
18 changes: 18 additions & 0 deletions Networking/Networking/Model/Product/ProductDimensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ public struct ProductDimensions: Codable, Equatable, GeneratedFakeable {
self.width = width
self.height = height
}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

// Even though a plain install of WooCommerce Core provides String dimension values,
// some plugins may alter the field values from String to Int or Decimal.
let length = container.failsafeDecodeIfPresent(targetType: String.self,
forKey: .length,
alternativeTypes: [.decimal(transform: { NSDecimalNumber(decimal: $0).stringValue })]) ?? ""
let width = container.failsafeDecodeIfPresent(targetType: String.self,
forKey: .width,
alternativeTypes: [.decimal(transform: { NSDecimalNumber(decimal: $0).stringValue })]) ?? ""
let height = container.failsafeDecodeIfPresent(targetType: String.self,
forKey: .height,
alternativeTypes: [.decimal(transform: { NSDecimalNumber(decimal: $0).stringValue })]) ?? ""

self.init(length: length, width: width, height: height)
}
}

/// Defines all of the Dimensions CodingKeys
Expand Down
6 changes: 5 additions & 1 deletion Networking/Networking/Model/Product/ProductDownload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ public struct ProductDownload: Codable, Equatable, GeneratedFakeable {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

let downloadID = try container.decode(String.self, forKey: .downloadID)
// Even though a plain install of WooCommerce Core provides String values,
// some plugins alter the field value from String to Int or Decimal.
let downloadID = container.failsafeDecodeIfPresent(targetType: String.self,
forKey: .downloadID,
alternativeTypes: [.decimal(transform: { NSDecimalNumber(decimal: $0).stringValue })]) ?? "0"
let name = try container.decodeIfPresent(String.self, forKey: .name)
let fileURL = try container.decodeIfPresent(String.self, forKey: .fileURL)

Expand Down
6 changes: 6 additions & 0 deletions Networking/NetworkingTests/Mapper/ProductMapperTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ final class ProductMapperTests: XCTestCase {
XCTAssertFalse(product.soldIndividually)
XCTAssertTrue(product.purchasable)
XCTAssertEqual(product.permalink, "")
XCTAssertEqual(product.sku, "123")
XCTAssertEqual(product.weight, "213")
XCTAssertEqual(product.dimensions.length, "12")
XCTAssertEqual(product.dimensions.width, "33")
XCTAssertEqual(product.dimensions.height, "54")
XCTAssertEqual(product.downloads.first?.downloadID, "12345")
}

/// Verifies that the `salePrice` field of the Product are parsed correctly when the product is on sale, and the sale price is an empty string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"catalog_visibility": "visible",
"description": "<p>This is the party room!</p>\n",
"short_description": "[contact-form]\n<p>The green room&#8217;s max capacity is 30 people. Reserving the date / time of your event is free. We can also accommodate large groups, with seating for 85 board game players at a time. If you have a large group, let us know and we&#8217;ll send you our large group rate.</p>\n<p>GROUP RATES</p>\n<p>Reserve your event for up to 30 guests for $100.</p>\n",
"sku": "",
"sku": 123,
"price": 17,
"regular_price": 12.89,
"sale_price": 26.73,
Expand All @@ -28,7 +28,11 @@
"total_sales": 0,
"virtual": true,
"downloadable": false,
"downloads": [],
"downloads": [{
"id" : 12345,
"name" : "Song #1",
"file" : "https://example.com/woo-single-1.ogg"
}],
"download_limit": -1,
"download_expiry": -1,
"external_url": "http://somewhere.com",
Expand All @@ -42,11 +46,11 @@
"backorders_allowed": false,
"backordered": false,
"sold_individually": null,
"weight": "213",
"weight": 213,
"dimensions": {
"length": "12",
"width": "33",
"height": "54"
"length": 12,
"width": 33,
"height": 54
},
"shipping_required": false,
"shipping_taxable": false,
Expand Down
1 change: 1 addition & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
13.9
-----
- [*] Payments: Location permissions request is not shown to TTP users who grant "Allow once" permission on first foregrounding the app any more [https://github.com/woocommerce/woocommerce-ios/pull/9821]
- [*] Products: Allow alternative types for the `sku` and `weight` in `Product`, the dimensions in `ProductDimensions`, and the `downloadID` in `ProductDownload`, as some third-party plugins alter the types in the API. This helps with the product list not loading due to product decoding errors. [https://github.com/woocommerce/woocommerce-ios/pull/9846]

13.8
-----
Expand Down