@ordergroove/offers 2.43.0 → 2.44.1-alpha-PR-1166-3.30

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 (43) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/bundle-report.html +55 -53
  3. package/dist/offers.js +38 -38
  4. package/dist/offers.js.map +4 -4
  5. package/package.json +2 -2
  6. package/src/components/FrequencyStatus.js +13 -10
  7. package/src/components/Offer.js +33 -14
  8. package/src/components/OptinButton.js +2 -2
  9. package/src/components/OptinSelect.js +5 -5
  10. package/src/components/OptinStatus.js +15 -9
  11. package/src/components/Price.js +3 -3
  12. package/src/components/SelectFrequency.js +11 -6
  13. package/src/components/TestWizard.js +45 -41
  14. package/src/components/UpsellModal.js +9 -3
  15. package/src/components/__tests__/Offer.spec.js +0 -19
  16. package/src/components/__tests__/OptinStatus.spec.js +17 -4
  17. package/src/core/__tests__/actions.spec.js +47 -1
  18. package/src/core/__tests__/base.spec.js +0 -77
  19. package/src/core/__tests__/offerRequest.spec.js +2 -1
  20. package/src/core/__tests__/selectors.spec.js +7 -7
  21. package/src/core/actions-preview.js +6 -3
  22. package/src/core/actions.js +22 -13
  23. package/src/core/base.js +0 -23
  24. package/src/core/experiments.js +2 -4
  25. package/src/core/offerRequest.js +1 -1
  26. package/src/core/{reducer.js → reducer.ts} +30 -10
  27. package/src/core/{selectors.js → selectors.ts} +73 -57
  28. package/src/core/types/api.ts +71 -0
  29. package/src/core/types/reducer.ts +95 -0
  30. package/src/core/types/utility.ts +1 -0
  31. package/src/core/utils.ts +32 -15
  32. package/src/make-api.js +1 -1
  33. package/src/shopify/__tests__/productPlan.spec.js +18 -8
  34. package/src/shopify/__tests__/reducers/config.spec.js +497 -0
  35. package/src/shopify/__tests__/shopifyReducer.spec.js +68 -611
  36. package/src/shopify/__tests__/utils.spec.js +68 -1
  37. package/src/shopify/reducers/config.ts +223 -0
  38. package/src/shopify/reducers/productPlans.ts +3 -10
  39. package/src/shopify/shopifyMiddleware.ts +2 -9
  40. package/src/shopify/{shopifyReducer.js → shopifyReducer.ts} +52 -221
  41. package/src/shopify/types/shopify.ts +1 -1
  42. package/src/shopify/utils.ts +70 -0
  43. package/src/types.ts +0 -16
package/src/core/utils.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import platform from '../platform';
2
2
  import { ENV_PROD, ENV_STAGING, STAGING_STATIC_HOST, STATIC_HOST } from './constants';
3
3
  import { isSameProduct } from './selectors';
4
+ import { ConfigState } from './types/reducer';
4
5
 
