package httpserver import ( "context" "encoding/json" "errors" "net/http" "net/http/httptest" "testing" "solopm.com/solopm-server/internal/config" ) type stubPinger struct{ err error } func (s stubPinger) Ping(ctx context.Context) error { return s.err } func TestHealthzHandler(t *testing.T) { cfg := &config.Config{} // no MEILI_URL/SMTP_HOST set: both report "absent" t.Run("db ok", func(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/healthz", nil) healthzHandler(cfg, stubPinger{}, "test")(rec, req) if rec.Code != http.StatusOK { t.Fatalf("status = %d, want 200", rec.Code) } var body healthResponse if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil { t.Fatalf("unmarshal: %v", err) } if body.Status != "ok" || body.Database != "ok" { t.Fatalf("body = %+v, want status=ok database=ok", body) } if body.Meilisearch != "absent" || body.SMTP != "absent" { t.Fatalf("body = %+v, want meilisearch/smtp absent", body) } }) t.Run("db unreachable", func(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/healthz", nil) healthzHandler(cfg, stubPinger{err: errors.New("boom")}, "test")(rec, req) if rec.Code != http.StatusServiceUnavailable { t.Fatalf("status = %d, want 503", rec.Code) } var body healthResponse if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil { t.Fatalf("unmarshal: %v", err) } if body.Status != "error" || body.Database != "unreachable" { t.Fatalf("body = %+v, want status=error database=unreachable", body) } }) }