TestHTTP_Discovery_SplitAPIURL pins the api_url split: when the API/MCP host differs from the web app host, the issuer + token/register/revoke/jwks live on api_url, while authorization_endpoint stays on public_url (the browser login/consent UI + session cookie live there). This is the agentdrive sha
(t *testing.T)
| 96 | // login/consent UI + session cookie live there). This is the agentdrive shape |
| 97 | // — issuer with the API, login page on the web domain. |
| 98 | func TestHTTP_Discovery_SplitAPIURL(t *testing.T) { |
| 99 | pool := testutil.TestDB(t) |
| 100 | store := identity.NewStore(pool) |
| 101 | smtpRelay := outbound.NewSMTPRelay(&config.OutboundSMTPConfig{}) |
| 102 | sender := outbound.NewSender(smtpRelay, "test.e2a.dev") |
| 103 | |
| 104 | const webURL = "https://e2a.dev" |
| 105 | const apiURL = "https://api.e2a.dev" |
| 106 | api := agent.NewAPI(store, sender, smtpRelay, nil, usage.NewNoopUsageTracker(), |
| 107 | "e2a.dev", "test.e2a.dev", "agents.e2a.dev", webURL, false) |
| 108 | api.SetAPIURL(apiURL) |
| 109 | |
| 110 | storage := oauth.NewStorage(pool) |
| 111 | provider, err := oauth.NewProvider(storage, apiURL, []byte("test-secret-test-secret-test-sec")) |
| 112 | if err != nil { |
| 113 | t.Fatalf("NewProvider: %v", err) |
| 114 | } |
| 115 | api.SetOAuthProvider(provider) |
| 116 | api.SetOAuthStorage(storage) |
| 117 | |
| 118 | router := mux.NewRouter() |
| 119 | api.RegisterRoutes(router) |
| 120 | srv := httptest.NewServer(router) |
| 121 | defer srv.Close() |
| 122 | |
| 123 | resp, err := http.Get(srv.URL + "/.well-known/oauth-authorization-server") |
| 124 | if err != nil { |
| 125 | t.Fatal(err) |
| 126 | } |
| 127 | defer resp.Body.Close() |
| 128 | var meta agent.OAuthMetadata |
| 129 | if err := json.NewDecoder(resp.Body).Decode(&meta); err != nil { |
| 130 | t.Fatal(err) |
| 131 | } |
| 132 | |
| 133 | // issuer + programmatic endpoints live on the API host (api_url). |
| 134 | if meta.Issuer != apiURL { |
| 135 | t.Errorf("issuer = %q, want %q (api_url)", meta.Issuer, apiURL) |
| 136 | } |
| 137 | for name, got := range map[string]string{ |
| 138 | "token_endpoint": meta.TokenEndpoint, |
| 139 | "registration_endpoint": meta.RegistrationEndpoint, |
| 140 | "revocation_endpoint": meta.RevocationEndpoint, |
| 141 | "jwks_uri": meta.JWKSURI, |
| 142 | } { |
| 143 | if !strings.HasPrefix(got, apiURL+"/") { |
| 144 | t.Errorf("%s = %q, want it on api_url %q", name, got, apiURL) |
| 145 | } |
| 146 | } |
| 147 | // the browser-facing authorize endpoint stays on the web app host — it |
| 148 | // needs the e2a.dev session cookie + login/consent UI, which don't travel |
| 149 | // cross-origin to api.e2a.dev. |
| 150 | if meta.AuthorizationEndpoint != webURL+"/oauth2/authorize" { |
| 151 | t.Errorf("authorization_endpoint = %q, want it on public_url %q", meta.AuthorizationEndpoint, webURL) |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | // TestHTTP_Discovery_TrailingSlashStripped: a publicURL configured |
nothing calls this directly
no test coverage detected