#![allow(dead_code)]
use std::sync::OnceLock;
use axum::Router;
use chrono::Utc;
use serde_json::{Value, json};
use tempfile::TempDir;
use course_service::{
api::rest::{AppState, create_router},
config::Config,
db::create_connection,
matching::CourseMatcher,
search::SearchEngine,
};
fn index_dir() -> &'static TempDir {
static DIR: OnceLock<TempDir> = OnceLock::new();
DIR.get_or_init(|| TempDir::new().expect("create search index dir"))
}
pub async fn create_test_app_state() -> AppState {
let mut config = Config::from_env().expect("load test config from env");
config.search.index_path = index_dir().path().to_string_lossy().into_owned();
let db = create_connection(&config.database)
.await
.expect(
"Postgres connection failed — set DATABASE_URL to a running, migrated DB before \
running integration tests",
);
let search_engine = SearchEngine::new(&config.search.index_path)
.expect("create Tantivy search engine");
let matcher = CourseMatcher::new(config.matching.clone());
AppState::new(db, search_engine, matcher, config)
}
pub async fn create_test_router() -> Router {
let state = create_test_app_state().await;
create_router(state)
}
pub fn unique_name(suffix: &str) -> String {
let ts = Utc::now().timestamp_micros();
format!("Integration {suffix} {ts}")
}
pub fn course_json(suffix: &str) -> Value {
json!({
"id": "00000000-0000-0000-0000-000000000000",
"name": unique_name(suffix),
"course_code": "TEST101",
"status": "published",
})
}