package handlers import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "testing" "github.com/google/uuid" "mgit.msbls.de/m/KanzlAI-mGMT/internal/auth" ) func TestAppointmentCreate_NoTenant(t *testing.T) { h := &AppointmentHandler{} r := httptest.NewRequest("POST", "/api/appointments", bytes.NewBufferString(`{}`)) w := httptest.NewRecorder() h.Create(w, r) if w.Code != http.StatusUnauthorized { t.Errorf("expected 401, got %d", w.Code) } } func TestAppointmentCreate_MissingTitle(t *testing.T) { h := &AppointmentHandler{} body := `{"start_at":"2026-04-01T10:00:00Z"}` r := httptest.NewRequest("POST", "/api/appointments", bytes.NewBufferString(body)) ctx := auth.ContextWithTenantID( auth.ContextWithUserID(r.Context(), uuid.New()), uuid.New(), ) r = r.WithContext(ctx) w := httptest.NewRecorder() h.Create(w, r) if w.Code != http.StatusBadRequest { t.Errorf("expected 400, got %d", w.Code) } var resp map[string]string json.NewDecoder(w.Body).Decode(&resp) if resp["error"] != "title is required" { t.Errorf("unexpected error: %s", resp["error"]) } } func TestAppointmentCreate_MissingStartAt(t *testing.T) { h := &AppointmentHandler{} body := `{"title":"Test Appointment"}` r := httptest.NewRequest("POST", "/api/appointments", bytes.NewBufferString(body)) ctx := auth.ContextWithTenantID( auth.ContextWithUserID(r.Context(), uuid.New()), uuid.New(), ) r = r.WithContext(ctx) w := httptest.NewRecorder() h.Create(w, r) if w.Code != http.StatusBadRequest { t.Errorf("expected 400, got %d", w.Code) } var resp map[string]string json.NewDecoder(w.Body).Decode(&resp) if resp["error"] != "start_at is required" { t.Errorf("unexpected error: %s", resp["error"]) } } func TestAppointmentCreate_InvalidJSON(t *testing.T) { h := &AppointmentHandler{} r := httptest.NewRequest("POST", "/api/appointments", bytes.NewBufferString(`{broken`)) ctx := auth.ContextWithTenantID( auth.ContextWithUserID(r.Context(), uuid.New()), uuid.New(), ) r = r.WithContext(ctx) w := httptest.NewRecorder() h.Create(w, r) if w.Code != http.StatusBadRequest { t.Errorf("expected 400, got %d", w.Code) } } func TestAppointmentList_NoTenant(t *testing.T) { h := &AppointmentHandler{} r := httptest.NewRequest("GET", "/api/appointments", nil) w := httptest.NewRecorder() h.List(w, r) if w.Code != http.StatusUnauthorized { t.Errorf("expected 401, got %d", w.Code) } } func TestAppointmentUpdate_NoTenant(t *testing.T) { h := &AppointmentHandler{} r := httptest.NewRequest("PUT", "/api/appointments/"+uuid.New().String(), bytes.NewBufferString(`{}`)) r.SetPathValue("id", uuid.New().String()) w := httptest.NewRecorder() h.Update(w, r) if w.Code != http.StatusUnauthorized { t.Errorf("expected 401, got %d", w.Code) } } func TestAppointmentUpdate_InvalidID(t *testing.T) { h := &AppointmentHandler{} r := httptest.NewRequest("PUT", "/api/appointments/not-uuid", bytes.NewBufferString(`{}`)) r.SetPathValue("id", "not-uuid") ctx := auth.ContextWithTenantID( auth.ContextWithUserID(r.Context(), uuid.New()), uuid.New(), ) r = r.WithContext(ctx) w := httptest.NewRecorder() h.Update(w, r) if w.Code != http.StatusBadRequest { t.Errorf("expected 400, got %d", w.Code) } } func TestAppointmentDelete_NoTenant(t *testing.T) { h := &AppointmentHandler{} r := httptest.NewRequest("DELETE", "/api/appointments/"+uuid.New().String(), nil) r.SetPathValue("id", uuid.New().String()) w := httptest.NewRecorder() h.Delete(w, r) if w.Code != http.StatusUnauthorized { t.Errorf("expected 401, got %d", w.Code) } } func TestAppointmentDelete_InvalidID(t *testing.T) { h := &AppointmentHandler{} r := httptest.NewRequest("DELETE", "/api/appointments/bad", nil) r.SetPathValue("id", "bad") ctx := auth.ContextWithTenantID( auth.ContextWithUserID(r.Context(), uuid.New()), uuid.New(), ) r = r.WithContext(ctx) w := httptest.NewRecorder() h.Delete(w, r) if w.Code != http.StatusBadRequest { t.Errorf("expected 400, got %d", w.Code) } } func TestAppointmentList_InvalidCaseID(t *testing.T) { h := &AppointmentHandler{} r := httptest.NewRequest("GET", "/api/appointments?case_id=bad", nil) ctx := auth.ContextWithTenantID( auth.ContextWithUserID(r.Context(), uuid.New()), uuid.New(), ) r = r.WithContext(ctx) w := httptest.NewRecorder() h.List(w, r) if w.Code != http.StatusBadRequest { t.Errorf("expected 400, got %d", w.Code) } } func TestAppointmentList_InvalidStartFrom(t *testing.T) { h := &AppointmentHandler{} r := httptest.NewRequest("GET", "/api/appointments?start_from=not-a-date", nil) ctx := auth.ContextWithTenantID( auth.ContextWithUserID(r.Context(), uuid.New()), uuid.New(), ) r = r.WithContext(ctx) w := httptest.NewRecorder() h.List(w, r) if w.Code != http.StatusBadRequest { t.Errorf("expected 400, got %d", w.Code) } }