@ordergroove/offers 2.29.0 → 2.29.1-alpha-PR-707-2.113

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 (37) hide show
  1. package/README.md +22 -1
  2. package/dist/bundle-report.html +72 -59
  3. package/dist/examples.js +262 -105
  4. package/dist/examples.js.map +2 -2
  5. package/dist/offers.js +82 -32
  6. package/dist/offers.js.map +3 -3
  7. package/examples/index.js +230 -218
  8. package/package.json +2 -2
  9. package/src/components/PrepaidData.js +110 -0
  10. package/src/components/PrepaidToggle.js +108 -0
  11. package/src/components/Price.js +6 -6
  12. package/src/components/Select.js +6 -1
  13. package/src/components/__tests__/PrepaidData.spec.js +173 -0
  14. package/src/components/__tests__/PrepaidToggle.spec.js +115 -0
  15. package/src/components/__tests__/Price.spec.js +96 -0
  16. package/src/core/__tests__/adapters.spec.js +232 -1
  17. package/src/core/__tests__/descriptors.spec.js +56 -0
  18. package/src/core/__tests__/reducer.spec.js +153 -1
  19. package/src/core/__tests__/selectors.spec.js +34 -1
  20. package/src/core/actions.js +5 -0
  21. package/src/core/adapters.js +48 -2
  22. package/src/core/constants.js +1 -0
  23. package/src/core/descriptors.js +7 -1
  24. package/src/core/reducer.js +35 -14
  25. package/src/core/selectors.js +32 -0
  26. package/src/core/utils.ts +16 -0
  27. package/src/make-api.js +4 -0
  28. package/src/shopify/__tests__/productPlan.spec.js +513 -0
  29. package/src/shopify/__tests__/shopifyReducer.spec.js +630 -19
  30. package/src/shopify/__tests__/utils.spec.js +25 -0
  31. package/src/shopify/reducers/productPlans.ts +134 -0
  32. package/src/shopify/shopifyMiddleware.ts +3 -0
  33. package/src/shopify/shopifyReducer.js +96 -47
  34. package/src/shopify/shopifyTrackingMiddleware.ts +1 -1
  35. package/src/shopify/types/productPlan.ts +11 -0
  36. package/src/shopify/types/shopify.ts +98 -0
  37. package/src/shopify/utils.ts +3 -0
@@ -3,7 +3,8 @@ import { combineReducers } from 'redux';
3
3
  import * as constants from './constants';
4
4
  import { isSameProduct } from './selectors';
5
5
  import { stringifyFrequency } from './api';
6
- import { safeProductId } from './utils';
6
+ import { getObjectStructuredProductPlans } from './adapters';
7
+ import { safeProductId, getMatchingProductIfExists } from './utils';
7
8
 
