170 lines · 5.4 KB · TypeScript
RawDownload
import { PROVIDER_SEND_TURN_MAX_INPUT_CHARS } from "@t3tools/contracts";import { describe, expect, it, vi } from "vite-plus/test"; import { submitComposerDraft } from "./composerSubmission"; describe("submitComposerDraft", () => {  it("keeps an oversized draft editable and sends a corrected follow-up", () => {    let draft = "x".repeat(PROVIDER_SEND_TURN_MAX_INPUT_CHARS + 1);    let validationMessage: string | null = null;    const dispatchedDrafts: string[] = [];    const preventDefault = vi.fn();     const submit = () => {      const result = submitComposerDraft({        prompt: draft,        submissionTarget: "provider-turn",        event: { preventDefault },        onSend: () => {          dispatchedDrafts.push(draft);        },      });      validationMessage = result.validationMessage;    };     submit();     expect(dispatchedDrafts).toEqual([]);    expect(draft).toHaveLength(PROVIDER_SEND_TURN_MAX_INPUT_CHARS + 1);    expect(validationMessage).toBe(      "Prompt is 1 character over the 120,000-character limit. Shorten or split it before sending.",    );    expect(preventDefault).toHaveBeenCalledOnce();     draft = "Corrected prompt";    submit();     expect(dispatchedDrafts).toEqual(["Corrected prompt"]);    expect(validationMessage).toBeNull();  });   it("allows a draft at the shared character limit through the normal send path", () => {    const draft = "x".repeat(PROVIDER_SEND_TURN_MAX_INPUT_CHARS);    const onSend = vi.fn();    const preventDefault = vi.fn();     const result = submitComposerDraft({      prompt: draft,      submissionTarget: "provider-turn",      event: { preventDefault },      onSend,    });     expect(result).toEqual({ validationMessage: null, didDispatch: true });    expect(onSend).toHaveBeenCalledOnce();    expect(preventDefault).not.toHaveBeenCalled();  });   it("blocks when appended context pushes the provider input over the shared limit", () => {    const draft = "x".repeat(PROVIDER_SEND_TURN_MAX_INPUT_CHARS);    const onSend = vi.fn();     const result = submitComposerDraft({      prompt: draft,      providerInput: `${draft}\n\nTerminal context`,      submissionTarget: "provider-turn",      event: undefined,      onSend,    });     expect(result).toEqual({      validationMessage:        "Prompt is 18 characters over the 120,000-character limit. Shorten or split it before sending.",      didDispatch: false,    });    expect(draft).toHaveLength(PROVIDER_SEND_TURN_MAX_INPUT_CHARS);    expect(onSend).not.toHaveBeenCalled();     const correctedResult = submitComposerDraft({      prompt: "Corrected prompt",      providerInput: "Corrected prompt\n\nShort terminal context",      submissionTarget: "provider-turn",      event: undefined,      onSend,    });     expect(correctedResult).toEqual({ validationMessage: null, didDispatch: true });    expect(onSend).toHaveBeenCalledOnce();  });   it("does not finish submission when the send boundary rejects composed provider input", () => {    const preventDefault = vi.fn();     const result = submitComposerDraft({      prompt: "Sendable raw draft",      submissionTarget: "provider-turn",      event: { preventDefault },      onSend: () => false,    });     expect(result).toEqual({ validationMessage: null, didDispatch: false });    expect(preventDefault).toHaveBeenCalledOnce();  });   it("allows fully composed provider input at the shared character limit", () => {    const onSend = vi.fn();     const result = submitComposerDraft({      prompt: "Short draft",      providerInput: "x".repeat(PROVIDER_SEND_TURN_MAX_INPUT_CHARS),      submissionTarget: "provider-turn",      event: undefined,      onSend,    });     expect(result).toEqual({ validationMessage: null, didDispatch: true });    expect(onSend).toHaveBeenCalledOnce();  });   it("blocks a generated plan follow-up that exceeds the shared limit", () => {    const onSend = vi.fn();     const result = submitComposerDraft({      prompt: "",      providerInput: `PLEASE IMPLEMENT THIS PLAN:\n${"x".repeat(        PROVIDER_SEND_TURN_MAX_INPUT_CHARS,      )}`,      submissionTarget: "provider-turn",      event: undefined,      onSend,    });     expect(result.didDispatch).toBe(false);    expect(result.validationMessage).toContain("over the 120,000-character limit");    expect(onSend).not.toHaveBeenCalled();  });   it("allows surrounding whitespace that the provider turn contract trims", () => {    const draft = ` ${"x".repeat(PROVIDER_SEND_TURN_MAX_INPUT_CHARS)} `;    const onSend = vi.fn();    const preventDefault = vi.fn();     const result = submitComposerDraft({      prompt: draft,      submissionTarget: "provider-turn",      event: { preventDefault },      onSend,    });     expect(result).toEqual({ validationMessage: null, didDispatch: true });    expect(onSend).toHaveBeenCalledOnce();    expect(preventDefault).not.toHaveBeenCalled();  });   it("dispatches pending user input answers on their separate response path", () => {    const answer = "x".repeat(PROVIDER_SEND_TURN_MAX_INPUT_CHARS + 1);    const onSend = vi.fn();    const preventDefault = vi.fn();     const result = submitComposerDraft({      prompt: answer,      submissionTarget: "pending-user-input",      event: { preventDefault },      onSend,    });     expect(result).toEqual({ validationMessage: null, didDispatch: true });    expect(onSend).toHaveBeenCalledOnce();    expect(preventDefault).not.toHaveBeenCalled();  });});