1
use axum::{extract::State, http::StatusCode, response::IntoResponse};
2
use axum_extra::extract::CookieJar;
3
use redis::Client;
4
use std::sync::Arc;
5
use tokio::sync::Mutex;
6
use uuid::Uuid;
7
use web::{AppState, Config, User, pages};
8

            
9
12
fn create_test_app_state() -> Arc<AppState> {
10
12
    let conf = Config {
11
12
        site_url: "http://localhost:8080".to_string(),
12
12
        redis_url: "redis://127.0.0.1:6379".to_string(),
13
12
        client_origin: "http://localhost:3000".to_string(),
14
12
        access_token_private_key: "test_private_key".to_string(),
15
12
        access_token_public_key: "test_public_key".to_string(),
16
12
        refresh_token_private_key: "test_refresh_private".to_string(),
17
12
        refresh_token_public_key: "test_refresh_public".to_string(),
18
12
        access_token_expires_in: "15m".to_string(),
19
12
        access_token_max_age: 900,
20
12
        refresh_token_expires_in: "60m".to_string(),
21
12
        refresh_token_max_age: 3600,
22
12
    };
23

            
24
12
    let redis_client = Client::open("redis://127.0.0.1:6379").unwrap();
25

            
26
12
    Arc::new(AppState {
27
12
        conf,
28
12
        redis_client,
29
12
        frac: 42,
30
12
        user: Mutex::new(Some(User {
31
12
            id: Uuid::new_v4(),
32
12
            name: "Test User".to_string(),
33
12
            email: "test@example.com".to_string(),
34
12
            password: "hashed".to_string(),
35
12
            role: "user".to_string(),
36
12
            photo: "".to_string(),
37
12
            verified: true,
38
12
            database: "testdb".to_string(),
39
12
            created_at: Some(chrono::Utc::now()),
40
12
            updated_at: Some(chrono::Utc::now()),
41
12
        })),
42
12
    })
43
12
}
44

            
45
#[tokio::test]
46
3
async fn test_index_handler_logged_out() {
47
2
    let app_state = create_test_app_state();
48
2
    let cookie_jar = CookieJar::new();
49

            
50
2
    let response = pages::index(State(app_state), cookie_jar).await;
51
2
    let response = response.into_response();
52

            
53
3
    assert_eq!(response.status(), StatusCode::OK);
54
2
}
55

            
56
#[tokio::test]
57
3
async fn test_index_handler_returns_correct_fraction() {
58
2
    let app_state = create_test_app_state();
59
2
    let cookie_jar = CookieJar::new();
60

            
61
    // Verify the fraction value is passed correctly
62
2
    assert_eq!(app_state.frac, 42);
63

            
64
3
    let _response = pages::index(State(app_state), cookie_jar).await;
65
    // Template should receive fraction: 42
66
2
}
67

            
68
#[tokio::test]
69
3
async fn test_index_handler_user_data() {
70
2
    let app_state = create_test_app_state();
71
2
    let cookie_jar = CookieJar::new();
72

            
73
    // Verify user data is accessible
74
2
    let user_guard = app_state.user.lock().await;
75
2
    assert!(user_guard.is_some());
76
2
    assert_eq!(user_guard.as_ref().unwrap().name, "Test User");
77
2
    drop(user_guard);
78

            
79
3
    let _response = pages::index(State(app_state), cookie_jar).await;
80
2
}
81

            
82
#[tokio::test]
83
3
async fn test_file_table_handler() {
84
2
    let app_state = create_test_app_state();
85

            
86
    // This will likely fail due to S3 dependencies, but we can test the structure
87
2
    let result = pages::file_table(State(app_state)).await;
88

            
89
    // Should return either Ok or Err, both are valid outcomes for this test
90
3
    match result {
91
3
        Ok(response) => {
92
3
            let response = response.into_response();
93
3
            assert_eq!(response.status(), StatusCode::OK);
94
2
        }
95
2
        Err(status) => {
96
2
            // Expected to fail in test environment due to S3 dependencies
97
2
            assert!(matches!(
98
2
                status,
99
2
                StatusCode::INTERNAL_SERVER_ERROR | StatusCode::SERVICE_UNAVAILABLE
100
2
            ));
101
2
        }
102
2
    }
103
2
}
104

            
105
#[tokio::test]
106
3
async fn test_register_handler() {
107
2
    let response = pages::register().await;
108
2
    let response = response.into_response();
109

            
110
3
    assert_eq!(response.status(), StatusCode::OK);
111
2
}
112

            
113
#[tokio::test]
114
3
async fn test_login_handler() {
115
2
    let response = pages::login().await;
116
2
    let response = response.into_response();
117

            
118
3
    assert_eq!(response.status(), StatusCode::OK);
119
2
}
120

            
121
#[tokio::test]
122
3
async fn test_app_state_fraction_value() {
123
2
    let app_state = create_test_app_state();
124

            
125
    // Verify the test value in AppState
126
3
    assert_eq!(app_state.frac, 42);
127
2
}
128

            
129
#[tokio::test]
130
3
async fn test_app_state_user_value() {
131
2
    let app_state = create_test_app_state();
132

            
133
2
    let user_guard = app_state.user.lock().await;
134
2
    assert!(user_guard.is_some());
135

            
136
2
    let user = user_guard.as_ref().unwrap();
137
2
    assert_eq!(user.name, "Test User");
138
2
    assert_eq!(user.email, "test@example.com");
139
2
    assert_eq!(user.database, "testdb");
140
3
    assert!(user.verified);
141
2
}