* feat(app): create empty workspace from new-workspace composer Pressing Create with an empty composer (no text, no attachments) on the new-workspace screen now creates the workspace without an agent and lands the user on the empty-state, where they can open a terminal or start an agent on their own. Dispatching submit handler routes to a named runCreateEmptyWorkspace sibling of runCreateChatAgent so empty creation is a first-class action, not a hidden branch in the chat path. * refactor(app): extract empty-workspace helpers into own module Gives the empty-workspace dispatch a real home, shrinks the test mock graph from ~20 modules to one. * test(app): type prompt in new-workspace e2e to exercise chat path Empty-submission now creates a bare workspace (no agent), so tests that assert agent-tab/optimistic-draft behavior must type a prompt to take the chat path.
56 lines
2.1 KiB
TypeScript
56 lines
2.1 KiB
TypeScript
import { beforeAll, describe, expect, it, vi } from "vitest";
|
|
import type { ComposerAttachment } from "@/attachments/types";
|
|
import type { MessagePayload } from "@/components/message-input";
|
|
|
|
const navigateToWorkspace = vi.hoisted(() => vi.fn());
|
|
vi.mock("@/hooks/use-workspace-navigation", () => ({ navigateToWorkspace }));
|
|
|
|
let isEmptyWorkspaceSubmission: typeof import("./new-workspace-empty").isEmptyWorkspaceSubmission;
|
|
let runCreateEmptyWorkspace: typeof import("./new-workspace-empty").runCreateEmptyWorkspace;
|
|
|
|
beforeAll(async () => {
|
|
({ isEmptyWorkspaceSubmission, runCreateEmptyWorkspace } = await import("./new-workspace-empty"));
|
|
});
|
|
|
|
function payload(
|
|
input: { text?: string; attachments?: ComposerAttachment[] } = {},
|
|
): MessagePayload {
|
|
return { text: input.text ?? "", attachments: input.attachments ?? [], cwd: "/sample/repo" };
|
|
}
|
|
|
|
describe("runCreateEmptyWorkspace", () => {
|
|
it("creates a workspace without prompt or attachments and navigates to it", async () => {
|
|
const workspace = { id: "workspace-123" };
|
|
const ensureWorkspace = vi.fn().mockResolvedValue(workspace);
|
|
|
|
await runCreateEmptyWorkspace({ payload: payload(), ensureWorkspace, serverId: "server-abc" });
|
|
|
|
expect(ensureWorkspace).toHaveBeenCalledOnce();
|
|
expect(ensureWorkspace).toHaveBeenCalledWith({
|
|
cwd: "/sample/repo",
|
|
prompt: "",
|
|
attachments: [],
|
|
});
|
|
expect(navigateToWorkspace).toHaveBeenCalledOnce();
|
|
expect(navigateToWorkspace).toHaveBeenCalledWith("server-abc", workspace.id);
|
|
});
|
|
});
|
|
|
|
describe("isEmptyWorkspaceSubmission", () => {
|
|
it("treats whitespace-only text with no attachments as empty, but any attachment as non-empty", () => {
|
|
const attachment: ComposerAttachment = {
|
|
kind: "image",
|
|
metadata: {
|
|
id: "image-1",
|
|
mimeType: "image/png",
|
|
storageType: "web-indexeddb",
|
|
storageKey: "image-1",
|
|
createdAt: 0,
|
|
},
|
|
};
|
|
|
|
expect(isEmptyWorkspaceSubmission(payload({ text: " \n\t " }))).toBe(true);
|
|
expect(isEmptyWorkspaceSubmission(payload({ attachments: [attachment] }))).toBe(false);
|
|
});
|
|
});
|