@magento/venia-ui 9.2.0 → 9.3.0-alpha.1

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 (167) hide show
  1. package/i18n/en_US.json +17 -3
  2. package/lib/RootComponents/CMS/__tests__/__snapshots__/cms.spec.js.snap +19 -0
  3. package/lib/RootComponents/CMS/__tests__/cms.spec.js +4 -9
  4. package/lib/RootComponents/CMS/cms.js +5 -4
  5. package/lib/RootComponents/CMS/cms.shimmer.js +18 -0
  6. package/lib/RootComponents/Category/__tests__/__snapshots__/categoryContent.shimmer.spec.js.snap +12 -0
  7. package/lib/RootComponents/Category/categoryContent.js +4 -1
  8. package/lib/components/AccountChip/accountChip.js +3 -1
  9. package/lib/components/AccountInformationPage/accountInformationPage.js +3 -1
  10. package/lib/components/AccountInformationPage/editModal.js +9 -2
  11. package/lib/components/AccountMenu/accountMenuItems.js +8 -3
  12. package/lib/components/CartPage/GiftCards/giftCards.js +1 -1
  13. package/lib/components/CartPage/PriceAdjustments/CouponCode/couponCode.js +5 -1
  14. package/lib/components/CartPage/PriceAdjustments/GiftOptions/__tests__/__snapshots__/giftOptions.spec.js.snap +1018 -78
  15. package/lib/components/CartPage/PriceAdjustments/GiftOptions/__tests__/giftOptions.spec.js +221 -35
  16. package/lib/components/CartPage/PriceAdjustments/GiftOptions/giftOptions.js +287 -40
  17. package/lib/components/CartPage/PriceAdjustments/GiftOptions/giftOptions.module.css +56 -1
  18. package/lib/components/CartPage/PriceAdjustments/__tests__/__snapshots__/giftCardSection.ee.spec.js.snap +12 -0
  19. package/lib/components/CartPage/PriceAdjustments/__tests__/__snapshots__/giftOptionsSection.ce.spec.js.snap +3 -0
  20. package/lib/components/CartPage/PriceAdjustments/__tests__/__snapshots__/giftOptionsSection.ee.spec.js.snap +16 -0
  21. package/lib/components/CartPage/PriceAdjustments/__tests__/__snapshots__/priceAdjustments.spec.js.snap +1 -32
  22. package/lib/components/CartPage/PriceAdjustments/__tests__/giftCardSection.ce.spec.js +17 -0
  23. package/lib/components/CartPage/PriceAdjustments/__tests__/giftCardSection.ee.spec.js +36 -0
  24. package/lib/components/CartPage/PriceAdjustments/__tests__/giftOptionsSection.ce.spec.js +17 -0
  25. package/lib/components/CartPage/PriceAdjustments/__tests__/giftOptionsSection.ee.spec.js +54 -0
  26. package/lib/components/CartPage/PriceAdjustments/__tests__/priceAdjustments.spec.js +1 -1
  27. package/lib/components/CartPage/PriceAdjustments/{giftCardSection.js → giftCardSection.ce.js} +0 -0
  28. package/lib/components/CartPage/PriceAdjustments/giftOptionsSection.ce.js +7 -0
  29. package/lib/components/CartPage/PriceAdjustments/giftOptionsSection.ee.js +38 -0
  30. package/lib/components/CartPage/PriceAdjustments/priceAdjustments.js +2 -14
  31. package/lib/components/CartPage/PriceSummary/__tests__/__snapshots__/discountSummary.spec.js.snap +496 -42
  32. package/lib/components/CartPage/PriceSummary/__tests__/__snapshots__/giftCardSummary.ce.spec.js.snap +3 -0
  33. package/lib/components/CartPage/PriceSummary/__tests__/__snapshots__/{giftCardSummary.spec.js.snap → giftCardSummary.ee.spec.js.snap} +4 -4
  34. package/lib/components/CartPage/PriceSummary/__tests__/__snapshots__/giftOptionsSummary.ce.spec.js.snap +3 -0
  35. package/lib/components/CartPage/PriceSummary/__tests__/__snapshots__/giftOptionsSummary.ee.spec.js.snap +63 -0
  36. package/lib/components/CartPage/PriceSummary/__tests__/__snapshots__/priceSummary.spec.js.snap +201 -141
  37. package/lib/components/CartPage/PriceSummary/__tests__/discountSummary.spec.js +41 -1
  38. package/lib/components/CartPage/PriceSummary/__tests__/giftCardSummary.ce.spec.js +17 -0
  39. package/lib/components/CartPage/PriceSummary/__tests__/giftCardSummary.ee.spec.js +84 -0
  40. package/lib/components/CartPage/PriceSummary/__tests__/giftOptionsSummary.ce.spec.js +17 -0
  41. package/lib/components/CartPage/PriceSummary/__tests__/giftOptionsSummary.ee.spec.js +69 -0
  42. package/lib/components/CartPage/PriceSummary/__tests__/priceSummary.spec.js +2 -0
  43. package/lib/components/CartPage/PriceSummary/discountSummary.js +99 -49
  44. package/lib/components/CartPage/PriceSummary/discountSummary.module.css +40 -0
  45. package/lib/components/CartPage/PriceSummary/giftOptionsSummary.ce.js +5 -0
  46. package/lib/components/CartPage/PriceSummary/giftOptionsSummary.ee.js +40 -0
  47. package/lib/components/CartPage/PriceSummary/priceSummary.js +95 -53
  48. package/lib/components/CartPage/PriceSummary/priceSummary.module.css +2 -0
  49. package/lib/components/CartPage/ProductListing/EditModal/__tests__/__snapshots__/productDetail.spec.js.snap +57 -0
  50. package/lib/components/CartPage/ProductListing/EditModal/__tests__/__snapshots__/productForm.spec.js.snap +22 -0
  51. package/lib/components/CartPage/ProductListing/EditModal/__tests__/productDetail.spec.js +42 -3
  52. package/lib/components/CartPage/ProductListing/EditModal/productDetail.js +13 -10
  53. package/lib/components/CartPage/ProductListing/EditModal/productForm.js +7 -2
  54. package/lib/components/CartPage/ProductListing/product.js +1 -0
  55. package/lib/components/CartPage/ProductListing/productListing.js +1 -1
  56. package/lib/components/CartPage/cartPage.js +1 -1
  57. package/lib/components/Checkbox/checkbox.js +6 -1
  58. package/lib/components/Checkbox/checkbox.module.css +1 -0
  59. package/lib/components/CheckoutPage/ItemsReview/__tests__/__snapshots__/item.spec.js.snap +2 -2
  60. package/lib/components/CheckoutPage/ItemsReview/__tests__/__snapshots__/itemsReview.spec.js.snap +33 -0
  61. package/lib/components/CheckoutPage/ItemsReview/__tests__/item.spec.js +2 -2
  62. package/lib/components/CheckoutPage/ItemsReview/itemsReview.js +4 -1
  63. package/lib/components/CheckoutPage/OrderConfirmationPage/__tests__/createAccount.spec.js +4 -0
  64. package/lib/components/CheckoutPage/OrderConfirmationPage/createAccount.js +9 -1
  65. package/lib/components/CheckoutPage/OrderConfirmationPage/orderConfirmationPage.js +12 -3
  66. package/lib/components/CheckoutPage/PaymentInformation/__tests__/__snapshots__/creditCard.spec.js.snap +1 -0
  67. package/lib/components/CheckoutPage/PaymentInformation/__tests__/creditCard.spec.js +2 -1
  68. package/lib/components/CheckoutPage/PaymentInformation/brainTreeDropIn.js +2 -18
  69. package/lib/components/CheckoutPage/PaymentInformation/creditCard.js +13 -3
  70. package/lib/components/CheckoutPage/PriceAdjustments/__tests__/__snapshots__/priceAdjustments.spec.js.snap +1 -6
  71. package/lib/components/CheckoutPage/PriceAdjustments/__tests__/priceAdjustments.spec.js +2 -2
  72. package/lib/components/CheckoutPage/PriceAdjustments/priceAdjustments.js +8 -12
  73. package/lib/components/CheckoutPage/ShippingInformation/AddressForm/customerForm.js +1 -1
  74. package/lib/components/CheckoutPage/ShippingInformation/shippingInformation.js +4 -1
  75. package/lib/components/CheckoutPage/ShippingMethod/shippingMethod.js +5 -2
  76. package/lib/components/CheckoutPage/__tests__/__snapshots__/checkoutPage.spec.js.snap +3 -3
  77. package/lib/components/CheckoutPage/__tests__/checkoutPage.spec.js +5 -0
  78. package/lib/components/CheckoutPage/checkoutPage.js +25 -4
  79. package/lib/components/CheckoutPage/checkoutPage.module.css +8 -1
  80. package/lib/components/CmsDynamicBlock/__tests__/__snapshots__/cmsDynamicBlock.ce.spec.js.snap +3 -0
  81. package/lib/components/CmsDynamicBlock/__tests__/__snapshots__/cmsDynamicBlock.ee.spec.js.snap +61 -0
  82. package/lib/components/CmsDynamicBlock/__tests__/__snapshots__/dynamicBlock.spec.js.snap +7 -0
  83. package/lib/components/CmsDynamicBlock/__tests__/cmsDynamicBlock.ce.spec.js +17 -0
  84. package/lib/components/CmsDynamicBlock/__tests__/cmsDynamicBlock.ee.spec.js +211 -0
  85. package/lib/components/CmsDynamicBlock/__tests__/constants.spec.js +37 -0
  86. package/lib/components/CmsDynamicBlock/__tests__/dynamicBlock.spec.js +33 -0
  87. package/lib/components/CmsDynamicBlock/cmsDynamicBlock.ce.js +5 -0
  88. package/lib/components/CmsDynamicBlock/cmsDynamicBlock.ee.js +73 -0
  89. package/lib/components/CmsDynamicBlock/constants.js +6 -0
  90. package/lib/components/CmsDynamicBlock/dynamicBlock.js +32 -0
  91. package/lib/components/CmsDynamicBlock/index.js +2 -0
  92. package/lib/components/CreateAccount/__tests__/createAccount.spec.js +6 -1
  93. package/lib/components/CreateAccount/createAccount.js +7 -2
  94. package/lib/components/Field/field.module.css +6 -0
  95. package/lib/components/FilterSidebar/filterSidebar.js +4 -1
  96. package/lib/components/Footer/__tests__/__snapshots__/footer.spec.js.snap +8 -2
  97. package/lib/components/Footer/footer.js +16 -9
  98. package/lib/components/Footer/footer.module.css +7 -2
  99. package/lib/components/ForgotPassword/ForgotPasswordForm/__tests__/__snapshots__/forgotPasswordForm.spec.js.snap +109 -1
  100. package/lib/components/ForgotPassword/ForgotPasswordForm/__tests__/forgotPasswordForm.spec.js +22 -3
  101. package/lib/components/ForgotPassword/ForgotPasswordForm/forgotPasswordForm.js +13 -3
  102. package/lib/components/ForgotPassword/ForgotPasswordForm/forgotPasswordForm.module.css +1 -1
  103. package/lib/components/ForgotPassword/__tests__/__snapshots__/forgotPassword.spec.js.snap +5 -6
  104. package/lib/components/ForgotPassword/__tests__/forgotPassword.spec.js +41 -28
  105. package/lib/components/ForgotPassword/forgotPassword.js +10 -3
  106. package/lib/components/ForgotPassword/forgotPassword.module.css +2 -2
  107. package/lib/components/Gallery/__tests__/__snapshots__/gallery.spec.js.snap +22 -0
  108. package/lib/components/Gallery/__tests__/__snapshots__/item.spec.js.snap +17 -0
  109. package/lib/components/Gallery/addToCartButton.js +2 -0
  110. package/lib/components/Gallery/gallery.js +6 -1
  111. package/lib/components/Gallery/item.js +7 -2
  112. package/lib/components/GoogleReCaptcha/googleReCaptcha.js +49 -0
  113. package/lib/components/GoogleReCaptcha/googleReCaptcha.module.css +3 -0
  114. package/lib/components/GoogleReCaptcha/index.js +1 -0
  115. package/lib/components/Header/currencySwitcher.js +2 -1
  116. package/lib/components/Header/header.js +1 -1
  117. package/lib/components/Header/header.module.css +2 -2
  118. package/lib/components/Header/searchTrigger.js +3 -1
  119. package/lib/components/Header/storeSwitcher.js +18 -4
  120. package/lib/components/Header/switcherItem.js +4 -1
  121. package/lib/components/HomePage/homePage.module.css +12 -0
  122. package/lib/components/Image/resourceImage.js +8 -1
  123. package/lib/components/Image/simpleImage.js +8 -1
  124. package/lib/components/Link/link.js +15 -13
  125. package/lib/components/LoadingIndicator/spinner.js +5 -7
  126. package/lib/components/LoadingIndicator/spinner.module.css +4 -17
  127. package/lib/components/MiniCart/ProductList/__tests__/__snapshots__/item.spec.js.snap +44 -0
  128. package/lib/components/MiniCart/ProductList/__tests__/item.spec.js +2 -2
  129. package/lib/components/MiniCart/ProductList/item.js +3 -2
  130. package/lib/components/MiniCart/miniCart.js +6 -3
  131. package/lib/components/MyAccount/ResetPassword/__tests__/__snapshots__/resetPassword.spec.js.snap +274 -254
  132. package/lib/components/MyAccount/ResetPassword/__tests__/resetPassword.spec.js +10 -5
  133. package/lib/components/MyAccount/ResetPassword/resetPassword.js +55 -55
  134. package/lib/components/MyAccount/ResetPassword/resetPassword.module.css +27 -79
  135. package/lib/components/Newsletter/newsletter.js +6 -2
  136. package/lib/components/OrderHistoryPage/OrderDetails/__tests__/__snapshots__/item.spec.js.snap +11 -0
  137. package/lib/components/ProductFullDetail/productFullDetail.js +12 -3
  138. package/lib/components/ProductImageCarousel/__tests__/__snapshots__/carousel.spec.js.snap +61 -0
  139. package/lib/components/ProductImageCarousel/__tests__/__snapshots__/thumbnail.spec.js.snap +26 -0
  140. package/lib/components/ProductOptions/__tests__/options.spec.js +1 -1
  141. package/lib/components/ProductOptions/__tests__/swatch.spec.js +1 -1
  142. package/lib/components/ProductOptions/__tests__/swatchList.spec.js +1 -1
  143. package/lib/components/ProductOptions/__tests__/tile.spec.js +1 -1
  144. package/lib/components/ProductOptions/__tests__/tileList.spec.js +1 -1
  145. package/lib/components/ProductOptions/option.js +4 -1
  146. package/lib/components/ProductSort/productSort.js +22 -14
  147. package/lib/components/Rating/rating.js +1 -1
  148. package/lib/components/SearchBar/__tests__/__snapshots__/suggestedProduct.spec.js.snap +11 -0
  149. package/lib/components/SearchBar/autocomplete.js +4 -2
  150. package/lib/components/SearchBar/suggestedProduct.js +1 -1
  151. package/lib/components/SearchBar/suggestions.js +1 -1
  152. package/lib/components/SignIn/__tests__/signIn.spec.js +11 -20
  153. package/lib/components/SignIn/signIn.js +6 -16
  154. package/lib/components/TextInput/textInput.module.css +0 -4
  155. package/lib/components/Wishlist/WishlistDialog/WishlistLineItem/__tests__/__snapshots__/wishlistLineItem.spec.js.snap +5 -1
  156. package/lib/components/Wishlist/WishlistDialog/WishlistLineItem/wishlistLineItem.js +7 -1
  157. package/lib/components/Wishlist/WishlistDialog/WishlistLineItem/wishlistLineItem.module.css +7 -0
  158. package/lib/components/Wishlist/WishlistDialog/__tests__/__snapshots__/wishlistDialog.spec.js.snap +6 -1
  159. package/lib/components/WishlistPage/__tests__/__snapshots__/wishlist.spec.js.snap +4 -0
  160. package/lib/components/WishlistPage/__tests__/__snapshots__/wishlistItem.spec.js.snap +22 -0
  161. package/lib/components/WishlistPage/__tests__/__snapshots__/wishlistPage.spec.js.snap +9 -3
  162. package/lib/components/WishlistPage/createWishlist.ee.js +3 -1
  163. package/lib/components/WishlistPage/wishlist.js +1 -1
  164. package/lib/components/WishlistPage/wishlist.module.css +3 -0
  165. package/lib/components/WishlistPage/wishlistPage.js +1 -1
  166. package/package.json +4 -3
  167. package/lib/components/CartPage/PriceSummary/__tests__/giftCardSummary.spec.js +0 -84
