1
use chrono::Utc;
2
use redis::Client;
3
use std::sync::{Arc, Once};
4
use uuid::Uuid;
5
use web::{AppState, Config, jwt_auth::JWTAuthMiddleware, model::User};
6

            
7
static TEST_ENV_INIT: Once = Once::new();
8

            
9
92
fn ensure_test_env() {
10
92
    TEST_ENV_INIT.call_once(|| {
11
1
        if std::env::var("DATABASE_URL").is_err()
12
            && let Ok(contents) = std::fs::read_to_string(".env")
13
            && let Some(db_url) = contents
14
                .lines()
15
                .map(str::trim)
16
                .find_map(|line| line.strip_prefix("DATABASE_URL=").map(str::to_string))
17
            && !db_url.trim().is_empty()
18
        {
19
            unsafe {
20
                std::env::set_var("DATABASE_URL", db_url);
21
            }
22
1
        }
23

            
24
1
        if std::env::var("DATABASE_URL").is_err() {
25
            // Used by server::db LazyLock during integration tests.
26
            // Connection may still fail, but this avoids startup panic and lock poisoning.
27
            unsafe {
28
                std::env::set_var(
29
                    "DATABASE_URL",
30
                    "postgres://postgres:postgres@127.0.0.1:5432/postgres",
31
                );
32
            }
33
1
        }
34
1
    });
35
92
}
36

            
37
/// Create a test app state with mock configuration
38
92
pub async fn create_test_app_state() -> Arc<AppState> {
39
92
    ensure_test_env();
40

            
41
92
    let config = Config {
42
92
        site_url: "http://localhost:3000".to_string(),
43
92
        redis_url: "redis://localhost:6379".to_string(),
44
92
        client_origin: "http://localhost:3000".to_string(),
45
92
        access_token_private_key: "dGVzdF9wcml2YXRlX2tleQ==".to_string(), // base64("test_private_key")
46
92
        access_token_public_key: "dGVzdF9wdWJsaWNfa2V5".to_string(), // base64("test_public_key")
47
92
        access_token_expires_in: "15m".to_string(),
48
92
        access_token_max_age: 15,
49
92
        refresh_token_private_key: "cmVmcmVzaF9wcml2YXRlX2tleQ==".to_string(), // base64("refresh_private_key")
50
92
        refresh_token_public_key: "cmVmcmVzaF9wdWJsaWNfa2V5".to_string(), // base64("refresh_public_key")
51
92
        refresh_token_expires_in: "60m".to_string(),
52
92
        refresh_token_max_age: 60,
53
92
    };
54

            
55
92
    let redis_client = Client::open("redis://localhost:6379").unwrap_or_else(|_| {
56
        Client::open("redis://127.0.0.1:6379")
57
            .unwrap_or_else(|_| panic!("Failed to connect to Redis for testing"))
58
    });
59

            
60
92
    AppState::new(config, redis_client)
61
92
}
62

            
63
/// Create a mock user for testing
64
57
pub fn create_mock_user() -> User {
65
57
    User {
66
57
        id: Uuid::new_v4(),
67
57
        name: "Test User".to_string(),
68
57
        email: "test@example.com".to_string(),
69
57
        password: "hashed_password".to_string(),
70
57
        role: "user".to_string(),
71
57
        photo: "photo.jpg".to_string(),
72
57
        verified: true,
73
57
        database: "test_db".to_string(),
74
57
        created_at: Some(Utc::now()),
75
57
        updated_at: Some(Utc::now()),
76
57
    }
77
57
}
78

            
79
/// Create mock JWT auth middleware for testing
80
57
pub fn create_mock_jwt_auth(user: User) -> JWTAuthMiddleware {
81
57
    JWTAuthMiddleware {
82
57
        user,
83
57
        access_token_uuid: Uuid::new_v4(),
84
57
    }
85
57
}