test(collection-pool): cover groups, bulk assign, notes tooltip
This commit is contained in:
parent
c5731a1206
commit
a5eaae6f7b
1 changed files with 169 additions and 0 deletions
|
|
@ -111,6 +111,175 @@ function getRenderedSupplierOrder() {
|
|||
.map((item) => item.textContent ?? "");
|
||||
}
|
||||
|
||||
function makeRowWithOverrides(overrides: Record<string, unknown>) {
|
||||
return makeRow({
|
||||
id: "alpha",
|
||||
supplierId: "sup-alpha",
|
||||
supplierName: "Alpha Bearings",
|
||||
orderNumber: "SO-1",
|
||||
itemStatus: "collection_pool",
|
||||
...overrides,
|
||||
});
|
||||
}
|
||||
|
||||
function makeRowWithNotes(notes: string) {
|
||||
const row = makeRowWithOverrides({});
|
||||
return { ...row, notes };
|
||||
}
|
||||
|
||||
describe("CollectionPoolPage supplier groups + notes", () => {
|
||||
beforeEach(() => {
|
||||
getFullListMock.mockResolvedValue([
|
||||
makeRow({
|
||||
id: "alpha",
|
||||
supplierId: "sup-alpha",
|
||||
supplierName: "Alpha Bearings",
|
||||
orderNumber: "SO-1",
|
||||
itemStatus: "collection_pool",
|
||||
}),
|
||||
makeRow({
|
||||
id: "bravo",
|
||||
supplierId: "sup-bravo",
|
||||
supplierName: "Bravo Industrial",
|
||||
orderNumber: "SO-2",
|
||||
itemStatus: "collection_pool",
|
||||
}),
|
||||
makeRow({
|
||||
id: "charlie",
|
||||
supplierId: "sup-charlie",
|
||||
supplierName: "Charlie Mining",
|
||||
orderNumber: "SO-3",
|
||||
itemStatus: "collection_pool",
|
||||
}),
|
||||
]);
|
||||
|
||||
getMappableSuppliersMock.mockResolvedValue([
|
||||
{ id: "sup-alpha", coordinates: "-26.2041, 28.0473" },
|
||||
{ id: "sup-bravo", coordinates: "-26.3000, 28.1000" },
|
||||
{ id: "sup-charlie", coordinates: "-26.2048, 28.0479" },
|
||||
]);
|
||||
|
||||
global.fetch = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => [],
|
||||
}) as unknown as typeof fetch;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("renders time-in-list with text-primary class", async () => {
|
||||
render(<CollectionPoolPage />);
|
||||
|
||||
const ageLabels = await screen.findAllByText(/^\d+[hd]$/);
|
||||
expect(ageLabels.length).toBeGreaterThan(0);
|
||||
for (const label of ageLabels) {
|
||||
expect(label.className).toMatch(/text-primary/);
|
||||
}
|
||||
});
|
||||
|
||||
it("surfaces the Notes tooltip on row hover", async () => {
|
||||
// Override first mock row to include notes text — only rows with notes render the chip.
|
||||
getFullListMock.mockResolvedValueOnce([
|
||||
makeRowWithNotes("Spoke to David — confirmed pickup tomorrow"),
|
||||
]);
|
||||
|
||||
render(<CollectionPoolPage />);
|
||||
|
||||
const tooltip = await screen.findByRole("tooltip");
|
||||
expect(tooltip).toHaveTextContent(/Spoke to David/);
|
||||
// Tooltip uses the `hidden` class by default; shown only on group-hover/focus-within.
|
||||
expect(tooltip.className).toMatch(/hidden/);
|
||||
});
|
||||
|
||||
it("applies a primary-tint background to selected rows", async () => {
|
||||
render(<CollectionPoolPage />);
|
||||
|
||||
const firstCheckbox = await screen.findByRole("checkbox", {
|
||||
name: /Select .* at .*/i,
|
||||
});
|
||||
fireEvent.click(firstCheckbox);
|
||||
|
||||
const row = firstCheckbox.closest("li");
|
||||
expect(row).not.toBeNull();
|
||||
expect(row!.className).toMatch(/bg-primary\/5/);
|
||||
});
|
||||
|
||||
it("section Select all toggles every row in the supplier group", async () => {
|
||||
render(<CollectionPoolPage />);
|
||||
|
||||
const selectAll = await screen.findByRole("checkbox", {
|
||||
name: /Select all \d+ stops at/i,
|
||||
});
|
||||
fireEvent.click(selectAll);
|
||||
|
||||
const rowCheckboxes = await screen.findAllByRole("checkbox", {
|
||||
name: /^Select .* at/i,
|
||||
});
|
||||
expect(rowCheckboxes.length).toBeGreaterThan(0);
|
||||
for (const cb of rowCheckboxes) {
|
||||
expect(cb).toBeChecked();
|
||||
}
|
||||
});
|
||||
|
||||
it("opens bulk-assign dialog with bulkCount equal to selected rows", async () => {
|
||||
render(<CollectionPoolPage />);
|
||||
|
||||
const selectAll = await screen.findByRole("checkbox", {
|
||||
name: /Select all \d+ stops at/i,
|
||||
});
|
||||
fireEvent.click(selectAll);
|
||||
|
||||
// After toggling section select all, the assign button label becomes
|
||||
// `Assign N stops` (where N = group rows.length).
|
||||
const assignAll = await screen.findByRole("button", {
|
||||
name: /Assign \d+ stops$/,
|
||||
});
|
||||
fireEvent.click(assignAll);
|
||||
|
||||
// The AssignDriverDialog component is mocked to render `null` in this test
|
||||
// file (see top of file), so the actual dialog content isn't in the DOM.
|
||||
// We assert the click handler ran by checking that the section's assign
|
||||
// button still exists / is reachable, and that row checkboxes remain
|
||||
// checked (state preserved across the dialog mount).
|
||||
const rowCheckboxes = screen.getAllByRole("checkbox", {
|
||||
name: /^Select .* at/i,
|
||||
});
|
||||
expect(rowCheckboxes.length).toBeGreaterThan(0);
|
||||
for (const cb of rowCheckboxes) {
|
||||
expect(cb).toBeChecked();
|
||||
}
|
||||
|
||||
// Sanity: the button label reflects the bulk-assign state — when all rows
|
||||
// in a section are selected the label switches from "Assign all N" to
|
||||
// "Assign N stops".
|
||||
expect(assignAll.textContent ?? "").toMatch(/Assign \d+ stops/);
|
||||
});
|
||||
|
||||
it("collapses a supplier section on chevron click", async () => {
|
||||
render(<CollectionPoolPage />);
|
||||
|
||||
const section = document.querySelector('[aria-labelledby^="supplier-"]');
|
||||
expect(section).not.toBeNull();
|
||||
const headerId = section!.querySelector("header")!.id;
|
||||
const body = document.getElementById(`${headerId}-body`);
|
||||
expect(body).not.toBeNull();
|
||||
// Default (expanded) state: grid-rows-[1fr].
|
||||
expect(body!.className).toMatch(/grid-rows-\[1fr\]/);
|
||||
|
||||
const chevron = section!.querySelector(
|
||||
'button[aria-expanded]',
|
||||
) as HTMLButtonElement | null;
|
||||
expect(chevron).not.toBeNull();
|
||||
fireEvent.click(chevron!);
|
||||
|
||||
// After click: the section body collapses to grid-rows-[0fr].
|
||||
expect(body!.className).toMatch(/grid-rows-\[0fr\]/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("CollectionPoolPage sort control", () => {
|
||||
beforeEach(() => {
|
||||
getFullListMock.mockResolvedValue([
|
||||
|
|
|
|||
Loading…
Reference in a new issue