tests/e2e/flows-api-list.spec.ts
Rama main · réplica de lectura del repositorio original.
import { expect, test } from "@playwright/test";
import {
user1Headers,
seedState,
resetState,
getTestState,
} from "./helpers/flows-api-fixtures";
test.beforeEach(async ({ request }) => {
await resetState(request);
});
test("GET /api/flows returns owned flows with published versions and summaries", async ({
request,
}) => {
await seedState(request, {
installations: [
{
id: "inst-1",
user_id: "user-1",
installation_id: 101,
account_login: "acme",
},
{
id: "inst-2",
user_id: "user-2",
installation_id: 202,
account_login: "other",
},
],
flows: [
{
id: "flow-1",
user_id: "user-1",
installation_id: 101,
name: "Review Flow",
description: "Primary flow",
notes: "hello",
source_kind: "github",
status: "active",
draft_graph: {
nodes: [
{
id: "start",
type: "start",
position: { x: 0, y: 0 },
data: { label: "PR opened", event: "pr_opened" },
},
{
id: "agent-1",
type: "agent",
position: { x: 100, y: 0 },
data: { label: "Reviewer", agentId: "agent-1" },
},
{
id: "end",
type: "end",
position: { x: 200, y: 0 },
data: { label: "Done" },
},
],
edges: [
{ id: "e1", source: "start", target: "agent-1" },
{ id: "e2", source: "agent-1", target: "end" },
],
viewport: { x: 0, y: 0, zoom: 1 },
},
published_version_id: "version-1",
created_at: "2026-03-28T10:00:00.000Z",
updated_at: "2026-03-28T10:05:00.000Z",
},
{
id: "flow-2",
user_id: "user-2",
installation_id: 202,
name: "Hidden Flow",
description: null,
notes: null,
source_kind: "github",
status: "inactive",
draft_graph: {
nodes: [],
edges: [],
viewport: { x: 0, y: 0, zoom: 1 },
},
published_version_id: null,
created_at: "2026-03-28T09:00:00.000Z",
updated_at: "2026-03-28T09:00:00.000Z",
},
],
flowVersions: [
{
id: "version-1",
flow_id: "flow-1",
version_number: 2,
graph: {
nodes: [
{
id: "start",
type: "start",
position: { x: 0, y: 0 },
data: { label: "PR opened", event: "pr_opened" },
},
{
id: "agent-1",
type: "agent",
position: { x: 100, y: 0 },
data: { label: "Reviewer", agentId: "agent-1" },
},
{
id: "end",
type: "end",
position: { x: 200, y: 0 },
data: { label: "Done" },
},
],
edges: [
{ id: "e1", source: "start", target: "agent-1" },
{ id: "e2", source: "agent-1", target: "end" },
],
viewport: { x: 0, y: 0, zoom: 1 },
},
created_at: "2026-03-28T10:01:00.000Z",
},
],
jobRuns: [
{
id: "job-1",
flow_id: "flow-1",
status: "failed",
error: "lint failed",
started_at: "2026-03-28T11:00:00.000Z",
created_at: "2026-03-28T10:59:00.000Z",
last_start_attempt_at: "2026-03-28T10:59:00.000Z",
},
],
dispatchEvents: [
{
id: "event-1",
job_run_id: null,
trigger_id: null,
flow_id: "flow-1",
outcome: "deferred",
reason: "REPO_CONCURRENCY_LIMIT",
created_at: "2026-03-28T11:10:00.000Z",
},
],
});
const response = await request.get("/api/flows", { headers: user1Headers });
expect(response.ok()).toBeTruthy();
const payload = await response.json();
expect(payload).toHaveLength(1);
expect(payload[0].id).toBe("flow-1");
expect(payload[0].published_version.version_number).toBe(2);
expect(payload[0].last_run_status).toBe("failed");
expect(payload[0].last_pressure_reason).toBe("REPO_CONCURRENCY_LIMIT");
});
test("GET /api/flows repairs active unpublished flows by relinking the latest published version", async ({
request,
}) => {
await seedState(request, {
installations: [
{
id: "inst-1",
user_id: "user-1",
installation_id: 101,
account_login: "acme",
},
],
flows: [
{
id: "flow-1",
user_id: "user-1",
installation_id: 101,
name: "Repair Me",
description: null,
notes: null,
source_kind: "github",
status: "active",
draft_graph: {
nodes: [
{
id: "start",
type: "start",
position: { x: 0, y: 0 },
data: { label: "PR opened", event: "pr_opened" },
},
{
id: "agent-1",
type: "agent",
position: { x: 100, y: 0 },
data: { label: "Reviewer", agentId: "agent-1" },
},
{
id: "end",
type: "end",
position: { x: 200, y: 0 },
data: { label: "Done" },
},
],
edges: [
{ id: "e1", source: "start", target: "agent-1" },
{ id: "e2", source: "agent-1", target: "end" },
],
viewport: { x: 0, y: 0, zoom: 1 },
},
published_version_id: null,
created_at: "2026-03-28T10:00:00.000Z",
updated_at: "2026-03-28T10:05:00.000Z",
},
],
flowVersions: [
{
id: "version-1",
flow_id: "flow-1",
version_number: 1,
graph: {
nodes: [
{
id: "start",
type: "start",
position: { x: 0, y: 0 },
data: { label: "PR opened", event: "pr_opened" },
},
{
id: "agent-1",
type: "agent",
position: { x: 100, y: 0 },
data: { label: "Reviewer", agentId: "agent-1" },
},
{
id: "end",
type: "end",
position: { x: 200, y: 0 },
data: { label: "Done" },
},
],
edges: [
{ id: "e1", source: "start", target: "agent-1" },
{ id: "e2", source: "agent-1", target: "end" },
],
viewport: { x: 0, y: 0, zoom: 1 },
},
created_at: "2026-03-28T10:01:00.000Z",
},
],
});
const response = await request.get("/api/flows", { headers: user1Headers });
expect(response.ok()).toBeTruthy();
const payload = await response.json();
expect(payload[0].published_version_id).toBe("version-1");
expect(payload[0].status).toBe("active");
const state = await getTestState(request);
expect(state.flows[0].published_version_id).toBe("version-1");
});