package health import ( "encoding/json" "errors" "net/http" "net/http/httptest" "testing" ) func TestHealthHandler_ServeHTTP(t *testing.T) { tests := []struct { name string method string checkers []HealthChecker expectedStatus int expectedHealth string }{ { name: "GET request with no checkers", method: "GET", checkers: []HealthChecker{}, expectedStatus: http.StatusOK, expectedHealth: "ok", }, { name: "GET request with healthy checker", method: "GET", checkers: []HealthChecker{ NewSimpleChecker("test", func() error { return nil }), }, expectedStatus: http.StatusOK, expectedHealth: "ok", }, { name: "GET request with unhealthy checker", method: "GET", checkers: []HealthChecker{ NewSimpleChecker("test", func() error { return errors.New("test error") }), }, expectedStatus: http.StatusServiceUnavailable, expectedHealth: "error", }, { name: "POST request should return 405", method: "POST", checkers: []HealthChecker{}, expectedStatus: http.StatusMethodNotAllowed, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { handler := NewHandler("1.0.0") for _, checker := range tt.checkers { handler.AddCheck(checker) } req := httptest.NewRequest(tt.method, "/health", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != tt.expectedStatus { t.Errorf("expected status %d, got %d", tt.expectedStatus, w.Code) } if tt.method == "GET" && tt.expectedStatus != http.StatusMethodNotAllowed { var response Response if err := json.NewDecoder(w.Body).Decode(&response); err != nil { t.Fatalf("failed to decode response: %v", err) } if response.Status != tt.expectedHealth { t.Errorf("expected status %s, got %s", tt.expectedHealth, response.Status) } if response.Version != "1.0.0" { t.Errorf("expected version 1.0.0, got %s", response.Version) } if len(response.Checks) != len(tt.checkers) { t.Errorf("expected %d checks, got %d", len(tt.checkers), len(response.Checks)) } } }) } } func TestSimpleChecker(t *testing.T) { t.Run("healthy checker", func(t *testing.T) { checker := NewSimpleChecker("test", func() error { return nil }) if checker.Name() != "test" { t.Errorf("expected name 'test', got %s", checker.Name()) } if err := checker.Check(); err != nil { t.Errorf("expected no error, got %v", err) } }) t.Run("unhealthy checker", func(t *testing.T) { testErr := errors.New("test error") checker := NewSimpleChecker("test", func() error { return testErr }) if checker.Name() != "test" { t.Errorf("expected name 'test', got %s", checker.Name()) } if err := checker.Check(); err != testErr { t.Errorf("expected error %v, got %v", testErr, err) } }) }