51 lines
1.6 KiB
TypeScript
51 lines
1.6 KiB
TypeScript
import { chargeableWeightKg, haversineKm, quoteCarrier, rankQuotes } from './freight-calculator';
|
|
|
|
describe('freight calculator', () => {
|
|
const cargo = {
|
|
weightKg: 10,
|
|
widthCm: 40,
|
|
heightCm: 30,
|
|
lengthCm: 50,
|
|
cargoValue: 1000,
|
|
distanceKm: 200,
|
|
};
|
|
|
|
it('uses volumetric weight when it exceeds real weight', () => {
|
|
expect(chargeableWeightKg({ weightKg: 1, widthCm: 100, heightCm: 100, lengthCm: 100 })).toBe(166.667);
|
|
});
|
|
|
|
it('quotes base + kg + km + ad valorem', () => {
|
|
const quote = quoteCarrier(
|
|
{ id: '1', name: 'Rota Sul', baseFee: 30, pricePerKg: 2, pricePerKm: 0.5, adValoremRate: 0.01 },
|
|
cargo,
|
|
);
|
|
expect(quote.price).toBe(160);
|
|
});
|
|
|
|
it('ranks cheapest first', () => {
|
|
const ranked = rankQuotes([
|
|
{ carrierId: 'a', carrierName: 'A', price: 90, chargeableKg: 10 },
|
|
{ carrierId: 'b', carrierName: 'B', price: 40, chargeableKg: 10 },
|
|
]);
|
|
expect(ranked[0].carrierId).toBe('b');
|
|
});
|
|
|
|
it('uses real weight when it exceeds volumetric weight', () => {
|
|
expect(chargeableWeightKg({ weightKg: 80, widthCm: 10, heightCm: 10, lengthCm: 10 })).toBe(80);
|
|
});
|
|
|
|
it('never quotes a negative price', () => {
|
|
const quote = quoteCarrier(
|
|
{ id: '1', name: 'X', baseFee: 0, pricePerKg: 0, pricePerKm: 0, adValoremRate: 0 },
|
|
{ ...cargo, cargoValue: 0, distanceKm: 0, weightKg: 0, widthCm: 0, heightCm: 0, lengthCm: 0 },
|
|
);
|
|
expect(quote.price).toBe(0);
|
|
});
|
|
|
|
it('computes haversine distance in km', () => {
|
|
const km = haversineKm({ lat: -23.55, lon: -46.63 }, { lat: -22.9, lon: -43.2 });
|
|
expect(km).toBeGreaterThan(350);
|
|
expect(km).toBeLessThan(450);
|
|
});
|
|
});
|