Adapt the server integration test to the new standalone OAuth endpoints that store secrets without creating a source. Add workspace execution environment tests for GraphQL tool loading and invocation. Update auth service and control-plane runtime tests for the refactored APIs.
Showing the changes to apps (1 of 5 files). Show all
Unified · Split
| @@ -802,7 +802,7 @@ describe("local-executor-server", () => { · 801 unmodified lines | ||
| 802 | 802 | }), |
| 803 | 803 | ); |
| 804 | 804 | |
| 805 | − it.scoped("starts MCP OAuth from the sources API and completes the popup callback flow", () => | |
| 805 | + it.scoped("starts source OAuth without creating a source and stores secrets on callback", () => | |
| 806 | 806 | Effect.gen(function* () { |
| 807 | 807 | const oauthServer = yield* Effect.acquireRelease( |
| 808 | 808 | Effect.promise(() => startOAuthProtectedMcpServer()), |
| @@ -820,16 +820,15 @@ describe("local-executor-server", () => { · 11 unmodified lines | ||
| 820 | 820 | const installation = yield* bootstrapClient.local.installation({}); |
| 821 | 821 | |
| 822 | 822 | const startResponse = yield* Effect.promise(() => |
| 823 | − fetch(`${server.baseUrl}/v1/workspaces/${encodeURIComponent(installation.workspaceId)}/sources/mcp/oauth/start`, { | |
| 823 | + fetch(`${server.baseUrl}/v1/workspaces/${encodeURIComponent(installation.workspaceId)}/oauth/source-auth/start`, { | |
| 824 | 824 | method: "POST", |
| 825 | 825 | headers: { |
| 826 | 826 | "content-type": "application/json", |
| 827 | 827 | "x-executor-account-id": installation.accountId, |
| 828 | 828 | }, |
| 829 | 829 | body: JSON.stringify({ |
| 830 | + provider: "mcp", | |
| 830 | 831 | endpoint: oauthServer.endpoint, |
| 831 | − name: "Axiom", | |
| 832 | − namespace: "axiom", | |
| 833 | 832 | transport: "auto", |
| 834 | 833 | }), |
| 835 | 834 | }), |
| @@ -837,29 +836,26 @@ describe("local-executor-server", () => { · 1 unmodified line | ||
| 837 | 836 | |
| 838 | 837 | assertTrue(startResponse.ok); |
| 839 | 838 | const started: { |
| 840 | − kind: "connected" | "oauth_required"; | |
| 841 | − source: { id: string; status: string; auth: { kind: string } }; | |
| 842 | − authorizationUrl?: string; | |
| 839 | + sessionId: string; | |
| 840 | + authorizationUrl: string; | |
| 843 | 841 | } = yield* Effect.promise(() => startResponse.json() as Promise<{ |
| 844 | − kind: "connected" | "oauth_required"; | |
| 845 | − source: { id: string; status: string; auth: { kind: string } }; | |
| 846 | − authorizationUrl?: string; | |
| 842 | + sessionId: string; | |
| 843 | + authorizationUrl: string; | |
| 847 | 844 | }>); |
| 848 | 845 | |
| 849 | − expect(started.kind).toBe("oauth_required"); | |
| 850 | − expect(started.source.status).toBe("auth_required"); | |
| 846 | + expect(started.sessionId).toBeTruthy(); | |
| 851 | 847 | expect(started.authorizationUrl).toBeDefined(); |
| 852 | 848 | |
| 853 | 849 | const callbackResponse = yield* Effect.promise(() => |
| 854 | − fetch(started.authorizationUrl!, { | |
| 850 | + fetch(started.authorizationUrl, { | |
| 855 | 851 | redirect: "follow", |
| 856 | 852 | }), |
| 857 | 853 | ); |
| 858 | 854 | |
| 859 | 855 | assertTrue(callbackResponse.ok); |
| 860 | 856 | const callbackHtml = yield* Effect.promise(() => callbackResponse.text()); |
| 861 | − expect(callbackHtml).toContain("Source connected:"); | |
| 862 | − expect(callbackHtml).toContain("executor-v3:source-oauth-result"); | |
| 857 | + expect(callbackHtml).toContain("OAuth connected"); | |
| 858 | + expect(callbackHtml).toContain("executor-v3:oauth-result"); | |
| 863 | 859 | |
| 864 | 860 | const client = yield* createControlPlaneClient({ |
| 865 | 861 | baseUrl: server.baseUrl, |
| @@ -870,12 +866,12 @@ describe("local-executor-server", () => { · 4 unmodified lines | ||
| 870 | 866 | workspaceId: installation.workspaceId, |
| 871 | 867 | }, |
| 872 | 868 | }); |
| 873 | − const source = sources.find((candidate) => candidate.id === started.source.id); | |
| 874 | 869 | |
| 875 | − assertTrue(Boolean(source)); | |
| 870 | + expect(sources).toHaveLength(0); | |
| 876 | 871 | |
| 877 | − expect(source?.status).toBe("connected"); | |
| 878 | − expect(source?.auth.kind).toBe("oauth2"); | |
| 872 | + const secrets = yield* bootstrapClient.local.listSecrets({}); | |
| 873 | + expect(secrets.some((secret) => secret.purpose === "oauth_access_token")).toBe(true); | |
| 874 | + expect(secrets.some((secret) => secret.purpose === "oauth_refresh_token")).toBe(true); | |
| 879 | 875 | }), |
| 880 | 876 | ); |
| 881 | 877 | |