import { describe, it, expect, vi, afterEach } from "vitest"; import { createCreateHandler } from "@/routes/worktree/routes/create.js"; import { AUTOMAKER_INITIAL_COMMIT_MESSAGE } from "@/routes/worktree/common.js"; import { exec } from "child_process"; import { promisify } from "util"; import * as fs from "fs/promises"; import * as os from "os"; import * as path from "path"; const execAsync = promisify(exec); describe("worktree create route - repositories without commits", () => { let repoPath: string | null = null; async function initRepoWithoutCommit() { repoPath = await fs.mkdtemp( path.join(os.tmpdir(), "automaker-no-commit-") ); await execAsync("git init", { cwd: repoPath }); await execAsync('git config user.email "test@example.com"', { cwd: repoPath, }); await execAsync('git config user.name "Test User"', { cwd: repoPath }); // Intentionally skip creating an initial commit } afterEach(async () => { if (!repoPath) { return; } await fs.rm(repoPath, { recursive: true, force: true }); repoPath = null; }); it("creates an initial commit before adding a worktree when HEAD is missing", async () => { await initRepoWithoutCommit(); const handler = createCreateHandler(); const json = vi.fn(); const status = vi.fn().mockReturnThis(); const req = { body: { projectPath: repoPath, branchName: "feature/no-head" }, } as any; const res = { json, status, } as any; await handler(req, res); expect(status).not.toHaveBeenCalled(); expect(json).toHaveBeenCalled(); const payload = json.mock.calls[0][0]; expect(payload.success).toBe(true); const { stdout: commitCount } = await execAsync( "git rev-list --count HEAD", { cwd: repoPath! } ); expect(Number(commitCount.trim())).toBeGreaterThan(0); const { stdout: latestMessage } = await execAsync( "git log -1 --pretty=%B", { cwd: repoPath! } ); expect(latestMessage.trim()).toBe(AUTOMAKER_INITIAL_COMMIT_MESSAGE); }); });