package api import ( "bytes" "context" "encoding/json" "net/http" "net/http/httptest" "os" "testing" "github.com/go-chi/chi/v5" "git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq" ) func newMeTimezoneRouter(h *handlers) chi.Router { r := chi.NewRouter() r.Put("/api/me/timezone", h.handlePutTimezone) return r } func TestPutTimezone_ValidIANA(t *testing.T) { if os.Getenv("MINSTREL_TEST_DATABASE_URL") == "" { t.Skip("MINSTREL_TEST_DATABASE_URL not set") } h, pool := testHandlers(t) user := seedUser(t, pool, "tz1", "irrelevant1", false) body := bytes.NewBufferString(`{"timezone":"America/New_York"}`) req := httptest.NewRequest(http.MethodPut, "/api/me/timezone", body) req.Header.Set("Content-Type", "application/json") req = withUser(req, user) rec := httptest.NewRecorder() newMeTimezoneRouter(h).ServeHTTP(rec, req) if rec.Code != http.StatusNoContent { t.Fatalf("status = %d, want 204; body=%s", rec.Code, rec.Body.String()) } // Verify the DB row was updated. got, err := dbq.New(pool).GetUserByID(context.Background(), user.ID) if err != nil { t.Fatalf("GetUserByID: %v", err) } if got.Timezone != "America/New_York" { t.Errorf("timezone = %q, want %q", got.Timezone, "America/New_York") } if !got.TimezoneUpdatedAt.Valid { t.Errorf("expected timezone_updated_at to be set after PUT") } } func TestPutTimezone_InvalidIANA(t *testing.T) { if os.Getenv("MINSTREL_TEST_DATABASE_URL") == "" { t.Skip("MINSTREL_TEST_DATABASE_URL not set") } h, pool := testHandlers(t) user := seedUser(t, pool, "tz2", "irrelevant1", false) body := bytes.NewBufferString(`{"timezone":"Not/A/Real/Zone"}`) req := httptest.NewRequest(http.MethodPut, "/api/me/timezone", body) req.Header.Set("Content-Type", "application/json") req = withUser(req, user) rec := httptest.NewRecorder() newMeTimezoneRouter(h).ServeHTTP(rec, req) if rec.Code != http.StatusBadRequest { t.Fatalf("status = %d, want 400; body=%s", rec.Code, rec.Body.String()) } var errResp struct { Code string `json:"code"` } if err := json.NewDecoder(rec.Body).Decode(&errResp); err != nil { t.Fatalf("decode err response: %v", err) } if errResp.Code != "invalid_timezone" { t.Errorf("error code = %q, want invalid_timezone", errResp.Code) } } func TestPutTimezone_EmptyTimezone(t *testing.T) { if os.Getenv("MINSTREL_TEST_DATABASE_URL") == "" { t.Skip("MINSTREL_TEST_DATABASE_URL not set") } h, pool := testHandlers(t) user := seedUser(t, pool, "tz3", "irrelevant1", false) body := bytes.NewBufferString(`{"timezone":""}`) req := httptest.NewRequest(http.MethodPut, "/api/me/timezone", body) req.Header.Set("Content-Type", "application/json") req = withUser(req, user) rec := httptest.NewRecorder() newMeTimezoneRouter(h).ServeHTTP(rec, req) if rec.Code != http.StatusBadRequest { t.Fatalf("status = %d, want 400", rec.Code) } }