import { Database } from "bun:sqlite"; import { afterEach, beforeEach, describe, expect, test } from "bun:test"; import { eq } from "drizzle-orm"; import { drizzle } from "drizzle-orm/bun-sqlite"; import { migrate } from "drizzle-orm/bun-sqlite/migrator"; import { MIGRATIONS_FOLDER } from "../db/fixtures"; import { githubRepositories, liveActivitySessions, projectRoots, projects, } from "../db/schema"; import { mergeProjects } from "./billing"; import type { CapabilityContext } from "./context"; let sqlite: Database; let db: CapabilityContext["db"]; beforeEach(() => { sqlite = new Database(":memory:"); db = drizzle({ client: sqlite }); migrate(db, { migrationsFolder: MIGRATIONS_FOLDER }); }); afterEach(() => { sqlite.close(); }); function context(): CapabilityContext { return { db, userId: "user-1", organizationId: "org-1", deviceIds: [], }; } describe("mergeProjects", () => { test("re-points source project relationships before deleting the source", async () => { await db.insert(projects).values([ { id: "project-target", name: "Target", organizationId: "org-1" }, { id: "project-source", name: "Source", organizationId: "org-1" }, ]); await db.insert(projectRoots).values({ id: "root-source", projectId: "project-source", path: "/work/source", }); await db.insert(githubRepositories).values({ id: "repository-source", organizationId: "org-1", projectId: "project-source", githubRepoId: 123, owner: "owner", name: "source", fullName: "owner/source", }); await db.insert(liveActivitySessions).values({ id: "session-source", providerId: "claude", externalThreadId: "thread-source", projectId: "project-source", lastActivityAt: new Date("2026-07-01T12:00:00Z"), }); const result = await mergeProjects.execute(context(), { targetProjectId: "project-target", sourceProjectIds: ["project-source"], }); expect(result).toMatchObject({ success: true, targetProjectId: "project-target", merged: 1, }); const [repository] = await db .select({ projectId: githubRepositories.projectId }) .from(githubRepositories) .where(eq(githubRepositories.id, "repository-source")); expect(repository?.projectId).toBe("project-target"); const [root] = await db .select({ projectId: projectRoots.projectId }) .from(projectRoots) .where(eq(projectRoots.id, "root-source")); expect(root?.projectId).toBe("project-target"); const [session] = await db .select({ projectId: liveActivitySessions.projectId }) .from(liveActivitySessions) .where(eq(liveActivitySessions.id, "session-source")); expect(session?.projectId).toBe("project-target"); const sourceProjects = await db .select({ id: projects.id }) .from(projects) .where(eq(projects.id, "project-source")); expect(sourceProjects).toHaveLength(0); }); });