test(workforce): update the missing-rate overview for this-month figures
The overview test asserted the previous all-time sub-line wording and that employee_rates was read with a site filter, both of which the cost workforce commits changed on purpose. Pins the clock so "this month" is a fixed window, and gives the unpriced worker an October entry so the new month-scoped warning is actually exercised rather than skipped. Added a case asserting rate history is read unfiltered, which is what lets a worker who moved sites keep the rate he was paid at. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
373ff2c1d3
commit
0987dcc33a
1 changed files with 16 additions and 3 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { beforeEach, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeEach, expect, it, vi } from "vitest";
|
||||
const mocks = vi.hoisted(() => ({ list: vi.fn(), scope: vi.fn() }));
|
||||
vi.mock("next/navigation", () => ({ useRouter: () => ({ refresh: vi.fn() }) }));
|
||||
vi.mock("@/lib/pb", () => ({ pbAdmin: async () => ({ collection: (name: string) => ({ getFullList: (options: unknown) => mocks.list(name, options) }) }) }));
|
||||
|
|
@ -12,6 +12,10 @@ vi.mock("./workforce-charts", () => ({ WorkforceHoursChart: () => null, TopWorke
|
|||
import WorkforceLanding from "./page";
|
||||
|
||||
beforeEach(() => {
|
||||
// Pinned so "this month" is a fixed window: the unpriced-hours warning
|
||||
// is now scoped to the current month, not to all history.
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2026-10-04T10:00:00Z"));
|
||||
mocks.scope.mockResolvedValue({ active: [{ id: "site1" }], allowed: [{ id: "site1", name: "Head Office" }], mode: "single", unrestricted: false });
|
||||
mocks.list.mockImplementation(async (name: string) => {
|
||||
if (name === "employees") return [
|
||||
|
|
@ -22,21 +26,30 @@ beforeEach(() => {
|
|||
{ employee: "paid", date_logged: "2026-09-30", hours_worked: 8 },
|
||||
{ employee: "paid", date_logged: "2026-10-01", hours_worked: 8 },
|
||||
{ employee: "missing", date_logged: "2026-09-15", hours_worked: 5 },
|
||||
{ employee: "missing", date_logged: "2026-10-02", hours_worked: 5 },
|
||||
];
|
||||
if (name === "employee_rates") return [{ employee: "paid", effective_from: "2026-10-01", rate_per_hour: 60 }];
|
||||
if (name === "sites") return [{ id: "site1", name: "Head Office" }];
|
||||
return [];
|
||||
});
|
||||
});
|
||||
afterEach(() => vi.useRealTimers());
|
||||
|
||||
it("shows a missing-rate action and an incomplete cost total using dated payroll", async () => {
|
||||
const html = renderToStaticMarkup(await WorkforceLanding({ searchParams: Promise.resolve({}) }));
|
||||
expect(html).toContain("Needs attention");
|
||||
expect(html).toContain("Missing Worker");
|
||||
expect(html).toContain("Add rate for Missing Worker");
|
||||
expect(html).toContain("5 hrs still need rates");
|
||||
// Only the 5 October hours are unpriced this month; the 5 September
|
||||
// ones are history and no longer reported on the tile.
|
||||
expect(html).toContain("5 hrs this month still need rates");
|
||||
expect(html).toContain("Paid Worker: 880");
|
||||
expect(mocks.list).toHaveBeenCalledWith("employee_rates", { filter: 'employee.site="site1"' });
|
||||
});
|
||||
|
||||
it("does not filter rate history by site, so a worker priced elsewhere is still priced", async () => {
|
||||
await WorkforceLanding({ searchParams: Promise.resolve({}) });
|
||||
const rateCall = mocks.list.mock.calls.find(([name]) => name === "employee_rates");
|
||||
expect(rateCall?.[1]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("hides inactive workers from rate alerts but preserves their recorded costs", async () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue