2026-04-04 01:40:24 +08:00
|
|
|
use http::Uri;
|
|
|
|
|
|
|
|
|
|
use super::{classify_control_route, headers};
|
2026-03-31 19:19:04 +08:00
|
|
|
|
2026-10-01 11:48:17 +08:00
|
|
|
#[test]
|
|
|
|
|
fn overview_routes_require_the_admin_stats_principal_and_get_method() {
|
|
|
|
|
for (suffix, kind) in [
|
|
|
|
|
("dashboard", "dashboard"),
|
|
|
|
|
("dashboard/summary", "dashboard_summary"),
|
|
|
|
|
("dashboard/total", "dashboard_total"),
|
|
|
|
|
("dashboard/charts", "dashboard_charts"),
|
|
|
|
|
("summary", "summary"),
|
|
|
|
|
("timeseries", "timeseries"),
|
|
|
|
|
("breakdown", "breakdown"),
|
|
|
|
|
("users", "users"),
|
|
|
|
|
("users/employee-1", "user_detail"),
|
|
|
|
|
("consumption", "consumption"),
|
|
|
|
|
("costs", "costs"),
|
|
|
|
|
("operations/live", "operations_live"),
|
|
|
|
|
("operations/performance", "operations_performance"),
|
|
|
|
|
("operations/resources", "operations_resources"),
|
|
|
|
|
] {
|
|
|
|
|
for trailing in ["", "/"] {
|
|
|
|
|
let uri: Uri = format!("/api/admin/overview/{suffix}{trailing}")
|
|
|
|
|
.parse()
|
|
|
|
|
.unwrap();
|
|
|
|
|
let decision = classify_control_route(&http::Method::GET, &uri, &headers(&[])).unwrap();
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("overview_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some(kind));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
|
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
|
|
|
|
let decision = classify_control_route(&http::Method::POST, &uri, &headers(&[]));
|
|
|
|
|
assert!(
|
|
|
|
|
decision.is_none_or(
|
|
|
|
|
|decision| decision.route_family.as_deref() != Some("overview_manage")
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 19:19:04 +08:00
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_provider_quota_usage_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/providers/quota-usage"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some("provider_quota_usage"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
2026-03-31 19:19:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_comparison_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/comparison"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some("comparison"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
2026-03-31 19:19:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_error_distribution_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/errors/distribution"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some("error_distribution"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
2026-03-31 19:19:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_performance_percentiles_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/performance/percentiles"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.route_kind.as_deref(),
|
|
|
|
|
Some("performance_percentiles")
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
2026-03-31 19:19:04 +08:00
|
|
|
}
|
|
|
|
|
|
2026-05-05 11:24:16 +08:00
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_provider_performance_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/performance/providers"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some("provider_performance"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
|
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 19:19:04 +08:00
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_cost_forecast_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/cost/forecast"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some("cost_forecast"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
2026-03-31 19:19:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_leaderboard_api_keys_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/leaderboard/api-keys"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some("leaderboard_api_keys"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
2026-03-31 19:19:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_leaderboard_models_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/leaderboard/models"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some("leaderboard_models"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
2026-03-31 19:19:04 +08:00
|
|
|
}
|
|
|
|
|
|
2026-09-18 16:03:46 +08:00
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_leaderboard_user_groups_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/leaderboard/user-groups"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.route_kind.as_deref(),
|
|
|
|
|
Some("leaderboard_user_groups")
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
|
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 19:19:04 +08:00
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_leaderboard_users_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/leaderboard/users"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some("leaderboard_users"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
2026-03-31 19:19:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_cost_savings_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/cost/savings"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some("cost_savings"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
2026-03-31 19:19:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn classifies_admin_stats_time_series_as_admin_proxy_route() {
|
|
|
|
|
let headers = headers(&[]);
|
|
|
|
|
let uri: Uri = "/api/admin/stats/time-series"
|
|
|
|
|
.parse()
|
|
|
|
|
.expect("uri should parse");
|
|
|
|
|
let decision =
|
|
|
|
|
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
|
|
|
|
|
|
|
|
|
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
|
|
|
|
assert_eq!(decision.route_family.as_deref(), Some("stats_manage"));
|
|
|
|
|
assert_eq!(decision.route_kind.as_deref(), Some("time_series"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
decision.auth_endpoint_signature.as_deref(),
|
|
|
|
|
Some("admin:stats")
|
|
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
assert!(!decision.is_execution_runtime_candidate());
|
2026-03-31 19:19:04 +08:00
|
|
|
}
|