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'); }); });