diff --git a/src/errors.rs b/src/errors.rs index 6b5cfaa..989a73f 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -131,7 +131,7 @@ fn map_handler_error(err: HandlerError) -> (StatusCode, String) { }, HandlerError::Referral(err) => match err { - ReferralHandlerError::ReferralNotFound(err) => (StatusCode::NOT_FOUND, err), + ReferralHandlerError::ReferralNotFound(err) => (StatusCode::OK, err), ReferralHandlerError::InvalidReferral(err) => (StatusCode::BAD_REQUEST, err), ReferralHandlerError::DuplicateReferral(err) => (StatusCode::CONFLICT, err), }, @@ -141,7 +141,7 @@ fn map_handler_error(err: HandlerError) -> (StatusCode, String) { fn map_db_error(err: DbError) -> (StatusCode, String) { match err { DbError::UniqueViolation(err) => (StatusCode::CONFLICT, err), - DbError::RecordNotFound(err) | DbError::AddressNotFound(err) => (StatusCode::NOT_FOUND, err), + DbError::RecordNotFound(err) | DbError::AddressNotFound(err) => (StatusCode::OK, err), DbError::Database(err) => { error!("Database error: {}", err); diff --git a/src/handlers/auth.rs b/src/handlers/auth.rs index effc21e..994d707 100644 --- a/src/handlers/auth.rs +++ b/src/handlers/auth.rs @@ -12,7 +12,6 @@ use tower_cookies::{Cookie, Cookies}; use uuid::Uuid; use crate::{ - db_persistence::DbError, handlers::{HandlerError, SuccessResponse}, http_server::{AppState, Challenge}, models::{ @@ -293,9 +292,8 @@ pub async fn handle_admin_login( .admin .find_by_username(&body.username) .await? - .ok_or(AppError::Database(DbError::RecordNotFound(format!( - "Admin with username {} is not exist", - &body.username, + .ok_or(AppError::Handler(HandlerError::Auth(AuthHandlerError::Unauthorized( + "Invalid username or password".to_string(), ))))?; let parsed_hash = @@ -342,7 +340,7 @@ mod tests { use std::sync::Arc; use crate::{ - handlers::auth::handle_x_oauth_callback, + handlers::auth::{handle_admin_login, handle_x_oauth_callback}, http_server::AppState, models::x_association::XAssociation, routes::auth::auth_routes, @@ -351,7 +349,7 @@ mod tests { test_db::{create_persisted_address, reset_database}, }, }; - use axum::{body::Body, http, routing::get}; + use axum::{body::Body, http, routing::get, routing::post}; use rusx::{ auth::TwitterToken, resources::{ @@ -607,4 +605,37 @@ mod tests { .unwrap(); assert_eq!(resp.status(), http::StatusCode::OK); } + + #[tokio::test] + async fn test_admin_login_nonexistent_username_returns_401() { + let state = create_test_app_state().await; + reset_database(&state.db.pool).await; + + let router = axum::Router::new() + .route("/auth/admin/login", post(handle_admin_login)) + .with_state(state); + + let payload = serde_json::json!({ + "username": "nonexistent_admin", + "password": "any_password" + }); + + let response = router + .oneshot( + http::Request::builder() + .method("POST") + .uri("/auth/admin/login") + .header(http::header::CONTENT_TYPE, "application/json") + .body(Body::from(serde_json::to_vec(&payload).unwrap())) + .unwrap(), + ) + .await + .unwrap(); + + assert_eq!(response.status(), http::StatusCode::UNAUTHORIZED); + + let body_bytes = axum::body::to_bytes(response.into_body(), usize::MAX).await.unwrap(); + let body: serde_json::Value = serde_json::from_slice(&body_bytes).unwrap(); + assert_eq!(body["error"], "Invalid username or password"); + } } diff --git a/src/handlers/raid_quest.rs b/src/handlers/raid_quest.rs index e6f1b83..2b87c71 100644 --- a/src/handlers/raid_quest.rs +++ b/src/handlers/raid_quest.rs @@ -689,8 +689,11 @@ mod tests { .await .unwrap(); - // 404/RecordNotFound for No Active Raid - assert!(response.status().is_server_error() || response.status() == StatusCode::NOT_FOUND); + // 200 OK / Handler Error + assert_eq!(response.status(), StatusCode::OK); + let body_bytes = axum::body::to_bytes(response.into_body(), usize::MAX).await.unwrap(); + let body: Value = serde_json::from_slice(&body_bytes).unwrap(); + assert_eq!(body["error"].as_str().unwrap(), "No active raid is found"); } #[tokio::test] @@ -727,8 +730,11 @@ mod tests { .await .unwrap(); - // 400 Bad Request / Handler Error - assert_eq!(response.status(), StatusCode::NOT_FOUND); + // 200 OK / Handler Error + assert_eq!(response.status(), StatusCode::OK); + let body_bytes = axum::body::to_bytes(response.into_body(), usize::MAX).await.unwrap(); + let body: Value = serde_json::from_slice(&body_bytes).unwrap(); + assert_eq!(body["error"].as_str().unwrap(), "User doesn't have X association"); } #[tokio::test] diff --git a/src/handlers/relevant_tweet.rs b/src/handlers/relevant_tweet.rs index 834db71..092aa21 100644 --- a/src/handlers/relevant_tweet.rs +++ b/src/handlers/relevant_tweet.rs @@ -379,6 +379,9 @@ mod tests { .await .unwrap(); - assert_eq!(response.status(), 404); + assert_eq!(response.status(), 200); + let body_bytes = axum::body::to_bytes(response.into_body(), usize::MAX).await.unwrap(); + let body: Value = serde_json::from_slice(&body_bytes).unwrap(); + assert_eq!(body["error"].as_str().unwrap(), "Tweet non_existent_tweet not found"); } } diff --git a/src/handlers/tweet_author.rs b/src/handlers/tweet_author.rs index 455234c..fb72fb0 100644 --- a/src/handlers/tweet_author.rs +++ b/src/handlers/tweet_author.rs @@ -359,7 +359,13 @@ mod tests { .await .unwrap(); - assert_eq!(response.status(), 404); + assert_eq!(response.status(), 200); + let body_bytes = axum::body::to_bytes(response.into_body(), usize::MAX).await.unwrap(); + let body: Value = serde_json::from_slice(&body_bytes).unwrap(); + assert_eq!( + body["error"].as_str().unwrap(), + "Tweet Author non_existent_id not found" + ); } #[tokio::test]