Skip to content

Commit 024e6bb

Browse files
authored
Prevent email reports when consolidated view ineligible (#5882)
* do not send email reports if consolidated view not ok to display * fix CE * more expressive condition in ok_to_send? * Map.get -> Map.fetch
1 parent b624f39 commit 024e6bb

File tree

4 files changed

+142
-22
lines changed

4 files changed

+142
-22
lines changed

lib/workers/send_email_report.ex

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
defmodule Plausible.Workers.SendEmailReport do
2+
use Plausible
23
use Plausible.Repo
34
use Oban.Worker, queue: :send_email_reports, max_attempts: 1
45

@@ -22,9 +23,9 @@ defmodule Plausible.Workers.SendEmailReport do
2223
)
2324
|> Repo.one()
2425

25-
report = site && Map.get(site, report_type)
26-
27-
if report do
26+
with %Plausible.Site{} <- site,
27+
%{} = report <- Map.fetch!(site, report_type),
28+
true <- ok_to_send?(site) do
2829
date_range = date_range(site, interval)
2930
report_name = report_name(interval, date_range.first)
3031
date_label = Calendar.strftime(date_range.last, "%-d %b %Y")
@@ -48,7 +49,7 @@ defmodule Plausible.Workers.SendEmailReport do
4849
|> Plausible.Mailer.send()
4950
end)
5051
else
51-
:discard
52+
_ -> :discard
5253
end
5354
end
5455

@@ -226,4 +227,14 @@ defmodule Plausible.Workers.SendEmailReport do
226227

227228
Date.range(first, last)
228229
end
230+
231+
on_ee do
232+
defp ok_to_send?(site) do
233+
Plausible.Sites.regular?(site) or
234+
(Plausible.Sites.consolidated?(site) and
235+
Plausible.ConsolidatedView.ok_to_display?(site.team))
236+
end
237+
else
238+
defp ok_to_send?(_site), do: always(true)
239+
end
229240
end

lib/workers/traffic_change_notifier.ex

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ defmodule Plausible.Workers.TrafficChangeNotifier do
22
@moduledoc """
33
Oban service sending out traffic drop/spike notifications
44
"""
5+
use Plausible
56
use Plausible.Repo
67
alias Plausible.Stats.{Query, Clickhouse}
78
alias Plausible.Site.TrafficChangeNotification
@@ -28,30 +29,32 @@ defmodule Plausible.Workers.TrafficChangeNotifier do
2829
preload: [site: {s, team: t}]
2930
)
3031

31-
for notification <- notifications do
32-
case notification.type do
33-
:spike ->
34-
current_visitors = Clickhouse.current_visitors(notification.site)
32+
for notification <- notifications, ok_to_send?(notification.site) do
33+
handle_notification(notification, now)
34+
end
3535

36-
if current_visitors >= notification.threshold do
37-
stats =
38-
notification.site
39-
|> get_traffic_spike_stats()
40-
|> Map.put(:current_visitors, current_visitors)
36+
:ok
37+
end
4138

42-
notify_spike(notification, stats, now)
43-
end
39+
defp handle_notification(%TrafficChangeNotification{type: :spike} = notification, now) do
40+
current_visitors = Clickhouse.current_visitors(notification.site)
4441

45-
:drop ->
46-
current_visitors = Clickhouse.current_visitors_12h(notification.site)
42+
if current_visitors >= notification.threshold do
43+
stats =
44+
notification.site
45+
|> get_traffic_spike_stats()
46+
|> Map.put(:current_visitors, current_visitors)
4747

48-
if current_visitors < notification.threshold do
49-
notify_drop(notification, current_visitors, now)
50-
end
51-
end
48+
notify_spike(notification, stats, now)
5249
end
50+
end
5351

54-
:ok
52+
defp handle_notification(%TrafficChangeNotification{type: :drop} = notification, now) do
53+
current_visitors = Clickhouse.current_visitors_12h(notification.site)
54+
55+
if current_visitors < notification.threshold do
56+
notify_drop(notification, current_visitors, now)
57+
end
5558
end
5659

5760
defp notify_spike(notification, stats, now) do
@@ -175,4 +178,14 @@ defmodule Plausible.Workers.TrafficChangeNotifier do
175178
)
176179
|> Repo.exists?()
177180
end
181+
182+
on_ee do
183+
defp ok_to_send?(site) do
184+
Plausible.Sites.regular?(site) or
185+
(Plausible.Sites.consolidated?(site) and
186+
Plausible.ConsolidatedView.ok_to_display?(site.team))
187+
end
188+
else
189+
defp ok_to_send?(_site), do: always(true)
190+
end
178191
end

