import { assignmentSummary, editNeedsReconcile, extractRiders, extractUnassigned, flattenRiders, moveOrderInPreviewData, withUnassignedZones } from '@/lib/dispatchPreview'; /** * One real failed run, start to finish. * * LIVE_RUN is the verbatim reply from * `routes.workolik.com/api/v1/optimization/riderassign?hypertuning_params=balanced` * on 2026-09-22 for booking DM-107871 — the run in the screenshots. It is * kept whole rather than trimmed: the defect these guard against was an * assumption about the response shape, and a fixture written from the same * assumption proves nothing. * * What it records: the solver processed the order correctly (zone resolved, * profit computed) and had no rider to give it to — `active_riders_pool: 0`, * before any filtering, with nothing excluded. */ const LIVE_RUN = { code: 200, zone_summary: [ { zone_name: 'North West', total_orders: 1, assigned_orders: 0, unassigned_orders_count: 1, active_riders_count: 0, total_delivery_kms: 0.0, total_profit: 56.0 } ], zones: [ { zone_name: 'North West', total_orders: 1, active_riders_count: 0, assigned_orders: 0, unassigned_orders_count: 1, total_delivery_kms: 0.0, total_profit: 56.0, riders: [], unassigned_orders: [ { bookingid: 1737, bookingno: 'DM-107871', tenantid: 1, pickupaddress: '124 Gandhipuram Main Rd', pickuplatitude: 11.0168, pickuplongitude: 76.9558, deliveryaddress: 'NO . 26, JMV GARDEN, Subramaniapalayam, Coimbatore, Tamil Nadu 641029', deliverylatitude: 11.0590674, deliverylongitude: 76.9298476, status: 'Pending_Pickup', assignedmileruserid: null, consignmentid: null, deliveryid: 0, deliverydate: '2026-09-23 17:56:04', assigntime: '2026-09-22 13:54:39', orderstatus: 'pending', orderamount: 56, droplat: '11.0590674', droplon: '76.9298476', pickuplat: 11.0168, pickuplon: 76.9558, deliverycharges: 56, pickuplocation: '124 Gandhipuram Main Rd', deliverylocation: 'NO . 26, JMV GARDEN, Subramaniapalayam, Coimbatore, Tamil Nadu 641029', hubid: 2, deliverylat: '11.0590674', deliverylong: '76.9298476', unassigned_reason: 'No riders found (check partner online status).', zone_name: 'North West', rider_charge: 0.0, profit: 56.0, profit_class: 'HighMargin' } ] } ], details: [], message: 'Success', status: true, meta: { total_orders: 1, utilized_riders: 0, active_riders_pool: 0, assigned_orders: 0, unassigned_orders: 1, total_profit: 56.0, unassigned_details: [{ orderid: null, reason: 'No riders found (check partner online status).' }], absent_riders_excluded: [], absent_riders_unknown: [], solver_mode: '2phase_heuristic' } }; // The order id every surface keys this booking by. The refusal list carries // no `orderid` of its own — `bookingno` is what it has. const ORDER_ID = 'DM-107871'; describe('the run as the page reads it', () => { it('reports the refusal instead of the 200', () => { expect(assignmentSummary(LIVE_RUN)).toMatchObject({ assigned: 0, unassigned: 1, total: 1, riders: 0, failed: true }); }); it('has nothing to commit before a miler is picked', () => { // `details: []` — so the Assign Orders fallback is empty too, and the // page must not offer to dispatch anything. expect(flattenRiders(extractRiders(LIVE_RUN))).toEqual([]); expect(LIVE_RUN.details).toEqual([]); }); it('puts the order on the board with its coordinates, so it can be pinned', () => { const order = withUnassignedZones(LIVE_RUN).zones[0].riders[0].orders[0]; expect(order.orderid).toBe(ORDER_ID); expect(Number(order.droplat)).toBeCloseTo(11.0590674); expect(Number(order.droplon)).toBeCloseTo(76.9298476); }); }); describe('recovering the run by hand', () => { // The operator opens the zone, presses "change rider" on DM-107871 and // picks a real Doormile miler. Everything below has to follow from that. const recovered = () => moveOrderInPreviewData(LIVE_RUN, { orderId: ORDER_ID, newRiderId: 12, newRiderName: 'Vijay Bangalore Rider' }); it('finds the order by its bookingno, which is the only id it has', () => { const rider = extractRiders(recovered())[0]; expect(rider).toMatchObject({ rider_id: 12, rider_name: 'Vijay Bangalore Rider' }); expect(rider.orders).toHaveLength(1); }); it('clears the refusal, so the banner and the Reconcile list empty out', () => { expect(extractUnassigned(recovered())).toEqual([]); expect(assignmentSummary(recovered())).toMatchObject({ assigned: 1, unassigned: 0, failed: false }); }); it('produces a commit payload carrying the real miler id', () => { const [delivery] = flattenRiders(extractRiders(recovered())); expect(delivery).toMatchObject({ orderid: ORDER_ID, bookingid: 1737, rider_id: 12, userid: 12 }); }); it('keeps the booking fields the commit needs', () => { const [delivery] = flattenRiders(extractRiders(recovered())); // `POST /admin/bookings/:id/assign-miler` is keyed on the booking, so // losing bookingid here would make the order uncommittable. expect(delivery.bookingid).toBe(1737); expect(delivery.deliverycharges).toBe(56); }); }); describe('whether the recovery still has to go through Reconcile', () => { const assignTo = (preview, newRiderId) => ({ before: preview, after: moveOrderInPreviewData(preview, { orderId: ORDER_ID, newRiderId, newRiderName: 'Vijay' }) }); it('does not, for a refused order given a miler with nothing else on', () => { // The dead end this exists to break: reconcile-steps is the same service // that had no riders, so gating Assign Orders on it would strand the // order permanently. const { before, after } = assignTo(LIVE_RUN, 12); expect(editNeedsReconcile(before, after, { orderId: ORDER_ID, newRiderId: 12 })).toBe(false); }); it('does, when the refused order is dropped into an existing route', () => { const withPlan = { ...LIVE_RUN, zones: [ { ...LIVE_RUN.zones[0], riders: [{ rider_id: 12, rider_name: 'Vijay', orders: [{ orderid: 'DM-100001' }, { orderid: 'DM-100002' }] }] } ] }; const { before, after } = assignTo(withPlan, 12); expect(editNeedsReconcile(before, after, { orderId: ORDER_ID, newRiderId: 12 })).toBe(true); }); it('does, for an ordinary rider-to-rider move inside the plan', () => { const planned = { zones: [ { zone_name: 'North West', riders: [ { rider_id: 7, rider_name: 'Rajan', orders: [{ orderid: 'DM-100001' }] }, { rider_id: 12, rider_name: 'Vijay', orders: [{ orderid: 'DM-100002' }] } ] } ] }; const after = moveOrderInPreviewData(planned, { orderId: 'DM-100001', newRiderId: 12, newRiderName: 'Vijay' }); expect(editNeedsReconcile(planned, after, { orderId: 'DM-100001', newRiderId: 12 })).toBe(true); }); });