@salesforce/retail-react-app 1.0.0-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (425) hide show
  1. package/.eslintignore +7 -0
  2. package/.eslintrc.js +25 -0
  3. package/.prettierignore +4 -0
  4. package/.prettierrc.yaml +7 -0
  5. package/CHANGELOG.md +173 -0
  6. package/LICENSE +14 -0
  7. package/README.md +48 -0
  8. package/app/assets/svg/account.svg +3 -0
  9. package/app/assets/svg/alert.svg +3 -0
  10. package/app/assets/svg/basket.svg +3 -0
  11. package/app/assets/svg/brand-logo.svg +10 -0
  12. package/app/assets/svg/cc-amex.svg +7 -0
  13. package/app/assets/svg/cc-cvv.svg +8 -0
  14. package/app/assets/svg/cc-discover.svg +14 -0
  15. package/app/assets/svg/cc-mastercard.svg +8 -0
  16. package/app/assets/svg/cc-visa.svg +11 -0
  17. package/app/assets/svg/check-circle.svg +3 -0
  18. package/app/assets/svg/check.svg +3 -0
  19. package/app/assets/svg/chevron-down.svg +3 -0
  20. package/app/assets/svg/chevron-left.svg +3 -0
  21. package/app/assets/svg/chevron-right.svg +3 -0
  22. package/app/assets/svg/chevron-up.svg +3 -0
  23. package/app/assets/svg/close.svg +3 -0
  24. package/app/assets/svg/dashboard.svg +4 -0
  25. package/app/assets/svg/figma-logo.svg +14 -0
  26. package/app/assets/svg/file.svg +3 -0
  27. package/app/assets/svg/filter.svg +3 -0
  28. package/app/assets/svg/flag-ca.svg +5 -0
  29. package/app/assets/svg/flag-cn.svg +19 -0
  30. package/app/assets/svg/flag-fr.svg +19 -0
  31. package/app/assets/svg/flag-gb.svg +16 -0
  32. package/app/assets/svg/flag-it.svg +29 -0
  33. package/app/assets/svg/flag-jp.svg +10 -0
  34. package/app/assets/svg/flag-us.svg +7 -0
  35. package/app/assets/svg/github-logo.svg +40 -0
  36. package/app/assets/svg/hamburger.svg +8 -0
  37. package/app/assets/svg/heart-solid.svg +7 -0
  38. package/app/assets/svg/heart.svg +3 -0
  39. package/app/assets/svg/info.svg +3 -0
  40. package/app/assets/svg/like.svg +4 -0
  41. package/app/assets/svg/location.svg +3 -0
  42. package/app/assets/svg/lock.svg +3 -0
  43. package/app/assets/svg/paypal.svg +19 -0
  44. package/app/assets/svg/plug.svg +3 -0
  45. package/app/assets/svg/plus.svg +3 -0
  46. package/app/assets/svg/receipt.svg +3 -0
  47. package/app/assets/svg/search.svg +8 -0
  48. package/app/assets/svg/signout.svg +3 -0
  49. package/app/assets/svg/social-facebook.svg +3 -0
  50. package/app/assets/svg/social-instagram.svg +3 -0
  51. package/app/assets/svg/social-pinterest.svg +4 -0
  52. package/app/assets/svg/social-twitter.svg +3 -0
  53. package/app/assets/svg/social-youtube.svg +3 -0
  54. package/app/assets/svg/user.svg +3 -0
  55. package/app/assets/svg/visibility-off.svg +5 -0
  56. package/app/assets/svg/visibility.svg +3 -0
  57. package/app/components/_app/index.jsx +401 -0
  58. package/app/components/_app/index.test.js +85 -0
  59. package/app/components/_app/partials/above-header.jsx +10 -0
  60. package/app/components/_app-config/index.jsx +125 -0
  61. package/app/components/_app-config/index.test.js +77 -0
  62. package/app/components/_error/index.jsx +142 -0
  63. package/app/components/_error/index.test.js +25 -0
  64. package/app/components/action-card/index.jsx +75 -0
  65. package/app/components/address-display/index.jsx +30 -0
  66. package/app/components/basic-tile/index.jsx +65 -0
  67. package/app/components/basic-tile/index.test.js +23 -0
  68. package/app/components/breadcrumb/index.jsx +67 -0
  69. package/app/components/breadcrumb/index.test.js +30 -0
  70. package/app/components/confirmation-modal/index.jsx +111 -0
  71. package/app/components/confirmation-modal/index.test.js +98 -0
  72. package/app/components/drawer-menu/index.jsx +405 -0
  73. package/app/components/drawer-menu/index.test.js +33 -0
  74. package/app/components/dynamic-image/index.jsx +56 -0
  75. package/app/components/field/index.jsx +161 -0
  76. package/app/components/footer/index.jsx +269 -0
  77. package/app/components/footer/index.test.js +22 -0
  78. package/app/components/forms/address-fields.jsx +49 -0
  79. package/app/components/forms/credit-card-fields.jsx +149 -0
  80. package/app/components/forms/form-action-buttons.jsx +55 -0
  81. package/app/components/forms/login-fields.jsx +31 -0
  82. package/app/components/forms/password-requirements.jsx +99 -0
  83. package/app/components/forms/post-checkout-registration-fields.jsx +43 -0
  84. package/app/components/forms/profile-fields.jsx +36 -0
  85. package/app/components/forms/promo-code-fields.jsx +43 -0
  86. package/app/components/forms/registration-fields.jsx +42 -0
  87. package/app/components/forms/reset-password-fields.jsx +31 -0
  88. package/app/components/forms/state-province-options.jsx +75 -0
  89. package/app/components/forms/update-password-fields.jsx +49 -0
  90. package/app/components/forms/useAddressFields.jsx +196 -0
  91. package/app/components/forms/useCreditCardFields.jsx +146 -0
  92. package/app/components/forms/useLoginFields.jsx +52 -0
  93. package/app/components/forms/useProfileFields.jsx +95 -0
  94. package/app/components/forms/usePromoCodeFields.jsx +39 -0
  95. package/app/components/forms/useRegistrationFields.jsx +136 -0
  96. package/app/components/forms/useResetPasswordFields.jsx +40 -0
  97. package/app/components/forms/useUpdatePasswordFields.jsx +89 -0
  98. package/app/components/header/index.jsx +290 -0
  99. package/app/components/header/index.test.js +217 -0
  100. package/app/components/hero/index.jsx +84 -0
  101. package/app/components/hero/index.test.js +40 -0
  102. package/app/components/icons/index.jsx +158 -0
  103. package/app/components/icons/index.test.js +20 -0
  104. package/app/components/image-gallery/index.jsx +176 -0
  105. package/app/components/image-gallery/index.test.js +485 -0
  106. package/app/components/item-variant/index.jsx +33 -0
  107. package/app/components/item-variant/item-attributes.jsx +107 -0
  108. package/app/components/item-variant/item-image.jsx +73 -0
  109. package/app/components/item-variant/item-name.jsx +28 -0
  110. package/app/components/item-variant/item-price.jsx +117 -0
  111. package/app/components/link/index.jsx +32 -0
  112. package/app/components/link/index.test.js +72 -0
  113. package/app/components/links-list/index.jsx +89 -0
  114. package/app/components/links-list/index.test.js +62 -0
  115. package/app/components/list-menu/index.jsx +280 -0
  116. package/app/components/list-menu/index.test.js +44 -0
  117. package/app/components/loading-spinner/index.jsx +46 -0
  118. package/app/components/locale-selector/index.jsx +124 -0
  119. package/app/components/locale-selector/index.test.js +37 -0
  120. package/app/components/locale-text/index.jsx +97 -0
  121. package/app/components/locale-text/index.test.js +36 -0
  122. package/app/components/login/index.jsx +96 -0
  123. package/app/components/nested-accordion/index.jsx +185 -0
  124. package/app/components/nested-accordion/index.test.js +98 -0
  125. package/app/components/offline-banner/index.jsx +40 -0
  126. package/app/components/offline-banner/index.test.js +15 -0
  127. package/app/components/offline-boundary/index.jsx +104 -0
  128. package/app/components/offline-boundary/index.test.js +123 -0
  129. package/app/components/order-summary/index.jsx +331 -0
  130. package/app/components/page-action-placeholder/index.jsx +50 -0
  131. package/app/components/pagination/index.jsx +134 -0
  132. package/app/components/pagination/index.test.js +25 -0
  133. package/app/components/product-item/index.jsx +146 -0
  134. package/app/components/product-item/index.test.js +38 -0
  135. package/app/components/product-scroller/index.jsx +172 -0
  136. package/app/components/product-scroller/index.test.js +98 -0
  137. package/app/components/product-tile/index.jsx +195 -0
  138. package/app/components/product-tile/index.test.js +96 -0
  139. package/app/components/product-view/index.jsx +538 -0
  140. package/app/components/product-view/index.test.js +224 -0
  141. package/app/components/product-view-modal/index.jsx +48 -0
  142. package/app/components/product-view-modal/index.test.js +72 -0
  143. package/app/components/promo-code/index.jsx +162 -0
  144. package/app/components/promo-popover/index.jsx +83 -0
  145. package/app/components/quantity-picker/index.jsx +58 -0
  146. package/app/components/radio-card/index.jsx +75 -0
  147. package/app/components/recommended-products/index.jsx +227 -0
  148. package/app/components/register/index.jsx +114 -0
  149. package/app/components/reset-password/index.jsx +87 -0
  150. package/app/components/responsive/index.jsx +29 -0
  151. package/app/components/scroll-to-top/index.jsx +24 -0
  152. package/app/components/scroll-to-top/index.test.js +46 -0
  153. package/app/components/search/index.jsx +279 -0
  154. package/app/components/search/index.test.js +127 -0
  155. package/app/components/search/partials/recent-searches.jsx +76 -0
  156. package/app/components/search/partials/search-suggestions.jsx +45 -0
  157. package/app/components/search/partials/suggestions.jsx +43 -0
  158. package/app/components/section/index.jsx +68 -0
  159. package/app/components/seo/index.jsx +33 -0
  160. package/app/components/social-icons/index.jsx +101 -0
  161. package/app/components/social-icons/index.test.js +30 -0
  162. package/app/components/swatch-group/index.jsx +77 -0
  163. package/app/components/swatch-group/index.test.js +136 -0
  164. package/app/components/swatch-group/swatch.jsx +94 -0
  165. package/app/components/toggle-card/index.jsx +97 -0
  166. package/app/components/with-registration/index.jsx +58 -0
  167. package/app/components/with-registration/index.test.js +85 -0
  168. package/app/constants.js +109 -0
  169. package/app/contexts/index.js +92 -0
  170. package/app/hooks/einstein-mock-data.js +916 -0
  171. package/app/hooks/index.js +17 -0
  172. package/app/hooks/use-add-to-cart-modal.js +344 -0
  173. package/app/hooks/use-add-to-cart-modal.test.js +625 -0
  174. package/app/hooks/use-auth-modal.js +337 -0
  175. package/app/hooks/use-auth-modal.test.js +365 -0
  176. package/app/hooks/use-currency.js +20 -0
  177. package/app/hooks/use-currency.test.js +41 -0
  178. package/app/hooks/use-current-basket.js +39 -0
  179. package/app/hooks/use-current-customer.js +29 -0
  180. package/app/hooks/use-derived-product.js +77 -0
  181. package/app/hooks/use-derived-product.test.js +69 -0
  182. package/app/hooks/use-einstein.js +512 -0
  183. package/app/hooks/use-einstein.test.js +224 -0
  184. package/app/hooks/use-intersection-observer.js +64 -0
  185. package/app/hooks/use-limit-urls.js +31 -0
  186. package/app/hooks/use-limit-urls.test.js +40 -0
  187. package/app/hooks/use-multi-site.js +36 -0
  188. package/app/hooks/use-multi-site.test.js +53 -0
  189. package/app/hooks/use-navigation.js +37 -0
  190. package/app/hooks/use-navigation.test.js +109 -0
  191. package/app/hooks/use-page-urls.js +35 -0
  192. package/app/hooks/use-page-urls.test.js +39 -0
  193. package/app/hooks/use-pdp-search-params.js +16 -0
  194. package/app/hooks/use-pdp-search-params.test.js +52 -0
  195. package/app/hooks/use-previous.js +17 -0
  196. package/app/hooks/use-product-view-modal.js +93 -0
  197. package/app/hooks/use-product-view-modal.test.js +172 -0
  198. package/app/hooks/use-search-params.js +96 -0
  199. package/app/hooks/use-search-params.test.js +91 -0
  200. package/app/hooks/use-sort-urls.js +33 -0
  201. package/app/hooks/use-sort-urls.test.js +42 -0
  202. package/app/hooks/use-toast.js +68 -0
  203. package/app/hooks/use-toast.test.js +58 -0
  204. package/app/hooks/use-variant.js +32 -0
  205. package/app/hooks/use-variant.test.js +81 -0
  206. package/app/hooks/use-variation-attributes.js +138 -0
  207. package/app/hooks/use-variation-attributes.test.js +119 -0
  208. package/app/hooks/use-variation-params.js +31 -0
  209. package/app/hooks/use-variation-params.test.js +73 -0
  210. package/app/hooks/use-wish-list.js +42 -0
  211. package/app/main.jsx +14 -0
  212. package/app/mocks/basket-with-suit.js +146 -0
  213. package/app/mocks/empty-basket.js +39 -0
  214. package/app/mocks/mock-data.js +5632 -0
  215. package/app/mocks/product-set-winter-lookM.js +1224 -0
  216. package/app/mocks/searchResults.js +144 -0
  217. package/app/mocks/variant-750518699578M.js +434 -0
  218. package/app/page-designer/README.md +102 -0
  219. package/app/page-designer/assets/image-tile/index.jsx +51 -0
  220. package/app/page-designer/assets/image-tile/index.test.js +30 -0
  221. package/app/page-designer/assets/image-with-text/index.jsx +140 -0
  222. package/app/page-designer/assets/image-with-text/index.test.js +38 -0
  223. package/app/page-designer/assets/index.js +9 -0
  224. package/app/page-designer/index.js +10 -0
  225. package/app/page-designer/layouts/carousel/index.jsx +222 -0
  226. package/app/page-designer/layouts/carousel/index.test.js +43 -0
  227. package/app/page-designer/layouts/index.js +14 -0
  228. package/app/page-designer/layouts/mobileGrid1r1c/index.jsx +36 -0
  229. package/app/page-designer/layouts/mobileGrid1r1c/index.test.js +35 -0
  230. package/app/page-designer/layouts/mobileGrid2r1c/index.jsx +37 -0
  231. package/app/page-designer/layouts/mobileGrid2r1c/index.test.js +47 -0
  232. package/app/page-designer/layouts/mobileGrid2r2c/index.jsx +37 -0
  233. package/app/page-designer/layouts/mobileGrid2r2c/index.test.js +71 -0
  234. package/app/page-designer/layouts/mobileGrid2r3c/index.jsx +37 -0
  235. package/app/page-designer/layouts/mobileGrid2r3c/index.test.js +95 -0
  236. package/app/page-designer/layouts/mobileGrid3r1c/index.jsx +37 -0
  237. package/app/page-designer/layouts/mobileGrid3r1c/index.test.js +59 -0
  238. package/app/page-designer/layouts/mobileGrid3r2c/index.jsx +37 -0
  239. package/app/page-designer/layouts/mobileGrid3r2c/index.test.js +95 -0
  240. package/app/page-designer/utils.js +14 -0
  241. package/app/pages/account/addresses.jsx +382 -0
  242. package/app/pages/account/addresses.test.js +120 -0
  243. package/app/pages/account/constant.js +57 -0
  244. package/app/pages/account/index.jsx +237 -0
  245. package/app/pages/account/index.test.js +188 -0
  246. package/app/pages/account/order-detail.jsx +397 -0
  247. package/app/pages/account/order-history.jsx +264 -0
  248. package/app/pages/account/orders.jsx +30 -0
  249. package/app/pages/account/orders.test.js +95 -0
  250. package/app/pages/account/profile.jsx +357 -0
  251. package/app/pages/account/wishlist/index.jsx +195 -0
  252. package/app/pages/account/wishlist/index.mock.js +1481 -0
  253. package/app/pages/account/wishlist/index.test.js +56 -0
  254. package/app/pages/account/wishlist/partials/wishlist-primary-action.jsx +170 -0
  255. package/app/pages/account/wishlist/partials/wishlist-primary-action.mock.js +1623 -0
  256. package/app/pages/account/wishlist/partials/wishlist-primary-action.test.js +99 -0
  257. package/app/pages/account/wishlist/partials/wishlist-secondary-button-group.jsx +120 -0
  258. package/app/pages/account/wishlist/partials/wishlist-secondary-button-group.test.js +391 -0
  259. package/app/pages/cart/index.jsx +476 -0
  260. package/app/pages/cart/index.test.js +481 -0
  261. package/app/pages/cart/partials/cart-cta.jsx +46 -0
  262. package/app/pages/cart/partials/cart-secondary-button-group.jsx +135 -0
  263. package/app/pages/cart/partials/cart-secondary-button-group.test.js +103 -0
  264. package/app/pages/cart/partials/cart-skeleton.jsx +93 -0
  265. package/app/pages/cart/partials/cart-title.jsx +27 -0
  266. package/app/pages/cart/partials/empty-cart.jsx +86 -0
  267. package/app/pages/checkout/confirmation.jsx +541 -0
  268. package/app/pages/checkout/confirmation.mock.js +450 -0
  269. package/app/pages/checkout/confirmation.test.js +114 -0
  270. package/app/pages/checkout/index.jsx +169 -0
  271. package/app/pages/checkout/index.test.js +582 -0
  272. package/app/pages/checkout/partials/cc-radio-group.jsx +122 -0
  273. package/app/pages/checkout/partials/checkout-footer.jsx +140 -0
  274. package/app/pages/checkout/partials/checkout-footer.test.js +16 -0
  275. package/app/pages/checkout/partials/checkout-header.jsx +54 -0
  276. package/app/pages/checkout/partials/checkout-header.test.js +16 -0
  277. package/app/pages/checkout/partials/checkout-skeleton.jsx +52 -0
  278. package/app/pages/checkout/partials/contact-info.jsx +251 -0
  279. package/app/pages/checkout/partials/contact-info.test.js +43 -0
  280. package/app/pages/checkout/partials/payment-form.jsx +97 -0
  281. package/app/pages/checkout/partials/payment.jsx +276 -0
  282. package/app/pages/checkout/partials/shipping-address-selection.jsx +377 -0
  283. package/app/pages/checkout/partials/shipping-address.jsx +132 -0
  284. package/app/pages/checkout/partials/shipping-options.jsx +232 -0
  285. package/app/pages/checkout/util/checkout-context.js +94 -0
  286. package/app/pages/home/data.js +134 -0
  287. package/app/pages/home/index.jsx +301 -0
  288. package/app/pages/home/index.test.js +23 -0
  289. package/app/pages/login/index.jsx +123 -0
  290. package/app/pages/login/index.test.js +229 -0
  291. package/app/pages/login-redirect/index.jsx +23 -0
  292. package/app/pages/login-redirect/index.test.js +16 -0
  293. package/app/pages/page-not-found/index.jsx +90 -0
  294. package/app/pages/page-not-found/index.test.js +31 -0
  295. package/app/pages/product-detail/index.jsx +394 -0
  296. package/app/pages/product-detail/index.mock.js +197 -0
  297. package/app/pages/product-detail/index.test.js +162 -0
  298. package/app/pages/product-detail/partials/information-accordion.jsx +121 -0
  299. package/app/pages/product-list/index.jsx +735 -0
  300. package/app/pages/product-list/index.test.js +180 -0
  301. package/app/pages/product-list/partials/above-page-header.jsx +10 -0
  302. package/app/pages/product-list/partials/checkbox-refinements.jsx +41 -0
  303. package/app/pages/product-list/partials/checkbox-refinements.test.js +53 -0
  304. package/app/pages/product-list/partials/color-refinements.jsx +88 -0
  305. package/app/pages/product-list/partials/empty-results.jsx +118 -0
  306. package/app/pages/product-list/partials/link-refinements.jsx +38 -0
  307. package/app/pages/product-list/partials/page-header.jsx +42 -0
  308. package/app/pages/product-list/partials/radio-refinements.jsx +60 -0
  309. package/app/pages/product-list/partials/refinements.jsx +144 -0
  310. package/app/pages/product-list/partials/selected-refinements.jsx +100 -0
  311. package/app/pages/product-list/partials/size-refinements.jsx +55 -0
  312. package/app/pages/registration/index.jsx +87 -0
  313. package/app/pages/registration/index.test.jsx +132 -0
  314. package/app/pages/reset-password/index.jsx +112 -0
  315. package/app/pages/reset-password/index.test.jsx +141 -0
  316. package/app/request-processor.js +118 -0
  317. package/app/request-processor.test.js +23 -0
  318. package/app/routes.jsx +111 -0
  319. package/app/routes.test.js +13 -0
  320. package/app/ssr.js +70 -0
  321. package/app/static/ico/favicon.ico +0 -0
  322. package/app/static/img/global/app-icon-192.png +0 -0
  323. package/app/static/img/global/app-icon-512.png +0 -0
  324. package/app/static/img/global/apple-touch-icon.png +0 -0
  325. package/app/static/img/hero.png +0 -0
  326. package/app/static/manifest.json +19 -0
  327. package/app/static/robots.txt +2 -0
  328. package/app/theme/components/base/accordion.js +21 -0
  329. package/app/theme/components/base/alert.js +17 -0
  330. package/app/theme/components/base/badge.js +25 -0
  331. package/app/theme/components/base/button.js +77 -0
  332. package/app/theme/components/base/checkbox.js +30 -0
  333. package/app/theme/components/base/container.js +17 -0
  334. package/app/theme/components/base/drawer.js +26 -0
  335. package/app/theme/components/base/formLabel.js +13 -0
  336. package/app/theme/components/base/icon.js +13 -0
  337. package/app/theme/components/base/input.js +44 -0
  338. package/app/theme/components/base/modal.js +11 -0
  339. package/app/theme/components/base/popover.js +61 -0
  340. package/app/theme/components/base/radio.js +33 -0
  341. package/app/theme/components/base/select.js +15 -0
  342. package/app/theme/components/base/skeleton.js +12 -0
  343. package/app/theme/components/base/tooltip.js +19 -0
  344. package/app/theme/components/project/_app.js +25 -0
  345. package/app/theme/components/project/breadcrumb.js +25 -0
  346. package/app/theme/components/project/checkout-footer.js +35 -0
  347. package/app/theme/components/project/drawer-menu.js +66 -0
  348. package/app/theme/components/project/footer.js +84 -0
  349. package/app/theme/components/project/header.js +84 -0
  350. package/app/theme/components/project/image-gallery.js +59 -0
  351. package/app/theme/components/project/links-list.js +43 -0
  352. package/app/theme/components/project/list-menu.js +91 -0
  353. package/app/theme/components/project/locale-selector.js +42 -0
  354. package/app/theme/components/project/nested-accordion.js +26 -0
  355. package/app/theme/components/project/offline-banner.js +25 -0
  356. package/app/theme/components/project/pagination.js +22 -0
  357. package/app/theme/components/project/product-tile.js +32 -0
  358. package/app/theme/components/project/social-icons.js +52 -0
  359. package/app/theme/components/project/swatch-group.js +115 -0
  360. package/app/theme/foundations/colors.js +170 -0
  361. package/app/theme/foundations/gradients.js +9 -0
  362. package/app/theme/foundations/layerStyles.js +41 -0
  363. package/app/theme/foundations/shadows.js +9 -0
  364. package/app/theme/foundations/sizes.js +18 -0
  365. package/app/theme/foundations/space.js +9 -0
  366. package/app/theme/foundations/styles.js +21 -0
  367. package/app/theme/index.js +104 -0
  368. package/app/utils/cc-utils.js +112 -0
  369. package/app/utils/cc-utils.test.js +41 -0
  370. package/app/utils/image-groups-utils.js +62 -0
  371. package/app/utils/image-groups-utils.test.js +65 -0
  372. package/app/utils/locale.js +78 -0
  373. package/app/utils/locale.test.js +112 -0
  374. package/app/utils/password-utils.js +21 -0
  375. package/app/utils/phone-utils.js +22 -0
  376. package/app/utils/phone-utils.test.js +15 -0
  377. package/app/utils/product-utils.js +35 -0
  378. package/app/utils/product-utils.test.js +51 -0
  379. package/app/utils/responsive-image.js +198 -0
  380. package/app/utils/responsive-image.test.js +170 -0
  381. package/app/utils/routes-utils.js +111 -0
  382. package/app/utils/routes-utils.test.js +291 -0
  383. package/app/utils/site-utils.js +222 -0
  384. package/app/utils/site-utils.test.js +376 -0
  385. package/app/utils/test-utils.js +257 -0
  386. package/app/utils/url.js +291 -0
  387. package/app/utils/url.test.js +421 -0
  388. package/app/utils/utils.js +201 -0
  389. package/app/utils/utils.test.js +182 -0
  390. package/babel.config.js +7 -0
  391. package/cache-hash-config.json +8 -0
  392. package/config/default.js +64 -0
  393. package/config/mocks/default.js +131 -0
  394. package/config/sites.js +78 -0
  395. package/jest-setup.js +191 -0
  396. package/jest.config.js +50 -0
  397. package/jsconfig.json +13 -0
  398. package/package.json +105 -0
  399. package/scripts/extract-default-messages.js +92 -0
  400. package/tests/lighthouserc.js +37 -0
  401. package/translations/README.md +127 -0
  402. package/translations/compiled/de-DE.json +3212 -0
  403. package/translations/compiled/en-GB.json +3212 -0
  404. package/translations/compiled/en-US.json +3212 -0
  405. package/translations/compiled/en-XA.json +6948 -0
  406. package/translations/compiled/es-MX.json +3216 -0
  407. package/translations/compiled/fr-FR.json +3216 -0
  408. package/translations/compiled/it-IT.json +3188 -0
  409. package/translations/compiled/ja-JP.json +3200 -0
  410. package/translations/compiled/ko-KR.json +3180 -0
  411. package/translations/compiled/pt-BR.json +3220 -0
  412. package/translations/compiled/zh-CN.json +3212 -0
  413. package/translations/compiled/zh-TW.json +3208 -0
  414. package/translations/de-DE.json +1417 -0
  415. package/translations/en-GB.json +1417 -0
  416. package/translations/en-US.json +1417 -0
  417. package/translations/es-MX.json +1417 -0
  418. package/translations/fr-FR.json +1417 -0
  419. package/translations/it-IT.json +1417 -0
  420. package/translations/ja-JP.json +1417 -0
  421. package/translations/ko-KR.json +1417 -0
  422. package/translations/pt-BR.json +1417 -0
  423. package/translations/zh-CN.json +1417 -0
  424. package/translations/zh-TW.json +1417 -0
  425. package/worker/main.js +36 -0
