131 lines · 4.9 KB · TypeScript
RawDownload
import { expect, layer } from "@effect/vitest";import { Effect, Layer } from "effect"; import { SecretId } from "./ids";import { SetSecretInput } from "./secrets";import {  makeTestWorkspaceLayer,  memorySecretsPlugin,  OAuthTestServer,  TestWorkspace,} from "./testing"; const plugins = [memorySecretsPlugin()] as const; const TestLayer = Layer.mergeAll(makeTestWorkspaceLayer({ plugins }), OAuthTestServer.layer()); layer(TestLayer, { timeout: "15 seconds" })("testing fixtures", (it) => {  it.effect("TestWorkspace exposes the real executor with an explicit scope stack", () =>    Effect.gen(function* () {      const workspace = yield* TestWorkspace.current<typeof plugins>();       expect(workspace.scopes.map((scope) => String(scope.id))).toEqual(["test-scope"]);      expect(workspace.executor.scopes.map((scope) => String(scope.id))).toEqual(["test-scope"]);      expect(yield* workspace.executor.secrets.providers()).toEqual(["memory"]);    }),  );   it.effect("OAuthTestServer completes a real authorization-code OAuth flow", () =>    Effect.gen(function* () {      const workspace = yield* TestWorkspace.current<typeof plugins>();      const oauth = yield* OAuthTestServer;      const scope = workspace.scopes[0]!;       yield* workspace.executor.secrets.set(        SetSecretInput.make({          id: SecretId.make("oauth-client-id"),          scope: scope.id,          name: "OAuth Client ID",          value: "test-client",        }),      );      yield* workspace.executor.secrets.set(        SetSecretInput.make({          id: SecretId.make("oauth-client-secret"),          scope: scope.id,          name: "OAuth Client Secret",          value: "test-secret",        }),      );       const started = yield* workspace.executor.oauth.start({        endpoint: oauth.resourceUrl,        connectionId: "test-oauth-authorization-code",        tokenScope: String(scope.id),        redirectUrl: "http://127.0.0.1/callback",        pluginId: "test",        identityLabel: "OAuth Test",        strategy: {          kind: "authorization-code",          authorizationEndpoint: oauth.authorizationEndpoint,          tokenEndpoint: oauth.tokenEndpoint,          clientIdSecretId: "oauth-client-id",          clientSecretSecretId: "oauth-client-secret",          scopes: ["read"],        },      });       expect(started.authorizationUrl).not.toBeNull();      const authorizationUrl = started.authorizationUrl ?? "";      const callback = yield* oauth.completeAuthorizationCodeFlow({ authorizationUrl });      const completed = yield* workspace.executor.oauth.complete({        state: callback.state,        code: callback.code,        tokenScope: String(scope.id),      });       expect(completed.connectionId).toBe("test-oauth-authorization-code");      const accessToken = yield* workspace.executor.connections.accessToken(completed.connectionId);      expect(yield* oauth.acceptsAccessToken(accessToken)).toBe(true);    }),  );   it.effect("OAuthTestServer supports MCP-style dynamic client registration", () =>    Effect.gen(function* () {      const workspace = yield* TestWorkspace.current<typeof plugins>();      const oauth = yield* OAuthTestServer;      const scope = workspace.scopes[0]!;       const probe = yield* workspace.executor.oauth.probe({ endpoint: oauth.mcpResourceUrl });      expect(probe.supportsDynamicRegistration).toBe(true);      expect(probe.isBearerChallengeEndpoint).toBe(true);       const started = yield* workspace.executor.oauth.start({        endpoint: oauth.mcpResourceUrl,        connectionId: "test-oauth-dynamic-dcr",        tokenScope: String(scope.id),        redirectUrl: "http://127.0.0.1/callback",        pluginId: "test",        identityLabel: "MCP OAuth Test",        strategy: { kind: "dynamic-dcr", scopes: ["read"] },      });       expect(started.authorizationUrl).not.toBeNull();      const authorizationUrl = started.authorizationUrl ?? "";      const callback = yield* oauth.completeAuthorizationCodeFlow({ authorizationUrl });      const completed = yield* workspace.executor.oauth.complete({        state: callback.state,        code: callback.code,        tokenScope: String(scope.id),      });       expect(completed.connectionId).toBe("test-oauth-dynamic-dcr");      const accessToken = yield* workspace.executor.connections.accessToken(completed.connectionId);      expect(yield* oauth.acceptsAccessToken(accessToken)).toBe(true);    }),  );   it.effect(    "OAuthTestServer can mint a bearer token through the full authorization-code flow",    () =>      Effect.gen(function* () {        const oauth = yield* OAuthTestServer;         const token = yield* oauth.completeAuthorizationCodeTokenFlow({ scopes: ["read"] });         expect(token.tokenType).toBe("Bearer");        expect(token.accessToken).toMatch(/^at_/);        expect(yield* oauth.acceptsAccessToken(token.accessToken)).toBe(true);      }),  );});