1import { describe, expect, it } from "vite-plus/test";
2import { userEvent } from "vite-plus/test/browser";
3
4import { resolvePastedPath } from "@t3tools/shared/path";
5
6import { render } from "../../test/render";
7import { DraftInput } from "../components/ui/draft-input";
8
9describe("settings draft commits", () => {
10 it("preserves an external update when an untouched field loses focus", async () => {
11 let saved = "~/";
12 const commit = (next: string) => {
13 saved = next;
14 };
15 await using screen = await render(<DraftInput value={saved} onCommit={commit} />);
16 const input = screen.getByRole("textbox");
17 await input.click();
18
19 saved = "/projects";
20 await screen.rerender(<DraftInput value={saved} onCommit={commit} />);
21 await userEvent.tab();
22
23 expect(saved).toBe("/projects");
24 });
25
26 it("preserves a saved edit when refocused before its server snapshot arrives", async () => {
27 let saved = "~/";
28 const commit = (next: string) => {
29 saved = next;
30 };
31 await using screen = await render(<DraftInput value="~/" onCommit={commit} />);
32 const input = screen.getByRole("textbox");
33 await input.fill("/projects");
34 await userEvent.tab();
35 expect(saved).toBe("/projects");
36
37 await input.click();
38 await screen.rerender(<DraftInput value={saved} onCommit={commit} />);
39 await userEvent.tab();
40
41 expect(saved).toBe("/projects");
42 });
43
44 it("normalizes each change against the draft before it", async () => {
45 let saved = "/mnt/old/";
46 const commit = (next: string) => {
47 saved = next;
48 };
49 await using screen = await render(
50 <DraftInput value={saved} onCommit={commit} normalizeDraft={resolvePastedPath} />,
51 );
52 const input = screen.getByRole("textbox");
53 await input.fill("/mnt/old//mnt/new");
54 await userEvent.tab();
55 expect(saved).toBe("/mnt/new");
56
57 await input.fill("");
58 await userEvent.type(input, "/tmp/a\\ b");
59 await userEvent.tab();
60 expect(saved).toBe("/tmp/a\\ b");
61 });
62});