import { fireEvent, waitFor } from "@testing-library/react";
import { beforeEach, 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 { probeVideoDurationSeconds } from "@/lib/probe-video-duration";
import { renderWithProviders } from "@/test/test-utils";
vi.mock("react-toastify", () => ({ toast: { error: vi.fn() } }));
vi.mock("@/lib/probe-video-duration", () => ({ probeVideoDurationSeconds: vi.fn() }));
const MB = 1_000_000;
function phoneFile(name: string, type: string, size: number): File {
return { name, type, size } as File;
}
function selectFiles(files: File[]) {
const input = document.querySelector('input[type="file"]');
fireEvent.change(input as HTMLInputElement, { target: { files } });
}
describe("SlideOverExtrasTab SH-116 media contract", () => {
beforeEach(() => {
vi.mocked(toast.error).mockClear();
vi.mocked(probeVideoDurationSeconds).mockReset();
vi.mocked(probeVideoDurationSeconds).mockResolvedValue(30);
});
it("rejects a video longer than 90 seconds before upload", async () => {
vi.mocked(probeVideoDurationSeconds).mockResolvedValue(95);
const onUpload = vi.fn();
renderWithProviders(
,
);
selectFiles([phoneFile("IMG_0700.MOV", "video/quicktime", 40 * MB)]);
await waitFor(() =>
expect(toast.error).toHaveBeenCalledWith("Videos must be 90 seconds or shorter."),
);
expect(onUpload).not.toHaveBeenCalled();
});
it("rejects the 11th photo and 4th video counted across the whole work order", async () => {
const onUpload = vi.fn();
const report = phoneFile("inspection.pdf", "application/pdf", 2 * MB);
renderWithProviders(
,
);
selectFiles([
phoneFile("IMG_0701.jpg", "image/jpeg", 2 * MB),
phoneFile("IMG_0702.MOV", "video/quicktime", 20 * MB),
report,
]);
await waitFor(() => expect(onUpload).toHaveBeenCalledTimes(1));
expect(onUpload).toHaveBeenCalledWith([report]);
expect(toast.error).toHaveBeenCalledWith("A work order can have at most 10 photos.");
expect(toast.error).toHaveBeenCalledWith("A work order can have at most 3 videos.");
});
it("accepts a ~60 MB phone video whose duration the browser cannot read", async () => {
vi.mocked(probeVideoDurationSeconds).mockResolvedValue(null);
const onUpload = vi.fn();
const video = phoneFile("IMG_0703.MOV", "", 60 * MB);
renderWithProviders(
,
);
selectFiles([video]);
await waitFor(() => expect(onUpload).toHaveBeenCalledWith([video]));
expect(toast.error).not.toHaveBeenCalled();
});
});