Skip to content

Commit f988e8a

Browse files
authored
Merge pull request #2303 from woocommerce/issue/2302-m1-settings-missing
Fix certain M1 settings aren't accessible if the data are empty when M2 feature switch is off
2 parents 6eb1b28 + 353fd12 commit f988e8a

File tree

6 files changed

+221
-141
lines changed

6 files changed

+221
-141
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Yosemite
2+
3+
/// Creates actions for product form bottom sheet.
4+
struct ProductFormBottomSheetActionsFactory {
5+
private let product: Product
6+
private let isEditProductsRelease2Enabled: Bool
7+
private let isEditProductsRelease3Enabled: Bool
8+
9+
init(product: Product, isEditProductsRelease2Enabled: Bool, isEditProductsRelease3Enabled: Bool) {
10+
self.product = product
11+
self.isEditProductsRelease2Enabled = isEditProductsRelease2Enabled
12+
self.isEditProductsRelease3Enabled = isEditProductsRelease3Enabled
13+
}
14+
15+
/// Retruns an array of actions that are visible in the product form bottom sheet.
16+
func actions() -> [ProductFormBottomSheetAction] {
17+
let shouldShowShippingSettingsRow = product.isShippingEnabled
18+
let shouldShowCategoriesRow = isEditProductsRelease3Enabled
19+
let shouldShowShortDescriptionRow = isEditProductsRelease2Enabled
20+
let actions: [ProductFormBottomSheetAction?] = [
21+
.editInventorySettings,
22+
shouldShowShippingSettingsRow ? .editShippingSettings: nil,
23+
shouldShowCategoriesRow ? .editCategories: nil,
24+
shouldShowShortDescriptionRow ? .editBriefDescription: nil
25+
]
26+
return actions.compactMap({ $0 }).filter({ $0.isVisible(product: product) })
27+
}
28+
}

WooCommerce/Classes/ViewRelated/Products/Edit Product/BottomSheetListSelector/ProductFormBottomSheetListSelectorCommand.swift

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,10 @@ final class ProductFormBottomSheetListSelectorCommand: BottomSheetListSelectorCo
1212

1313
private let onSelection: (ProductFormBottomSheetAction) -> Void
1414

