import { assertEquals } from "@std/assert"; import { executeOperations } from "./executor.ts"; import type { Operation } from "./operations.ts"; import type { ActualState } from "../state/actual.ts"; function emptyActual(): ActualState { return { groups: [], groupsByName: new Map(), groupsById: new Map(), setupKeys: [], setupKeysByName: new Map(), peers: [], peersByName: new Map(), peersById: new Map(), policies: [], policiesByName: new Map(), routes: [], routesByNetworkId: new Map(), dns: [], dnsByName: new Map(), }; } Deno.test("executor calls createGroup for create_group op", async () => { const calls: string[] = []; const mockClient = { createGroup: (data: { name: string }) => { calls.push(`createGroup:${data.name}`); return Promise.resolve({ id: "new-g1", name: data.name, peers_count: 0, peers: [], issued: "api" as const, }); }, }; const ops: Operation[] = [ { type: "create_group", name: "pilots" }, ]; const { results } = await executeOperations( ops, mockClient as never, emptyActual(), ); assertEquals(calls, ["createGroup:pilots"]); assertEquals(results[0].status, "success"); }); Deno.test("executor aborts on first failure", async () => { const mockClient = { createGroup: () => Promise.reject(new Error("API down")), createSetupKey: () => Promise.resolve({ id: 1, key: "k", name: "key1" }), }; const ops: Operation[] = [ { type: "create_group", name: "pilots" }, { type: "create_setup_key", name: "key1" }, ]; const { results } = await executeOperations( ops, mockClient as never, emptyActual(), ); assertEquals(results[0].status, "failed"); assertEquals(results.length, 1); // second op never executed }); Deno.test("executor tracks created group IDs for setup key auto_groups", async () => { const calls: Array<{ method: string; data: unknown }> = []; const mockClient = { createGroup: (data: { name: string }) => { calls.push({ method: "createGroup", data }); return Promise.resolve({ id: "new-g1", name: data.name, peers_count: 0, peers: [], issued: "api" as const, }); }, createSetupKey: (data: Record) => { calls.push({ method: "createSetupKey", data }); return Promise.resolve({ id: 1, name: data.name, key: "raw-key-123", type: data.type, expires: "2026-04-01T00:00:00Z", valid: true, revoked: false, used_times: 0, state: "valid" as const, auto_groups: data.auto_groups, usage_limit: data.usage_limit, }); }, }; const ops: Operation[] = [ { type: "create_group", name: "pilots" }, { type: "create_setup_key", name: "key1", details: { type: "one-off", auto_groups: ["pilots"], usage_limit: 1, expires_in: 604800, }, }, ]; const { results, createdKeys } = await executeOperations( ops, mockClient as never, emptyActual(), ); assertEquals(results.length, 2); assertEquals(results[0].status, "success"); assertEquals(results[1].status, "success"); // The setup key call should have resolved "pilots" -> "new-g1" const setupKeyCall = calls.find((c) => c.method === "createSetupKey"); assertEquals( (setupKeyCall?.data as Record).auto_groups, ["new-g1"], ); // Created keys map stores the raw key assertEquals(createdKeys.get("key1"), "raw-key-123"); }); Deno.test("executor resolves group IDs from actual state", async () => { const calls: Array<{ method: string; data: unknown }> = []; const actual = emptyActual(); actual.groupsByName.set("pilots", { id: "existing-g1", name: "pilots", peers_count: 0, peers: [], issued: "api", }); const mockClient = { createSetupKey: (data: Record) => { calls.push({ method: "createSetupKey", data }); return Promise.resolve({ id: 1, name: data.name, key: "raw-key-456", type: data.type, expires: "2026-04-01T00:00:00Z", valid: true, revoked: false, used_times: 0, state: "valid" as const, auto_groups: data.auto_groups, usage_limit: data.usage_limit, }); }, }; const ops: Operation[] = [ { type: "create_setup_key", name: "key1", details: { type: "one-off", auto_groups: ["pilots"], usage_limit: 1, expires_in: 604800, }, }, ]; const { results } = await executeOperations( ops, mockClient as never, actual, ); assertEquals(results[0].status, "success"); const setupKeyCall = calls.find((c) => c.method === "createSetupKey"); assertEquals( (setupKeyCall?.data as Record).auto_groups, ["existing-g1"], ); }); Deno.test("executor deletes group by resolving ID from actual", async () => { const calls: string[] = []; const actual = emptyActual(); actual.groupsByName.set("stale-group", { id: "g-old", name: "stale-group", peers_count: 0, peers: [], issued: "api", }); const mockClient = { deleteGroup: (id: string) => { calls.push(`deleteGroup:${id}`); return Promise.resolve(); }, }; const ops: Operation[] = [ { type: "delete_group", name: "stale-group" }, ]; const { results } = await executeOperations( ops, mockClient as never, actual, ); assertEquals(calls, ["deleteGroup:g-old"]); assertEquals(results[0].status, "success"); }); Deno.test("executor stores error message on failure", async () => { const mockClient = { createGroup: () => Promise.reject(new Error("rate limited")), }; const ops: Operation[] = [ { type: "create_group", name: "pilots" }, ]; const { results } = await executeOperations( ops, mockClient as never, emptyActual(), ); assertEquals(results[0].status, "failed"); assertEquals(results[0].error, "rate limited"); });