import { randomUUID } from "node:crypto"; import express from "express"; import request from "supertest"; import { afterAll, beforeAll, describe, expect, it } from "vitest"; import { eq } from "drizzle-orm"; import { companies, createDb, issues } from "@paperclipai/db"; import { getEmbeddedPostgresTestSupport, startEmbeddedPostgresTestDatabase, } from "./helpers/embedded-postgres.js"; import { errorHandler } from "../middleware/index.js"; import { issueRoutes } from "../routes/issues.js"; const embeddedPostgresSupport = await getEmbeddedPostgresTestSupport(); const describeEmbeddedPostgres = embeddedPostgresSupport.supported ? describe : describe.skip; if (!embeddedPostgresSupport.supported) { console.warn( `Skipping embedded Postgres issue identifier route tests on this host: ${embeddedPostgresSupport.reason ?? "unsupported environment"}`, ); } describeEmbeddedPostgres("issue identifier routes", () => { let db!: ReturnType; let tempDb: Awaited> | null = null; beforeAll(async () => { tempDb = await startEmbeddedPostgresTestDatabase("paperclip-issue-identifier-routes-"); db = createDb(tempDb.connectionString); }, 20_000); afterAll(async () => { await tempDb?.cleanup(); }); function createApp(companyId: string) { const app = express(); app.use(express.json()); app.use((req, _res, next) => { (req as any).actor = { type: "board", userId: "cloud-user-1", companyIds: [companyId], memberships: [{ companyId, membershipRole: "owner", status: "active" }], source: "cloud_tenant", isInstanceAdmin: true, }; next(); }); app.use("/api", issueRoutes(db, {} as any)); app.use(errorHandler); return app; } it("resolves alphanumeric Cloud tenant issue identifiers for detail reads and updates", async () => { const companyId = randomUUID(); const issueId = randomUUID(); await db.insert(companies).values({ id: companyId, name: "Cloud tenant", issuePrefix: "PC1A2", requireBoardApprovalForNewAgents: false, }); await db.insert(issues).values({ id: issueId, companyId, issueNumber: 7, identifier: "PC1A2-7", title: "Tenant identifier route", status: "todo", priority: "medium", createdByUserId: "cloud-user-1", }); const app = createApp(companyId); const read = await request(app).get("/api/issues/pc1a2-7"); expect(read.status, JSON.stringify(read.body)).toBe(200); expect(read.body).toMatchObject({ id: issueId, companyId, identifier: "PC1A2-7", }); const updated = await request(app) .patch("/api/issues/PC1A2-7") .send({ priority: "high" }); expect(updated.status, JSON.stringify(updated.body)).toBe(200); expect(updated.body).toMatchObject({ id: issueId, companyId, identifier: "PC1A2-7", priority: "high", }); const stored = await db .select({ priority: issues.priority }) .from(issues) .where(eq(issues.id, issueId)) .then((rows) => rows[0] ?? null); expect(stored?.priority).toBe("high"); }); });