Readur/src/tests/helpers.rs

151 lines
5.0 KiB
Rust

use crate::{AppState, models::UserResponse};
use axum::Router;
use serde_json::json;
use std::sync::Arc;
use testcontainers::{core::WaitFor, runners::AsyncRunner, ContainerAsync, GenericImage, ImageExt};
use testcontainers_modules::postgres::Postgres;
use tower::util::ServiceExt;
pub async fn create_test_app() -> (Router, ContainerAsync<Postgres>) {
let postgres_image = Postgres::default()
.with_tag("15-alpine")
.with_env_var("POSTGRES_USER", "test")
.with_env_var("POSTGRES_PASSWORD", "test")
.with_env_var("POSTGRES_DB", "test");
let container = postgres_image.start().await.expect("Failed to start postgres container");
let port = container.get_host_port_ipv4(5432).await.expect("Failed to get postgres port");
let database_url = format!("postgresql://test:test@localhost:{}/test", port);
let db = crate::db::Database::new(&database_url).await.unwrap();
db.migrate().await.unwrap();
let config = crate::config::Config {
database_url: database_url.clone(),
server_address: "127.0.0.1:0".to_string(),
jwt_secret: "test-secret".to_string(),
upload_path: "./test-uploads".to_string(),
watch_folder: "./test-watch".to_string(),
allowed_file_types: vec!["pdf".to_string(), "txt".to_string(), "png".to_string()],
watch_interval_seconds: Some(30),
file_stability_check_ms: Some(500),
max_file_age_hours: None,
// OCR Configuration
ocr_language: "eng".to_string(),
concurrent_ocr_jobs: 2, // Lower for tests
ocr_timeout_seconds: 60, // Shorter for tests
max_file_size_mb: 10, // Smaller for tests
// Performance
memory_limit_mb: 256, // Lower for tests
cpu_priority: "normal".to_string(),
// OIDC Configuration (disabled for tests)
oidc_enabled: false,
oidc_client_id: None,
oidc_client_secret: None,
oidc_issuer_url: None,
oidc_redirect_uri: None,
};
let queue_service = Arc::new(crate::ocr::queue::OcrQueueService::new(db.clone(), db.pool.clone(), 2));
let state = Arc::new(AppState {
db,
config,
webdav_scheduler: None,
source_scheduler: None,
queue_service,
oidc_client: None,
});
let app = Router::new()
.nest("/api/auth", crate::routes::auth::router())
.nest("/api/documents", crate::routes::documents::router())
.nest("/api/search", crate::routes::search::router())
.nest("/api/settings", crate::routes::settings::router())
.nest("/api/users", crate::routes::users::router())
.with_state(state);
(app, container)
}
pub async fn create_test_user(app: &Router) -> UserResponse {
let user_data = json!({
"username": "testuser",
"email": "test@example.com",
"password": "password123"
});
let response = app
.clone()
.oneshot(
axum::http::Request::builder()
.method("POST")
.uri("/api/auth/register")
.header("Content-Type", "application/json")
.body(axum::body::Body::from(serde_json::to_vec(&user_data).unwrap()))
.unwrap(),
)
.await
.unwrap();
let body = axum::body::to_bytes(response.into_body(), usize::MAX)
.await
.unwrap();
serde_json::from_slice(&body).unwrap()
}
pub async fn create_admin_user(app: &Router) -> UserResponse {
let admin_data = json!({
"username": "adminuser",
"email": "admin@example.com",
"password": "adminpass123",
"role": "admin"
});
let response = app
.clone()
.oneshot(
axum::http::Request::builder()
.method("POST")
.uri("/api/auth/register")
.header("Content-Type", "application/json")
.body(axum::body::Body::from(serde_json::to_vec(&admin_data).unwrap()))
.unwrap(),
)
.await
.unwrap();
let body = axum::body::to_bytes(response.into_body(), usize::MAX)
.await
.unwrap();
serde_json::from_slice(&body).unwrap()
}
pub async fn login_user(app: &Router, username: &str, password: &str) -> String {
let login_data = json!({
"username": username,
"password": password
});
let response = app
.clone()
.oneshot(
axum::http::Request::builder()
.method("POST")
.uri("/api/auth/login")
.header("Content-Type", "application/json")
.body(axum::body::Body::from(serde_json::to_vec(&login_data).unwrap()))
.unwrap(),
)
.await
.unwrap();
let body = axum::body::to_bytes(response.into_body(), usize::MAX)
.await
.unwrap();
let login_response: serde_json::Value = serde_json::from_slice(&body).unwrap();
login_response["token"].as_str().unwrap().to_string()
}