package server import ( "context" "net/http" "net/http/httptest" "strings" "testing" "time" "github.com/labstack/echo/v4" ) type stubStripeSyncer struct { from time.Time to time.Time err error } func (s *stubStripeSyncer) SyncStripePayments(ctx context.Context, from, to time.Time) error { s.from = from s.to = to return s.err } func TestHandleStripeSyncSuccess(t *testing.T) { syncer := &stubStripeSyncer{} handler := handleStripeSync(syncer) now := time.Now().UTC().Truncate(time.Second) from := now.Add(-2 * time.Hour).Format(time.RFC3339) to := now.Format(time.RFC3339) e := echo.New() req := httptest.NewRequest(http.MethodPost, "/api/stripe/sync", strings.NewReader(`{"from":"`+from+`","to":"`+to+`"}`)) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() c := e.NewContext(req, rec) if err := handler(c); err != nil { t.Fatalf("handler returned error: %v", err) } if rec.Code != http.StatusOK { t.Fatalf("expected status 200, got %d", rec.Code) } if syncer.from.IsZero() || syncer.to.IsZero() { t.Fatal("expected syncer to receive time bounds") } } func TestHandleStripeSyncInvalidTimestamp(t *testing.T) { syncer := &stubStripeSyncer{} handler := handleStripeSync(syncer) e := echo.New() req := httptest.NewRequest(http.MethodPost, "/api/stripe/sync", strings.NewReader(`{"from":"not-a-date"}`)) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() c := e.NewContext(req, rec) err := handler(c) if err == nil { t.Fatal("expected error for invalid timestamp") } httpErr, ok := err.(*echo.HTTPError) if !ok { t.Fatalf("expected HTTPError, got %T", err) } if httpErr.Code != http.StatusBadRequest { t.Fatalf("expected status 400, got %d", httpErr.Code) } }