use reqwest::Client; use rhythm_backend::{ controller, state::AppState, }; use axum::Router; use sqlx::PgPool; use std::sync::Arc; use dashmap::DashMap; async fn setup_app() -> (Router, PgPool) { let db_url = "postgres://user:password@localhost:5432/rhythm-dev?sslmode=disable"; let db = PgPool::connect(db_url) .await .expect("Failed to connect to Postgres at localhost:5432"); // Run migrations sqlx::migrate!("./migrations") .run(&db) .await .expect("Failed to run migrations"); let state = AppState { db: db.clone(), jwt_secret: "test-secret-key-12345678901234567890".to_string(), rate_limit: Arc::new(DashMap::new()), }; let app = controller::router(state.clone()).with_state(state); (app, db) } #[tokio::test] async fn test_register_and_login() { let (app, _db) = setup_app().await; // Start the server on a random port let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap(); let port = listener.local_addr().unwrap().port(); tokio::spawn(async move { axum::serve(listener, app.into_make_service()).await.unwrap(); }); // Give server a moment to start tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; let base_url = format!("http://127.0.0.1:{}", port); let client = Client::new(); // Use a unique email so we don't conflict with previous test runs let unique_email = format!("testuser_{}@test.com", uuid::Uuid::new_v4()); // Test 1: Register let reg_resp = client .post(format!("{}/api/v1/auth/register", base_url)) .json(&serde_json::json!({ "email": unique_email, "password": "SuperSecureP@ssw0rd2024!" })) .send() .await .unwrap(); println!("Register status: {}", reg_resp.status()); assert!( reg_resp.status().is_success(), "Register should succeed: {}", reg_resp.text().await.unwrap_or_default() ); // Test 2: Login with correct password let login_resp = client .post(format!("{}/api/v1/auth/login", base_url)) .json(&serde_json::json!({ "email": unique_email, "password": "SuperSecureP@ssw0rd2024!" })) .send() .await .unwrap(); println!("Login status: {}", login_resp.status()); assert!(login_resp.status().is_success(), "Login should succeed with correct password: {}", login_resp.text().await.unwrap_or_default()); let body: serde_json::Value = login_resp.json().await.unwrap(); assert!(body.get("access_token").is_some(), "Login response should have access_token"); // Test 3: Login with wrong password let bad_login = client .post(format!("{}/api/v1/auth/login", base_url)) .json(&serde_json::json!({ "email": unique_email, "password": "WrongPassword1!" })) .send() .await .unwrap(); println!("Bad login status: {}", bad_login.status()); assert_eq!(bad_login.status(), 401, "Login with wrong password should return 401"); }