Files
doormilxpress_astryx/tests/lib/bulkOrderPayload.test.js

137 lines
4.8 KiB
JavaScript

import { buildBulkBookingPayload, buildBulkBookingPayloads } from '@/lib/bulkOrderPayload';
/**
* Coordinates on the bulk booking payload.
*
* This is the regression guard for the billing defect. The builder used
* `Number(value) || 0` on all four coordinates, so a row with no usable pin
* was submitted as (0, 0) — and the backend cannot tell that apart from a
* deliberate pin in the Gulf of Guinea.
*
* Both failure modes came from that one substitution:
*
* • With a charge quoted, the console had measured the distance from those
* same 0,0 coordinates. OSRM refuses to route to open ocean, so the
* Haversine fallback returned roughly 11,000 km, and adminController
* honours a supplied `finalprice` verbatim. Massive overcharge.
* • With no charge quoted, the backend measured for itself — and skipped the
* calculation entirely, because its guard is
* `if booking.Deliverylatitude != 0 && ...`. Base rate, no distance
* component. Undercharge.
*
* A coordinate we do not have is now null, which the server can refuse.
*/
const PICKUP = {
address: 'Doormile Base, Peelamedu',
pincode: '641004',
city: 'Coimbatore',
latitude: 11.0168,
longitude: 76.9558,
};
const ROW = {
firstname: 'Priya',
contactno: '9876543210',
address: '45 Cross Cut Rd, Gandhipuram',
postcode: '641012',
city: 'Coimbatore',
latitude: 11.0272,
longitude: 76.9722,
totalcharge: 180,
};
const build = (row = {}, pickup = PICKUP) =>
buildBulkBookingPayload({
row: { ...ROW, ...row },
sharedPickup: pickup,
tenantId: 3,
tenantLocationId: 7,
deliverytime: '2026-09-18 10:00:00',
notes: '',
anchors: [],
});
describe('buildBulkBookingPayload — coordinates', () => {
it('passes real coordinates through untouched', () => {
const p = build();
expect(p.pickuplatitude).toBe(11.0168);
expect(p.pickuplongitude).toBe(76.9558);
expect(p.deliverylatitude).toBe(11.0272);
expect(p.deliverylongitude).toBe(76.9722);
});
it('sends null, NOT 0, for a delivery pin that is missing', () => {
const p = build({ latitude: null, longitude: null });
expect(p.deliverylatitude).toBeNull();
expect(p.deliverylongitude).toBeNull();
// The specific regression: 0 would have been priced as an 11,000 km run.
expect(p.deliverylatitude).not.toBe(0);
});
it('sends null for an empty sheet cell', () => {
// An untouched Excel cell arrives as '' rather than null, and
// `Number('') || 0` is 0.
const p = build({ latitude: '', longitude: '' });
expect(p.deliverylatitude).toBeNull();
expect(p.deliverylongitude).toBeNull();
});
it('sends null for an unparseable sheet cell', () => {
const p = build({ latitude: 'N/A', longitude: '--' });
expect(p.deliverylatitude).toBeNull();
expect(p.deliverylongitude).toBeNull();
});
it('refuses to forward a literal zero it was handed', () => {
// A row that already carried 0 — which is what the geocoding shim used to
// return for a suggestion with no coordinates — must not be laundered
// into a valid-looking payload.
const p = build({ latitude: 0, longitude: 0 });
expect(p.deliverylatitude).toBeNull();
expect(p.deliverylongitude).toBeNull();
});
it('sends null for a coordinate outside its axis range', () => {
const p = build({ latitude: 94.912, longitude: 200 });
expect(p.deliverylatitude).toBeNull();
expect(p.deliverylongitude).toBeNull();
});
it('nulls the pickup end too, rather than relying on the backend rescue', () => {
// adminController falls back to the hub or tenant location when pickup is
// 0,0. That rescue exists, but sending data that needs rescuing is not the
// same as sending correct data.
const p = build({}, { ...PICKUP, latitude: null, longitude: undefined });
expect(p.pickuplatitude).toBeNull();
expect(p.pickuplongitude).toBeNull();
});
it('treats the two ends independently', () => {
const p = build({ latitude: null, longitude: null });
expect(p.pickuplatitude).toBe(11.0168);
expect(p.deliverylatitude).toBeNull();
});
});
describe('buildBulkBookingPayloads — batch', () => {
it('nulls only the rows that are missing a pin', () => {
const payloads = buildBulkBookingPayloads({
rows: [ROW, { ...ROW, latitude: 0, longitude: 0 }, { ...ROW, latitude: '' }],
sharedPickup: PICKUP,
tenantId: 3,
tenantLocationId: 7,
deliverytime: '2026-09-18 10:00:00',
notes: '',
anchors: [],
});
expect(payloads).toHaveLength(3);
expect(payloads[0].deliverylatitude).toBe(11.0272);
expect(payloads[1].deliverylatitude).toBeNull();
expect(payloads[2].deliverylatitude).toBeNull();
// The good row keeps its longitude even though a sibling lost its latitude.
expect(payloads[2].deliverylongitude).toBe(76.9722);
});
});