test/workers/send_email_report_test.exs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,25 @@ defmodule Plausible.Workers.SendEmailReportTest do
158158
assert text_of_element(html_body, ".page-name") == "/"
159159
assert text_of_element(html_body, ".page-count") == "2"
160160
end
161+
162+
test "does not send weekly report for consolidated view with ok_to_display? false" do
163+
{:ok, team} = new_user() |> Plausible.Teams.get_or_create()
164+
165+
site = new_site(team: team)
166+
new_site(team: team)
167+
168+
consolidated_view = new_consolidated_view(team)
169+
170+
insert(:weekly_report, site: consolidated_view, recipients: ["[email protected]"])
171+
172+
Plausible.Repo.delete!(site)
173+
174+
refute Plausible.ConsolidatedView.ok_to_display?(team)
175+
176+
perform_job(SendEmailReport, %{"site_id" => consolidated_view.id, "interval" => "weekly"})
177+
178+
assert_no_emails_delivered()
179+
end
161180
end
162181

163182
test "renders correct signs (+/-) and trend colors for positive percentage changes" do
@@ -540,6 +559,25 @@ defmodule Plausible.Workers.SendEmailReportTest do
540559
assert goal_names == ["Signup", "Purchase", "Visit /thank-you"]
541560
assert goal_conversions == ["2", "1", "1"]
542561
end
562+
563+
test "does not send monthly report for consolidated view with ok_to_display? false" do
564+
{:ok, team} = new_user() |> Plausible.Teams.get_or_create()
565+
566+
site = new_site(team: team)
567+
new_site(team: team)
568+
569+
consolidated_view = new_consolidated_view(team)
570+
571+
insert(:monthly_report, site: consolidated_view, recipients: ["[email protected]"])
572+
573+
Plausible.Repo.delete!(site)
574+
575+
refute Plausible.ConsolidatedView.ok_to_display?(site.team)
576+
577+
perform_job(SendEmailReport, %{"site_id" => consolidated_view.id, "interval" => "monthly"})
578+
579+
assert_no_emails_delivered()
580+
end
543581
end
544582
end
545583
end

test/workers/traffic_change_notifier_test.exs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,29 @@ defmodule Plausible.Workers.TrafficChangeNotifierTest do
149149
assert html_body =~ @view_dashboard_text
150150
refute html_body =~ @review_installation_text
151151
end
152+
153+
test "does not notify traffic drop on consolidated view when ok_to_display? is false" do
154+
user = new_user()
155+
{:ok, team} = Plausible.Teams.get_or_create(user)
156+
site = new_site(team: team)
157+
new_site(team: team)
158+
159+
consolidated_view = new_consolidated_view(team)
160+
161+
Plausible.Repo.delete(site)
162+
163+
refute Plausible.ConsolidatedView.ok_to_display?(team)
164+
165+
insert(:drop_notification,
166+
site: consolidated_view,
167+
threshold: 10,
168+
recipients: [user.email]
169+
)
170+
171+
TrafficChangeNotifier.perform(nil)
172+
173+
assert_no_emails_delivered()
174+
end
152175
end
153176

154177
test "does not send notifications more than once every 12 hours" do
@@ -283,6 +306,41 @@ defmodule Plausible.Workers.TrafficChangeNotifierTest do
283306
assert html_body =~ "<b>2</b> visitors on <b>/a</b>"
284307
assert html_body =~ "<b>1</b> visitor on <b>/b</b>"
285308
end
309+
310+
test "does not notify traffic spike on consolidated view when ok_to_display? is false" do
311+
user = new_user()
312+
{:ok, team} = Plausible.Teams.get_or_create(user)
313+
site1 = new_site(team: team)
314+
site2 = new_site(team: team)
315+
316+
consolidated_view = new_consolidated_view(team)
317+
318+
insert(:spike_notification,
319+
site: consolidated_view,
320+
threshold: 2,
321+
recipients: ["[email protected]"]
322+
)
323+
324+
populate_stats(site1, [
325+
build(:pageview, timestamp: minutes_ago(1)),
326+
build(:pageview, timestamp: minutes_ago(2)),
327+
build(:pageview, timestamp: minutes_ago(3))
328+
])
329+
330+
Plausible.Repo.delete(site2)
331+
332+
refute Plausible.ConsolidatedView.ok_to_display?(team)
333+
334+
insert(:drop_notification,
335+
site: consolidated_view,
336+
threshold: 10,
337+
recipients: [user.email]
338+
)
339+
340+
TrafficChangeNotifier.perform(nil)
341+
342+
assert_no_emails_delivered()
343+
end
286344
end
287345

288346
test "ignores 'Direct / None' source" do

0 commit comments

Comments
 (0)