mirror of
https://github.com/multica-ai/multica.git
synced 2026-08-03 11:10:23 +02:00
86 lines
2.4 KiB
TypeScript
86 lines
2.4 KiB
TypeScript
import { act, render, waitFor } from "@testing-library/react";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { useAutoSave } from "./use-auto-save";
|
|
|
|
function deferred<T>() {
|
|
let resolve!: (value: T | PromiseLike<T>) => void;
|
|
let reject!: (reason?: unknown) => void;
|
|
const promise = new Promise<T>((resolvePromise, rejectPromise) => {
|
|
resolve = resolvePromise;
|
|
reject = rejectPromise;
|
|
});
|
|
return { promise, resolve, reject };
|
|
}
|
|
|
|
function AutoSaveHarness({
|
|
value,
|
|
onSave,
|
|
onSuccess,
|
|
}: {
|
|
value: string;
|
|
onSave: (value: string) => Promise<void>;
|
|
onSuccess: (value: string) => void;
|
|
}) {
|
|
useAutoSave({
|
|
value,
|
|
savedValue: "",
|
|
onSave,
|
|
onSuccess,
|
|
delay: 650,
|
|
isEqual: (left, right) => left === right,
|
|
});
|
|
return null;
|
|
}
|
|
|
|
describe("useAutoSave success feedback", () => {
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it("reports success after the persisted value resolves", async () => {
|
|
vi.useFakeTimers({ shouldAdvanceTime: true });
|
|
const onSave = vi.fn(async () => undefined);
|
|
const onSuccess = vi.fn();
|
|
render(
|
|
<AutoSaveHarness value="saved" onSave={onSave} onSuccess={onSuccess} />,
|
|
);
|
|
|
|
act(() => vi.advanceTimersByTime(650));
|
|
|
|
await waitFor(() => {
|
|
expect(onSave).toHaveBeenCalledWith("saved");
|
|
expect(onSuccess).toHaveBeenCalledWith("saved");
|
|
});
|
|
});
|
|
|
|
it("waits for the latest queued value before reporting success", async () => {
|
|
vi.useFakeTimers({ shouldAdvanceTime: true });
|
|
const first = deferred<void>();
|
|
const second = deferred<void>();
|
|
const onSave = vi
|
|
.fn<(value: string) => Promise<void>>()
|
|
.mockReturnValueOnce(first.promise)
|
|
.mockReturnValueOnce(second.promise);
|
|
const onSuccess = vi.fn();
|
|
const { rerender } = render(
|
|
<AutoSaveHarness value="first" onSave={onSave} onSuccess={onSuccess} />,
|
|
);
|
|
|
|
act(() => vi.advanceTimersByTime(650));
|
|
await waitFor(() => expect(onSave).toHaveBeenCalledWith("first"));
|
|
|
|
rerender(
|
|
<AutoSaveHarness value="second" onSave={onSave} onSuccess={onSuccess} />,
|
|
);
|
|
act(() => vi.advanceTimersByTime(650));
|
|
|
|
await act(async () => first.resolve());
|
|
await waitFor(() => expect(onSave).toHaveBeenCalledWith("second"));
|
|
expect(onSuccess).not.toHaveBeenCalled();
|
|
|
|
await act(async () => second.resolve());
|
|
await waitFor(() => expect(onSuccess).toHaveBeenCalledWith("second"));
|
|
expect(onSuccess).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|