Files
cms-service/tests/iam_client_expr.rs
2026-02-11 10:56:04 +08:00

69 lines
2.0 KiB
Rust

use std::sync::{
Arc,
atomic::{AtomicUsize, Ordering},
};
use std::time::Duration;
use axum::{Json, Router, routing::post};
use axum::response::IntoResponse;
use cms_service::infrastructure::iam_client::{IamClient, IamClientConfig};
use serde_json::Value;
async fn start_mock_iam(call_count: Arc<AtomicUsize>) -> (String, tokio::task::JoinHandle<()>) {
let app = Router::new().route(
"/api/v1/authorize/check-expr",
post(move |Json(body): Json<Value>| {
let call_count = call_count.clone();
async move {
call_count.fetch_add(1, Ordering::SeqCst);
let allowed = body.get("expr").is_some();
let resp = serde_json::json!({
"code": 0,
"message": "ok",
"data": { "allowed": allowed }
});
(axum::http::StatusCode::OK, Json(resp)).into_response()
}
}),
);
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = listener.local_addr().unwrap();
let base_url = format!("http://{}", addr);
let handle = tokio::spawn(async move {
axum::serve(listener, app).await.unwrap();
});
(base_url, handle)
}
#[tokio::test]
async fn iam_client_check_expr_hits_endpoint() {
let call_count = Arc::new(AtomicUsize::new(0));
let (base_url, handle) = start_mock_iam(call_count.clone()).await;
let client = IamClient::new(IamClientConfig {
base_url,
timeout: Duration::from_millis(500),
cache_ttl: Duration::from_secs(5),
cache_stale_if_error: Duration::from_secs(30),
cache_max_entries: 1000,
});
let tenant_id = uuid::Uuid::new_v4();
let user_id = uuid::Uuid::new_v4();
client
.require_any_permissions(
tenant_id,
user_id,
&["cms:article:edit", "cms:article:create"],
"token",
)
.await
.unwrap();
assert_eq!(call_count.load(Ordering::SeqCst), 1);
handle.abort();
}