15-
init(product: Product,
16-
isEditProductsRelease3Enabled: Bool,
15+
init(actions: [ProductFormBottomSheetAction],
1716
onSelection: @escaping (ProductFormBottomSheetAction) -> Void) {
1817
self.onSelection = onSelection
19-
20-
let shouldShowShippingSettingsRow = product.isShippingEnabled
21-
let shouldShowCategoriesRow = isEditProductsRelease3Enabled
22-
let actions: [ProductFormBottomSheetAction?] = [
23-
.editInventorySettings,
24-
shouldShowShippingSettingsRow ? .editShippingSettings: nil,
25-
shouldShowCategoriesRow ? .editCategories: nil,
26-
.editBriefDescription
27-
]
28-
self.data = actions.compactMap({ $0 }).filter({ $0.isVisible(product: product) })
18+
self.data = actions
2919
}
3020

3121
func configureCell(cell: ImageAndTitleAndTextTableViewCell, model: ProductFormBottomSheetAction) {

WooCommerce/Classes/ViewRelated/Products/Edit Product/ProductFormViewController.swift

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,6 @@ private extension ProductFormViewController {
229229
}
230230

231231
func configureMoreDetailsContainerView() {
232-
guard isEditProductsRelease2Enabled else {
233-
moreDetailsContainerView.isHidden = true
234-
return
235-
}
236-
237232
let title = NSLocalizedString("Add more details", comment: "Title of the button at the bottom of the product form to add more product details.")
238233
let viewModel = BottomButtonContainerView.ViewModel(style: .link,
239234
title: title,
@@ -258,8 +253,8 @@ private extension ProductFormViewController {
258253
let title = NSLocalizedString("Add more details",
259254
comment: "Title of the bottom sheet from the product form to add more product details.")
260255
let viewProperties = BottomSheetListSelectorViewProperties(title: title)
261-
let dataSource = ProductFormBottomSheetListSelectorCommand(product: product,
262-
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled) { [weak self] action in
256+
let actions = createBottomSheetActions()
257+
let dataSource = ProductFormBottomSheetListSelectorCommand(actions: actions) { [weak self] action in
263258
self?.dismiss(animated: true) { [weak self] in
264259
switch action {
265260
case .editInventorySettings:
@@ -282,16 +277,8 @@ private extension ProductFormViewController {
282277
}
283278

284279
func updateMoreDetailsButtonVisibility(product: Product) {
285-
guard isEditProductsRelease2Enabled else {
286-
moreDetailsContainerView.isHidden = true
287-
return
288-
}
289-
290-
let moreDetailsActions: [ProductFormBottomSheetAction] = isEditProductsRelease3Enabled ?
291-
[.editInventorySettings, .editShippingSettings, .editCategories, .editBriefDescription]:
292-
[.editInventorySettings, .editShippingSettings, .editBriefDescription]
293-
let hasVisibleActions = moreDetailsActions.map({ $0.isVisible(product: product) }).contains(true)
294-
moreDetailsContainerView.isHidden = hasVisibleActions == false
280+
let moreDetailsActions = createBottomSheetActions()
281+
moreDetailsContainerView.isHidden = moreDetailsActions.isEmpty
295282
}
296283
}
297284

@@ -477,6 +464,12 @@ private extension ProductFormViewController {
477464
moreButton.accessibilityIdentifier = "edit-product-more-options-button"
478465
return moreButton
479466
}
467+
468+
private func createBottomSheetActions() -> [ProductFormBottomSheetAction] {
469+
ProductFormBottomSheetActionsFactory(product: product,
470+
isEditProductsRelease2Enabled: isEditProductsRelease2Enabled,
471+
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled).actions()
472+
}
480473
}
481474

482475
extension ProductFormViewController: UITableViewDelegate {

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@
9292
0235595B24496E88004BE2B8 /* BottomSheetListSelectorViewController+DrawerPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0235595A24496E88004BE2B8 /* BottomSheetListSelectorViewController+DrawerPresentable.swift */; };
9393
02357B2A23CDB3E300147C2B /* ProductImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02357B2823CDB3E300147C2B /* ProductImageViewController.swift */; };
9494
02357B2B23CDB3E300147C2B /* ProductImageViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 02357B2923CDB3E300147C2B /* ProductImageViewController.xib */; };
95+
0235BFD9246E959500778909 /* ProductFormBottomSheetActionsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0235BFD8246E959500778909 /* ProductFormBottomSheetActionsFactory.swift */; };
96+
0235BFDB246E99A700778909 /* ProductFormBottomSheetActionsFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0235BFDA246E99A700778909 /* ProductFormBottomSheetActionsFactoryTests.swift */; };
9597
02396251239948470096F34C /* UIImage+TintColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02396250239948470096F34C /* UIImage+TintColor.swift */; };
9698
023A059A24135F2600E3FC99 /* ReviewsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023A059824135F2600E3FC99 /* ReviewsViewController.swift */; };
9799
023A059B24135F2600E3FC99 /* ReviewsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 023A059924135F2600E3FC99 /* ReviewsViewController.xib */; };
@@ -940,6 +942,8 @@
940942
0235595A24496E88004BE2B8 /* BottomSheetListSelectorViewController+DrawerPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BottomSheetListSelectorViewController+DrawerPresentable.swift"; sourceTree = "<group>"; };
941943
02357B2823CDB3E300147C2B /* ProductImageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductImageViewController.swift; sourceTree = "<group>"; };
942944
02357B2923CDB3E300147C2B /* ProductImageViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ProductImageViewController.xib; sourceTree = "<group>"; };
945+
0235BFD8246E959500778909 /* ProductFormBottomSheetActionsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductFormBottomSheetActionsFactory.swift; sourceTree = "<group>"; };
946+
0235BFDA246E99A700778909 /* ProductFormBottomSheetActionsFactoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductFormBottomSheetActionsFactoryTests.swift; sourceTree = "<group>"; };
943947
02396250239948470096F34C /* UIImage+TintColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+TintColor.swift"; sourceTree = "<group>"; };
944948
023A059824135F2600E3FC99 /* ReviewsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewsViewController.swift; sourceTree = "<group>"; };
945949
023A059924135F2600E3FC99 /* ReviewsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ReviewsViewController.xib; sourceTree = "<group>"; };
@@ -1768,6 +1772,7 @@
17681772
children = (
17691773
0212276024498A270042161F /* ProductFormBottomSheetListSelectorCommand.swift */,
17701774
0212276224498CDC0042161F /* ProductFormBottomSheetAction.swift */,
1775+
0235BFD8246E959500778909 /* ProductFormBottomSheetActionsFactory.swift */,
17711776
);
17721777
path = BottomSheetListSelector;
17731778
sourceTree = "<group>";
@@ -2203,6 +2208,7 @@
22032208
children = (
22042209
02A9A495244D84AB00757B99 /* ProductsSortOrderBottomSheetListSelectorCommandTests.swift */,
22052210
02E493EE245C1087000AEA9E /* ProductFormBottomSheetListSelectorCommandTests.swift */,
2211+
0235BFDA246E99A700778909 /* ProductFormBottomSheetActionsFactoryTests.swift */,
22062212
);
22072213
path = BottomSheetListSelector;
22082214
sourceTree = "<group>";
@@ -4757,6 +4763,7 @@
47574763
D8C251DB230D288A00F49782 /* PushNotesManager.swift in Sources */,
47584764
748D34E12148291E00E21A2F /* TopPerformerDataViewController.swift in Sources */,
47594765
02C887712450285100E4470F /* BottomButtonContainerView.swift in Sources */,
4766+
0235BFD9246E959500778909 /* ProductFormBottomSheetActionsFactory.swift in Sources */,
47604767
024EFA6923FCC10B00F36918 /* Product+Media.swift in Sources */,
47614768
5795F23023E26B5300F6707C /* OrderSearchStarterViewModel.swift in Sources */,
47624769
0202B68D23876BC100F3EBE0 /* ProductsTabProductViewModel+ProductVariation.swift in Sources */,
@@ -4980,6 +4987,7 @@
49804987
02BA23C022EE9DAF009539E7 /* AsyncDictionaryTests.swift in Sources */,
49814988
B555531121B57E6F00449E71 /* MockupApplicationAdapter.swift in Sources */,
49824989
021E2A2023AA274700B1DE07 /* ProductBackordersSettingListSelectorCommandTests.swift in Sources */,
4990+
0235BFDB246E99A700778909 /* ProductFormBottomSheetActionsFactoryTests.swift in Sources */,
49834991
020BE76723B49FE9007FE54C /* AztecBoldFormatBarCommandTests.swift in Sources */,
49844992
CE4DA5C821DD759400074607 /* CurrencyFormatterTests.swift in Sources */,
49854993
B57C745120F56EE900EEFC87 /* UITableViewCellHelpersTests.swift in Sources */,
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import XCTest
2+
@testable import WooCommerce
3+
@testable import Yosemite
4+
5+
final class ProductFormBottomSheetActionsFactoryTests: XCTestCase {
6+
7+
// M3 feature flag off & M2 feature flag off
8+
9+
func testDataHasNoEditProductsRelease2And3ActionsForAPhysicalProductWhenBothFeatureFlagsAreOff() {
10+
let product = Fixtures.physicalProduct
11+
let isEditProductsRelease2Enabled = false
12+
let isEditProductsRelease3Enabled = false
13+
let actions = ProductFormBottomSheetActionsFactory(product: product,
14+
isEditProductsRelease2Enabled: isEditProductsRelease2Enabled,
15+
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled).actions()
16+
17+
let expectedActions: [ProductFormBottomSheetAction] = [
18+
.editInventorySettings,
19+
.editShippingSettings
20+
]
21+
XCTAssertEqual(actions, expectedActions)
22+
}
23+
24+
func testDataHasNoEditProductsRelease2And3AndShippingActionsForAVirtualProductWhenBothFeatureFlagsAreOff() {
25+
let product = Fixtures.virtualProduct
26+
let isEditProductsRelease2Enabled = false
27+
let isEditProductsRelease3Enabled = false
28+
let actions = ProductFormBottomSheetActionsFactory(product: product,
29+
isEditProductsRelease2Enabled: isEditProductsRelease2Enabled,
30+
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled).actions()
31+
32+
let expectedActions: [ProductFormBottomSheetAction] = [
33+
.editInventorySettings
34+
]
35+
XCTAssertEqual(actions, expectedActions)
36+
}
37+
38+
func testDataHasNoEditProductsRelease2And3AndShippingActionsForADownloadableProductWhenBothFeatureFlagsAreOff() {
39+
let product = Fixtures.downloadableProduct
40+
let isEditProductsRelease2Enabled = false
41+
let isEditProductsRelease3Enabled = false
42+
let actions = ProductFormBottomSheetActionsFactory(product: product,
43+
isEditProductsRelease2Enabled: isEditProductsRelease2Enabled,
44+
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled).actions()
45+
46+
let expectedActions: [ProductFormBottomSheetAction] = [
47+
.editInventorySettings
48+
]
49+
XCTAssertEqual(actions, expectedActions)
50+
}
51+
52+
// M3 feature flag off & M2 feature flag on
53+
54+
func testDataHasNoEditProductsRelease3ActionsForAPhysicalProductWhenM3FeatureFlagIsOff() {
55+
let product = Fixtures.physicalProduct
56+
let isEditProductsRelease2Enabled = true
57+
let isEditProductsRelease3Enabled = false
58+
let actions = ProductFormBottomSheetActionsFactory(product: product,
59+
isEditProductsRelease2Enabled: isEditProductsRelease2Enabled,
60+
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled).actions()
61+
62+
let expectedActions: [ProductFormBottomSheetAction] = [
63+
.editInventorySettings,
64+
.editShippingSettings,
65+
.editBriefDescription
66+
]
67+
XCTAssertEqual(actions, expectedActions)
68+
}
69+
70+
func testDataHasNoEditProductsRelease3AndShippingActionsForAVirtualProductWhenM3FeatureFlagIsOff() {
71+
let product = Fixtures.virtualProduct
72+
let isEditProductsRelease2Enabled = true
73+
let isEditProductsRelease3Enabled = false
74+
let actions = ProductFormBottomSheetActionsFactory(product: product,
75+
isEditProductsRelease2Enabled: isEditProductsRelease2Enabled,
76+
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled).actions()
77+
78+
let expectedActions: [ProductFormBottomSheetAction] = [
79+
.editInventorySettings,
80+
.editBriefDescription
81+
]
82+
XCTAssertEqual(actions, expectedActions)
83+
}
84+
85+
func testDataHasNoEditProductsRelease3AndShippingActionsForADownloadableProductWhenM3FeatureFlagIsOff() {
86+
let product = Fixtures.downloadableProduct
87+
let isEditProductsRelease2Enabled = true
88+
let isEditProductsRelease3Enabled = false
89+
let actions = ProductFormBottomSheetActionsFactory(product: product,
90+
isEditProductsRelease2Enabled: isEditProductsRelease2Enabled,
91+
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled).actions()
92+
93+
let expectedActions: [ProductFormBottomSheetAction] = [
94+
.editInventorySettings,
95+
.editBriefDescription
96+
]
97+
XCTAssertEqual(actions, expectedActions)
98+
}
99+
100+
// M3 feature flag on & M2 feature flag is on
101+
102+
func testDataHasEditProductsRelease3ActionsForAPhysicalProductWhenBothFeatureFlagsAreOn() {
103+
let product = Fixtures.physicalProduct
104+
let isEditProductsRelease2Enabled = true
105+
let isEditProductsRelease3Enabled = true
106+
let actions = ProductFormBottomSheetActionsFactory(product: product,
107+
isEditProductsRelease2Enabled: isEditProductsRelease2Enabled,
108+
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled).actions()
109+
110+
let expectedActions: [ProductFormBottomSheetAction] = [
111+
.editInventorySettings,
112+
.editShippingSettings,
113+
.editCategories,
114+
.editBriefDescription
115+
]
116+
XCTAssertEqual(actions, expectedActions)
117+
}
118+
119+
func testDataHasEditProductsRelease3ButNoShippingActionsForAVirtualProductWhenBothFeatureFlagsAreOn() {
120+
let product = Fixtures.virtualProduct
121+
let isEditProductsRelease2Enabled = true
122+
let isEditProductsRelease3Enabled = true
123+
let actions = ProductFormBottomSheetActionsFactory(product: product,
124+
isEditProductsRelease2Enabled: isEditProductsRelease2Enabled,
125+
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled).actions()
126+
127+
let expectedActions: [ProductFormBottomSheetAction] = [
128+
.editInventorySettings,
129+
.editCategories,
130+
.editBriefDescription
131+
]
132+
XCTAssertEqual(actions, expectedActions)
133+
}
134+
135+
func testDataHasEditProductsRelease3ButNoShippingActionsForADownloadableProductWhenBothFeatureFlagsAreOn() {
136+
let product = Fixtures.downloadableProduct
137+
let isEditProductsRelease2Enabled = true
138+
let isEditProductsRelease3Enabled = true
139+
let actions = ProductFormBottomSheetActionsFactory(product: product,
140+
isEditProductsRelease2Enabled: isEditProductsRelease2Enabled,
141+
isEditProductsRelease3Enabled: isEditProductsRelease3Enabled).actions()
142+
143+
let expectedActions: [ProductFormBottomSheetAction] = [
144+
.editInventorySettings,
145+
.editCategories,
146+
.editBriefDescription
147+
]
148+
XCTAssertEqual(actions, expectedActions)
149+
}
150+
151+
}
152+
153+
private extension ProductFormBottomSheetActionsFactoryTests {
154+
enum Fixtures {
155+
// downloadable: false, virtual: false, missing inventory/shipping/categories/brief description
156+
static let physicalProduct = MockProduct().product(downloadable: false, briefDescription: "", manageStock: true, sku: nil, stockQuantity: nil,
157+
dimensions: ProductDimensions(length: "", width: "", height: ""), weight: nil,
158+
virtual: false,
159+
categories: [])
160+
// downloadable: false, virtual: true, missing inventory/shipping/categories/brief description
161+
static let virtualProduct = MockProduct().product(downloadable: false, briefDescription: "", manageStock: true, sku: nil, stockQuantity: nil,
162+
dimensions: ProductDimensions(length: "", width: "", height: ""), weight: nil,
163+
virtual: true,
164+
categories: [])
165+
// downloadable: true, virtual: true, missing inventory/shipping/categories/brief description
166+
static let downloadableProduct = MockProduct().product(downloadable: true, briefDescription: "", manageStock: true, sku: nil, stockQuantity: nil,
167+
dimensions: ProductDimensions(length: "", width: "", height: ""), weight: nil,
168+
virtual: true,
169+
categories: [])
170+
}
171+
}

0 commit comments

Comments
 (0)