FIX: correctly compute the window for email summaries

In 958437e7dd we ensured that the email summaries are properly sent based on 'digest_attempted_at' for people who barely/never visit the forum.

This fixed the "frequency" of the email summaries but introduced a bug where the digest would be sent even though there wasn't anything new since for some users.

The logic we use to compute the threshold date for the content to be included in the digest was

```ruby
@since = opts[:since] || user.last_seen_at || user.user_stat&.digest_attempted_at || 1.month.ago
```

It was working as expected for users who haven never been seen but for users who have connected at least once, we would use their "last_seen_at" date as the "threshold date" for the content to be sent in a summary 😬

This fix changes the logic to be the most recent date amongst the `last_seen_at`, `digest_attempted_at` and `1.month.ago` so it's correctly handling cases where

- user has never been seen nor emailed a summary
- user has been seen in a while but has recently been sent a summary
- user has been sent a summary recently but hasn't been seen in a while.
This commit is contained in:
Régis Hanol 2024-05-27 17:33:41 +02:00
parent 6a21143d83
commit 5f6b6e9818
2 changed files with 25 additions and 1 deletions

View File

@ -224,7 +224,8 @@ class UserNotifications < ActionMailer::Base
build_summary_for(user)
@unsubscribe_key = UnsubscribeKey.create_key_for(@user, UnsubscribeKey::DIGEST_TYPE)
@since = opts[:since] || user.last_seen_at || user.user_stat&.digest_attempted_at || 1.month.ago
@since = opts[:since].presence
@since ||= [user.last_seen_at, user.user_stat&.digest_attempted_at, 1.month.ago].compact.max
# Fetch some topics and posts to show
digest_opts = {

View File

@ -450,6 +450,29 @@ RSpec.describe UserNotifications do
expect(html).to match(' lang="pl-PL"')
expect(html).to match(' xml:lang="pl-PL"')
end
it "uses digest_attempted_at when user hasn't been seen in a while" do
user.update!(last_seen_at: 7.days.ago)
user.user_stat.update!(digest_attempted_at: 30.minutes.ago)
expect(email.to).to be_nil
end
it "uses last_seen_at when user has been sent a digest in a while" do
user.update!(last_seen_at: 30.minutes.ago)
user.user_stat.update!(digest_attempted_at: 7.days.ago)
expect(email.to).to be_nil
end
it "caps at 1 month when user has never been seen or sent a digest" do
old_topic = Fabricate(:topic, created_at: 2.months.ago)
user.update!(last_seen_at: nil)
user.user_stat.update!(digest_attempted_at: nil)
expect(email.to).to contain_exactly(user.email)
html = email.html_part.body.to_s
expect(html).not_to include(old_topic.title)
end
end
end