Skip to content

Commit b65edef

Browse files
authored
Merge pull request #8091 from woocommerce/issue/8071-preview-new-template
Product Onboarding: Allow Template Products to be previewed
2 parents 6918860 + 5b90ccb commit b65edef

File tree

6 files changed

+54
-6
lines changed

6 files changed

+54
-6
lines changed

Fakes/Fakes/Products/ProductFactory.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ public enum ProductFactory {
2424
/// Returns a fake product filled with data can be edited by the merchants
2525
///
2626
public static func productWithEditableDataFilled() -> Product {
27-
Product.fake().copy(name: "name",
27+
Product.fake().copy(productID: 123,
28+
name: "name",
2829
dateOnSaleStart: Date(),
2930
dateOnSaleEnd: Date(),
3031
fullDescription: "description",

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,20 @@ extension EditableProductModel: ProductFormDataModel, TaxClassRequestable {
181181
var existsRemotely: Bool {
182182
product.existsRemotely
183183
}
184+
185+
/// Helper to determine if a product model is empty.
186+
/// We consider it as empty if its underlying product matches the `ProductFactory.createNewProduct` output.
187+
/// Additionally we don't take dates into consideration as we don't control their value when creating a product.
188+
///
189+
func isEmpty() -> Bool {
190+
guard let emptyProduct = ProductFactory().createNewProduct(type: productType, isVirtual: virtual, siteID: siteID) else {
191+
return false
192+
}
193+
194+
let commonDate = Date()
195+
return emptyProduct.copy(date: commonDate, dateCreated: commonDate, dateModified: commonDate, dateOnSaleStart: commonDate, dateOnSaleEnd: commonDate) ==
196+
product.copy(date: commonDate, dateCreated: commonDate, dateModified: commonDate, dateOnSaleStart: commonDate, dateOnSaleEnd: commonDate)
197+
}
184198
}
185199

186200
extension EditableProductModel: Equatable {

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ final class ProductFormViewModel: ProductFormViewModelProtocol {
221221
productOrVariationID: .product(id: product.productID),
222222
isLocalID: !product.existsRemotely),
223223
originalImages: originalProduct.images)
224-
return hasProductChangesExcludingImages || hasImageChanges || password != originalPassword
224+
return hasProductChangesExcludingImages || hasImageChanges || password != originalPassword || isNewTemplateProduct()
225225
}
226226
}
227227

@@ -620,6 +620,15 @@ private extension ProductFormViewModel {
620620

621621
return controller
622622
}
623+
624+
/// Helper to determine if the added/editted product comes as a new template product.
625+
/// We assume that a new template product is a product that:
626+
/// - Doesn't have an `id` - has not been saved remotely
627+
/// - Is not empty.
628+
///
629+
private func isNewTemplateProduct() -> Bool {
630+
originalProduct.productID == .zero && !originalProduct.isEmpty()
631+
}
623632
}
624633

625634
// MARK: Beta feature handling

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ extension ProductFormViewModelProtocol {
185185
/// Returns `false` when it's a new blank product without any changes.
186186
///
187187
func shouldEnablePreviewButton() -> Bool {
188-
!(formType == .add && !hasUnsavedChanges())
188+
switch formType {
189+
case .add:
190+
return hasUnsavedChanges()
191+
case .edit, .readonly:
192+
return true
193+
}
189194
}
190195
}

WooCommerce/WooCommerceTests/ViewRelated/Products/Edit Product/ProductFormViewModel+ObservablesTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ final class ProductFormViewModel_ObservablesTests: XCTestCase {
159159

160160
func testObservablesFromUpdatingProductPasswordRemotely() {
161161
// Arrange
162-
let product = Product.fake()
162+
let product = Product.fake().copy(productID: 123)
163163
let model = EditableProductModel(product: product)
164164
let productImageActionHandler = ProductImageActionHandler(siteID: defaultSiteID, product: model)
165165
let viewModel = ProductFormViewModel(product: model,

WooCommerce/WooCommerceTests/ViewRelated/Products/Edit Product/ProductFormViewModelTests.swift

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,11 +542,11 @@ final class ProductFormViewModelTests: XCTestCase {
542542

543543
// MARK: Preview button tests (with enabled Product Onboarding feature flag)
544544

545-
func test_disabled_preview_button_for_new_blank_product_without_any_changes() {
545+
func test_disabled_preview_button_for_new_blank_product_without_any_changes() throws {
546546
// Given
547547
sessionManager.defaultSite = Site.fake().copy(frameNonce: "abc123")
548548

549-
let product = Product.fake().copy(statusKey: ProductStatus.published.rawValue)
549+
let product = try XCTUnwrap(ProductFactory().createNewProduct(type: .simple, isVirtual: false, siteID: 123))
550550
let viewModel = createViewModel(product: product,
551551
formType: .add,
552552
stores: stores,
@@ -560,6 +560,25 @@ final class ProductFormViewModelTests: XCTestCase {
560560
XCTAssertFalse(viewModel.shouldEnablePreviewButton())
561561
}
562562

563+
func test_enabled_preview_button_for_new_template_product() throws {
564+
// Given
565+
sessionManager.defaultSite = Site.fake().copy(frameNonce: "abc123")
566+
567+
// Adding some value to simulate a template product
568+
let product = try XCTUnwrap(ProductFactory().createNewProduct(type: .simple, isVirtual: false, siteID: 123)?.copy(price: "10.00"))
569+
let viewModel = createViewModel(product: product,
570+
formType: .add,
571+
stores: stores,
572+
featureFlagService: MockFeatureFlagService(isProductsOnboardingEnabled: true))
573+
574+
// When
575+
let actionButtons = viewModel.actionButtons
576+
577+
// Then
578+
XCTAssertEqual(actionButtons, [.preview, .publish, .more])
579+
XCTAssertTrue(viewModel.shouldEnablePreviewButton())
580+
}
581+
563582
func test_enabled_preview_button_for_new_product_with_pending_changes() {
564583
// Given
565584
sessionManager.defaultSite = Site.fake().copy(frameNonce: "abc123")

0 commit comments

Comments
 (0)