mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-04 19:32:06 +00:00
200 lines
6.2 KiB
TypeScript
200 lines
6.2 KiB
TypeScript
import { fireEvent, screen } from "@testing-library/react";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { toast } from "react-toastify";
|
|
import { SlideOverExtrasTab } from "@/app/(protected)/workorders/_components/detail/tabs/slide-over-extras-tab";
|
|
import { workOrdersApi } from "@/domain/work-orders/api/work-orders-api";
|
|
import type { MediaFile } from "@/domain/work-orders/types/work-order-media";
|
|
import { renderWithProviders } from "@/test/test-utils";
|
|
|
|
const photo: MediaFile = {
|
|
id: "m1",
|
|
name: "safety-form.pdf",
|
|
fileType: "pdf",
|
|
url: "blob:1",
|
|
category: "Report",
|
|
};
|
|
|
|
const avetaDoc: MediaFile = {
|
|
id: "m2",
|
|
name: "aveta-clearance.pdf",
|
|
fileType: "pdf",
|
|
url: "blob:2",
|
|
category: "Aveta",
|
|
};
|
|
|
|
describe("SlideOverExtrasTab Aveta", () => {
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
vi.unstubAllGlobals();
|
|
});
|
|
it("does not label the first extra document as Aveta when none is explicitly Aveta", () => {
|
|
renderWithProviders(
|
|
<SlideOverExtrasTab
|
|
uploads={[photo]}
|
|
avetaRequired
|
|
isReadOnly
|
|
onUpload={vi.fn()}
|
|
onRemove={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
expect(screen.getByText("safety-form.pdf")).toBeInTheDocument();
|
|
expect(screen.getAllByText("Aveta")).toHaveLength(1);
|
|
});
|
|
|
|
it("labels only an explicitly Aveta-categorized extra document", () => {
|
|
renderWithProviders(
|
|
<SlideOverExtrasTab
|
|
uploads={[photo, avetaDoc]}
|
|
avetaRequired
|
|
isReadOnly
|
|
onUpload={vi.fn()}
|
|
onRemove={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
expect(screen.getByText("safety-form.pdf")).toBeInTheDocument();
|
|
expect(screen.getByText("aveta-clearance.pdf")).toBeInTheDocument();
|
|
expect(screen.getAllByText("Aveta").length).toBeGreaterThanOrEqual(2);
|
|
});
|
|
|
|
it("categorizes an Extra file as Aveta without auto-labeling the first upload", () => {
|
|
const onCategorize = vi.fn();
|
|
renderWithProviders(
|
|
<SlideOverExtrasTab
|
|
uploads={[photo]}
|
|
avetaRequired
|
|
isReadOnly={false}
|
|
onUpload={vi.fn()}
|
|
onRemove={vi.fn()}
|
|
onCategorize={onCategorize}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.change(screen.getByLabelText("Category for safety-form.pdf"), {
|
|
target: { value: "Aveta" },
|
|
});
|
|
expect(onCategorize).toHaveBeenCalledWith("m1", "Aveta");
|
|
expect(screen.queryByText("safety-form.pdf")).toBeInTheDocument();
|
|
});
|
|
|
|
it("opens Extra Docs through authenticated content instead of a static href", async () => {
|
|
const blob = new Blob(["pdf"], { type: "application/pdf" });
|
|
const getMediaContent = vi.spyOn(workOrdersApi, "getMediaContent").mockResolvedValue(blob);
|
|
const createObjectURL = vi.fn(() => "blob:authorized");
|
|
vi.stubGlobal("URL", { ...URL, createObjectURL, revokeObjectURL: vi.fn() });
|
|
const tab = {
|
|
opener: window,
|
|
location: { href: "about:blank" },
|
|
close: vi.fn(),
|
|
};
|
|
const open = vi.fn(() => tab);
|
|
vi.stubGlobal("open", open);
|
|
|
|
renderWithProviders(
|
|
<SlideOverExtrasTab
|
|
uploads={[{ ...photo, url: "https://cdn.example.com/Assets/Documents/secret.pdf" }]}
|
|
workOrderId={10}
|
|
avetaRequired
|
|
isReadOnly
|
|
onUpload={vi.fn()}
|
|
onRemove={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
expect(screen.queryByRole("link")).not.toBeInTheDocument();
|
|
fireEvent.click(screen.getByRole("button", { name: "safety-form.pdf" }));
|
|
|
|
await vi.waitFor(() => {
|
|
expect(getMediaContent).toHaveBeenCalledWith(10, "m1");
|
|
});
|
|
expect(createObjectURL).toHaveBeenCalledWith(blob);
|
|
expect(open).toHaveBeenCalledWith("about:blank", "_blank");
|
|
expect(tab.opener).toBeNull();
|
|
expect(tab.location.href).toBe("blob:authorized");
|
|
});
|
|
|
|
it("shows an error when the browser blocks the document tab", async () => {
|
|
const getMediaContent = vi.spyOn(workOrdersApi, "getMediaContent");
|
|
const toastError = vi.spyOn(toast, "error").mockImplementation(vi.fn());
|
|
vi.stubGlobal(
|
|
"open",
|
|
vi.fn(() => null),
|
|
);
|
|
|
|
renderWithProviders(
|
|
<SlideOverExtrasTab
|
|
uploads={[photo]}
|
|
workOrderId={10}
|
|
isReadOnly
|
|
onUpload={vi.fn()}
|
|
onRemove={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "safety-form.pdf" }));
|
|
|
|
expect(toastError).toHaveBeenCalledWith(
|
|
"Unable to open this document. Please allow pop-ups and try again.",
|
|
);
|
|
expect(getMediaContent).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("shows Extra Docs accept copy with PDF DOC and 50MB", () => {
|
|
renderWithProviders(
|
|
<SlideOverExtrasTab uploads={[]} isReadOnly={false} onUpload={vi.fn()} onRemove={vi.fn()} />,
|
|
);
|
|
|
|
expect(
|
|
screen.getByText("Accepted: JPG, PNG, MP4, MOV, PDF, DOC · Max 50MB per file"),
|
|
).toBeInTheDocument();
|
|
const input = document.querySelector('input[type="file"]');
|
|
expect(input?.getAttribute("accept")).toContain(".pdf");
|
|
expect(input?.getAttribute("accept")).toContain(".doc");
|
|
expect(input?.getAttribute("accept")).toContain(".docx");
|
|
});
|
|
|
|
it("disables document opening until the work order id is available", () => {
|
|
renderWithProviders(
|
|
<SlideOverExtrasTab uploads={[photo]} isReadOnly onUpload={vi.fn()} onRemove={vi.fn()} />,
|
|
);
|
|
|
|
expect(screen.getByRole("button", { name: "safety-form.pdf" })).toBeDisabled();
|
|
});
|
|
|
|
it("labels each extra item with its type and category", () => {
|
|
const sitePhoto: MediaFile = {
|
|
id: "m3",
|
|
name: "site.jpg",
|
|
fileType: "image",
|
|
url: "blob:3",
|
|
category: "Photo",
|
|
purpose: "Extra",
|
|
};
|
|
const walkthrough: MediaFile = {
|
|
id: "m4",
|
|
name: "walkthrough.mp4",
|
|
fileType: "video",
|
|
url: "blob:4",
|
|
category: "Video",
|
|
purpose: "Extra",
|
|
};
|
|
|
|
renderWithProviders(
|
|
<SlideOverExtrasTab
|
|
uploads={[sitePhoto, walkthrough, avetaDoc]}
|
|
isReadOnly
|
|
onUpload={vi.fn()}
|
|
onRemove={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
expect(screen.getByRole("group", { name: "Photo, Extra: site.jpg" })).toBeInTheDocument();
|
|
expect(
|
|
screen.getByRole("group", { name: "Video, Extra: walkthrough.mp4" }),
|
|
).toBeInTheDocument();
|
|
expect(
|
|
screen.getByRole("group", { name: "PDF, Aveta: aveta-clearance.pdf" }),
|
|
).toBeInTheDocument();
|
|
});
|
|
});
|