use crate::plugins::EmailPasswordPlugin;
use crate::{AuthBuilder, AuthConfig, AuthRequest, HttpMethod, MemoryDatabaseAdapter};

fn invalid_json_request(path: &str, trace_id: &str) -> AuthRequest {
    let mut request: AuthRequest = AuthRequest::new(HttpMethod::Post, path);
    request
        .headers
        .insert("content-type".to_string(), "application/json".to_string());
    request
        .headers
        .insert("x-request-id".to_string(), trace_id.to_string());
    request.body = Some(br#"{"email":"broken""#.to_vec());
    request
}

#[tokio::test]
async fn invalid_json_error_preserves_request_trace_id() {
    let auth: crate::AthenaAuth<MemoryDatabaseAdapter> =
        AuthBuilder::new(AuthConfig::new("trace-id-test-secret-key-32-chars"))
            .database(MemoryDatabaseAdapter::new())
            .plugin(EmailPasswordPlugin::new())
            .build()
            .await
            .expect("auth should build");

    let response: athena_auth_core::AuthResponse = auth
        .handle_request(invalid_json_request("/sign-up/email", "invalid-json-trace"))
        .await
        .expect("invalid JSON should become a handled auth response");

    assert_eq!(response.status, 400);
    assert_eq!(
        response.headers.get("x-request-id").map(String::as_str),
        Some("invalid-json-trace")
    );
    assert_eq!(
        response
            .headers
            .get("x-athena-trace-id")
            .map(String::as_str),
        Some("invalid-json-trace")
    );

    let body: serde_json::Value =
        serde_json::from_slice(&response.body).expect("body should be valid JSON");
    assert_eq!(body["traceId"], "invalid-json-trace");
    assert!(body["version"].is_string(), "version should be present");
}