@@ -0,0 +1,101 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+
8
+ import React from 'react'
9
+ import PropTypes from 'prop-types'
10
+
11
+ // Components
12
+ import {
13
+ Flex,
14
+ IconButton,
15
+
16
+ // Hooks
17
+ useMultiStyleConfig
18
+ } from '@chakra-ui/react'
19
+
20
+ // Icons
21
+ import {
22
+ SocialFacebookIcon,
23
+ SocialInstagramIcon,
24
+ SocialPinterestIcon,
25
+ SocialTwitterIcon,
26
+ SocialYoutubeIcon
27
+ } from '@salesforce/retail-react-app/app/components/icons'
28
+
29
+ /**
30
+ *
31
+ */
32
+ const SocialIcons = ({variant, pinterestInnerColor = 'white', ...otherProps}) => {
33
+ const styles = useMultiStyleConfig('SocialIcons', {variant})
34
+
35
+ return (
36
+ <Flex
37
+ className="sf-social-icons"
38
+ {...styles.container}
39
+ sx={{'--pinterest-icon-inner': pinterestInnerColor}}
40
+ {...otherProps}
41
+ >
42
+ {/* Social Links */}
43
+ {[
44
+ {
45
+ href: 'https://www.youtube.com/channel/UCSTGHqzR1Q9yAVbiS3dAFHg',
46
+ icon: SocialYoutubeIcon,
47
+ ariaLabel: 'YouTube'
48
+ },
49
+ {
50
+ href: 'https://www.instagram.com/commercecloud/?hl=en',
51
+ icon: SocialInstagramIcon,
52
+ ariaLabel: 'Instagram'
53
+ },
54
+ {
55
+ href: '/',
56
+ icon: SocialPinterestIcon,
57
+ ariaLabel: 'Pinterest'
58
+ },
59
+ {
60
+ href: 'https://twitter.com/CommerceCloud',
61
+ icon: SocialTwitterIcon,
62
+ ariaLabel: 'Twitter'
63
+ },
64
+ {
65
+ href: 'https://www.facebook.com/CommerceCloud/',
66
+ icon: SocialFacebookIcon,
67
+ ariaLabel: 'Facebook'
68
+ }
69
+ ].map(({href, icon, ariaLabel}) => (
70
+ <IconButton
71
+ {...styles.item}
72
+ key={href}
73
+ icon={React.createElement(icon, styles.icon)}
74
+ variant="unstyled"
75
+ onClick={() => {
76
+ window.open(href)
77
+ }}
78
+ aria-label={ariaLabel}
79
+ />
80
+ ))}
81
+ </Flex>
82
+ )
83
+ }
84
+
85
+ SocialIcons.displayName = 'SocialIcons'
86
+
87
+ SocialIcons.propTypes = {
88
+ /**
89
+ * This component has 3 variants, 'flex', 'flex-start' and 'flex-end'.
90
+ * All will affect how the child icons are displayed. By default, it's
91
+ * value is `flex`.
92
+ */
93
+ variant: PropTypes.string,
94
+
95
+ /**
96
+ * The inverse color of Pinterest icon's `currentColor`. For example, if the pinterest icon is white, then its inner 'p' is black.
97
+ */
98
+ pinterestInnerColor: PropTypes.string
99
+ }
100
+
101
+ export default SocialIcons
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import React from 'react'
8
+ import SocialIcons from '@salesforce/retail-react-app/app/components/social-icons/index'
9
+ import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
10
+ import {fireEvent} from '@testing-library/react'
11
+
12
+ describe('Social Icons Component', () => {
13
+ test('Renders SocialIcons', () => {
14
+ renderWithProviders(<SocialIcons />)
15
+
16
+ const links = document.querySelectorAll('button')
17
+
18
+ expect(links.length).toBeGreaterThan(0)
19
+ })
20
+
21
+ test('should open a new windown when an icon is clicked', () => {
22
+ window.open = jest.fn()
23
+ renderWithProviders(<SocialIcons />)
24
+
25
+ const links = document.querySelectorAll('button')
26
+ // click the first link
27
+ fireEvent.click(links[0])
28
+ expect(global.open).toHaveBeenCalled()
29
+ })
30
+ })
@@ -0,0 +1,77 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+
8
+ import React from 'react'
9
+ import PropTypes from 'prop-types'
10
+ import {Flex, Box, HStack, useStyleConfig} from '@chakra-ui/react'
11
+ import {noop} from '@salesforce/retail-react-app/app/utils/utils'
12
+
13
+ /**
14
+ * SwatchGroup allows you to create a list of swatches
15
+ * Each Swatch is a link with will direct to a href passed to them
16
+ */
17
+ const SwatchGroup = (props) => {
18
+ const {
19
+ displayName,
20
+ children,
21
+ value: selectedValue,
22
+ label = '',
23
+ variant = 'square',
24
+ onChange = noop
25
+ } = props
26
+ const styles = useStyleConfig('SwatchGroup')
27
+ return (
28
+ <Flex {...styles.swatchGroup} role="radiogroup">
29
+ <HStack {...styles.swatchLabel}>
30
+ <Box fontWeight="semibold">{`${label}:`}</Box>
31
+ <Box>{displayName}</Box>
32
+ </HStack>
33
+ <Flex {...styles.swatchesWrapper}>
34
+ {React.Children.map(children, (child) => {
35
+ const childValue = child.props.value
36
+
37
+ return React.cloneElement(child, {
38
+ selected: childValue === selectedValue,
39
+ variant,
40
+ onChange
41
+ })
42
+ })}
43
+ </Flex>
44
+ </Flex>
45
+ )
46
+ }
47
+
48
+ SwatchGroup.displayName = 'SwatchGroup'
49
+
50
+ SwatchGroup.propTypes = {
51
+ /**
52
+ * The attribute name of the swatch group. E.g color, size
53
+ */
54
+ label: PropTypes.string,
55
+ /**
56
+ * The selected Swatch value.
57
+ */
58
+ value: PropTypes.string,
59
+ /**
60
+ * The display value of the selected option
61
+ */
62
+ displayName: PropTypes.string,
63
+ /**
64
+ * The Swatch options to choose between
65
+ */
66
+ children: PropTypes.array,
67
+ /**
68
+ * The shape of the swatches
69
+ */
70
+ variant: PropTypes.oneOf(['square', 'circle']),
71
+ /**
72
+ * This function is called when a new option is selected
73
+ */
74
+ onChange: PropTypes.func
75
+ }
76
+
77
+ export default SwatchGroup
@@ -0,0 +1,136 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import React from 'react'
8
+ import {screen, render, fireEvent, waitFor} from '@testing-library/react'
9
+ import {Router, useHistory, useLocation} from 'react-router-dom'
10
+ import SwatchGroup from '@salesforce/retail-react-app/app/components/swatch-group/index'
11
+ import {Box} from '@chakra-ui/react'
12
+ import Swatch from '@salesforce/retail-react-app/app/components/swatch-group/swatch'
13
+ import {createMemoryHistory} from 'history'
14
+
15
+ const data = {
16
+ id: 'color',
17
+ name: 'Color',
18
+ values: [
19
+ {
20
+ name: 'Black',
21
+ orderable: false,
22
+ value: 'BLACKFB',
23
+ href: '/en-GB/swatch-example?color=BLACKFB',
24
+ image: {
25
+ alt: 'Navy Single Pleat Wool Suit, Navy, swatch',
26
+ disBaseLink:
27
+ 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dwad8e7f28/images/swatch/PG.52002RUBN4Q.NAVYWL.CP.jpg',
28
+ link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dwad8e7f28/images/swatch/PG.52002RUBN4Q.NAVYWL.CP.jpg',
29
+ title: 'Navy Single Pleat Wool Suit, Navy'
30
+ }
31
+ },
32
+ {
33
+ name: 'Grey Heather',
34
+ orderable: true,
35
+ value: 'JJ2XNXX',
36
+ href: '/en-GB/swatch-example?color=JJ2XNXX',
37
+ image: {
38
+ alt: 'Long Sleeve Crew Neck, Grey Heather, swatch',
39
+ disBaseLink:
40
+ 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw3238595c/images/swatch/PG.10219685.JJ2XNXX.CP.jpg',
41
+ link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw3238595c/images/swatch/PG.10219685.JJ2XNXX.CP.jpg',
42
+ title: 'Long Sleeve Crew Neck, Grey Heather'
43
+ }
44
+ },
45
+ {
46
+ name: 'Meadow Violet',
47
+ orderable: true,
48
+ value: 'JJ3HDXX',
49
+ href: '/en-GB/swatch-example?color=JJ3HDXX',
50
+ image: {
51
+ alt: 'Long Sleeve Crew Neck, Meadow Violet, swatch',
52
+ disBaseLink:
53
+ 'https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/ZZRF_001/on/demandware.static/-/Sites-apparel-m-catalog/default/dw7b40c85a/images/swatch/PG.10219685.JJ3HDXX.CP.jpg',
54
+ link: 'https://zzrf-001.dx.commercecloud.salesforce.com/on/demandware.static/-/Sites-apparel-m-catalog/default/dw7b40c85a/images/swatch/PG.10219685.JJ3HDXX.CP.jpg',
55
+ title: 'Long Sleeve Crew Neck, Meadow Violet'
56
+ }
57
+ }
58
+ ]
59
+ }
60
+
61
+ const Page = () => {
62
+ const location = useLocation()
63
+ const history = useHistory()
64
+ const params = new URLSearchParams(location.search)
65
+ const selectedColor = data.values.find(({value}) => {
66
+ return value === params.get('color')
67
+ })
68
+
69
+ return (
70
+ <SwatchGroup
71
+ variant="circle"
72
+ key={data.id}
73
+ value={params.get('color')}
74
+ displayName={(selectedColor && selectedColor.name) || ''}
75
+ label={data.name}
76
+ name={data.name}
77
+ onChange={(_, href) => {
78
+ if (!href) return
79
+ history.replace(href)
80
+ }}
81
+ >
82
+ {data.values.map(({value, name, image, orderable, href}) => {
83
+ return (
84
+ <Swatch
85
+ href={href}
86
+ key={value}
87
+ image={image}
88
+ disabled={!orderable}
89
+ value={value}
90
+ name={name}
91
+ >
92
+ <Box
93
+ h="100%"
94
+ w="100%"
95
+ minW="32px"
96
+ bgImage={image ? `url(${image.disBaseLink})` : ''}
97
+ />
98
+ <div>{value}</div>
99
+ </Swatch>
100
+ )
101
+ })}
102
+ </SwatchGroup>
103
+ )
104
+ }
105
+
106
+ describe('Swatch Component', () => {
107
+ test('renders component', () => {
108
+ const history = createMemoryHistory()
109
+ history.push('/en-GB/swatch-example?color=JJ2XNXX')
110
+
111
+ render(
112
+ <Router history={history}>
113
+ <Page />
114
+ </Router>
115
+ )
116
+ expect(screen.getAllByRole('radio')).toHaveLength(data.values.length)
117
+ })
118
+
119
+ test('swatch can be selected', () => {
120
+ const history = createMemoryHistory()
121
+ history.push('/en-GB/swatch-example')
122
+
123
+ render(
124
+ <Router history={history}>
125
+ <Page />
126
+ </Router>
127
+ )
128
+
129
+ expect(screen.getAllByRole('radio')).toHaveLength(data.values.length)
130
+ const firstSwatch = screen.getAllByRole('radio')[0]
131
+ fireEvent.click(firstSwatch)
132
+ waitFor(() => {
133
+ expect(history.search).toBe('?color=BLACKFB')
134
+ })
135
+ })
136
+ })
@@ -0,0 +1,94 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+
8
+ import React from 'react'
9
+ import PropTypes from 'prop-types'
10
+ import {Button, Box, Center, useMultiStyleConfig} from '@chakra-ui/react'
11
+ import {Link as RouteLink} from 'react-router-dom'
12
+
13
+ /**
14
+ * The Swatch Component displays item inside `SwatchGroup`
15
+ */
16
+ const Swatch = (props) => {
17
+ const {
18
+ disabled,
19
+ selected,
20
+ label,
21
+ children,
22
+ href,
23
+ variant = 'square',
24
+ onChange,
25
+ value,
26
+ name
27
+ } = props
28
+ const styles = useMultiStyleConfig('SwatchGroup', {variant, disabled, selected})
29
+ return (
30
+ <Button
31
+ {...styles.swatch}
32
+ as={RouteLink}
33
+ to={href}
34
+ aria-label={name}
35
+ onClick={(e) => {
36
+ e.preventDefault()
37
+ onChange(value, href)
38
+ }}
39
+ aria-checked={selected}
40
+ variant="outline"
41
+ role="radio"
42
+ >
43
+ <Center {...styles.swatchButton}>
44
+ {children}
45
+ {label && <Box>{label}</Box>}
46
+ </Center>
47
+ </Button>
48
+ )
49
+ }
50
+
51
+ Swatch.displayName = 'Swatch'
52
+
53
+ Swatch.propTypes = {
54
+ /**
55
+ * The children to be rendered within swatch item.
56
+ */
57
+ children: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
58
+ /**
59
+ * Indicates whether the option is disabled
60
+ */
61
+ disabled: PropTypes.bool,
62
+ /**
63
+ * Indicates whether the option is selected.
64
+ * This props is provided internally by SwatchGroup
65
+ */
66
+ selected: PropTypes.bool,
67
+ /**
68
+ * The shape of the Swatch
69
+ */
70
+ variant: PropTypes.oneOf(['square', 'circle']),
71
+ /**
72
+ * The label of the option.
73
+ */
74
+ label: PropTypes.string,
75
+ /**
76
+ * The url of this option
77
+ */
78
+ href: PropTypes.string,
79
+ /**
80
+ * This function is called whenever the user selects an option.
81
+ * It is passed the new value.
82
+ */
83
+ onChange: PropTypes.func,
84
+ /**
85
+ * The value for the option.
86
+ */
87
+ value: PropTypes.string,
88
+ /**
89
+ * The display value for each swatch
90
+ */
91
+ name: PropTypes.string
92
+ }
93
+
94
+ export default Swatch
@@ -0,0 +1,97 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import React, {useContext, createContext} from 'react'
8
+ import PropTypes from 'prop-types'
9
+ import {FormattedMessage} from 'react-intl'
10
+ import {Box, Button, Flex, Heading, Stack} from '@chakra-ui/react'
11
+ import LoadingSpinner from '@salesforce/retail-react-app/app/components/loading-spinner'
12
+
13
+ const ToggleCardContext = createContext()
14
+
15
+ /**
16
+ * A card-like box that renders one of two states: 'edit' and 'summary'. It takes a single
17
+ * `ToggleCardSummary` and `ToggleCardEdit` component as children and renders one or the
18
+ * other depending on the `editing` prop. See `app/pages/checkout` for example.
19
+ */
20
+ export const ToggleCard = ({
21
+ id,
22
+ title,
23
+ editing,
24
+ disabled,
25
+ onEdit,
26
+ editLabel,
27
+ isLoading,
28
+ children,
29
+ ...props
30
+ }) => {
31
+ return (
32
+ <ToggleCardContext.Provider value={{editing, disabled}}>
33
+ <Box
34
+ layerStyle="card"
35
+ rounded={[0, 0, 'base']}
36
+ px={[4, 4, 6]}
37
+ data-testid={`sf-toggle-card-${id}`}
38
+ position="relative"
39
+ {...props}
40
+ >
41
+ <Stack spacing={editing || (!editing && !disabled) ? 4 : 0}>
42
+ <Flex justify="space-between">
43
+ <Heading
44
+ fontSize="lg"
45
+ lineHeight="30px"
46
+ color={disabled && !editing && 'gray.400'}
47
+ >
48
+ {title}
49
+ </Heading>
50
+ {!editing && !disabled && onEdit && (
51
+ <Button variant="link" size="sm" onClick={onEdit}>
52
+ {editLabel || (
53
+ <FormattedMessage
54
+ defaultMessage="Edit"
55
+ id="toggle_card.action.edit"
56
+ />
57
+ )}
58
+ </Button>
59
+ )}
60
+ </Flex>
61
+ <Box data-testid={`sf-toggle-card-${id}-content`}>{children}</Box>
62
+ </Stack>
63
+
64
+ {isLoading && editing && <LoadingSpinner />}
65
+ </Box>
66
+ </ToggleCardContext.Provider>
67
+ )
68
+ }
69
+
70
+ export const ToggleCardEdit = ({children}) => {
71
+ const {editing} = useContext(ToggleCardContext)
72
+ return editing ? children : null
73
+ }
74
+
75
+ export const ToggleCardSummary = ({children}) => {
76
+ const {editing, disabled} = useContext(ToggleCardContext)
77
+ return !editing && !disabled ? children : null
78
+ }
79
+
80
+ ToggleCard.propTypes = {
81
+ id: PropTypes.string,
82
+ title: PropTypes.any,
83
+ editLabel: PropTypes.any,
84
+ editing: PropTypes.bool,
85
+ isLoading: PropTypes.bool,
86
+ disabled: PropTypes.bool,
87
+ onEdit: PropTypes.func,
88
+ children: PropTypes.any
89
+ }
90
+
91
+ ToggleCardEdit.propTypes = {
92
+ children: PropTypes.any
93
+ }
94
+
95
+ ToggleCardSummary.propTypes = {
96
+ children: PropTypes.any
97
+ }
@@ -0,0 +1,58 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import React from 'react'
8
+ import {AuthModal, useAuthModal} from '@salesforce/retail-react-app/app/hooks/use-auth-modal'
9
+ import PropTypes from 'prop-types'
10
+ import {noop} from '@salesforce/retail-react-app/app/utils/utils'
11
+ import {useIntl} from 'react-intl'
12
+ import {useLocation} from 'react-router-dom'
13
+ import {useToast} from '@salesforce/retail-react-app/app/hooks/use-toast'
14
+ import {useCurrentCustomer} from '@salesforce/retail-react-app/app/hooks/use-current-customer'
15
+
16
+ const withRegistration = (Component) => {
17
+ const WrappedComponent = ({onClick = noop, ...passThroughProps}) => {
18
+ const {data: customer} = useCurrentCustomer()
19
+ const authModal = useAuthModal()
20
+ const location = useLocation()
21
+ const {formatMessage, locale} = useIntl()
22
+ const isLoginPage = new RegExp(`^/${locale}/login$`).test(location.pathname)
23
+ const showToast = useToast()
24
+
25
+ const handleClick = (e) => {
26
+ e.preventDefault()
27
+ if (!customer.isRegistered) {
28
+ // Do not show auth modal if users is already on the login page
29
+ if (isLoginPage) {
30
+ showToast({
31
+ title: formatMessage({
32
+ defaultMessage: 'Please sign in to continue!',
33
+ id: 'with_registration.info.please_sign_in'
34
+ }),
35
+ status: 'info'
36
+ })
37
+ } else {
38
+ authModal.onOpen()
39
+ }
40
+ } else {
41
+ onClick()
42
+ }
43
+ }
44
+
45
+ return (
46
+ <React.Fragment>
47
+ <Component {...passThroughProps} onClick={handleClick} />
48
+ <AuthModal {...authModal} onLoginSuccess={onClick} />
49
+ </React.Fragment>
50
+ )
51
+ }
52
+ WrappedComponent.propTypes = {
53
+ onClick: PropTypes.func
54
+ }
55
+ return WrappedComponent
56
+ }
57
+
58
+ export default withRegistration
@@ -0,0 +1,85 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import React from 'react'
8
+ import {Button} from '@chakra-ui/react'
9
+ import {screen, waitFor} from '@testing-library/react'
10
+ import withRegistration from '@salesforce/retail-react-app/app/components/with-registration/index'
11
+ import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
12
+ import userEvent from '@testing-library/user-event'
13
+ import {rest} from 'msw'
14
+ import {mockedGuestCustomer} from '@salesforce/retail-react-app/app/mocks/mock-data'
15
+
16
+ const ButtonWithRegistration = withRegistration(Button)
17
+
18
+ const MockedComponent = (props) => {
19
+ return (
20
+ <div>
21
+ <ButtonWithRegistration {...props}>Button</ButtonWithRegistration>
22
+ </div>
23
+ )
24
+ }
25
+
26
+ // Set up and clean up
27
+ beforeAll(() => {
28
+ // Since we're testing some navigation logic, we are using a simple Router
29
+ // around our component. We need to initialize the default route/path here.
30
+ window.history.pushState({}, 'Account', '/en-GB/account')
31
+ })
32
+
33
+ afterEach(() => {
34
+ jest.resetModules()
35
+ sessionStorage.clear()
36
+ })
37
+
38
+ describe('Registered users tests', function () {
39
+ test('should execute onClick for registered users', async () => {
40
+ const user = userEvent.setup()
41
+
42
+ const onClick = jest.fn()
43
+ renderWithProviders(<MockedComponent onClick={onClick} />)
44
+
45
+ const trigger = screen.getByText(/button/i)
46
+ expect(trigger).toBeInTheDocument()
47
+ await user.click(trigger)
48
+
49
+ await waitFor(() => {
50
+ expect(onClick).toHaveBeenCalledTimes(1)
51
+ })
52
+ })
53
+ })
54
+
55
+ describe('Guest user tests', function () {
56
+ beforeEach(() => {
57
+ global.server.use(
58
+ rest.get('*/customers/:customerId', (req, res, ctx) => {
59
+ return res(ctx.delay(0), ctx.status(200), ctx.json(mockedGuestCustomer))
60
+ })
61
+ )
62
+ })
63
+ test('should show login modal if user not registered', async () => {
64
+ const user = userEvent.setup()
65
+ const onClick = jest.fn()
66
+ renderWithProviders(
67
+ <ButtonWithRegistration onClick={onClick}>Button</ButtonWithRegistration>,
68
+ {
69
+ wrapperProps: {
70
+ isGuest: true
71
+ }
72
+ }
73
+ )
74
+
75
+ const trigger = await screen.findByText(/button/i)
76
+ await user.click(trigger)
77
+
78
+ await waitFor(() => {
79
+ expect(screen.getByLabelText(/email/i)).toBeInTheDocument()
80
+ expect(screen.getByLabelText(/Password/)).toBeInTheDocument()
81
+ expect(screen.getByText(/forgot password/i)).toBeInTheDocument()
82
+ expect(screen.getByText(/sign in/i)).toBeInTheDocument()
83
+ })
84
+ })
85
+ })