1import { describe, expect, it } from "vite-plus/test";
2import { createComposerTypingGuardState, updateComposerTypingGuard } from "./composerTypingGuard";
3
4function typing() {
5 return updateComposerTypingGuard(
6 updateComposerTypingGuard(createComposerTypingGuardState(), { type: "focus" }),
7 { type: "type", now: 1000 },
8 );
9}
10
11describe("composer typing guard", () => {
12 it("holds new requests while the focused draft was recently edited", () => {
13 const state = updateComposerTypingGuard(typing(), {
14 type: "requests",
15 requestIds: ["approval", "question"],
16 now: 2499,
17 });
18 expect([...state.held]).toEqual(["approval", "question"]);
19 });
20
21 it.each(["idle", "send", "blur"] as const)(
22 "releases on %s and never re-holds the request",
23 (type) => {
24 let state = updateComposerTypingGuard(typing(), {
25 type: "requests",
26 requestIds: ["question"],
27 now: 1200,
28 });
29 state = updateComposerTypingGuard(state, { type });
30 expect([...state.held]).toEqual([]);
31 state = updateComposerTypingGuard(state, { type: "focus" });
32 state = updateComposerTypingGuard(state, { type: "type", now: 2000 });
33 state = updateComposerTypingGuard(state, { type: "requests", requestIds: [], now: 2100 });
34 state = updateComposerTypingGuard(state, {
35 type: "requests",
36 requestIds: ["question", "new-question"],
37 now: 2200,
38 });
39 expect([...state.held]).toEqual(["new-question"]);
40 },
41 );
42
43 it("shows requests immediately when idle or unfocused", () => {
44 for (const state of [
45 createComposerTypingGuardState(),
46 typing(),
47 updateComposerTypingGuard(typing(), { type: "blur" }),
48 ]) {
49 expect([
50 ...updateComposerTypingGuard(state, {
51 type: "requests",
52 requestIds: ["question"],
53 now: 2500,
54 }).held,
55 ]).toEqual([]);
56 }
57 });
58
59 it("does not hide a request that already took over when typing starts", () => {
60 let state = updateComposerTypingGuard(createComposerTypingGuardState(), {
61 type: "requests",
62 requestIds: ["question"],
63 now: 0,
64 });
65 state = updateComposerTypingGuard(state, { type: "focus" });
66 state = updateComposerTypingGuard(state, { type: "type", now: 1000 });
67 state = updateComposerTypingGuard(state, {
68 type: "requests",
69 requestIds: ["question"],
70 now: 1100,
71 });
72 expect([...state.held]).toEqual([]);
73 });
74
75 it("drops a hold when its request is resolved", () => {
76 const held = updateComposerTypingGuard(typing(), {
77 type: "requests",
78 requestIds: ["question"],
79 now: 1100,
80 });
81 expect([
82 ...updateComposerTypingGuard(held, {
83 type: "requests",
84 requestIds: [],
85 now: 1200,
86 }).held,
87 ]).toEqual([]);
88 });
89});