TEST - CODEX AGENTS: real Tasker e2e smoke harness
This commit is contained in:
parent
9f402074f2
commit
418914fefd
|
|
@ -12,6 +12,7 @@
|
|||
"check": "tsc --noEmit -p tsconfig.json",
|
||||
"migrate": "tsx src/scripts/migrate.ts",
|
||||
"migrate:dist": "node dist/scripts/migrate.js",
|
||||
"smoke:e2e": "tsx src/scripts/smoke-e2e.ts",
|
||||
"smoke:gateway": "tsx src/scripts/smoke-gateway.ts",
|
||||
"start": "node dist/server.js"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,182 @@
|
|||
import { Pool } from "pg";
|
||||
|
||||
import { buildApp } from "../app.js";
|
||||
import { loadConfig } from "../config.js";
|
||||
import { runMigrations } from "../db/migrations.js";
|
||||
|
||||
const config = loadConfig();
|
||||
const workspaceSlug = readRequiredEnv("SMOKE_WORKSPACE_SLUG");
|
||||
const projectId = readRequiredEnv("SMOKE_PROJECT_ID");
|
||||
|
||||
if (!config.DATABASE_URL) {
|
||||
throw new Error("DATABASE_URL is required for e2e smoke test.");
|
||||
}
|
||||
|
||||
if (!config.NODEDC_INTERNAL_ACCESS_TOKEN) {
|
||||
throw new Error("NODEDC_INTERNAL_ACCESS_TOKEN is required for e2e smoke test.");
|
||||
}
|
||||
|
||||
const migrationPool = new Pool({ connectionString: config.DATABASE_URL });
|
||||
await runMigrations(migrationPool);
|
||||
await migrationPool.end();
|
||||
|
||||
const app = await buildApp({
|
||||
...config,
|
||||
LOG_LEVEL: process.env.LOG_LEVEL === "debug" ? "debug" : "silent",
|
||||
});
|
||||
|
||||
try {
|
||||
const suffix = Date.now().toString(36);
|
||||
const agentId = await createAgent(suffix);
|
||||
await upsertGrant(agentId);
|
||||
const token = await createToken(agentId);
|
||||
const authHeaders = { Authorization: `Bearer ${token}` };
|
||||
|
||||
const projects = await requestJson("GET", "/api/v1/tools/projects", authHeaders);
|
||||
const context = await requestJson(
|
||||
"GET",
|
||||
`/api/v1/tools/projects/${projectId}/context?workspace_slug=${encodeURIComponent(workspaceSlug)}`,
|
||||
authHeaders
|
||||
);
|
||||
const issue = await requestJson("POST", "/api/v1/tools/issues", authHeaders, {
|
||||
project_id: projectId,
|
||||
workspace_slug: workspaceSlug,
|
||||
title: `NODE.DC Codex API smoke ${suffix}`,
|
||||
description: "Created by Agent Gateway e2e smoke test.",
|
||||
priority: "medium",
|
||||
structured_blocks: [
|
||||
{
|
||||
id: "current-architecture",
|
||||
type: "text",
|
||||
title: "Текущая архитектура",
|
||||
body: "Gateway создал карточку через реальный Tasker internal adapter.",
|
||||
},
|
||||
{
|
||||
id: "checker-1",
|
||||
type: "checker",
|
||||
title: "Чекер smoke",
|
||||
items: [
|
||||
{
|
||||
id: "auth",
|
||||
text: "Agent token accepted",
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
id: "tasker",
|
||||
text: "Tasker adapter created issue",
|
||||
checked: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const issueId = issue.issue.id as string;
|
||||
await requestJson("POST", `/api/v1/tools/issues/${issueId}/comments`, authHeaders, {
|
||||
project_id: projectId,
|
||||
workspace_slug: workspaceSlug,
|
||||
body: "Smoke comment from Agent Gateway.",
|
||||
});
|
||||
|
||||
const states = Array.isArray(context.states) ? context.states : [];
|
||||
const targetState = states.find((state) => typeof state?.id === "string");
|
||||
if (targetState) {
|
||||
await requestJson("POST", `/api/v1/tools/issues/${issueId}/move`, authHeaders, {
|
||||
project_id: projectId,
|
||||
workspace_slug: workspaceSlug,
|
||||
state_id: targetState.id,
|
||||
});
|
||||
}
|
||||
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
ok: true,
|
||||
tasker_url: config.NODEDC_TASKER_INTERNAL_URL,
|
||||
workspace_slug: workspaceSlug,
|
||||
project_id: projectId,
|
||||
visible_projects: Array.isArray(projects.projects) ? projects.projects.length : null,
|
||||
issue_id: issueId,
|
||||
moved: Boolean(targetState),
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
} finally {
|
||||
await app.close();
|
||||
}
|
||||
|
||||
async function createAgent(suffix: string): Promise<string> {
|
||||
const payload = await requestJson("POST", "/api/v1/agents", undefined, {
|
||||
owner_user_id: `e2e-owner-${suffix}`,
|
||||
owner_email: `e2e-${suffix}@example.test`,
|
||||
display_name: `E2E Codex ${suffix}`,
|
||||
});
|
||||
|
||||
return payload.agent.id as string;
|
||||
}
|
||||
|
||||
async function upsertGrant(agentId: string): Promise<void> {
|
||||
await requestJson("POST", `/api/v1/agents/${agentId}/grants`, undefined, {
|
||||
workspace_slug: workspaceSlug,
|
||||
project_id: projectId,
|
||||
scopes: [
|
||||
"workspace:read",
|
||||
"project:read",
|
||||
"issue:read",
|
||||
"issue:create",
|
||||
"issue:update",
|
||||
"issue:move",
|
||||
"issue:comment",
|
||||
"issue:label",
|
||||
"issue:assign",
|
||||
"issue:structured_blocks:write",
|
||||
],
|
||||
mode: "voluntary",
|
||||
created_by_user_id: "e2e-smoke-admin",
|
||||
});
|
||||
}
|
||||
|
||||
async function createToken(agentId: string): Promise<string> {
|
||||
const payload = await requestJson("POST", `/api/v1/agents/${agentId}/tokens`, undefined, {
|
||||
name: "E2E smoke token",
|
||||
});
|
||||
|
||||
return payload.token as string;
|
||||
}
|
||||
|
||||
async function requestJson(
|
||||
method: "GET" | "POST",
|
||||
url: string,
|
||||
headers?: Record<string, string>,
|
||||
payload?: unknown
|
||||
): Promise<Record<string, any>> {
|
||||
const injectOptions: any = {
|
||||
method,
|
||||
url,
|
||||
headers,
|
||||
};
|
||||
|
||||
if (payload !== undefined) {
|
||||
injectOptions.payload = payload;
|
||||
}
|
||||
|
||||
const response = await app.inject(injectOptions);
|
||||
|
||||
const body = response.body ? JSON.parse(response.body) : {};
|
||||
|
||||
if (response.statusCode < 200 || response.statusCode >= 300) {
|
||||
throw new Error(`HTTP ${response.statusCode} for ${method} ${url}: ${JSON.stringify(body)}`);
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
function readRequiredEnv(key: string): string {
|
||||
const value = process.env[key]?.trim();
|
||||
if (!value) {
|
||||
throw new Error(`${key} is required for e2e smoke test.`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
Loading…
Reference in New Issue