Files
dailygrubs_console/src/pages/nearle/ai/OpsAgentDrawer.test.js

148 lines
5.6 KiB
JavaScript

/**
* Smoke test for the Ops Agent drawer.
*
* The rest of this folder tests pure logic, which is the repo's preference —
* but "does the component actually render without throwing" is exactly the gap
* a build cannot close, and this drawer is the only place the analysis is ever
* seen. It needs no react-query, router or notistack provider, so it can be
* mounted directly; there is no @testing-library in this project, so it mounts
* through react-dom/client and reads the DOM.
*
* MUI renders Drawer content into a portal on document.body, so assertions read
* body text rather than the container.
*/
import React from 'react';
import { createRoot } from 'react-dom/client';
import { act } from 'react-dom/test-utils';
import OpsAgentDrawer from './OpsAgentDrawer';
global.IS_REACT_ACT_ENVIRONMENT = true;
const order = (orderid, deliverydate, assigntime, deliverytime, extra = {}) => ({
orderid,
tenantname: 'Bawa medical Nagercoil',
rider: 'Sivakumar Subramani',
deliverydate: `2026-09-02T${deliverydate}:00+05:30`,
assigntime: `2026-09-02 ${assigntime}`,
starttime: '',
arrivaltime: '',
pickuptime: '',
deliverytime: `2026-09-02 ${deliverytime}`,
deliverysuburb: 'King Nagar',
...extra
});
// The real 2 Sep day, trimmed to what the drawer renders.
const DAY = [
order('908-20246318', '14:00', '19:20:42', '22:59:24', { kms: '3', deliverycharge: '60', deliverylocation: 'Parvathipuram' }),
order('908-20246317', '11:30', '19:20:42', '22:59:33', { kms: '1', deliverycharge: '60', deliverylocation: 'Puthukudierupu' }),
order('908-20246316', '09:30', '14:36:45', '22:59:42', { kms: '3', deliverycharge: '60', deliverylocation: 'CBH ROAD' }),
order('908-20246315', '07:30', '13:26:51', '22:59:51', { kms: '4', deliverycharge: '60', deliverylocation: 'NGL' }),
order('908-20246313', '07:30', '13:26:51', '22:59:59', { kms: '3', deliverycharge: '60', deliverylocation: 'Erulapappuram' }),
order('908-20246314', '07:30', '13:26:51', '23:00:07', { kms: '2', deliverycharge: '60', deliverylocation: 'Ramavarmapuram' }),
order('908-20246312', '07:30', '12:39:45', '23:00:18', {
kms: '1',
deliverycharge: '60',
deliverylocation: 'Simon Nagar',
deliverysuburb: 'Weavers Colony'
}),
order('908-20246308', '05:30', '11:43:03', '23:00:25', {
kms: '1',
deliverycharge: '60',
deliverylocation: 'ராமவர்மபுரம்',
deliverysuburb: 'Weavers Colony'
}),
order('908-20246309', '06:00', '11:43:03', '23:00:34', { kms: '6', deliverycharge: '84', deliverylocation: 'Erumbukadu (post' }),
order('908-20246310', '06:00', '11:43:03', '23:00:42', { kms: '4', deliverycharge: '60', deliverylocation: 'Kurusady' }),
order('908-20246311', '06:00', '11:43:03', '23:00:50', { kms: '5', deliverycharge: '72', deliverylocation: 'NGL' }),
order('908-20246307', '04:30', '10:04:53', '10:50:56', {
kms: '3',
deliverycharge: '60',
deliverylocation: 'Udhayamarthandam',
starttime: '2026-09-02 10:50:40',
arrivaltime: '2026-09-02 10:33:25',
pickuptime: '2026-09-02 10:33:38'
})
];
let container;
let root;
const mount = (props) => {
container = document.createElement('div');
document.body.appendChild(container);
root = createRoot(container);
act(() => {
root.render(<OpsAgentDrawer open onClose={() => {}} rows={DAY} {...props} />);
});
};
afterEach(() => {
if (root) act(() => root.unmount());
if (container) container.remove();
document.body.innerHTML = '';
root = null;
container = null;
});
describe('OpsAgentDrawer', () => {
it('renders the day without throwing and shows the verdict', () => {
mount();
const text = document.body.textContent;
expect(text).toContain('Ops Agent');
expect(text).toContain('12 orders');
expect(text).toContain('1 rider');
// 0 of 12 delivery stamps survive the bulk-close and event-order checks.
expect(text).toContain('0/12');
});
it('renders the headline tiles with the tested figures', () => {
mount();
const text = document.body.textContent;
expect(text).toContain('45%'); // lifecycle capture, 27 of 60
expect(text).toContain('27 of 60 stamps');
expect(text).toContain('+13m'); // median slot to assignment, skew-corrected
expect(text).toContain('₹756');
expect(text).toContain('36 km');
});
it('lists findings with the blocking ones present', () => {
mount();
const text = document.body.textContent;
expect(text).toContain('Blocking');
expect(text).toContain('Delivery timestamps were written in bulk');
expect(text).toContain('Promised slots read exactly one IST offset early');
});
it('rolls up both zones', () => {
mount();
const text = document.body.textContent;
expect(text).toContain('King Nagar');
expect(text).toContain('Weavers Colony');
});
it('expands a finding to reveal its evidence and fix', () => {
mount();
const heading = [...document.querySelectorAll('[role="button"]')].find((el) =>
el.textContent.includes('Delivery timestamps were written in bulk')
);
expect(heading).toBeTruthy();
act(() => {
heading.dispatchEvent(new MouseEvent('click', { bubbles: true }));
});
expect(document.body.textContent).toContain('Stamp delivery server-side from the rider action');
});
it('shows an empty state rather than fabricating numbers when there are no rows', () => {
mount({ rows: [] });
expect(document.body.textContent).toContain('No orders in the current filter');
});
it('says plainly that no model was called', () => {
mount();
expect(document.body.textContent).toContain('No model was called');
});
});