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", "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); }