import { afterEach, describe, expect, mock, spyOn, test } from "bun:test" import { Instance } from "../../src/project/instance" import { Server } from "../../src/server/server" import { Session } from "../../src/session" import { ModelID, ProviderID } from "../../src/provider/schema" import { MessageID, PartID, type SessionID } from "../../src/session/schema" import { SessionPrompt } from "../../src/session/prompt" import { Log } from "../../src/util/log" import { tmpdir } from "../fixture/fixture" Log.init({ print: false }) afterEach(async () => { mock.restore() await Instance.disposeAll() }) async function user(sessionID: SessionID, text: string) { const msg = await Session.updateMessage({ id: MessageID.ascending(), role: "user", sessionID, agent: "build", model: { providerID: ProviderID.make("test"), modelID: ModelID.make("test") }, time: { created: Date.now() }, }) await Session.updatePart({ id: PartID.ascending(), sessionID, messageID: msg.id, type: "text", text, }) return msg } describe("session action routes", () => { test("abort route calls SessionPrompt.cancel", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const session = await Session.create({}) const cancel = spyOn(SessionPrompt, "cancel").mockResolvedValue() const app = Server.Default() const res = await app.request(`/session/${session.id}/abort`, { method: "POST", }) expect(res.status).toBe(200) expect(await res.json()).toBe(true) expect(cancel).toHaveBeenCalledWith(session.id) await Session.remove(session.id) }, }) }) test("delete message route returns 400 when session is busy", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const session = await Session.create({}) const msg = await user(session.id, "hello") const busy = spyOn(SessionPrompt, "assertNotBusy").mockRejectedValue(new Session.BusyError(session.id)) const remove = spyOn(Session, "removeMessage").mockResolvedValue(msg.id) const app = Server.Default() const res = await app.request(`/session/${session.id}/message/${msg.id}`, { method: "DELETE", }) expect(res.status).toBe(400) expect(busy).toHaveBeenCalledWith(session.id) expect(remove).not.toHaveBeenCalled() await Session.remove(session.id) }, }) }) })