Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- Fix usage_stats SQL: add ::timestamptz cast for Option<String> params - Fix usage_stats SQL: add ::bigint cast for COALESCE(SUM(...)) - Fix telemetry INSERT: add ::timestamptz cast for reported_at column - Fix config_analysis_empty test: seed data makes total_items > 0 - Fix key_pool_crud test: key_value must be >= 20 chars - Fix SkillManifest test helpers: add missing tools field All 1048 tests pass: 580 Rust + 138 SaaS + 330 Desktop Vitest
135 lines
4.7 KiB
Rust
135 lines
4.7 KiB
Rust
mod common;
|
|
|
|
use axum::http::StatusCode;
|
|
use common::*;
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Relay models list
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn relay_models_list_empty() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "relaylist").await;
|
|
let (status, body) = send(&app, get("/api/v1/relay/models", &token)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
assert!(body.is_array());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn relay_chat_nonexistent_model() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "relaychat").await;
|
|
let (status, _) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/relay/chat/completions",
|
|
&token,
|
|
serde_json::json!({
|
|
"model": "nonexistent-model",
|
|
"messages": [{ "role": "user", "content": "hello" }]
|
|
}),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::NOT_FOUND);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn relay_tasks_list() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "relaytasks").await;
|
|
let (status, body) = send(&app, get("/api/v1/relay/tasks", &token)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn relay_task_get_nonexistent() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "relayget").await;
|
|
let (status, _) = send(&app, get("/api/v1/relay/tasks/nonexistent-id", &token)).await;
|
|
assert_eq!(status, StatusCode::NOT_FOUND);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn relay_retry_forbidden_for_user() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "retryuser").await;
|
|
let (status, _) = send(
|
|
&app,
|
|
post("/api/v1/relay/tasks/nonexistent/retry", &token, serde_json::json!({})),
|
|
).await;
|
|
// 404 (task not found) or 403 (forbidden) — either way not 200
|
|
assert_ne!(status, StatusCode::OK);
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Key pool management
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn key_pool_crud() {
|
|
let (app, pool) = build_test_app().await;
|
|
let admin = admin_token(&app, &pool, "kpooladmin").await;
|
|
|
|
// Create provider
|
|
let (_, prov) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/providers",
|
|
&admin,
|
|
serde_json::json!({ "name": "kpool-prov", "display_name": "KPool", "base_url": "https://api.kpool.com/v1" }),
|
|
),
|
|
).await;
|
|
let provider_id = prov["id"].as_str().unwrap();
|
|
|
|
// Add key to pool
|
|
let (status, body) = send(
|
|
&app,
|
|
post(
|
|
&format!("/api/v1/providers/{provider_id}/keys"),
|
|
&admin,
|
|
serde_json::json!({ "key_label": "Pool Key 1", "key_value": "sk-pool-key-001-abcdefg", "priority": 0 }),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::OK, "add key to pool: {body}");
|
|
let key_id = body["key_id"].as_str().unwrap();
|
|
|
|
// List pool keys
|
|
let (status, keys) = send(&app, get(&format!("/api/v1/providers/{provider_id}/keys"), &admin)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
assert!(keys.is_array());
|
|
|
|
// Toggle key
|
|
let (status, _) = send(
|
|
&app,
|
|
put(
|
|
&format!("/api/v1/providers/{provider_id}/keys/{key_id}/toggle"),
|
|
&admin,
|
|
serde_json::json!({ "active": false }),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
|
|
// Delete key
|
|
let (status, _) = send(
|
|
&app,
|
|
delete(&format!("/api/v1/providers/{provider_id}/keys/{key_id}"), &admin),
|
|
).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn key_pool_forbidden_for_user() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "kpooluser").await;
|
|
let (status, _) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/providers/nonexistent/keys",
|
|
&token,
|
|
serde_json::json!({ "key_label": "X", "key_value": "sk-x" }),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::FORBIDDEN);
|
|
}
|