101 lines
2.7 KiB
TypeScript
101 lines
2.7 KiB
TypeScript
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
import { fireEvent, waitFor, within } from '@testing-library/react';
|
|
|
|
import NodeList from '@/pages/nodes/NodeList';
|
|
import type { NodeRecord } from '@/schemas/node';
|
|
|
|
import { renderWithProviders } from './test-utils';
|
|
|
|
const noop = () => {};
|
|
|
|
function renderNodes(nodes: NodeRecord[]) {
|
|
return renderWithProviders(
|
|
<NodeList
|
|
nodes={nodes}
|
|
isMobile={false}
|
|
selectedIds={[]}
|
|
onSelectionChange={noop}
|
|
onAdd={noop}
|
|
onProbeTasks={noop}
|
|
onEdit={noop}
|
|
onDelete={noop}
|
|
onProbe={noop}
|
|
onToggleEnable={noop}
|
|
onUpdateNode={noop}
|
|
onUpdateSelected={noop}
|
|
/>,
|
|
);
|
|
}
|
|
|
|
function rowFor(container: HTMLElement, name: string): HTMLElement {
|
|
const cell = within(container).getByText(name);
|
|
const row = cell.closest('tr');
|
|
if (!row) throw new Error(`row not found for ${name}`);
|
|
return row as HTMLElement;
|
|
}
|
|
|
|
// The nodes page category chips used to hover to a bare category title.
|
|
// When the backend sends the category's email list, hovering a chip must
|
|
// pop the list over (same pattern as the inbounds page); without a list
|
|
// the chip keeps the plain title tooltip.
|
|
describe('NodeList clients-cell category chips', () => {
|
|
afterEach(() => vi.restoreAllMocks());
|
|
|
|
it('pops the online and depleted email lists on hover', async () => {
|
|
const { container } = renderNodes([
|
|
{
|
|
id: 5,
|
|
name: 'agent-node',
|
|
enable: true,
|
|
status: 'online',
|
|
clientCount: 9,
|
|
activeCount: 2,
|
|
activeEmails: ['active-a@x', 'active-b@x'],
|
|
depletedCount: 3,
|
|
depletedEmails: ['dep-a@x', 'dep-b@x', 'dep-c@x'],
|
|
onlineCount: 1,
|
|
onlineEmails: ['online@x'],
|
|
},
|
|
]);
|
|
|
|
const row = rowFor(container, 'agent-node');
|
|
|
|
fireEvent.mouseEnter(within(row).getByText('1'));
|
|
await waitFor(
|
|
() => {
|
|
expect(document.body.textContent).toContain('online@x');
|
|
},
|
|
{ timeout: 5000 },
|
|
);
|
|
|
|
fireEvent.mouseEnter(within(row).getByText('3'));
|
|
await waitFor(
|
|
() => {
|
|
expect(document.body.textContent).toContain('dep-b@x');
|
|
},
|
|
{ timeout: 5000 },
|
|
);
|
|
});
|
|
|
|
it('keeps the title tooltip when a category has no email list', async () => {
|
|
const { container } = renderNodes([
|
|
{
|
|
id: 6,
|
|
name: 'bare-node',
|
|
enable: true,
|
|
status: 'online',
|
|
clientCount: 4,
|
|
onlineCount: 1,
|
|
},
|
|
]);
|
|
|
|
const row = rowFor(container, 'bare-node');
|
|
fireEvent.mouseEnter(within(row).getByText('1'));
|
|
|
|
await waitFor(() => {
|
|
expect(document.body.textContent).toContain('Online');
|
|
});
|
|
expect(document.querySelector('.client-email-list')).toBeNull();
|
|
});
|
|
});
|