1import { EnvironmentId } from "@t3tools/contracts";
2import { expect, it, vi } from "vite-plus/test";
3
4import { act, fakeTimers, render } from "../../test/render";
5import type { AttachmentUploadState } from "../lib/attachmentUploadState";
6import { useAttachmentUploadProgress } from "./useAttachmentUploadProgress";
7
8function Probe({ id = "image", upload }: { id?: string; upload: AttachmentUploadState }) {
9 const progress = useAttachmentUploadProgress(id, upload);
10 return <output>{progress ?? "hidden"}</output>;
11}
12
13it("skips fast uploads and delays each attempt without delaying later progress or completion", async () => {
14 const environmentId = EnvironmentId.make("environment");
15 const uploading = (progress: number) => ({
16 status: "uploading" as const,
17 environmentId,
18 progress,
19 });
20 const ready = { status: "ready" as const, environmentId, attachmentId: "attachment" };
21 // The first render reads the clock to schedule the badge.
22 using _timers = fakeTimers({ now: 0 });
23 await using screen = await render(<Probe upload={uploading(0)} />);
24 await expect.element(screen.getByText("hidden")).toBeInTheDocument();
25 await act(() => vi.advanceTimersByTime(75));
26 await screen.rerender(<Probe upload={ready} />);
27 await act(() => vi.advanceTimersByTime(75));
28 await expect.element(screen.getByText("hidden")).toBeInTheDocument();
29
30 await screen.rerender(<Probe upload={uploading(0)} />);
31 await act(() => vi.advanceTimersByTime(149));
32 await screen.rerender(<Probe upload={uploading(0.45)} />);
33 await expect.element(screen.getByText("hidden")).toBeInTheDocument();
34 await act(() => vi.advanceTimersByTime(1));
35 await expect.element(screen.getByText("45%")).toBeInTheDocument();
36 await screen.rerender(<Probe upload={uploading(0.7)} />);
37 await expect.element(screen.getByText("70%")).toBeInTheDocument();
38 await screen.rerender(<Probe upload={ready} />);
39 await expect.element(screen.getByText("hidden")).toBeInTheDocument();
40
41 await screen.rerender(<Probe upload={uploading(0)} />);
42 await expect.element(screen.getByText("hidden")).toBeInTheDocument();
43 await act(() => vi.advanceTimersByTime(150));
44 await expect.element(screen.getByText("0%")).toBeInTheDocument();
45 await screen.rerender(<Probe id="another-image" upload={uploading(0)} />);
46 await expect.element(screen.getByText("hidden")).toBeInTheDocument();
47});