1
use axum::{
2
    Router,
3
    body::Body,
4
    http::{Request, StatusCode},
5
    routing::get,
6
};
7
use tower::ServiceExt;
8

            
9
use crate::common::create_test_app_state;
10

            
11
// SIMPLE HANDLERS TESTS (no external dependencies)
12

            
13
#[tokio::test]
14
3
async fn test_get_version_handler() {
15
2
    let app = Router::new().route("/version", get(web::handler::get_version));
16

            
17
2
    let response = app
18
2
        .oneshot(
19
2
            Request::builder()
20
2
                .uri("/version")
21
2
                .body(Body::empty())
22
2
                .unwrap(),
23
2
        )
24
2
        .await
25
2
        .unwrap();
26

            
27
2
    assert_eq!(response.status(), StatusCode::OK);
28

            
29
2
    let body = axum::body::to_bytes(response.into_body(), usize::MAX)
30
2
        .await
31
2
        .unwrap();
32
2
    let body_str = String::from_utf8(body.to_vec()).unwrap();
33

            
34
    // Should contain some version info (git hash)
35
3
    assert!(!body_str.is_empty());
36
2
}
37

            
38
#[tokio::test]
39
3
async fn test_get_logout_link_handler() {
40
2
    let app_state = create_test_app_state().await;
41
2
    let app = Router::new()
42
2
        .route("/logout", get(web::handler::get_logout_link))
43
2
        .with_state(app_state);
44

            
45
2
    let response = app
46
2
        .oneshot(
47
2
            Request::builder()
48
2
                .uri("/logout")
49
2
                .body(Body::empty())
50
2
                .unwrap(),
51
2
        )
52
2
        .await
53
2
        .unwrap();
54

            
55
2
    assert_eq!(response.status(), StatusCode::OK);
56

            
57
2
    let body = axum::body::to_bytes(response.into_body(), usize::MAX)
58
2
        .await
59
2
        .unwrap();
60
2
    let body_str = String::from_utf8(body.to_vec()).unwrap();
61

            
62
    // Should contain the logout link
63
3
    assert!(body_str.contains("/api/auth/logout"));
64
2
}
65

            
66
#[tokio::test]
67
3
async fn test_handlers_return_proper_json_errors() {
68
2
    let app_state = create_test_app_state().await;
69
2
    let app = Router::new()
70
2
        .route(
71
2
            "/auth/login",
72
2
            axum::routing::post(web::handler::login_user_handler),
73
        )
74
2
        .route(
75
2
            "/auth/register",
76
2
            axum::routing::post(web::handler::register_user_handler),
77
        )
78
2
        .route(
79
2
            "/auth/refresh",
80
2
            axum::routing::get(web::handler::refresh_access_token_handler),
81
        )
82
2
        .with_state(app_state);
83

            
84
    // Test login with invalid JSON
85
2
    let response = app
86
2
        .clone()
87
2
        .oneshot(
88
2
            Request::builder()
89
2
                .method("POST")
90
2
                .uri("/auth/login")
91
2
                .header("content-type", "application/json")
92
2
                .body(Body::from("invalid json"))
93
2
                .unwrap(),
94
2
        )
95
2
        .await
96
2
        .unwrap();
97

            
98
2
    assert_eq!(response.status(), StatusCode::BAD_REQUEST);
99

            
100
    // Test register with invalid JSON
101
2
    let response = app
102
2
        .clone()
103
2
        .oneshot(
104
2
            Request::builder()
105
2
                .method("POST")
106
2
                .uri("/auth/register")
107
2
                .header("content-type", "application/json")
108
2
                .body(Body::from("invalid json"))
109
2
                .unwrap(),
110
2
        )
111
2
        .await
112
2
        .unwrap();
113

            
114
2
    assert_eq!(response.status(), StatusCode::BAD_REQUEST);
115

            
116
    // Test refresh without cookie
117
2
    let response = app
118
2
        .oneshot(
119
2
            Request::builder()
120
2
                .uri("/auth/refresh")
121
2
                .body(Body::empty())
122
2
                .unwrap(),
123
2
        )
124
2
        .await
125
2
        .unwrap();
126

            
127
    // May return 401 (Unauthorized) or 403 (Forbidden) depending on auth middleware
128
2
    assert!(
129
2
        response.status() == StatusCode::UNAUTHORIZED || response.status() == StatusCode::FORBIDDEN,
130
        "Expected 401 or 403, got: {}",
131
        response.status()
132
    );
133

            
134
    // Verify it returns JSON
135
2
    let body = axum::body::to_bytes(response.into_body(), usize::MAX)
136
2
        .await
137
2
        .unwrap();
138
2
    let body_str = String::from_utf8(body.to_vec()).unwrap();
139
3
    let _: serde_json::Value =
140
3
        serde_json::from_str(&body_str).expect("Response should be valid JSON");
141
2
}