5
6
  export function onReady(fn) {
6
7
  if (document.readyState === 'loading') {
@@ -47,33 +48,45 @@ export const safeProductId = product => {
47
48
  return productId;
48
49
  };
49
50
 
51
+ type Frequencies = ConfigState['frequencies'];
52
+ type FrequenciesEveryPeriod = ConfigState['frequenciesEveryPeriod'];
53
+
50
54
  /**
51
55
  * Returns the OG frequency if platform is running on selling plans
52
- * @param initialFrequency
53
- * @param config
54
56
  */
55
- export const safeOgFrequency = (initialFrequency, config) => {
57
+ export const safeOgFrequency = (
58
+ initialFrequency: string | null,
59
+ frequencies: Frequencies,
60
+ frequenciesEveryPeriod: FrequenciesEveryPeriod
61
+ ) => {
56
62
  if (platform.shopify_selling_plans) {
57
- const ix = config.frequencies?.indexOf(initialFrequency);
58
- if (ix >= 0 && config.frequenciesEveryPeriod[ix]) {
59
- return config.frequenciesEveryPeriod[ix];
63
+ const ix = frequencies?.indexOf(initialFrequency);
64
+ if (ix >= 0 && frequenciesEveryPeriod[ix]) {
65
+ return frequenciesEveryPeriod[ix];
60
66
  }
61
67
  }
62
68
  return initialFrequency;
63
69
  };
64
70
 
65
- export const frequencyToSellingPlan = (ogFrequency, config) => {
71
+ export const frequencyToSellingPlan = (
72
+ ogFrequency: string,
73
+ frequencyConfig: {
74
+ frequencies: Frequencies;
75
+ frequenciesEveryPeriod: FrequenciesEveryPeriod;
76
+ }
77
+ ) => {
66
78
  // og frequency contains underscore
67
79
  if (!`${ogFrequency}`.includes('_')) return ogFrequency;
68
- const ix = config.frequenciesEveryPeriod?.indexOf(ogFrequency);
69
- if (ix >= 0 && config.frequenciesEveryPeriod[ix]) {
70
- return config.frequencies[ix];
80
+ const { frequencies, frequenciesEveryPeriod } = frequencyConfig;
81
+ const ix = frequenciesEveryPeriod?.indexOf(ogFrequency);
82
+ if (ix >= 0 && frequenciesEveryPeriod[ix]) {
83
+ return frequencies[ix];
71
84
  }
72
85
 
73
86
  // if we can't find the OG frequency, but we have selling plans, return the first selling plan
74
- if (config.frequencies?.length > 0 && config.frequenciesEveryPeriod?.length > 0) {
87
+ if (frequencies?.length > 0 && frequenciesEveryPeriod?.length > 0) {
75
88
  console.warn(`Unable to find selling plan match for frequency ${ogFrequency}; falling back to first selling plan`);
76
- return config.frequencies[0];
89
+ return frequencies[0];
77
90
  }
78
91
 
79
92
  return ogFrequency;
@@ -110,14 +123,18 @@ export function getCookieValue(cookieId) {
110
123
  const cookie = document.cookie.match(`(^|;) ?${cookieId}=([^;]*)(;|$)`);
111
124
  return cookie ? cookie[2] : null;
112
125
  }
113
- export const isOgFrequency = frequency => !!(frequency && frequency?.includes('_'));
126
+ export const isOgFrequency = (frequency: string) => !!(frequency && frequency?.includes('_'));
114
127
 
115
- export const getFirstSellingPlan = (frequencies = []) => frequencies?.[0] || null;
128
+ export const getFirstSellingPlan = (frequencies: string[] = []) => frequencies?.[0] || null;
116
129
 
117
130
  export const hasShopifySellingPlans = (sellingPlans = [], frequenciesEveryPeriod = []) =>
118
131
  !!(platform?.shopify_selling_plans && sellingPlans.length && frequenciesEveryPeriod.length);
119
132
 
120
- export const mapFrequencyToSellingPlan = (sellingPlans, frequenciesEveryPeriod, frequency) => {
133
+ export const mapFrequencyToSellingPlan = (
134
+ sellingPlans: string[],
135
+ frequenciesEveryPeriod: string[],
136
+ frequency: string
137
+ ) => {
121
138
  if (sellingPlans.length !== frequenciesEveryPeriod.length) {
122
139
  return null;
123
140
  }
package/src/make-api.js CHANGED
@@ -164,7 +164,7 @@ export default function makeApi(store) {
164
164
  * @param {*} merchantId
165
165
  * @param {*} env
166
166
  * @param {*} authUrl
167
- * @param {import('./types').MerchantSettings} merchantSettings
167
+ * @param {import('./core/types/api').MerchantSettings} merchantSettings
168
168
  */
169
169
  initialize(merchantId, env, authUrl, merchantSettings = {}) {
170
170
  // settings resolves once, before anything.
@@ -6,9 +6,9 @@ import {
6
6
  getAllocationDiscountRate,
7
7
  addPrepaidPriceAndSavings,
8
8
  mapSellingPlanToDiscount,
9
- getSellingPlans,
10
- DEFAULT_PAY_AS_YOU_GO_GROUP_NAME
9
+ getSellingPlans
11
10
  } from '../reducers/productPlans';
11
+ import { DEFAULT_PAY_AS_YOU_GO_GROUP_NAME } from '../utils';
12
12
 
13
13
  describe('Shopify productPlan Reducer', () => {
14
14
  describe('isPrepaidAllocation', () => {
@@ -329,6 +329,9 @@ describe('Shopify productPlan Reducer', () => {
329
329
  const sellingPlans = [
330
330
  {
331
331
  id: 688412983572,
332
+ group: {
333
+ name: 'Prepaid-'
334
+ },
332
335
  name: 'Delivered every 1 month, prepaid for 3 shipments',
333
336
  description: null,
334
337
  options: [
@@ -410,7 +413,10 @@ describe('Shopify productPlan Reducer', () => {
410
413
  value_type: 'price',
411
414
  value: 4798
412
415
  }
413
- ]
416
+ ],
417
+ group: {
418
+ name: 'Prepaid-'
419
+ }
414
420
  }
415
421
  ];
416
422
 
@@ -462,7 +468,9 @@ describe('Shopify productPlan Reducer', () => {
462
468
  value: 4800
463
469
  }
464
470
  ],
465
- group_name: 'Prepaid-'
471
+ group: {
472
+ name: 'Prepaid-'
473
+ }
466
474
  },
467
475
  {
468
476
  id: 688412983573,
@@ -484,7 +492,9 @@ describe('Shopify productPlan Reducer', () => {
484
492
  value: 10
485
493
  }
486
494
  ],
487
- group_name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME
495
+ group: {
496
+ name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME
497
+ }
488
498
  }
489
499
  ];
490
500
 
@@ -560,7 +570,7 @@ describe('Shopify productPlan Reducer', () => {
560
570
 
561
571
  const expectedSellingPlans = [
562
572
  {
563
- group_name: 'Prepaid-',
573
+ group: product.selling_plan_groups[0],
564
574
  id: 688412721428,
565
575
  options: [
566
576
  {
@@ -576,7 +586,7 @@ describe('Shopify productPlan Reducer', () => {
576
586
  ]
577
587
  },
578
588
  {
579
- group_name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME,
589
+ group: product.selling_plan_groups[1],
580
590
  id: 688412623124,
581
591
  options: [
582
592
  {
@@ -587,7 +597,7 @@ describe('Shopify productPlan Reducer', () => {
587
597
  ]
588
598
  },
589
599
  {
590
- group_name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME,
600
+ group: product.selling_plan_groups[1],
591
601
  id: 688412655892,
592
602
  options: [
593
603
  {
@@ -0,0 +1,497 @@
1
+ import config from '../../reducers/config';
2
+ import * as constants from '../../../core/constants';
3
+ import { DEFAULT_PAY_AS_YOU_GO_GROUP_NAME } from '../../utils';
4
+
5
+ describe('config', () => {
6
+ it('should return unique frequencies given action RECEIVE_PRODUCT_PLANS', () => {
7
+ const actual = config(
8
+ {},
9
+ {
10
+ type: constants.RECEIVE_PRODUCT_PLANS,
11
+ payload: {
12
+ 'product plan id': { '1_1': {}, '3_1': {} }
13
+ }
14
+ }
15
+ );
16
+
17
+ expect(actual).toEqual(
18
+ jasmine.objectContaining({
19
+ frequencies: ['1_1', '3_1']
20
+ })
21
+ );
22
+ });
23
+
24
+ it('should set defaultFrequency to selling plan given selling plan exists for frequency given action SETUP_PRODUCT', () => {
25
+ const actual = config(
26
+ {
27
+ defaultFrequency: '1_2'
28
+ },
29
+ {
30
+ type: constants.SETUP_PRODUCT,
31
+ payload: {
32
+ offer: {
33
+ config: {
34
+ frequencies: ['yum selling plan id 1', 'yum selling plan id 2'],
35
+ frequenciesEveryPeriod: ['1_1', '1_2']
36
+ }
37
+ },
38
+ product: {
39
+ selling_plan_groups: [
40
+ {
41
+ name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME,
42
+ selling_plans: [
43
+ {
44
+ id: 'yum selling plan id 1',
45
+ options: [
46
+ {
47
+ value: '1 day'
48
+ }
49
+ ]
50
+ },
51
+ {
52
+ id: 'yum selling plan id 2',
53
+ options: [
54
+ {
55
+ value: '1 week'
56
+ }
57
+ ]
58
+ }
59
+ ]
60
+ }
61
+ ]
62
+ }
63
+ }
64
+ }
65
+ );
66
+
67
+ expect(actual).toEqual(
68
+ jasmine.objectContaining({
69
+ defaultFrequency: 'yum selling plan id 2'
70
+ })
71
+ );
72
+ });
73
+
74
+ it('should set defaultFrequency to first selling plan given selling plan does not exist for frequency given action SETUP_PRODUCT', () => {
75
+ const actual = config(
76
+ {
77
+ defaultFrequency: '1_3'
78
+ },
79
+ {
80
+ type: constants.SETUP_PRODUCT,
81
+ payload: {
82
+ offer: {
83
+ config: {
84
+ frequencies: ['yum selling plan id 1', 'yum selling plan id 2'],
85
+ frequenciesEveryPeriod: ['1_1', '1_2']
86
+ }
87
+ },
88
+ product: {
89
+ selling_plan_groups: [
90
+ {
91
+ name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME,
92
+ selling_plans: [
93
+ {
94
+ id: 'yum selling plan id 1',
95
+ options: [
96
+ {
97
+ value: '1 day'
98
+ }
99
+ ]
100
+ },
101
+ {
102
+ id: 'yum selling plan id 2',
103
+ options: [
104
+ {
105
+ value: '1 week'
106
+ }
107
+ ]
108
+ }
109
+ ]
110
+ }
111
+ ]
112
+ }
113
+ }
114
+ }
115
+ );
116
+
117
+ expect(actual).toEqual(
118
+ jasmine.objectContaining({
119
+ defaultFrequency: 'yum selling plan id 1'
120
+ })
121
+ );
122
+ });
123
+
124
+ it('should not change default frequency if is already a selling plan given action SETUP_PRODUCT', () => {
125
+ const actual = config(
126
+ {
127
+ defaultFrequency: 'yum selling plan id 5'
128
+ },
129
+ {
130
+ type: constants.SETUP_PRODUCT,
131
+ payload: {
132
+ offer: {
133
+ config: {
134
+ frequencies: ['yum selling plan id 1', 'yum selling plan id 2'],
135
+ frequenciesEveryPeriod: ['1_1', '1_2']
136
+ }
137
+ },
138
+ product: {
139
+ selling_plan_groups: [
140
+ {
141
+ name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME,
142
+ selling_plans: [
143
+ {
144
+ id: 'yum selling plan id 1',
145
+ options: [
146
+ {
147
+ value: '1 day'
148
+ }
149
+ ]
150
+ },
151
+ {
152
+ id: 'yum selling plan id 2',
153
+ options: [
154
+ {
155
+ value: '1 week'
156
+ }
157
+ ]
158
+ }
159
+ ]
160
+ }
161
+ ]
162
+ }
163
+ }
164
+ }
165
+ );
166
+
167
+ expect(actual).toEqual(
168
+ jasmine.objectContaining({
169
+ defaultFrequency: 'yum selling plan id 5'
170
+ })
171
+ );
172
+ });
173
+
174
+ const defaultSellingPlanPayload = {
175
+ product: {
176
+ selling_plan_groups: [
177
+ {
178
+ name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME,
179
+ selling_plans: [
180
+ {
181
+ id: 'yum selling plan id 1'
182
+ },
183
+ {
184
+ id: 'yum selling plan id 2'
185
+ }
186
+ ]
187
+ }
188
+ ]
189
+ }
190
+ };
191
+
192
+ it('should return selling plan ids as frequencies given action SETUP_PRODUCT', () => {
193
+ const actual = config(
194
+ {},
195
+ {
196
+ type: constants.SETUP_PRODUCT,
197
+ payload: defaultSellingPlanPayload
198
+ }
199
+ );
200
+
201
+ expect(actual).toEqual(
202
+ jasmine.objectContaining({
203
+ frequencies: ['yum selling plan id 1', 'yum selling plan id 2'],
204
+ hasProductSpecificFrequencies: false
205
+ })
206
+ );
207
+ });
208
+
209
+ it('should return values of first OG selling plan group as frequencies text given action SETUP_PRODUCT', () => {
210
+ const actual = config(
211
+ {},
212
+ {
213
+ type: constants.SETUP_PRODUCT,
214
+ payload: {
215
+ product: {
216
+ selling_plan_groups: [
217
+ {
218
+ name: 'Old Selling Plan Group',
219
+ options: [{ values: 'old yum values' }],
220
+ selling_plans: [
221
+ {
222
+ id: 'old yum selling plan id'
223
+ }
224
+ ]
225
+ },
226
+ {
227
+ name: DEFAULT_PAY_AS_YOU_GO_GROUP_NAME,
228
+ options: [{ values: 'yum values' }],
229
+ selling_plans: [
230
+ {
231
+ id: 'yum selling plan id'
232
+ }
233
+ ]
234
+ }
235
+ ]
236
+ }
237
+ }
238
+ }
239
+ );
240
+
241
+ expect(actual).toEqual(
242
+ jasmine.objectContaining({
243
+ frequenciesText: 'yum values'
244
+ })
245
+ );
246
+ });
247
+
248
+ it('should use product-specific frequency selling plan groups if present', () => {
249
+ const actual = config(
250
+ {},
251
+ {
252
+ type: constants.SETUP_PRODUCT,
253
+ payload: {
254
+ product: {
255
+ selling_plan_groups: [
256
+ {
257
+ name: 'og_psfl_2m4m6m',
258
+ options: [
259
+ {
260
+ values: ['2 months', '4 months', '6 months']
261
+ }
262
+ ],
263
+ selling_plans: [
264
+ {
265
+ id: 'psfl-id-1'
266
+ },
267
+ {
268
+ id: 'psfl-id-2'
269
+ },
270
+ {
271
+ id: 'psfl-id-3'
272
+ }
273
+ ]
274
+ },
275
+ {
276
+ name: 'Subscribe and Save',
277
+ options: [
278
+ {
279
+ values: ['month', '2 months', '3 months']
280
+ }
281
+ ],
282
+ selling_plans: [
283
+ {
284
+ id: 'regular-id-1'
285
+ },
286
+ {
287
+ id: 'regular-id-2'
288
+ },
289
+ {
290
+ id: 'regular-id-3'
291
+ }
292
+ ]
293
+ }
294
+ ]
295
+ }
296
+ }
297
+ }
298
+ );
299
+
300
+ expect(actual).toEqual(
301
+ jasmine.objectContaining({
302
+ frequencies: ['psfl-id-1', 'psfl-id-2', 'psfl-id-3'],
303
+ hasProductSpecificFrequencies: true
304
+ })
305
+ );
306
+ });
307
+
308
+ it('does not overwrite hasProductSpecificFrequencies on subsequent calls', () => {
309
+ const actual = config(
310
+ {
311
+ hasProductSpecificFrequencies: true
312
+ },
313
+ {
314
+ type: constants.SETUP_PRODUCT,
315
+ payload: defaultSellingPlanPayload
316
+ }
317
+ );
318
+
319
+ expect(actual).toEqual(
320
+ jasmine.objectContaining({
321
+ hasProductSpecificFrequencies: true
322
+ })
323
+ );
324
+ });
325
+
326
+ it('should set prepaidSellingPlans', () => {
327
+ const sellingPlanGroups = [
328
+ {
329
+ name: 'Prepaid-43017264201944',
330
+ selling_plans: [
331
+ {
332
+ id: 2146042072,
333
+ name: 'Delivered every 2 months, prepaid for 4 shipments',
334
+ options: [
335
+ { name: 'Delivery every', position: 1, value: 'PREPAID-2 months' },
336
+ { name: 'Shipment amount', position: 2, value: '4 shipments' }
337
+ ]
338
+ }
339
+ ]
340
+ }
341
+ ];
342
+ const actual = config(
343
+ {},
344
+ {
345
+ type: constants.SETUP_PRODUCT,
346
+ payload: {
347
+ product: {
348
+ selling_plan_groups: sellingPlanGroups
349
+ }
350
+ }
351
+ }
352
+ );
353
+ expect(actual).toEqual(
354
+ jasmine.objectContaining({
355
+ prepaidSellingPlans: {
356
+ 43017264201944: [
357
+ {
358
+ numberShipments: 4,
359
+ sellingPlan: '2146042072'
360
+ }
361
+ ]
362
+ }
363
+ })
364
+ );
365
+ });
366
+
367
+ it('should add prepaidSellingPlans on top of old ones', () => {
368
+ const sellingPlanGroups = [
369
+ {
370
+ name: 'Prepaid-43017264201946',
371
+ selling_plans: [
372
+ {
373
+ id: 2146042072,
374
+ name: 'Delivered every 1 months, prepaid for 3 shipments',
375
+ options: [
376
+ { name: 'Delivery every', position: 1, value: 'PREPAID-1 months' },
377
+ { name: 'Shipment amount', position: 2, value: '3 shipments' }
378
+ ]
379
+ }
380
+ ]
381
+ },
382
+ {
383
+ name: 'Prepaid-43017264201945',
384
+ selling_plans: [
385
+ {
386
+ id: 2146042073,
387
+ name: 'Delivered every 3 months, prepaid for 5 shipments',
388
+ options: [
389
+ { name: 'Delivery every', position: 1, value: 'PREPAID-3 months' },
390
+ { name: 'Shipment amount', position: 2, value: '5 shipments' }
391
+ ]
392
+ }
393
+ ]
394
+ }
395
+ ];
396
+ const actual = config(
397
+ {
398
+ prepaidSellingPlans: {
399
+ 43017264201946: [
400
+ {
401
+ numberShipments: 1,
402
+ sellingPlan: '2146042072'
403
+ }
404
+ ],
405
+ 43017264201944: [
406
+ {
407
+ numberShipments: 4,
408
+ sellingPlan: '2146042071'
409
+ }
410
+ ]
411
+ }
412
+ },
413
+ {
414
+ type: constants.SETUP_PRODUCT,
415
+ payload: {
416
+ product: {
417
+ selling_plan_groups: sellingPlanGroups
418
+ }
419
+ }
420
+ }
421
+ );
422
+ expect(actual).toEqual(
423
+ jasmine.objectContaining({
424
+ prepaidSellingPlans: {
425
+ 43017264201944: [
426
+ {
427
+ numberShipments: 4,
428
+ sellingPlan: '2146042071'
429
+ }
430
+ ],
431
+ 43017264201946: [
432
+ {
433
+ numberShipments: 3,
434
+ sellingPlan: '2146042072'
435
+ }
436
+ ],
437
+ 43017264201945: [
438
+ {
439
+ numberShipments: 5,
440
+ sellingPlan: '2146042073'
441
+ }
442
+ ]
443
+ }
444
+ })
445
+ );
446
+ });
447
+
448
+ it('should return unmodified state given unsupported action', () => {
449
+ const actual = config(
450
+ { 'yum existing key': 'yum existing value' },
451
+ {
452
+ type: 'yum unsupported action',
453
+ payload: {}
454
+ }
455
+ );
456
+
457
+ expect(actual).toEqual({ 'yum existing key': 'yum existing value' });
458
+ });
459
+
460
+ it('should not set prepaid selling plan as a defaultFrequency', () => {
461
+ const initial = {
462
+ frequencies: ['yum selling plan id 1', 'yum selling plan id 4'],
463
+ frequenciesEveryPeriod: ['1_1', '1_4'],
464
+ prepaidSellingPlans: {
465
+ 123: [
466
+ {
467
+ sellingPlan: 'prepaid selling plan'
468
+ }
469
+ ]
470
+ },
471
+ productFrequencies: {
472
+ 123: {
473
+ frequencies: ['yum selling plan id 1', 'yum selling plan id 4'],
474
+ frequenciesEveryPeriod: ['1_1', '1_4']
475
+ }
476
+ }
477
+ };
478
+ const actual = config(initial, {
479
+ type: constants.RECEIVE_OFFER,
480
+ payload: {
481
+ offer: {
482
+ product: { id: 123 },
483
+ defaultFrequency: 'prepaid selling plan'
484
+ }
485
+ }
486
+ });
487
+ expect(actual).toEqual({
488
+ ...initial,
489
+ defaultFrequency: 'yum selling plan id 1',
490
+ productFrequencies: {
491
+ 123: jasmine.objectContaining({
492
+ defaultFrequency: 'yum selling plan id 1'
493
+ })
494
+ }
495
+ });
496
+ });
497
+ });