@ordergroove/offers 2.47.2-alpha-PR-1356-3.33 → 2.47.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ordergroove/offers",
3
- "version": "2.47.2-alpha-PR-1356-3.33+ee810ebfe",
3
+ "version": "2.47.2",
4
4
  "description": "offer state component",
5
5
  "author": "Eugenio Lattanzio <eugenio63@gmail.com>",
6
6
  "homepage": "https://github.com/ordergroove/plush-toys#readme",
@@ -49,5 +49,5 @@
49
49
  "@ordergroove/offers-templates": "^0.10.0",
50
50
  "@types/lodash.memoize": "^4.1.9"
51
51
  },
52
- "gitHead": "ee810ebfe69c9a4aae3d7dbf2624cf4ef49324e6"
52
+ "gitHead": "b039a0b5286ac8736eb4501b4763512f27e58953"
53
53
  }
@@ -109,6 +109,9 @@ export class IncentiveText extends withProduct(LitElement) {
109
109
  // we only have criteria if the incentive is standardized
110
110
  incentive.criteria &&
111
111
  incentive.criteria.node_type === 'PREMISE' &&
112
+ // prefer to show non-threshold discounts
113
+ // we don't currently evaluate thresholds, so we don't know if they apply or not (especially if it's order-level)
114
+ !incentive.threshold_field &&
112
115
  preferredIncentiveStandards.includes(incentive.criteria.standard)
113
116
  );
114
117
 
@@ -7,7 +7,6 @@ import {
7
7
  } from '../core/selectors';
8
8
  import { productChangePrepaidShipments } from '../core/actions';
9
9
  import { withProduct } from '../core/resolveProperties';
10
- import { getDefaultPrepaidOption } from '../shopify/utils';
11
10
 
