@unchainedshop/utils 3.0.0-alpha3 → 3.0.0-alpha4
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/lib/locale-helpers.d.ts +6 -4
- package/lib/locale-helpers.d.ts.map +1 -1
- package/lib/locale-helpers.js.map +1 -1
- package/package.json +5 -5
- package/src/calculation.test.ts +24 -32
- package/src/director/base-director.test.ts +55 -66
- package/src/director/base-discount-adapter.test.ts +22 -25
- package/src/director/base-price-sheet.test.ts +50 -56
- package/src/locale-helpers.ts +2 -4
- package/src/utils-index.test.ts +47 -57
package/lib/locale-helpers.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { Country } from '@unchainedshop/core-countries';
|
|
2
|
-
import { Currency } from '@unchainedshop/core-currencies';
|
|
3
1
|
export declare const systemLocale: Intl.Locale;
|
|
4
2
|
export declare const resolveBestSupported: (acceptLanguage: string, supportedLocales: Array<string>, fallbackLocale: string) => Intl.Locale;
|
|
5
|
-
export declare const resolveBestCountry: (localeCountry: string, shopCountry: string, countries: Array<
|
|
6
|
-
|
|
3
|
+
export declare const resolveBestCountry: (localeCountry: string, shopCountry: string, countries: Array<{
|
|
4
|
+
isoCode: string;
|
|
5
|
+
}>) => string;
|
|
6
|
+
export declare const resolveBestCurrency: (localeCurrency: string, currencies: Array<{
|
|
7
|
+
isoCode: string;
|
|
8
|
+
}>) => string;
|
|
7
9
|
//# sourceMappingURL=locale-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale-helpers.d.ts","sourceRoot":"","sources":["../src/locale-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"locale-helpers.d.ts","sourceRoot":"","sources":["../src/locale-helpers.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,aAA4D,CAAC;AAEtF,eAAO,MAAM,oBAAoB,mBACf,MAAM,oBACJ,KAAK,CAAC,MAAM,CAAC,kBACf,MAAM,KACrB,IAAI,CAAC,MAKP,CAAC;AAEF,eAAO,MAAM,kBAAkB,kBACd,MAAM,eACR,MAAM,aACR,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,WActC,CAAC;AAEF,eAAO,MAAM,mBAAmB,mBAAoB,MAAM,cAAc,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,WAcjG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale-helpers.js","sourceRoot":"","sources":["../src/locale-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"locale-helpers.js","sourceRoot":"","sources":["../src/locale-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,EAAE,cAAc,GAAG,IAAI,EAAE,iBAAiB,GAAG,IAAI,EAAE,kBAAkB,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;AAEpG,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,cAAc,IAAI,iBAAiB,EAAE,CAAC,CAAC;AAEtF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,cAAsB,EACtB,gBAA+B,EAC/B,cAAsB,EACT,EAAE;IACf,MAAM,EAAE,KAAK,EAAE,GAAG,qBAAqB,CAAC,cAAc,IAAI,EAAE,EAAE,gBAAgB,EAAE,cAAc,EAAE;QAC9F,eAAe,EAAE,IAAI;KACtB,CAAC,CAAC;IACH,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,aAAqB,EACrB,WAAmB,EACnB,SAAqC,EACrC,EAAE;IACF,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CAAS,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE;YACzE,IAAI,WAAW,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpC,OAAO,OAAO,CAAC,OAAO,CAAC;YACzB,CAAC;YACD,OAAO,YAAY,CAAC;QACtB,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,eAAe,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,aAAa,IAAI,YAAY,CAAC,MAAM,CAAC;AAC9C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,cAAsB,EAAE,UAAsC,EAAE,EAAE;IACpG,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,gBAAgB,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,KAAK,cAAc,CAAC,CAAC;QAC5F,IAAI,gBAAgB,EAAE,CAAC;YACrB,OAAO,gBAAgB,CAAC,OAAO,CAAC;QAClC,CAAC;IACH,CAAC;IAED,MAAM,gBAAgB,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,KAAK,kBAAkB,CAAC,CAAC;IAChG,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,gBAAgB,CAAC,OAAO,CAAC;IAClC,CAAC;IAED,OAAO,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,kBAAkB,CAAC;AACxD,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/utils",
|
|
3
|
-
"version": "3.0.0-
|
|
3
|
+
"version": "3.0.0-alpha4",
|
|
4
4
|
"main": "lib/utils-index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./lib/utils-index.js",
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@unchainedshop/logger": "^3.0.0-
|
|
33
|
+
"@unchainedshop/logger": "^3.0.0-alpha4",
|
|
34
34
|
"hashids": "^2.3.0",
|
|
35
|
-
"resolve-accept-language": "^3.1.
|
|
35
|
+
"resolve-accept-language": "^3.1.8"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@types/node": "^22.
|
|
38
|
+
"@types/node": "^22.7.8",
|
|
39
39
|
"jest": "^29.7.0",
|
|
40
|
-
"typescript": "^5.6.
|
|
40
|
+
"typescript": "^5.6.3"
|
|
41
41
|
}
|
|
42
42
|
}
|
package/src/calculation.test.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
applyRate,
|
|
3
|
+
resolveRatioAndTaxDivisorForPricingSheet,
|
|
4
|
+
roundToNext,
|
|
5
|
+
resolveAmountAndTax,
|
|
6
|
+
applyDiscountToMultipleShares,
|
|
7
|
+
calculateAmountToSplit,
|
|
8
|
+
} from './calculation';
|
|
2
9
|
|
|
3
10
|
describe('roundToNext', () => {
|
|
4
11
|
it('rounds to the next multiple of precision correctly when the value is positive', () => {
|
|
@@ -20,10 +27,9 @@ describe('roundToNext', () => {
|
|
|
20
27
|
it('returns the same value when the precision is 1', () => {
|
|
21
28
|
expect(roundToNext(5, 1)).toBe(5);
|
|
22
29
|
});
|
|
23
|
-
|
|
24
30
|
});
|
|
25
31
|
|
|
26
|
-
describe(
|
|
32
|
+
describe('resolveRatioAndTaxDivisorForPricingSheet', () => {
|
|
27
33
|
it('total is 0 and pricing is provided', () => {
|
|
28
34
|
const pricing: any = {
|
|
29
35
|
taxSum: () => 10,
|
|
@@ -63,11 +69,9 @@ describe("resolveRatioAndTaxDivisorForPricingSheet", () => {
|
|
|
63
69
|
const result = resolveRatioAndTaxDivisorForPricingSheet(pricing, 20);
|
|
64
70
|
expect(result).toEqual({ ratio: 1, taxDivisor: 1 });
|
|
65
71
|
});
|
|
72
|
+
});
|
|
66
73
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
describe("resolveAmountAndTax", () => {
|
|
74
|
+
describe('resolveAmountAndTax', () => {
|
|
71
75
|
it('ratio is 0 and taxDivisor is 0', () => {
|
|
72
76
|
const result = resolveAmountAndTax({ ratio: 0, taxDivisor: 0 }, 100);
|
|
73
77
|
expect(result).toEqual([0, 0]);
|
|
@@ -83,7 +87,6 @@ describe("resolveAmountAndTax", () => {
|
|
|
83
87
|
expect(result).toEqual([0, 0]);
|
|
84
88
|
});
|
|
85
89
|
|
|
86
|
-
|
|
87
90
|
it('ratio and taxDivisor are not 0', () => {
|
|
88
91
|
const result = resolveAmountAndTax({ ratio: 0.5, taxDivisor: 2 }, 100);
|
|
89
92
|
expect(result).toEqual([50, 25]);
|
|
@@ -93,9 +96,9 @@ describe("resolveAmountAndTax", () => {
|
|
|
93
96
|
const result = resolveAmountAndTax({ ratio: Number.NaN, taxDivisor: Number.NaN }, 100);
|
|
94
97
|
expect(result).toEqual([0, 0]);
|
|
95
98
|
});
|
|
96
|
-
})
|
|
99
|
+
});
|
|
97
100
|
|
|
98
|
-
describe(
|
|
101
|
+
describe('resolveAmountAndTax', () => {
|
|
99
102
|
it('shares are empty', () => {
|
|
100
103
|
const result = applyDiscountToMultipleShares([], 100);
|
|
101
104
|
expect(result).toEqual([0, 0]);
|
|
@@ -115,12 +118,12 @@ describe("resolveAmountAndTax", () => {
|
|
|
115
118
|
const result = applyDiscountToMultipleShares(shares, 100);
|
|
116
119
|
expect(result).toEqual([70, 31.666666666666664]);
|
|
117
120
|
});
|
|
118
|
-
})
|
|
121
|
+
});
|
|
119
122
|
|
|
120
123
|
describe('applyRate', () => {
|
|
121
124
|
it('applies the rate correctly when a rate is provided', () => {
|
|
122
125
|
const configuration = {
|
|
123
|
-
rate: 0.1
|
|
126
|
+
rate: 0.1,
|
|
124
127
|
};
|
|
125
128
|
const amount = 100;
|
|
126
129
|
expect(applyRate(configuration, amount)).toBe(10);
|
|
@@ -128,7 +131,7 @@ describe('applyRate', () => {
|
|
|
128
131
|
|
|
129
132
|
it('applies the fixed rate correctly when a fixed rate is provided', () => {
|
|
130
133
|
const configuration = {
|
|
131
|
-
fixedRate: 50
|
|
134
|
+
fixedRate: 50,
|
|
132
135
|
};
|
|
133
136
|
const amount = 100;
|
|
134
137
|
expect(applyRate(configuration, amount)).toBe(50);
|
|
@@ -136,7 +139,7 @@ describe('applyRate', () => {
|
|
|
136
139
|
|
|
137
140
|
it('applies the fixed rate correctly when a fixed rate is provided and the amount is less than fixed rate', () => {
|
|
138
141
|
const configuration = {
|
|
139
|
-
fixedRate: 150
|
|
142
|
+
fixedRate: 150,
|
|
140
143
|
};
|
|
141
144
|
const amount = 100;
|
|
142
145
|
expect(applyRate(configuration, amount)).toBe(100);
|
|
@@ -144,48 +147,43 @@ describe('applyRate', () => {
|
|
|
144
147
|
|
|
145
148
|
it('applies the rate correctly when rate is less than or equal to 0', () => {
|
|
146
149
|
const configuration = {
|
|
147
|
-
rate: -0.1
|
|
150
|
+
rate: -0.1,
|
|
148
151
|
};
|
|
149
152
|
const amount = 100;
|
|
150
153
|
expect(applyRate(configuration, amount)).toBe(-10);
|
|
151
154
|
});
|
|
152
155
|
it('applies the rate correctly when only rate is provided and amount is negative', () => {
|
|
153
156
|
const configuration = {
|
|
154
|
-
rate: 0.1
|
|
157
|
+
rate: 0.1,
|
|
155
158
|
};
|
|
156
159
|
const amount = -100;
|
|
157
160
|
expect(applyRate(configuration, amount)).toBe(-10);
|
|
158
161
|
});
|
|
159
162
|
|
|
160
|
-
|
|
161
163
|
it('applies the rate correctly when only rate is provided and amount is negative', () => {
|
|
162
164
|
const configuration = {
|
|
163
|
-
rate: 0.1
|
|
165
|
+
rate: 0.1,
|
|
164
166
|
};
|
|
165
167
|
const amount = -100;
|
|
166
168
|
expect(applyRate(configuration, amount)).toBe(-10);
|
|
167
169
|
});
|
|
168
170
|
|
|
169
|
-
|
|
170
171
|
it('applies the rate correctly when only rate is provided and amount is negative', () => {
|
|
171
172
|
const configuration = {
|
|
172
|
-
rate: 0.1
|
|
173
|
+
rate: 0.1,
|
|
173
174
|
};
|
|
174
175
|
const amount = -100;
|
|
175
176
|
expect(applyRate(configuration, amount)).toBe(-10);
|
|
176
177
|
});
|
|
177
178
|
|
|
178
|
-
|
|
179
|
-
|
|
180
179
|
it('applies the rate correctly when only rate is provided and amount is negative', () => {
|
|
181
180
|
const configuration = {
|
|
182
|
-
rate: 0.1
|
|
181
|
+
rate: 0.1,
|
|
183
182
|
};
|
|
184
183
|
const amount = -100;
|
|
185
184
|
expect(applyRate(configuration, amount)).toBe(-10);
|
|
186
185
|
});
|
|
187
186
|
|
|
188
|
-
|
|
189
187
|
it('returns 0 when rate and fixed rate are not provided', () => {
|
|
190
188
|
const configuration = {};
|
|
191
189
|
const amount = 100;
|
|
@@ -194,7 +192,7 @@ describe('applyRate', () => {
|
|
|
194
192
|
|
|
195
193
|
it('applies the rate correctly when only rate is provided and amount is negative', () => {
|
|
196
194
|
const configuration = {
|
|
197
|
-
rate: 0.1
|
|
195
|
+
rate: 0.1,
|
|
198
196
|
};
|
|
199
197
|
const amount = -100;
|
|
200
198
|
expect(applyRate(configuration, amount)).toBe(-10);
|
|
@@ -205,11 +203,8 @@ describe('applyRate', () => {
|
|
|
205
203
|
const amount = 100;
|
|
206
204
|
expect(applyRate(configuration, amount)).toBe(0);
|
|
207
205
|
});
|
|
208
|
-
|
|
209
|
-
|
|
210
206
|
});
|
|
211
207
|
|
|
212
|
-
|
|
213
208
|
describe('calculateAmountToSplit', () => {
|
|
214
209
|
it('calculates the correct amount to split when using a rate', () => {
|
|
215
210
|
const configuration = {
|
|
@@ -235,7 +230,6 @@ describe('calculateAmountToSplit', () => {
|
|
|
235
230
|
expect(calculateAmountToSplit(configuration, amount)).toBe(0);
|
|
236
231
|
});
|
|
237
232
|
|
|
238
|
-
|
|
239
233
|
it('returns 0 when amount is negative', () => {
|
|
240
234
|
const configuration = {
|
|
241
235
|
rate: 0.1,
|
|
@@ -251,6 +245,4 @@ describe('calculateAmountToSplit', () => {
|
|
|
251
245
|
const amount = 1000;
|
|
252
246
|
expect(calculateAmountToSplit(configuration, amount)).toBe(0);
|
|
253
247
|
});
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
});
|
|
248
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseDirector } from
|
|
1
|
+
import { BaseDirector } from './BaseDirector.js';
|
|
2
2
|
|
|
3
3
|
const adapter1 = {
|
|
4
4
|
key: 'adapter1',
|
|
@@ -31,99 +31,88 @@ describe('BaseDirector', () => {
|
|
|
31
31
|
director.registerAdapter(adapter2);
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
describe('registerAdapter',
|
|
35
|
-
|
|
34
|
+
describe('registerAdapter', () => {
|
|
36
35
|
it('should add the adapter to the director', () => {
|
|
37
36
|
director.registerAdapter(adapter1);
|
|
38
37
|
expect(director.getAdapter(adapter1.key)).toBe(adapter1);
|
|
39
38
|
});
|
|
40
|
-
|
|
39
|
+
|
|
41
40
|
xit('should generate a log message when an adapter is registered', () => {
|
|
42
|
-
const spy = import.meta.jest.spyOn(console, 'log')
|
|
43
|
-
|
|
44
|
-
'TestDirector -> Registered adapter1 1.0.0 (Adapter 1)',
|
|
45
|
-
);
|
|
41
|
+
const spy = import.meta.jest.spyOn(console, 'log');
|
|
42
|
+
expect(spy).toHaveBeenCalledWith('TestDirector -> Registered adapter1 1.0.0 (Adapter 1)');
|
|
46
43
|
});
|
|
47
|
-
|
|
44
|
+
|
|
48
45
|
it('should allow multiple adapters to be registered', () => {
|
|
49
46
|
expect(director.getAdapter(adapter1.key)).toBe(adapter1);
|
|
50
47
|
expect(director.getAdapter(adapter2.key)).toBe(adapter2);
|
|
51
48
|
});
|
|
52
|
-
|
|
49
|
+
|
|
53
50
|
it('should register an adapter and add it to the internal map', () => {
|
|
54
51
|
expect(director.getAdapter(adapter1.key)).toEqual(adapter1);
|
|
55
52
|
});
|
|
56
|
-
|
|
53
|
+
|
|
57
54
|
it('should use the adapterKeyField specified in the options to store the adapter in the internal map', () => {
|
|
58
|
-
|
|
59
55
|
director = BaseDirector('TestDirector', {
|
|
60
56
|
adapterKeyField: 'label',
|
|
61
57
|
});
|
|
62
58
|
director.registerAdapter(adapter1);
|
|
63
59
|
expect(director.getAdapter(adapter1.label)).toEqual(adapter1);
|
|
64
60
|
});
|
|
65
|
-
|
|
66
|
-
it('should return the correct Adapter object', () => {
|
|
67
|
-
const directorName = 'TestDirector';
|
|
68
|
-
const adapterKeyField = 'key';
|
|
69
|
-
director = BaseDirector(directorName, { adapterKeyField });
|
|
70
|
-
director.registerAdapter(adapter1);
|
|
71
|
-
|
|
72
|
-
expect(director.getAdapter(adapter1.key)).toEqual(adapter1);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('should return undefined if the Adapter does not exist', () => {
|
|
76
|
-
const directorName = 'TestDirector';
|
|
77
|
-
const adapterKeyField = 'key';
|
|
78
|
-
director = BaseDirector(directorName, { adapterKeyField });
|
|
79
|
-
expect(director.getAdapter(adapter1.key)).toBeUndefined();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
})
|
|
83
61
|
|
|
62
|
+
it('should return the correct Adapter object', () => {
|
|
63
|
+
const directorName = 'TestDirector';
|
|
64
|
+
const adapterKeyField = 'key';
|
|
65
|
+
director = BaseDirector(directorName, { adapterKeyField });
|
|
66
|
+
director.registerAdapter(adapter1);
|
|
84
67
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// Expect that calling getAdapter with the key 'foo' returns the fooAdapter
|
|
88
|
-
expect(director.getAdapter(adapter1.key)).toBe(adapter1);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('should return undefined if no Adapter is registered with the given key', () => {
|
|
92
|
-
// Expect that calling getAdapter with a key that has not been registered returns undefined
|
|
93
|
-
expect(director.getAdapter('invalid-key')).toBeUndefined();
|
|
94
|
-
});
|
|
68
|
+
expect(director.getAdapter(adapter1.key)).toEqual(adapter1);
|
|
69
|
+
});
|
|
95
70
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
71
|
+
it('should return undefined if the Adapter does not exist', () => {
|
|
72
|
+
const directorName = 'TestDirector';
|
|
73
|
+
const adapterKeyField = 'key';
|
|
74
|
+
director = BaseDirector(directorName, { adapterKeyField });
|
|
75
|
+
expect(director.getAdapter(adapter1.key)).toBeUndefined();
|
|
76
|
+
});
|
|
101
77
|
});
|
|
102
|
-
});
|
|
103
78
|
|
|
104
|
-
describe('
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
79
|
+
describe('getAdapter', () => {
|
|
80
|
+
it('should return the correct Adapter object for a given key', () => {
|
|
81
|
+
// Expect that calling getAdapter with the key 'foo' returns the fooAdapter
|
|
82
|
+
expect(director.getAdapter(adapter1.key)).toBe(adapter1);
|
|
83
|
+
});
|
|
108
84
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
expect(baseDirector.getAdapters()).toEqual([]);
|
|
114
|
-
});
|
|
85
|
+
it('should return undefined if no Adapter is registered with the given key', () => {
|
|
86
|
+
// Expect that calling getAdapter with a key that has not been registered returns undefined
|
|
87
|
+
expect(director.getAdapter('invalid-key')).toBeUndefined();
|
|
88
|
+
});
|
|
115
89
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
90
|
+
it('should return the correct Adapter object when the keyField is set to a property other than "key"', () => {
|
|
91
|
+
// Create a director with the keyField option set to 'label'
|
|
92
|
+
director = BaseDirector('TestDirector', { adapterKeyField: 'label' });
|
|
93
|
+
director.registerAdapter(adapter1);
|
|
94
|
+
expect(director.getAdapter(adapter1.label)).toBe(adapter1);
|
|
95
|
+
});
|
|
122
96
|
});
|
|
123
97
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
})
|
|
98
|
+
describe('getAdapters', () => {
|
|
99
|
+
it('should return an array of registered Adapter objects', () => {
|
|
100
|
+
expect(director.getAdapters()).toEqual([adapter1, adapter3, adapter2]);
|
|
101
|
+
});
|
|
128
102
|
|
|
103
|
+
it('should return an empty array if no Adapter objects have been registered', () => {
|
|
104
|
+
const directorName = 'TestDirector';
|
|
105
|
+
const adapterKeyField = 'key';
|
|
106
|
+
const baseDirector = BaseDirector(directorName, { adapterKeyField });
|
|
107
|
+
expect(baseDirector.getAdapters()).toEqual([]);
|
|
108
|
+
});
|
|
129
109
|
|
|
110
|
+
it('should return an array of registered Adapter objects sorted by the adapterSortKey provided', () => {
|
|
111
|
+
director = BaseDirector('TestDirector', { adapterSortKey: 'version' });
|
|
112
|
+
director.registerAdapter(adapter1);
|
|
113
|
+
director.registerAdapter(adapter3);
|
|
114
|
+
director.registerAdapter(adapter2);
|
|
115
|
+
expect(director.getAdapters()).toEqual([adapter1, adapter2, adapter3]);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { BaseDiscountAdapter } from
|
|
1
|
+
import { BaseDiscountAdapter } from './BaseDiscountAdapter.js';
|
|
2
2
|
|
|
3
|
-
describe(
|
|
3
|
+
describe('BaseDiscountAdapter instantiation', () => {
|
|
4
4
|
const adapter = BaseDiscountAdapter;
|
|
5
|
-
const context = null
|
|
6
|
-
it(
|
|
5
|
+
const context = null as any;
|
|
6
|
+
it('should initialize with default values', async () => {
|
|
7
7
|
expect(adapter.orderIndex).toEqual(0);
|
|
8
8
|
expect(adapter.log).toEqual(expect.any(Function));
|
|
9
|
-
expect(adapter.isManualAdditionAllowed('')).
|
|
10
|
-
expect(adapter.isManualRemovalAllowed()).
|
|
11
|
-
|
|
12
|
-
expect(adapter.actions(context)).resolves.toEqual({
|
|
9
|
+
expect(await adapter.isManualAdditionAllowed('')).toEqual(false);
|
|
10
|
+
expect(await adapter.isManualRemovalAllowed()).toEqual(false);
|
|
11
|
+
expect(await adapter.actions(context)).toEqual({
|
|
13
12
|
isValidForSystemTriggering: expect.any(Function),
|
|
14
13
|
reserve: expect.any(Function),
|
|
15
14
|
release: expect.any(Function),
|
|
@@ -18,35 +17,33 @@ describe("BaseDiscountAdapter instantiation", () => {
|
|
|
18
17
|
});
|
|
19
18
|
});
|
|
20
19
|
|
|
21
|
-
describe('actions',
|
|
22
|
-
const actions = adapter.actions(context)
|
|
23
|
-
|
|
20
|
+
describe('actions', () => {
|
|
24
21
|
it('isValidForSystemTriggering', async () => {
|
|
25
22
|
const result = await adapter.actions(context);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
})
|
|
23
|
+
expect(await result.isValidForSystemTriggering()).toEqual(false);
|
|
24
|
+
});
|
|
29
25
|
|
|
30
26
|
it('reserve', async () => {
|
|
31
27
|
const result = await adapter.actions(context);
|
|
32
|
-
expect(await result.reserve({code: ''})).toEqual({})
|
|
33
|
-
})
|
|
28
|
+
expect(await result.reserve({ code: '' })).toEqual({});
|
|
29
|
+
});
|
|
34
30
|
|
|
35
31
|
it('release', async () => {
|
|
36
32
|
const result = await adapter.actions(context);
|
|
37
|
-
expect(await result.release()).toEqual(null)
|
|
38
|
-
})
|
|
33
|
+
expect(await result.release()).toEqual(null);
|
|
34
|
+
});
|
|
39
35
|
|
|
40
36
|
it('isValidForCodeTriggering', async () => {
|
|
41
37
|
const result = await adapter.actions(context);
|
|
42
|
-
expect(await result.isValidForCodeTriggering({code: ''})).toEqual(false)
|
|
43
|
-
})
|
|
38
|
+
expect(await result.isValidForCodeTriggering({ code: '' })).toEqual(false);
|
|
39
|
+
});
|
|
44
40
|
|
|
45
41
|
it('discountForPricingAdapterKey', async () => {
|
|
46
42
|
const result = await adapter.actions(context);
|
|
47
|
-
const calculationSheet = {}
|
|
48
|
-
expect(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
const calculationSheet = {};
|
|
44
|
+
expect(
|
|
45
|
+
await result.discountForPricingAdapterKey({ calculationSheet, pricingAdapterKey: 'key' } as any),
|
|
46
|
+
).toEqual(null);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
52
49
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BasePricingSheet } from
|
|
1
|
+
import { BasePricingSheet } from './BasePricingSheet.js';
|
|
2
2
|
|
|
3
3
|
describe('BasePricingSheet', () => {
|
|
4
4
|
let pricingSheet;
|
|
@@ -9,7 +9,7 @@ describe('BasePricingSheet', () => {
|
|
|
9
9
|
const calculations = [TAX, DISCOUNT, ITEM1, ITEM2];
|
|
10
10
|
|
|
11
11
|
beforeEach(() => {
|
|
12
|
-
pricingSheet =
|
|
12
|
+
pricingSheet = BasePricingSheet({
|
|
13
13
|
calculation: calculations,
|
|
14
14
|
});
|
|
15
15
|
});
|
|
@@ -21,86 +21,80 @@ describe('BasePricingSheet', () => {
|
|
|
21
21
|
it('gross() returns 0 if the calculation is empty', () => {
|
|
22
22
|
expect(BasePricingSheet({ calculation: [] }).gross()).toEqual(0);
|
|
23
23
|
});
|
|
24
|
-
|
|
25
24
|
|
|
25
|
+
it('total() calculates the sum of the amounts in the calculations by default', () => {
|
|
26
|
+
expect(pricingSheet.total()).toEqual({ amount: 550, currency: undefined });
|
|
27
|
+
});
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
it('total() calculates the sum of the amounts in the calculations for a given category', () => {
|
|
32
|
-
expect(pricingSheet.total({ category: 'item' })).toEqual({ amount: 400, currency: undefined });
|
|
33
|
-
});
|
|
29
|
+
it('total() calculates the sum of the amounts in the calculations for a given category', () => {
|
|
30
|
+
expect(pricingSheet.total({ category: 'item' })).toEqual({ amount: 400, currency: undefined });
|
|
31
|
+
});
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
it('total() calculates the net sum of the amounts in the calculations if useNetPrice is true', () => {
|
|
34
|
+
expect(pricingSheet.total({ useNetPrice: true })).toEqual({ amount: 550, currency: undefined });
|
|
35
|
+
});
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
it('calculates the correct net amount', () => {
|
|
44
|
-
expect(pricingSheet.net()).toEqual(550);
|
|
45
|
-
});
|
|
37
|
+
it('total() returns 0 if the calculation is empty', () => {
|
|
38
|
+
expect(BasePricingSheet({ calculation: [] }).total()).toEqual({ amount: 0, currency: undefined });
|
|
39
|
+
});
|
|
46
40
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
it('calculates the correct net amount', () => {
|
|
42
|
+
expect(pricingSheet.net()).toEqual(550);
|
|
43
|
+
});
|
|
50
44
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
it('calculates the correct sum for a given category', () => {
|
|
46
|
+
expect(pricingSheet.sum({ category: 'item' })).toEqual(400);
|
|
47
|
+
});
|
|
54
48
|
|
|
55
|
-
|
|
49
|
+
it('calculates the correct tax amount', () => {
|
|
50
|
+
expect(pricingSheet.taxSum()).toEqual(0);
|
|
51
|
+
});
|
|
56
52
|
|
|
57
53
|
describe('getRawPricingSheet', () => {
|
|
58
|
-
it('returns the correct list of calculations', () => {
|
|
54
|
+
it('returns the correct list of calculations', () => {
|
|
59
55
|
expect(pricingSheet.getRawPricingSheet()).toEqual(calculations);
|
|
60
56
|
});
|
|
61
|
-
|
|
57
|
+
|
|
62
58
|
it('returns an empty list of calculations if none are provided', () => {
|
|
63
59
|
expect(BasePricingSheet({}).getRawPricingSheet()).toEqual([]);
|
|
64
60
|
});
|
|
65
61
|
});
|
|
66
|
-
|
|
67
62
|
|
|
68
|
-
describe('isValid', () => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
describe('isValid', () => {
|
|
64
|
+
it('returns true if the sheet has calculations', () => {
|
|
65
|
+
expect(pricingSheet.isValid()).toEqual(true);
|
|
66
|
+
});
|
|
72
67
|
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
it('returns false if the sheet does not have calculations', () => {
|
|
69
|
+
expect(BasePricingSheet({}).isValid()).toEqual(false);
|
|
70
|
+
});
|
|
75
71
|
});
|
|
76
|
-
});
|
|
77
72
|
|
|
78
|
-
describe('filterBy', () => {
|
|
73
|
+
describe('filterBy', () => {
|
|
79
74
|
it('filters the list of calculations correctly', () => {
|
|
80
75
|
expect(pricingSheet.filterBy({ category: 'item' })).toEqual([ITEM1, ITEM2]);
|
|
81
76
|
});
|
|
82
77
|
|
|
83
78
|
it('returns the full list of calculations if no filter is provided', () => {
|
|
84
|
-
|
|
85
|
-
})
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
expect(pricingSheet.filterBy()).toEqual(calculations);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
89
82
|
|
|
90
|
-
describe('resetCalculation', () => {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
83
|
+
describe('resetCalculation', () => {
|
|
84
|
+
it('resets the list of calculations correctly', () => {
|
|
85
|
+
const expectedCalculations = calculations.reduce(
|
|
86
|
+
(prev, { amount, ...row }) => {
|
|
87
|
+
return [
|
|
94
88
|
...prev,
|
|
95
89
|
{
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
90
|
+
...row,
|
|
91
|
+
amount: -amount,
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
},
|
|
95
|
+
[...calculations],
|
|
96
|
+
);
|
|
97
|
+
expect(pricingSheet.resetCalculation(pricingSheet)).toEqual(expectedCalculations);
|
|
98
|
+
});
|
|
102
99
|
});
|
|
103
|
-
|
|
104
|
-
})
|
|
105
|
-
|
|
106
100
|
});
|
package/src/locale-helpers.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { Country } from '@unchainedshop/core-countries';
|
|
2
|
-
import { Currency } from '@unchainedshop/core-currencies';
|
|
3
1
|
import { resolveAcceptLanguage } from 'resolve-accept-language';
|
|
4
2
|
|
|
5
3
|
const { UNCHAINED_LANG = 'de', UNCHAINED_COUNTRY = 'CH', UNCHAINED_CURRENCY = 'CHF' } = process.env;
|
|
@@ -20,7 +18,7 @@ export const resolveBestSupported = (
|
|
|
20
18
|
export const resolveBestCountry = (
|
|
21
19
|
localeCountry: string,
|
|
22
20
|
shopCountry: string,
|
|
23
|
-
countries: Array<
|
|
21
|
+
countries: Array<{ isoCode: string }>,
|
|
24
22
|
) => {
|
|
25
23
|
if (shopCountry) {
|
|
26
24
|
const resolvedCountry = countries.reduce<string>((lastResolved, country) => {
|
|
@@ -36,7 +34,7 @@ export const resolveBestCountry = (
|
|
|
36
34
|
return localeCountry || systemLocale.region;
|
|
37
35
|
};
|
|
38
36
|
|
|
39
|
-
export const resolveBestCurrency = (localeCurrency: string, currencies: Array<
|
|
37
|
+
export const resolveBestCurrency = (localeCurrency: string, currencies: Array<{ isoCode: string }>) => {
|
|
40
38
|
if (localeCurrency) {
|
|
41
39
|
const resolvedCurrency = currencies.find((currency) => currency.isoCode === localeCurrency);
|
|
42
40
|
if (resolvedCurrency) {
|
package/src/utils-index.test.ts
CHANGED
|
@@ -1,67 +1,57 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
resolveBestSupported,
|
|
4
|
-
slugify,
|
|
5
|
-
systemLocale,
|
|
6
|
-
} from '@unchainedshop/utils';
|
|
7
|
-
import generateHashId from './generate-random-hash.js'
|
|
1
|
+
import { resolveBestCountry, resolveBestSupported, slugify, systemLocale } from '@unchainedshop/utils';
|
|
2
|
+
import generateHashId from './generate-random-hash.js';
|
|
8
3
|
|
|
9
4
|
describe('Utils', () => {
|
|
10
|
-
|
|
11
5
|
it('Locale', () => {
|
|
12
6
|
expect(systemLocale).toBeDefined();
|
|
13
|
-
expect(resolveBestCountry).toBeInstanceOf(Function)
|
|
14
|
-
expect(resolveBestSupported).toBeInstanceOf(Function)
|
|
7
|
+
expect(resolveBestCountry).toBeInstanceOf(Function);
|
|
8
|
+
expect(resolveBestSupported).toBeInstanceOf(Function);
|
|
15
9
|
});
|
|
16
10
|
|
|
17
|
-
describe('generateHashId', () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
expect(typeof result).toBe('string');
|
|
22
|
-
expect(result).toMatch(/^[A-Z0-9]+$/);
|
|
23
|
-
})
|
|
24
|
-
});
|
|
11
|
+
describe('generateHashId', () => {
|
|
12
|
+
it('should create a random hash ', () => {
|
|
13
|
+
const result = generateHashId();
|
|
25
14
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const expected = 'the-quick-brown-fox-jumps-over-the-lazy-dog';
|
|
30
|
-
|
|
31
|
-
const result = slugify(text);
|
|
32
|
-
|
|
33
|
-
expect(result).toEqual(expected);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('with a string containing special characters', () => {
|
|
37
|
-
const text = 'The Quick Brown Fox! Jumps Over The Lazy Dog?';
|
|
38
|
-
const expected = 'the-quick-brown-fox-jumps-over-the-lazy-dog';
|
|
39
|
-
|
|
40
|
-
const result = slugify(text);
|
|
41
|
-
|
|
42
|
-
expect(result).toEqual(expected);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('with a string containing multiple spaces', () => {
|
|
46
|
-
const text = 'The Quick Brown Fox Jumps Over The Lazy Dog';
|
|
47
|
-
const expected = 'the-quick-brown-fox-jumps-over-the-lazy-dog';
|
|
48
|
-
|
|
49
|
-
const result = slugify(text);
|
|
50
|
-
|
|
51
|
-
expect(result).toEqual(expected);
|
|
15
|
+
expect(typeof result).toBe('string');
|
|
16
|
+
expect(result).toMatch(/^[A-Z0-9]+$/);
|
|
17
|
+
});
|
|
52
18
|
});
|
|
53
|
-
|
|
54
|
-
it('with a string containing only special characters (leave underscore)', () => {
|
|
55
|
-
const text = '!@#$%^&*()_+';
|
|
56
|
-
const expected = '_';
|
|
57
|
-
|
|
58
|
-
const result = slugify(text);
|
|
59
|
-
|
|
60
|
-
expect(result).toEqual(expected);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
});
|
|
66
19
|
|
|
20
|
+
describe('slugify', () => {
|
|
21
|
+
it('with a normal string', () => {
|
|
22
|
+
const text = 'The Quick Brown Fox Jumps Over The Lazy Dog';
|
|
23
|
+
const expected = 'the-quick-brown-fox-jumps-over-the-lazy-dog';
|
|
24
|
+
|
|
25
|
+
const result = slugify(text);
|
|
26
|
+
|
|
27
|
+
expect(result).toEqual(expected);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('with a string containing special characters', () => {
|
|
31
|
+
const text = 'The Quick Brown Fox! Jumps Over The Lazy Dog?';
|
|
32
|
+
const expected = 'the-quick-brown-fox-jumps-over-the-lazy-dog';
|
|
67
33
|
|
|
34
|
+
const result = slugify(text);
|
|
35
|
+
|
|
36
|
+
expect(result).toEqual(expected);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('with a string containing multiple spaces', () => {
|
|
40
|
+
const text = 'The Quick Brown Fox Jumps Over The Lazy Dog';
|
|
41
|
+
const expected = 'the-quick-brown-fox-jumps-over-the-lazy-dog';
|
|
42
|
+
|
|
43
|
+
const result = slugify(text);
|
|
44
|
+
|
|
45
|
+
expect(result).toEqual(expected);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('with a string containing only special characters (leave underscore)', () => {
|
|
49
|
+
const text = '!@#$%^&*()_+';
|
|
50
|
+
const expected = '_';
|
|
51
|
+
|
|
52
|
+
const result = slugify(text);
|
|
53
|
+
|
|
54
|
+
expect(result).toEqual(expected);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|