@@ -1,50 +1,236 @@
1
1
  import React from 'react';
2
+ import { IntlProvider } from 'react-intl';
3
+
2
4
  import { createTestInstance } from '@magento/peregrine';
5
+ import { useGiftOptions } from '@magento/peregrine/lib/talons/CartPage/PriceAdjustments/GiftOptions/useGiftOptions';
3
6
 
4
7
  import GiftOptions from '../giftOptions';
5
8
 
6
- jest.mock('@magento/peregrine/lib/context/cart', () => {
7
- const state = { cartId: 'fakeCartId' };
8
- const api = {};
9
- const useCartContext = jest.fn(() => [state, api]);
9
+ jest.mock('react-intl', () => ({
10
+ ...jest.requireActual('react-intl')
11
+ }));
12
+ jest.mock('informed', () => ({
13
+ Form: ({ children, ...rest }) => <mock-Form {...rest}>{children}</mock-Form>
14
+ }));
10
15
 
11
- return { useCartContext };
12
- });
16
+ jest.mock(
17
+ '@magento/peregrine/lib/talons/CartPage/PriceAdjustments/GiftOptions/useGiftOptions'
18
+ );
19
+ jest.mock('@magento/venia-ui/lib/classify');
20
+ jest.mock('@magento/venia-ui/lib/components/Button', () => props => (
21
+ <mock-Button {...props} />
22
+ ));
23
+ jest.mock('@magento/venia-ui/lib/components/Checkbox', () => props => (
24
+ <mock-Checkbox {...props} />
25
+ ));
26
+ jest.mock(
27
+ '@magento/venia-ui/lib/components/Field',
28
+ () => ({ children, ...rest }) => (
29
+ <mock-Field {...rest}>{children}</mock-Field>
30
+ )
31
+ );
32
+ jest.mock('@magento/venia-ui/lib/components/FormError', () => props => (
33
+ <mock-FormError {...props} />
34
+ ));
35
+ jest.mock('@magento/venia-ui/lib/components/Icon', () => props => (
36
+ <mock-Icon {...props} />
37
+ ));
38
+ jest.mock('@magento/venia-ui/lib/components/LoadingIndicator', () => ({
39
+ __esModule: true,
40
+ default: jest
41
+ .fn()
42
+ .mockImplementation(props => <mock-LoadingIndicator {...props} />),
43
+ Spinner: jest.fn().mockImplementation(props => <mock-Spinner {...props} />)
44
+ }));
45
+ jest.mock('@magento/venia-ui/lib/components/LinkButton', () => props => (
46
+ <mock-LinkButton {...props} />
47
+ ));
48
+ jest.mock('@magento/venia-ui/lib/components/Price', () => props => (
49
+ <mock-Price {...props} />
50
+ ));
51
+ jest.mock('@magento/venia-ui/lib/components/TextArea', () => props => (
52
+ <mock-TextArea {...props} />
53
+ ));
54
+ jest.mock('@magento/venia-ui/lib/components/TextInput', () => props => (
55
+ <mock-TextInput {...props} />
56
+ ));
13
57
 
