@zoxllc/shopify-checkout-extensions 0.0.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 (41) hide show
  1. package/README.md +3 -0
  2. package/package.json +31 -0
  3. package/src/common/AndSelector.ts +35 -0
  4. package/src/common/BuyXGetY.ts +109 -0
  5. package/src/common/Campaign.ts +55 -0
  6. package/src/common/CampaignConfiguration.ts +10 -0
  7. package/src/common/CampaignFactory.ts +180 -0
  8. package/src/common/CartAmountQualifier.ts +64 -0
  9. package/src/common/CartHasItemQualifier.ts +64 -0
  10. package/src/common/CartQuantityQualifier.ts +73 -0
  11. package/src/common/CustomerEmailQualifier.ts +60 -0
  12. package/src/common/CustomerSubscriberQualifier.ts +32 -0
  13. package/src/common/CustomerTagQualifier.ts +56 -0
  14. package/src/common/DiscountCart.ts +130 -0
  15. package/src/common/DiscountInterface.ts +13 -0
  16. package/src/common/OrSelector.ts +35 -0
  17. package/src/common/PostCartAmountQualifier.ts +21 -0
  18. package/src/common/ProductHandleSelector.ts +29 -0
  19. package/src/common/ProductIdSelector.ts +28 -0
  20. package/src/common/ProductTagSelector.ts +54 -0
  21. package/src/common/ProductTypeSelector.ts +34 -0
  22. package/src/common/Qualifier.ts +67 -0
  23. package/src/common/SaleItemSelector.ts +35 -0
  24. package/src/common/Selector.ts +53 -0
  25. package/src/common/SubscriptionItemSelector.ts +21 -0
  26. package/src/generated/api.ts +2103 -0
  27. package/src/index.ts +39 -0
  28. package/src/lineItem/ConditionalDiscount.ts +102 -0
  29. package/src/lineItem/DiscountCodeList.ts +91 -0
  30. package/src/lineItem/FixedItemDiscount.ts +53 -0
  31. package/src/lineItem/PercentageDiscount.ts +46 -0
  32. package/tests/AndSelector.test.ts +27 -0
  33. package/tests/CartQuantityQualifier.test.ts +381 -0
  34. package/tests/CustomerSubscriberQualifier.test.ts +101 -0
  35. package/tests/DiscountCart.test.ts +115 -0
  36. package/tests/OrSelector.test.ts +27 -0
  37. package/tests/ProductTagSelector.test.ts +75 -0
  38. package/tests/Qualifier.test.ts +193 -0
  39. package/tests/SaleItemSelector.test.ts +113 -0
  40. package/tests/Selector.test.ts +83 -0
  41. package/tsconfig.json +25 -0
