diff --git a/packages/template-retail-react-app/app/commerce-api/mocks/product-set-winter-lookM.js b/packages/template-retail-react-app/app/commerce-api/mocks/product-set-winter-lookM.js new file mode 100644 index 0000000000..89d313fcb2 --- /dev/null +++ b/packages/template-retail-react-app/app/commerce-api/mocks/product-set-winter-lookM.js @@ -0,0 +1,1224 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ + +export default { + currency: 'GBP', + id: 'winter-lookM', + imageGroups: [ + { + images: [ + { + alt: 'Winter Look, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe1c4cd52/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe1c4cd52/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Winter Look, ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Winter Look, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw07f25517/images/medium/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw07f25517/images/medium/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Winter Look, ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Winter Look, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwab300645/images/small/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwab300645/images/small/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Winter Look, ' + } + ], + viewType: 'small' + } + ], + longDescription: '

Jacket

\r\n

Pant

\r\n

Shoes

', + minOrderQuantity: 1, + name: 'Winter Look', + price: 44.16, + priceMax: 71.03, + pricePerUnit: 44.16, + pricePerUnitMax: 71.03, + primaryCategoryId: 'womens-outfits', + setProducts: [ + { + currency: 'GBP', + id: '25518447M', + imageGroups: [ + { + images: [ + { + alt: 'Quilted Jacket, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe1c4cd52/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe1c4cd52/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Quilted Jacket, ' + }, + { + alt: 'Quilted Jacket, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwb2158085/images/large/PG.10205921.JJ5FUXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwb2158085/images/large/PG.10205921.JJ5FUXX.BZ.jpg', + title: 'Quilted Jacket, ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Quilted Jacket, royal, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe1c4cd52/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe1c4cd52/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Quilted Jacket, royal' + }, + { + alt: 'Quilted Jacket, royal, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwb2158085/images/large/PG.10205921.JJ5FUXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwb2158085/images/large/PG.10205921.JJ5FUXX.BZ.jpg', + title: 'Quilted Jacket, royal' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJ5FUXX' + } + ] + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Quilted Jacket, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw07f25517/images/medium/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw07f25517/images/medium/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Quilted Jacket, ' + }, + { + alt: 'Quilted Jacket, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw34fd2ab3/images/medium/PG.10205921.JJ5FUXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw34fd2ab3/images/medium/PG.10205921.JJ5FUXX.BZ.jpg', + title: 'Quilted Jacket, ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Quilted Jacket, royal, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw07f25517/images/medium/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw07f25517/images/medium/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Quilted Jacket, royal' + }, + { + alt: 'Quilted Jacket, royal, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw34fd2ab3/images/medium/PG.10205921.JJ5FUXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw34fd2ab3/images/medium/PG.10205921.JJ5FUXX.BZ.jpg', + title: 'Quilted Jacket, royal' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJ5FUXX' + } + ] + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Quilted Jacket, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwab300645/images/small/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwab300645/images/small/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Quilted Jacket, ' + }, + { + alt: 'Quilted Jacket, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwbb5eb9b1/images/small/PG.10205921.JJ5FUXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwbb5eb9b1/images/small/PG.10205921.JJ5FUXX.BZ.jpg', + title: 'Quilted Jacket, ' + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Quilted Jacket, royal, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwab300645/images/small/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwab300645/images/small/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Quilted Jacket, royal' + }, + { + alt: 'Quilted Jacket, royal, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwbb5eb9b1/images/small/PG.10205921.JJ5FUXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwbb5eb9b1/images/small/PG.10205921.JJ5FUXX.BZ.jpg', + title: 'Quilted Jacket, royal' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJ5FUXX' + } + ] + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Quilted Jacket, royal, swatch', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5dea9b57/images/swatch/PG.10205921.JJ5FUXX.CP.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5dea9b57/images/swatch/PG.10205921.JJ5FUXX.CP.jpg', + title: 'Quilted Jacket, royal' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJ5FUXX' + } + ] + } + ], + viewType: 'swatch' + } + ], + inventory: { + ats: 400, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 400 + }, + longDescription: + 'A classic quilted car coat looks new again. Add a great Commerce Cloud Store top for a perfect look.', + master: { + masterId: '25518447M', + orderable: true, + price: 71.03 + }, + minOrderQuantity: 1, + name: 'Quilted Jacket', + pageDescription: + 'A classic quilted car coat looks new again. Add a great Commerce Cloud Store top for a perfect look.', + pageTitle: 'Quilted Jacket', + price: 71.03, + pricePerUnit: 71.03, + primaryCategoryId: 'womens-clothing-jackets', + recommendations: [ + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: '22951021M' + }, + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: '25518397M' + } + ], + shortDescription: + 'A classic quilted car coat looks new again. Add a great Commerce Cloud Store top for a perfect look.', + stepQuantity: 1, + type: { + master: true + }, + validFrom: { + default: '2010-10-21T04:00:00.000Z' + }, + variants: [ + { + orderable: true, + price: 71.03, + productId: '701642853695M', + variationValues: { + color: 'JJ5FUXX', + size: '9LG' + } + }, + { + orderable: true, + price: 71.03, + productId: '701642853718M', + variationValues: { + color: 'JJ5FUXX', + size: '9SM' + } + }, + { + orderable: true, + price: 71.03, + productId: '701642853725M', + variationValues: { + color: 'JJ5FUXX', + size: '9XL' + } + }, + { + orderable: true, + price: 71.03, + productId: '701642853701M', + variationValues: { + color: 'JJ5FUXX', + size: '9MD' + } + } + ], + variationAttributes: [ + { + id: 'color', + name: 'Colour', + values: [ + { + name: 'royal', + orderable: true, + value: 'JJ5FUXX' + } + ] + }, + { + id: 'size', + name: 'Size', + values: [ + { + name: 'S', + orderable: true, + value: '9SM' + }, + { + name: 'M', + orderable: true, + value: '9MD' + }, + { + name: 'L', + orderable: true, + value: '9LG' + }, + { + name: 'XL', + orderable: true, + value: '9XL' + } + ] + } + ], + c_isNewtest: true, + c_isSale: true + }, + { + currency: 'GBP', + id: '25518704M', + imageGroups: [ + { + images: [ + { + alt: 'Pull On Pant, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw018b9798/images/large/PG.10218785.JJ2XNXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw018b9798/images/large/PG.10218785.JJ2XNXX.PZ.jpg', + title: 'Pull On Pant, ' + }, + { + alt: 'Pull On Pant, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5303e0ee/images/large/PG.10218785.JJ2XNXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5303e0ee/images/large/PG.10218785.JJ2XNXX.BZ.jpg', + title: 'Pull On Pant, ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Pull On Pant, Grey Heather, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw018b9798/images/large/PG.10218785.JJ2XNXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw018b9798/images/large/PG.10218785.JJ2XNXX.PZ.jpg', + title: 'Pull On Pant, Grey Heather' + }, + { + alt: 'Pull On Pant, Grey Heather, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5303e0ee/images/large/PG.10218785.JJ2XNXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5303e0ee/images/large/PG.10218785.JJ2XNXX.BZ.jpg', + title: 'Pull On Pant, Grey Heather' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJ2XNXX' + } + ] + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Pull On Pant, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwba195443/images/medium/PG.10218785.JJ2XNXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwba195443/images/medium/PG.10218785.JJ2XNXX.PZ.jpg', + title: 'Pull On Pant, ' + }, + { + alt: 'Pull On Pant, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw8119e7a0/images/medium/PG.10218785.JJ2XNXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw8119e7a0/images/medium/PG.10218785.JJ2XNXX.BZ.jpg', + title: 'Pull On Pant, ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Pull On Pant, Grey Heather, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwba195443/images/medium/PG.10218785.JJ2XNXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwba195443/images/medium/PG.10218785.JJ2XNXX.PZ.jpg', + title: 'Pull On Pant, Grey Heather' + }, + { + alt: 'Pull On Pant, Grey Heather, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw8119e7a0/images/medium/PG.10218785.JJ2XNXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw8119e7a0/images/medium/PG.10218785.JJ2XNXX.BZ.jpg', + title: 'Pull On Pant, Grey Heather' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJ2XNXX' + } + ] + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Pull On Pant, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw19377146/images/small/PG.10218785.JJ2XNXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw19377146/images/small/PG.10218785.JJ2XNXX.PZ.jpg', + title: 'Pull On Pant, ' + }, + { + alt: 'Pull On Pant, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw912e293d/images/small/PG.10218785.JJ2XNXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw912e293d/images/small/PG.10218785.JJ2XNXX.BZ.jpg', + title: 'Pull On Pant, ' + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Pull On Pant, Grey Heather, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw19377146/images/small/PG.10218785.JJ2XNXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw19377146/images/small/PG.10218785.JJ2XNXX.PZ.jpg', + title: 'Pull On Pant, Grey Heather' + }, + { + alt: 'Pull On Pant, Grey Heather, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw912e293d/images/small/PG.10218785.JJ2XNXX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw912e293d/images/small/PG.10218785.JJ2XNXX.BZ.jpg', + title: 'Pull On Pant, Grey Heather' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJ2XNXX' + } + ] + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Pull On Pant, Grey Heather, swatch', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw9dedffb4/images/swatch/PG.10218785.JJ2XNXX.CP.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw9dedffb4/images/swatch/PG.10218785.JJ2XNXX.CP.jpg', + title: 'Pull On Pant, Grey Heather' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJ2XNXX' + } + ] + } + ], + viewType: 'swatch' + } + ], + inventory: { + ats: 500, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 500 + }, + longDescription: + 'Meet a Commerce Cloud Store new wardrobe favorite - a knit pant that works perfectly 12 months a year!', + master: { + masterId: '25518704M', + orderable: true, + price: 44.16 + }, + minOrderQuantity: 1, + name: 'Pull On Pant', + pageDescription: + 'Meet a Commerce Cloud Store new wardrobe favorite - a knit pant that works perfectly 12 months a year!', + pageTitle: 'Pull On Pant', + price: 44.16, + pricePerUnit: 44.16, + primaryCategoryId: 'womens-clothing-bottoms', + shortDescription: + 'Meet a Commerce Cloud Store new wardrobe favorite - a knit pant that works perfectly 12 months a year!', + stepQuantity: 1, + type: { + master: true + }, + validFrom: { + default: '2010-10-21T04:00:00.000Z' + }, + variants: [ + { + orderable: true, + price: 44.16, + productId: '701642867098M', + variationValues: { + color: 'JJ2XNXX', + size: '9LG' + } + }, + { + orderable: true, + price: 44.16, + productId: '701642867111M', + variationValues: { + color: 'JJ2XNXX', + size: '9SM' + } + }, + { + orderable: true, + price: 44.16, + productId: '701642867104M', + variationValues: { + color: 'JJ2XNXX', + size: '9MD' + } + }, + { + orderable: true, + price: 44.16, + productId: '701642867128M', + variationValues: { + color: 'JJ2XNXX', + size: '9XL' + } + }, + { + orderable: true, + price: 44.16, + productId: '701642867135M', + variationValues: { + color: 'JJ2XNXX', + size: '9XS' + } + } + ], + variationAttributes: [ + { + id: 'color', + name: 'Colour', + values: [ + { + name: 'Grey Heather', + orderable: true, + value: 'JJ2XNXX' + } + ] + }, + { + id: 'size', + name: 'Size', + values: [ + { + name: 'XS', + orderable: true, + value: '9XS' + }, + { + name: 'S', + orderable: true, + value: '9SM' + }, + { + name: 'M', + orderable: true, + value: '9MD' + }, + { + name: 'L', + orderable: true, + value: '9LG' + }, + { + name: 'XL', + orderable: true, + value: '9XL' + } + ] + } + ], + c_isNewtest: true + }, + { + currency: 'GBP', + id: '25772717M', + imageGroups: [ + { + images: [ + { + alt: 'Zerrick, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw25b9c8eb/images/large/PG.CJZERRICK.BLACKLE.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw25b9c8eb/images/large/PG.CJZERRICK.BLACKLE.PZ.jpg', + title: 'Zerrick, ' + }, + { + alt: 'Zerrick, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw42769ff1/images/large/PG.CJZERRICK.BLACKLE.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw42769ff1/images/large/PG.CJZERRICK.BLACKLE.BZ.jpg', + title: 'Zerrick, ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Zerrick, Black, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw25b9c8eb/images/large/PG.CJZERRICK.BLACKLE.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw25b9c8eb/images/large/PG.CJZERRICK.BLACKLE.PZ.jpg', + title: 'Zerrick, Black' + }, + { + alt: 'Zerrick, Black, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw42769ff1/images/large/PG.CJZERRICK.BLACKLE.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw42769ff1/images/large/PG.CJZERRICK.BLACKLE.BZ.jpg', + title: 'Zerrick, Black' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'BLACKLE' + } + ] + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Zerrick, Taupe, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw08fba265/images/large/PG.CJZERRICK.TAUPETX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw08fba265/images/large/PG.CJZERRICK.TAUPETX.PZ.jpg', + title: 'Zerrick, Taupe' + }, + { + alt: 'Zerrick, Taupe, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw20ceacbb/images/large/PG.CJZERRICK.TAUPETX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw20ceacbb/images/large/PG.CJZERRICK.TAUPETX.BZ.jpg', + title: 'Zerrick, Taupe' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'TAUPETX' + } + ] + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Zerrick, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw0ae06682/images/medium/PG.CJZERRICK.BLACKLE.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw0ae06682/images/medium/PG.CJZERRICK.BLACKLE.PZ.jpg', + title: 'Zerrick, ' + }, + { + alt: 'Zerrick, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw025c3d0d/images/medium/PG.CJZERRICK.BLACKLE.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw025c3d0d/images/medium/PG.CJZERRICK.BLACKLE.BZ.jpg', + title: 'Zerrick, ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Zerrick, Black, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw0ae06682/images/medium/PG.CJZERRICK.BLACKLE.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw0ae06682/images/medium/PG.CJZERRICK.BLACKLE.PZ.jpg', + title: 'Zerrick, Black' + }, + { + alt: 'Zerrick, Black, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw025c3d0d/images/medium/PG.CJZERRICK.BLACKLE.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw025c3d0d/images/medium/PG.CJZERRICK.BLACKLE.BZ.jpg', + title: 'Zerrick, Black' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'BLACKLE' + } + ] + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Zerrick, Taupe, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw0019f83a/images/medium/PG.CJZERRICK.TAUPETX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw0019f83a/images/medium/PG.CJZERRICK.TAUPETX.PZ.jpg', + title: 'Zerrick, Taupe' + }, + { + alt: 'Zerrick, Taupe, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw2ac76531/images/medium/PG.CJZERRICK.TAUPETX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw2ac76531/images/medium/PG.CJZERRICK.TAUPETX.BZ.jpg', + title: 'Zerrick, Taupe' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'TAUPETX' + } + ] + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Zerrick, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwfa0a6275/images/small/PG.CJZERRICK.BLACKLE.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwfa0a6275/images/small/PG.CJZERRICK.BLACKLE.PZ.jpg', + title: 'Zerrick, ' + }, + { + alt: 'Zerrick, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw47a9b12f/images/small/PG.CJZERRICK.BLACKLE.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw47a9b12f/images/small/PG.CJZERRICK.BLACKLE.BZ.jpg', + title: 'Zerrick, ' + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Zerrick, Black, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwfa0a6275/images/small/PG.CJZERRICK.BLACKLE.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwfa0a6275/images/small/PG.CJZERRICK.BLACKLE.PZ.jpg', + title: 'Zerrick, Black' + }, + { + alt: 'Zerrick, Black, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw47a9b12f/images/small/PG.CJZERRICK.BLACKLE.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw47a9b12f/images/small/PG.CJZERRICK.BLACKLE.BZ.jpg', + title: 'Zerrick, Black' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'BLACKLE' + } + ] + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Zerrick, Taupe, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwabc944c5/images/small/PG.CJZERRICK.TAUPETX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwabc944c5/images/small/PG.CJZERRICK.TAUPETX.PZ.jpg', + title: 'Zerrick, Taupe' + }, + { + alt: 'Zerrick, Taupe, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5b4e54ad/images/small/PG.CJZERRICK.TAUPETX.BZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5b4e54ad/images/small/PG.CJZERRICK.TAUPETX.BZ.jpg', + title: 'Zerrick, Taupe' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'TAUPETX' + } + ] + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Zerrick, Black, swatch', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwcc030b86/images/swatch/PG.CJZERRICK.BLACKLE.CP.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwcc030b86/images/swatch/PG.CJZERRICK.BLACKLE.CP.jpg', + title: 'Zerrick, Black' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'BLACKLE' + } + ] + } + ], + viewType: 'swatch' + }, + { + images: [ + { + alt: 'Zerrick, Taupe, swatch', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw9dc4320e/images/swatch/PG.CJZERRICK.TAUPETX.CP.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw9dc4320e/images/swatch/PG.CJZERRICK.TAUPETX.CP.jpg', + title: 'Zerrick, Taupe' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'TAUPETX' + } + ] + } + ], + viewType: 'swatch' + } + ], + inventory: { + ats: 1498, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 1498 + }, + longDescription: 'The perfect pump for any outfit!', + master: { + masterId: '25772717M', + orderable: true, + price: 63.36 + }, + minOrderQuantity: 1, + name: 'Zerrick', + pageDescription: 'The perfect pump for any outfit!', + pageTitle: 'Zerrick', + price: 63.36, + pricePerUnit: 63.36, + primaryCategoryId: 'womens-accessories-shoes', + recommendations: [ + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: '25593254M' + }, + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: '25720050M' + } + ], + shortDescription: 'The perfect pump for any outfit!', + stepQuantity: 1, + type: { + master: true + }, + validFrom: { + default: '2011-03-01T05:00:00.000Z' + }, + variants: [ + { + orderable: true, + price: 63.36, + productId: '740357357531M', + variationValues: { + color: 'BLACKLE', + size: '065', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358095M', + variationValues: { + color: 'TAUPETX', + size: '065', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357623M', + variationValues: { + color: 'BLACKLE', + size: '110', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357609M', + variationValues: { + color: 'BLACKLE', + size: '100', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358156M', + variationValues: { + color: 'TAUPETX', + size: '095', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358132M', + variationValues: { + color: 'TAUPETX', + size: '085', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358101M', + variationValues: { + color: 'TAUPETX', + size: '070', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357562M', + variationValues: { + color: 'BLACKLE', + size: '080', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357548M', + variationValues: { + color: 'BLACKLE', + size: '070', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358187M', + variationValues: { + color: 'TAUPETX', + size: '110', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357593M', + variationValues: { + color: 'BLACKLE', + size: '095', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357555M', + variationValues: { + color: 'BLACKLE', + size: '075', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357524M', + variationValues: { + color: 'BLACKLE', + size: '060', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358149M', + variationValues: { + color: 'TAUPETX', + size: '090', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358088M', + variationValues: { + color: 'TAUPETX', + size: '060', + width: 'M' + } + } + ], + variationAttributes: [ + { + id: 'color', + name: 'Colour', + values: [ + { + name: 'Black', + orderable: true, + value: 'BLACKLE' + }, + { + name: 'Taupe', + orderable: true, + value: 'TAUPETX' + } + ] + }, + { + id: 'size', + name: 'Size', + values: [ + { + name: '6', + orderable: true, + value: '060' + }, + { + name: '6.5', + orderable: true, + value: '065' + }, + { + name: '7', + orderable: true, + value: '070' + }, + { + name: '7.5', + orderable: true, + value: '075' + }, + { + name: '8', + orderable: true, + value: '080' + }, + { + name: '8.5', + orderable: true, + value: '085' + }, + { + name: '9', + orderable: true, + value: '090' + }, + { + name: '9.5', + orderable: true, + value: '095' + }, + { + name: '10', + orderable: true, + value: '100' + }, + { + name: '11', + orderable: true, + value: '110' + } + ] + }, + { + id: 'width', + name: 'Width', + values: [ + { + name: 'M', + orderable: true, + value: 'M' + } + ] + } + ] + } + ], + shortDescription: 'Look for Winter', + slugUrl: + 'https://zzrf-001.dx.commercecloud.salesforce.com/s/RefArchGlobal/womens/clothing/outfits/winter-lookM.html?lang=en_GB', + stepQuantity: 1, + type: { + set: true + } +} diff --git a/packages/template-retail-react-app/app/components/product-tile/index.jsx b/packages/template-retail-react-app/app/components/product-tile/index.jsx index e509366788..b27205a8b6 100644 --- a/packages/template-retail-react-app/app/components/product-tile/index.jsx +++ b/packages/template-retail-react-app/app/components/product-tile/index.jsx @@ -130,7 +130,7 @@ const ProductTile = (props) => { {localizedProductName} {/* Price */} - + {hitType === 'set' && intl.formatMessage({ id: 'product_tile.label.starting_at_price', diff --git a/packages/template-retail-react-app/app/components/product-tile/index.test.js b/packages/template-retail-react-app/app/components/product-tile/index.test.js index fa6185fb79..86a3be2091 100644 --- a/packages/template-retail-react-app/app/components/product-tile/index.test.js +++ b/packages/template-retail-react-app/app/components/product-tile/index.test.js @@ -19,7 +19,58 @@ const mockProductSearchItem = { productName: 'Charcoal Single Pleat Wool Suit' } -test('Renders Breadcrumb', () => { +const mockProductSet = { + currency: 'GBP', + hitType: 'set', + image: { + alt: 'Winter Look, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe1c4cd52/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe1c4cd52/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Winter Look, ' + }, + orderable: true, + price: 44.16, + priceMax: 71.03, + pricePerUnit: 44.16, + pricePerUnitMax: 71.03, + productId: 'winter-lookM', + productName: 'Winter Look', + productType: { + set: true + }, + representedProduct: { + id: '701642853695M' + }, + representedProducts: [ + {id: '701642853695M'}, + {id: '701642853718M'}, + {id: '701642853725M'}, + {id: '701642853701M'}, + {id: '740357357531M'}, + {id: '740357358095M'}, + {id: '740357357623M'}, + {id: '740357357609M'}, + {id: '740357358156M'}, + {id: '740357358132M'}, + {id: '740357358101M'}, + {id: '740357357562M'}, + {id: '740357357548M'}, + {id: '740357358187M'}, + {id: '740357357593M'}, + {id: '740357357555M'}, + {id: '740357357524M'}, + {id: '740357358149M'}, + {id: '740357358088M'}, + {id: '701642867098M'}, + {id: '701642867111M'}, + {id: '701642867104M'}, + {id: '701642867128M'}, + {id: '701642867135M'} + ] +} + +test('Renders links and images', () => { const {getAllByRole} = renderWithProviders() const link = getAllByRole('link') @@ -36,3 +87,10 @@ test('Renders Skeleton', () => { expect(skeleton).toBeDefined() }) + +test('Product set - renders the appropriate price label', async () => { + const {getByTestId} = renderWithProviders() + + const container = getByTestId('product-tile-price') + expect(container).toHaveTextContent(/starting at/i) +}) diff --git a/packages/template-retail-react-app/app/components/product-view-modal/index.jsx b/packages/template-retail-react-app/app/components/product-view-modal/index.jsx index 3471ba7be2..43f7fec12b 100644 --- a/packages/template-retail-react-app/app/components/product-view-modal/index.jsx +++ b/packages/template-retail-react-app/app/components/product-view-modal/index.jsx @@ -17,9 +17,9 @@ import {useProductViewModal} from '../../hooks/use-product-view-modal' const ProductViewModal = ({product, isOpen, onClose, ...props}) => { const productViewModalData = useProductViewModal(product) return ( - + - + { const intl = useIntl() const basket = useBasket() const size = useBreakpointValue({base: 'full', lg: '2xl', xl: '4xl'}) - const {currency, productItems, productSubTotal, itemAccumulatedCount} = basket + const {currency, productItems, productSubTotal} = basket const totalQuantity = itemsAdded.reduce((acc, {quantity}) => acc + quantity, 0) return ( - + {intl.formatMessage( { @@ -118,6 +123,7 @@ export const AddToCartModal = () => { borderBottomWidth={{base: '1px', lg: '0px'}} borderColor="gray.200" borderStyle="solid" + data-testid="product-added" > @@ -180,7 +186,7 @@ export const AddToCartModal = () => { 'Cart Subtotal ({itemAccumulatedCount} item)', id: 'add_to_cart_modal.label.cart_subtotal' }, - {itemAccumulatedCount} + {itemAccumulatedCount: totalQuantity} )} @@ -245,7 +251,7 @@ export const AddToCartModal = () => { defaultMessage: 'Cart Subtotal ({itemAccumulatedCount} item)', id: 'add_to_cart_modal.label.cart_subtotal' }, - {itemAccumulatedCount} + {itemAccumulatedCount: totalQuantity} )} diff --git a/packages/template-retail-react-app/app/hooks/use-add-to-cart-modal.test.js b/packages/template-retail-react-app/app/hooks/use-add-to-cart-modal.test.js index c0ffdcc18e..effa7501cd 100644 --- a/packages/template-retail-react-app/app/hooks/use-add-to-cart-modal.test.js +++ b/packages/template-retail-react-app/app/hooks/use-add-to-cart-modal.test.js @@ -7,6 +7,7 @@ import React from 'react' import {AddToCartModal, AddToCartModalContext} from './use-add-to-cart-modal' import {renderWithProviders} from '../utils/test-utils' +import {screen} from '@testing-library/react' const MOCK_PRODUCT = { currency: 'USD', @@ -560,7 +561,7 @@ const MOCK_PRODUCT = { c_width: 'Z' } -test('Renders AddToCartModal', () => { +test('Renders AddToCartModal with multiple products', () => { const MOCK_DATA = { product: MOCK_PRODUCT, itemsAdded: [ @@ -568,10 +569,16 @@ test('Renders AddToCartModal', () => { product: MOCK_PRODUCT, variant: MOCK_PRODUCT.variants[0], quantity: 22 + }, + { + product: MOCK_PRODUCT, + variant: MOCK_PRODUCT.variants[0], + quantity: 1 } ] } - const {getByText} = renderWithProviders( + + renderWithProviders( { ) - expect(getByText(MOCK_PRODUCT.name)).toBeInTheDocument() + expect(screen.getAllByText(MOCK_PRODUCT.name)[0]).toBeInTheDocument() + expect(screen.getByRole('dialog', {name: /23 items added to cart/i})).toBeInTheDocument() + + const numOfRowsRendered = screen.getAllByTestId('product-added').length + expect(numOfRowsRendered).toEqual(MOCK_DATA.itemsAdded.length) }) test('Do not render when isOpen is false', () => { diff --git a/packages/template-retail-react-app/app/hooks/use-pdp-search-params.test.js b/packages/template-retail-react-app/app/hooks/use-pdp-search-params.test.js new file mode 100644 index 0000000000..67136b08ee --- /dev/null +++ b/packages/template-retail-react-app/app/hooks/use-pdp-search-params.test.js @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ + +import React from 'react' +import {screen} from '@testing-library/react' +import PropTypes from 'prop-types' +import {usePDPSearchParams} from './use-pdp-search-params' +import {renderWithProviders} from '../utils/test-utils' + +const MockComponent = ({productId} = {}) => { + const [allParams, productParams] = usePDPSearchParams(productId) + + return ( + <> +
{allParams.toString()}
+
{productParams.toString()}
{' '} + + ) +} +MockComponent.propTypes = { + productId: PropTypes.string +} + +test('product set', () => { + const url = + // The parent's id is `winter-lookM`, while the children's are `25518447M` and `25518704M` + '/global/en-GB/product/winter-lookM?25518447M=color%3DJJ5FUXX%26size%3D9XL&25518704M=color%3DJJ2XNXX%26size%3D9MD' + window.history.pushState({}, '', url) + + renderWithProviders() + + expect(screen.getByTestId('all-params')).toHaveTextContent( + /^25518447M=color%3DJJ5FUXX%26size%3D9XL&25518704M=color%3DJJ2XNXX%26size%3D9MD$/ + ) + expect(screen.getByTestId('product-params')).toHaveTextContent(/^color=JJ2XNXX&size=9MD$/) +}) + +test('regular product with variant', () => { + const url = '/global/en-GB/product/25502228M?color=JJ0NLD0&size=9MD&pid=701642889830M' + window.history.pushState({}, '', url) + + renderWithProviders() + + expect(screen.getByTestId('all-params')).toHaveTextContent( + /^color=JJ0NLD0&size=9MD&pid=701642889830M$/ + ) + expect(screen.getByTestId('product-params')).toHaveTextContent(/^$/) +}) diff --git a/packages/template-retail-react-app/app/pages/account/wishlist/partials/wishlist-primary-action.mock.js b/packages/template-retail-react-app/app/pages/account/wishlist/partials/wishlist-primary-action.mock.js new file mode 100644 index 0000000000..0932e7cdc1 --- /dev/null +++ b/packages/template-retail-react-app/app/pages/account/wishlist/partials/wishlist-primary-action.mock.js @@ -0,0 +1,1623 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +export const mockWishListDetails = { + limit: 4, + data: [ + { + currency: 'GBP', + id: 'winter-lookM', + imageGroups: [ + { + images: [ + { + alt: 'Winter Look, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe6b93900/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe6b93900/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Winter Look, ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Winter Look, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwfce3ae7f/images/medium/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwfce3ae7f/images/medium/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Winter Look, ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Winter Look, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw97ad16fc/images/small/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw97ad16fc/images/small/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Winter Look, ' + } + ], + viewType: 'small' + } + ], + longDescription: '

Jacket

\r\n

Pant

\r\n

Shoes

', + minOrderQuantity: 1, + name: 'Winter Look', + price: 44.16, + priceMax: 71.03, + pricePerUnit: 44.16, + pricePerUnitMax: 71.03, + primaryCategoryId: 'womens-outfits', + shortDescription: 'Look for Winter', + setProducts: [ + { + currency: 'GBP', + id: '25518447M', + imageGroups: [ + { + images: [ + { + alt: 'Quilted Jacket, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe6b93900/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe6b93900/images/large/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Quilted Jacket, ' + }, + { + alt: 'Quilted Jacket, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw3f3cfaa8/images/large/PG.10205921.JJ5FUXX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw3f3cfaa8/images/large/PG.10205921.JJ5FUXX.BZ.jpg', + title: 'Quilted Jacket, ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Quilted Jacket, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwfce3ae7f/images/medium/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwfce3ae7f/images/medium/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Quilted Jacket, ' + }, + { + alt: 'Quilted Jacket, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5d0b1941/images/medium/PG.10205921.JJ5FUXX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5d0b1941/images/medium/PG.10205921.JJ5FUXX.BZ.jpg', + title: 'Quilted Jacket, ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Quilted Jacket, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw97ad16fc/images/small/PG.10205921.JJ5FUXX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw97ad16fc/images/small/PG.10205921.JJ5FUXX.PZ.jpg', + title: 'Quilted Jacket, ' + }, + { + alt: 'Quilted Jacket, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw764f0594/images/small/PG.10205921.JJ5FUXX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw764f0594/images/small/PG.10205921.JJ5FUXX.BZ.jpg', + title: 'Quilted Jacket, ' + } + ], + viewType: 'small' + } + ], + inventory: { + ats: 400, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 400 + }, + longDescription: + 'A classic quilted car coat looks new again. Add a great Commerce Cloud Store top for a perfect look.', + master: { + masterId: '25518447M', + orderable: true, + price: 71.03 + }, + minOrderQuantity: 1, + name: 'Quilted Jacket', + pageDescription: + 'A classic quilted car coat looks new again. Add a great Commerce Cloud Store top for a perfect look.', + pageTitle: 'Quilted Jacket', + price: 71.03, + pricePerUnit: 71.03, + primaryCategoryId: 'womens-clothing-jackets', + recommendations: [ + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: '22951021M' + }, + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: '25518397M' + } + ], + shortDescription: + 'A classic quilted car coat looks new again. Add a great Commerce Cloud Store top for a perfect look.', + stepQuantity: 1, + type: { + master: true + }, + validFrom: { + default: '2010-10-21T04:00:00.000Z' + }, + variants: [ + { + orderable: true, + price: 71.03, + productId: '701642853695M', + variationValues: { + color: 'JJ5FUXX', + size: '9LG' + } + }, + { + orderable: true, + price: 71.03, + productId: '701642853718M', + variationValues: { + color: 'JJ5FUXX', + size: '9SM' + } + }, + { + orderable: true, + price: 71.03, + productId: '701642853725M', + variationValues: { + color: 'JJ5FUXX', + size: '9XL' + } + }, + { + orderable: true, + price: 71.03, + productId: '701642853701M', + variationValues: { + color: 'JJ5FUXX', + size: '9MD' + } + } + ], + variationAttributes: [ + { + id: 'color', + name: 'Colour', + values: [ + { + name: 'royal', + orderable: true, + value: 'JJ5FUXX' + } + ] + }, + { + id: 'size', + name: 'Size', + values: [ + { + name: 'S', + orderable: true, + value: '9SM' + }, + { + name: 'M', + orderable: true, + value: '9MD' + }, + { + name: 'L', + orderable: true, + value: '9LG' + }, + { + name: 'XL', + orderable: true, + value: '9XL' + } + ] + } + ], + c_isNewtest: true, + c_isSale: true + }, + { + currency: 'GBP', + id: '25518704M', + imageGroups: [ + { + images: [ + { + alt: 'Pull On Pant, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwf7f4a945/images/large/PG.10218785.JJ2XNXX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwf7f4a945/images/large/PG.10218785.JJ2XNXX.PZ.jpg', + title: 'Pull On Pant, ' + }, + { + alt: 'Pull On Pant, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwb6df46d9/images/large/PG.10218785.JJ2XNXX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwb6df46d9/images/large/PG.10218785.JJ2XNXX.BZ.jpg', + title: 'Pull On Pant, ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Pull On Pant, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe1f27107/images/medium/PG.10218785.JJ2XNXX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe1f27107/images/medium/PG.10218785.JJ2XNXX.PZ.jpg', + title: 'Pull On Pant, ' + }, + { + alt: 'Pull On Pant, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwb0628c49/images/medium/PG.10218785.JJ2XNXX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwb0628c49/images/medium/PG.10218785.JJ2XNXX.BZ.jpg', + title: 'Pull On Pant, ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Pull On Pant, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe180ef4e/images/small/PG.10218785.JJ2XNXX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwe180ef4e/images/small/PG.10218785.JJ2XNXX.PZ.jpg', + title: 'Pull On Pant, ' + }, + { + alt: 'Pull On Pant, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwf7fe8cc7/images/small/PG.10218785.JJ2XNXX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwf7fe8cc7/images/small/PG.10218785.JJ2XNXX.BZ.jpg', + title: 'Pull On Pant, ' + } + ], + viewType: 'small' + } + ], + inventory: { + ats: 500, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 500 + }, + longDescription: + 'Meet a Commerce Cloud Store new wardrobe favorite - a knit pant that works perfectly 12 months a year!', + master: { + masterId: '25518704M', + orderable: true, + price: 44.16 + }, + minOrderQuantity: 1, + name: 'Pull On Pant', + pageDescription: + 'Meet a Commerce Cloud Store new wardrobe favorite - a knit pant that works perfectly 12 months a year!', + pageTitle: 'Pull On Pant', + price: 44.16, + pricePerUnit: 44.16, + primaryCategoryId: 'womens-clothing-bottoms', + shortDescription: + 'Meet a Commerce Cloud Store new wardrobe favorite - a knit pant that works perfectly 12 months a year!', + stepQuantity: 1, + type: { + master: true + }, + validFrom: { + default: '2010-10-21T04:00:00.000Z' + }, + variants: [ + { + orderable: true, + price: 44.16, + productId: '701642867098M', + variationValues: { + color: 'JJ2XNXX', + size: '9LG' + } + }, + { + orderable: true, + price: 44.16, + productId: '701642867111M', + variationValues: { + color: 'JJ2XNXX', + size: '9SM' + } + }, + { + orderable: true, + price: 44.16, + productId: '701642867104M', + variationValues: { + color: 'JJ2XNXX', + size: '9MD' + } + }, + { + orderable: true, + price: 44.16, + productId: '701642867128M', + variationValues: { + color: 'JJ2XNXX', + size: '9XL' + } + }, + { + orderable: true, + price: 44.16, + productId: '701642867135M', + variationValues: { + color: 'JJ2XNXX', + size: '9XS' + } + } + ], + variationAttributes: [ + { + id: 'color', + name: 'Colour', + values: [ + { + name: 'Grey Heather', + orderable: true, + value: 'JJ2XNXX' + } + ] + }, + { + id: 'size', + name: 'Size', + values: [ + { + name: 'XS', + orderable: true, + value: '9XS' + }, + { + name: 'S', + orderable: true, + value: '9SM' + }, + { + name: 'M', + orderable: true, + value: '9MD' + }, + { + name: 'L', + orderable: true, + value: '9LG' + }, + { + name: 'XL', + orderable: true, + value: '9XL' + } + ] + } + ], + c_isNewtest: true + }, + { + currency: 'GBP', + id: '25772717M', + imageGroups: [ + { + images: [ + { + alt: 'Zerrick, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwbf4dd593/images/large/PG.CJZERRICK.BLACKLE.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwbf4dd593/images/large/PG.CJZERRICK.BLACKLE.PZ.jpg', + title: 'Zerrick, ' + }, + { + alt: 'Zerrick, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwcc515695/images/large/PG.CJZERRICK.BLACKLE.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwcc515695/images/large/PG.CJZERRICK.BLACKLE.BZ.jpg', + title: 'Zerrick, ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Zerrick, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw44a22aa5/images/medium/PG.CJZERRICK.BLACKLE.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw44a22aa5/images/medium/PG.CJZERRICK.BLACKLE.PZ.jpg', + title: 'Zerrick, ' + }, + { + alt: 'Zerrick, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw18ebc5f7/images/medium/PG.CJZERRICK.BLACKLE.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw18ebc5f7/images/medium/PG.CJZERRICK.BLACKLE.BZ.jpg', + title: 'Zerrick, ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Zerrick, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw9248ea6e/images/small/PG.CJZERRICK.BLACKLE.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw9248ea6e/images/small/PG.CJZERRICK.BLACKLE.PZ.jpg', + title: 'Zerrick, ' + }, + { + alt: 'Zerrick, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwc38f297b/images/small/PG.CJZERRICK.BLACKLE.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwc38f297b/images/small/PG.CJZERRICK.BLACKLE.BZ.jpg', + title: 'Zerrick, ' + } + ], + viewType: 'small' + } + ], + inventory: { + ats: 1500, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 1500 + }, + longDescription: 'The perfect pump for any outfit!', + master: { + masterId: '25772717M', + orderable: true, + price: 63.36 + }, + minOrderQuantity: 1, + name: 'Zerrick', + pageDescription: 'The perfect pump for any outfit!', + pageTitle: 'Zerrick', + price: 63.36, + pricePerUnit: 63.36, + primaryCategoryId: 'womens-accessories-shoes', + recommendations: [ + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: '25593254M' + }, + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: '25720050M' + } + ], + shortDescription: 'The perfect pump for any outfit!', + stepQuantity: 1, + type: { + master: true + }, + validFrom: { + default: '2011-03-01T05:00:00.000Z' + }, + variants: [ + { + orderable: true, + price: 63.36, + productId: '740357357531M', + variationValues: { + color: 'BLACKLE', + size: '065', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358095M', + variationValues: { + color: 'TAUPETX', + size: '065', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357623M', + variationValues: { + color: 'BLACKLE', + size: '110', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357609M', + variationValues: { + color: 'BLACKLE', + size: '100', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358156M', + variationValues: { + color: 'TAUPETX', + size: '095', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358132M', + variationValues: { + color: 'TAUPETX', + size: '085', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358101M', + variationValues: { + color: 'TAUPETX', + size: '070', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357562M', + variationValues: { + color: 'BLACKLE', + size: '080', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357548M', + variationValues: { + color: 'BLACKLE', + size: '070', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358187M', + variationValues: { + color: 'TAUPETX', + size: '110', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357593M', + variationValues: { + color: 'BLACKLE', + size: '095', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357555M', + variationValues: { + color: 'BLACKLE', + size: '075', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357357524M', + variationValues: { + color: 'BLACKLE', + size: '060', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358149M', + variationValues: { + color: 'TAUPETX', + size: '090', + width: 'M' + } + }, + { + orderable: true, + price: 63.36, + productId: '740357358088M', + variationValues: { + color: 'TAUPETX', + size: '060', + width: 'M' + } + } + ], + variationAttributes: [ + { + id: 'color', + name: 'Colour', + values: [ + { + name: 'Black', + orderable: true, + value: 'BLACKLE' + }, + { + name: 'Taupe', + orderable: true, + value: 'TAUPETX' + } + ] + }, + { + id: 'size', + name: 'Size', + values: [ + { + name: '6', + orderable: true, + value: '060' + }, + { + name: '6.5', + orderable: true, + value: '065' + }, + { + name: '7', + orderable: true, + value: '070' + }, + { + name: '7.5', + orderable: true, + value: '075' + }, + { + name: '8', + orderable: true, + value: '080' + }, + { + name: '8.5', + orderable: true, + value: '085' + }, + { + name: '9', + orderable: true, + value: '090' + }, + { + name: '9.5', + orderable: true, + value: '095' + }, + { + name: '10', + orderable: true, + value: '100' + }, + { + name: '11', + orderable: true, + value: '110' + } + ] + }, + { + id: 'width', + name: 'Width', + values: [ + { + name: 'M', + orderable: true, + value: 'M' + } + ] + } + ] + } + ], + slugUrl: + 'https://zzrf-009.dx.commercecloud.salesforce.com/s/RefArchGlobal/womens/clothing/outfits/winter-lookM.html?lang=en_GB', + stepQuantity: 1, + type: { + set: true + }, + quantity: 1 + }, + { + currency: 'GBP', + id: 'some-outfit', + minOrderQuantity: 1, + name: 'Some Outfit', + price: 63.99, + pricePerUnit: 63.99, + primaryCategoryId: 'womens-outfits', + setProducts: [ + { + currency: 'GBP', + id: 'P0150M', + imageGroups: [ + { + images: [ + { + alt: 'Upright Case (33L - 3.7Kg), , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw7cc6a969/images/large/P0150_001.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw7cc6a969/images/large/P0150_001.jpg', + title: 'Upright Case (33L - 3.7Kg), ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Upright Case (33L - 3.7Kg), , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwcb7fa07a/images/medium/P0150_001.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwcb7fa07a/images/medium/P0150_001.jpg', + title: 'Upright Case (33L - 3.7Kg), ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Upright Case (33L - 3.7Kg), , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5630e983/images/small/P0150_001.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5630e983/images/small/P0150_001.jpg', + title: 'Upright Case (33L - 3.7Kg), ' + } + ], + viewType: 'small' + } + ], + inventory: { + ats: 2, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 2 + }, + longDescription: + '1682 ballistic nylon and genuine leather inserts |Pull-out metallic handle for wheeling|Top and side handles|Cabin size for convenient travelling|TSA lock for security', + minOrderQuantity: 1, + name: 'Upright Case (33L - 3.7Kg)', + pageDescription: + 'This practical case is perfect for business – with no need to check in as luggage due to its cabin size dimensions – or for any no-fuss travel.', + pageKeywords: + 'Commerce Cloud, P0150, T10 150 Upright 50, General Accessories, Accessories, Packs and Gear', + pageTitle: 'Commerce Cloud - Upright Case (33L - 3.7Kg)', + price: 63.99, + pricePerUnit: 63.99, + primaryCategoryId: 'mens-accessories-luggage', + recommendations: [ + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: 'P0048M' + }, + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: 'P0138M' + } + ], + shortDescription: + 'This practical and functional case is perfect for business – with no need to check in as luggage due to its cabin size dimensions – or for any convenient no-fuss travel any time any where. You can pull along for comfort or carry by the handle, and with plenty of space inside and a large front pocket with additional zippered pocket, there’s plenty of useful and compact storage.', + stepQuantity: 1, + type: { + item: true + }, + c_styleNumber: 'P0150', + c_tabDescription: + 'This practical and functional case is perfect for business – with no need to check in as luggage due to its cabin size dimensions – or for any convenient no-fuss travel any time any where. You can pull along for comfort or carry by the handle, and with plenty of space inside and a large front pocket with additional zippered pocket, there’s plenty of useful and compact storage.', + c_tabDetails: + '1682 ballistic nylon and genuine leather inserts |Pull-out metallic handle for wheeling|Top and side handles|Cabin size for convenient travelling|TSA lock for security' + }, + { + currency: 'GBP', + id: 'P0138M', + imageGroups: [ + { + images: [ + { + alt: 'Laptop Messenger (16L), , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw59b8bbd6/images/large/P0138_001.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw59b8bbd6/images/large/P0138_001.jpg', + title: 'Laptop Messenger (16L), ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Laptop Messenger (16L), , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwf15f2283/images/medium/P0138_001.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwf15f2283/images/medium/P0138_001.jpg', + title: 'Laptop Messenger (16L), ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Laptop Messenger (16L), , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5bfec55c/images/small/P0138_001.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5bfec55c/images/small/P0138_001.jpg', + title: 'Laptop Messenger (16L), ' + } + ], + viewType: 'small' + } + ], + inventory: { + ats: 100, + backorderable: false, + id: 'inventory_m', + inStockDate: '2012-03-09T00:00:00.000Z', + orderable: true, + preorderable: true, + stockLevel: 0 + }, + longDescription: + '1682 ballistic nylon and genuine leather inserts|Shoulder strap and top handle for alternative carrying options|Main compartment for laptop storage|Internal pockets for storage and organisation|TSA Lock for security', + minOrderQuantity: 1, + name: 'Laptop Messenger (16L)', + pageDescription: + 'This duffle style laptop messenger bag is great for travelling and commuting with your laptop and other essential work items. Compact and comfortable.', + pageKeywords: + 'Commerce Cloud, P0138, Packs and Gear Laptop Messenger, Black, Computer Bag, Cases, Luggage, Sling Bag, Should Begs', + pageTitle: 'Commerce Cloud - Laptop Messenger (16L)', + price: 63.99, + pricePerUnit: 63.99, + primaryCategoryId: 'mens-accessories-luggage', + recommendations: [ + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: 'P0150M' + }, + { + recommendationType: { + displayValue: 'Product Detail Page - Cross Sell', + value: 1 + }, + recommendedItemId: 'P0048M' + } + ], + shortDescription: + 'This duffle style laptop messenger bag is great for travelling and commuting with your laptop and other essential work items. Compact and comfortable with internal and external pockets for storage, carry over your shoulder for support and balance or by the top handle for a more briefcase-style look.', + stepQuantity: 1, + type: { + item: true + }, + c_styleNumber: 'P0138', + c_tabDescription: + 'This duffle style laptop messenger bag is great for travelling and commuting with your laptop and other essential work items. Compact and comfortable with internal and external pockets for storage, carry over your shoulder for support and balance or by the top handle for a more briefcase-style look.', + c_tabDetails: + '1682 ballistic nylon and genuine leather inserts|Shoulder strap and top handle for alternative carrying options|Main compartment for laptop storage|Internal pockets for storage and organisation|TSA Lock for security' + } + ], + slugUrl: + 'https://zzrf-009.dx.commercecloud.salesforce.com/s/RefArchGlobal/womens/clothing/outfits/some-outfit.html?lang=en_GB', + stepQuantity: 1, + type: { + set: true + }, + quantity: 1 + }, + { + currency: 'GBP', + id: '25501802M', + imageGroups: [ + { + images: [ + { + alt: 'Textured Zip Front Cardigan, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw978b037a/images/large/PG.10219181.JJG80XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw978b037a/images/large/PG.10219181.JJG80XX.PZ.jpg', + title: 'Textured Zip Front Cardigan, ' + }, + { + alt: 'Textured Zip Front Cardigan, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwebe72fa5/images/large/PG.10219181.JJG80XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwebe72fa5/images/large/PG.10219181.JJG80XX.BZ.jpg', + title: 'Textured Zip Front Cardigan, ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Textured Zip Front Cardigan, Sugar, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw978b037a/images/large/PG.10219181.JJG80XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw978b037a/images/large/PG.10219181.JJG80XX.PZ.jpg', + title: 'Textured Zip Front Cardigan, Sugar' + }, + { + alt: 'Textured Zip Front Cardigan, Sugar, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwebe72fa5/images/large/PG.10219181.JJG80XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwebe72fa5/images/large/PG.10219181.JJG80XX.BZ.jpg', + title: 'Textured Zip Front Cardigan, Sugar' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJG80XX' + } + ] + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Textured Zip Front Cardigan, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw9cfb0f38/images/medium/PG.10219181.JJG80XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw9cfb0f38/images/medium/PG.10219181.JJG80XX.PZ.jpg', + title: 'Textured Zip Front Cardigan, ' + }, + { + alt: 'Textured Zip Front Cardigan, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw34667c2c/images/medium/PG.10219181.JJG80XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw34667c2c/images/medium/PG.10219181.JJG80XX.BZ.jpg', + title: 'Textured Zip Front Cardigan, ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Textured Zip Front Cardigan, Sugar, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw9cfb0f38/images/medium/PG.10219181.JJG80XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw9cfb0f38/images/medium/PG.10219181.JJG80XX.PZ.jpg', + title: 'Textured Zip Front Cardigan, Sugar' + }, + { + alt: 'Textured Zip Front Cardigan, Sugar, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw34667c2c/images/medium/PG.10219181.JJG80XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw34667c2c/images/medium/PG.10219181.JJG80XX.BZ.jpg', + title: 'Textured Zip Front Cardigan, Sugar' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJG80XX' + } + ] + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Textured Zip Front Cardigan, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwa9c81767/images/small/PG.10219181.JJG80XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwa9c81767/images/small/PG.10219181.JJG80XX.PZ.jpg', + title: 'Textured Zip Front Cardigan, ' + }, + { + alt: 'Textured Zip Front Cardigan, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5f88f729/images/small/PG.10219181.JJG80XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5f88f729/images/small/PG.10219181.JJG80XX.BZ.jpg', + title: 'Textured Zip Front Cardigan, ' + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Textured Zip Front Cardigan, Sugar, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwa9c81767/images/small/PG.10219181.JJG80XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwa9c81767/images/small/PG.10219181.JJG80XX.PZ.jpg', + title: 'Textured Zip Front Cardigan, Sugar' + }, + { + alt: 'Textured Zip Front Cardigan, Sugar, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5f88f729/images/small/PG.10219181.JJG80XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5f88f729/images/small/PG.10219181.JJG80XX.BZ.jpg', + title: 'Textured Zip Front Cardigan, Sugar' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJG80XX' + } + ] + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Textured Zip Front Cardigan, Sugar, swatch', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwa9e0d71c/images/swatch/PG.10219181.JJG80XX.CP.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwa9e0d71c/images/swatch/PG.10219181.JJG80XX.CP.jpg', + title: 'Textured Zip Front Cardigan, Sugar' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJG80XX' + } + ] + } + ], + viewType: 'swatch' + } + ], + inventory: { + ats: 400, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 400 + }, + longDescription: + 'Classically designed, this zip front textured cardigan is perfect to pair with a great Commerce Cloud Store bottom!', + master: { + masterId: '25501802M', + orderable: true, + price: 53.11 + }, + minOrderQuantity: 1, + name: 'Textured Zip Front Cardigan', + pageDescription: + 'Classically designed, this zip front textured cardigan is perfect to pair with a great Commerce Cloud Store bottom!', + pageTitle: 'Textured Zip Front Cardigan', + price: 53.11, + pricePerUnit: 53.11, + primaryCategoryId: 'womens-clothing-tops', + productPromotions: [ + { + calloutMsg: 'Buy one Long Center Seam Skirt and get 2 tops', + promotionId: 'ChoiceOfBonusProdect-ProductLevel-ruleBased' + } + ], + shortDescription: + 'Classically designed, this zip front textured cardigan is perfect to pair with a great Commerce Cloud Store bottom!', + slugUrl: + 'https://zzrf-009.dx.commercecloud.salesforce.com/s/RefArchGlobal/textured-zip-front-cardigan/25501802M.html?lang=en_GB', + stepQuantity: 1, + type: { + master: true + }, + validFrom: { + default: '2010-10-21T04:00:00.000Z' + }, + variants: [ + { + orderable: true, + price: 53.11, + productId: '701642856139M', + variationValues: { + color: 'JJG80XX', + size: '9LG' + } + }, + { + orderable: true, + price: 53.11, + productId: '701642856160M', + variationValues: { + color: 'JJG80XX', + size: '9XL' + } + }, + { + orderable: true, + price: 53.11, + productId: '701642856146M', + variationValues: { + color: 'JJG80XX', + size: '9MD' + } + }, + { + orderable: true, + price: 53.11, + productId: '701642856153M', + variationValues: { + color: 'JJG80XX', + size: '9SM' + } + } + ], + variationAttributes: [ + { + id: 'color', + name: 'Colour', + values: [ + { + name: 'Sugar', + orderable: true, + value: 'JJG80XX' + } + ] + }, + { + id: 'size', + name: 'Size', + values: [ + { + name: 'S', + orderable: true, + value: '9SM' + }, + { + name: 'M', + orderable: true, + value: '9MD' + }, + { + name: 'L', + orderable: true, + value: '9LG' + }, + { + name: 'XL', + orderable: true, + value: '9XL' + } + ] + } + ], + quantity: 1 + }, + { + currency: 'GBP', + id: '701642884934M', + imageGroups: [ + { + images: [ + { + alt: 'Classic Blouse, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw36217548/images/large/PG.10208973.JJZ01XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw36217548/images/large/PG.10208973.JJZ01XX.PZ.jpg', + title: 'Classic Blouse, ' + }, + { + alt: 'Classic Blouse, , large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw7944a3a4/images/large/PG.10208973.JJZ01XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw7944a3a4/images/large/PG.10208973.JJZ01XX.BZ.jpg', + title: 'Classic Blouse, ' + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Classic Blouse, Multi, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw36217548/images/large/PG.10208973.JJZ01XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw36217548/images/large/PG.10208973.JJZ01XX.PZ.jpg', + title: 'Classic Blouse, Multi' + }, + { + alt: 'Classic Blouse, Multi, large', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw7944a3a4/images/large/PG.10208973.JJZ01XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw7944a3a4/images/large/PG.10208973.JJZ01XX.BZ.jpg', + title: 'Classic Blouse, Multi' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJZ01XX' + } + ] + } + ], + viewType: 'large' + }, + { + images: [ + { + alt: 'Classic Blouse, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5c673dcc/images/medium/PG.10208973.JJZ01XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5c673dcc/images/medium/PG.10208973.JJZ01XX.PZ.jpg', + title: 'Classic Blouse, ' + }, + { + alt: 'Classic Blouse, , medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw6367d44a/images/medium/PG.10208973.JJZ01XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw6367d44a/images/medium/PG.10208973.JJZ01XX.BZ.jpg', + title: 'Classic Blouse, ' + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Classic Blouse, Multi, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5c673dcc/images/medium/PG.10208973.JJZ01XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw5c673dcc/images/medium/PG.10208973.JJZ01XX.PZ.jpg', + title: 'Classic Blouse, Multi' + }, + { + alt: 'Classic Blouse, Multi, medium', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw6367d44a/images/medium/PG.10208973.JJZ01XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw6367d44a/images/medium/PG.10208973.JJZ01XX.BZ.jpg', + title: 'Classic Blouse, Multi' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJZ01XX' + } + ] + } + ], + viewType: 'medium' + }, + { + images: [ + { + alt: 'Classic Blouse, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw876f6604/images/small/PG.10208973.JJZ01XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw876f6604/images/small/PG.10208973.JJZ01XX.PZ.jpg', + title: 'Classic Blouse, ' + }, + { + alt: 'Classic Blouse, , small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw95a5c5e9/images/small/PG.10208973.JJZ01XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw95a5c5e9/images/small/PG.10208973.JJZ01XX.BZ.jpg', + title: 'Classic Blouse, ' + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Classic Blouse, Multi, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw876f6604/images/small/PG.10208973.JJZ01XX.PZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw876f6604/images/small/PG.10208973.JJZ01XX.PZ.jpg', + title: 'Classic Blouse, Multi' + }, + { + alt: 'Classic Blouse, Multi, small', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dw95a5c5e9/images/small/PG.10208973.JJZ01XX.BZ.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw95a5c5e9/images/small/PG.10208973.JJZ01XX.BZ.jpg', + title: 'Classic Blouse, Multi' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJZ01XX' + } + ] + } + ], + viewType: 'small' + }, + { + images: [ + { + alt: 'Classic Blouse, Multi, swatch', + disBaseLink: + 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_009/on/demandware.static/-/Sites-apparel-m-catalog/default/dwbf88a038/images/swatch/PG.10208973.JJZ01XX.CP.jpg', + link: 'https://zzrf-009.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwbf88a038/images/swatch/PG.10208973.JJZ01XX.CP.jpg', + title: 'Classic Blouse, Multi' + } + ], + variationAttributes: [ + { + id: 'color', + values: [ + { + value: 'JJZ01XX' + } + ] + } + ], + viewType: 'swatch' + } + ], + inventory: { + ats: 100, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 100 + }, + longDescription: + 'We took our long sleeve button front classic blouse and updated it with a new colour for the season.', + master: { + masterId: '25502072M', + orderable: true, + price: 42.23 + }, + minOrderQuantity: 1, + name: 'Classic Blouse', + pageDescription: + 'We took our long sleeve button front classic blouse and updated it with a new colour for the season.', + pageTitle: 'Classic Blouse', + price: 42.23, + pricePerUnit: 42.23, + productPromotions: [ + { + calloutMsg: 'Buy one Long Center Seam Skirt and get 2 tops', + promotionId: 'ChoiceOfBonusProdect-ProductLevel-ruleBased' + } + ], + shortDescription: + 'We took our long sleeve button front classic blouse and updated it with a new colour for the season.', + slugUrl: + 'https://zzrf-009.dx.commercecloud.salesforce.com/s/RefArchGlobal/classic-blouse/701642884934M.html?lang=en_GB', + stepQuantity: 1, + type: { + variant: true + }, + unitMeasure: '', + unitQuantity: 0, + upc: '701642884934', + validFrom: { + default: '2010-11-18T05:00:00.000Z' + }, + variants: [ + { + orderable: true, + price: 42.23, + productId: '701642884910M', + variationValues: { + color: 'JJZ01XX', + size: '004' + } + }, + { + orderable: true, + price: 42.23, + productId: '701642884927M', + variationValues: { + color: 'JJZ01XX', + size: '006' + } + }, + { + orderable: true, + price: 42.23, + productId: '701642884897M', + variationValues: { + color: 'JJZ01XX', + size: '014' + } + }, + { + orderable: true, + price: 42.23, + productId: '701642884903M', + variationValues: { + color: 'JJZ01XX', + size: '016' + } + }, + { + orderable: true, + price: 42.23, + productId: '701642884934M', + variationValues: { + color: 'JJZ01XX', + size: '008' + } + }, + { + orderable: true, + price: 42.23, + productId: '701642884880M', + variationValues: { + color: 'JJZ01XX', + size: '012' + } + }, + { + orderable: true, + price: 42.23, + productId: '701642884873M', + variationValues: { + color: 'JJZ01XX', + size: '010' + } + } + ], + variationAttributes: [ + { + id: 'color', + name: 'Colour', + values: [ + { + name: 'Multi', + orderable: true, + value: 'JJZ01XX' + } + ] + }, + { + id: 'size', + name: 'Size', + values: [ + { + name: '4', + orderable: true, + value: '004' + }, + { + name: '6', + orderable: true, + value: '006' + }, + { + name: '8', + orderable: true, + value: '008' + }, + { + name: '10', + orderable: true, + value: '010' + }, + { + name: '12', + orderable: true, + value: '012' + }, + { + name: '14', + orderable: true, + value: '014' + }, + { + name: '16', + orderable: true, + value: '016' + } + ] + } + ], + variationValues: { + color: 'JJZ01XX', + size: '008' + }, + c_color: 'JJZ01XX', + c_refinementColor: 'miscellaneous', + c_size: '008', + c_width: 'Z', + quantity: 1 + } + ], + total: 4 +} diff --git a/packages/template-retail-react-app/app/pages/account/wishlist/partials/wishlist-primary-action.test.js b/packages/template-retail-react-app/app/pages/account/wishlist/partials/wishlist-primary-action.test.js index 0ceb2e920d..a082e80cd6 100644 --- a/packages/template-retail-react-app/app/pages/account/wishlist/partials/wishlist-primary-action.test.js +++ b/packages/template-retail-react-app/app/pages/account/wishlist/partials/wishlist-primary-action.test.js @@ -5,20 +5,24 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import React from 'react' -import {mockedCustomerProductListsDetails} from '../../../../commerce-api/mock-data' +import {mockWishListDetails} from './wishlist-primary-action.mock' import ItemVariantProvider from '../../../../components/item-variant' import {renderWithProviders} from '../../../../utils/test-utils' import WishlistPrimaryAction from './wishlist-primary-action' -import user from '@testing-library/user-event' +import userEvent from '@testing-library/user-event' import {screen, waitFor} from '@testing-library/react' +import PropTypes from 'prop-types' -const MockedComponent = (variant) => { +const MockedComponent = ({variant}) => { return ( ) } +MockedComponent.propTypes = { + variant: PropTypes.object +} jest.mock('../../../../commerce-api/hooks/useBasket', () => { return () => { @@ -32,19 +36,56 @@ beforeEach(() => { jest.resetModules() }) -test('renders primary action component', async () => { - const {getByRole} = renderWithProviders( - - ) +test('the Add To Cart button', async () => { + const variant = mockWishListDetails.data[3] + const {getByRole} = renderWithProviders() + const addToCartButton = getByRole('button', { name: /add to cart/i }) expect(addToCartButton).toBeInTheDocument() - user.click(addToCartButton) + userEvent.click(addToCartButton) await waitFor(() => { // Chakra UI renders multiple elements with toast title in DOM for accessibility. // We need to assert the actual text within the alert - expect(screen.getByRole('alert')).toHaveTextContent(/items added to cart/i) + expect(screen.getAllByRole('alert')[0]).toHaveTextContent(/1 item added to cart/i) + }) +}) + +test('the Add Set To Cart button', async () => { + const productSetWithoutVariants = mockWishListDetails.data[1] + renderWithProviders() + + const button = screen.getByRole('button', {name: /add set to cart/i}) + userEvent.click(button) + + await waitFor(() => { + expect(screen.getAllByRole('alert')[0]).toHaveTextContent(/2 items added to cart/i) }) }) + +test('the View Full Details button', () => { + const productSetWithVariants = mockWishListDetails.data[0] + renderWithProviders() + + const link = screen.getByRole('link', {name: /view full details/i}) + expect(link).toBeInTheDocument() +}) + +test('the View Options button', async () => { + const masterProduct = mockWishListDetails.data[2] + renderWithProviders() + + const button = screen.getByRole('button', {name: /view options/i}) + userEvent.click(button) + + await waitFor( + () => { + const modal = screen.getByTestId('product-view-modal') + expect(modal).toBeVisible() + }, + // Seems like rendering the modal takes a bit more time + {timeout: 5000} + ) +}) diff --git a/packages/template-retail-react-app/app/pages/product-detail/index.jsx b/packages/template-retail-react-app/app/pages/product-detail/index.jsx index 3645b64ea0..acf512a56c 100644 --- a/packages/template-retail-react-app/app/pages/product-detail/index.jsx +++ b/packages/template-retail-react-app/app/pages/product-detail/index.jsx @@ -151,10 +151,12 @@ const ProductDetail = ({category, product, isLoading}) => { // Get the reference to the product view and scroll to it. const {ref} = childProductRefs.current[firstUnselectedProduct.id] - ref.scrollIntoView({ - behavior: 'smooth', - block: 'end' - }) + if (ref.scrollIntoView) { + ref.scrollIntoView({ + behavior: 'smooth', + block: 'end' + }) + } return false } @@ -215,7 +217,7 @@ const ProductDetail = ({category, product, isLoading}) => { { // Product Set: render the child products product.setProducts.map((childProduct) => ( - + {
-
+ )) } diff --git a/packages/template-retail-react-app/app/pages/product-detail/index.mock.js b/packages/template-retail-react-app/app/pages/product-detail/index.mock.js new file mode 100644 index 0000000000..7434cd36b2 --- /dev/null +++ b/packages/template-retail-react-app/app/pages/product-detail/index.mock.js @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +export const basketWithProductSet = { + _v: '21.3', + _type: 'basket', + _resource_state: '9fdc9a8aeaea84a84a9dfed115ad37a0a32c86df4693cc7a9f62afc3395527c7', + _flash: [ + { + _type: 'flash', + type: 'PaymentMethodRequired', + message: + 'No payment method ID was specified. Please provide a valid payment method ID.', + path: '$.payment_instruments[0].payment_method_id' + }, + { + _type: 'flash', + type: 'BillingAddressRequired', + message: 'No billing address was specified. Please provide a valid billing address.', + path: '$.billing_address' + }, + { + _type: 'flash', + type: 'OrderTotalNotSet', + message: 'Order total missing, calculation failed.', + path: '$.order_total' + }, + { + _type: 'flash', + type: 'ShippingAddressRequired', + message: 'No shipping address was specified. Please provide a valid shipping address.', + path: '$.shipments[0].shipping_address', + details: { + shipmentId: 'me' + } + }, + { + _type: 'flash', + type: 'ShippingMethodRequired', + message: + 'No shipping method ID was specified. Please provide a valid shipping method ID.', + path: '$.shipments[0].shipping_method', + details: { + shipmentId: 'me' + } + }, + { + _type: 'flash', + type: 'ShippingItemAdjustedPriceNotSet', + message: "Price missing for shipping item ''5fb887a2999303b33676e0d3a5''.", + path: '$.shipping_items[0].adjusted_price' + } + ], + adjusted_merchandize_total_tax: 17.01, + adjusted_shipping_total_tax: null, + agent_basket: false, + basket_id: '437113007d685eab389f1cd229', + channel_type: 'storefront', + creation_date: '2023-02-22T21:47:29.585Z', + currency: 'GBP', + customer_info: { + _type: 'customer_info', + customer_id: 'abkHtKmulJkKgRmrkVwqYYkHBI', + email: '' + }, + last_modified: '2023-02-22T22:15:41.482Z', + merchandize_total_tax: 17.01, + notes: { + _type: 'simple_link', + link: 'https://zzrf-001.dx.commercecloud.salesforce.com/s/RefArchGlobal/dw/shop/v21_3/baskets/437113007d685eab389f1cd229/notes' + }, + order_total: null, + product_items: [ + { + _type: 'product_item', + adjusted_tax: 6.76, + base_price: 71.03, + bonus_product_line_item: false, + gift: false, + item_id: '5060f31486572338f05d04fc56', + item_text: 'Quilted Jacket', + price: 142.06, + price_after_item_discount: 142.06, + price_after_order_discount: 142.06, + product_id: '701642853695M', + product_name: 'Quilted Jacket', + quantity: 2, + shipment_id: 'me', + tax: 6.76, + tax_basis: 142.06, + tax_class_id: 'standard', + tax_rate: 0.05 + }, + { + _type: 'product_item', + adjusted_tax: 4.21, + base_price: 44.16, + bonus_product_line_item: false, + gift: false, + item_id: '9a8003bebeea153d112083f2bd', + item_text: 'Pull On Pant', + price: 88.32, + price_after_item_discount: 88.32, + price_after_order_discount: 88.32, + product_id: '701642867104M', + product_name: 'Pull On Pant', + quantity: 2, + shipment_id: 'me', + tax: 4.21, + tax_basis: 88.32, + tax_class_id: 'standard', + tax_rate: 0.05 + }, + { + _type: 'product_item', + adjusted_tax: 3.02, + base_price: 63.36, + bonus_product_line_item: false, + gift: false, + item_id: '1cda01244dc449d9b245577378', + item_text: 'Zerrick', + price: 63.36, + price_after_item_discount: 63.36, + price_after_order_discount: 63.36, + product_id: '740357358101M', + product_name: 'Zerrick', + quantity: 1, + shipment_id: 'me', + tax: 3.02, + tax_basis: 63.36, + tax_class_id: 'standard', + tax_rate: 0.05 + }, + { + _type: 'product_item', + adjusted_tax: 3.02, + base_price: 63.36, + bonus_product_line_item: false, + gift: false, + item_id: '1007d8db121aa4331836f8f934', + item_text: 'Zerrick', + price: 63.36, + price_after_item_discount: 63.36, + price_after_order_discount: 63.36, + product_id: '740357358095M', + product_name: 'Zerrick', + quantity: 1, + shipment_id: 'me', + tax: 3.02, + tax_basis: 63.36, + tax_class_id: 'standard', + tax_rate: 0.05 + } + ], + product_sub_total: 357.1, + product_total: 357.1, + shipments: [ + { + _type: 'shipment', + adjusted_merchandize_total_tax: 17.01, + adjusted_shipping_total_tax: null, + gift: false, + merchandize_total_tax: 17.01, + product_sub_total: 357.1, + product_total: 357.1, + shipment_id: 'me', + shipment_total: null, + shipping_status: 'not_shipped', + shipping_total: null, + shipping_total_tax: null, + tax_total: null + } + ], + shipping_items: [ + { + _type: 'shipping_item', + adjusted_tax: null, + base_price: null, + item_id: '5fb887a2999303b33676e0d3a5', + item_text: 'Shipping', + price: null, + price_after_item_discount: null, + shipment_id: 'me', + tax: null, + tax_basis: null, + tax_class_id: null, + tax_rate: 0.05 + } + ], + shipping_total: null, + shipping_total_tax: null, + taxation: 'gross', + tax_total: null +} diff --git a/packages/template-retail-react-app/app/pages/product-detail/index.test.js b/packages/template-retail-react-app/app/pages/product-detail/index.test.js index 1e8ee5ab44..5216447994 100644 --- a/packages/template-retail-react-app/app/pages/product-detail/index.test.js +++ b/packages/template-retail-react-app/app/pages/product-detail/index.test.js @@ -7,10 +7,12 @@ import React from 'react' import {rest} from 'msw' import {mockedCustomerProductLists, productsResponse} from '../../commerce-api/mock-data' -import {screen} from '@testing-library/react' +import {fireEvent, screen, waitFor, within} from '@testing-library/react' import {Route, Switch} from 'react-router-dom' import ProductDetail from '.' +import {basketWithProductSet} from './index.mock' import {renderWithProviders} from '../../utils/test-utils' +import mockedProductSet from '../../commerce-api/mocks/product-set-winter-lookM' jest.setTimeout(60000) @@ -31,15 +33,23 @@ const MockedComponent = () => { ) } -// Set up and clean up -beforeAll(() => { - // Since we're testing some navigation logic, we are using a simple Router - // around our component. We need to initialize the default route/path here. - window.history.pushState({}, 'ProductDetail', '/en-GB/product/test-product') -}) +const MockedPageWithProductSet = () => { + return ( + + } + /> + + ) +} beforeEach(() => { jest.resetModules() + + // Since we're testing some navigation logic, we are using a simple Router + // around our component. We need to initialize the default route/path here. + window.history.pushState({}, 'ProductDetail', '/en-GB/product/test-product') }) afterEach(() => { @@ -63,4 +73,71 @@ test('should render product details page', async () => { expect(screen.getAllByText(/14.99/).length).toEqual(2) expect(screen.getAllByText(/Add to Cart/).length).toEqual(2) expect(screen.getAllByText(/Add to Wishlist/).length).toEqual(2) + expect(screen.getAllByTestId('product-view').length).toEqual(1) +}) + +describe('product set', () => { + beforeEach(() => { + global.server.use( + // For adding items to basket + rest.post('*/baskets/:basketId/items', (req, res, ctx) => { + return res(ctx.json(basketWithProductSet)) + }) + ) + }) + + test('render multi-product layout', async () => { + renderWithProviders() + + await waitFor(() => { + expect(screen.getAllByTestId('product-view').length).toEqual(4) // 1 parent + 3 children + }) + }) + + test('add the set to cart successfully', async () => { + const urlPathAfterSelectingAllVariants = + '/en-GB/product/winter-lookM?25518447M=color%3DJJ5FUXX%26size%3D9MD&25518704M=color%3DJJ2XNXX%26size%3D9MD&25772717M=color%3DTAUPETX%26size%3D070%26width%3DM' + window.history.pushState({}, 'ProductDetail', urlPathAfterSelectingAllVariants) + + // Initial basket is necessary to add items to it + const initialBasket = {basketId: 'valid_id'} + renderWithProviders(, {wrapperProps: {initialBasket}}) + + const buttons = await screen.findAllByRole('button', {name: /add set to cart/i}) + fireEvent.click(buttons[0]) + + await waitFor( + () => { + const modal = screen.getByTestId('add-to-cart-modal') + expect(within(modal).getByText(/3 items added to cart/i)).toBeVisible() + }, + // Seems like rendering the modal takes a bit more time + {timeout: 5000} + ) + }) + + test('add the set to cart with error messages', async () => { + renderWithProviders() + + const buttons = await screen.findAllByRole('button', {name: /add set to cart/i}) + fireEvent.click(buttons[0]) + + await waitFor(() => { + // Show error when users have not selected all the variants yet + // 1 error for each child product + const errorMessages = screen.getAllByText(/Please select all your options above/i) + expect(errorMessages.length).toEqual(3) + }) + }) + + test("child products' images are lazy loaded", async () => { + renderWithProviders() + + const childProducts = await screen.findAllByTestId('child-product') + + childProducts.forEach((child) => { + const heroImage = within(child).getAllByRole('img')[0] + expect(heroImage.getAttribute('loading')).toEqual('lazy') + }) + }) }) diff --git a/packages/template-retail-react-app/app/pages/registration/index.test.jsx b/packages/template-retail-react-app/app/pages/registration/index.test.jsx index 404021de99..0b6d7eb82a 100644 --- a/packages/template-retail-react-app/app/pages/registration/index.test.jsx +++ b/packages/template-retail-react-app/app/pages/registration/index.test.jsx @@ -117,8 +117,11 @@ test('Allows customer to create an account', async () => { user.click(withinForm.getByText(/create account/i)) // wait for success state to appear - await waitFor(() => { - screen.logTestingPlaygroundURL() - expect(screen.getAllByText(/My Account/).length).toEqual(2) - }) + await waitFor( + () => { + expect(screen.getAllByText(/My Account/).length).toEqual(2) + }, + // Needs to wait a little bit more for the test to pass + {timeout: 5000} + ) }) diff --git a/packages/template-retail-react-app/app/partials/product-view/index.test.js b/packages/template-retail-react-app/app/partials/product-view/index.test.js index 09b5d09ca5..390b56488f 100644 --- a/packages/template-retail-react-app/app/partials/product-view/index.test.js +++ b/packages/template-retail-react-app/app/partials/product-view/index.test.js @@ -9,6 +9,7 @@ import React, {useEffect} from 'react' import PropTypes from 'prop-types' import {fireEvent, screen, waitFor} from '@testing-library/react' import mockProductDetail from '../../commerce-api/mocks/variant-750518699578M' +import mockProductSet from '../../commerce-api/mocks/product-set-winter-lookM' import ProductView from './index' import {renderWithProviders} from '../../utils/test-utils' import useCustomer from '../../commerce-api/hooks/useCustomer' @@ -16,7 +17,7 @@ import userEvent from '@testing-library/user-event' jest.mock('../../commerce-api/einstein') -const MockComponent = ({product, addToCart, addToWishlist, updateWishlist}) => { +const MockComponent = (props) => { const customer = useCustomer() useEffect(() => { if (!customer.isRegistered) { @@ -26,12 +27,7 @@ const MockComponent = ({product, addToCart, addToWishlist, updateWishlist}) => { return (
customer: {customer?.authType}
- +
) } @@ -120,3 +116,95 @@ test('Product View can update quantity', () => { userEvent.type(quantityBox, '{backspace}3') expect(quantityBox).toHaveValue('3') }) + +test('renders a product set properly - parent item', () => { + const parent = mockProductSet + renderWithProviders( + {}} addToWishlist={() => {}} /> + ) + + // NOTE: there can be duplicates of the same element, due to mobile and desktop views + // (they're hidden with display:none style) + + const startingAtLabel = screen.getAllByText(/starting at/i)[0] + const addSetToCartButton = screen.getAllByRole('button', {name: /add set to cart/i})[0] + const addSetToWishlistButton = screen.getAllByRole('button', {name: /add set to wishlist/i})[0] + const variationAttributes = screen.queryAllByRole('radiogroup') // e.g. sizes, colors + const quantityPicker = screen.queryByRole('spinbutton', {name: /quantity:/i}) + + // What should exist: + expect(startingAtLabel).toBeInTheDocument() + expect(addSetToCartButton).toBeInTheDocument() + expect(addSetToWishlistButton).toBeInTheDocument() + + // What should _not_ exist: + expect(variationAttributes.length).toEqual(0) + expect(quantityPicker).toBe(null) +}) + +test('renders a product set properly - child item', () => { + const child = mockProductSet.setProducts[0] + renderWithProviders( + {}} addToWishlist={() => {}} /> + ) + + // NOTE: there can be duplicates of the same element, due to mobile and desktop views + // (they're hidden with display:none style) + + const addToCartButton = screen.getAllByRole('button', {name: /add to cart/i})[0] + const addToWishlistButton = screen.getAllByRole('button', {name: /add to wishlist/i})[0] + const variationAttributes = screen.getAllByRole('radiogroup') // e.g. sizes, colors + const quantityPicker = screen.getByRole('spinbutton', {name: /quantity:/i}) + const startingAtLabels = screen.queryAllByText(/starting at/i) + + // What should exist: + expect(addToCartButton).toBeInTheDocument() + expect(addToWishlistButton).toBeInTheDocument() + expect(variationAttributes.length).toEqual(2) + expect(quantityPicker).toBeInTheDocument() + + // What should _not_ exist: + expect(startingAtLabels.length).toEqual(0) +}) + +test('validateOrderability callback is called when adding a set to cart', async () => { + const parent = mockProductSet + const validateOrderability = jest.fn() + + renderWithProviders( + {}} + addToWishlist={() => {}} + /> + ) + + const button = screen.getByRole('button', {name: /add set to cart/i}) + userEvent.click(button) + + await waitFor(() => { + expect(validateOrderability).toHaveBeenCalledTimes(1) + }) +}) + +test('onVariantSelected callback is called after successfully selected a variant', async () => { + const onVariantSelected = jest.fn() + const child = mockProductSet.setProducts[0] + + renderWithProviders( + {}} + addToWishlist={() => {}} + /> + ) + + const size = screen.getByRole('link', {name: /xl/i}) + userEvent.click(size) + + await waitFor(() => { + expect(onVariantSelected).toHaveBeenCalledTimes(1) + }) +}) diff --git a/packages/template-retail-react-app/app/utils/product-utils.js b/packages/template-retail-react-app/app/utils/product-utils.js index 1e9d93f988..48d9489524 100644 --- a/packages/template-retail-react-app/app/utils/product-utils.js +++ b/packages/template-retail-react-app/app/utils/product-utils.js @@ -6,9 +6,8 @@ */ /** - * Given a variation attribute array and and variation values object return an object - * where the key is the attributes display name, and the value is the attribute display - * value. + * Get the human-friendly version of the variation values that users have selected. + * Useful for displaying these values in the UI. * * @param {Object} variationAttributes - The products variation attributes. * @param {Object} values - The variations selected attribute values. @@ -16,10 +15,10 @@ * * @example * const displayValues = getDisplayVariationValues( - * [{id: 'size', name: 'Size', values: [{name: "md", value: "Medium"}]}], - * {size: 'md'} + * [ { "id": "color", "name": "Colour", "values": [ { "name": "royal", "orderable": true, "value": "JJ5FUXX" } ] } ], + * { "color": "JJ5FUXX" } * ) - * // returns {Size: "Medium"} + * // returns { "Colour": "royal" } */ export const getDisplayVariationValues = (variationAttributes, values = {}) => { const returnVal = Object.entries(values).reduce((acc, [id, value]) => { diff --git a/packages/template-retail-react-app/app/utils/product-utils.test.js b/packages/template-retail-react-app/app/utils/product-utils.test.js new file mode 100644 index 0000000000..896087e5f7 --- /dev/null +++ b/packages/template-retail-react-app/app/utils/product-utils.test.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ + +import {getDisplayVariationValues} from './product-utils' + +const variationAttributes = [ + { + id: 'color', + name: 'Colour', + values: [ + {name: 'Black', orderable: true, value: 'BLACKLE'}, + {name: 'Taupe', orderable: true, value: 'TAUPETX'} + ] + }, + { + id: 'size', + name: 'Size', + values: [ + {name: '6', orderable: true, value: '060'}, + {name: '6.5', orderable: true, value: '065'}, + {name: '7', orderable: true, value: '070'}, + {name: '7.5', orderable: true, value: '075'}, + {name: '8', orderable: true, value: '080'}, + {name: '8.5', orderable: true, value: '085'}, + {name: '9', orderable: true, value: '090'}, + {name: '9.5', orderable: true, value: '095'}, + {name: '10', orderable: true, value: '100'}, + {name: '11', orderable: true, value: '110'} + ] + }, + {id: 'width', name: 'Width', values: [{name: 'M', orderable: true, value: 'M'}]} +] + +test('getDisplayVariationValues', () => { + const selectedValues = { + color: 'TAUPETX', + size: '065', + width: 'M' + } + const result = getDisplayVariationValues(variationAttributes, selectedValues) + + expect(result).toEqual({ + Colour: 'Taupe', + Size: '6.5', + Width: 'M' + }) +}) diff --git a/packages/template-retail-react-app/app/utils/test-utils.js b/packages/template-retail-react-app/app/utils/test-utils.js index 02c8958ada..b6339c0858 100644 --- a/packages/template-retail-react-app/app/utils/test-utils.js +++ b/packages/template-retail-react-app/app/utils/test-utils.js @@ -18,7 +18,7 @@ import { CustomerProvider, CustomerProductListsProvider } from '../commerce-api/contexts' -import {AddToCartModalContext} from '../hooks/use-add-to-cart-modal' +import {AddToCartModal, AddToCartModalContext} from '../hooks/use-add-to-cart-modal' import {IntlProvider} from 'react-intl' import {mockCategories as initialMockCategories} from '../commerce-api/mock-data' import fallbackMessages from '../translations/compiled/en-GB.json' @@ -66,6 +66,30 @@ export const renderWithRouterAndCommerceAPI = (node) => { ) } +const useAddToCartModal = () => { + const [state, setState] = useState({ + isOpen: false, + data: null + }) + + return { + isOpen: state.isOpen, + data: state.data, + onOpen: (data) => { + setState({ + isOpen: true, + data + }) + }, + onClose: () => { + setState({ + isOpen: false, + data: null + }) + } + } +} + /** * This is the Providers used to wrap components * for testing purposes. @@ -112,12 +136,7 @@ export const TestProviders = ({ _setBasket(data) }) - const addToCartModal = { - isOpen: false, - data: null, - onOpen: () => {}, - onClose: () => {} - } + const addToCartModal = useAddToCartModal() const site = getSiteByReference(siteAlias || appConfig.defaultSite) @@ -142,6 +161,7 @@ export const TestProviders = ({ value={addToCartModal} > {children} +