100 lines · 4.2 KB · TypeScript
RawDownload
import { ApprovalRequestId, EnvironmentId, ThreadId } from "@t3tools/contracts";import { beforeEach, expect, it, vi } from "vite-plus/test";import { useComposerDraftStore } from "./composerDraftStore";import {  questionAttachmentDraftId,  questionAttachmentDraftPrefix,  changeQuestionAttachmentPreparation,  clearQuestionAttachmentDraft,  useQuestionAttachmentPreparation,} from "./questionAttachments"; const release = vi.hoisted(() => vi.fn());vi.mock("./lib/attachmentUploadQueue", () => ({ releaseDraftAttachments: release }));const environmentId = EnvironmentId.make("environment-1");const threadId = ThreadId.make("thread-1");const requestId = ApprovalRequestId.make("request-1");beforeEach(() => {  useComposerDraftStore.setState({ draftsByThreadKey: {}, draftThreadsByThreadKey: {} });  useQuestionAttachmentPreparation.setState({ counts: {} });  release.mockClear();});it("keeps question files separate from the normal draft and other questions", () => {  const revoke = vi.spyOn(URL, "revokeObjectURL");  const store = useComposerDraftStore.getState();  const first = questionAttachmentDraftId(environmentId, threadId, requestId, "first");  const second = questionAttachmentDraftId(environmentId, threadId, requestId, "second");  store.setPrompt({ environmentId, threadId }, "Unsent prompt");  const image = {    type: "image" as const,    id: "image-1",    name: "image.png",    mimeType: "image/png",    sizeBytes: 5,    previewUrl: "blob:question-image",    file: new File(["image"], "image.png", { type: "image/png" }),  };  store.addImages(first, [image]);  store.addFiles(second, [    {      type: "file",      id: "file-1",      name: "spec.txt",      mimeType: "text/plain",      sizeBytes: 4,      file: new File(["spec"], "spec.txt", { type: "text/plain" }),    },  ]);  changeQuestionAttachmentPreparation(first, 1);  expect(store.getComposerDraft(first)?.images).toHaveLength(1);  expect(store.getComposerDraft(second)?.files).toHaveLength(1);  clearQuestionAttachmentDraft(first);  expect(store.getComposerDraft(first)).toBeNull();  expect(store.getComposerDraft(second)?.files).toHaveLength(1);  expect(store.getComposerDraft({ environmentId, threadId })?.prompt).toBe("Unsent prompt");  expect(useQuestionAttachmentPreparation.getState().counts[first]).toBeUndefined();  expect(release).toHaveBeenCalledWith([image]);  expect(revoke).toHaveBeenCalledWith(image.previewUrl);  revoke.mockRestore();});it("scopes provider request ids to their environment and thread", () => {  const keys = [    questionAttachmentDraftId(environmentId, threadId, requestId, "q"),    questionAttachmentDraftId(EnvironmentId.make("environment-2"), threadId, requestId, "q"),    questionAttachmentDraftId(environmentId, ThreadId.make("thread-2"), requestId, "q"),  ];  expect(new Set(keys).size).toBe(3);});it("does not match drafts belonging to threads with a shared id prefix", () => {  const prefix = questionAttachmentDraftPrefix(environmentId, threadId);  expect(    questionAttachmentDraftId(environmentId, threadId, requestId, "q").startsWith(prefix),  ).toBe(true);  for (const suffix of ["-extra", ":extra", "/extra", "%extra"]) {    expect(      questionAttachmentDraftId(        environmentId,        ThreadId.make(`${threadId}${suffix}`),        requestId,        "q",      ).startsWith(prefix),    ).toBe(false);  }}); it("does not clear another environment whose id contains a question prefix", () => {  const otherEnvironment = EnvironmentId.make(    `${environmentId}:question-${encodeURIComponent(JSON.stringify(threadId))}-nested`,  );  const otherKey = questionAttachmentDraftId(otherEnvironment, threadId, requestId, "q");  const ownKey = questionAttachmentDraftId(environmentId, threadId, requestId, "q");  const store = useComposerDraftStore.getState();  store.setPrompt(otherKey, "Keep this answer");  store.setPrompt(ownKey, "Discard this answer");  const prefix = questionAttachmentDraftPrefix(environmentId, threadId);  for (const key of [ownKey, otherKey]) {    if (key.startsWith(prefix)) clearQuestionAttachmentDraft(key);  }  expect(store.getComposerDraft(ownKey)).toBeNull();  expect(store.getComposerDraft(otherKey)?.prompt).toBe("Keep this answer");});