import type { MessageBlock } from "@rakazo/contracts"; import type { PrismaClient } from "@rakazo/db"; import { createDb, provisionMessagingIdentity } from "@rakazo/db"; import { afterAll, beforeAll, describe, expect, it } from "vitest"; import { loadMessagePage } from "./thread-message-pages.js"; const databaseUrl = process.env.DATABASE_URL; const describePostgres = process.env.VERIFY_DATABASE && databaseUrl ? describe.sequential : describe.skip; describePostgres("loadMessagePage (PostgreSQL)", () => { let prisma: PrismaClient; let close: () => Promise; let identity: { userId: string; spaceId: string; botId: string; threadId: string }; let userRunId: string; let peerRunId: string; let seq = 0; beforeAll(async () => { const db = createDb(databaseUrl!); prisma = db.prisma; close = async () => { await db.prisma.$disconnect(); await db.pool.end(); }; identity = await provisionMessagingIdentity( prisma, { provider: "sendblue", address: `+1555${Date.now().toString().slice(-7)}` }, { signupsEnabled: undefined, signupAllowlist: undefined }, ); const { spaceId, botId, threadId, userId } = identity; const owner = { spaceId, botId, threadId, userId }; const run = async (trigger: string) => { const task = await prisma.task.create({ data: { ...owner, prompt: "fixture", status: "completed" }, }); const created = await prisma.run.create({ data: { ...owner, taskId: task.id, status: "completed", trigger }, }); return created.id; }; userRunId = await run("user_message"); peerRunId = await run("bot_message"); seq = ( await prisma.message.aggregate({ where: { threadId: identity.threadId }, _max: { seq: true }, }) )._max.seq ?? 0; }); afterAll(async () => { if (identity) { await prisma.messagingIdentity.deleteMany({ where: { userId: identity.userId } }); await prisma.organization.deleteMany({ where: { id: identity.spaceId } }); await prisma.user.deleteMany({ where: { id: identity.userId } }); } await close?.(); }); async function message(id: string, runId: string | null, blocks: MessageBlock[]) { seq += 1; await prisma.message.create({ data: { id: `${identity.threadId}-${id}`, threadId: identity.threadId, seq, role: "bot", runId, blocks, }, }); return seq; } const ids = (page: Awaited>) => page.messages.map((row) => row.id.slice(identity.threadId.length + 1)); it("fills a page with visible rows across a long stretch of hidden peer activity", async () => { await message("older", userRunId, [{ kind: "text", text: "Older answer" }]); await message("newer", userRunId, [{ kind: "text", text: "Newer answer" }]); for (let index = 0; index < 30; index += 1) { await message(`peer-steps-${index}`, peerRunId, [ { kind: "steps", steps: [{ label: "Working", count: 1 }] }, ]); } await message("peer-receipt", peerRunId, [ { kind: "bot_message_received", fromBotId: "bot-2", fromBotName: "Coder", text: "Done." }, ]); await message("peer-reply", peerRunId, [{ kind: "text", text: "Peer summary" }]); await message("orphan-run", "run-that-no-longer-exists", [{ kind: "text", text: "Kept" }]); const first = await loadMessagePage(prisma, identity.threadId, undefined, 3); expect(ids(first)).toEqual(["peer-receipt", "peer-reply", "orphan-run"]); const second = await loadMessagePage(prisma, identity.threadId, first.olderCursor!, 2); expect(ids(second)).toEqual(["older", "newer"]); const peerView = await loadMessagePage( prisma, identity.threadId, undefined, 3, undefined, true, ); expect(ids(peerView)).toEqual(["peer-receipt", "peer-reply", "orphan-run"]); const peerOlder = await loadMessagePage( prisma, identity.threadId, peerView.olderCursor!, 1, undefined, true, ); expect(ids(peerOlder)).toEqual(["peer-steps-29"]); }); it("skips a receipt-only page for web but returns it when receipts are displayed", async () => { await message("before-receipts", userRunId, [{ kind: "text", text: "Answer" }]); await message("sent", userRunId, [ { kind: "bot_message_sent", toBotId: "bot-2", toBotName: "Coder", text: "Check this." }, ]); await message("received", peerRunId, [ { kind: "bot_message_received", fromBotId: "bot-2", fromBotName: "Coder", text: "Done." }, ]); const web = await loadMessagePage(prisma, identity.threadId, undefined, 2); expect(ids(web)).toEqual(["orphan-run", "before-receipts"]); const mobile = await loadMessagePage( prisma, identity.threadId, undefined, 2, undefined, false, true, ); expect(ids(mobile)).toEqual(["sent", "received"]); }); });