76 lines
2.3 KiB
TypeScript
76 lines
2.3 KiB
TypeScript
import { calculatePrice, type PriceRule } from '../src/pricing/pricing.policy';
|
|
import { pricingSchema } from '../src/pricing/pricing.schema';
|
|
const rule: PriceRule = {
|
|
taxMode: 'EXCLUSIVE',
|
|
merchandiseTaxBps: 1800,
|
|
shippingFee: '50.00',
|
|
shippingTaxBps: 1800,
|
|
freeShippingMinimum: null,
|
|
};
|
|
describe('configurable pricing calculations', () => {
|
|
it('calculates exclusive merchandise tax and shipping tax exactly', () => {
|
|
expect(calculatePrice('100.00', rule)).toEqual({
|
|
merchandiseTax: '18.00',
|
|
shippingNet: '50.00',
|
|
shippingTax: '9.00',
|
|
taxTotal: '27.00',
|
|
payableTotal: '177.00',
|
|
});
|
|
});
|
|
it('extracts inclusive tax without adding it twice and handles odd basis points', () => {
|
|
expect(
|
|
calculatePrice('118.00', { ...rule, taxMode: 'INCLUSIVE' }),
|
|
).toMatchObject({ merchandiseTax: '18.00', payableTotal: '177.00' });
|
|
expect(
|
|
calculatePrice('100.01', {
|
|
...rule,
|
|
taxMode: 'INCLUSIVE',
|
|
merchandiseTaxBps: 1,
|
|
}),
|
|
).toMatchObject({ merchandiseTax: '0.01' });
|
|
});
|
|
it('applies free shipping at the discounted merchandise threshold and rounds small values', () => {
|
|
const free = { ...rule, freeShippingMinimum: '100.00' };
|
|
expect(calculatePrice('100.00', free)).toMatchObject({
|
|
shippingNet: '0.00',
|
|
shippingTax: '0.00',
|
|
payableTotal: '118.00',
|
|
});
|
|
expect(calculatePrice('99.99', free).shippingNet).toBe('50.00');
|
|
expect(
|
|
calculatePrice('0.01', {
|
|
...rule,
|
|
merchandiseTaxBps: 5000,
|
|
shippingFee: '0.00',
|
|
}).merchandiseTax,
|
|
).toBe('0.01');
|
|
expect(
|
|
calculatePrice('0', { ...free, freeShippingMinimum: '0.00' })
|
|
.payableTotal,
|
|
).toBe('0.00');
|
|
});
|
|
it('requires explicit bounded rules and rejects active or unknown fields on creation', () => {
|
|
const input = {
|
|
...rule,
|
|
name: 'Test policy',
|
|
currency: 'INR',
|
|
countryCode: 'in',
|
|
};
|
|
expect(pricingSchema.parse(input)).toMatchObject({
|
|
countryCode: 'IN',
|
|
region: '',
|
|
});
|
|
for (const change of [
|
|
{ merchandiseTaxBps: -1 },
|
|
{ shippingTaxBps: 10001 },
|
|
{ shippingFee: '-1.00' },
|
|
{ active: true },
|
|
{ countryCode: 'IND' },
|
|
{ currency: 'XXX' },
|
|
])
|
|
expect(pricingSchema.safeParse({ ...input, ...change }).success).toBe(
|
|
false,
|
|
);
|
|
});
|
|
});
|