12
11
  export class PrepaidStatus extends withProduct(LitElement) {
13
12
  static get properties() {
@@ -30,7 +29,7 @@ export class PrepaidStatus extends withProduct(LitElement) {
30
29
  getDefaultPrepaidShipments() {
31
30
  return this.options.includes(this.defaultPrepaidShipments)
32
31
  ? this.defaultPrepaidShipments
33
- : getDefaultPrepaidOption(this.options);
32
+ : this.options[1] || this.options[0];
34
33
  }
35
34
 
36
35
  handleSelect({ target: { value } }) {
@@ -208,6 +208,42 @@ describe('IncentiveText', () => {
208
208
  expect(el.innerText.trim()).toEqual('33%');
209
209
  });
210
210
 
211
+ it('prefers non-threshold incentives', async () => {
212
+ const el = new IncentiveText();
213
+ el.from = 'DiscountPercent';
214
+ el.incentives = {
215
+ initial: [],
216
+ ongoing: [
217
+ {
218
+ field: 'total_price',
219
+ object: 'item',
220
+ type: 'Discount Percent',
221
+ value: 25,
222
+ threshold_field: 'order',
223
+ threshold_value: '10.00',
224
+ criteria: {
225
+ node_type: 'PREMISE',
226
+ standard: 'PROGRAM_WIDE'
227
+ }
228
+ },
229
+ {
230
+ field: 'total_price',
231
+ object: 'item',
232
+ type: 'Discount Percent',
233
+ value: 10,
234
+ threshold_field: null,
235
+ threshold_value: null,
236
+ criteria: {
237
+ node_type: 'PREMISE',
238
+ standard: 'PROGRAM_WIDE'
239
+ }
240
+ }
241
+ ]
242
+ };
243
+ await appendToBody(el);
244
+ expect(el.innerText.trim()).toEqual('10%');
245
+ });
246
+
211
247
  it('returns other matching incentives if no preferred incentives available', async () => {
212
248
  const el = new IncentiveText();
213
249
  el.from = 'DiscountPercent';
@@ -1072,6 +1072,21 @@ describe('reducers', () => {
1072
1072
  it('should consider incentives_display_enhanced if present', () => {
1073
1073
  const enhancedOfferResponse = {
1074
1074
  ...offerResponse,
1075
+ incentives: {
1076
+ 44198332104980: {
1077
+ ongoing: ['8285f16f826e4cf29b49f073e45e32ab', 'threshold-id', '10205e185a5c4ccf83de75459241623a'],
1078
+ initial: ['0f98a321d29e47d2a17fe3a8a7522d26']
1079
+ }
1080
+ },
1081
+ incentives_display: {
1082
+ ...offerResponse.incentives_display,
1083
+ 'threshold-id': {
1084
+ object: 'order',
1085
+ field: 'sub_total',
1086
+ type: 'Discount Percent',
1087
+ value: 20.0
1088
+ }
1089
+ },
1075
1090
  incentives_display_enhanced: {
1076
1091
  '8285f16f826e4cf29b49f073e45e32ab': {
1077
1092
  incentive_target: 'order',
@@ -1081,6 +1096,14 @@ describe('reducers', () => {
1081
1096
  threshold_field: null,
1082
1097
  threshold_value: null
1083
1098
  },
1099
+ 'threshold-id': {
1100
+ incentive_target: 'order',
1101
+ incentive_type: 'discount_percent',
1102
+ incentive_value: '20.00',
1103
+ // no criteria, since this is program-wide
1104
+ threshold_field: 'order',
1105
+ threshold_value: '10.00'
1106
+ },
1084
1107
  '10205e185a5c4ccf83de75459241623a': {
1085
1108
  incentive_target: 'item',
1086
1109
  incentive_type: 'discount_percent',
@@ -1117,6 +1140,22 @@ describe('reducers', () => {
1117
1140
  type: 'Discount Percent',
1118
1141
  value: 10.0,
1119
1142
  id: '8285f16f826e4cf29b49f073e45e32ab',
1143
+ threshold_field: null,
1144
+ threshold_value: null,
1145
+ criteria: {
1146
+ node_type: 'PREMISE',
1147
+ standard: 'PROGRAM_WIDE',
1148
+ premise_value: null
1149
+ }
1150
+ },
1151
+ {
1152
+ object: 'order',
1153
+ field: 'sub_total',
1154
+ type: 'Discount Percent',
1155
+ value: 20.0,
1156
+ id: 'threshold-id',
1157
+ threshold_field: 'order',
1158
+ threshold_value: '10.00',
1120
1159
  criteria: {
1121
1160
  node_type: 'PREMISE',
1122
1161
  standard: 'PROGRAM_WIDE',
@@ -1129,6 +1168,8 @@ describe('reducers', () => {
1129
1168
  type: 'Discount Amount',
1130
1169
  value: 5.0,
1131
1170
  id: '10205e185a5c4ccf83de75459241623a',
1171
+ threshold_field: null,
1172
+ threshold_value: null,
1132
1173
  criteria: {
1133
1174
  node_type: 'PREMISE',
1134
1175
  standard: 'PREPAID_ORDERS_PER_BILLING',
@@ -1143,6 +1184,8 @@ describe('reducers', () => {
1143
1184
  type: 'Discount Percent',
1144
1185
  value: 11.0,
1145
1186
  id: '0f98a321d29e47d2a17fe3a8a7522d26',
1187
+ threshold_field: null,
1188
+ threshold_value: null,
1146
1189
  criteria: {
1147
1190
  node_type: 'PREMISE',
1148
1191
  standard: 'PSI',
@@ -2,11 +2,7 @@ import { resolveAuth } from '@ordergroove/auth';
2
2
  import * as constants from './constants';
3
3
  import { api } from './api';
4
4
  import { safeOgFrequency } from './utils';
5
- import {
6
- makeFrequencyForPrepaidShipmentsSelector,
7
- makePrepaidSellingPlansSelector,
8
- makeProductFrequenciesSelector
9
- } from './selectors';
5
+ import { makeFrequencyForPrepaidShipmentsSelector, makeProductFrequenciesSelector } from './selectors';
10
6
 
11
7
  export const optinProduct = (product, frequency, offer) => ({
12
8
  type: constants.OPTIN_PRODUCT,
@@ -194,12 +190,10 @@ export const requestSessionId = () => (dispatch, getState) => {
194
190
 
195
191
  export const receiveOffer = (response, offer, productId) => (dispatch, getState) => {
196
192
  // this is a thunk so that we access the state for the selector
197
- const state = getState();
198
- const frequencyConfig = makeProductFrequenciesSelector(productId)(state);
199
- const prepaidSellingPlans = makePrepaidSellingPlansSelector(productId)(state);
193
+ const frequencyConfig = makeProductFrequenciesSelector(productId)(getState());
200
194
  dispatch({
201
195
  type: constants.RECEIVE_OFFER,
202
- payload: { ...response, offer, frequencyConfig, prepaidSellingPlans }
196
+ payload: { ...response, offer, frequencyConfig }
203
197
  });
204
198
  };
205
199
 
@@ -61,10 +61,6 @@ export const INCENTIVE_STANDARD_TYPES = {
61
61
  PROGRAM_WIDE: 'PROGRAM_WIDE'
62
62
  };
63
63
 
64
- export const ELIGIBILITY_GROUPS = {
65
- PREPAID: 'prepaid'
66
- };
67
-
68
64
  /**
69
65
  * @event
70
66
  * Events that fires once optin/optout occurs on a cart offer
@@ -1,4 +1,3 @@
1
- import { ELIGIBILITY_GROUPS } from './constants';
2
1
  import {
3
2
  makeSubscribedSelector,
4
3
  makeOptedoutSelector,
@@ -26,7 +25,7 @@ export const hasUpsellGroup = (state, ownProps) => {
26
25
 
27
26
  export const prepaidEligible = (state, ownProps) => {
28
27
  const groups = eligibilityGroups(state, ownProps);
29
- return groups?.some(it => it === ELIGIBILITY_GROUPS.PREPAID) || false;
28
+ return groups?.some(it => it === 'prepaid') || false;
30
29
  };
31
30
 
32
31
  export const subscribed = (state, ownProps) => makeSubscribedSelector(ownProps.product)(state);
@@ -180,7 +180,13 @@ const mapIncentive = (
180
180
  ? enhanced.criteria
181
181
  : // when there is no criteria in the enhanced incentive, it means it's a program wide incentive
182
182
  // for ease-of-use, we set use a "PROGRAM_WIDE" pseudo-standard here
183
- { node_type: 'PREMISE', standard: constants.INCENTIVE_STANDARD_TYPES.PROGRAM_WIDE, premise_value: null }
183
+ {
184
+ node_type: 'PREMISE',
185
+ standard: constants.INCENTIVE_STANDARD_TYPES.PROGRAM_WIDE,
186
+ premise_value: null
187
+ },
188
+ threshold_field: enhanced.threshold_field,
189
+ threshold_value: enhanced.threshold_value
184
190
  }
185
191
  : {}),
186
192
  id: [i][0]
@@ -232,12 +232,6 @@ export const makeFrequencyForPrepaidShipmentsSelector = (product: BaseProduct, p
232
232
  }
233
233
  );
234
234
 
235
- export const makePrepaidSellingPlansSelector = (product: string) =>
236
- createSelector(prepaidSellingPlansSelector, prepaidSellingPlans => {
237
- const productId = safeProductId(product);
238
- return prepaidSellingPlans[productId] || [];
239
- });
240
-
241
235
  /** Determine the discounted price of the product, based on the incentives returned from the Offers endpoint. This assumes a pay-as-you-go subscription. */
242
236
  export const makeDiscountedProductPriceSelector = memoize((productId: string) =>
243
237
  createSelector(
@@ -20,8 +20,10 @@ export type IncentivesState = Record<string, IncentiveObject>;
20
20
  export type Incentive = ApiIncentive & {
21
21
  id: string;
22
22
  /**
23
- * undefined when the offer profile is not standardized
23
+ * all these fields are undefined when the offer profile is not standardized
24
24
  */
25
+ threshold_field?: string | null;
26
+ threshold_value?: string | null;
25
27
  criteria?: {
26
28
  node_type: string;
27
29
  premise_value: unknown;
@@ -53,13 +55,11 @@ export type ConfigState = Partial<{
53
55
  * @deprecated use productFrequencies instead
54
56
  */
55
57
  frequenciesText: string[];
56
- prepaidSellingPlans: Record<string, PrepaidSellingPlan[]>;
58
+ prepaidSellingPlans: Record<string, { numberShipments: number; sellingPlan: string }[]>;
57
59
  storeCurrency: string;
58
60
  productFrequencies: Record<string, ProductFrequencyConfig>;
59
61
  }>;
60
62
 
61
- export type PrepaidSellingPlan = { numberShipments: number; sellingPlan: string };
62
-
63
63
  export type ProductFrequencyConfig = {
64
64
  frequencies?: string[];
65
65
  frequenciesEveryPeriod?: string[];
@@ -92,7 +92,6 @@ export type ReceiveOfferPayload = OfferResponse & {
92
92
  frequenciesEveryPeriod?: string[];
93
93
  frequenciesText?: string[];
94
94
  };
95
- prepaidSellingPlans: PrepaidSellingPlan[];
96
95
  };
97
96
 
98
97
  export type OfferElement = InstanceType<typeof Offer> & { config: ConfigState };
@@ -2,45 +2,6 @@ import * as constants from '../../../core/constants';
2
2
  import { optedin } from '../../shopifyReducer';
3
3
  import { DEFAULT_PAY_AS_YOU_GO_GROUP_NAME } from '../../utils';
4
4
 
5
- const PREPAID_PRODUCT_ID = '43017264201944';
6
- const BOTH_ELIGIBLE_PRODUCT_ID = '43017264201946';
7
-
8
- const PREPAID_PLAN_3_SHIPMENTS = 'prepaid-plan-3-shipments';
9
- const PREPAID_PLAN_6_SHIPMENTS = 'prepaid-plan-6-shipments';
10
-
11
- const prepaidPlanWith3Shipments = { sellingPlan: PREPAID_PLAN_3_SHIPMENTS, numberShipments: 3 };
12
- const prepaidPlanWith6Shipments = { sellingPlan: PREPAID_PLAN_6_SHIPMENTS, numberShipments: 6 };
13
-
14
- function buildReceiveOfferPayload(overrides = {}) {
15
- return {
16
- autoship: {},
17
- autoship_by_default: {},
18
- default_frequencies: {},
19
- in_stock: {},
20
- eligibility_groups: {},
21
- offer: {},
22
- frequencyConfig: {
23
- frequencies: [],
24
- frequenciesEveryPeriod: []
25
- },
26
- prepaidSellingPlans: [],
27
- ...overrides
28
- };
29
- }
30
-
31
- function buildPrepaidSellingPlanGroup(variantId, plans) {
32
- return {
33
- name: `Prepaid-${variantId}`,
34
- selling_plans: plans.map((plan, index) => ({
35
- id: plan.sellingPlan,
36
- options: [
37
- { name: 'Delivery every', value: `PREPAID-${index + 1} months` },
38
- { name: 'Shipment amount', value: `${plan.numberShipments} shipments` }
39
- ]
40
- }))
41
- };
42
- }
43
-
44
5
  describe('optedin', () => {
45
6
  it('should return optins given action SETUP_CART', () => {
46
7
  const actual = optedin([], {
@@ -622,208 +583,6 @@ describe('optedin', () => {
622
583
  ]);
623
584
  });
624
585
  });
625
-
626
- describe('given product is prepaid eligible but NOT autoship eligible', () => {
627
- describe('given prepaidSellingPlans are populated', () => {
628
- it('should opt into 2nd prepaid plan and set prepaidShipments when multiple plans available', () => {
629
- const actual = optedin([], {
630
- type: constants.RECEIVE_OFFER,
631
- payload: buildReceiveOfferPayload({
632
- autoship: {
633
- [PREPAID_PRODUCT_ID]: false
634
- },
635
- autoship_by_default: {
636
- [PREPAID_PRODUCT_ID]: true
637
- },
638
- in_stock: {
639
- [PREPAID_PRODUCT_ID]: true
640
- },
641
- eligibility_groups: {
642
- [PREPAID_PRODUCT_ID]: [constants.ELIGIBILITY_GROUPS.PREPAID]
643
- },
644
- prepaidSellingPlans: [prepaidPlanWith3Shipments, prepaidPlanWith6Shipments]
645
- })
646
- });
647
-
648
- expect(actual).toEqual([
649
- {
650
- id: PREPAID_PRODUCT_ID,
651
- frequency: PREPAID_PLAN_6_SHIPMENTS,
652
- prepaidShipments: 6
653
- }
654
- ]);
655
- });
656
-
657
- it('should opt into 1st prepaid plan and set prepaidShipments when only one plan available', () => {
658
- const actual = optedin([], {
659
- type: constants.RECEIVE_OFFER,
660
- payload: buildReceiveOfferPayload({
661
- autoship: {
662
- [PREPAID_PRODUCT_ID]: false
663
- },
664
- autoship_by_default: {
665
- [PREPAID_PRODUCT_ID]: true
666
- },
667
- in_stock: {
668
- [PREPAID_PRODUCT_ID]: true
669
- },
670
- eligibility_groups: {
671
- [PREPAID_PRODUCT_ID]: [constants.ELIGIBILITY_GROUPS.PREPAID]
672
- },
673
- prepaidSellingPlans: [prepaidPlanWith3Shipments]
674
- })
675
- });
676
-
677
- expect(actual).toEqual([
678
- {
679
- id: PREPAID_PRODUCT_ID,
680
- frequency: PREPAID_PLAN_3_SHIPMENTS,
681
- prepaidShipments: 3
682
- }
683
- ]);
684
- });
685
- });
686
-
687
- describe('given prepaidSellingPlans are NOT populated', () => {
688
- it('should opt into prepaid with PREPAID_PLACEHOLDER and prepaidShipments null', () => {
689
- const actual = optedin([], {
690
- type: constants.RECEIVE_OFFER,
691
- payload: buildReceiveOfferPayload({
692
- autoship: {
693
- [PREPAID_PRODUCT_ID]: false
694
- },
695
- autoship_by_default: {
696
- [PREPAID_PRODUCT_ID]: true
697
- },
698
- in_stock: {
699
- [PREPAID_PRODUCT_ID]: true
700
- },
701
- eligibility_groups: {
702
- [PREPAID_PRODUCT_ID]: [constants.ELIGIBILITY_GROUPS.PREPAID]
703
- },
704
- prepaidSellingPlans: []
705
- })
706
- });
707
-
708
- expect(actual).toEqual([
709
- {
710
- id: PREPAID_PRODUCT_ID,
711
- frequency: 'prepaid-replace-me',
712
- prepaidShipments: null
713
- }
714
- ]);
715
- });
716
- });
717
-
718
- describe('edge cases', () => {
719
- it('should not create optin when product not in stock, not autoship_by_default, or not in eligibility_groups', () => {
720
- // Product not in stock
721
- const notInStock = optedin([], {
722
- type: constants.RECEIVE_OFFER,
723
- payload: buildReceiveOfferPayload({
724
- autoship: {
725
- [PREPAID_PRODUCT_ID]: false
726
- },
727
- autoship_by_default: {
728
- [PREPAID_PRODUCT_ID]: true
729
- },
730
- in_stock: {
731
- [PREPAID_PRODUCT_ID]: false
732
- },
733
- eligibility_groups: {
734
- [PREPAID_PRODUCT_ID]: [constants.ELIGIBILITY_GROUPS.PREPAID]
735
- },
736
- prepaidSellingPlans: [prepaidPlanWith3Shipments]
737
- })
738
- });
739
-
740
- // Product not autoship_by_default
741
- const notAutoshipByDefault = optedin([], {
742
- type: constants.RECEIVE_OFFER,
743
- payload: buildReceiveOfferPayload({
744
- autoship: {
745
- [PREPAID_PRODUCT_ID]: false
746
- },
747
- autoship_by_default: {
748
- [PREPAID_PRODUCT_ID]: false
749
- },
750
- in_stock: {
751
- [PREPAID_PRODUCT_ID]: true
752
- },
753
- eligibility_groups: {
754
- [PREPAID_PRODUCT_ID]: [constants.ELIGIBILITY_GROUPS.PREPAID]
755
- },
756
- prepaidSellingPlans: [prepaidPlanWith3Shipments]
757
- })
758
- });
759
-
760
- // Product not in eligibility_groups
761
- const notInEligibilityGroups = optedin([], {
762
- type: constants.RECEIVE_OFFER,
763
- payload: buildReceiveOfferPayload({
764
- autoship: {
765
- [PREPAID_PRODUCT_ID]: false
766
- },
767
- autoship_by_default: {
768
- [PREPAID_PRODUCT_ID]: true
769
- },
770
- in_stock: {
771
- [PREPAID_PRODUCT_ID]: true
772
- },
773
- eligibility_groups: {
774
- [PREPAID_PRODUCT_ID]: []
775
- },
776
- prepaidSellingPlans: [prepaidPlanWith3Shipments]
777
- })
778
- });
779
-
780
- expect(notInStock).toEqual([]);
781
- expect(notAutoshipByDefault).toEqual([]);
782
- expect(notInEligibilityGroups).toEqual([]);
783
- });
784
- });
785
- });
786
-
787
- describe('given product is BOTH prepaid eligible AND autoship eligible', () => {
788
- it('should opt into regular subscription with PSDF frequency, not prepaid', () => {
789
- const actual = optedin([], {
790
- type: constants.RECEIVE_OFFER,
791
- payload: buildReceiveOfferPayload({
792
- autoship: {
793
- [BOTH_ELIGIBLE_PRODUCT_ID]: true
794
- },
795
- autoship_by_default: {
796
- [BOTH_ELIGIBLE_PRODUCT_ID]: true
797
- },
798
- default_frequencies: {
799
- [BOTH_ELIGIBLE_PRODUCT_ID]: {
800
- every: 1,
801
- every_period: 2
802
- }
803
- },
804
- in_stock: {
805
- [BOTH_ELIGIBLE_PRODUCT_ID]: true
806
- },
807
- eligibility_groups: {
808
- [BOTH_ELIGIBLE_PRODUCT_ID]: [constants.ELIGIBILITY_GROUPS.PREPAID]
809
- },
810
- frequencyConfig: {
811
- frequencies: ['yum selling plan id 1', 'yum selling plan id 2'],
812
- frequenciesEveryPeriod: ['1_1', '1_2']
813
- },
814
- prepaidSellingPlans: [prepaidPlanWith3Shipments, prepaidPlanWith6Shipments]
815
- })
816
- });
817
-
818
- expect(actual).toEqual([
819
- {
820
- id: BOTH_ELIGIBLE_PRODUCT_ID,
821
- frequency: 'yum selling plan id 2'
822
- }
823
- ]);
824
- expect(actual[0].prepaidShipments).toBeUndefined();
825
- });
826
- });
827
586
  });
828
587
  });
829
588
 
@@ -997,69 +756,6 @@ describe('optedin', () => {
997
756
  }
998
757
  ]);
999
758
  });
1000
-
1001
- describe('given frequency is PREPAID_PLACEHOLDER', () => {
1002
- describe('given prepaidSellingPlans exist for variant', () => {
1003
- it('should replace prepaid placeholder optin', () => {
1004
- const actual = optedin(
1005
- [
1006
- {
1007
- id: PREPAID_PRODUCT_ID,
1008
- frequency: 'prepaid-replace-me',
1009
- prepaidShipments: null
1010
- }
1011
- ],
1012
- {
1013
- type: constants.SETUP_PRODUCT,
1014
- payload: {
1015
- product: {
1016
- variants: [{ id: PREPAID_PRODUCT_ID }],
1017
- selling_plan_groups: [
1018
- buildPrepaidSellingPlanGroup(PREPAID_PRODUCT_ID, [
1019
- prepaidPlanWith3Shipments,
1020
- prepaidPlanWith6Shipments
1021
- ])
1022
- ]
1023
- }
1024
- }
1025
- }
1026
- );
1027
-
1028
- expect(actual).toEqual([
1029
- {
1030
- id: PREPAID_PRODUCT_ID,
1031
- frequency: PREPAID_PLAN_6_SHIPMENTS,
1032
- prepaidShipments: 6
1033
- }
1034
- ]);
1035
- });
1036
- });
1037
-
1038
- describe('given prepaidSellingPlans do NOT exist for variant', () => {
1039
- it('should remove placeholder optin', () => {
1040
- const actual = optedin(
1041
- [
1042
- {
1043
- id: PREPAID_PRODUCT_ID,
1044
- frequency: 'prepaid-replace-me',
1045
- prepaidShipments: null
1046
- }
1047
- ],
1048
- {
1049
- type: constants.SETUP_PRODUCT,
1050
- payload: {
1051
- product: {
1052
- variants: [{ id: PREPAID_PRODUCT_ID }],
1053
- selling_plan_groups: []
1054
- }
1055
- }
1056
- }
1057
- );
1058
-
1059
- expect(actual).toEqual([]);
1060
- });
1061
- });
1062
- });
1063
759
  });
1064
760
 
1065
761
  describe('given action is PRODUCT_CHANGE_PREPAID_SHIPMENTS', () => {
@@ -1111,49 +807,6 @@ describe('optedin', () => {
1111
807
  });
1112
808
  });
1113
809
 
1114
- it('integration: SETUP_PRODUCT after RECEIVE_OFFER should handle default prepaid optin', () => {
1115
- // Step 1: RECEIVE_OFFER creates optin with placeholder (no prepaidSellingPlans available yet)
1116
- const afterReceiveOffer = optedin([], {
1117
- type: constants.RECEIVE_OFFER,
1118
- payload: buildReceiveOfferPayload({
1119
- autoship: {
1120
- [PREPAID_PRODUCT_ID]: false
1121
- },
1122
- autoship_by_default: {
1123
- [PREPAID_PRODUCT_ID]: true
1124
- },
1125
- in_stock: {
1126
- [PREPAID_PRODUCT_ID]: true
1127
- },
1128
- eligibility_groups: {
1129
- [PREPAID_PRODUCT_ID]: [constants.ELIGIBILITY_GROUPS.PREPAID]
1130
- },
1131
- prepaidSellingPlans: []
1132
- })
1133
- });
1134
-
1135
- // Step 2: SETUP_PRODUCT replaces placeholder with actual selling plan
1136
- const afterSetupProduct = optedin(afterReceiveOffer, {
1137
- type: constants.SETUP_PRODUCT,
1138
- payload: {
1139
- product: {
1140
- variants: [{ id: PREPAID_PRODUCT_ID }],
1141
- selling_plan_groups: [
1142
- buildPrepaidSellingPlanGroup(PREPAID_PRODUCT_ID, [prepaidPlanWith3Shipments, prepaidPlanWith6Shipments])
1143
- ]
1144
- }
1145
- }
1146
- });
1147
-
1148
- expect(afterSetupProduct).toEqual([
1149
- {
1150
- id: PREPAID_PRODUCT_ID,
1151
- frequency: PREPAID_PLAN_6_SHIPMENTS,
1152
- prepaidShipments: 6
1153
- }
1154
- ]);
1155
- });
1156
-
1157
810
  it('should return unmodified state given unsupported action', () => {
1158
811
  const actual = optedin(
1159
812
  { 'yum existing key': 'yum existing value' },