import { convexTest } from "convex-test"; import { anyApi } from "convex/server"; import { describe, expect, test } from "vitest"; import schema from "./schema"; declare global { interface ImportMeta { readonly glob: (pattern: string) => Record Promise>; } } const modules = import.meta.glob("./**/*.ts"); const api = anyApi; const identity = { tokenIdentifier: "https://convex.test|exec-user" }; describe("Work execution without simulation", () => { test("rejects execution when Work is not ready", async () => { const t = convexTest({ modules, schema }); await t.withIdentity(identity).run(async (ctx) => { const organizationId = await ctx.db.insert("organizations", { createdAt: 1, createdBy: identity.tokenIdentifier, kind: "personal", name: "Personal", }); await ctx.db.insert("organizationMembers", { createdAt: 1, organizationId, role: "owner", userId: identity.tokenIdentifier, }); const projectId = await ctx.db.insert("projects", { createdAt: 2, name: "Project", normalizedSourceUrl: "https://git.example.com/test/repo", organizationId, repositoryPath: "test/repo", sourceHost: "gitea", sourceUrl: "https://git.example.com/test/repo.git", updatedAt: 2, }); const workId = await ctx.db.insert("works", { createdAt: 3, objective: "Test", organizationId, projectId, status: "proposed", title: "Proposed Work", updatedAt: 3, }); await expect( t.withIdentity(identity).mutation(api.workExecution.start, { workId }) ).rejects.toThrow(/Ready/u); }); }); test("rejects execution without Definition or Design", async () => { const t = convexTest({ modules, schema }); await t.withIdentity(identity).run(async (ctx) => { const organizationId = await ctx.db.insert("organizations", { createdAt: 1, createdBy: identity.tokenIdentifier, kind: "personal", name: "Personal", }); await ctx.db.insert("organizationMembers", { createdAt: 1, organizationId, role: "owner", userId: identity.tokenIdentifier, }); const projectId = await ctx.db.insert("projects", { createdAt: 2, name: "Project", normalizedSourceUrl: "https://git.example.com/test/repo", organizationId, repositoryPath: "test/repo", sourceHost: "gitea", sourceUrl: "https://git.example.com/test/repo.git", updatedAt: 2, }); const workId = await ctx.db.insert("works", { createdAt: 3, objective: "Test", organizationId, projectId, status: "ready", title: "Ready but unplanned", updatedAt: 3, }); await expect( t.withIdentity(identity).mutation(api.workExecution.start, { workId }) ).rejects.toThrow(/Definition and Design/u); }); }); test("rejects invalid service token", async () => { const t = convexTest({ modules, schema }); await t.withIdentity(identity).run(async (ctx) => { const organizationId = await ctx.db.insert("organizations", { createdAt: 1, createdBy: identity.tokenIdentifier, kind: "personal", name: "Personal", }); await ctx.db.insert("organizationMembers", { createdAt: 1, organizationId, role: "owner", userId: identity.tokenIdentifier, }); const projectId = await ctx.db.insert("projects", { createdAt: 2, name: "Project", normalizedSourceUrl: "https://git.example.com/test/repo", organizationId, repositoryPath: "test/repo", sourceHost: "gitea", sourceUrl: "https://git.example.com/test/repo.git", updatedAt: 2, }); const workId = await ctx.db.insert("works", { createdAt: 3, definitionVersion: 1, designVersion: 1, objective: "Test", organizationId, projectId, status: "ready", title: "Ready Work", updatedAt: 3, }); await expect( t.mutation(api.workExecution.start, { organizationId, token: "wrong-token", workId, }) ).rejects.toThrow(/agent control token/u); }); }); });