package integration import ( "bytes" "encoding/json" "fmt" "net/http" "net/http/httptest" "os" "testing" "github.com/atlasos/calypso/internal/common/config" "github.com/atlasos/calypso/internal/common/logger" "github.com/atlasos/calypso/internal/common/password" "github.com/atlasos/calypso/internal/common/router" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestMain(m *testing.M) { // Set Gin to test mode gin.SetMode(gin.TestMode) // Run tests code := m.Run() // Cleanup if TestDB != nil { TestDB.Close() } os.Exit(code) } func TestHealthEndpoint(t *testing.T) { db := SetupTestDB(t) defer CleanupTestDB(t) cfg := TestConfig if cfg == nil { cfg = &config.Config{ Server: config.ServerConfig{ Port: 8080, }, } } log := TestLogger if log == nil { log = logger.NewLogger("test") } r := router.NewRouter(cfg, db, log) req := httptest.NewRequest("GET", "/api/v1/health", nil) w := httptest.NewRecorder() r.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) var response map[string]interface{} err := json.Unmarshal(w.Body.Bytes(), &response) require.NoError(t, err) assert.Equal(t, "calypso-api", response["service"]) } func TestLoginEndpoint(t *testing.T) { db := SetupTestDB(t) defer CleanupTestDB(t) // Create test user passwordHash, err := password.HashPassword("testpass123", config.Argon2Params{ Memory: 64 * 1024, Iterations: 3, Parallelism: 4, SaltLength: 16, KeyLength: 32, }) require.NoError(t, err) userID := CreateTestUser(t, "testuser", "test@example.com", passwordHash, false) cfg := TestConfig if cfg == nil { cfg = &config.Config{ Server: config.ServerConfig{ Port: 8080, }, Auth: config.AuthConfig{ JWTSecret: "test-jwt-secret-key-minimum-32-characters-long", TokenLifetime: 24 * 60 * 60 * 1000000000, // 24 hours in nanoseconds }, } } log := TestLogger if log == nil { log = logger.NewLogger("test") } r := router.NewRouter(cfg, db, log) // Test login loginData := map[string]string{ "username": "testuser", "password": "testpass123", } jsonData, _ := json.Marshal(loginData) req := httptest.NewRequest("POST", "/api/v1/auth/login", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() r.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) var response map[string]interface{} err = json.Unmarshal(w.Body.Bytes(), &response) require.NoError(t, err) assert.NotEmpty(t, response["token"]) assert.Equal(t, userID, response["user"].(map[string]interface{})["id"]) } func TestLoginEndpoint_WrongPassword(t *testing.T) { db := SetupTestDB(t) defer CleanupTestDB(t) // Create test user passwordHash, err := password.HashPassword("testpass123", config.Argon2Params{ Memory: 64 * 1024, Iterations: 3, Parallelism: 4, SaltLength: 16, KeyLength: 32, }) require.NoError(t, err) CreateTestUser(t, "testuser", "test@example.com", passwordHash, false) cfg := TestConfig if cfg == nil { cfg = &config.Config{ Server: config.ServerConfig{ Port: 8080, }, Auth: config.AuthConfig{ JWTSecret: "test-jwt-secret-key-minimum-32-characters-long", TokenLifetime: 24 * 60 * 60 * 1000000000, }, } } log := TestLogger if log == nil { log = logger.NewLogger("test") } r := router.NewRouter(cfg, db, log) // Test login with wrong password loginData := map[string]string{ "username": "testuser", "password": "wrongpassword", } jsonData, _ := json.Marshal(loginData) req := httptest.NewRequest("POST", "/api/v1/auth/login", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() r.ServeHTTP(w, req) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestGetCurrentUser(t *testing.T) { db := SetupTestDB(t) defer CleanupTestDB(t) // Create test user and get token passwordHash, err := password.HashPassword("testpass123", config.Argon2Params{ Memory: 64 * 1024, Iterations: 3, Parallelism: 4, SaltLength: 16, KeyLength: 32, }) require.NoError(t, err) userID := CreateTestUser(t, "testuser", "test@example.com", passwordHash, false) cfg := TestConfig if cfg == nil { cfg = &config.Config{ Server: config.ServerConfig{ Port: 8080, }, Auth: config.AuthConfig{ JWTSecret: "test-jwt-secret-key-minimum-32-characters-long", TokenLifetime: 24 * 60 * 60 * 1000000000, }, } } log := TestLogger if log == nil { log = logger.NewLogger("test") } // Login to get token loginData := map[string]string{ "username": "testuser", "password": "testpass123", } jsonData, _ := json.Marshal(loginData) r := router.NewRouter(cfg, db, log) req := httptest.NewRequest("POST", "/api/v1/auth/login", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() r.ServeHTTP(w, req) require.Equal(t, http.StatusOK, w.Code) var loginResponse map[string]interface{} err = json.Unmarshal(w.Body.Bytes(), &loginResponse) require.NoError(t, err) token := loginResponse["token"].(string) // Test /auth/me endpoint (use same router instance) req2 := httptest.NewRequest("GET", "/api/v1/auth/me", nil) req2.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) w2 := httptest.NewRecorder() r.ServeHTTP(w2, req2) assert.Equal(t, http.StatusOK, w2.Code) var userResponse map[string]interface{} err = json.Unmarshal(w2.Body.Bytes(), &userResponse) require.NoError(t, err) assert.Equal(t, userID, userResponse["id"]) assert.Equal(t, "testuser", userResponse["username"]) } func TestListAlerts(t *testing.T) { db := SetupTestDB(t) defer CleanupTestDB(t) // Create test user and get token passwordHash, err := password.HashPassword("testpass123", config.Argon2Params{ Memory: 64 * 1024, Iterations: 3, Parallelism: 4, SaltLength: 16, KeyLength: 32, }) require.NoError(t, err) CreateTestUser(t, "testuser", "test@example.com", passwordHash, true) // Admin user cfg := TestConfig if cfg == nil { cfg = &config.Config{ Server: config.ServerConfig{ Port: 8080, }, Auth: config.AuthConfig{ JWTSecret: "test-jwt-secret-key-minimum-32-characters-long", TokenLifetime: 24 * 60 * 60 * 1000000000, }, } } log := TestLogger if log == nil { log = logger.NewLogger("test") } r := router.NewRouter(cfg, db, log) // Login to get token loginData := map[string]string{ "username": "testuser", "password": "testpass123", } jsonData, _ := json.Marshal(loginData) req := httptest.NewRequest("POST", "/api/v1/auth/login", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() r.ServeHTTP(w, req) require.Equal(t, http.StatusOK, w.Code) var loginResponse map[string]interface{} err = json.Unmarshal(w.Body.Bytes(), &loginResponse) require.NoError(t, err) token := loginResponse["token"].(string) // Test /monitoring/alerts endpoint (use same router instance) req2 := httptest.NewRequest("GET", "/api/v1/monitoring/alerts", nil) req2.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) w2 := httptest.NewRecorder() r.ServeHTTP(w2, req2) assert.Equal(t, http.StatusOK, w2.Code) var alertsResponse map[string]interface{} err = json.Unmarshal(w2.Body.Bytes(), &alertsResponse) require.NoError(t, err) assert.NotNil(t, alertsResponse["alerts"]) }