191 lines
4.6 KiB
JavaScript
191 lines
4.6 KiB
JavaScript
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 (
|
|
<div data-testid="responsive-table">
|
|
<div>{`rows:${dataSource.length}`}</div>
|
|
{summary ? <div>{summary()}</div> : null}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
ResponsiveTable.Summary = {
|
|
Row: ({ children }) => <div>{children}</div>,
|
|
Cell: ({ children }) => <div>{children}</div>
|
|
};
|
|
|
|
return {
|
|
default: ResponsiveTable
|
|
};
|
|
});
|
|
|
|
vi.mock("../feature-wrapper/feature-wrapper.component", () => ({
|
|
HasFeatureAccess: () => true
|
|
}));
|
|
|
|
vi.mock("../upsell/upsell.component", () => ({
|
|
default: () => <div>Upsell</div>,
|
|
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(
|
|
<PayrollLaborAllocationsTable
|
|
jobId="job-1"
|
|
joblines={[{ id: "line-1", convertedtolbr: false }]}
|
|
timetickets={[]}
|
|
bodyshop={{
|
|
features: {
|
|
timetickets: true
|
|
},
|
|
employees: [{ id: "emp-1", first_name: "Avery", last_name: "Johnson" }]
|
|
}}
|
|
adjustments={[]}
|
|
refetch={refetch}
|
|
/>
|
|
);
|
|
|
|
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(
|
|
<PayrollLaborAllocationsTable
|
|
jobId="job-1"
|
|
joblines={[{ id: "line-1", convertedtolbr: false }]}
|
|
timetickets={[]}
|
|
bodyshop={{
|
|
features: {
|
|
timetickets: true
|
|
},
|
|
employees: [{ id: "emp-1", first_name: "Avery", last_name: "Johnson" }]
|
|
}}
|
|
adjustments={[]}
|
|
/>
|
|
);
|
|
|
|
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."
|
|
});
|
|
});
|
|
});
|
|
});
|