8
9
  export const optedin = (state = [], action) => {
9
10
  switch (action.type) {
@@ -12,16 +13,26 @@ export const optedin = (state = [], action) => {
12
13
  case constants.LOCAL_STORAGE_CHANGE:
13
14
  return action.newValue ? action.newValue.optedin : state;
14
15
  case constants.OPTIN_PRODUCT:
15
- case constants.PRODUCT_CHANGE_FREQUENCY:
16
- const [[oldone], rest] = state.reduce(
17
- (acc, val) => acc[isSameProduct(action.payload.product, val) ? 0 : 1].push(val) && acc,
18
- [[], []]
19
- );
20
- return (rest || []).concat({
16
+ case constants.PRODUCT_CHANGE_FREQUENCY: {
17
+ // since prepaid maps to a different set of frequencies, we remove prepaidShipments when frequency is changed
18
+ const [{ prepaidShipments, ...oldone }, rest] = getMatchingProductIfExists(state, action.payload.product);
19
+ return rest.concat({
21
20
  ...oldone,
22
21
  ...action.payload.product,
23
22
  frequency: action.payload.frequency
24
23
  });
24
+ }
25
+ case constants.PRODUCT_CHANGE_PREPAID_SHIPMENTS:
26
+ const { payload } = action;
27
+ const [{ prepaidShipments, ...oldone }, rest] = getMatchingProductIfExists(state, payload.product);
28
+ const newState = {
29
+ ...oldone,
30
+ ...payload.product
31
+ };
32
+ if (payload.prepaidShipments) {
33
+ newState.prepaidShipments = payload.prepaidShipments;
34
+ }
35
+ return rest.concat(newState);
25
36
  case constants.OPTOUT_PRODUCT:
26
37
  return state.filter(a => !isSameProduct(action.payload.product, a));
27
38
  case constants.PRODUCT_HAS_CHANGED:
@@ -47,11 +58,8 @@ export const optedout = (state = [], action) => {
47
58
  case constants.PRODUCT_CHANGE_FREQUENCY:
48
59
  return state.filter(a => !isSameProduct(action.payload.product, a));
49
60
  case constants.OPTOUT_PRODUCT:
50
- const [[oldone], rest] = state.reduce(
51
- (acc, val) => acc[isSameProduct(action.payload.product, val) ? 0 : 1].push(val) && acc,
52
- [[], []]
53
- );
54
- return (rest || []).concat({
61
+ const [oldone, rest] = getMatchingProductIfExists(state, action.payload.product);
62
+ return rest.concat({
55
63
  ...oldone,
56
64
  ...action.payload.product,
57
65
  frequency: action.payload.frequency
@@ -451,7 +459,19 @@ export const templates = (state = [], action) => {
451
459
  export const productPlans = (state = {}, action) => {
452
460
  switch (action.type) {
453
461
  case constants.RECEIVE_PRODUCT_PLANS:
454
- return { ...action.payload };
462
+ return getObjectStructuredProductPlans(action.payload);
463
+ default:
464
+ return state;
465
+ }
466
+ };
467
+
468
+ export const prepaidShipmentsSelected = (state = {}, action) => {
469
+ switch (action.type) {
470
+ case constants.PRODUCT_CHANGE_PREPAID_SHIPMENTS:
471
+ if (action.payload.prepaidShipments) {
472
+ return { ...state, [action.payload.product.id]: action.payload.prepaidShipments };
473
+ }
474
+ return state;
455
475
  default:
456
476
  return state;
457
477
  }
@@ -483,5 +503,6 @@ export default combineReducers({
483
503
  autoshipByDefault,
484
504
  defaultFrequencies,
485
505
  templates,
486
- productPlans
506
+ productPlans,
507
+ prepaidShipmentsSelected
487
508
  });
@@ -60,6 +60,9 @@ export const sellingPlansSelector = state => state?.config?.frequencies || [];
60
60
 
61
61
  export const frequenciesEveryPeriodSelector = state => state?.config?.frequenciesEveryPeriod || [];
62
62
 
63
+ export const prepaidSellingPlansSelector = state => state?.config?.prepaidSellingPlans || [];
64
+ export const prepaidShipmentsSelectedSelector = state => state?.prepaidShipmentsSelected || {};
65
+
63
66
  /**
64
67
  * Creates a function with state arguments that return the true when
65
68
  * productId is in the optedin array or not in optedout or autoship by default
@@ -99,6 +102,21 @@ export const makeSubscribedSelector = memoize(
99
102
  product => JSON.stringify(product)
100
103
  );
101
104
 
105
+ export const makePrepaidSubscribedSelector = memoize(
106
+ product =>
107
+ createSelector(optedinSelector, optedin => optedin.some(b => isSameProduct(product, b) && b.prepaidShipments)),
108
+ product => JSON.stringify(product)
109
+ );
110
+
111
+ export const makePrepaidShipmentsSelectedSelector = memoize(
112
+ product =>
113
+ createSelector(
114
+ prepaidShipmentsSelectedSelector,
115
+ prepaidShipmentsSelected => prepaidShipmentsSelected[product.id] || null
116
+ ),
117
+ product => JSON.stringify(product)
118
+ );
119
+
102
120
  /**
103
121
  * Creates a function with state arguments that return the true when
104
122
  * productId is in the optedout array
@@ -114,6 +132,20 @@ export const makeProductFrequencySelector = memoize(productId =>
114
132
  createSelector(makeOptedinSelector(productId), productOptin => (productOptin && productOptin.frequency) || null)
115
133
  );
116
134
 
135
+ export const makeProductPrepaidShipmentsOptedInSelector = memoize(productId =>
136
+ createSelector(
137
+ makeOptedinSelector(productId),
138
+ productOptin => (productOptin && productOptin.prepaidShipments) || null
139
+ )
140
+ );
141
+
142
+ export const makeProductPrepaidShipmentOptionsSelector = memoize(productId =>
143
+ createSelector(
144
+ prepaidSellingPlansSelector,
145
+ prepaidSellingPlans => prepaidSellingPlans[productId]?.map(({ numberShipments }) => numberShipments) || []
146
+ )
147
+ );
148
+
117
149
  /**
118
150
  * Creates a function with state arguments that returns stringified frequency
119
151
  * if default frequency exists for the product
package/src/core/utils.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import platform from '../platform';
2
2
  import { ENV_PROD, ENV_STAGING, STAGING_STATIC_HOST, STATIC_HOST } from './constants';
3
+ import { isSameProduct } from './selectors';
3
4
 
4
5
  export function onReady(fn) {
5
6
  if (document.readyState === 'loading') {
@@ -140,3 +141,18 @@ export function getOrCreateHidden(parent, name, value) {
140
141
  input.value = value;
141
142
  }
142
143
  }
144
+
145
+ /**
146
+ * Returns the first matching product if it exists, or an empty object if it doesn't.
147
+ * @param state - the optedin/optedout state array to search
148
+ * @param product - the product to search for
149
+ * @returns {[any, any[]]} - a two item array where the first item is the matching product and the second is the remaining items from the original state.
150
+ */
151
+ export function getMatchingProductIfExists(state, product) {
152
+ const [[oldone], rest] = state.reduce((acc, val) => acc[isSameProduct(product, val) ? 0 : 1].push(val) && acc, [
153
+ [],
154
+ []
155
+ ]);
156
+
157
+ return [oldone || {}, rest || []];
158
+ }
package/src/make-api.js CHANGED
@@ -20,6 +20,8 @@ import { Modal } from './components/Modal';
20
20
  import { Select } from './components/Select';
21
21
  import { Tooltip } from './components/Tooltip';
22
22
  import { ConnectedFrequencyStatus } from './components/FrequencyStatus';
23
+ import { ConnectedPrepaidToggle } from './components/PrepaidToggle';
24
+ import { ConnectedPrepaidData } from './components/PrepaidData';
23
25
  import * as testMode from './test-mode';
24
26
  import { api } from './core/api';
25
27
  import { environment, offer } from './core/reducer';
@@ -51,6 +53,8 @@ export default function makeApi(store) {
51
53
  customElements.define('og-upsell-modal', ConnectedUpsellModal);
52
54
  customElements.define('og-next-upcoming-order', ConnectedNextUpcomingOrder);
53
55
  customElements.define('og-price', ConnectedPrice);
56
+ customElements.define('og-prepaid-toggle', ConnectedPrepaidToggle);
57
+ customElements.define('og-prepaid-data', ConnectedPrepaidData);
54
58
  } catch (err) {
55
59
  console.info('OG WebComponents already registered, skipping.');
56
60
  }
@@ -0,0 +1,513 @@
1
+ import {
2
+ isPrepaidAllocation,
3
+ getPrepaidShipmentsNumberFromOptions,
4
+ getAllocationFrequency,
5
+ getAllocationSubscriptionPrice,
6
+ getAllocationDiscountRate,
7
+ addPrepaidPriceAndSavings,
8
+ mapSellingPlanToDiscount,
9
+ getSellingPlans,
10
+ DEFAULT_PAY_AS_YOU_GO_GROUP_NAME
11
+ } from '../reducers/productPlans';
12
+
13
+ describe('Shopify productPlan Reducer', () => {
14
+ describe('isPrepaidAllocation', () => {
15
+ it('should return true if there is prepaid option', () => {
16
+ const allocation = {
17
+ selling_plan: {
18
+ options: [
19
+ {
20
+ name: 'Delivery every',
21
+ position: 1,
22
+ value: 'PREPAID-1 month'
23
+ },
24
+ {
25
+ name: 'Shipment amount',
26
+ position: 2,
27
+ value: '3 shipments'
28
+ }
29
+ ]
30
+ }
31
+ };
32
+ expect(isPrepaidAllocation(allocation)).toBeTruthy();
33
+ });
34
+
35
+ it('should return false if there is no prepaid option', () => {
36
+ const allocation = {
37
+ selling_plan: {
38
+ options: [
39
+ {
40
+ name: 'Delivery every',
41
+ position: 1,
42
+ value: '1 month'
43
+ }
44
+ ]
45
+ }
46
+ };
47
+ expect(isPrepaidAllocation(allocation)).toBeFalsy();
48
+ });
49
+ });
50
+
51
+ describe('getPrepaidShipmentsNumberFromOptions', () => {
52
+ it('should return number of shipments as number', () => {
53
+ const options = [
54
+ {
55
+ name: 'Delivery every',
56
+ position: 1,
57
+ value: 'PREPAID-1 month'
58
+ },
59
+ {
60
+ name: 'Shipment amount',
61
+ position: 2,
62
+ value: '3 shipments'
63
+ }
64
+ ];
65
+ expect(getPrepaidShipmentsNumberFromOptions(options)).toBe(3);
66
+ });
67
+
68
+ it('should return null when getting shipments from a non prepaid selling plan', () => {
69
+ const options = [
70
+ {
71
+ name: 'Delivery every',
72
+ position: 1,
73
+ value: '1 month'
74
+ }
75
+ ];
76
+ expect(getPrepaidShipmentsNumberFromOptions(options)).toBe(null);
77
+ });
78
+ });
79
+
80
+ describe('getAllocationFrequency', () => {
81
+ it('should return frequency as selling-plan-id for allocation with selling_plan_id', () => {
82
+ const allocation = {
83
+ selling_plan_id: 123456789
84
+ };
85
+ expect(getAllocationFrequency(allocation)).toBe('123456789');
86
+ });
87
+
88
+ it('should return frequency as selling-plan-id for allocation with selling_plan object', () => {
89
+ const allocation = {
90
+ selling_plan: { id: 123456789 }
91
+ };
92
+ expect(getAllocationFrequency(allocation)).toBe('123456789');
93
+ });
94
+ });
95
+
96
+ describe('getAllocationSubscriptionPrice', () => {
97
+ it('should return money price for pay-as-you-go subscription', () => {
98
+ const allocation = {
99
+ price: 1350
100
+ };
101
+ expect(getAllocationSubscriptionPrice(allocation)).toBe('$13.50');
102
+ });
103
+
104
+ it('should return per delivery money price for prepaid subscription', () => {
105
+ const allocation = {
106
+ price: 3000,
107
+ selling_plan: {
108
+ options: [
109
+ {
110
+ name: 'Delivery every',
111
+ position: 1,
112
+ value: 'PREPAID-1 month'
113
+ },
114
+ {
115
+ name: 'Shipment amount',
116
+ position: 2,
117
+ value: '3 shipments'
118
+ }
119
+ ]
120
+ }
121
+ };
122
+ expect(getAllocationSubscriptionPrice(allocation)).toBe('$10.00');
123
+ });
124
+ });
125
+
126
+ describe('getAllocationDiscountRate', () => {
127
+ it('should return discount for pay-as-you-go subscription as percentage', () => {
128
+ const allocation = {
129
+ price_adjustments: [{ position: 1, value: 10, value_type: 'percentage' }]
130
+ };
131
+ expect(getAllocationDiscountRate(allocation)).toBe('10%');
132
+ });
133
+
134
+ it('should return discount for pay-as-you-go subscription from price adjustment', () => {
135
+ const allocation = {
136
+ price_adjustments: [{ position: 1, value: 1050 }]
137
+ };
138
+ expect(getAllocationDiscountRate(allocation)).toBe('$10.50');
139
+ });
140
+
141
+ it('should return discount for pay-as-you-go subscription from compare_at_price', () => {
142
+ const allocation = {
143
+ compare_at_price: 1350,
144
+ price: 1200,
145
+ price_adjustments: []
146
+ };
147
+ expect(getAllocationDiscountRate(allocation)).toBe('$1.50');
148
+ });
149
+
150
+ it('should return prepaid percentage discount when prepaid options are present - 3 shipments', () => {
151
+ const allocation = {
152
+ compare_at_price: 1500,
153
+ price: 3600,
154
+ selling_plan: {
155
+ options: [
156
+ {
157
+ name: 'Delivery every',
158
+ position: 1,
159
+ value: 'PREPAID-1 month'
160
+ },
161
+ {
162
+ name: 'Shipment amount',
163
+ position: 2,
164
+ value: '3 shipments'
165
+ }
166
+ ]
167
+ }
168
+ };
169
+ expect(getAllocationDiscountRate(allocation)).toBe('20%');
170
+ });
171
+
172
+ it('should return prepaid percentage discount when prepaid options are present - 12 shipments', () => {
173
+ const allocation = {
174
+ compare_at_price: 1500,
175
+ price: 13500,
176
+ selling_plan: {
177
+ options: [
178
+ {
179
+ name: 'Delivery every',
180
+ position: 1,
181
+ value: 'PREPAID-1 month'
182
+ },
183
+ {
184
+ name: 'Shipment amount',
185
+ position: 2,
186
+ value: '12 shipments'
187
+ }
188
+ ]
189
+ }
190
+ };
191
+ expect(getAllocationDiscountRate(allocation)).toBe('25%');
192
+ });
193
+ });
194
+
195
+ describe('addPrepaidPriceAndSavings', () => {
196
+ it('should add more prepaid data when selling plan is prepaid', () => {
197
+ const allocation = {
198
+ price: 2400,
199
+ compare_at_price: 500,
200
+ selling_plan: {
201
+ options: [
202
+ {
203
+ name: 'Delivery every',
204
+ position: 1,
205
+ value: 'PREPAID-1 month'
206
+ },
207
+ {
208
+ name: 'Shipment amount',
209
+ position: 2,
210
+ value: '6 shipments'
211
+ }
212
+ ]
213
+ }
214
+ };
215
+
216
+ const productPlan = {
217
+ frequency: '688412852500',
218
+ regularPrice: '$5.00',
219
+ subscriptionPrice: '$4.00',
220
+ discountRate: '20%',
221
+ prepaidShipments: 6
222
+ };
223
+
224
+ const expectedProductPlan = {
225
+ frequency: '688412852500',
226
+ regularPrice: '$5.00',
227
+ subscriptionPrice: '$4.00',
228
+ discountRate: '20%',
229
+ prepaidShipments: 6,
230
+ regularPrepaidPrice: '$24.00',
231
+ prepaidSavingsPerShipment: '$1.00',
232
+ prepaidSavingsTotal: '$6.00'
233
+ };
234
+
235
+ const newProductPlan = addPrepaidPriceAndSavings(allocation, productPlan);
236
+
237
+ expect(newProductPlan).toEqual(expectedProductPlan);
238
+ });
239
+ });
240
+
241
+ describe('mapSellingPlanToDiscount', () => {
242
+ it('should create pay-as-you-go product plan', () => {
243
+ const allocation = {
244
+ price_adjustments: [
245
+ {
246
+ position: 1,
247
+ price: 450
248
+ }
249
+ ],
250
+ price: 450,
251
+ compare_at_price: 500,
252
+ per_delivery_price: 450,
253
+ selling_plan_id: 688412655892,
254
+ selling_plan_group_id: 'f0c2b41b7b770c58287b7e02da5a2f4df4605c7b'
255
+ };
256
+
257
+ const expectedProductPlan = {
258
+ frequency: '688412655892',
259
+ regularPrice: '$5.00',
260
+ subscriptionPrice: '$4.50',
261
+ discountRate: '$.50',
262
+ prepaidShipments: null
263
+ };
264
+
265
+ const productPlanCreated = mapSellingPlanToDiscount(allocation);
266
+
267
+ expect(productPlanCreated).toEqual(expectedProductPlan);
268
+ });
269
+
270
+ it('should create prepaid product plan', () => {
271
+ const allocation = {
272
+ price_adjustments: [
273
+ {
274
+ position: 1,
275
+ price: 4800
276
+ }
277
+ ],
278
+ price: 4800,
279
+ compare_at_price: 2000,
280
+ per_delivery_price: 4800,
281
+ selling_plan_id: 688412983572,
282
+ selling_plan_group_id: '78cc7d24bc5c4f3000c0d86f2d514e066c4b9fd2'
283
+ };
284
+
285
+ const sellingPlans = [
286
+ {
287
+ id: 688412983572,
288
+ name: 'Delivered every 1 month, prepaid for 3 shipments',
289
+ description: null,
290
+ options: [
291
+ {
292
+ name: 'Delivery every',
293
+ position: 1,
294
+ value: 'PREPAID-1 month'
295
+ },
296
+ {
297
+ name: 'Shipment amount',
298
+ position: 2,
299
+ value: '3 shipments'
300
+ }
301
+ ],
302
+ recurring_deliveries: true,
303
+ price_adjustments: [
304
+ {
305
+ order_count: null,
306
+ position: 1,
307
+ value_type: 'price',
308
+ value: 4800
309
+ }
310
+ ]
311
+ }
312
+ ];
313
+
314
+ const expectedProductPlan = {
315
+ frequency: '688412983572',
316
+ regularPrice: '$20.00',
317
+ subscriptionPrice: '$16.00',
318
+ discountRate: '20%',
319
+ prepaidShipments: 3,
320
+ regularPrepaidPrice: '$48.00',
321
+ prepaidSavingsPerShipment: '$4.00',
322
+ prepaidSavingsTotal: '$12.00'
323
+ };
324
+
325
+ const productPlanCreated = mapSellingPlanToDiscount(allocation, sellingPlans);
326
+
327
+ expect(productPlanCreated).toEqual(expectedProductPlan);
328
+ });
329
+
330
+ it('should create prepaid product plan with extra discount percentage', () => {
331
+ const allocation = {
332
+ price_adjustments: [
333
+ {
334
+ position: 1,
335
+ price: 4800
336
+ }
337
+ ],
338
+ price: 4800,
339
+ compare_at_price: 2000,
340
+ per_delivery_price: 4800,
341
+ selling_plan_id: 688412983572,
342
+ selling_plan_group_id: '78cc7d24bc5c4f3000c0d86f2d514e066c4b9fd2'
343
+ };
344
+
345
+ const sellingPlans = [
346
+ {
347
+ id: 688412983572,
348
+ name: 'Delivered every 1 month, prepaid for 3 shipments',
349
+ description: null,
350
+ options: [
351
+ {
352
+ name: 'Delivery every',
353
+ position: 1,
354
+ value: 'PREPAID-1 month'
355
+ },
356
+ {
357
+ name: 'Shipment amount',
358
+ position: 2,
359
+ value: '3 shipments'
360
+ }
361
+ ],
362
+ recurring_deliveries: true,
363
+ price_adjustments: [
364
+ {
365
+ order_count: null,
366
+ position: 1,
367
+ value_type: 'price',
368
+ value: 4800
369
+ }
370
+ ],
371
+ group_name: 'Prepaid-'
372
+ },
373
+ {
374
+ id: 688412983573,
375
+ name: 'Delivered every month. Get 10% off today and all future orders.',
376
+ description: null,
377
+ options: [
378
+ {
379
+ name: 'Delivery every',
380
+ position: 1,
381
+ value: '1 month'
382
+ }
383
+ ],
384
+ recurring_deliveries: true,
385
+ price_adjustments: [
386
+ {
387
+ order_count: null,
388
+ position: 1,
389
+ value_type: 'percentage',
390
+ value: 10
391
+ }
392
+ ],
393
+ group_name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME
394
+ }
395
+ ];
396
+
397
+ const expectedProductPlan = {
398
+ frequency: '688412983572',
399
+ regularPrice: '$20.00',
400
+ subscriptionPrice: '$16.00',
401
+ discountRate: '20%',
402
+ prepaidShipments: 3,
403
+ regularPrepaidPrice: '$48.00',
404
+ prepaidSavingsPerShipment: '$4.00',
405
+ prepaidSavingsTotal: '$12.00',
406
+ prepaidExtraSavingsPercentage: '10%'
407
+ };
408
+
409
+ const productPlanCreated = mapSellingPlanToDiscount(allocation, sellingPlans);
410
+
411
+ expect(productPlanCreated).toEqual(expectedProductPlan);
412
+ });
413
+ });
414
+
415
+ describe('getSellingPlans', () => {
416
+ it('should convert selling plan groups to selling plan', () => {
417
+ const product = {
418
+ selling_plan_groups: [
419
+ {
420
+ name: 'Prepaid-',
421
+ selling_plans: [
422
+ {
423
+ id: 688412721428,
424
+ options: [
425
+ {
426
+ name: 'Delivery every',
427
+ position: 1,
428
+ value: 'PREPAID-1 month'
429
+ },
430
+ {
431
+ name: 'Shipment amount',
432
+ position: 2,
433
+ value: '3 shipments'
434
+ }
435
+ ]
436
+ }
437
+ ]
438
+ },
439
+ {
440
+ name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME,
441
+ selling_plans: [
442
+ {
443
+ id: 688412623124,
444
+ options: [
445
+ {
446
+ name: 'Delivery every',
447
+ position: 1,
448
+ value: 'month'
449
+ }
450
+ ]
451
+ },
452
+ {
453
+ id: 688412655892,
454
+ options: [
455
+ {
456
+ name: 'Delivery every',
457
+ position: 1,
458
+ value: '2 months'
459
+ }
460
+ ]
461
+ }
462
+ ]
463
+ }
464
+ ]
465
+ };
466
+
467
+ const expectedSellingPlans = [
468
+ {
469
+ group_name: 'Prepaid-',
470
+ id: 688412721428,
471
+ options: [
472
+ {
473
+ name: 'Delivery every',
474
+ position: 1,
475
+ value: 'PREPAID-1 month'
476
+ },
477
+ {
478
+ name: 'Shipment amount',
479
+ position: 2,
480
+ value: '3 shipments'
481
+ }
482
+ ]
483
+ },
484
+ {
485
+ group_name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME,
486
+ id: 688412623124,
487
+ options: [
488
+ {
489
+ name: 'Delivery every',
490
+ position: 1,
491
+ value: 'month'
492
+ }
493
+ ]
494
+ },
495
+ {
496
+ group_name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME,
497
+ id: 688412655892,
498
+ options: [
499
+ {
500
+ name: 'Delivery every',
501
+ position: 1,
502
+ value: '2 months'
503
+ }
504
+ ]
505
+ }
506
+ ];
507
+
508
+ const sellingPlans = getSellingPlans(product);
509
+
510
+ expect(sellingPlans).toEqual(expectedSellingPlans);
511
+ });
512
+ });
513
+ });