165 lines · 5.6 KB · TypeScript
RawDownload
import { describe, expect, it } from "@effect/vitest"; import { migrateMcpAuthConfig } from "./migrate-config";import { parseMcpIntegrationConfig } from "./types"; // ---------------------------------------------------------------------------// The one-off config migration rewrites every pre-canonical MCP blob family// into the canonical placements model. Two invariants are load-bearing:// slugs are preserved verbatim (connections bind by `connection.template`)// and variable names are preserved verbatim (they key stored `item_ids`).// --------------------------------------------------------------------------- const REMOTE = { transport: "remote", endpoint: "https://x.example/mcp" } as const; describe("migrateMcpAuthConfig", () => {  it("lifts a singular `auth: {kind:'header'}` into a one-method template, slug = kind", () => {    const migrated = migrateMcpAuthConfig({      ...REMOTE,      auth: { kind: "header", headerName: "Authorization", prefix: "Bearer " },    });    expect(migrated).toEqual({      ...REMOTE,      authenticationTemplate: [        {          slug: "header",          kind: "apikey",          placements: [{ carrier: "header", name: "Authorization", prefix: "Bearer " }],        },      ],    });    expect(parseMcpIntegrationConfig(migrated)).not.toBeNull();  });   it("lifts a singular `auth: {kind:'oauth2'}` (the v1→v2 migration's output)", () => {    expect(migrateMcpAuthConfig({ ...REMOTE, auth: { kind: "oauth2" } })).toEqual({      ...REMOTE,      authenticationTemplate: [{ slug: "oauth2", kind: "oauth2" }],    });  });   it("treats a remote config with no auth field as an open server", () => {    expect(migrateMcpAuthConfig({ ...REMOTE })).toEqual({      ...REMOTE,      authenticationTemplate: [{ slug: "none", kind: "none" }],    });  });   it("rewrites retired single-placement `header` / `query` methods, slugs preserved", () => {    const migrated = migrateMcpAuthConfig({      ...REMOTE,      authenticationTemplate: [        { slug: "header", kind: "header", headerName: "X-Api-Key", prefix: "Bearer " },        { slug: "custom_q1", kind: "query", paramName: "token" },        { slug: "none", kind: "none" },      ],    });    expect(migrated).toEqual({      ...REMOTE,      authenticationTemplate: [        {          slug: "header",          kind: "apikey",          placements: [{ carrier: "header", name: "X-Api-Key", prefix: "Bearer " }],        },        {          slug: "custom_q1",          kind: "apikey",          placements: [{ carrier: "query", name: "token" }],        },        { slug: "none", kind: "none" },      ],    });  });   it("rewrites openapi-shaped entries the v1→v2 migration wrote, variables preserved", () => {    // Exactly what `migrateOpenApiAuthTemplate` emits for a two-input source.    const migrated = migrateMcpAuthConfig({      ...REMOTE,      authenticationTemplate: [        {          slug: "apiKey",          type: "apiKey",          headers: {            "DD-API-KEY": [{ type: "variable", name: "dd_api_key" }],            Authorization: ["Bearer ", { type: "variable", name: "dd_application_key" }],          },          queryParams: { team: [{ type: "variable", name: "team" }] },        },      ],    });    expect(migrated).toEqual({      ...REMOTE,      authenticationTemplate: [        {          slug: "apiKey",          kind: "apikey",          placements: [            { carrier: "header", name: "DD-API-KEY", variable: "dd_api_key" },            {              carrier: "header",              name: "Authorization",              prefix: "Bearer ",              variable: "dd_application_key",            },            { carrier: "query", name: "team", variable: "team" },          ],        },      ],    });  });   it("stores the canonical `token` variable as absent and literal-only values as literals", () => {    const migrated = migrateMcpAuthConfig({      ...REMOTE,      authenticationTemplate: [        {          slug: "apiKey",          type: "apiKey",          headers: {            Authorization: ["Bearer ", { type: "variable", name: "token" }],            "X-Api-Version": "2023-01-01",          },        },      ],    }) as { authenticationTemplate: readonly unknown[] };    expect(migrated.authenticationTemplate[0]).toEqual({      slug: "apiKey",      kind: "apikey",      placements: [        { carrier: "header", name: "Authorization", prefix: "Bearer " },        { carrier: "header", name: "X-Api-Version", literal: "2023-01-01" },      ],    });  });   it("is idempotent — a canonical config returns null (no rewrite)", () => {    const canonical = {      ...REMOTE,      authenticationTemplate: [        { slug: "oauth2", kind: "oauth2" },        {          slug: "header",          kind: "apikey",          placements: [{ carrier: "header", name: "Authorization", prefix: "Bearer " }],        },      ],    };    expect(migrateMcpAuthConfig(canonical)).toBeNull();    // And the lifted output of every family is itself canonical.    const lifted = migrateMcpAuthConfig({ ...REMOTE, auth: { kind: "oauth2" } });    expect(migrateMcpAuthConfig(lifted)).toBeNull();  });   it("leaves stdio, foreign, and unmigratable blobs untouched", () => {    expect(migrateMcpAuthConfig({ transport: "stdio", command: "run" })).toBeNull();    expect(migrateMcpAuthConfig({ not: "mcp" })).toBeNull();    expect(migrateMcpAuthConfig(null)).toBeNull();    expect(      migrateMcpAuthConfig({        ...REMOTE,        authenticationTemplate: [{ slug: "x", kind: "mystery" }],      }),    ).toBeNull();  });});