@jsdev_ninja/core 0.13.27 → 0.13.29

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 (145) hide show
  1. package/dist/core.cjs.js +2 -0
  2. package/dist/core.cjs.js.map +1 -0
  3. package/dist/core.es.js +3584 -0
  4. package/dist/core.es.js.map +1 -0
  5. package/dist/core.umd.js +2 -0
  6. package/dist/core.umd.js.map +1 -0
  7. package/dist/lib/entities/Address.d.ts +28 -0
  8. package/dist/lib/entities/Address.d.ts.map +1 -0
  9. package/dist/lib/entities/Address.js +10 -0
  10. package/dist/lib/entities/Atoms.d.ts +16 -0
  11. package/dist/lib/entities/Atoms.d.ts.map +1 -0
  12. package/{lib/entities/Atoms.ts → dist/lib/entities/Atoms.js} +2 -6
  13. package/dist/lib/entities/Cart.d.ts +1278 -0
  14. package/dist/lib/entities/Cart.d.ts.map +1 -0
  15. package/dist/lib/entities/Cart.js +18 -0
  16. package/dist/lib/entities/Category.d.ts +103 -0
  17. package/dist/lib/entities/Category.d.ts.map +1 -0
  18. package/dist/lib/entities/Category.js +20 -0
  19. package/dist/lib/entities/Company.d.ts +16 -0
  20. package/dist/lib/entities/Company.d.ts.map +1 -0
  21. package/dist/lib/entities/Company.js +6 -0
  22. package/dist/lib/entities/DeliveryNote.d.ts +248 -0
  23. package/dist/lib/entities/DeliveryNote.d.ts.map +1 -0
  24. package/dist/lib/entities/DeliveryNote.js +61 -0
  25. package/dist/lib/entities/Discount/__tests__/engine.test.d.ts +2 -0
  26. package/dist/lib/entities/Discount/__tests__/engine.test.d.ts.map +1 -0
  27. package/dist/lib/entities/Discount/__tests__/engine.test.js +298 -0
  28. package/dist/lib/entities/Discount/__tests__/factory.test.d.ts +2 -0
  29. package/dist/lib/entities/Discount/__tests__/factory.test.d.ts.map +1 -0
  30. package/dist/lib/entities/Discount/__tests__/factory.test.js +75 -0
  31. package/dist/lib/entities/Discount/__tests__/integration.test.d.ts +2 -0
  32. package/dist/lib/entities/Discount/__tests__/integration.test.d.ts.map +1 -0
  33. package/dist/lib/entities/Discount/__tests__/integration.test.js +115 -0
  34. package/dist/lib/entities/Discount/__tests__/simple.test.d.ts +2 -0
  35. package/dist/lib/entities/Discount/__tests__/simple.test.d.ts.map +1 -0
  36. package/dist/lib/entities/Discount/__tests__/simple.test.js +186 -0
  37. package/dist/lib/entities/Discount/__tests__/utils.test.d.ts +2 -0
  38. package/dist/lib/entities/Discount/__tests__/utils.test.d.ts.map +1 -0
  39. package/dist/lib/entities/Discount/__tests__/utils.test.js +55 -0
  40. package/dist/lib/entities/Discount/engine.d.ts +29 -0
  41. package/dist/lib/entities/Discount/engine.d.ts.map +1 -0
  42. package/dist/lib/entities/Discount/engine.js +85 -0
  43. package/dist/lib/entities/Discount/factory.d.ts +10 -0
  44. package/dist/lib/entities/Discount/factory.d.ts.map +1 -0
  45. package/dist/lib/entities/Discount/factory.js +18 -0
  46. package/dist/lib/entities/Discount/index.d.ts +9 -0
  47. package/dist/lib/entities/Discount/index.d.ts.map +1 -0
  48. package/{lib/entities/Discount/index.ts → dist/lib/entities/Discount/index.js} +0 -2
  49. package/dist/lib/entities/Discount/strategies/BundleStrategy.d.ts +12 -0
  50. package/dist/lib/entities/Discount/strategies/BundleStrategy.d.ts.map +1 -0
  51. package/dist/lib/entities/Discount/strategies/BundleStrategy.js +78 -0
  52. package/dist/lib/entities/Discount/strategies/__tests__/BundleStrategy.test.d.ts +2 -0
  53. package/dist/lib/entities/Discount/strategies/__tests__/BundleStrategy.test.d.ts.map +1 -0
  54. package/dist/lib/entities/Discount/strategies/__tests__/BundleStrategy.test.js +265 -0
  55. package/dist/lib/entities/Discount/strategy.d.ts +6 -0
  56. package/dist/lib/entities/Discount/strategy.d.ts.map +1 -0
  57. package/dist/lib/entities/Discount/types.d.ts +148 -0
  58. package/dist/lib/entities/Discount/types.d.ts.map +1 -0
  59. package/dist/lib/entities/Discount/types.js +29 -0
  60. package/dist/lib/entities/Discount/utils.d.ts +29 -0
  61. package/dist/lib/entities/Discount/utils.d.ts.map +1 -0
  62. package/{lib/entities/Discount/utils.ts → dist/lib/entities/Discount/utils.js} +12 -15
  63. package/dist/lib/entities/FavoriteProduct.d.ts +25 -0
  64. package/dist/lib/entities/FavoriteProduct.d.ts.map +1 -0
  65. package/dist/lib/entities/FavoriteProduct.js +9 -0
  66. package/dist/lib/entities/Invoice.d.ts +210 -0
  67. package/dist/lib/entities/Invoice.d.ts.map +1 -0
  68. package/dist/lib/entities/Invoice.js +49 -0
  69. package/dist/lib/entities/Locale.d.ts +22 -0
  70. package/dist/lib/entities/Locale.d.ts.map +1 -0
  71. package/{lib/entities/Locale.ts → dist/lib/entities/Locale.js} +2 -4
  72. package/dist/lib/entities/Order.d.ts +1806 -0
  73. package/dist/lib/entities/Order.d.ts.map +1 -0
  74. package/dist/lib/entities/Order.js +63 -0
  75. package/dist/lib/entities/Organization.d.ts +100 -0
  76. package/dist/lib/entities/Organization.d.ts.map +1 -0
  77. package/dist/lib/entities/Organization.js +17 -0
  78. package/dist/lib/entities/Payment/index.d.ts +4 -0
  79. package/dist/lib/entities/Payment/index.d.ts.map +1 -0
  80. package/dist/lib/entities/Payment/index.js +4 -0
  81. package/dist/lib/entities/Product.d.ts +694 -0
  82. package/dist/lib/entities/Product.d.ts.map +1 -0
  83. package/dist/lib/entities/Product.js +61 -0
  84. package/dist/lib/entities/Profile.d.ts +95 -0
  85. package/dist/lib/entities/Profile.d.ts.map +1 -0
  86. package/dist/lib/entities/Profile.js +22 -0
  87. package/dist/lib/entities/Store.d.ts +93 -0
  88. package/dist/lib/entities/Store.d.ts.map +1 -0
  89. package/dist/lib/entities/Store.js +21 -0
  90. package/dist/lib/entities/index.d.ts +16 -0
  91. package/dist/lib/entities/index.d.ts.map +1 -0
  92. package/{lib/entities/index.ts → dist/lib/entities/index.js} +1 -0
  93. package/dist/lib/firebase-api/app.d.ts +2 -0
  94. package/dist/lib/firebase-api/app.d.ts.map +1 -0
  95. package/dist/lib/firebase-api/app.js +16 -0
  96. package/dist/lib/firebase-api/index.d.ts +75 -0
  97. package/dist/lib/firebase-api/index.d.ts.map +1 -0
  98. package/dist/lib/firebase-api/index.js +33 -0
  99. package/dist/lib/index.d.ts +4 -0
  100. package/dist/lib/index.d.ts.map +1 -0
  101. package/dist/lib/utils/index.d.ts +109 -0
  102. package/dist/lib/utils/index.d.ts.map +1 -0
  103. package/dist/lib/utils/index.js +95 -0
  104. package/dist/tsconfig.app.tsbuildinfo +1 -0
  105. package/dist/tsconfig.node.tsbuildinfo +1 -0
  106. package/dist/vite.config.d.ts +3 -0
  107. package/dist/vite.config.d.ts.map +1 -0
  108. package/dist/vite.config.js +25 -0
  109. package/package.json +8 -1
  110. package/eslint.config.js +0 -28
  111. package/index.html +0 -13
  112. package/lib/entities/Address.ts +0 -13
  113. package/lib/entities/Cart.ts +0 -24
  114. package/lib/entities/Category.ts +0 -35
  115. package/lib/entities/Company.ts +0 -9
  116. package/lib/entities/DeliveryNote.ts +0 -70
  117. package/lib/entities/Discount/__tests__/engine.test.ts +0 -337
  118. package/lib/entities/Discount/__tests__/factory.test.ts +0 -91
  119. package/lib/entities/Discount/__tests__/integration.test.ts +0 -132
  120. package/lib/entities/Discount/__tests__/simple.test.ts +0 -215
  121. package/lib/entities/Discount/__tests__/utils.test.ts +0 -69
  122. package/lib/entities/Discount/engine.ts +0 -138
  123. package/lib/entities/Discount/factory.ts +0 -25
  124. package/lib/entities/Discount/strategies/BundleStrategy.ts +0 -119
  125. package/lib/entities/Discount/strategies/__tests__/BundleStrategy.test.ts +0 -295
  126. package/lib/entities/Discount/strategy.ts +0 -6
  127. package/lib/entities/Discount/types.ts +0 -68
  128. package/lib/entities/FavoriteProduct.ts +0 -12
  129. package/lib/entities/Invoice.ts +0 -57
  130. package/lib/entities/Order.ts +0 -67
  131. package/lib/entities/Organization.ts +0 -23
  132. package/lib/entities/Product.ts +0 -68
  133. package/lib/entities/Profile.ts +0 -56
  134. package/lib/entities/Store.ts +0 -24
  135. package/lib/firebase-api/app.ts +0 -18
  136. package/lib/firebase-api/index.ts +0 -46
  137. package/lib/utils/index.ts +0 -127
  138. package/src/vite-env.d.ts +0 -1
  139. package/tsconfig.app.json +0 -20
  140. package/tsconfig.json +0 -7
  141. package/tsconfig.node.json +0 -26
  142. package/vite.config.ts +0 -27
  143. package/vitest.config.ts +0 -10
  144. /package/{src/main.tsx → dist/lib/entities/Discount/strategy.js} +0 -0
  145. /package/{lib/index.tsx → dist/lib/index.js} +0 -0
