Skip to content

Commit cdc9f3d

Browse files
authored
Merge pull request #2129 from woocommerce/merge/4.0.0.1-to-develop
Merge 4.0.0.1 to develop
2 parents b027c7c + 6963334 commit cdc9f3d

File tree

6 files changed

+55
-18
lines changed

6 files changed

+55
-18
lines changed

Networking/NetworkingTests/Mapper/ProductMapperTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class ProductMapperTests: XCTestCase {
8282
XCTAssertFalse(product.shippingRequired)
8383
XCTAssertFalse(product.shippingTaxable)
8484
XCTAssertEqual(product.shippingClass, "")
85-
XCTAssertEqual(product.shippingClassID, 0)
85+
XCTAssertEqual(product.shippingClassID, 134)
8686

8787
XCTAssertTrue(product.reviewsAllowed)
8888
XCTAssertEqual(product.averageRating, "4.30")

Networking/NetworkingTests/Responses/product.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"shipping_required": false,
5252
"shipping_taxable": false,
5353
"shipping_class": "",
54-
"shipping_class_id": 0,
54+
"shipping_class_id": 134,
5555
"reviews_allowed": true,
5656
"average_rating": "4.30",
5757
"rating_count": 23,

WooCommerce/Classes/ViewRelated/Products/Edit Product/Shipping Settings/ProductShippingSettingsViewController.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ final class ProductShippingSettingsViewController: UIViewController {
2121
//
2222
private var shippingClass: ProductShippingClass?
2323

24+
/// Tracks whether the original shipping class has been retrieved, if the product has a shipping class.
25+
/// The shipping class picker action is blocked until the original shipping class has been retrieved.
26+
private var hasRetrievedShippingClassIfNeeded: Bool = false
27+
2428
/// Table Sections to be rendered
2529
///
2630
private let sections: [Section] = [
@@ -96,15 +100,18 @@ private extension ProductShippingSettingsViewController {
96100
}
97101

98102
func retrieveProductShippingClass() {
99-
guard let shippingClass = shippingClass else {
103+
let productHasShippingClass = product.shippingClass?.isEmpty == false
104+
guard productHasShippingClass else {
105+
hasRetrievedShippingClassIfNeeded = true
100106
return
101107
}
102108

103109
let action = ProductShippingClassAction
104110
.retrieveProductShippingClass(siteID: product.siteID,
105-
remoteID: shippingClass.shippingClassID) { [weak self] (shippingClass, error) in
106-
self?.shippingClass = shippingClass
107-
self?.tableView.reloadData()
111+
remoteID: product.shippingClassID) { [weak self] (shippingClass, error) in
112+
self?.shippingClass = shippingClass
113+
self?.hasRetrievedShippingClassIfNeeded = true
114+
self?.tableView.reloadData()
108115
}
109116
ServiceLocator.stores.dispatch(action)
110117
}
@@ -187,6 +194,9 @@ extension ProductShippingSettingsViewController: UITableViewDelegate {
187194
let row = rowAtIndexPath(indexPath)
188195
switch row {
189196
case .shippingClass:
197+
guard hasRetrievedShippingClassIfNeeded else {
198+
return
199+
}
190200
let dataSource = PaginatedProductShippingClassListSelectorDataSource(product: product, selected: shippingClass)
191201
let navigationBarTitle = NSLocalizedString("Shipping classes", comment: "Navigation bar title of the Product shipping class selector screen")
192202
let noResultsPlaceholderText = NSLocalizedString("No shipping classes yet",

Yosemite/Yosemite/Stores/ProductStore.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,9 @@ private extension ProductStore {
170170
return
171171
}
172172

173-
self?.upsertStoredProductsInBackground(readOnlyProducts: [product]) {
174-
onCompletion(product, nil)
173+
self?.upsertStoredProductsInBackground(readOnlyProducts: [product]) { [weak self] in
174+
let storageProduct = self?.storageManager.viewStorage.loadProduct(siteID: siteID, productID: productID)
175+
onCompletion(storageProduct?.toReadOnly(), nil)
175176
}
176177
}
177178
}
@@ -187,8 +188,9 @@ private extension ProductStore {
187188
return
188189
}
189190

190-
self?.upsertStoredProductsInBackground(readOnlyProducts: [product]) {
191-
onCompletion(product, nil)
191+
self?.upsertStoredProductsInBackground(readOnlyProducts: [product]) { [weak self] in
192+
let storageProduct = self?.storageManager.viewStorage.loadProduct(siteID: product.siteID, productID: product.productID)
193+
onCompletion(storageProduct?.toReadOnly(), nil)
192194
}
193195
}
194196
}

Yosemite/YosemiteTests/Stores/ProductStoreTests.swift

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,15 @@ class ProductStoreTests: XCTestCase {
292292
/// Verifies that `ProductAction.retrieveProduct` returns the expected `Product`.
293293
///
294294
func testRetrieveSingleProductReturnsExpectedFields() {
295+
// The shipping class ID should match the `shipping_class_id` field in `product.json`.
296+
let expectedShippingClass = sampleProductShippingClass(remoteID: 134, siteID: sampleSiteID)
297+
storageManager.insertSampleProductShippingClass(readOnlyProductShippingClass: expectedShippingClass)
298+
295299
let expectation = self.expectation(description: "Retrieve single product")
296300
let productStore = ProductStore(dispatcher: dispatcher, storageManager: storageManager, network: network)
297-
let remoteProduct = sampleProduct()
301+
let remoteProduct = sampleProduct(productShippingClass: expectedShippingClass)
298302

299-
network.simulateResponse(requestUrlSuffix: "products/282", filename: "product")
303+
network.simulateResponse(requestUrlSuffix: "products/\(sampleProductID)", filename: "product")
300304
let action = ProductAction.retrieveProduct(siteID: sampleSiteID, productID: sampleProductID) { (product, error) in
301305
XCTAssertNil(error)
302306
XCTAssertNotNil(product)
@@ -335,7 +339,12 @@ class ProductStoreTests: XCTestCase {
335339
func testRetrieveSingleProductEffectivelyPersistsProductFieldsAndRelatedObjects() {
336340
let expectation = self.expectation(description: "Persist single product")
337341
let productStore = ProductStore(dispatcher: dispatcher, storageManager: storageManager, network: network)
338-
let remoteProduct = sampleProduct()
342+
343+
// The shipping class ID should match the `shipping_class_id` field in `product.json`.
344+
let expectedShippingClass = sampleProductShippingClass(remoteID: 134, siteID: sampleSiteID)
345+
storageManager.insertSampleProductShippingClass(readOnlyProductShippingClass: expectedShippingClass)
346+
347+
let remoteProduct = sampleProduct(productShippingClass: expectedShippingClass)
339348

340349
network.simulateResponse(requestUrlSuffix: "products/282", filename: "product")
341350
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.Product.self), 0)
@@ -772,6 +781,7 @@ class ProductStoreTests: XCTestCase {
772781
let expectedProductDescription = "Learn something!"
773782
let expectedProductShippingClassID: Int64 = 96987515
774783
let expectedProductShippingClassSlug = "two-days"
784+
let expectedProductShippingClass = sampleProductShippingClass(remoteID: expectedProductShippingClassID, siteID: sampleSiteID)
775785
let expectedProductSKU = "94115"
776786
let expectedProductManageStock = true
777787
let expectedProductSoldIndividually = false
@@ -788,6 +798,11 @@ class ProductStoreTests: XCTestCase {
788798
network.simulateResponse(requestUrlSuffix: "products/\(expectedProductID)", filename: "product-update")
789799
let product = sampleProduct(productID: expectedProductID)
790800

801+
// Saves an existing shipping class into storage, so that it can be linked to the updated product.
802+
// The shipping class ID should match the `shipping_class_id` field in `product.json`.
803+
storageManager.insertSampleProductShippingClass(readOnlyProductShippingClass: expectedProductShippingClass)
804+
XCTAssertEqual(viewStorage.countObjects(ofType: StorageProductShippingClass.self), 1)
805+
791806
// Saves an existing Product into storage.
792807
// Note: the fields to be tested should be different in the sample model and network response.
793808
storageManager.insertSampleProduct(readOnlyProduct: product)
@@ -802,6 +817,7 @@ class ProductStoreTests: XCTestCase {
802817
// Shipping settings.
803818
XCTAssertEqual(product?.shippingClassID, expectedProductShippingClassID)
804819
XCTAssertEqual(product?.shippingClass, expectedProductShippingClassSlug)
820+
XCTAssertEqual(product?.productShippingClass, expectedProductShippingClass)
805821
// Inventory settings.
806822
XCTAssertEqual(product?.sku, expectedProductSKU)
807823
XCTAssertEqual(product?.manageStock, expectedProductManageStock)
@@ -944,7 +960,7 @@ class ProductStoreTests: XCTestCase {
944960
//
945961
private extension ProductStoreTests {
946962

947-
func sampleProduct(_ siteID: Int64? = nil, productID: Int64? = nil) -> Networking.Product {
963+
func sampleProduct(_ siteID: Int64? = nil, productID: Int64? = nil, productShippingClass: Networking.ProductShippingClass? = nil) -> Networking.Product {
948964
let testSiteID = siteID ?? sampleSiteID
949965
let testProductID = productID ?? sampleProductID
950966
return Product(siteID: testSiteID,
@@ -993,9 +1009,9 @@ private extension ProductStoreTests {
9931009
dimensions: sampleDimensions(),
9941010
shippingRequired: false,
9951011
shippingTaxable: false,
996-
shippingClass: "",
997-
shippingClassID: 0,
998-
productShippingClass: nil,
1012+
shippingClass: productShippingClass?.slug ?? "",
1013+
shippingClassID: productShippingClass?.shippingClassID ?? 0,
1014+
productShippingClass: productShippingClass,
9991015
reviewsAllowed: true,
10001016
averageRating: "4.30",
10011017
ratingCount: 23,
@@ -1208,6 +1224,15 @@ private extension ProductStoreTests {
12081224
return [defaultAttribute1]
12091225
}
12101226

1227+
func sampleProductShippingClass(remoteID: Int64, siteID: Int64) -> Yosemite.ProductShippingClass {
1228+
return ProductShippingClass(count: 3,
1229+
descriptionHTML: "Limited offer!",
1230+
name: "Free Shipping",
1231+
shippingClassID: remoteID,
1232+
siteID: siteID,
1233+
slug: "")
1234+
}
1235+
12111236
func sampleVariationTypeProduct(_ siteID: Int64? = nil) -> Networking.Product {
12121237
let testSiteID = siteID ?? sampleSiteID
12131238
return Product(siteID: testSiteID,

config/Version.Public.xcconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
VERSION_SHORT=4.0
22

33
// Public long version example: VERSION_LONG=1.2.0.0
4-
VERSION_LONG=4.0.0.0
4+
VERSION_LONG=4.0.0.1

0 commit comments

Comments
 (0)