chore: 提交所有工作进度 — SaaS 后端增强、Admin UI、桌面端集成
包含大量 SaaS 平台改进、Admin 管理后台更新、桌面端集成完善、 文档同步、测试文件重构等内容。为 QA 测试准备干净工作树。
This commit is contained in:
174
crates/zclaw-saas/tests/prompt_test.rs
Normal file
174
crates/zclaw-saas/tests/prompt_test.rs
Normal file
@@ -0,0 +1,174 @@
|
||||
mod common;
|
||||
|
||||
use axum::http::StatusCode;
|
||||
use common::*;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// OTA check
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn prompt_ota_check() {
|
||||
let (app, _pool) = build_test_app().await;
|
||||
let token = register_token(&app, "otacheck").await;
|
||||
let (status, body) = send(
|
||||
&app,
|
||||
post(
|
||||
"/api/v1/prompts/check",
|
||||
&token,
|
||||
serde_json::json!({
|
||||
"device_id": "test-device-001",
|
||||
"versions": { "reflection": 0, "compaction": 0, "extraction": 0 }
|
||||
}),
|
||||
),
|
||||
).await;
|
||||
assert_eq!(status, StatusCode::OK);
|
||||
assert!(body["updates"].is_array());
|
||||
assert!(body["server_time"].is_string());
|
||||
// 3 builtin templates should have updates
|
||||
assert_eq!(body["updates"].as_array().unwrap().len(), 3);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Prompt list (admin only)
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn prompt_list_requires_permission() {
|
||||
let (app, _pool) = build_test_app().await;
|
||||
let token = register_token(&app, "promptuser").await;
|
||||
let (status, _) = send(&app, get("/api/v1/prompts", &token)).await;
|
||||
// Regular user has prompt:read via user role → may succeed or fail based on permissions
|
||||
// User role has prompt:read → should succeed
|
||||
assert_eq!(status, StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn prompt_list_shows_builtins() {
|
||||
let (app, pool) = build_test_app().await;
|
||||
let admin = admin_token(&app, &pool, "promptlist").await;
|
||||
let (status, body) = send(&app, get("/api/v1/prompts", &admin)).await;
|
||||
assert_eq!(status, StatusCode::OK);
|
||||
let items = body["items"].as_array().unwrap_or_else(|| {
|
||||
// Fallback: some handlers may return bare array
|
||||
body.as_array().unwrap()
|
||||
});
|
||||
assert!(items.len() >= 3, "should have 3 builtin templates, got {}: {body}", items.len());
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Prompt CRUD
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn prompt_create_and_get() {
|
||||
let (app, pool) = build_test_app().await;
|
||||
let admin = admin_token(&app, &pool, "promptcreate").await;
|
||||
|
||||
// Create
|
||||
let (status, body) = send(
|
||||
&app,
|
||||
post(
|
||||
"/api/v1/prompts",
|
||||
&admin,
|
||||
serde_json::json!({
|
||||
"name": "test-prompt",
|
||||
"category": "test",
|
||||
"description": "A test prompt",
|
||||
"system_prompt": "You are a test assistant.",
|
||||
"user_prompt_template": "Hello {{name}}",
|
||||
"variables": [{ "name": "name", "required": true }]
|
||||
}),
|
||||
),
|
||||
).await;
|
||||
assert_eq!(status, StatusCode::OK, "create prompt: {body}");
|
||||
|
||||
// Get by name
|
||||
let (status, body) = send(&app, get("/api/v1/prompts/test-prompt", &admin)).await;
|
||||
assert_eq!(status, StatusCode::OK);
|
||||
assert_eq!(body["name"], "test-prompt");
|
||||
|
||||
// Update metadata
|
||||
let (status, body) = send(
|
||||
&app,
|
||||
put(
|
||||
"/api/v1/prompts/test-prompt",
|
||||
&admin,
|
||||
serde_json::json!({ "description": "Updated description" }),
|
||||
),
|
||||
).await;
|
||||
assert_eq!(status, StatusCode::OK);
|
||||
assert_eq!(body["description"], "Updated description");
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Prompt versions
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn prompt_version_publish_and_list() {
|
||||
let (app, pool) = build_test_app().await;
|
||||
let admin = admin_token(&app, &pool, "promptver").await;
|
||||
|
||||
// Create template first
|
||||
send(
|
||||
&app,
|
||||
post(
|
||||
"/api/v1/prompts",
|
||||
&admin,
|
||||
serde_json::json!({
|
||||
"name": "versioned-prompt",
|
||||
"category": "test",
|
||||
"system_prompt": "Version 1 system prompt"
|
||||
}),
|
||||
),
|
||||
).await;
|
||||
|
||||
// Publish a new version
|
||||
let (status, body) = send(
|
||||
&app,
|
||||
post(
|
||||
"/api/v1/prompts/versioned-prompt/versions",
|
||||
&admin,
|
||||
serde_json::json!({
|
||||
"system_prompt": "Version 2 system prompt",
|
||||
"changelog": "Updated for testing"
|
||||
}),
|
||||
),
|
||||
).await;
|
||||
assert_eq!(status, StatusCode::OK, "publish version: {body}");
|
||||
|
||||
// List versions
|
||||
let (status, body) = send(&app, get("/api/v1/prompts/versioned-prompt/versions", &admin)).await;
|
||||
assert_eq!(status, StatusCode::OK);
|
||||
assert!(body.is_array());
|
||||
assert!(body.as_array().unwrap().len() >= 2);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Prompt archive
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn prompt_archive() {
|
||||
let (app, pool) = build_test_app().await;
|
||||
let sa = super_admin_token(&app, &pool, "promptarchive").await;
|
||||
|
||||
// Create
|
||||
send(
|
||||
&app,
|
||||
post(
|
||||
"/api/v1/prompts",
|
||||
&sa,
|
||||
serde_json::json!({
|
||||
"name": "to-archive",
|
||||
"category": "test",
|
||||
"system_prompt": "Will be archived"
|
||||
}),
|
||||
),
|
||||
).await;
|
||||
|
||||
// Archive (delete)
|
||||
let (status, _) = send(&app, delete("/api/v1/prompts/to-archive", &sa)).await;
|
||||
assert_eq!(status, StatusCode::OK);
|
||||
}
|
||||
Reference in New Issue
Block a user