@@ -0,0 +1,298 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { DiscountEngine } from "../engine";
3
+ import { DiscountStrategyFactory } from "../factory";
4
+ import { BundleDiscountStrategy } from "../strategies/BundleStrategy";
5
+ describe("DiscountEngine", () => {
6
+ beforeEach(() => {
7
+ DiscountStrategyFactory.clearStrategies();
8
+ DiscountStrategyFactory.registerStrategy("bundle", new BundleDiscountStrategy());
9
+ });
10
+ afterEach(() => {
11
+ DiscountStrategyFactory.clearStrategies();
12
+ });
13
+ describe("calculateDiscounts", () => {
14
+ it("should apply bundle discount correctly", () => {
15
+ const cart = [
16
+ {
17
+ amount: 2,
18
+ product: {
19
+ id: "product1",
20
+ price: 10,
21
+ },
22
+ },
23
+ {
24
+ amount: 1,
25
+ product: {
26
+ id: "product2",
27
+ price: 15,
28
+ },
29
+ },
30
+ ];
31
+ const discounts = [
32
+ {
33
+ type: "Discount",
34
+ storeId: "store1",
35
+ companyId: "company1",
36
+ id: "bundle1",
37
+ name: [{ lang: "he", value: "Buy 3 for $25" }],
38
+ active: true,
39
+ startDate: Date.now() - 1000,
40
+ endDate: Date.now() + 1000,
41
+ variant: {
42
+ variantType: "bundle",
43
+ productsId: ["product1", "product2"],
44
+ requiredQuantity: 3,
45
+ bundlePrice: 25,
46
+ },
47
+ conditions: {
48
+ stackable: false,
49
+ },
50
+ },
51
+ ];
52
+ const result = DiscountEngine.calculateDiscounts(cart, discounts);
53
+ expect(result.totalDiscount).toBe(10);
54
+ expect(result.appliedDiscounts).toHaveLength(1);
55
+ expect(result.appliedDiscounts[0].discountId).toBe("bundle1");
56
+ expect(result.items).toHaveLength(2);
57
+ // Check final prices
58
+ const product1Item = result.items.find(item => item.product.id === "product1");
59
+ expect(product1Item?.finalPrice).toBeCloseTo(7.14, 2); // 10 - (5.71/2) = 7.145
60
+ const product2Item = result.items.find(item => item.product.id === "product2");
61
+ expect(product2Item?.finalPrice).toBeCloseTo(10.71, 2); // 15 - 4.29 = 10.71
62
+ });
63
+ it("should handle multiple discounts", () => {
64
+ const cart = [
65
+ {
66
+ amount: 4,
67
+ product: {
68
+ id: "product1",
69
+ price: 10,
70
+ },
71
+ },
72
+ ];
73
+ const discounts = [
74
+ {
75
+ type: "Discount",
76
+ storeId: "store1",
77
+ companyId: "company1",
78
+ id: "bundle1",
79
+ name: [{ lang: "he", value: "Buy 3 for $25" }],
80
+ active: true,
81
+ startDate: Date.now() - 1000,
82
+ endDate: Date.now() + 1000,
83
+ variant: {
84
+ variantType: "bundle",
85
+ productsId: ["product1"],
86
+ requiredQuantity: 3,
87
+ bundlePrice: 25,
88
+ },
89
+ conditions: {
90
+ stackable: true, // Allow stacking
91
+ },
92
+ },
93
+ {
94
+ type: "Discount",
95
+ storeId: "store1",
96
+ companyId: "company1",
97
+ id: "bundle2",
98
+ name: [{ lang: "he", value: "Buy 2 for $15" }],
99
+ active: true,
100
+ startDate: Date.now() - 1000,
101
+ endDate: Date.now() + 1000,
102
+ variant: {
103
+ variantType: "bundle",
104
+ productsId: ["product1"],
105
+ requiredQuantity: 2,
106
+ bundlePrice: 15,
107
+ },
108
+ conditions: {
109
+ stackable: true,
110
+ },
111
+ },
112
+ ];
113
+ const result = DiscountEngine.calculateDiscounts(cart, discounts);
114
+ expect(result.appliedDiscounts).toHaveLength(2);
115
+ expect(result.totalDiscount).toBeGreaterThan(0);
116
+ });
117
+ it("should filter out inactive discounts", () => {
118
+ const cart = [
119
+ {
120
+ amount: 3,
121
+ product: {
122
+ id: "product1",
123
+ price: 10,
124
+ },
125
+ },
126
+ ];
127
+ const discounts = [
128
+ {
129
+ type: "Discount",
130
+ storeId: "store1",
131
+ companyId: "company1",
132
+ id: "bundle1",
133
+ name: [{ lang: "he", value: "Buy 3 for $25" }],
134
+ active: false, // Inactive
135
+ startDate: Date.now() - 1000,
136
+ endDate: Date.now() + 1000,
137
+ variant: {
138
+ variantType: "bundle",
139
+ productsId: ["product1"],
140
+ requiredQuantity: 3,
141
+ bundlePrice: 25,
142
+ },
143
+ conditions: {
144
+ stackable: false,
145
+ },
146
+ },
147
+ ];
148
+ const result = DiscountEngine.calculateDiscounts(cart, discounts);
149
+ expect(result.totalDiscount).toBe(0);
150
+ expect(result.appliedDiscounts).toHaveLength(0);
151
+ });
152
+ it("should handle empty cart", () => {
153
+ const cart = [];
154
+ const discounts = [
155
+ {
156
+ type: "Discount",
157
+ storeId: "store1",
158
+ companyId: "company1",
159
+ id: "bundle1",
160
+ name: [{ lang: "he", value: "Buy 3 for $25" }],
161
+ active: true,
162
+ startDate: Date.now() - 1000,
163
+ endDate: Date.now() + 1000,
164
+ variant: {
165
+ variantType: "bundle",
166
+ productsId: ["product1"],
167
+ requiredQuantity: 3,
168
+ bundlePrice: 25,
169
+ },
170
+ conditions: {
171
+ stackable: false,
172
+ },
173
+ },
174
+ ];
175
+ const result = DiscountEngine.calculateDiscounts(cart, discounts);
176
+ expect(result.totalDiscount).toBe(0);
177
+ expect(result.appliedDiscounts).toHaveLength(0);
178
+ expect(result.items).toHaveLength(0);
179
+ });
180
+ it("should handle empty discounts", () => {
181
+ const cart = [
182
+ {
183
+ amount: 2,
184
+ product: {
185
+ id: "product1",
186
+ price: 10,
187
+ },
188
+ },
189
+ ];
190
+ const discounts = [];
191
+ const result = DiscountEngine.calculateDiscounts(cart, discounts);
192
+ expect(result.totalDiscount).toBe(0);
193
+ expect(result.appliedDiscounts).toHaveLength(0);
194
+ expect(result.items).toHaveLength(1);
195
+ expect(result.items[0].finalPrice).toBe(10); // No discount applied
196
+ });
197
+ });
198
+ describe("isDiscountActive", () => {
199
+ it("should return true for active discount", () => {
200
+ const discount = {
201
+ type: "Discount",
202
+ storeId: "store1",
203
+ companyId: "company1",
204
+ id: "bundle1",
205
+ name: [{ lang: "he", value: "Buy 3 for $25" }],
206
+ active: true,
207
+ startDate: Date.now() - 1000,
208
+ endDate: Date.now() + 1000,
209
+ variant: {
210
+ variantType: "bundle",
211
+ productsId: ["product1"],
212
+ requiredQuantity: 3,
213
+ bundlePrice: 25,
214
+ },
215
+ };
216
+ expect(DiscountEngine.isDiscountActive(discount)).toBe(true);
217
+ });
218
+ it("should return false for inactive discount", () => {
219
+ const discount = {
220
+ type: "Discount",
221
+ storeId: "store1",
222
+ companyId: "company1",
223
+ id: "bundle1",
224
+ name: [{ lang: "he", value: "Buy 3 for $25" }],
225
+ active: false,
226
+ startDate: Date.now() - 1000,
227
+ endDate: Date.now() + 1000,
228
+ variant: {
229
+ variantType: "bundle",
230
+ productsId: ["product1"],
231
+ requiredQuantity: 3,
232
+ bundlePrice: 25,
233
+ },
234
+ };
235
+ expect(DiscountEngine.isDiscountActive(discount)).toBe(false);
236
+ });
237
+ it("should return false for expired discount", () => {
238
+ const discount = {
239
+ type: "Discount",
240
+ storeId: "store1",
241
+ companyId: "company1",
242
+ id: "bundle1",
243
+ name: [{ lang: "he", value: "Buy 3 for $25" }],
244
+ active: true,
245
+ startDate: Date.now() - 2000,
246
+ endDate: Date.now() - 1000, // Expired
247
+ variant: {
248
+ variantType: "bundle",
249
+ productsId: ["product1"],
250
+ requiredQuantity: 3,
251
+ bundlePrice: 25,
252
+ },
253
+ };
254
+ expect(DiscountEngine.isDiscountActive(discount)).toBe(false);
255
+ });
256
+ });
257
+ describe("getActiveDiscounts", () => {
258
+ it("should filter active discounts", () => {
259
+ const discounts = [
260
+ {
261
+ type: "Discount",
262
+ storeId: "store1",
263
+ companyId: "company1",
264
+ id: "active1",
265
+ name: [{ lang: "he", value: "Active Discount" }],
266
+ active: true,
267
+ startDate: Date.now() - 1000,
268
+ endDate: Date.now() + 1000,
269
+ variant: {
270
+ variantType: "bundle",
271
+ productsId: ["product1"],
272
+ requiredQuantity: 3,
273
+ bundlePrice: 25,
274
+ },
275
+ },
276
+ {
277
+ type: "Discount",
278
+ storeId: "store1",
279
+ companyId: "company1",
280
+ id: "inactive1",
281
+ name: [{ lang: "he", value: "Inactive Discount" }],
282
+ active: false,
283
+ startDate: Date.now() - 1000,
284
+ endDate: Date.now() + 1000,
285
+ variant: {
286
+ variantType: "bundle",
287
+ productsId: ["product1"],
288
+ requiredQuantity: 3,
289
+ bundlePrice: 25,
290
+ },
291
+ },
292
+ ];
293
+ const activeDiscounts = DiscountEngine.getActiveDiscounts(discounts);
294
+ expect(activeDiscounts).toHaveLength(1);
295
+ expect(activeDiscounts[0].id).toBe("active1");
296
+ });
297
+ });
298
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=factory.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.test.d.ts","sourceRoot":"","sources":["../../../../../lib/entities/Discount/__tests__/factory.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { DiscountStrategyFactory } from "../factory";
3
+ describe("DiscountStrategyFactory", () => {
4
+ beforeEach(() => {
5
+ DiscountStrategyFactory.clearStrategies();
6
+ });
7
+ afterEach(() => {
8
+ DiscountStrategyFactory.clearStrategies();
9
+ });
10
+ it("should register and get strategy", () => {
11
+ const mockStrategy = {
12
+ canApply: () => false,
13
+ calculate: () => ({ applicable: false, discountAmount: 0, affectedItems: [] }),
14
+ };
15
+ DiscountStrategyFactory.registerStrategy("bundle", mockStrategy);
16
+ const discount = {
17
+ type: "Discount",
18
+ storeId: "store1",
19
+ companyId: "company1",
20
+ id: "test1",
21
+ name: [{ lang: "he", value: "Test Discount" }],
22
+ active: true,
23
+ startDate: Date.now() - 1000,
24
+ endDate: Date.now() + 1000,
25
+ variant: {
26
+ variantType: "bundle",
27
+ productsId: ["product1"],
28
+ requiredQuantity: 3,
29
+ bundlePrice: 25,
30
+ },
31
+ };
32
+ const result = DiscountStrategyFactory.getStrategy(discount);
33
+ expect(result).toBe(mockStrategy);
34
+ });
35
+ it("should return null for unregistered strategy", () => {
36
+ const discount = {
37
+ type: "Discount",
38
+ storeId: "store1",
39
+ companyId: "company1",
40
+ id: "test1",
41
+ name: [{ lang: "he", value: "Test Discount" }],
42
+ active: true,
43
+ startDate: Date.now() - 1000,
44
+ endDate: Date.now() + 1000,
45
+ variant: {
46
+ variantType: "bundle",
47
+ productsId: ["product1"],
48
+ requiredQuantity: 3,
49
+ bundlePrice: 25,
50
+ },
51
+ };
52
+ const result = DiscountStrategyFactory.getStrategy(discount);
53
+ expect(result).toBeNull();
54
+ });
55
+ it("should get registered types", () => {
56
+ const mockStrategy = {
57
+ canApply: () => false,
58
+ calculate: () => ({ applicable: false, discountAmount: 0, affectedItems: [] }),
59
+ };
60
+ DiscountStrategyFactory.registerStrategy("bundle", mockStrategy);
61
+ DiscountStrategyFactory.registerStrategy("percentage", mockStrategy);
62
+ const types = DiscountStrategyFactory.getRegisteredTypes();
63
+ expect(types).toEqual(["bundle", "percentage"]);
64
+ });
65
+ it("should clear strategies", () => {
66
+ const mockStrategy = {
67
+ canApply: () => false,
68
+ calculate: () => ({ applicable: false, discountAmount: 0, affectedItems: [] }),
69
+ };
70
+ DiscountStrategyFactory.registerStrategy("bundle", mockStrategy);
71
+ expect(DiscountStrategyFactory.getRegisteredTypes()).toHaveLength(1);
72
+ DiscountStrategyFactory.clearStrategies();
73
+ expect(DiscountStrategyFactory.getRegisteredTypes()).toHaveLength(0);
74
+ });
75
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../../../../lib/entities/Discount/__tests__/integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,115 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { DiscountEngine } from "../engine";
3
+ import { DiscountStrategyFactory } from "../factory";
4
+ import { BundleDiscountStrategy } from "../strategies/BundleStrategy";
5
+ describe("Discount System Integration", () => {
6
+ beforeEach(() => {
7
+ DiscountStrategyFactory.clearStrategies();
8
+ DiscountStrategyFactory.registerStrategy("bundle", new BundleDiscountStrategy());
9
+ });
10
+ afterEach(() => {
11
+ DiscountStrategyFactory.clearStrategies();
12
+ });
13
+ it("should handle real-world bundle scenario", () => {
14
+ // Scenario: Buy 3 dairy products for $20
15
+ const cart = [
16
+ {
17
+ amount: 2, // 2 milk
18
+ product: {
19
+ id: "milk",
20
+ price: 8, // $8 each
21
+ },
22
+ },
23
+ {
24
+ amount: 1, // 1 yogurt
25
+ product: {
26
+ id: "yogurt",
27
+ price: 6, // $6 each
28
+ },
29
+ },
30
+ {
31
+ amount: 1, // 1 bread (not in bundle)
32
+ product: {
33
+ id: "bread",
34
+ price: 4, // $4 each
35
+ },
36
+ },
37
+ ];
38
+ const dairyBundle = {
39
+ type: "Discount",
40
+ storeId: "store1",
41
+ companyId: "company1",
42
+ id: "dairy-bundle",
43
+ name: [{ lang: "he", value: "3 Dairy Products for $20" }],
44
+ active: true,
45
+ startDate: Date.now() - 1000,
46
+ endDate: Date.now() + 1000,
47
+ variant: {
48
+ variantType: "bundle",
49
+ productsId: ["milk", "yogurt", "cheese"], // Dairy products
50
+ requiredQuantity: 3,
51
+ bundlePrice: 20,
52
+ },
53
+ conditions: {
54
+ stackable: false,
55
+ },
56
+ };
57
+ const result = DiscountEngine.calculateDiscounts(cart, [dairyBundle]);
58
+ // Original prices:
59
+ // milk: 2 × $8 = $16
60
+ // yogurt: 1 × $6 = $6
61
+ // bread: 1 × $4 = $4
62
+ // Total: $26
63
+ // Bundle applies to milk + yogurt (3 items for $20)
64
+ // Remaining: bread at $4
65
+ // New total: $24
66
+ expect(result.totalDiscount).toBe(2); // $26 - $24
67
+ expect(result.appliedDiscounts).toHaveLength(1);
68
+ expect(result.appliedDiscounts[0].discountId).toBe("dairy-bundle");
69
+ // Check individual item prices
70
+ const milkItem = result.items.find(item => item.product.id === "milk");
71
+ expect(milkItem?.finalPrice).toBeCloseTo(7.28, 2); // 8 - (1.45/2) = 7.275
72
+ const yogurtItem = result.items.find(item => item.product.id === "yogurt");
73
+ expect(yogurtItem?.finalPrice).toBeCloseTo(5.45, 2); // 6 - 0.55 = 5.45
74
+ const breadItem = result.items.find(item => item.product.id === "bread");
75
+ expect(breadItem?.finalPrice).toBe(4); // No discount
76
+ });
77
+ it("should handle BOGO scenario", () => {
78
+ // Scenario: Buy 2 Get 1 Free
79
+ const cart = [
80
+ {
81
+ amount: 3, // Buy 3 items
82
+ product: {
83
+ id: "product1",
84
+ price: 10, // $10 each
85
+ },
86
+ },
87
+ ];
88
+ const bogoDiscount = {
89
+ type: "Discount",
90
+ storeId: "store1",
91
+ companyId: "company1",
92
+ id: "bogo",
93
+ name: [{ lang: "he", value: "Buy 2 Get 1 Free" }],
94
+ active: true,
95
+ startDate: Date.now() - 1000,
96
+ endDate: Date.now() + 1000,
97
+ variant: {
98
+ variantType: "bundle",
99
+ productsId: ["product1"],
100
+ requiredQuantity: 3, // Buy 2 + get 1 free = 3 items
101
+ bundlePrice: 20, // Price of 2 items (10 × 2)
102
+ },
103
+ conditions: {
104
+ stackable: false,
105
+ },
106
+ };
107
+ const result = DiscountEngine.calculateDiscounts(cart, [bogoDiscount]);
108
+ // Original: 3 × $10 = $30
109
+ // Bundle: 3 items for $20
110
+ // Discount: $10
111
+ expect(result.totalDiscount).toBe(10);
112
+ expect(result.appliedDiscounts).toHaveLength(1);
113
+ expect(result.items[0].finalPrice).toBeCloseTo(6.67, 2); // $20 / 3
114
+ });
115
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=simple.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple.test.d.ts","sourceRoot":"","sources":["../../../../../lib/entities/Discount/__tests__/simple.test.ts"],"names":[],"mappings":""}