175 lines
7.5 KiB
Rust
175 lines
7.5 KiB
Rust
mod common;
|
|
|
|
use axum::http::StatusCode;
|
|
use common::*;
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Config analysis
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn config_analysis_empty() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "cfganalyze").await;
|
|
let (status, body) = send(&app, get("/api/v1/config/analysis", &token)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
assert_eq!(body["total_items"], 0);
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Config items CRUD
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn config_items_crud() {
|
|
let (app, pool) = build_test_app().await;
|
|
let admin = admin_token(&app, &pool, "cfgadmin").await;
|
|
|
|
// Create config item
|
|
let (status, body) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/config/items",
|
|
&admin,
|
|
serde_json::json!({
|
|
"category": "server",
|
|
"key_path": "server.host",
|
|
"value_type": "string",
|
|
"current_value": "0.0.0.0",
|
|
"description": "Server bind address"
|
|
}),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::CREATED, "create config item: {body}");
|
|
let item_id = body["id"].as_str().unwrap();
|
|
|
|
// List
|
|
let (status, list) = send(&app, get("/api/v1/config/items", &admin)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
assert!(list.is_array() || list["items"].is_array());
|
|
|
|
// Get
|
|
let (status, body) = send(&app, get(&format!("/api/v1/config/items/{item_id}"), &admin)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
assert_eq!(body["key_path"], "server.host");
|
|
|
|
// Update
|
|
let (status, body) = send(
|
|
&app,
|
|
put(
|
|
&format!("/api/v1/config/items/{item_id}"),
|
|
&admin,
|
|
serde_json::json!({ "current_value": "127.0.0.1" }),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
assert_eq!(body["current_value"], "127.0.0.1");
|
|
|
|
// Delete
|
|
let (status, _) = send(&app, delete(&format!("/api/v1/config/items/{item_id}"), &admin)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn config_items_write_forbidden_for_user() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "cfguser").await;
|
|
let (status, _) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/config/items",
|
|
&token,
|
|
serde_json::json!({ "category": "x", "key_path": "y", "value_type": "string" }),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::FORBIDDEN);
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Config seed
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn config_seed_admin_only() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let user_token = register_token(&app, "cfgseeduser").await;
|
|
let (status, _) = send(&app, post("/api/v1/config/seed", &user_token, serde_json::json!({}))).await;
|
|
assert_eq!(status, StatusCode::FORBIDDEN);
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Config sync (push)
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn config_sync_push() {
|
|
let (app, pool) = build_test_app().await;
|
|
let admin = admin_token(&app, &pool, "cfgsync").await;
|
|
let (status, body) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/config/sync",
|
|
&admin,
|
|
serde_json::json!({
|
|
"client_fingerprint": "test-desktop-v1",
|
|
"action": "push",
|
|
"config_keys": ["server.host", "server.port"],
|
|
"client_values": { "server.host": "192.168.1.1", "server.port": "9090" }
|
|
}),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::OK, "config sync push: {body}");
|
|
// Push mode: keys don't exist in SaaS → auto-created
|
|
assert_eq!(body["created"], 2);
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Config diff
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn config_diff() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "cfgdiff").await;
|
|
let (status, body) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/config/diff",
|
|
&token,
|
|
serde_json::json!({
|
|
"client_fingerprint": "test-client",
|
|
"action": "push",
|
|
"config_keys": ["server.host"],
|
|
"client_values": { "server.host": "0.0.0.0" }
|
|
}),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
assert_eq!(body["total_keys"], 1);
|
|
assert!(body["items"].is_array());
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Config sync logs
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn config_sync_logs() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "cfglogs").await;
|
|
let (status, _) = send(&app, get("/api/v1/config/sync-logs", &token)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Config pull
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn config_pull_empty() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "cfgpull").await;
|
|
let (status, _) = send(&app, get("/api/v1/config/pull", &token)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
}
|