111 lines
3.6 KiB
TypeScript
111 lines
3.6 KiB
TypeScript
import { randomUUID } from "node:crypto";
|
|
import express from "express";
|
|
import request from "supertest";
|
|
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
|
|
import { companies, createDb, projects } from "@paperclipai/db";
|
|
import {
|
|
getEmbeddedPostgresTestSupport,
|
|
startEmbeddedPostgresTestDatabase,
|
|
} from "./helpers/embedded-postgres.js";
|
|
import { errorHandler } from "../middleware/index.js";
|
|
import { projectRoutes } from "../routes/projects.js";
|
|
|
|
const embeddedPostgresSupport = await getEmbeddedPostgresTestSupport();
|
|
const describeEmbeddedPostgres = embeddedPostgresSupport.supported ? describe : describe.skip;
|
|
|
|
if (!embeddedPostgresSupport.supported) {
|
|
console.warn(
|
|
`Skipping embedded Postgres project list archived tests on this host: ${
|
|
embeddedPostgresSupport.reason ?? "unsupported environment"
|
|
}`,
|
|
);
|
|
}
|
|
|
|
function boardActor(companyId: string): Express.Request["actor"] {
|
|
return {
|
|
type: "board",
|
|
userId: "user-1",
|
|
source: "session",
|
|
isInstanceAdmin: true,
|
|
companyIds: [companyId],
|
|
memberships: [{ companyId, membershipRole: "admin", status: "active" }],
|
|
};
|
|
}
|
|
|
|
function createApp(db: ReturnType<typeof createDb>, actor: Express.Request["actor"]) {
|
|
const app = express();
|
|
app.use(express.json());
|
|
app.use((req, _res, next) => {
|
|
req.actor = actor;
|
|
next();
|
|
});
|
|
app.use("/api", projectRoutes(db));
|
|
app.use(errorHandler);
|
|
return app;
|
|
}
|
|
|
|
describeEmbeddedPostgres("project list archived route defaults", () => {
|
|
let db!: ReturnType<typeof createDb>;
|
|
let tempDb: Awaited<ReturnType<typeof startEmbeddedPostgresTestDatabase>> | null = null;
|
|
|
|
beforeAll(async () => {
|
|
tempDb = await startEmbeddedPostgresTestDatabase("paperclip-projects-list-archived-");
|
|
db = createDb(tempDb.connectionString);
|
|
}, 20_000);
|
|
|
|
afterEach(async () => {
|
|
await db.delete(projects);
|
|
await db.delete(companies);
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await tempDb?.cleanup();
|
|
});
|
|
|
|
async function seed() {
|
|
const companyId = randomUUID();
|
|
const activeProjectId = randomUUID();
|
|
const archivedProjectId = randomUUID();
|
|
|
|
await db.insert(companies).values({
|
|
id: companyId,
|
|
name: "Paperclip",
|
|
issuePrefix: `T${companyId.replace(/-/g, "").slice(0, 6).toUpperCase()}`,
|
|
requireBoardApprovalForNewAgents: false,
|
|
});
|
|
await db.insert(projects).values([
|
|
{ id: activeProjectId, companyId, name: "Active Project", status: "in_progress" },
|
|
{
|
|
id: archivedProjectId,
|
|
companyId,
|
|
name: "Archived Project",
|
|
status: "completed",
|
|
archivedAt: new Date(),
|
|
},
|
|
]);
|
|
|
|
return { activeProjectId, archivedProjectId, companyId };
|
|
}
|
|
|
|
it("omits archived projects by default", async () => {
|
|
const { activeProjectId, archivedProjectId, companyId } = await seed();
|
|
const app = createApp(db, boardActor(companyId));
|
|
|
|
const res = await request(app).get(`/api/companies/${companyId}/projects`);
|
|
|
|
expect(res.status).toBe(200);
|
|
expect(res.body.map((project: { id: string }) => project.id)).toEqual([activeProjectId]);
|
|
expect(res.body.map((project: { id: string }) => project.id)).not.toContain(archivedProjectId);
|
|
});
|
|
|
|
it("includes archived projects when includeArchived is true", async () => {
|
|
const { activeProjectId, archivedProjectId, companyId } = await seed();
|
|
const app = createApp(db, boardActor(companyId));
|
|
|
|
const res = await request(app).get(`/api/companies/${companyId}/projects?includeArchived=true`);
|
|
|
|
expect(res.status).toBe(200);
|
|
expect(res.body.map((project: { id: string }) => project.id)).toEqual([activeProjectId, archivedProjectId]);
|
|
});
|
|
});
|