(t *testing.T)
| 1426 | } |
| 1427 | |
| 1428 | func TestMCPOAuth2DiscoveryEdgeCases(t *testing.T) { |
| 1429 | t.Parallel() |
| 1430 | |
| 1431 | t.Run("EmptyAuthorizationServers", func(t *testing.T) { |
| 1432 | t.Parallel() |
| 1433 | |
| 1434 | // When the path-aware PRM returns an empty |
| 1435 | // authorization_servers array, discovery should fall |
| 1436 | // back to the root-level PRM. |
| 1437 | t.Run("RootFallback", func(t *testing.T) { |
| 1438 | t.Parallel() |
| 1439 | |
| 1440 | ctx := testutil.Context(t, testutil.WaitLong) |
| 1441 | |
| 1442 | authServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 1443 | switch r.URL.Path { |
| 1444 | case "/.well-known/oauth-authorization-server": |
| 1445 | w.Header().Set("Content-Type", "application/json") |
| 1446 | _, _ = w.Write([]byte(`{ |
| 1447 | "issuer": "` + "http://" + r.Host + `", |
| 1448 | "authorization_endpoint": "` + "http://" + r.Host + `/authorize", |
| 1449 | "token_endpoint": "` + "http://" + r.Host + `/token", |
| 1450 | "registration_endpoint": "` + "http://" + r.Host + `/register", |
| 1451 | "response_types_supported": ["code"], |
| 1452 | "scopes_supported": ["fallback-scope"] |
| 1453 | }`)) |
| 1454 | case "/register": |
| 1455 | if r.Method != http.MethodPost { |
| 1456 | http.Error(w, "method not allowed", http.StatusMethodNotAllowed) |
| 1457 | return |
| 1458 | } |
| 1459 | w.Header().Set("Content-Type", "application/json") |
| 1460 | w.WriteHeader(http.StatusCreated) |
| 1461 | _, _ = w.Write([]byte(`{ |
| 1462 | "client_id": "fallback-client-id", |
| 1463 | "client_secret": "fallback-client-secret" |
| 1464 | }`)) |
| 1465 | default: |
| 1466 | http.NotFound(w, r) |
| 1467 | } |
| 1468 | })) |
| 1469 | t.Cleanup(authServer.Close) |
| 1470 | |
| 1471 | mcpServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 1472 | switch r.URL.Path { |
| 1473 | case "/.well-known/oauth-protected-resource/v1/mcp": |
| 1474 | // Path-aware: empty authorization_servers. |
| 1475 | w.Header().Set("Content-Type", "application/json") |
| 1476 | _, _ = w.Write([]byte(`{ |
| 1477 | "resource": "` + "http://" + r.Host + `/v1/mcp", |
| 1478 | "authorization_servers": [] |
| 1479 | }`)) |
| 1480 | case "/.well-known/oauth-protected-resource": |
| 1481 | // Root: valid authorization_servers. |
| 1482 | w.Header().Set("Content-Type", "application/json") |
| 1483 | _, _ = w.Write([]byte(`{ |
| 1484 | "resource": "` + "http://" + r.Host + `", |
| 1485 | "authorization_servers": ["` + authServer.URL + `"] |
nothing calls this directly
no test coverage detected