use axum::{Router, routing::get}; use axum_test::{TestServer, TestServerConfig, Transport}; use hurl::runner::{self, RunnerOptions, Value, VariableSet}; use hurl::util::logger::LoggerOptionsBuilder; async fn create_app() -> Router { use backend::database::{DatabaseConfig, create_pool}; use backend::services; // Use in-memory SQLite for tests let config = DatabaseConfig { database_url: "sqlite::memory:".to_string(), }; let pool = create_pool(&config) .await .expect("Failed to create test database pool"); // Run migrations on in-memory database sqlx::migrate!("./migrations") .run(&pool) .await .expect("Failed to run migrations"); Router::new() .route("/health", get(health)) .nest("/api/tasks", services::create_task_router()) .with_state(pool) } async fn health() -> &'static str { "Ok" } async fn run_hurl_test(hurl_file_path: &str) { let app = create_app().await; let config = TestServerConfig { transport: Some(Transport::HttpRandomPort), ..TestServerConfig::default() }; let server = TestServer::new_with_config(app, config).unwrap(); let address = server.server_address().unwrap(); let host = address.as_str().strip_suffix("/").unwrap(); let content = std::fs::read_to_string(hurl_file_path).unwrap(); let mut variables = VariableSet::new(); variables.insert("host".to_string(), Value::String(host.to_string())); let runner_opts = RunnerOptions::default(); let logger_opts = LoggerOptionsBuilder::new().build(); let result = runner::run(&content, None, &runner_opts, &variables, &logger_opts).unwrap(); assert!( result.success, "Hurl test failed for {}: {:?}", hurl_file_path, result ); } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_tasks_api() { run_hurl_test("./tests/api/tasks.hurl").await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_list_tasks_api() { run_hurl_test("./tests/api/list_tasks.hurl").await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_update_tasks_api() { run_hurl_test("./tests/api/update_tasks.hurl").await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_delete_tasks_api() { run_hurl_test("./tests/api/delete_tasks.hurl").await; }