|
| 1 | +import{describe,it,expect,vi,beforeEach}from"vitest"; |
| 2 | + |
| 3 | +import{validateAuthContext}from"@/lib/auth/validateAuthContext"; |
| 4 | +import{insertSession}from"@/lib/supabase/sessions/insertSession"; |
| 5 | +import{deleteSessionById}from"@/lib/supabase/sessions/deleteSessionById"; |
| 6 | +import{insertChat}from"@/lib/supabase/chats/insertChat"; |
| 7 | +import{createSessionHandler}from"@/lib/sessions/createSessionHandler"; |
| 8 | +import{ |
| 9 | +baseChatRow, |
| 10 | +baseSessionRow, |
| 11 | +makeCreateSessionReq, |
| 12 | +okAuth, |
| 13 | +}from"@/lib/sessions/__tests__/createSessionHandlerFixtures"; |
| 14 | + |
| 15 | +vi.mock("@/lib/networking/getCorsHeaders",()=>({ |
| 16 | +getCorsHeaders: ()=>({"Access-Control-Allow-Origin": "*"}), |
| 17 | +})); |
| 18 | +vi.mock("@/lib/auth/validateAuthContext",()=>({validateAuthContext: vi.fn()})); |
| 19 | +vi.mock("@/lib/supabase/sessions/insertSession",()=>({insertSession: vi.fn()})); |
| 20 | +vi.mock("@/lib/supabase/sessions/deleteSessionById",()=>({deleteSessionById: vi.fn()})); |
| 21 | +vi.mock("@/lib/supabase/chats/insertChat",()=>({insertChat: vi.fn()})); |
| 22 | + |
| 23 | +describe("createSessionHandler — persistence",()=>{ |
| 24 | +beforeEach(()=>vi.clearAllMocks()); |
| 25 | + |
| 26 | +it("creates session and chat with defaults on empty body",async()=>{ |
| 27 | +vi.mocked(validateAuthContext).mockResolvedValue(okAuth); |
| 28 | +vi.mocked(insertSession).mockResolvedValue(baseSessionRow()); |
| 29 | +vi.mocked(insertChat).mockResolvedValue(baseChatRow()); |
| 30 | + |
| 31 | +constres=awaitcreateSessionHandler(makeCreateSessionReq({})); |
| 32 | +expect(res.status).toBe(200); |
| 33 | + |
| 34 | +constbody=(awaitres.json())as{session: {userId: string};chat: {sessionId: string}}; |
| 35 | +expect(body.session.userId).toBe("acc-uuid-1"); |
| 36 | +expect(body.chat.sessionId).toBe("sess_1"); |
| 37 | + |
| 38 | +constinsertArgs=vi.mocked(insertSession).mock.calls[0][0]; |
| 39 | +expect(insertArgs.account_id).toBe("acc-uuid-1"); |
| 40 | +expect(insertArgs.status).toBe("running"); |
| 41 | +expect(insertArgs.lifecycle_state).toBe("provisioning"); |
| 42 | +expect(insertArgs.sandbox_state).toEqual({type: "vercel"}); |
| 43 | + |
| 44 | +constchatArgs=vi.mocked(insertChat).mock.calls[0][0]; |
| 45 | +expect(chatArgs.session_id).toBe("sess_1"); |
| 46 | +expect(chatArgs.title).toBe("New chat"); |
| 47 | +}); |
| 48 | + |
| 49 | +it("uses provided title when present",async()=>{ |
| 50 | +vi.mocked(validateAuthContext).mockResolvedValue(okAuth); |
| 51 | +vi.mocked(insertSession).mockResolvedValue(baseSessionRow({title: "Hello world"})); |
| 52 | +vi.mocked(insertChat).mockResolvedValue(baseChatRow()); |
| 53 | + |
| 54 | +awaitcreateSessionHandler(makeCreateSessionReq({title: "Hello world"})); |
| 55 | +expect(vi.mocked(insertSession).mock.calls[0][0].title).toBe("Hello world"); |
| 56 | +}); |
| 57 | + |
| 58 | +it("returns 500 when insertSession fails",async()=>{ |
| 59 | +vi.mocked(validateAuthContext).mockResolvedValue(okAuth); |
| 60 | +vi.mocked(insertSession).mockResolvedValue(null); |
| 61 | + |
| 62 | +constres=awaitcreateSessionHandler(makeCreateSessionReq({})); |
| 63 | +expect(res.status).toBe(500); |
| 64 | +expect(insertChat).not.toHaveBeenCalled(); |
| 65 | +}); |
| 66 | + |
| 67 | +it("rolls back the session and returns 500 when insertChat fails",async()=>{ |
| 68 | +vi.mocked(validateAuthContext).mockResolvedValue(okAuth); |
| 69 | +vi.mocked(insertSession).mockResolvedValue(baseSessionRow({id: "sess_rollback"})); |
| 70 | +vi.mocked(insertChat).mockResolvedValue(null); |
| 71 | + |
| 72 | +constres=awaitcreateSessionHandler(makeCreateSessionReq({})); |
| 73 | +expect(res.status).toBe(500); |
| 74 | +expect(deleteSessionById).toHaveBeenCalledWith("sess_rollback"); |
| 75 | +}); |
| 76 | +}); |
0 commit comments