mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
refactor: 移除独立 hub/proxy/executor/gateway crate,统一为 gateway tunnel 架构
- 删除 aether-hub、aether-proxy 独立项目及其 Dockerfile/配置 - 删除 crates/aether-executor 和 crates/aether-gateway 全部模块 - 新增 apps/ 目录作为应用入口 - 将 hub 概念重构为 gateway tunnel transport - 将 executor 重构为 execution runtime - 新增 tunnel.rs 合约定义和 testkit tunnel/execution_runtime 模块 - 更新 Python 服务层和测试适配新架构命名
This commit is contained in:
115
apps/aether-gateway/src/control/tests/admin_adaptive.rs
Normal file
115
apps/aether-gateway/src/control/tests/admin_adaptive.rs
Normal file
@@ -0,0 +1,115 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_adaptive_keys_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/adaptive/keys?provider_id=provider-openai"
|
||||
.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("adaptive_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_keys"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:adaptive")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_adaptive_summary_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/adaptive/summary"
|
||||
.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("adaptive_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("summary"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:adaptive")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_adaptive_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/adaptive/keys/key-openai/stats"
|
||||
.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("adaptive_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:adaptive")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_adaptive_toggle_mode_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/adaptive/keys/key-openai/mode"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PATCH, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("adaptive_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("toggle_mode"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:adaptive")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_adaptive_set_limit_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/adaptive/keys/key-openai/limit?limit=9"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PATCH, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("adaptive_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("set_limit"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:adaptive")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_adaptive_reset_learning_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/adaptive/keys/key-openai/learning"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("adaptive_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("reset_learning"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:adaptive")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
113
apps/aether-gateway/src/control/tests/admin_api_keys.rs
Normal file
113
apps/aether-gateway/src/control/tests/admin_api_keys.rs
Normal file
@@ -0,0 +1,113 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_api_keys_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/api-keys?limit=100"
|
||||
.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("api_keys_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_api_keys"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:api_keys")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_api_keys_create_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/api-keys".parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("api_keys_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("create_api_key"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:api_keys")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_api_keys_detail_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/api-keys/key-123"
|
||||
.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("api_keys_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("api_key_detail"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:api_keys")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_api_keys_update_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/api-keys/key-123"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::PUT, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("api_keys_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("update_api_key"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:api_keys")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_api_keys_toggle_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/api-keys/key-123"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PATCH, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("api_keys_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("toggle_api_key"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:api_keys")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_api_keys_delete_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/api-keys/key-123"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("api_keys_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("delete_api_key"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:api_keys")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
121
apps/aether-gateway/src/control/tests/admin_billing.rs
Normal file
121
apps/aether-gateway/src/control/tests/admin_billing.rs
Normal file
@@ -0,0 +1,121 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_billing_presets_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/billing/presets"
|
||||
.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("billing_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_presets"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:billing")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_billing_apply_preset_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/billing/presets/apply"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("billing_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("apply_preset"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:billing")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_billing_rule_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
|
||||
let list_uri: Uri = "/api/admin/billing/rules?page=1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let list = classify_control_route(&http::Method::GET, &list_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(list.route_family.as_deref(), Some("billing_manage"));
|
||||
assert_eq!(list.route_kind.as_deref(), Some("list_rules"));
|
||||
|
||||
let detail_uri: Uri = "/api/admin/billing/rules/rule-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let detail = classify_control_route(&http::Method::GET, &detail_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(detail.route_family.as_deref(), Some("billing_manage"));
|
||||
assert_eq!(detail.route_kind.as_deref(), Some("get_rule"));
|
||||
|
||||
let create_uri: Uri = "/api/admin/billing/rules"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let create = classify_control_route(&http::Method::POST, &create_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(create.route_family.as_deref(), Some("billing_manage"));
|
||||
assert_eq!(create.route_kind.as_deref(), Some("create_rule"));
|
||||
|
||||
let update_uri: Uri = "/api/admin/billing/rules/rule-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let update = classify_control_route(&http::Method::PUT, &update_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(update.route_family.as_deref(), Some("billing_manage"));
|
||||
assert_eq!(update.route_kind.as_deref(), Some("update_rule"));
|
||||
assert_eq!(
|
||||
update.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:billing")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_billing_collector_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
|
||||
let list_uri: Uri = "/api/admin/billing/collectors?page=1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let list = classify_control_route(&http::Method::GET, &list_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(list.route_family.as_deref(), Some("billing_manage"));
|
||||
assert_eq!(list.route_kind.as_deref(), Some("list_collectors"));
|
||||
|
||||
let detail_uri: Uri = "/api/admin/billing/collectors/collector-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let detail = classify_control_route(&http::Method::GET, &detail_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(detail.route_family.as_deref(), Some("billing_manage"));
|
||||
assert_eq!(detail.route_kind.as_deref(), Some("get_collector"));
|
||||
|
||||
let create_uri: Uri = "/api/admin/billing/collectors"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let create = classify_control_route(&http::Method::POST, &create_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(create.route_family.as_deref(), Some("billing_manage"));
|
||||
assert_eq!(create.route_kind.as_deref(), Some("create_collector"));
|
||||
|
||||
let update_uri: Uri = "/api/admin/billing/collectors/collector-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let update = classify_control_route(&http::Method::PUT, &update_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(update.route_family.as_deref(), Some("billing_manage"));
|
||||
assert_eq!(update.route_kind.as_deref(), Some("update_collector"));
|
||||
assert_eq!(
|
||||
update.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:billing")
|
||||
);
|
||||
}
|
||||
753
apps/aether-gateway/src/control/tests/admin_core.rs
Normal file
753
apps/aether-gateway/src/control/tests/admin_core.rs
Normal file
@@ -0,0 +1,753 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_endpoint_health_api_formats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/health/api-formats?lookback_hours=12"
|
||||
.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("endpoints_health"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("health_api_formats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_health")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_modules_status_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/modules/status"
|
||||
.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("modules_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("status_list"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:modules")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_modules_status_detail_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/modules/status/oauth"
|
||||
.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("modules_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("status_detail"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:modules")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_modules_set_enabled_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/modules/status/management_tokens/enabled"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::PUT, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("modules_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("set_enabled"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:modules")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_version_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/version"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("version"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_settings_get_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/settings"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("settings_get"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_config_export_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/config/export"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("config_export"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_users_export_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/users/export"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("users_export"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_maintenance_write_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let cases = [
|
||||
("/api/admin/system/config/import", "config_import"),
|
||||
("/api/admin/system/users/import", "users_import"),
|
||||
("/api/admin/system/smtp/test", "smtp_test"),
|
||||
("/api/admin/system/cleanup", "cleanup"),
|
||||
("/api/admin/system/purge/config", "purge_config"),
|
||||
("/api/admin/system/purge/users", "purge_users"),
|
||||
("/api/admin/system/purge/usage", "purge_usage"),
|
||||
("/api/admin/system/purge/audit-logs", "purge_audit_logs"),
|
||||
(
|
||||
"/api/admin/system/purge/request-bodies",
|
||||
"purge_request_bodies",
|
||||
),
|
||||
("/api/admin/system/purge/stats", "purge_stats"),
|
||||
];
|
||||
|
||||
for (path, expected_kind) in cases {
|
||||
let uri: Uri = path.parse().expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::POST, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some(expected_kind));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_check_update_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/check-update"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("check_update"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_aws_regions_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/aws-regions"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("aws_regions"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/stats".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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_settings_set_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/settings"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::PUT, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("settings_set"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_email_templates_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/email/templates"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("email_templates_list"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_email_template_get_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/email/templates/verification"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("email_template_get"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_email_template_set_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/email/templates/verification"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::PUT, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("email_template_set"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_email_template_preview_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/email/templates/verification/preview"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("system_manage"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("email_template_preview")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_email_template_reset_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/email/templates/verification/reset"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("email_template_reset"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_configs_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/configs?limit=20"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("configs_list"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_config_get_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/configs/smtp_password"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("config_get"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_config_set_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/configs/smtp_password"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::PUT, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("config_set"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_config_delete_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/configs/request_log_level"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("config_delete"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_system_api_formats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/system/api-formats"
|
||||
.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("system_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("api_formats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:system")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_list_providers_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/?skip=0&limit=50"
|
||||
.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("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_providers"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_list_management_tokens_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/management-tokens?limit=20"
|
||||
.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("management_tokens_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_tokens"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:management_tokens")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_ldap_config_get_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/ldap/config".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("ldap_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_config"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:ldap")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_ldap_config_set_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/ldap/config".parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::PUT, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("ldap_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("set_config"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:ldap")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_ldap_test_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/ldap/test".parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("ldap_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("test_connection"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:ldap")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_list_gemini_file_mappings_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/gemini-files/mappings?page=1"
|
||||
.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("gemini_files_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_mappings"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:gemini_files")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_gemini_file_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/gemini-files/stats"
|
||||
.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("gemini_files_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:gemini_files")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_delete_gemini_file_mapping_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/gemini-files/mappings/mapping-123"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("gemini_files_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("delete_mapping"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:gemini_files")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_cleanup_gemini_file_mappings_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/gemini-files/mappings"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("gemini_files_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("cleanup_mappings"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:gemini_files")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_list_gemini_file_capable_keys_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/gemini-files/capable-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("gemini_files_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("capable_keys"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:gemini_files")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_gemini_file_upload_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/gemini-files/upload"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("gemini_files_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("upload"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:gemini_files")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_oauth_supported_types_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/oauth/supported-types"
|
||||
.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("oauth_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("supported_types"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_oauth_supported_types_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-oauth/supported-types"
|
||||
.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("provider_oauth_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("supported_types"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_trace_request_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/trace/request-id-123"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("trace_request"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_trace_provider_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/trace/stats/provider/provider-id"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("trace_provider_stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
382
apps/aether-gateway/src/control/tests/admin_endpoints.rs
Normal file
382
apps/aether-gateway/src/control/tests/admin_endpoints.rs
Normal file
@@ -0,0 +1,382 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_endpoint_health_summary_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/health/summary"
|
||||
.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("endpoints_health"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("health_summary"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_health")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_endpoint_key_health_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/health/key/key-openai?api_format=openai:chat"
|
||||
.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("endpoints_health"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("key_health"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_health")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_endpoint_recover_key_health_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/health/keys/key-openai?api_format=openai:chat"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PATCH, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_health"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("recover_key_health"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_health")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_endpoint_recover_all_keys_health_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/health/keys"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PATCH, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_health"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("recover_all_keys_health")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_health")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_endpoint_health_status_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/health/status?lookback_hours=12"
|
||||
.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("endpoints_health"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("health_status"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_health")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_endpoint_key_rpm_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/rpm/key/key-1"
|
||||
.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("endpoints_rpm"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("key_rpm"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_rpm")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_endpoint_reset_key_rpm_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/rpm/key/key-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_rpm"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("reset_key_rpm"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_rpm")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_list_provider_endpoints_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/providers/provider-1/endpoints?skip=0&limit=50"
|
||||
.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("endpoints_manage"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("list_provider_endpoints")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_manage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_list_provider_keys_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/providers/provider-openai/keys?skip=0&limit=20"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::GET, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_provider_keys"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_keys_grouped_by_format_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/keys/grouped-by-format"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::GET, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("keys_grouped_by_format")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_reveal_key_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/keys/key-openai/reveal"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::GET, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("reveal_key"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_export_key_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/keys/key-openai/export"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::GET, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("export_key"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_update_key_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/keys/key-openai"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PUT, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("update_key"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_delete_key_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/keys/key-openai"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("delete_key"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_batch_delete_keys_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/keys/batch-delete"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::POST, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("batch_delete_keys"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_clear_oauth_invalid_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/keys/key-openai/clear-oauth-invalid"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::POST, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("clear_oauth_invalid"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_create_provider_key_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/providers/provider-openai/keys"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::POST, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("create_provider_key"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_get_endpoint_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/endpoint-1"
|
||||
.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("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_endpoint"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_manage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_create_endpoint_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/providers/provider-openai/endpoints"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::POST, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("create_endpoint"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_update_endpoint_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/endpoint-openai-chat"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PUT, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("update_endpoint"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_delete_endpoint_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/endpoint-openai-chat"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("delete_endpoint"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_refresh_provider_quota_as_admin_proxy_route() {
|
||||
let headers = http::HeaderMap::new();
|
||||
let uri: Uri = "/api/admin/endpoints/providers/provider-codex/refresh-quota"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::POST, &uri, &headers)
|
||||
.expect("decision should resolve");
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("refresh_quota"));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_default_body_rules_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/endpoints/defaults/openai:cli/body-rules?provider_type=codex"
|
||||
.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("endpoints_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("default_body_rules"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:endpoints_manage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
387
apps/aether-gateway/src/control/tests/admin_monitoring.rs
Normal file
387
apps/aether-gateway/src/control/tests/admin_monitoring.rs
Normal file
@@ -0,0 +1,387 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_audit_logs_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/audit-logs"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("audit_logs"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_trace_request_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/trace/request-1"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("trace_request"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_cache_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/stats"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_cache_affinities_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/affinities"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_cache_affinity_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/affinity/user-1"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_cache_users_delete_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/users/user-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_cache_affinity_delete_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/affinity/user-key-1/endpoint-1/model-alpha/openai"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_cache_flush_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_cache_provider_delete_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/providers/provider-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_cache_metrics_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/metrics"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_cache_config_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/config"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_model_mapping_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/model-mapping/stats"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_model_mapping_delete_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/model-mapping"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_model_mapping_delete_model_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/model-mapping/model-alpha"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_model_mapping_delete_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/model-mapping/provider/provider-1/model-alpha"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_redis_keys_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/redis-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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_redis_keys_delete_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/cache/redis-keys/dashboard"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("monitoring_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_resilience_status_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/resilience-status"
|
||||
.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("monitoring"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("monitoring_resilience")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_resilience_error_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/resilience/error-stats"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("monitoring"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("monitoring_resilience")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_monitoring_user_behavior_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/monitoring/user-behavior/user-1"
|
||||
.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("monitoring"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("user_behavior"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
284
apps/aether-gateway/src/control/tests/admin_oauth.rs
Normal file
284
apps/aether-gateway/src/control/tests/admin_oauth.rs
Normal file
@@ -0,0 +1,284 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_oauth_start_key_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-oauth/keys/key-123/start"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_oauth_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("start_key_oauth"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_oauth_start_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-oauth/providers/provider-123/start"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_oauth_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("start_provider_oauth"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_oauth_batch_import_task_status_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-oauth/providers/provider-123/batch-import/tasks/task-456"
|
||||
.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("provider_oauth_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("get_batch_import_task_status")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_oauth_maintenance_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
for (method, path, route_kind) in [
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/admin/provider-oauth/keys/key-123/complete",
|
||||
"complete_key_oauth",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/admin/provider-oauth/keys/key-123/refresh",
|
||||
"refresh_key_oauth",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/admin/provider-oauth/providers/provider-123/complete",
|
||||
"complete_provider_oauth",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/admin/provider-oauth/providers/provider-123/import-refresh-token",
|
||||
"import_refresh_token",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/admin/provider-oauth/providers/provider-123/batch-import",
|
||||
"batch_import_oauth",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/admin/provider-oauth/providers/provider-123/batch-import/tasks",
|
||||
"start_batch_import_oauth_task",
|
||||
),
|
||||
(
|
||||
http::Method::GET,
|
||||
"/api/admin/provider-oauth/providers/provider-123/batch-import/tasks/task-123",
|
||||
"get_batch_import_task_status",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/admin/provider-oauth/providers/provider-123/device-authorize",
|
||||
"device_authorize",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/admin/provider-oauth/providers/provider-123/device-poll",
|
||||
"device_poll",
|
||||
),
|
||||
] {
|
||||
let uri: Uri = path.parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&method, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_oauth_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some(route_kind));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_oauth_list_providers_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/oauth/providers?limit=20"
|
||||
.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("oauth_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_providers"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_oauth_get_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/oauth/providers/linuxdo"
|
||||
.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("oauth_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_provider"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_oauth_upsert_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/oauth/providers/linuxdo"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::PUT, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("oauth_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("upsert_provider"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_oauth_delete_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/oauth/providers/linuxdo"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("oauth_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("delete_provider"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_oauth_test_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/oauth/providers/linuxdo/test"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("oauth_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("test_provider"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:oauth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_get_management_token_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/management-tokens/token-123"
|
||||
.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("management_tokens_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_token"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_delete_management_token_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/management-tokens/token-123"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("management_tokens_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("delete_token"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_toggle_management_token_status_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/management-tokens/token-123/status"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PATCH, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("management_tokens_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("toggle_status"));
|
||||
}
|
||||
136
apps/aether-gateway/src/control/tests/admin_payments.rs
Normal file
136
apps/aether-gateway/src/control/tests/admin_payments.rs
Normal file
@@ -0,0 +1,136 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_payments_list_orders_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/payments/orders"
|
||||
.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("payments_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_orders"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:payments")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_payments_get_order_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/payments/orders/order-1"
|
||||
.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("payments_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_order"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:payments")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_payments_trailing_slash_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
|
||||
let detail_uri: Uri = "/api/admin/payments/orders/order-1/"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let detail = classify_control_route(&http::Method::GET, &detail_uri, &headers)
|
||||
.expect("detail route should classify");
|
||||
assert_eq!(detail.route_family.as_deref(), Some("payments_manage"));
|
||||
assert_eq!(detail.route_kind.as_deref(), Some("get_order"));
|
||||
|
||||
let credit_uri: Uri = "/api/admin/payments/orders/order-1/credit/"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let credit = classify_control_route(&http::Method::POST, &credit_uri, &headers)
|
||||
.expect("credit route should classify");
|
||||
assert_eq!(credit.route_family.as_deref(), Some("payments_manage"));
|
||||
assert_eq!(credit.route_kind.as_deref(), Some("credit_order"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_payments_expire_order_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/payments/orders/order-1/expire"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("payments_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("expire_order"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:payments")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_payments_credit_order_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/payments/orders/order-1/credit"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("payments_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("credit_order"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:payments")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_payments_fail_order_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/payments/orders/order-1/fail"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("payments_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("fail_order"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:payments")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_payments_callbacks_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/payments/callbacks"
|
||||
.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("payments_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_callbacks"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:payments")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
174
apps/aether-gateway/src/control/tests/admin_pool.rs
Normal file
174
apps/aether-gateway/src/control/tests/admin_pool.rs
Normal file
@@ -0,0 +1,174 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_pool_overview_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/pool/overview"
|
||||
.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("pool_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("overview"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:pool")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_pool_scheduling_presets_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/pool/scheduling-presets"
|
||||
.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("pool_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("scheduling_presets"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:pool")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_pool_provider_key_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
|
||||
let list_uri: Uri = "/api/admin/pool/provider-1/keys?page=1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let list = classify_control_route(&http::Method::GET, &list_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(list.route_family.as_deref(), Some("pool_manage"));
|
||||
assert_eq!(list.route_kind.as_deref(), Some("list_keys"));
|
||||
|
||||
let batch_import_uri: Uri = "/api/admin/pool/provider-1/keys/batch-import"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let batch_import = classify_control_route(&http::Method::POST, &batch_import_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(batch_import.route_family.as_deref(), Some("pool_manage"));
|
||||
assert_eq!(
|
||||
batch_import.route_kind.as_deref(),
|
||||
Some("batch_import_keys")
|
||||
);
|
||||
|
||||
let batch_action_uri: Uri = "/api/admin/pool/provider-1/keys/batch-action"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let batch_action = classify_control_route(&http::Method::POST, &batch_action_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(batch_action.route_family.as_deref(), Some("pool_manage"));
|
||||
assert_eq!(
|
||||
batch_action.route_kind.as_deref(),
|
||||
Some("batch_action_keys")
|
||||
);
|
||||
|
||||
let resolve_selection_uri: Uri = "/api/admin/pool/provider-1/keys/resolve-selection"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let resolve_selection =
|
||||
classify_control_route(&http::Method::POST, &resolve_selection_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(
|
||||
resolve_selection.route_family.as_deref(),
|
||||
Some("pool_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_selection.route_kind.as_deref(),
|
||||
Some("resolve_selection")
|
||||
);
|
||||
|
||||
let batch_delete_task_uri: Uri = "/api/admin/pool/provider-1/keys/batch-delete-task/task-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let batch_delete_task =
|
||||
classify_control_route(&http::Method::GET, &batch_delete_task_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(
|
||||
batch_delete_task.route_family.as_deref(),
|
||||
Some("pool_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
batch_delete_task.route_kind.as_deref(),
|
||||
Some("batch_delete_task_status")
|
||||
);
|
||||
|
||||
let cleanup_banned_uri: Uri = "/api/admin/pool/provider-1/keys/cleanup-banned"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let cleanup_banned = classify_control_route(&http::Method::POST, &cleanup_banned_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(cleanup_banned.route_family.as_deref(), Some("pool_manage"));
|
||||
assert_eq!(
|
||||
cleanup_banned.route_kind.as_deref(),
|
||||
Some("cleanup_banned_keys")
|
||||
);
|
||||
assert_eq!(
|
||||
cleanup_banned.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:pool")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_pool_trailing_slash_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
|
||||
let list_uri: Uri = "/api/admin/pool/provider-1/keys/"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let list = classify_control_route(&http::Method::GET, &list_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(list.route_family.as_deref(), Some("pool_manage"));
|
||||
assert_eq!(list.route_kind.as_deref(), Some("list_keys"));
|
||||
|
||||
let resolve_selection_uri: Uri = "/api/admin/pool/provider-1/keys/resolve-selection/"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let resolve_selection =
|
||||
classify_control_route(&http::Method::POST, &resolve_selection_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(
|
||||
resolve_selection.route_family.as_deref(),
|
||||
Some("pool_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_selection.route_kind.as_deref(),
|
||||
Some("resolve_selection")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_pool_malformed_provider_id_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
|
||||
let list_uri: Uri = "/api/admin/pool//keys".parse().expect("uri should parse");
|
||||
let list = classify_control_route(&http::Method::GET, &list_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(list.route_family.as_deref(), Some("pool_manage"));
|
||||
assert_eq!(list.route_kind.as_deref(), Some("list_keys"));
|
||||
|
||||
let import_uri: Uri = "/api/admin/pool//keys/batch-import"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let import = classify_control_route(&http::Method::POST, &import_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(import.route_family.as_deref(), Some("pool_manage"));
|
||||
assert_eq!(import.route_kind.as_deref(), Some("batch_import_keys"));
|
||||
|
||||
let cleanup_uri: Uri = "/api/admin/pool//keys/cleanup-banned"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let cleanup = classify_control_route(&http::Method::POST, &cleanup_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(cleanup.route_family.as_deref(), Some("pool_manage"));
|
||||
assert_eq!(cleanup.route_kind.as_deref(), Some("cleanup_banned_keys"));
|
||||
}
|
||||
318
apps/aether-gateway/src/control/tests/admin_provider_ops.rs
Normal file
318
apps/aether-gateway/src/control/tests/admin_provider_ops.rs
Normal file
@@ -0,0 +1,318 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_architectures_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/architectures?limit=20"
|
||||
.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("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_architectures"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_architecture_detail_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/architectures/generic_api"
|
||||
.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("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_architecture"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_provider_status_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/status"
|
||||
.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("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_provider_status"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_provider_config_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/config"
|
||||
.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("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_provider_config"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_save_provider_config_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/config"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::PUT, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("save_provider_config"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_delete_provider_config_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/config"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("delete_provider_config")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_disconnect_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/disconnect"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("disconnect_provider"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_connect_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/connect"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("connect_provider"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_verify_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/verify"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("verify_provider"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_get_balance_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/balance"
|
||||
.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("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_provider_balance"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_refresh_balance_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/balance"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("refresh_provider_balance")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_checkin_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/checkin"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("provider_checkin"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_execute_action_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/providers/provider-openai/actions/query_balance"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("execute_provider_action")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_ops_batch_balance_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-ops/batch/balance"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_ops_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("batch_balance"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_ops")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_query_models_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-query/models"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_query_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("query_models"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_query")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_query_test_model_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-query/test-model"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_query_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("test_model"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_query")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_query_test_model_failover_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-query/test-model-failover"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_query_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("test_model_failover"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_query")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_strategy_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-strategy/strategies"
|
||||
.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("provider_strategy_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_strategies"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_strategy")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_strategy_reset_quota_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-strategy/providers/provider-openai/quota"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_strategy_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("reset_provider_quota"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_strategy")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_strategy_update_billing_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-strategy/providers/provider-openai/billing"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::PUT, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_strategy_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("update_provider_billing")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_strategy")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_strategy_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/provider-strategy/providers/provider-openai/stats?hours=48"
|
||||
.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("provider_strategy_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_provider_stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:provider_strategy")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
691
apps/aether-gateway/src/control/tests/admin_providers_models.rs
Normal file
691
apps/aether-gateway/src/control/tests/admin_providers_models.rs
Normal file
@@ -0,0 +1,691 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_create_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/".parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("create_provider"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_providers_summary_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/summary?page=1&page_size=20"
|
||||
.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("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("summary_list"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_update_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PATCH, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("update_provider"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_delete_provider_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("delete_provider"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_summary_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/summary"
|
||||
.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("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("provider_summary"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_health_monitor_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/health-monitor?lookback_hours=6"
|
||||
.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("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("health_monitor"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_mapping_preview_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/mapping-preview"
|
||||
.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("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("mapping_preview"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_delete_task_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/delete-task/task-1234"
|
||||
.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("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("delete_provider_task"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_pool_status_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/pool-status"
|
||||
.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("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("pool_status"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_clear_pool_cooldown_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/pool/clear-cooldown/key-openai"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("clear_pool_cooldown"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_reset_pool_cost_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/pool/reset-cost/key-openai"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("providers_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("reset_pool_cost"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_list_provider_models_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/models?skip=0&limit=20"
|
||||
.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("provider_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_provider_models"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_get_provider_model_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/models/model-gpt-5"
|
||||
.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("provider_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_provider_model"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_create_provider_model_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/models"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_models_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("create_provider_model")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_update_provider_model_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/models/model-gpt-5"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PATCH, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_models_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("update_provider_model")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_delete_provider_model_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/models/model-gpt-5"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_models_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("delete_provider_model")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_batch_create_provider_models_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/models/batch"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_models_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("batch_create_provider_models")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_provider_available_source_models_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/available-source-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("provider_models_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("available_source_models")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_assign_global_models_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/assign-global-models"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("assign_global_models"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_import_provider_models_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/providers/provider-openai/import-from-upstream"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("provider_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("import_from_upstream"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:providers")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_list_global_models_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/global?skip=0&limit=20"
|
||||
.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("global_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_global_models"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_model_catalog_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/catalog"
|
||||
.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("model_catalog_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("catalog"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_external_models_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/external"
|
||||
.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("model_external_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("external"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_clear_external_models_cache_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/external/cache"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("model_external_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("clear_external_cache"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_global_model_routing_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/global/global-gpt-5/routing"
|
||||
.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("global_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("routing_preview"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_get_global_model_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/global/global-gpt-5"
|
||||
.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("global_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("get_global_model"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_create_global_model_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/global"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("global_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("create_global_model"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_assign_global_model_to_providers_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/global/global-gpt-5/assign-to-providers"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("global_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("assign_to_providers"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_global_model_providers_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/global/global-gpt-5/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("global_models_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("global_model_providers")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_update_global_model_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/global/global-gpt-5"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PATCH, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("global_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("update_global_model"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_delete_global_model_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/global/global-gpt-5"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("global_models_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("delete_global_model"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_batch_delete_global_models_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/models/global/batch-delete"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("global_models_manage")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("batch_delete_global_models")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:models")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
58
apps/aether-gateway/src/control/tests/admin_proxy_nodes.rs
Normal file
58
apps/aether-gateway/src/control/tests/admin_proxy_nodes.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_proxy_nodes_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/proxy-nodes?status=online&skip=10&limit=20"
|
||||
.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("proxy_nodes_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_nodes"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:proxy_nodes")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_proxy_nodes_register_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/proxy-nodes/register"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("proxy_nodes_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("register_node"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:proxy_nodes")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_proxy_nodes_events_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/proxy-nodes/node-1/events?limit=50"
|
||||
.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("proxy_nodes_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_node_events"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:proxy_nodes")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
134
apps/aether-gateway/src/control/tests/admin_security.rs
Normal file
134
apps/aether-gateway/src/control/tests/admin_security.rs
Normal file
@@ -0,0 +1,134 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_security_blacklist_add_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/security/ip/blacklist"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("security_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("blacklist_add"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:security")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_security_blacklist_remove_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/security/ip/blacklist/1.2.3.4"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("security_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("blacklist_remove"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:security")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_security_blacklist_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/security/ip/blacklist/stats"
|
||||
.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("security_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("blacklist_stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:security")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_security_blacklist_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/security/ip/blacklist"
|
||||
.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("security_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("blacklist_list"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:security")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_security_whitelist_add_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/security/ip/whitelist"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("security_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("whitelist_add"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:security")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_security_whitelist_remove_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/security/ip/whitelist/1.2.3.4"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("security_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("whitelist_remove"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:security")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_security_whitelist_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/security/ip/whitelist"
|
||||
.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("security_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("whitelist_list"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:security")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
194
apps/aether-gateway/src/control/tests/admin_stats.rs
Normal file
194
apps/aether-gateway/src/control/tests/admin_stats.rs
Normal file
@@ -0,0 +1,194 @@
|
||||
use super::*;
|
||||
|
||||
#[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")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[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")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[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")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[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")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[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")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[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")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[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")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[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")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[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")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[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")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
249
apps/aether-gateway/src/control/tests/admin_usage.rs
Normal file
249
apps/aether-gateway/src/control/tests/admin_usage.rs
Normal file
@@ -0,0 +1,249 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/stats".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("usage_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_aggregation_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/aggregation/stats"
|
||||
.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("usage_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("aggregation_stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_heatmap_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/heatmap"
|
||||
.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("usage_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("heatmap"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_records_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/records"
|
||||
.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("usage_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("records"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_active_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/active".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("usage_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("active"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_cache_affinity_hit_analysis_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/cache-affinity/hit-analysis"
|
||||
.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("usage_manage"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("cache_affinity_hit_analysis")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_cache_affinity_interval_timeline_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/cache-affinity/interval-timeline"
|
||||
.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("usage_manage"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("cache_affinity_interval_timeline")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_cache_affinity_ttl_analysis_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/cache-affinity/ttl-analysis"
|
||||
.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("usage_manage"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("cache_affinity_ttl_analysis")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_detail_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/usage-1"
|
||||
.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("usage_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("detail"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_detail_with_empty_usage_id_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/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("usage_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("detail"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_curl_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/usage-1/curl"
|
||||
.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("usage_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("curl"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_curl_with_empty_usage_id_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage//curl".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("usage_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("curl"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_usage_replay_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/usage/usage-1/replay"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("usage_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("replay"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:usage")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
182
apps/aether-gateway/src/control/tests/admin_users.rs
Normal file
182
apps/aether-gateway/src/control/tests/admin_users.rs
Normal file
@@ -0,0 +1,182 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_users_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/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("users_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_users"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:users")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_users_create_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/users".parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("create_user"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:users")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_user_detail_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
|
||||
let get_uri: Uri = "/api/admin/users/user-1".parse().expect("uri should parse");
|
||||
let get = classify_control_route(&http::Method::GET, &get_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(get.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(get.route_kind.as_deref(), Some("get_user"));
|
||||
|
||||
let put_uri: Uri = "/api/admin/users/user-1".parse().expect("uri should parse");
|
||||
let put = classify_control_route(&http::Method::PUT, &put_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(put.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(put.route_kind.as_deref(), Some("update_user"));
|
||||
|
||||
let delete_uri: Uri = "/api/admin/users/user-1".parse().expect("uri should parse");
|
||||
let delete = classify_control_route(&http::Method::DELETE, &delete_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(delete.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(delete.route_kind.as_deref(), Some("delete_user"));
|
||||
assert_eq!(
|
||||
delete.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:users")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_user_session_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
|
||||
let list_uri: Uri = "/api/admin/users/user-1/sessions"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let list = classify_control_route(&http::Method::GET, &list_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(list.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(list.route_kind.as_deref(), Some("list_user_sessions"));
|
||||
|
||||
let delete_all_uri: Uri = "/api/admin/users/user-1/sessions"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let delete_all = classify_control_route(&http::Method::DELETE, &delete_all_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(delete_all.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(
|
||||
delete_all.route_kind.as_deref(),
|
||||
Some("delete_user_sessions")
|
||||
);
|
||||
|
||||
let delete_one_uri: Uri = "/api/admin/users/user-1/sessions/session-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let delete_one = classify_control_route(&http::Method::DELETE, &delete_one_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(delete_one.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(
|
||||
delete_one.route_kind.as_deref(),
|
||||
Some("delete_user_session")
|
||||
);
|
||||
assert_eq!(
|
||||
delete_one.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:users")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_user_api_key_routes_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
|
||||
let list_uri: Uri = "/api/admin/users/user-1/api-keys"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let list = classify_control_route(&http::Method::GET, &list_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(list.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(list.route_kind.as_deref(), Some("list_user_api_keys"));
|
||||
|
||||
let create_uri: Uri = "/api/admin/users/user-1/api-keys"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let create = classify_control_route(&http::Method::POST, &create_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(create.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(create.route_kind.as_deref(), Some("create_user_api_key"));
|
||||
|
||||
let delete_uri: Uri = "/api/admin/users/user-1/api-keys/key-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let delete = classify_control_route(&http::Method::DELETE, &delete_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(delete.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(delete.route_kind.as_deref(), Some("delete_user_api_key"));
|
||||
|
||||
let update_uri: Uri = "/api/admin/users/user-1/api-keys/key-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let update = classify_control_route(&http::Method::PUT, &update_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(update.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(update.route_kind.as_deref(), Some("update_user_api_key"));
|
||||
|
||||
let lock_uri: Uri = "/api/admin/users/user-1/api-keys/key-1/lock"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let lock = classify_control_route(&http::Method::PATCH, &lock_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(lock.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(lock.route_kind.as_deref(), Some("lock_user_api_key"));
|
||||
|
||||
let full_key_uri: Uri = "/api/admin/users/user-1/api-keys/key-1/full-key"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let full_key = classify_control_route(&http::Method::GET, &full_key_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(full_key.route_family.as_deref(), Some("users_manage"));
|
||||
assert_eq!(full_key.route_kind.as_deref(), Some("reveal_user_api_key"));
|
||||
assert_eq!(
|
||||
full_key.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:users")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_user_api_key_mutation_routes_with_admin_users_signature() {
|
||||
let headers = headers(&[]);
|
||||
|
||||
let create_uri: Uri = "/api/admin/users/user-1/api-keys"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let create = classify_control_route(&http::Method::POST, &create_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(create.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
create.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:users")
|
||||
);
|
||||
|
||||
let lock_uri: Uri = "/api/admin/users/user-1/api-keys/key-1/lock"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let lock = classify_control_route(&http::Method::PATCH, &lock_uri, &headers)
|
||||
.expect("route should classify");
|
||||
assert_eq!(lock.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(lock.auth_endpoint_signature.as_deref(), Some("admin:users"));
|
||||
}
|
||||
96
apps/aether-gateway/src/control/tests/admin_video_tasks.rs
Normal file
96
apps/aether-gateway/src/control/tests/admin_video_tasks.rs
Normal file
@@ -0,0 +1,96 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_video_tasks_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/video-tasks?status=completed&page=2"
|
||||
.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("video_tasks_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_tasks"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:video_tasks")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_video_tasks_stats_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/video-tasks/stats"
|
||||
.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("video_tasks_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:video_tasks")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_video_tasks_detail_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/video-tasks/task-123"
|
||||
.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("video_tasks_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("detail"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:video_tasks")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_video_tasks_cancel_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/video-tasks/task-123/cancel"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("video_tasks_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("cancel"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:video_tasks")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_video_tasks_video_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/video-tasks/task-123/video"
|
||||
.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("video_tasks_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("video"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:video_tasks")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
254
apps/aether-gateway/src/control/tests/admin_wallets.rs
Normal file
254
apps/aether-gateway/src/control/tests/admin_wallets.rs
Normal file
@@ -0,0 +1,254 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_list_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets?status=active&limit=20"
|
||||
.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("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_wallets"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_ledger_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/ledger?owner_type=user"
|
||||
.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("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("ledger"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_refund_requests_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/refund-requests?status=pending_approval"
|
||||
.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("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_refund_requests"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_detail_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/wallet-123"
|
||||
.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("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("wallet_detail"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_transactions_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/wallet-123/transactions?limit=50"
|
||||
.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("wallets_manage"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("list_wallet_transactions")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_transactions_with_empty_wallet_id_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets//transactions"
|
||||
.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("wallets_manage"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("list_wallet_transactions")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_refunds_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/wallet-123/refunds?limit=50"
|
||||
.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("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list_wallet_refunds"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_adjust_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/wallet-123/adjust"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("adjust_balance"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_recharge_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/wallet-123/recharge"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("recharge_balance"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_process_refund_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/wallet-123/refunds/refund-1/process"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("process_refund"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_process_refund_with_empty_refund_id_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/wallet-123/refunds//process"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("process_refund"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_complete_refund_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/wallet-123/refunds/refund-1/complete"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("complete_refund"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_wallets_fail_refund_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/admin/wallets/wallet-123/refunds/refund-1/fail"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("wallets_manage"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("fail_refund"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:wallets")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
87
apps/aether-gateway/src/control/tests/ai.rs
Normal file
87
apps/aether-gateway/src/control/tests/ai.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_claude_count_tokens_as_non_execution_runtime_public_route() {
|
||||
let headers = headers(&[("x-api-key", "sk-test")]);
|
||||
let uri: Uri = "/v1/messages/count_tokens"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_family.as_deref(), Some("claude"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("count_tokens"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("claude:chat")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_models_list_as_claude_when_headers_match() {
|
||||
let headers = headers(&[
|
||||
("x-api-key", "sk-claude"),
|
||||
("anthropic-version", "2023-06-01"),
|
||||
]);
|
||||
let uri: Uri = "/v1/models".parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::GET, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("claude:chat")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_claude_messages_cli_when_bearer_without_api_key() {
|
||||
let headers = headers(&[("authorization", "Bearer token-123")]);
|
||||
let uri: Uri = "/v1/messages".parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_family.as_deref(), Some("claude"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("cli"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("claude:cli")
|
||||
);
|
||||
assert!(decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_gemini_cli_generate_content_when_x_app_contains_cli() {
|
||||
let headers = headers(&[("x-app", "Gemini-CLI")]);
|
||||
let uri: Uri = "/v1beta/models/gemini-2.5-pro:generateContent"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_family.as_deref(), Some("gemini"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("cli"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("gemini:cli")
|
||||
);
|
||||
assert!(decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_gemini_predict_long_running_as_video_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/v1beta/models/veo-3:predictLongRunning"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_family.as_deref(), Some("gemini"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("video"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("gemini:video")
|
||||
);
|
||||
assert!(decision.is_execution_runtime_candidate());
|
||||
}
|
||||
55
apps/aether-gateway/src/control/tests/internal.rs
Normal file
55
apps/aether-gateway/src/control/tests/internal.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_internal_tunnel_heartbeat_as_internal_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/internal/tunnel/heartbeat"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("internal_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some(crate::gateway::TUNNEL_ROUTE_FAMILY)
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("heartbeat"));
|
||||
assert_eq!(decision.auth_endpoint_signature.as_deref(), Some(""));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_internal_gateway_resolve_as_internal_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/internal/gateway/resolve"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("internal_proxy"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("gateway_legacy"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("resolve"));
|
||||
assert_eq!(decision.auth_endpoint_signature.as_deref(), Some(""));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_internal_tunnel_node_status_as_internal_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/internal/tunnel/node-status"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("internal_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some(crate::gateway::TUNNEL_ROUTE_FAMILY)
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("node_status"));
|
||||
assert_eq!(decision.auth_endpoint_signature.as_deref(), Some(""));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
88
apps/aether-gateway/src/control/tests/mod.rs
Normal file
88
apps/aether-gateway/src/control/tests/mod.rs
Normal file
@@ -0,0 +1,88 @@
|
||||
use super::*;
|
||||
|
||||
fn headers(items: &[(&str, &str)]) -> http::HeaderMap {
|
||||
let mut headers = http::HeaderMap::new();
|
||||
for (name, value) in items {
|
||||
headers.insert(
|
||||
http::header::HeaderName::from_bytes(name.as_bytes()).expect("valid header name"),
|
||||
http::HeaderValue::from_str(value).expect("valid header value"),
|
||||
);
|
||||
}
|
||||
headers
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builds_public_request_context_from_request_parts() {
|
||||
let mut headers = headers(&[
|
||||
(http::header::HOST.as_str(), "api.example.test"),
|
||||
(http::header::CONTENT_TYPE.as_str(), "application/json"),
|
||||
]);
|
||||
headers.insert("x-app", http::HeaderValue::from_static("gemini-cli"));
|
||||
let uri: Uri = "/v1beta/models/gemini-2.5-pro:generateContent?alt=sse"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::POST, &uri, &headers);
|
||||
|
||||
let context = GatewayPublicRequestContext::from_request_parts(
|
||||
"trace-123",
|
||||
&http::Method::POST,
|
||||
&uri,
|
||||
&headers,
|
||||
decision,
|
||||
);
|
||||
|
||||
assert_eq!(context.trace_id, "trace-123");
|
||||
assert_eq!(context.request_method, http::Method::POST);
|
||||
assert_eq!(
|
||||
context.request_path,
|
||||
"/v1beta/models/gemini-2.5-pro:generateContent"
|
||||
);
|
||||
assert_eq!(context.request_query_string.as_deref(), Some("alt=sse"));
|
||||
assert_eq!(
|
||||
context.request_path_and_query(),
|
||||
"/v1beta/models/gemini-2.5-pro:generateContent?alt=sse"
|
||||
);
|
||||
assert_eq!(
|
||||
context.request_content_type.as_deref(),
|
||||
Some("application/json")
|
||||
);
|
||||
assert_eq!(context.host_header.as_deref(), Some("api.example.test"));
|
||||
assert_eq!(
|
||||
context
|
||||
.control_decision
|
||||
.as_ref()
|
||||
.and_then(|value| value.route_family.as_deref()),
|
||||
Some("gemini")
|
||||
);
|
||||
assert_eq!(
|
||||
context
|
||||
.control_decision
|
||||
.as_ref()
|
||||
.and_then(|value| value.route_kind.as_deref()),
|
||||
Some("cli")
|
||||
);
|
||||
}
|
||||
|
||||
mod admin_adaptive;
|
||||
mod admin_api_keys;
|
||||
mod admin_billing;
|
||||
mod admin_core;
|
||||
mod admin_endpoints;
|
||||
mod admin_monitoring;
|
||||
mod admin_oauth;
|
||||
mod admin_payments;
|
||||
mod admin_pool;
|
||||
mod admin_provider_ops;
|
||||
mod admin_provider_query;
|
||||
mod admin_provider_strategy;
|
||||
mod admin_providers_models;
|
||||
mod admin_proxy_nodes;
|
||||
mod admin_security;
|
||||
mod admin_stats;
|
||||
mod admin_usage;
|
||||
mod admin_users;
|
||||
mod admin_video_tasks;
|
||||
mod admin_wallets;
|
||||
mod ai;
|
||||
mod internal;
|
||||
mod public_support;
|
||||
817
apps/aether-gateway/src/control/tests/public_support.rs
Normal file
817
apps/aether-gateway/src/control/tests/public_support.rs
Normal file
@@ -0,0 +1,817 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn classifies_models_list_as_public_support_route() {
|
||||
let headers = headers(&[("authorization", "Bearer sk-test")]);
|
||||
let uri: Uri = "/v1/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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("models"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("openai:chat")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_v1beta_models_as_gemini_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/v1beta/models?pageSize=10"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("models"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("gemini:chat")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_public_catalog_site_info_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/public/site-info".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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("public_catalog"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("site_info"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:catalog")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_public_announcement_list_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/announcements?limit=20"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("announcements"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:announcements")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_announcement_create_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/announcements".parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("announcements_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("create_announcement"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:announcements")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_announcement_update_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/announcements/announcement-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::PUT, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("announcements_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("update_announcement"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:announcements")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_admin_announcement_delete_as_admin_proxy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/announcements/announcement-1"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::DELETE, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("admin_proxy"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("announcements_manage")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("delete_announcement"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("admin:announcements")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_public_active_announcements_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/announcements/active"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("announcements"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("active"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:announcements")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_public_announcement_detail_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/announcements/announcement-1"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("announcements"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("detail"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:announcements")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_dashboard_stats_as_public_support_legacy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/dashboard/stats".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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("dashboard_legacy"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("user:dashboard")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_user_monitoring_audit_logs_as_public_support_legacy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/monitoring/my-audit-logs"
|
||||
.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("public_support"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("monitoring_user_legacy")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("audit_logs"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("user:monitoring")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_announcement_unread_count_as_public_support_legacy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/announcements/users/me/unread-count"
|
||||
.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("public_support"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("announcement_user_legacy")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("unread_count"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("user:announcements")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_announcement_read_status_as_public_support_legacy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/announcements/announcement-1/read-status"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision = classify_control_route(&http::Method::PATCH, &uri, &headers)
|
||||
.expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("public_support"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("announcement_user_legacy")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("read_status"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("user:announcements")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_announcement_read_all_as_public_support_legacy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/announcements/read-all"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("public_support"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("announcement_user_legacy")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("read_all"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("user:announcements")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_wallet_legacy_routes_as_public_support_legacy_route() {
|
||||
let headers = headers(&[]);
|
||||
for (method, uri, route_kind) in [
|
||||
(http::Method::GET, "/api/wallet/balance", "balance"),
|
||||
(
|
||||
http::Method::GET,
|
||||
"/api/wallet/transactions?limit=20",
|
||||
"transactions",
|
||||
),
|
||||
(http::Method::GET, "/api/wallet/flow?limit=20", "flow"),
|
||||
(http::Method::GET, "/api/wallet/today-cost", "today_cost"),
|
||||
(
|
||||
http::Method::GET,
|
||||
"/api/wallet/recharge?limit=20",
|
||||
"list_recharge_orders",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/wallet/recharge",
|
||||
"create_recharge_order",
|
||||
),
|
||||
(
|
||||
http::Method::GET,
|
||||
"/api/wallet/recharge/order-1",
|
||||
"recharge_detail",
|
||||
),
|
||||
(
|
||||
http::Method::GET,
|
||||
"/api/wallet/refunds?limit=20",
|
||||
"list_refunds",
|
||||
),
|
||||
(http::Method::POST, "/api/wallet/refunds", "create_refund"),
|
||||
(
|
||||
http::Method::GET,
|
||||
"/api/wallet/refunds/refund-1",
|
||||
"refund_detail",
|
||||
),
|
||||
] {
|
||||
let uri: Uri = uri.parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&method, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("wallet_legacy"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some(route_kind));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("user:wallet")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_users_me_legacy_routes_as_public_support_legacy_route() {
|
||||
let headers = headers(&[]);
|
||||
for (method, uri, route_kind) in [
|
||||
(http::Method::GET, "/api/users/me", "detail"),
|
||||
(http::Method::PUT, "/api/users/me", "update_detail"),
|
||||
(http::Method::PATCH, "/api/users/me/password", "password"),
|
||||
(http::Method::GET, "/api/users/me/sessions", "sessions"),
|
||||
(
|
||||
http::Method::DELETE,
|
||||
"/api/users/me/sessions/others",
|
||||
"sessions_others_delete",
|
||||
),
|
||||
(
|
||||
http::Method::PATCH,
|
||||
"/api/users/me/sessions/session-1",
|
||||
"session_update",
|
||||
),
|
||||
(
|
||||
http::Method::GET,
|
||||
"/api/users/me/api-keys/key-1",
|
||||
"api_key_detail",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/users/me/api-keys",
|
||||
"api_keys_create",
|
||||
),
|
||||
(
|
||||
http::Method::PUT,
|
||||
"/api/users/me/api-keys/key-1",
|
||||
"api_key_update",
|
||||
),
|
||||
(
|
||||
http::Method::PATCH,
|
||||
"/api/users/me/api-keys/key-1",
|
||||
"api_key_patch",
|
||||
),
|
||||
(
|
||||
http::Method::DELETE,
|
||||
"/api/users/me/api-keys/key-1",
|
||||
"api_key_delete",
|
||||
),
|
||||
(
|
||||
http::Method::PUT,
|
||||
"/api/users/me/api-keys/key-1/providers",
|
||||
"api_key_providers_update",
|
||||
),
|
||||
(
|
||||
http::Method::PUT,
|
||||
"/api/users/me/api-keys/key-1/capabilities",
|
||||
"api_key_capabilities_update",
|
||||
),
|
||||
(
|
||||
http::Method::GET,
|
||||
"/api/users/me/available-models",
|
||||
"available_models",
|
||||
),
|
||||
(
|
||||
http::Method::PUT,
|
||||
"/api/users/me/model-capabilities",
|
||||
"model_capabilities_update",
|
||||
),
|
||||
(
|
||||
http::Method::GET,
|
||||
"/api/me/management-tokens",
|
||||
"management_tokens_list",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/me/management-tokens",
|
||||
"management_tokens_create",
|
||||
),
|
||||
(
|
||||
http::Method::GET,
|
||||
"/api/me/management-tokens/token-1",
|
||||
"management_token_detail",
|
||||
),
|
||||
(
|
||||
http::Method::PUT,
|
||||
"/api/me/management-tokens/token-1",
|
||||
"management_token_update",
|
||||
),
|
||||
(
|
||||
http::Method::DELETE,
|
||||
"/api/me/management-tokens/token-1",
|
||||
"management_token_delete",
|
||||
),
|
||||
(
|
||||
http::Method::PATCH,
|
||||
"/api/me/management-tokens/token-1/status",
|
||||
"management_token_toggle",
|
||||
),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/me/management-tokens/token-1/regenerate",
|
||||
"management_token_regenerate",
|
||||
),
|
||||
] {
|
||||
let uri: Uri = uri.parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&method, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("users_me_legacy"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some(route_kind));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("user:self")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_payment_callback_as_public_support_legacy_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/payment/callback/alipay"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("public_support"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("payment_callback_legacy")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("callback"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:payment")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_public_catalog_providers_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/public/providers?limit=20"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("public_catalog"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("providers"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:catalog")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_public_catalog_models_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/public/models?provider_id=provider-openai"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("public_catalog"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("models"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:catalog")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_public_catalog_search_models_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/public/search/models?q=gpt"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("public_catalog"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("search_models"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:catalog")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_public_catalog_stats_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/public/stats".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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("public_catalog"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("stats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:catalog")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_public_catalog_global_models_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/public/global-models?limit=10"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("public_catalog"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("global_models"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:catalog")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_public_catalog_health_api_formats_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/public/health/api-formats?lookback_hours=12"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("public_catalog"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("health_api_formats"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:catalog")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_auth_registration_settings_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/auth/registration-settings"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("auth_public"));
|
||||
assert_eq!(
|
||||
decision.route_kind.as_deref(),
|
||||
Some("registration_settings")
|
||||
);
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:auth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_auth_settings_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/auth/settings".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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("auth_public"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("settings"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:auth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_auth_legacy_routes_as_public_support_route() {
|
||||
for (method, path, route_kind) in [
|
||||
(http::Method::POST, "/api/auth/login", "login"),
|
||||
(http::Method::POST, "/api/auth/refresh", "refresh"),
|
||||
(http::Method::POST, "/api/auth/register", "register"),
|
||||
(http::Method::GET, "/api/auth/me", "me"),
|
||||
(http::Method::POST, "/api/auth/logout", "logout"),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/auth/send-verification-code",
|
||||
"send_verification_code",
|
||||
),
|
||||
(http::Method::POST, "/api/auth/verify-email", "verify_email"),
|
||||
(
|
||||
http::Method::POST,
|
||||
"/api/auth/verification-status",
|
||||
"verification_status",
|
||||
),
|
||||
] {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = path.parse().expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&method, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("auth_legacy"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some(route_kind));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("user:auth")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_oauth_public_providers_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/oauth/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("public_support"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("oauth_public_legacy")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("providers"));
|
||||
assert_eq!(decision.auth_endpoint_signature.as_deref(), Some(""));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_oauth_public_authorize_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/oauth/linuxdo/authorize?client_device_id=device-1"
|
||||
.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("public_support"));
|
||||
assert_eq!(
|
||||
decision.route_family.as_deref(),
|
||||
Some("oauth_public_legacy")
|
||||
);
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("authorize"));
|
||||
assert_eq!(decision.auth_endpoint_signature.as_deref(), Some(""));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_oauth_user_bindable_providers_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/user/oauth/bindable-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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("oauth_user_legacy"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("bindable_providers"));
|
||||
assert_eq!(decision.auth_endpoint_signature.as_deref(), Some(""));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_oauth_user_bind_token_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/user/oauth/linuxdo/bind-token"
|
||||
.parse()
|
||||
.expect("uri should parse");
|
||||
let decision =
|
||||
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
|
||||
|
||||
assert_eq!(decision.route_class.as_deref(), Some("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("oauth_user_legacy"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("bind_token"));
|
||||
assert_eq!(decision.auth_endpoint_signature.as_deref(), Some(""));
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_capabilities_list_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/capabilities".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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("capabilities"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("list"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:capabilities")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_capabilities_user_configurable_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/capabilities/user-configurable"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("capabilities"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("user_configurable"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:capabilities")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_capabilities_model_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/capabilities/model/gpt-5"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("capabilities"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("model"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:capabilities")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_modules_auth_status_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/api/modules/auth-status"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("modules"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("auth_status"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:modules")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_system_catalog_provider_detail_as_public_support_route() {
|
||||
let headers = headers(&[]);
|
||||
let uri: Uri = "/v1/providers/provider-openai"
|
||||
.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("public_support"));
|
||||
assert_eq!(decision.route_family.as_deref(), Some("system_catalog"));
|
||||
assert_eq!(decision.route_kind.as_deref(), Some("provider_detail"));
|
||||
assert_eq!(
|
||||
decision.auth_endpoint_signature.as_deref(),
|
||||
Some("public:system_catalog")
|
||||
);
|
||||
assert!(!decision.is_execution_runtime_candidate());
|
||||
}
|
||||
Reference in New Issue
Block a user