import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import SlaRemediationCard from '@/components/doormile/SlaRemediationCard';
// lucide-react ships ESM Jest does not transform; every component test here stubs it.
jest.mock('lucide-react', () =>
new Proxy({}, { get: (_t, prop) => (prop === '__esModule' ? true : (props) => ) })
);
jest.mock('@/api/doormile/notify', () => ({
OpenToast: jest.fn()
}));
describe('SlaRemediationCard Component', () => {
const sampleFinding = {
title: '3 orders overdue in RS Puram',
why: 'Parcels have exceeded their promised delivery SLA window by >45 minutes.',
severity: 'critical',
count: 3,
proposal: {
label: 'Split between Karthik & Suresh',
blastRadius: 'Will transfer 2 orders to Karthik and 1 order to Suresh.'
}
};
it('renders title, explanation, and proposal details properly', () => {
render();
expect(screen.getByText('3 orders overdue in RS Puram')).toBeInTheDocument();
expect(screen.getByText(/Parcels have exceeded their promised delivery SLA window/)).toBeInTheDocument();
expect(screen.getByText('Needs attention now')).toBeInTheDocument();
expect(screen.getByText('3 Orders')).toBeInTheDocument();
expect(screen.getAllByText('Split between Karthik & Suresh').length).toBeGreaterThanOrEqual(1);
});
it('triggers onRemediate callback when Apply button is clicked', async () => {
const handleRemediate = jest.fn(async () => {});
render();
const button = screen.getByRole('button', { name: /Split between Karthik & Suresh/i });
fireEvent.click(button);
await waitFor(() => {
expect(handleRemediate).toHaveBeenCalledTimes(1);
expect(handleRemediate).toHaveBeenCalledWith(sampleFinding);
expect(screen.getByText('Action sent')).toBeInTheDocument();
});
});
it('returns null if no finding is passed', () => {
const { container } = render();
expect(container.firstChild).toBeNull();
});
});
describe('SlaRemediationCard — never claims an action it did not perform', () => {
const { OpenToast } = require('@/api/doormile/notify');
const finding = {
title: '1 rider stalled at door',
why: 'Rider stamped arrival but delivery has not completed.',
severity: 'critical',
count: 1,
proposal: {
label: 'Message waiting riders',
blastRadius: 'Sends an assistance check-in to stalled riders.'
}
};
beforeEach(() => {
OpenToast.mockClear();
});
// The bug: with no onRemediate the handler fell through to a 600ms timer and
// then reported "Remediation executed" with a green card. No caller has ever
// passed onRemediate, so every click on the Exceptions page took that branch
// and told the operator a rider had been messaged when nothing was sent.
it('does not report success when no executor is wired', async () => {
render();
const button = screen.getByRole('button', { name: /review only/i });
expect(button).toBeDisabled();
fireEvent.click(button);
await waitFor(() => {
expect(OpenToast).not.toHaveBeenCalled();
});
expect(screen.queryByText(/remediation executed/i)).not.toBeInTheDocument();
});
it('labels the action as review-only rather than offering a fix', () => {
render();
expect(screen.getByRole('button', { name: /review only/i })).toBeInTheDocument();
expect(screen.queryByRole('button', { name: /message waiting riders/i })).not.toBeInTheDocument();
});
it('executes and reports success only when an executor IS supplied', async () => {
const onRemediate = jest.fn().mockResolvedValue({ ok: true, message: 'Notified 1 rider.' });
render();
const button = screen.getByRole('button', { name: /message waiting riders/i });
expect(button).toBeEnabled();
fireEvent.click(button);
await waitFor(() => {
expect(onRemediate).toHaveBeenCalledWith(finding);
// (message, variant) — the branch passed ('success', msg), which rendered a RED error toast reading "success".
// The executor's own message is shown, so a partial success stays visible.
expect(OpenToast).toHaveBeenCalledWith('Notified 1 rider.', 'success');
});
});
it('reports failure honestly when the executor throws', async () => {
const onRemediate = jest.fn().mockRejectedValue(new Error('network'));
render();
fireEvent.click(screen.getByRole('button', { name: /message waiting riders/i }));
await waitFor(() => {
expect(OpenToast).toHaveBeenCalledWith('network', 'error');
});
expect(OpenToast).not.toHaveBeenCalledWith(expect.anything(), 'success');
});
});