import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import axios from "axios"; import { describe, expect, it, beforeEach, vi } from "vitest"; import { PayrollLaborAllocationsTable } from "./labor-allocations-table.payroll.component.jsx"; const notification = { success: vi.fn(), error: vi.fn() }; vi.mock("axios", () => ({ default: { post: vi.fn() } })); vi.mock("react-i18next", () => ({ useTranslation: () => ({ t: (key, values = {}) => { const translations = { "jobs.labels.laborallocations": "Labor Allocations", "timetickets.actions.payall": "Pay All", "general.labels.totals": "Totals", "jobs.labels.outstandinghours": "Outstanding hours remain." }; if (key === "timetickets.successes.payall") { return "All hours paid out successfully."; } if (key === "timetickets.errors.payall") { return `Error flagging hours. ${values.error || ""}`.trim(); } return translations[key] || key; } }) })); vi.mock("../../contexts/Notifications/notificationContext.jsx", () => ({ useNotification: () => notification })); vi.mock("../responsive-table/responsive-table.component", () => { function ResponsiveTable({ dataSource = [], summary }) { return (
{`rows:${dataSource.length}`}
{summary ?
{summary()}
: null}
); } ResponsiveTable.Summary = { Row: ({ children }) =>
{children}
, Cell: ({ children }) =>
{children}
}; return { default: ResponsiveTable }; }); vi.mock("../feature-wrapper/feature-wrapper.component", () => ({ HasFeatureAccess: () => true })); vi.mock("../upsell/upsell.component", () => ({ default: () =>
Upsell
, upsellEnum: () => ({ timetickets: { allocations: "allocations" } }) })); vi.mock("../lock-wrapper/lock-wrapper.component", () => ({ default: ({ children }) => children })); describe("PayrollLaborAllocationsTable", () => { beforeEach(() => { vi.clearAllMocks(); }); it("shows a success notification after Pay All completes", async () => { axios.post .mockResolvedValueOnce({ data: [ { employeeid: "emp-1", mod_lbr_ty: "LAA", expectedHours: 4, claimedHours: 1 } ] }) .mockResolvedValueOnce({ status: 200, data: [{ id: "ticket-1" }] }); const refetch = vi.fn(); render( ); await waitFor(() => { expect(axios.post).toHaveBeenNthCalledWith(1, "/payroll/calculatelabor", { jobid: "job-1" }); }); fireEvent.click(screen.getByRole("button", { name: "Pay All" })); await waitFor(() => { expect(axios.post).toHaveBeenNthCalledWith(2, "/payroll/payall", { jobid: "job-1" }); }); expect(notification.success).toHaveBeenCalledWith({ title: "All hours paid out successfully." }); expect(refetch).toHaveBeenCalled(); }); it("shows the returned pay-all error message when payroll rejects the request", async () => { axios.post .mockResolvedValueOnce({ data: [ { employeeid: "emp-1", mod_lbr_ty: "LAA", expectedHours: 4, claimedHours: 1 } ] }) .mockResolvedValueOnce({ status: 200, data: { success: false, error: "Not all hours have been assigned." } }); render( ); await waitFor(() => { expect(axios.post).toHaveBeenNthCalledWith(1, "/payroll/calculatelabor", { jobid: "job-1" }); }); fireEvent.click(screen.getByRole("button", { name: "Pay All" })); await waitFor(() => { expect(notification.error).toHaveBeenCalledWith({ title: "Error flagging hours. Not all hours have been assigned." }); }); }); });