14
- jest.mock('@apollo/client', () => {
15
- const queryResult = {
16
- data: {
17
- cart: {
18
- include_gift_receipt: true,
19
- include_printed_card: false,
20
- gift_message: 'Sample Message'
21
- }
22
- },
23
- error: null,
24
- loading: false
25
- };
58
+ let inputProps = {};
26
59
 
27
- const useQuery = jest.fn(() => queryResult);
60
+ const talonProps = {
61
+ loading: false,
62
+ errors: [],
63
+ savingOptions: [],
64
+ giftReceiptProps: {
65
+ field: 'includeGiftReceipt'
66
+ },
67
+ printedCardProps: {
68
+ field: 'includePrintedCard'
69
+ },
70
+ printedCardPrice: {},
71
+ giftMessageCheckboxProps: {
72
+ field: 'includeGiftMessage'
73
+ },
74
+ giftMessageResult: {},
75
+ hasGiftMessage: false,
76
+ showGiftMessageResult: false,
77
+ cardToProps: {
78
+ field: 'cardTo'
79
+ },
80
+ cardFromProps: {
81
+ field: 'cardFrom'
82
+ },
83
+ cardMessageProps: {
84
+ field: 'cardMessage'
85
+ },
86
+ editGiftMessageButtonProps: {},
87
+ cancelGiftMessageButtonProps: {},
88
+ saveGiftMessageButtonProps: {},
89
+ optionsFormProps: {}
90
+ };
28
91
 
29
- const useMutation = jest.fn(() => [() => {}]);
92
+ const Component = () => {
93
+ return (
94
+ <IntlProvider locale="en-US">
95
+ <GiftOptions {...inputProps} />
96
+ </IntlProvider>
97
+ );
98
+ };
30
99
 
31
- return {
32
- gql: jest.fn(),
33
- useApolloClient: jest.fn(() => ({
34
- cache: {}
35
- })),
36
- useQuery,
37
- useMutation
100
+ const givenDefaultValues = () => {
101
+ inputProps = {
102
+ giftOptionsConfigData: null
38
103
  };
39
- });
104
+ };
40
105
 
41
- beforeAll(() => {
42
- // informed's random ids make snapshots unstable
43
- jest.spyOn(Math, 'random').mockReturnValue(0);
44
- });
106
+ const givenOptionsConfigData = () => {
107
+ inputProps.giftOptionsConfigData = {
108
+ allow_order: '1',
109
+ allow_gift_receipt: '1',
110
+ allow_printed_card: '1'
111
+ };
112
+ };
113
+
114
+ describe('#GiftOptions', () => {
115
+ beforeEach(() => {
116
+ givenDefaultValues();
117
+ });
118
+
119
+ it('renders loading indicator when loading', () => {
120
+ useGiftOptions.mockReturnValueOnce({
121
+ ...talonProps,
122
+ loading: true
123
+ });
124
+
125
+ const tree = createTestInstance(<Component />);
126
+
127
+ expect(tree.toJSON()).toMatchSnapshot();
128
+ });
129
+
130
+ it('renders empty form when no options are enabled', () => {
131
+ useGiftOptions.mockReturnValueOnce(talonProps);
132
+
133
+ const tree = createTestInstance(<Component />);
134
+
135
+ expect(tree.toJSON()).toMatchSnapshot();
136
+ });
137
+
138
+ it('renders form when options are enabled', () => {
139
+ givenOptionsConfigData();
140
+ useGiftOptions.mockReturnValueOnce(talonProps);
141
+
142
+ const tree = createTestInstance(<Component />);
143
+
144
+ expect(tree.toJSON()).toMatchSnapshot();
145
+ });
146
+
147
+ it('renders form returns errors', () => {
148
+ givenOptionsConfigData();
149
+ useGiftOptions.mockReturnValueOnce({
150
+ ...talonProps,
151
+ errors: new Map([['query', { message: 'error' }]])
152
+ });
153
+
154
+ const tree = createTestInstance(<Component />);
155
+
156
+ expect(tree.toJSON()).toMatchSnapshot();
157
+ });
158
+
159
+ it('renders form when gift message form is opened', () => {
160
+ givenOptionsConfigData();
161
+ useGiftOptions.mockReturnValueOnce({
162
+ ...talonProps,
163
+ showGiftMessageResult: true
164
+ });
165
+
166
+ const tree = createTestInstance(<Component />);
167
+
168
+ expect(tree.toJSON()).toMatchSnapshot();
169
+ });
170
+
171
+ it('renders form when gift message exists', () => {
172
+ givenOptionsConfigData();
173
+ useGiftOptions.mockReturnValueOnce({
174
+ ...talonProps,
175
+ hasGiftMessage: true,
176
+ giftMessageResult: {
177
+ cardTo: 'To',
178
+ cardFrom: 'From',
179
+ cardMessage: 'Message'
180
+ }
181
+ });
182
+
183
+ const tree = createTestInstance(<Component />);
184
+
185
+ expect(tree.toJSON()).toMatchSnapshot();
186
+ });
187
+
188
+ it('renders form when gift message exists and form is opened', () => {
189
+ givenOptionsConfigData();
190
+ useGiftOptions.mockReturnValueOnce({
191
+ ...talonProps,
192
+ hasGiftMessage: true,
193
+ giftMessageResult: {
194
+ cardTo: 'To',
195
+ cardFrom: 'From',
196
+ cardMessage: 'Message'
197
+ },
198
+ showGiftMessageResult: true
199
+ });
200
+
201
+ const tree = createTestInstance(<Component />);
202
+
203
+ expect(tree.toJSON()).toMatchSnapshot();
204
+ });
205
+
206
+ it('renders printed card price when above 0', () => {
207
+ givenOptionsConfigData();
208
+ useGiftOptions.mockReturnValueOnce({
209
+ ...talonProps,
210
+ printedCardPrice: {
211
+ currency: 'USD',
212
+ value: 10
213
+ }
214
+ });
215
+
216
+ const tree = createTestInstance(<Component />);
217
+
218
+ expect(tree.toJSON()).toMatchSnapshot();
219
+ });
220
+
221
+ it('renders spinners when gift options are saving', () => {
222
+ givenOptionsConfigData();
223
+ useGiftOptions.mockReturnValueOnce({
224
+ ...talonProps,
225
+ savingOptions: [
226
+ 'includeGiftReceipt',
227
+ 'includePrintedCard',
228
+ 'giftMessage'
229
+ ]
230
+ });
45
231
 
46
- test('it renders gift options in venia cart page', () => {
47
- const instance = createTestInstance(<GiftOptions />);
232
+ const tree = createTestInstance(<Component />);
48
233
 
49
- expect(instance.toJSON()).toMatchSnapshot();
234
+ expect(tree.toJSON()).toMatchSnapshot();
235
+ });
50
236
  });
@@ -1,11 +1,23 @@
1
1
  import React from 'react';
2
- import { useIntl } from 'react-intl';
3
- import { Form, Relevant } from 'informed';
4
- import useGiftOptions from '@magento/peregrine/lib/talons/CartPage/PriceAdjustments/GiftOptions/useGiftOptions.js';
2
+ import { FormattedMessage, useIntl } from 'react-intl';
3
+ import { Edit2 as EditIcon } from 'react-feather';
4
+ import { Form } from 'informed';
5
+
6
+ import { useGiftOptions } from '@magento/peregrine/lib/talons/CartPage/PriceAdjustments/GiftOptions/useGiftOptions';
7
+ import { useStyle } from '@magento/venia-ui/lib/classify';
8
+ import Button from '@magento/venia-ui/lib/components/Button';
9
+ import Checkbox from '@magento/venia-ui/lib/components/Checkbox';
10
+ import Field from '@magento/venia-ui/lib/components/Field';
11
+ import FormError from '@magento/venia-ui/lib/components/FormError';
12
+ import Icon from '@magento/venia-ui/lib/components/Icon';
13
+ import LoadingIndicator, {
14
+ Spinner
15
+ } from '@magento/venia-ui/lib/components/LoadingIndicator';
16
+ import LinkButton from '@magento/venia-ui/lib/components/LinkButton';
17
+ import Price from '@magento/venia-ui/lib/components/Price';
18
+ import TextArea from '@magento/venia-ui/lib/components/TextArea';
19
+ import TextInput from '@magento/venia-ui/lib/components/TextInput';
5
20
 
6
- import { useStyle } from '../../../../classify';
7
- import Checkbox from '../../../Checkbox';
8
- import TextArea from '../../../TextArea';
9
21
  import defaultClasses from './giftOptions.module.css';
10
22
 
11
23
  /**
@@ -13,7 +25,8 @@ import defaultClasses from './giftOptions.module.css';
13
25
  * This component displays the form for adding gift options.
14
26
  *
15
27
  * @param {Object} props
16
- * @param {Object} props.classes CSS className overrides.
28
+ * @param {Object} [props.classes] CSS className overrides.
29
+ * @param {Object} [props.giftOptionsConfigData] store config data.
17
30
  * See [giftOptions.module.css]{@link https://github.com/magento/pwa-studio/blob/develop/packages/venia-ui/lib/components/CartPage/PriceAdjustments/GiftOptions/giftOptions.module.css}
18
31
  * for a list of classes you can override.
19
32
  *
@@ -23,50 +36,284 @@ import defaultClasses from './giftOptions.module.css';
23
36
  * import GiftOptions from "@magento/venia-ui/lib/components/CartPage/PriceAdjustments/GiftOptions";
24
37
  */
25
38
  const GiftOptions = props => {
39
+ const { classes: propClasses } = props;
26
40
  const {
27
- cardMessageProps,
41
+ loading,
42
+ errors,
43
+ savingOptions,
28
44
  giftReceiptProps,
29
- optionsFormProps,
30
45
  printedCardProps,
31
- shouldPromptForMessage
46
+ printedCardPrice,
47
+ giftMessageCheckboxProps,
48
+ giftMessageResult,
49
+ hasGiftMessage,
50
+ showGiftMessageResult,
51
+ cardToProps,
52
+ cardFromProps,
53
+ cardMessageProps,
54
+ editGiftMessageButtonProps,
55
+ cancelGiftMessageButtonProps,
56
+ saveGiftMessageButtonProps,
57
+ optionsFormProps
32
58
  } = useGiftOptions();
33
59
  const { formatMessage } = useIntl();
34
- const classes = useStyle(defaultClasses, props.classes);
60
+ const classes = useStyle(defaultClasses, propClasses);
35
61
 
36
- return (
37
- <Form {...optionsFormProps} className={classes.root}>
38
- <div className={classes.option}>
39
- <Checkbox
40
- {...giftReceiptProps}
41
- data-cy="GiftOptions-includeGiftReceipt"
42
- label={formatMessage({
43
- id: 'giftOptions.includeGiftReceipt',
44
- defaultMessage: 'Include gift receipt'
45
- })}
46
- />
47
- </div>
62
+ if (loading) {
63
+ return <LoadingIndicator />;
64
+ }
65
+
66
+ const { allow_order, allow_gift_receipt, allow_printed_card } =
67
+ props?.giftOptionsConfigData || {};
68
+
69
+ const includeGiftReceipt =
70
+ allow_gift_receipt === '1' ? (
48
71
  <div className={classes.option}>
49
- <Checkbox
50
- {...printedCardProps}
51
- data-cy="GiftOptions-includePrintedCard"
52
- label={formatMessage({
53
- id: 'giftOptions.includePrintedCard',
54
- defaultMessage: 'Include printed card'
55
- })}
56
- />
72
+ <div className={classes.checkboxContainer}>
73
+ <Checkbox
74
+ {...giftReceiptProps}
75
+ data-cy="GiftOptions-includeGiftReceipt"
76
+ label={formatMessage({
77
+ id: 'giftOptions.includeGiftReceipt',
78
+ defaultMessage: 'Include gift receipt'
79
+ })}
80
+ />
81
+ </div>
82
+
83
+ {savingOptions.includes(giftReceiptProps.field) ? (
84
+ <div className={classes.savingContainer}>
85
+ <span className={classes.savingText}>
86
+ <FormattedMessage
87
+ id={'giftOptions.saving'}
88
+ defaultMessage={'Saving'}
89
+ />
90
+ </span>
91
+ <Spinner classes={{ root: classes.savingSpinner }} />
92
+ </div>
93
+ ) : null}
57
94
  </div>
58
- <div className={classes.option}>
59
- <Relevant when={shouldPromptForMessage}>
60
- <TextArea
61
- {...cardMessageProps}
62
- data-cy="GiftOptions-cardMessage"
63
- placeholder={formatMessage({
64
- id: 'giftOptions.cardMessage',
65
- defaultMessage: 'Enter your message here'
95
+ ) : null;
96
+
97
+ const includeGiftMessage =
98
+ allow_order === '1' ? (
99
+ <>
100
+ <div className={classes.option}>
101
+ <div className={classes.checkboxContainer}>
102
+ <Checkbox
103
+ {...giftMessageCheckboxProps}
104
+ data-cy="GiftOptions-includeGiftMessage"
105
+ label={formatMessage({
106
+ id: 'giftOptions.includeGiftMessage',
107
+ defaultMessage: 'Optional Message'
108
+ })}
109
+ />
110
+ </div>
111
+
112
+ {savingOptions.includes('giftMessage') ? (
113
+ <div className={classes.savingContainer}>
114
+ <span className={classes.savingText}>
115
+ <FormattedMessage
116
+ id={'giftOptions.saving'}
117
+ defaultMessage={'Saving'}
118
+ />
119
+ </span>
120
+ <Spinner
121
+ classes={{ root: classes.savingSpinner }}
122
+ />
123
+ </div>
124
+ ) : null}
125
+ </div>
126
+
127
+ <div
128
+ className={
129
+ showGiftMessageResult
130
+ ? classes.giftMessageResultContainer
131
+ : classes.hidden
132
+ }
133
+ >
134
+ <div
135
+ className={classes.giftMessageResult}
136
+ data-cy="GiftOptions-giftMessageResult"
137
+ >
138
+ <p>
139
+ <FormattedMessage
140
+ id="giftOptions.giftMessageTo"
141
+ defaultMessage="<strong>To:</strong> {cardTo}"
142
+ values={{
143
+ cardTo: giftMessageResult.cardTo,
144
+ strong: chunks => <strong>{chunks}</strong>
145
+ }}
146
+ />
147
+ </p>
148
+ <p>
149
+ <FormattedMessage
150
+ id="giftOptions.giftMessageFrom"
151
+ defaultMessage="<strong>From:</strong> {cardFrom}"
152
+ values={{
153
+ cardFrom: giftMessageResult.cardFrom,
154
+ strong: chunks => <strong>{chunks}</strong>
155
+ }}
156
+ />
157
+ </p>
158
+ <p>{giftMessageResult.cardMessage}</p>
159
+ </div>
160
+
161
+ <LinkButton
162
+ {...editGiftMessageButtonProps}
163
+ classes={{ root: classes.editGiftMessageButton }}
164
+ data-cy="GiftOptions-editGiftMessageButton"
165
+ >
166
+ <Icon
167
+ classes={{ icon: null }}
168
+ size={16}
169
+ src={EditIcon}
170
+ />
171
+ <span className={classes.actionLabel}>
172
+ <FormattedMessage
173
+ id="giftOptions.editGiftMessageButton"
174
+ defaultMessage="Edit"
175
+ />
176
+ </span>
177
+ </LinkButton>
178
+ </div>
179
+
180
+ <div
181
+ className={
182
+ !showGiftMessageResult
183
+ ? classes.giftMessageFields
184
+ : classes.hidden
185
+ }
186
+ >
187
+ <Field
188
+ id="to"
189
+ label={formatMessage({
190
+ id: 'giftOptions.to',
191
+ defaultMessage: 'To'
192
+ })}
193
+ >
194
+ <TextInput
195
+ {...cardToProps}
196
+ data-cy="GiftOptions-cardTo"
197
+ />
198
+ </Field>
199
+ <Field
200
+ id={cardFromProps.field}
201
+ label={formatMessage({
202
+ id: 'giftOptions.from',
203
+ defaultMessage: 'From'
204
+ })}
205
+ >
206
+ <TextInput
207
+ {...cardFromProps}
208
+ data-cy="GiftOptions-cardFrom"
209
+ />
210
+ </Field>
211
+ <Field
212
+ id="message"
213
+ label={formatMessage({
214
+ id: 'giftOptions.message',
215
+ defaultMessage: 'Message'
66
216
  })}
217
+ >
218
+ <TextArea
219
+ {...cardMessageProps}
220
+ data-cy="GiftOptions-cardMessage"
221
+ placeholder={formatMessage({
222
+ id: 'giftOptions.cardMessage',
223
+ defaultMessage: 'Enter your message here'
224
+ })}
225
+ />
226
+ </Field>
227
+
228
+ <div className={classes.giftMessageActions}>
229
+ {hasGiftMessage ? (
230
+ <Button
231
+ {...cancelGiftMessageButtonProps}
232
+ data-cy="GiftOptions-cancelGiftMessageButton"
233
+ >
234
+ <FormattedMessage
235
+ id="giftOptions.cancelGiftMessageButton"
236
+ defaultMessage="Cancel"
237
+ />
238
+ </Button>
239
+ ) : null}
240
+ <Button
241
+ {...saveGiftMessageButtonProps}
242
+ data-cy="GiftOptions-updateGiftMessageButton"
243
+ >
244
+ {hasGiftMessage ? (
245
+ <FormattedMessage
246
+ id="giftOptions.updateGiftMessageButton"
247
+ defaultMessage="Update Message"
248
+ />
249
+ ) : (
250
+ <FormattedMessage
251
+ id="giftOptions.addGiftMessage"
252
+ defaultMessage="Add Message"
253
+ />
254
+ )}
255
+ </Button>
256
+ </div>
257
+ </div>
258
+ </>
259
+ ) : null;
260
+
261
+ const includePrintedCard =
262
+ allow_printed_card === '1' ? (
263
+ <div className={classes.option}>
264
+ <div className={classes.checkboxContainer}>
265
+ <Checkbox
266
+ {...printedCardProps}
267
+ data-cy="GiftOptions-includePrintedCard"
268
+ label={formatMessage(
269
+ {
270
+ id: 'giftOptions.includePrintedCard',
271
+ defaultMessage: 'Add printed card{price}'
272
+ },
273
+ {
274
+ price:
275
+ printedCardPrice &&
276
+ printedCardPrice.value > 0 ? (
277
+ <>
278
+ {' ( + '}
279
+ <Price
280
+ currencyCode={
281
+ printedCardPrice.currency
282
+ }
283
+ value={printedCardPrice.value}
284
+ />
285
+ {')'}
286
+ </>
287
+ ) : null
288
+ }
289
+ )}
67
290
  />
68
- </Relevant>
291
+ </div>
292
+
293
+ {savingOptions.includes(printedCardProps.field) ? (
294
+ <div className={classes.savingContainer}>
295
+ <span className={classes.savingText}>
296
+ <FormattedMessage
297
+ id={'giftOptions.saving'}
298
+ defaultMessage={'Saving'}
299
+ />
300
+ </span>
301
+ <Spinner classes={{ root: classes.savingSpinner }} />
302
+ </div>
303
+ ) : null}
69
304
  </div>
305
+ ) : null;
306
+
307
+ return (
308
+ <Form
309
+ data-cy="GiftOptions-form"
310
+ {...optionsFormProps}
311
+ className={classes.root}
312
+ >
313
+ <FormError errors={Array.from(errors.values())} />
314
+ {includeGiftReceipt}
315
+ {includeGiftMessage}
316
+ {includePrintedCard}
70
317
  </Form>
71
318
  );
72
319
  };
@@ -2,5 +2,60 @@
2
2
  }
3
3
 
4
4
  .option {
5
- padding: 0.5rem 0rem;
5
+ composes: grid from global;
6
+ composes: px-0 from global;
7
+ composes: py-2 from global;
8
+ grid-template-columns: auto min-content;
9
+ }
10
+
11
+ .giftMessageResultContainer,
12
+ .giftMessageFields {
13
+ composes: pb-4 from global;
14
+ composes: pl-8 from global;
15
+ }
16
+
17
+ .giftMessageResultContainer {
18
+ composes: gap-8 from global;
19
+ composes: items-start from global;
20
+
21
+ /* Small */
22
+ composes: sm_flex from global;
23
+ composes: sm_gap-12 from global;
24
+ }
25
+
26
+ .giftMessageResult p {
27
+ padding: 0.25rem 0;
28
+ }
29
+
30
+ .editGiftMessageButton {
31
+ composes: root from '../../../LinkButton/linkButton.module.css';
32
+ composes: mt-4 from global;
33
+
34
+ /* Small */
35
+ composes: sm_mt-2 from global;
36
+ }
37
+
38
+ .giftMessageActions {
39
+ composes: gap-4 from global;
40
+ composes: grid from global;
41
+ composes: mt-4 from global;
42
+
43
+ /* Small */
44
+ composes: sm_flex from global;
45
+ }
46
+
47
+ .savingContainer {
48
+ composes: flex from global;
49
+ composes: items-center from global;
50
+ composes: pl-4 from global;
51
+ composes: text-gray-500 from global;
52
+ }
53
+
54
+ .savingSpinner {
55
+ composes: root from '../../../LoadingIndicator/spinner.module.css';
56
+ composes: ml-2 from global;
57
+ }
58
+
59
+ .hidden {
60
+ composes: hidden from global;
6
61
  }