diff --git a/models/user.go b/models/user.go index 8d16d5d..d8d2045 100644 --- a/models/user.go +++ b/models/user.go @@ -126,7 +126,12 @@ func (u *User) WakaTimeURL(fallback string) string { return fallback } +// HasActiveSubscription returns true if subscriptions are enabled on the server and the user has got one func (u *User) HasActiveSubscription() bool { + return conf.Get().Subscriptions.Enabled && u.HasActiveSubscriptionStrict() +} + +func (u *User) HasActiveSubscriptionStrict() bool { return u.SubscribedUntil != nil && u.SubscribedUntil.T().After(time.Now()) } diff --git a/models/user_test.go b/models/user_test.go index 305d43f..840aa80 100644 --- a/models/user_test.go +++ b/models/user_test.go @@ -1,6 +1,7 @@ package models import ( + conf "github.com/muety/wakapi/config" "github.com/stretchr/testify/assert" "testing" "time" @@ -18,3 +19,41 @@ func TestUser_TZ(t *testing.T) { assert.InDelta(t, time.Duration(offset1*int(time.Second)), sut1.TZOffset(), float64(1*time.Second)) assert.InDelta(t, time.Duration(offset2*int(time.Second)), sut2.TZOffset(), float64(1*time.Second)) } + +func TestUser_MinDataAge(t *testing.T) { + c := conf.Load("") + + var sut *User + + // test with unlimited retention time / clean-up disabled + c.App.DataRetentionMonths = -1 + c.Subscriptions.Enabled = false + sut = &User{} + assert.Zero(t, sut.MinDataAge()) + + // test with limited retention time / clean-up enabled, and subscriptions disabled + c.App.DataRetentionMonths = 1 + c.Subscriptions.Enabled = false + sut = &User{} + assert.WithinRange(t, sut.MinDataAge(), time.Now().AddDate(0, -1, -1), time.Now().AddDate(0, -1, 1)) + + // test with limited retention time, subscriptions enabled, and user hasn't got one + c.App.DataRetentionMonths = 1 + c.Subscriptions.Enabled = true + sut = &User{} + assert.WithinRange(t, sut.MinDataAge(), time.Now().AddDate(0, -1, -1), time.Now().AddDate(0, -1, 1)) + + // test with limited retention time, subscriptions disabled, but user still got (an expired) one + c.App.DataRetentionMonths = 1 + c.Subscriptions.Enabled = false + until2 := CustomTime(time.Now().AddDate(0, 0, -1)) + sut = &User{SubscribedUntil: &until2} + assert.WithinRange(t, sut.MinDataAge(), time.Now().AddDate(0, -1, -1), time.Now().AddDate(0, -1, 1)) + + // test with limited retention time, subscriptions enabled, and user has got one + c.App.DataRetentionMonths = 1 + c.Subscriptions.Enabled = true + until1 := CustomTime(time.Now().AddDate(0, 1, 0)) + sut = &User{SubscribedUntil: &until1} + assert.Zero(t, sut.MinDataAge()) +} diff --git a/routes/settings.go b/routes/settings.go index 0b54a9a..b99ae2d 100644 --- a/routes/settings.go +++ b/routes/settings.go @@ -181,7 +181,7 @@ func (h *SettingsHandler) actionUpdateUser(w http.ResponseWriter, r *http.Reques return http.StatusBadRequest, "", "invalid parameters" } - if user.Email == "" && h.config.Subscriptions.Enabled && user.HasActiveSubscription() { + if user.Email == "" && user.HasActiveSubscription() { return http.StatusBadRequest, "", "cannot unset email while subscription is active" } diff --git a/services/housekeeping.go b/services/housekeeping.go index 92b6ffb..b0d9cda 100644 --- a/services/housekeeping.go +++ b/services/housekeeping.go @@ -45,11 +45,7 @@ func (s *HousekeepingService) Schedule() { // schedule jobs for _, u := range users { - // don't clean data for subscribed users - if s.config.Subscriptions.Enabled && u.HasActiveSubscription() { - continue - } - + // don't clean data for subscribed users or when they otherwise have unlimited data access if u.MinDataAge().IsZero() { continue } diff --git a/services/imports/wakatime.go b/services/imports/wakatime.go index 626452f..287d96d 100644 --- a/services/imports/wakatime.go +++ b/services/imports/wakatime.go @@ -116,7 +116,11 @@ func (w *WakatimeHeartbeatImporter) Import(user *models.User, minFrom time.Time, } } - logbuch.Info("scheduling wakatime import for user '%s'", user.ID) + if minDataAge := user.MinDataAge(); minFrom.Before(minDataAge) { + logbuch.Info("wakatime data import for user '%s' capped to [%v, &v]", user.ID, minDataAge, maxTo) + } + + logbuch.Info("scheduling wakatime import for user '%s' (interval [%v, &v])", user.ID, minFrom, maxTo) if err := w.queue.Dispatch(func() { process(user, minFrom, maxTo, out) }); err != nil {