Final integration step. The page shell is now a thin composition
of the hook + the previously-extracted children:
- DeckyFleet.tsx: 1,674 -> 274 LOC. Page owns only the
pure-UI state (filter, search, armed-confirm, modal visibility,
selected-card-for-inspect) and the toast-wrapping handlers that
translate hook results into toast tone. Polling, REST plumbing,
role lookup, and archetype catalog all moved to useDeckyFleet
in the prior commit.
- New DeckyFilters.tsx (header pill row + DEPLOY shortcut) +
DeckyGridEmpty.tsx (fleet-empty vs. filter-empty copy).
- DeckyFilters.test.tsx + DeckyGridEmpty.test.tsx cover count
rendering, filter-click callbacks, and admin-gated DEPLOY
visibility.
Two-step teardown arming logic stays in the page (it's pure UI).
Toast tone branching on { ok, reason } from useDeckyFleet
results moves the policy decision out of the data layer.
42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest';
|
|
import { render, screen } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { DeckyGridEmpty } from './DeckyGridEmpty';
|
|
|
|
describe('DeckyGridEmpty', () => {
|
|
it('shows the fleet-empty copy when fleetEmpty is true', () => {
|
|
render(
|
|
<DeckyGridEmpty fleetEmpty isAdmin={false} onDeploy={() => {}} />,
|
|
);
|
|
expect(screen.getByText('NO DECOYS DEPLOYED IN THIS SECTOR')).toBeInTheDocument();
|
|
});
|
|
|
|
it('shows the filtered-empty copy when fleetEmpty is false', () => {
|
|
render(
|
|
<DeckyGridEmpty fleetEmpty={false} isAdmin={false} onDeploy={() => {}} />,
|
|
);
|
|
expect(screen.getByText('NO DECOYS MATCH CURRENT FILTER')).toBeInTheDocument();
|
|
});
|
|
|
|
it('only renders the DEPLOY shortcut for admins on a truly empty fleet', () => {
|
|
const { rerender } = render(
|
|
<DeckyGridEmpty fleetEmpty isAdmin={false} onDeploy={() => {}} />,
|
|
);
|
|
expect(screen.queryByText(/DEPLOY DECKIES/)).not.toBeInTheDocument();
|
|
|
|
rerender(
|
|
<DeckyGridEmpty fleetEmpty={false} isAdmin onDeploy={() => {}} />,
|
|
);
|
|
expect(screen.queryByText(/DEPLOY DECKIES/)).not.toBeInTheDocument();
|
|
|
|
const onDeploy = vi.fn();
|
|
rerender(
|
|
<DeckyGridEmpty fleetEmpty isAdmin onDeploy={onDeploy} />,
|
|
);
|
|
const user = userEvent.setup();
|
|
return user.click(screen.getByText(/DEPLOY DECKIES/)).then(() => {
|
|
expect(onDeploy).toHaveBeenCalled();
|
|
});
|
|
});
|
|
});
|