History

Merge remote-tracking branch 'origin/codex/batch10-openapi-oauth-tests' into codex/effect-lint-integration

Rhys Sullivan committed 6 months ago

Commit 86d576a2 parents a1200b1 4194ac62 files · +51 −19Browse files

Unified · Split

2 files
  1. packages/plugins/openapi/src/sdk/client-credentials-oauth.test.ts +19 −5
  2. packages/plugins/openapi/src/sdk/oauth-refresh.test.ts +32 −14
packages/plugins/openapi/src/sdk/client-credentials-oauth.test.ts+19−5
@@ -31,6 +31,13 @@ import { OAuth2Auth } from "./types"; · 30 unmodified lines
31 31
32const autoApprove: InvokeOptions = { onElicitation: "accept-all" };32const autoApprove: InvokeOptions = { onElicitation: "accept-all" };
33 33
34class OpenApiClientCredentialsTestSetupError extends Schema.TaggedErrorClass<OpenApiClientCredentialsTestSetupError>()(
35 "OpenApiClientCredentialsTestSetupError",
36 {
37 message: Schema.String,
38 },
39) {}
40
34// ---------------------------------------------------------------------------41// ---------------------------------------------------------------------------
35// Test API — single endpoint that echoes the Authorization header.42// Test API — single endpoint that echoes the Authorization header.
36// ---------------------------------------------------------------------------43// ---------------------------------------------------------------------------
@@ -147,7 +154,11 @@ layer(TestLayer)("OpenAPI client_credentials OAuth", (it) => { · 110 unmodified lines
147 const clientLayer = FetchHttpClient.layer;154 const clientLayer = FetchHttpClient.layer;
148 const server = yield* HttpServer.HttpServer;155 const server = yield* HttpServer.HttpServer;
149 const address = server.address;156 const address = server.address;
150 if (address._tag !== "TcpAddress") return yield* Effect.die("test server must bind to TCP");157 if (!("port" in address)) {
158 return yield* new OpenApiClientCredentialsTestSetupError({
159 message: "Test server must bind to TCP",
160 });
161 }
151 const baseUrl = `http://127.0.0.1:${address.port}`;162 const baseUrl = `http://127.0.0.1:${address.port}`;
152 const plugins = [163 const plugins = [
153 openApiPlugin({ httpClientLayer: clientLayer }),164 openApiPlugin({ httpClientLayer: clientLayer }),
@@ -231,12 +242,15 @@ layer(TestLayer)("OpenAPI client_credentials OAuth", (it) => { · 77 unmodified lines
231 },242 },
232 });243 });
233 244
234 if (!started.completedConnection) {245 const completedConnection = started.completedConnection;
235 throw new Error("expected completed clientCredentials connection");246 if (!completedConnection) {
247 return yield* new OpenApiClientCredentialsTestSetupError({
248 message: "Expected completed clientCredentials connection",
249 });
236 }250 }
237 const auth = new OAuth2Auth({251 const auth = new OAuth2Auth({
238 kind: "oauth2",252 kind: "oauth2",
239 connectionId: started.completedConnection.connectionId,253 connectionId: completedConnection.connectionId,
240 securitySchemeName: "oauth2",254 securitySchemeName: "oauth2",
241 flow: "clientCredentials",255 flow: "clientCredentials",
242 tokenUrl: "https://token.example.com/token",256 tokenUrl: "https://token.example.com/token",
@@ -257,7 +271,7 @@ layer(TestLayer)("OpenAPI client_credentials OAuth", (it) => { · 14 unmodified lines
257 // Add the source with OAuth2Auth pointing at the completed connection.271 // Add the source with OAuth2Auth pointing at the completed connection.
258 yield* userExec.openapi.addSpec({272 yield* userExec.openapi.addSpec({
259 spec: specJson,273 spec: specJson,
260 scope: userScope.id as string,274 scope: userScope.id,
261 namespace: "petstore",275 namespace: "petstore",
262 baseUrl,276 baseUrl,
263 oauth2: auth,277 oauth2: auth,
packages/plugins/openapi/src/sdk/oauth-refresh.test.ts+32−14
@@ -20,7 +20,6 @@ import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer"; · 19 unmodified lines
20 20
21import {21import {
22 ConnectionId,22 ConnectionId,
23 ConnectionReauthRequiredError,
24 CreateConnectionInput,23 CreateConnectionInput,
25 ScopeId,24 ScopeId,
26 SecretId,25 SecretId,
@@ -41,6 +40,13 @@ import { OAuth2Auth } from "./types"; · 14 unmodified lines
41 40
42const autoApprove: InvokeOptions = { onElicitation: "accept-all" };41const autoApprove: InvokeOptions = { onElicitation: "accept-all" };
43 42
43class OpenApiOauthTestSetupError extends Schema.TaggedErrorClass<OpenApiOauthTestSetupError>()(
44 "OpenApiOauthTestSetupError",
45 {
46 message: Schema.String,
47 },
48) {}
49
44// ---------------------------------------------------------------------------50// ---------------------------------------------------------------------------
45// Test API — one endpoint that echoes the Authorization header so we can51// Test API — one endpoint that echoes the Authorization header so we can
46// prove which access token was in flight at invoke time.52// prove which access token was in flight at invoke time.
@@ -141,11 +147,15 @@ const makeExecutor = () => · 94 unmodified lines
141 storage: () => ({}),147 storage: () => ({}),
142 secretProviders: [memoryProvider],148 secretProviders: [memoryProvider],
143 }));149 }));
144 const clientLayer = FetchHttpClient.layer;150 const clientLayer = FetchHttpClient.layer;
145 const server = yield* HttpServer.HttpServer;151 const server = yield* HttpServer.HttpServer;
146 const address = server.address;152 const address = server.address;
147 if (address._tag !== "TcpAddress") return yield* Effect.die("test server must bind to TCP");153 if (!("port" in address)) {
148 const baseUrl = `http://127.0.0.1:${address.port}`;154 return yield* new OpenApiOauthTestSetupError({
155 message: "Test server must bind to TCP",
156 });
157 }
158 const baseUrl = `http://127.0.0.1:${address.port}`;
149 const plugins = [159 const plugins = [
150 openApiPlugin({ httpClientLayer: clientLayer }),160 openApiPlugin({ httpClientLayer: clientLayer }),
151 memorySecretsPlugin(),161 memorySecretsPlugin(),
@@ -277,7 +287,7 @@ layer(TestLayer)("OpenAPI oauth refresh", (it) => { · 125 unmodified lines
277 287
278 yield* executor.openapi.addSpec({288 yield* executor.openapi.addSpec({
279 spec: specJson,289 spec: specJson,
280 scope: String(scopeId),290 scope: scopeId,
281 namespace: "petstore",291 namespace: "petstore",
282 baseUrl,292 baseUrl,
283 oauth2: auth,293 oauth2: auth,
@@ -334,7 +344,7 @@ layer(TestLayer)("OpenAPI oauth refresh", (it) => { · 50 unmodified lines
334 344
335 yield* executor.openapi.addSpec({345 yield* executor.openapi.addSpec({
336 spec: specJson,346 spec: specJson,
337 scope: String(scopeId),347 scope: scopeId,
338 namespace: "petstore",348 namespace: "petstore",
339 baseUrl,349 baseUrl,
340 oauth2: auth,350 oauth2: auth,
@@ -392,7 +402,7 @@ layer(TestLayer)("OpenAPI oauth refresh", (it) => { · 51 unmodified lines
392 402
393 yield* executor.openapi.addSpec({403 yield* executor.openapi.addSpec({
394 spec: specJson,404 spec: specJson,
395 scope: String(scopeId),405 scope: scopeId,
396 namespace: "petstore",406 namespace: "petstore",
397 baseUrl,407 baseUrl,
398 oauth2: auth,408 oauth2: auth,
@@ -402,15 +412,23 @@ layer(TestLayer)("OpenAPI oauth refresh", (it) => { · 3 unmodified lines
402 // generic Error (see openapi invokeTool), so we assert against412 // generic Error (see openapi invokeTool), so we assert against
403 // the `accessToken` call directly too — that's the surface413 // the `accessToken` call directly too — that's the surface
404 // the UI bridges use to trigger re-auth.414 // the UI bridges use to trigger re-auth.
405 const flipped = yield* executor.connections415 const reauthRequired = yield* executor.connections
406 .accessToken("conn-refresh-dead")416 .accessToken("conn-refresh-dead")
407 .pipe(Effect.flip);417 .pipe(
408 expect(flipped._tag).toBe("ConnectionReauthRequiredError");418 Effect.flatMap(() =>
409 expect((flipped as ConnectionReauthRequiredError).provider).toBe(419 Effect.fail(
420 new OpenApiOauthTestSetupError({
421 message: "Expected refresh to require re-auth",
422 }),
423 ),
424 ),
425 Effect.catchTag("ConnectionReauthRequiredError", Effect.succeed),
426 );
427 expect(reauthRequired.provider).toBe(
410 "openapi:oauth2",428 "openapi:oauth2",
411 );429 );
412 expect(430 expect(
413 (flipped as ConnectionReauthRequiredError).message,431 reauthRequired.message,
414 ).toMatch(/invalid_grant|revoked/i);432 ).toMatch(/invalid_grant|revoked/i);
415 }),433 }),
416 );434 );