setupOAuthAPI builds the API with a fosite provider wired in, against a fresh test DB. Returns the running httptest server, the provider (for inline authorize flow seeding), the underlying pool, and seeded client + user IDs ready for /token exchanges.
(t *testing.T)
| 30 | // (for inline authorize flow seeding), the underlying pool, and |
| 31 | // seeded client + user IDs ready for /token exchanges. |
| 32 | func setupOAuthAPI(t *testing.T) (server *httptest.Server, provider fosite.OAuth2Provider, pool *pgxpool.Pool, clientID, userID string) { |
| 33 | t.Helper() |
| 34 | pool = testutil.TestDB(t) |
| 35 | store := identity.NewStore(pool) |
| 36 | smtpRelay := outbound.NewSMTPRelay(&config.OutboundSMTPConfig{}) |
| 37 | sender := outbound.NewSender(smtpRelay, "test.e2a.dev") |
| 38 | |
| 39 | api := agent.NewAPI(store, sender, smtpRelay, nil, usage.NewNoopUsageTracker(), |
| 40 | "e2a.dev", "test.e2a.dev", "agents.e2a.dev", "https://test.e2a.dev", false) |
| 41 | |
| 42 | secret := []byte("test-secret-test-secret-test-sec") |
| 43 | storage := oauth.NewStorage(pool) |
| 44 | var err error |
| 45 | provider, err = oauth.NewProvider(storage, "https://test.e2a.dev", secret) |
| 46 | if err != nil { |
| 47 | t.Fatalf("NewProvider: %v", err) |
| 48 | } |
| 49 | api.SetOAuthProvider(provider) |
| 50 | |
| 51 | router := mux.NewRouter() |
| 52 | api.RegisterRoutes(router) |
| 53 | server = httptest.NewServer(router) |
| 54 | t.Cleanup(server.Close) |
| 55 | |
| 56 | // Seed user + client. |
| 57 | userID = "usr_" + randHex8(t) |
| 58 | if _, err := pool.Exec(context.Background(), ` |
| 59 | INSERT INTO users (id, email, name, google_subject, created_at) |
| 60 | VALUES ($1, $2, 'Test User', $3, NOW()) |
| 61 | ON CONFLICT (id) DO NOTHING |
| 62 | `, userID, userID+"@example.com", "google-"+userID); err != nil { |
| 63 | t.Fatal(err) |
| 64 | } |
| 65 | |
| 66 | clientID = "mcp_http_test" |
| 67 | if _, err := pool.Exec(context.Background(), ` |
| 68 | INSERT INTO oauth_clients |
| 69 | (client_id, client_name, redirect_uris, grant_types, |
| 70 | response_types, scopes, audiences, token_endpoint_auth_method, |
| 71 | public, created_via) |
| 72 | VALUES ($1, 'test client', |
| 73 | ARRAY['http://localhost:8765/callback'], |
| 74 | ARRAY['authorization_code','refresh_token'], |
| 75 | ARRAY['code'], |
| 76 | ARRAY['mcp'], |
| 77 | ARRAY[]::TEXT[], |
| 78 | 'none', TRUE, 'dcr') |
| 79 | ON CONFLICT (client_id) DO NOTHING |
| 80 | `, clientID); err != nil { |
| 81 | t.Fatal(err) |
| 82 | } |
| 83 | return server, provider, pool, clientID, userID |
| 84 | } |
| 85 | |
| 86 | func randHex8(t *testing.T) string { |
| 87 | t.Helper() |
no test coverage detected