@@ -0,0 +1,381 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { DiscountCart } from '../src/common/DiscountCart';
3
+ import { RunInput } from '../src/generated/api';
4
+ import _ from 'lodash';
5
+ import { NumericalComparisonType } from '../src/common/Qualifier';
6
+ import {
7
+ CartQuantityBehavior,
8
+ CartQuantityQualifier,
9
+ } from '../src/common/CartQuantityQualifier';
10
+
11
+ describe('CartQuantityQualifier', () => {
12
+ it('calculates :CART and :EQUAL_TO correctly', () => {
13
+ qualifier = new CartQuantityQualifier(
14
+ CartQuantityBehavior.CART,
15
+ NumericalComparisonType.EQUAL_TO,
16
+ 14
17
+ );
18
+ matchResult = qualifier.match(cart);
19
+ expect(matchResult).toBe(true);
20
+
21
+ qualifier = new CartQuantityQualifier(
22
+ CartQuantityBehavior.CART,
23
+ NumericalComparisonType.EQUAL_TO,
24
+ 10
25
+ );
26
+ matchResult = qualifier.match(cart);
27
+ expect(matchResult).toBe(false);
28
+
29
+ qualifier = new CartQuantityQualifier(
30
+ CartQuantityBehavior.CART,
31
+ NumericalComparisonType.EQUAL_TO,
32
+ 100
33
+ );
34
+ matchResult = qualifier.match(cart);
35
+ expect(matchResult).toBe(false);
36
+ });
37
+
38
+ it('calculates :CART and :LESS_THAN correctly', () => {
39
+ qualifier = new CartQuantityQualifier(
40
+ CartQuantityBehavior.CART,
41
+ NumericalComparisonType.LESS_THAN,
42
+ 14
43
+ );
44
+ matchResult = qualifier.match(cart);
45
+ expect(matchResult).toBe(false);
46
+
47
+ qualifier = new CartQuantityQualifier(
48
+ CartQuantityBehavior.CART,
49
+ NumericalComparisonType.LESS_THAN,
50
+ 13
51
+ );
52
+ matchResult = qualifier.match(cart);
53
+ expect(matchResult).toBe(false);
54
+
55
+ qualifier = new CartQuantityQualifier(
56
+ CartQuantityBehavior.CART,
57
+ NumericalComparisonType.LESS_THAN,
58
+ 15
59
+ );
60
+ matchResult = qualifier.match(cart);
61
+ expect(matchResult).toBe(true);
62
+ });
63
+
64
+ it('calculates :CART and :LESS_THAN_OR_EQUAL correctly', () => {
65
+ qualifier = new CartQuantityQualifier(
66
+ CartQuantityBehavior.CART,
67
+ NumericalComparisonType.LESS_THAN_OR_EQUAL,
68
+ 14
69
+ );
70
+ matchResult = qualifier.match(cart);
71
+ expect(matchResult).toBe(true);
72
+
73
+ qualifier = new CartQuantityQualifier(
74
+ CartQuantityBehavior.CART,
75
+ NumericalComparisonType.LESS_THAN_OR_EQUAL,
76
+ 13
77
+ );
78
+ matchResult = qualifier.match(cart);
79
+ expect(matchResult).toBe(false);
80
+
81
+ qualifier = new CartQuantityQualifier(
82
+ CartQuantityBehavior.CART,
83
+ NumericalComparisonType.LESS_THAN_OR_EQUAL,
84
+ 15
85
+ );
86
+ matchResult = qualifier.match(cart);
87
+ expect(matchResult).toBe(true);
88
+ });
89
+
90
+ it('calculates :CART and :GREATER_THAN correctly', () => {
91
+ qualifier = new CartQuantityQualifier(
92
+ CartQuantityBehavior.CART,
93
+ NumericalComparisonType.GREATER_THAN,
94
+ 14
95
+ );
96
+ matchResult = qualifier.match(cart);
97
+ expect(matchResult).toBe(false);
98
+
99
+ qualifier = new CartQuantityQualifier(
100
+ CartQuantityBehavior.CART,
101
+ NumericalComparisonType.GREATER_THAN,
102
+ 13
103
+ );
104
+ matchResult = qualifier.match(cart);
105
+ expect(matchResult).toBe(true);
106
+
107
+ qualifier = new CartQuantityQualifier(
108
+ CartQuantityBehavior.CART,
109
+ NumericalComparisonType.GREATER_THAN,
110
+ 15
111
+ );
112
+ matchResult = qualifier.match(cart);
113
+ expect(matchResult).toBe(false);
114
+ });
115
+
116
+ it('calculates :CART and :GREATER_THAN_OR_EQUAL correctly', () => {
117
+ qualifier = new CartQuantityQualifier(
118
+ CartQuantityBehavior.CART,
119
+ NumericalComparisonType.GREATER_THAN_OR_EQUAL,
120
+ 14
121
+ );
122
+ matchResult = qualifier.match(cart);
123
+ expect(matchResult).toBe(true);
124
+
125
+ qualifier = new CartQuantityQualifier(
126
+ CartQuantityBehavior.CART,
127
+ NumericalComparisonType.GREATER_THAN_OR_EQUAL,
128
+ 13
129
+ );
130
+ matchResult = qualifier.match(cart);
131
+ expect(matchResult).toBe(true);
132
+
133
+ qualifier = new CartQuantityQualifier(
134
+ CartQuantityBehavior.CART,
135
+ NumericalComparisonType.GREATER_THAN_OR_EQUAL,
136
+ 15
137
+ );
138
+ matchResult = qualifier.match(cart);
139
+ expect(matchResult).toBe(false);
140
+ });
141
+
142
+ it('calculates :ITEM and :EQUAL_TO correctly', () => {
143
+ qualifier = new CartQuantityQualifier(
144
+ CartQuantityBehavior.ITEM,
145
+ NumericalComparisonType.EQUAL_TO,
146
+ 14
147
+ );
148
+ matchResult = qualifier.match(cart);
149
+ expect(matchResult).toBe(true);
150
+
151
+ qualifier = new CartQuantityQualifier(
152
+ CartQuantityBehavior.ITEM,
153
+ NumericalComparisonType.EQUAL_TO,
154
+ 10
155
+ );
156
+ matchResult = qualifier.match(cart);
157
+ expect(matchResult).toBe(false);
158
+
159
+ qualifier = new CartQuantityQualifier(
160
+ CartQuantityBehavior.ITEM,
161
+ NumericalComparisonType.EQUAL_TO,
162
+ 100
163
+ );
164
+ matchResult = qualifier.match(cart);
165
+ expect(matchResult).toBe(false);
166
+ });
167
+
168
+ it('calculates :ITEM and :LESS_THAN correctly', () => {
169
+ qualifier = new CartQuantityQualifier(
170
+ CartQuantityBehavior.ITEM,
171
+ NumericalComparisonType.LESS_THAN,
172
+ 14
173
+ );
174
+ matchResult = qualifier.match(cart);
175
+ expect(matchResult).toBe(false);
176
+
177
+ qualifier = new CartQuantityQualifier(
178
+ CartQuantityBehavior.ITEM,
179
+ NumericalComparisonType.LESS_THAN,
180
+ 13
181
+ );
182
+ matchResult = qualifier.match(cart);
183
+ expect(matchResult).toBe(false);
184
+
185
+ qualifier = new CartQuantityQualifier(
186
+ CartQuantityBehavior.ITEM,
187
+ NumericalComparisonType.LESS_THAN,
188
+ 15
189
+ );
190
+ matchResult = qualifier.match(cart);
191
+ expect(matchResult).toBe(true);
192
+ });
193
+
194
+ it('calculates :ITEM and :LESS_THAN_OR_EQUAL correctly', () => {
195
+ qualifier = new CartQuantityQualifier(
196
+ CartQuantityBehavior.ITEM,
197
+ NumericalComparisonType.LESS_THAN_OR_EQUAL,
198
+ 14
199
+ );
200
+ matchResult = qualifier.match(cart);
201
+ expect(matchResult).toBe(true);
202
+
203
+ qualifier = new CartQuantityQualifier(
204
+ CartQuantityBehavior.ITEM,
205
+ NumericalComparisonType.LESS_THAN_OR_EQUAL,
206
+ 13
207
+ );
208
+ matchResult = qualifier.match(cart);
209
+ expect(matchResult).toBe(false);
210
+
211
+ qualifier = new CartQuantityQualifier(
212
+ CartQuantityBehavior.ITEM,
213
+ NumericalComparisonType.LESS_THAN_OR_EQUAL,
214
+ 15
215
+ );
216
+ matchResult = qualifier.match(cart);
217
+ expect(matchResult).toBe(true);
218
+ });
219
+
220
+ it('calculates :ITEM and :GREATER_THAN correctly', () => {
221
+ qualifier = new CartQuantityQualifier(
222
+ CartQuantityBehavior.ITEM,
223
+ NumericalComparisonType.GREATER_THAN,
224
+ 14
225
+ );
226
+ matchResult = qualifier.match(cart);
227
+ expect(matchResult).toBe(false);
228
+
229
+ qualifier = new CartQuantityQualifier(
230
+ CartQuantityBehavior.ITEM,
231
+ NumericalComparisonType.GREATER_THAN,
232
+ 13
233
+ );
234
+ matchResult = qualifier.match(cart);
235
+ expect(matchResult).toBe(true);
236
+
237
+ qualifier = new CartQuantityQualifier(
238
+ CartQuantityBehavior.ITEM,
239
+ NumericalComparisonType.GREATER_THAN,
240
+ 15
241
+ );
242
+ matchResult = qualifier.match(cart);
243
+ expect(matchResult).toBe(false);
244
+ });
245
+
246
+ it('calculates :ITEM and :GREATER_THAN_OR_EQUAL correctly', () => {
247
+ qualifier = new CartQuantityQualifier(
248
+ CartQuantityBehavior.ITEM,
249
+ NumericalComparisonType.GREATER_THAN_OR_EQUAL,
250
+ 14
251
+ );
252
+ matchResult = qualifier.match(cart);
253
+ expect(matchResult).toBe(true);
254
+
255
+ qualifier = new CartQuantityQualifier(
256
+ CartQuantityBehavior.ITEM,
257
+ NumericalComparisonType.GREATER_THAN_OR_EQUAL,
258
+ 13
259
+ );
260
+ matchResult = qualifier.match(cart);
261
+ expect(matchResult).toBe(true);
262
+
263
+ qualifier = new CartQuantityQualifier(
264
+ CartQuantityBehavior.ITEM,
265
+ NumericalComparisonType.GREATER_THAN_OR_EQUAL,
266
+ 15
267
+ );
268
+ matchResult = qualifier.match(cart);
269
+ expect(matchResult).toBe(false);
270
+ });
271
+
272
+ const withSubscription: RunInput['cart'] = {
273
+ __typename: 'Cart',
274
+ cost: {
275
+ subtotalAmount: {
276
+ amount: '112.0',
277
+ },
278
+ totalAmount: {
279
+ amount: '112.0',
280
+ },
281
+ },
282
+ lines: [
283
+ {
284
+ cost: {
285
+ amountPerQuantity: {
286
+ amount: '8.0',
287
+ },
288
+ subtotalAmount: {
289
+ amount: '64.0',
290
+ },
291
+ totalAmount: {
292
+ amount: '64.0',
293
+ },
294
+ compareAtAmountPerQuantity: null,
295
+ },
296
+ quantity: 8,
297
+ merchandise: {
298
+ __typename: 'ProductVariant',
299
+ id: 'gid://shopify/ProductVariant/Single',
300
+ product: {
301
+ id: 'gid://shopify/Product/Single',
302
+ productType: 'Wristband - Single',
303
+ hasTags: [
304
+ {
305
+ tag: 'meta-exclude-gift',
306
+ hasTag: false,
307
+ },
308
+ {
309
+ tag: 'mystery-3-pack',
310
+ hasTag: false,
311
+ },
312
+ ],
313
+ },
314
+ },
315
+ },
316
+ {
317
+ cost: {
318
+ amountPerQuantity: {
319
+ amount: '8.0',
320
+ },
321
+ subtotalAmount: {
322
+ amount: '48.0',
323
+ },
324
+ totalAmount: {
325
+ amount: '48.0',
326
+ },
327
+ compareAtAmountPerQuantity: null,
328
+ },
329
+ quantity: 6,
330
+ merchandise: {
331
+ __typename: 'ProductVariant',
332
+ id: 'gid://shopify/ProductVariant/Strap',
333
+ product: {
334
+ id: 'gid://shopify/Product/Strap',
335
+ productType: 'Wristband - Strap',
336
+ hasTags: [
337
+ {
338
+ tag: 'meta-exclude-gift',
339
+ hasTag: false,
340
+ },
341
+ {
342
+ tag: 'mystery-3-pack',
343
+ hasTag: false,
344
+ },
345
+ ],
346
+ },
347
+ },
348
+ },
349
+ ],
350
+ buyerIdentity: {
351
+ customer: {
352
+ isActiveSubscriber: true,
353
+ hasTags: [
354
+ {
355
+ tag: 'Active product subscription',
356
+ hasTag: true,
357
+ },
358
+ ],
359
+ },
360
+ },
361
+ };
362
+
363
+ const withoutSubscription = _.cloneDeep(withSubscription);
364
+ _.merge(withoutSubscription, {
365
+ buyerIdentity: {
366
+ customer: {
367
+ isActiveSubscriber: false,
368
+ hasTags: [
369
+ {
370
+ hasTag: false,
371
+ tag: 'Active product subscription',
372
+ },
373
+ ],
374
+ },
375
+ },
376
+ } as RunInput['cart']);
377
+
378
+ const cart = new DiscountCart(withSubscription);
379
+ let qualifier: CartQuantityQualifier;
380
+ let matchResult: boolean;
381
+ });
@@ -0,0 +1,101 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { DiscountCart } from '../src/common/DiscountCart';
3
+ import { RunInput } from '../src/generated/api';
4
+ import _ from 'lodash';
5
+ import { CustomerSubscriberQualifier } from '../src/common/CustomerSubscriberQualifier';
6
+ import { QualifierMatchType } from '../src/common/Qualifier';
7
+
8
+ describe('CustomerSubscriberQualifier', () => {
9
+ it('is true when a customer contains a subscription', () => {
10
+ const cart = new DiscountCart(withSubscription);
11
+
12
+ const qualifier = new CustomerSubscriberQualifier(
13
+ QualifierMatchType.DOES
14
+ );
15
+ const matchResult = qualifier.match(cart);
16
+ expect(matchResult).toEqual(true);
17
+ });
18
+
19
+ it('is true when a customer does NOT contain an active subscription', () => {
20
+ const cart = new DiscountCart(withoutSubscription);
21
+
22
+ const qualifier = new CustomerSubscriberQualifier(
23
+ QualifierMatchType.DOES_NOT
24
+ );
25
+ const matchResult = qualifier.match(cart);
26
+ expect(matchResult).toEqual(true);
27
+ });
28
+
29
+ const withSubscription: RunInput['cart'] = {
30
+ __typename: 'Cart',
31
+ cost: {
32
+ subtotalAmount: {
33
+ amount: '164.0',
34
+ },
35
+ totalAmount: {
36
+ amount: '164.0',
37
+ },
38
+ },
39
+ lines: [
40
+ {
41
+ cost: {
42
+ amountPerQuantity: {
43
+ amount: '8.0',
44
+ },
45
+ subtotalAmount: {
46
+ amount: '64.0',
47
+ },
48
+ totalAmount: {
49
+ amount: '64.0',
50
+ },
51
+ compareAtAmountPerQuantity: null,
52
+ },
53
+ quantity: 8,
54
+ merchandise: {
55
+ __typename: 'ProductVariant',
56
+ id: 'gid://shopify/ProductVariant/43900890579178',
57
+ product: {
58
+ id: 'gid://shopify/Product/8069766840554',
59
+ productType: 'Wristband - Single',
60
+ hasTags: [
61
+ {
62
+ tag: 'meta-exclude-gift',
63
+ hasTag: false,
64
+ },
65
+ {
66
+ tag: 'mystery-3-pack',
67
+ hasTag: false,
68
+ },
69
+ ],
70
+ },
71
+ },
72
+ },
73
+ ],
74
+ buyerIdentity: {
75
+ customer: {
76
+ isActiveSubscriber: true,
77
+ hasTags: [
78
+ {
79
+ tag: 'Active product subscription',
80
+ hasTag: true,
81
+ },
82
+ ],
83
+ },
84
+ },
85
+ };
86
+
87
+ const withoutSubscription = _.cloneDeep(withSubscription);
88
+ _.merge(withoutSubscription, {
89
+ buyerIdentity: {
90
+ customer: {
91
+ isActiveSubscriber: false,
92
+ hasTags: [
93
+ {
94
+ hasTag: false,
95
+ tag: 'Active product subscription',
96
+ },
97
+ ],
98
+ },
99
+ },
100
+ } as RunInput['cart']);
101
+ });
@@ -0,0 +1,115 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { DiscountCart } from '../src/common/DiscountCart';
3
+ import { RunInput } from '../src/generated/api';
4
+
5
+ describe('DiscountCart', () => {
6
+ const discountCart = new DiscountCart(
7
+ ONE_GWP_BULK_DISCOUNT_8_PLUS.cart as RunInput['cart']
8
+ );
9
+
10
+ it('Contains correct amounts', () => {
11
+ expect(discountCart.discounts.length).toBe(0);
12
+ expect(discountCart.subtotalAmount).toBe(64);
13
+ expect(discountCart.appliedDiscountTotal).toBe(0);
14
+
15
+ discountCart.addDiscount({
16
+ targets: [
17
+ {
18
+ productVariant: {
19
+ id: 'gid://shopify/ProductVariant/43900890579178',
20
+ },
21
+ },
22
+ ],
23
+ value: {
24
+ fixedAmount: {
25
+ amount: 2,
26
+ appliesToEachItem: true,
27
+ },
28
+ },
29
+ });
30
+
31
+ expect(discountCart.discounts.length).toBe(1);
32
+ expect(discountCart.appliedDiscountTotal).toBe(16);
33
+ });
34
+ });
35
+
36
+ const ONE_GWP_BULK_DISCOUNT_8_PLUS = {
37
+ cart: {
38
+ cost: {
39
+ subtotalAmount: {
40
+ amount: '164.0',
41
+ },
42
+ totalAmount: {
43
+ amount: '164.0',
44
+ },
45
+ },
46
+ lines: [
47
+ {
48
+ gwp: null,
49
+ cost: {
50
+ amountPerQuantity: {
51
+ amount: '8.0',
52
+ },
53
+ subtotalAmount: {
54
+ amount: '64.0',
55
+ },
56
+ totalAmount: {
57
+ amount: '64.0',
58
+ },
59
+ compareAtAmountPerQuantity: null,
60
+ },
61
+ quantity: 8,
62
+ merchandise: {
63
+ __typename: 'ProductVariant',
64
+ id: 'gid://shopify/ProductVariant/43900890579178',
65
+ product: {
66
+ id: 'gid://shopify/Product/8069766840554',
67
+ productType: 'Wristband - Single',
68
+ hasTags: [
69
+ {
70
+ tag: 'meta-exclude-gift',
71
+ hasTag: false,
72
+ },
73
+ ],
74
+ },
75
+ },
76
+ },
77
+ {
78
+ gwp: null,
79
+ cost: {
80
+ amountPerQuantity: {
81
+ amount: '100.0',
82
+ },
83
+ subtotalAmount: {
84
+ amount: '100.0',
85
+ },
86
+ totalAmount: {
87
+ amount: '100.0',
88
+ },
89
+ compareAtAmountPerQuantity: null,
90
+ },
91
+ quantity: 1,
92
+ merchandise: {
93
+ __typename: 'ProductVariant',
94
+ id: 'gid://shopify/ProductVariant/43137443692778',
95
+ product: {
96
+ id: 'gid://shopify/Product/7803814379754',
97
+ productType: 'Gift',
98
+ hasTags: [
99
+ {
100
+ tag: 'meta-exclude-gift',
101
+ hasTag: true,
102
+ },
103
+ ],
104
+ },
105
+ },
106
+ },
107
+ ],
108
+ },
109
+ discountNode: {
110
+ metafield: {
111
+ value:
112
+ '{"campaigns":[{"__type":"BuyXGetY","inputs":[":all",[],{"__type":"FixedItemDiscount","inputs":[2,true,"Bulky functions discount!"]},{"__type":"ProductTypeSelector","inputs":[":is_one",["Wristband - Single","Wristband - Strap"]]},{"__type":"ProductTypeSelector","inputs":[":is_one",["Wristband - Single","Wristband - Strap"]]},8,null,null]},{"__type":"ConditionalDiscount","inputs":[":all",[{"__type":"AndSelector","inputs":[{"__type":"PostCartAmountQualifier","inputs":[":greater_than_or_equal",50]},{"__type":"CartAmountQualifier","inputs":[":cart",":greater_than_or_equal",50]}]}],{"__type":"PercentageDiscount","inputs":[100,"Now you\'re family! :)"]},{"__type":"ProductIdSelector","inputs":[":is_one",["gid://shopify/Product/7803814379754"]]}]}], "discountApplicationStrategy": "ALL"}',
113
+ },
114
+ },
115
+ };
@@ -0,0 +1,27 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { OrSelector } from '../src/common/OrSelector';
3
+ import { CartLine } from '../src/generated/api';
4
+ import {
5
+ MockFalseyQualifier,
6
+ MockTruthyQualifier,
7
+ } from './Qualifier.test';
8
+
9
+ describe('OrSelector', () => {
10
+ it('Returns true if any conditions are met', () => {
11
+ const selector = new OrSelector([
12
+ new MockFalseyQualifier(),
13
+ new MockTruthyQualifier(),
14
+ ]);
15
+
16
+ expect(selector.match({} as CartLine)).toBeTruthy();
17
+ });
18
+
19
+ it('Returns false if all conditions are not met', () => {
20
+ const selector = new OrSelector([
21
+ new MockFalseyQualifier(),
22
+ new MockFalseyQualifier(),
23
+ ]);
24
+
25
+ expect(selector.match({} as CartLine)).toBeFalsy();
26
+ });
27
+ });
@@ -0,0 +1,75 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import _ from 'lodash';
3
+ import { ProductTagSelector } from '../src/common/ProductTagSelector';
4
+ import { CartLine } from '../src/generated/api';
5
+ import {
6
+ QualifierMatchType,
7
+ StringComparisonType,
8
+ } from '../src/common/Qualifier';
9
+
10
+ describe('ProductTagSelector', () => {
11
+ it('is true when it matches one of', () => {
12
+ const selector = new ProductTagSelector(
13
+ QualifierMatchType.DOES,
14
+ StringComparisonType.MATCH,
15
+ ['tag1', 'tag2', 'tag3', 'TAG4']
16
+ );
17
+ const result = selector.match(lineItem);
18
+ expect(result).toEqual(true);
19
+ });
20
+
21
+ it('is false when it does NOT match one of', () => {
22
+ const selector = new ProductTagSelector(
23
+ QualifierMatchType.DOES,
24
+ StringComparisonType.MATCH,
25
+ ['tag6', 'tag7', 'tag8', 'tag9']
26
+ );
27
+ const result = selector.match(lineItem);
28
+ expect(result).toEqual(false);
29
+ });
30
+
31
+ it('is true when it contains one of', () => {
32
+ const selector = new ProductTagSelector(
33
+ QualifierMatchType.DOES,
34
+ StringComparisonType.CONTAINS,
35
+ ['ag', 'a']
36
+ );
37
+ const result = selector.match(lineItem);
38
+ expect(result).toEqual(true);
39
+ });
40
+
41
+ it('is false when it does NOT contain one of', () => {
42
+ const selector = new ProductTagSelector(
43
+ QualifierMatchType.DOES,
44
+ StringComparisonType.CONTAINS,
45
+ ['sandwich', 'choir']
46
+ );
47
+ const result = selector.match(lineItem);
48
+ expect(result).toEqual(false);
49
+ });
50
+
51
+ const lineItem = {
52
+ merchandise: {
53
+ product: {
54
+ hasTags: [
55
+ {
56
+ tag: 'tag1',
57
+ hasTag: true,
58
+ },
59
+ {
60
+ tag: 'tag2',
61
+ hasTag: true,
62
+ },
63
+ {
64
+ tag: 'tag3',
65
+ hasTag: true,
66
+ },
67
+ {
68
+ tag: 'tag4',
69
+ hasTag: true,
70
+ },
71
+ ],
72
+ },
73
+ },
74
+ } as CartLine;
75
+ });