mirror of
https://github.com/perstarkse/minne.git
synced 2026-05-31 03:40:38 +02:00
168 lines
4.4 KiB
Rust
168 lines
4.4 KiB
Rust
#![allow(clippy::expect_used)]
|
|
|
|
use std::sync::Arc;
|
|
|
|
use api_router::{api_routes_v1, api_state::ApiState};
|
|
use axum::{
|
|
body::{to_bytes, Body},
|
|
http::{Request, StatusCode},
|
|
Router,
|
|
};
|
|
use common::{
|
|
storage::{
|
|
db::SurrealDbClient,
|
|
store::StorageManager,
|
|
types::user::User,
|
|
},
|
|
utils::config::{AppConfig, StorageKind},
|
|
};
|
|
use tower::ServiceExt;
|
|
|
|
async fn build_test_app() -> (Router, Arc<SurrealDbClient>) {
|
|
let namespace = "api_router_test";
|
|
let database = uuid::Uuid::new_v4().to_string();
|
|
let db = Arc::new(
|
|
SurrealDbClient::memory(namespace, &database)
|
|
.await
|
|
.expect("in-memory db"),
|
|
);
|
|
db.apply_migrations()
|
|
.await
|
|
.expect("migrations should apply");
|
|
|
|
let config = AppConfig {
|
|
storage: StorageKind::Memory,
|
|
..Default::default()
|
|
};
|
|
let storage = StorageManager::new(&config)
|
|
.await
|
|
.expect("storage manager");
|
|
|
|
let state = ApiState {
|
|
db: Arc::clone(&db),
|
|
config,
|
|
storage,
|
|
};
|
|
|
|
let router = api_routes_v1(&state).with_state(state);
|
|
|
|
(router, db)
|
|
}
|
|
|
|
async fn response_body(response: axum::response::Response) -> String {
|
|
let body = to_bytes(response.into_body(), usize::MAX)
|
|
.await
|
|
.expect("response body");
|
|
String::from_utf8(body.to_vec()).expect("utf-8 body")
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn live_probe_is_public() {
|
|
let (app, _db) = build_test_app().await;
|
|
|
|
let response = app
|
|
.clone()
|
|
.oneshot(
|
|
Request::builder()
|
|
.uri("/live")
|
|
.body(Body::empty())
|
|
.expect("live request"),
|
|
)
|
|
.await
|
|
.expect("live response");
|
|
|
|
assert_eq!(response.status(), StatusCode::OK);
|
|
assert!(response_body(response).await.contains("\"status\":\"ok\""));
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn ready_probe_is_public_and_reports_db_ok() {
|
|
let (app, _db) = build_test_app().await;
|
|
|
|
let response = app
|
|
.clone()
|
|
.oneshot(
|
|
Request::builder()
|
|
.uri("/ready")
|
|
.body(Body::empty())
|
|
.expect("ready request"),
|
|
)
|
|
.await
|
|
.expect("ready response");
|
|
|
|
assert_eq!(response.status(), StatusCode::OK);
|
|
let body = response_body(response).await;
|
|
assert!(body.contains("\"checks\":{\"db\":\"ok\"}") || body.contains("\"db\":\"ok\""));
|
|
assert!(!body.contains("reason"));
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn protected_route_requires_api_key() {
|
|
let (app, _db) = build_test_app().await;
|
|
|
|
let response = app
|
|
.clone()
|
|
.oneshot(
|
|
Request::builder()
|
|
.uri("/categories")
|
|
.body(Body::empty())
|
|
.expect("categories request"),
|
|
)
|
|
.await
|
|
.expect("categories response");
|
|
|
|
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn protected_route_rejects_invalid_api_key() {
|
|
let (app, _db) = build_test_app().await;
|
|
|
|
let response = app
|
|
.clone()
|
|
.oneshot(
|
|
Request::builder()
|
|
.uri("/categories")
|
|
.header("X-API-Key", "sk_invalid")
|
|
.body(Body::empty())
|
|
.expect("categories request"),
|
|
)
|
|
.await
|
|
.expect("categories response");
|
|
|
|
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn authenticated_user_can_list_categories() {
|
|
let (app, db) = build_test_app().await;
|
|
|
|
let user = User::create_new(
|
|
"api_router_test@example.com".to_string(),
|
|
"test_password".to_string(),
|
|
&db,
|
|
"UTC".to_string(),
|
|
"system".to_string(),
|
|
)
|
|
.await
|
|
.expect("test user");
|
|
|
|
let api_key = User::set_api_key(&user.id, &db)
|
|
.await
|
|
.expect("api key");
|
|
|
|
let response = app
|
|
.clone()
|
|
.oneshot(
|
|
Request::builder()
|
|
.uri("/categories")
|
|
.header("X-API-Key", api_key)
|
|
.body(Body::empty())
|
|
.expect("categories request"),
|
|
)
|
|
.await
|
|
.expect("categories response");
|
|
|
|
assert_eq!(response.status(), StatusCode::OK);
|
|
}
|