Files
iven 5fdf96c3f5 chore: 提交所有工作进度 — SaaS 后端增强、Admin UI、桌面端集成
包含大量 SaaS 平台改进、Admin 管理后台更新、桌面端集成完善、
文档同步、测试文件重构等内容。为 QA 测试准备干净工作树。
2026-03-29 10:46:41 +08:00

171 lines
6.7 KiB
Rust

mod common;
use axum::http::StatusCode;
use common::*;
// ═══════════════════════════════════════════════════════════════════
// Role listing
// ═══════════════════════════════════════════════════════════════════
#[tokio::test]
async fn list_roles_includes_system_roles() {
let (app, pool) = build_test_app().await;
let admin = admin_token(&app, &pool, "roleadmin").await;
let (status, body) = send(&app, get("/api/v1/roles", &admin)).await;
assert_eq!(status, StatusCode::OK);
let roles = body.as_array().unwrap();
let ids: Vec<&str> = roles.iter().map(|r| r["id"].as_str().unwrap()).collect();
assert!(ids.contains(&"super_admin"));
assert!(ids.contains(&"admin"));
assert!(ids.contains(&"user"));
}
// ═══════════════════════════════════════════════════════════════════
// Role CRUD
// ═══════════════════════════════════════════════════════════════════
#[tokio::test]
async fn role_crud() {
let (app, pool) = build_test_app().await;
let admin = admin_token(&app, &pool, "rolecrud").await;
// Create custom role
let (status, body) = send(
&app,
post(
"/api/v1/roles",
&admin,
serde_json::json!({
"id": "custom-role-1",
"name": "Custom Role",
"description": "A test role",
"permissions": ["model:read", "relay:use"]
}),
),
).await;
assert_eq!(status, StatusCode::CREATED, "create role: {body}");
// Get
let (status, body) = send(&app, get("/api/v1/roles/custom-role-1", &admin)).await;
assert_eq!(status, StatusCode::OK);
assert_eq!(body["name"], "Custom Role");
// Update
let (status, body) = send(
&app,
put(
"/api/v1/roles/custom-role-1",
&admin,
serde_json::json!({ "description": "Updated description" }),
),
).await;
assert_eq!(status, StatusCode::OK);
assert_eq!(body["description"], "Updated description");
// Delete custom role
let (status, _) = send(&app, delete("/api/v1/roles/custom-role-1", &admin)).await;
assert_eq!(status, StatusCode::OK);
}
// ═══════════════════════════════════════════════════════════════════
// System role protection
// ═══════════════════════════════════════════════════════════════════
#[tokio::test]
async fn cannot_delete_system_role() {
let (app, pool) = build_test_app().await;
let admin = admin_token(&app, &pool, "sysrole").await;
let (status, _) = send(&app, delete("/api/v1/roles/super_admin", &admin)).await;
assert_ne!(status, StatusCode::OK);
}
// ═══════════════════════════════════════════════════════════════════
// Role creation forbidden for regular user
// ═══════════════════════════════════════════════════════════════════
#[tokio::test]
async fn role_create_forbidden_for_user() {
let (app, _pool) = build_test_app().await;
let token = register_token(&app, "rolenouser").await;
let (status, _) = send(
&app,
post(
"/api/v1/roles",
&token,
serde_json::json!({ "id": "x", "name": "X", "permissions": [] }),
),
).await;
assert_eq!(status, StatusCode::FORBIDDEN);
}
// ═══════════════════════════════════════════════════════════════════
// Permission templates
// ═══════════════════════════════════════════════════════════════════
#[tokio::test]
async fn permission_template_crud() {
let (app, pool) = build_test_app().await;
let admin = admin_token(&app, &pool, "tmpladmin").await;
// Create template
let (status, body) = send(
&app,
post(
"/api/v1/permission-templates",
&admin,
serde_json::json!({
"name": "Read-Only Template",
"description": "Only read access",
"permissions": ["model:read", "config:read", "prompt:read"]
}),
),
).await;
assert_eq!(status, StatusCode::CREATED, "create template: {body}");
let tmpl_id = body["id"].as_str().unwrap();
// List templates
let (status, list) = send(&app, get("/api/v1/permission-templates", &admin)).await;
assert_eq!(status, StatusCode::OK);
assert!(list.is_array());
// Get template
let (status, _) = send(&app, get(&format!("/api/v1/permission-templates/{tmpl_id}"), &admin)).await;
assert_eq!(status, StatusCode::OK);
// Delete template
let (status, _) = send(&app, delete(&format!("/api/v1/permission-templates/{tmpl_id}"), &admin)).await;
assert_eq!(status, StatusCode::OK);
}
#[tokio::test]
async fn apply_permission_template() {
let (app, pool) = build_test_app().await;
let admin = admin_token(&app, &pool, "applyadmin").await;
// Create template
let (_, tmpl_body) = send(
&app,
post(
"/api/v1/permission-templates",
&admin,
serde_json::json!({ "name": "Apply Test", "permissions": ["model:read"] }),
),
).await;
let tmpl_id = tmpl_body["id"].as_str().unwrap();
// Create a target user
let (_, _, reg) = register(&app, "targetuser", "target@test.io", DEFAULT_PASSWORD).await;
let target_id = reg["account"]["id"].as_str().unwrap();
// Apply template
let (status, _) = send(
&app,
post(
&format!("/api/v1/permission-templates/{tmpl_id}/apply"),
&admin,
serde_json::json!({ "account_ids": [target_id] }),
),
).await;
assert_eq!(status, StatusCode::OK);
}