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
99
fn ensure_test_env() {
10
99
    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
99
}
36

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

            
41
99
    let config = Config {
42
99
        site_url: "http://localhost:3000".to_string(),
43
99
        redis_url: "redis://localhost:6379".to_string(),
44
99
        access_token_max_age: 15,
45
99
        refresh_token_max_age: 60,
46
99
        ssh: web::config::SshConnectInfo {
47
99
            hostname: "ssh.example.invalid".to_string(),
48
99
            port: 2222,
49
99
            host_fingerprint: "(test)".to_string(),
50
99
        },
51
99
    };
52

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

            
58
99
    AppState::new(config, redis_client)
59
99
}
60

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

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