Skip to content

Commit f87b4be

Browse files
authored
Hotfix: forgot to add service change to diversions (#2474)
* add service change tod diversions page * docs * docs * docs * add time based tests * add time based tests
1 parent af98d43 commit f87b4be

File tree

6 files changed

+109
-68
lines changed

6 files changed

+109
-68
lines changed

lib/alerts/alert.ex

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,6 @@ defmodule Alerts.Alert do
3939
:unknown | @ongoing_effects
4040
]
4141

42-
@diversion_effects [
43-
:detour,
44-
:shuttle,
45-
:stop_closure,
46-
:station_closure,
47-
:suspension
48-
]
49-
5042
@lifecycles [:new, :ongoing, :ongoing_upcoming, :unknown, :upcoming]
5143

5244
defstruct id: "",
@@ -291,15 +283,6 @@ defmodule Alerts.Alert do
291283

292284
def high_severity_or_high_priority?(_), do: false
293285

294-
@spec diversion?(t) :: boolean()
295-
def diversion?(alert) do
296-
alert.effect in @diversion_effects &&
297-
alert.active_period
298-
|> List.first()
299-
|> Kernel.elem(0)
300-
|> Timex.after?(alert.created_at)
301-
end
302-
303286
@spec municipality(t) :: String.t() | nil
304287
def municipality(alert) do
305288
alert

lib/alerts/repo.ex

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule Alerts.Repo do
2+
import Dotcom.Alerts, only: [diversion_alert?: 1]
3+
24
alias Alerts.{Alert, Banner, Priority}
35
alias Alerts.Cache.Store
46
alias Alerts.Repo.Behaviour
@@ -33,15 +35,15 @@ defmodule Alerts.Repo do
3335
end
3436

3537
@doc """
36-
Get alerts that are diversion types: shuttle, station_closure, suspension.
38+
Get alerts that are diversions: detour, service change, shuttle, station closure, stop closure, or suspension.
3739
38-
We sort them so that earlier alerts are displaed first.
40+
Sort them so that earlier alerts are displaed first.
3941
"""
4042
@spec diversions_by_route_ids([String.t()], DateTime.t()) :: [Alert.t()]
4143
def diversions_by_route_ids(route_ids, now) do
4244
route_ids
4345
|> by_route_ids(now)
44-
|> Enum.filter(&Alert.diversion?/1)
46+
|> Enum.filter(&diversion_alert?/1)
4547
|> Enum.sort(fn a, b ->
4648
first = a.active_period |> List.first() |> elem(0)
4749
second = b.active_period |> List.first() |> elem(0)

lib/dotcom/alerts.ex

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,22 @@ defmodule Dotcom.Alerts do
88

99
@stops_repo_module Application.compile_env!(:dotcom, :repo_modules)[:stops]
1010

11+
@type diversion_effect_t() ::
12+
:detour | :service_change | :shuttle | :station_closure | :stop_closure | :suspension
13+
1114
@typedoc "Service alerts which typically impact rider experience."
1215
@type service_effect_t() :: :delay | :service_change | :shuttle | :suspension | :station_closure
1316

17+
# A keyword list of effects and the severity level necessary to make an alert a 'diversion.'
18+
@diversion_effects [
19+
detour: 1,
20+
service_change: 3,
21+
shuttle: 1,
22+
station_closure: 1,
23+
stop_closure: 1,
24+
suspension: 1
25+
]
26+
1427
# A keyword list of effects and the severity level necessary to make an alert 'service impacting.'
1528
@service_impacting_effects [
1629
delay: 1,
@@ -35,6 +48,22 @@ defmodule Dotcom.Alerts do
3548
|> Enum.sort_by(& &1.name)
3649
end
3750

51+
@doc """
52+
Does the alert have an effect/severity that is considered a diversion?
53+
And, was it planned?
54+
"""
55+
@spec diversion_alert?(Alert.t()) :: boolean()
56+
def diversion_alert?(alert) do
57+
effects_match?(@diversion_effects, alert) &&
58+
planned_alert?(alert)
59+
end
60+
61+
@doc """
62+
Returns a keyword list of the alert effects that are considered service-impacting and their severity levels.
63+
"""
64+
@spec diversion_effects() :: [{diversion_effect_t(), integer()}]
65+
def diversion_effects(), do: @diversion_effects
66+
3867
@doc """
3968
Does the alert match a group of effects/severities?
4069
"""
@@ -86,6 +115,14 @@ defmodule Dotcom.Alerts do
86115
effect == alert.effect && alert.severity >= severity
87116
end
88117

118+
# We consider an alert planned if the first active period starts after the alert was created.
119+
defp planned_alert?(alert) do
120+
alert.active_period
121+
|> List.first()
122+
|> Kernel.elem(0)
123+
|> Timex.after?(alert.created_at)
124+
end
125+
89126
# Take an alert and return the start time of the first active period.
90127
# Return nil if there is no active period.
91128
defp sort_by_start_time_mapper(alert) do

test/alerts/alerts_test.exs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ defmodule AlertsTest do
77

88
alias Alerts.Alert
99
alias Alerts.InformedEntity
10-
alias Test.Support.Factories
1110

1211
setup :verify_on_exit!
1312

@@ -148,48 +147,6 @@ defmodule AlertsTest do
148147
end
149148
end
150149

151-
describe "diversion?/1" do
152-
test "returns true when created at is before active period" do
153-
created_at = Timex.now()
154-
active_period = [{Timex.shift(created_at, days: 1), Timex.shift(created_at, days: 2)}]
155-
156-
alert =
157-
Factories.Alerts.Alert.build(:alert,
158-
active_period: active_period,
159-
created_at: created_at,
160-
effect: :shuttle
161-
)
162-
163-
assert diversion?(alert)
164-
end
165-
166-
test "returns false when created at is after active period" do
167-
created_at = Timex.now()
168-
active_period = [{Timex.shift(created_at, days: -2), Timex.shift(created_at, days: -1)}]
169-
170-
alert =
171-
Factories.Alerts.Alert.build(:alert,
172-
active_period: active_period,
173-
created_at: created_at,
174-
effect: :shuttle
175-
)
176-
177-
refute diversion?(alert)
178-
end
179-
180-
test "returns true for certain effects" do
181-
assert diversion?(Factories.Alerts.Alert.build(:alert, effect: :shuttle))
182-
assert diversion?(Factories.Alerts.Alert.build(:alert, effect: :stop_closure))
183-
assert diversion?(Factories.Alerts.Alert.build(:alert, effect: :station_closure))
184-
end
185-
186-
test "returns false for other effects" do
187-
refute diversion?(Factories.Alerts.Alert.build(:alert, effect: :access_issue))
188-
refute diversion?(Factories.Alerts.Alert.build(:alert, effect: :amber_alert))
189-
refute diversion?(Factories.Alerts.Alert.build(:alert, effect: :delay))
190-
end
191-
end
192-
193150
describe "municipality/1" do
194151
test "gets municipality from an alert's stops" do
195152
alert_with_muni = Alert.new(informed_entity: [%InformedEntity{stop: "some-stop"}])

test/alerts/repo_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ defmodule Alerts.RepoTest do
6666
describe "diversions_by_route_id/2" do
6767
test "returns only diversions for the given route_ids" do
6868
# Setup
69-
diversion = Factories.Alerts.Alert.build(:alert, effect: :shuttle)
70-
non_diversion = Factories.Alerts.Alert.build(:alert, effect: :delay)
69+
diversion = Factories.Alerts.Alert.build(:alert, effect: :service_change, severity: 3)
70+
non_diversion = Factories.Alerts.Alert.build(:alert, effect: :delay, severity: 1)
7171

7272
Store.update([diversion, non_diversion], nil)
7373

test/dotcom/alerts_test.exs

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ defmodule Dotcom.AlertsTest do
77
import Test.Support.Generators.DateTime,
88
only: [random_date_time: 0, random_time_range_date_time: 1]
99

10-
alias Alerts.Alert
1110
alias Test.Support.Factories
1211

1312
setup :verify_on_exit!
@@ -24,6 +23,69 @@ defmodule Dotcom.AlertsTest do
2423
:ok
2524
end
2625

26+
describe "diversion_alert?/1" do
27+
test "returns true if the alert has an effect that is considered a diversion" do
28+
# Setup
29+
{effect, severity} = diversion_effects() |> Faker.Util.pick()
30+
alert = Factories.Alerts.Alert.build(:alert, effect: effect, severity: severity)
31+
32+
# Exercise/Verify
33+
assert diversion_alert?(alert)
34+
end
35+
36+
test "returns false if the alert does not have an effect that is considered a diversion" do
37+
# Setup
38+
alert = Factories.Alerts.Alert.build(:alert, effect: :not_a_diversion)
39+
40+
# Exercise/Verify
41+
refute diversion_alert?(alert)
42+
end
43+
44+
test "returns true when created at is before active period" do
45+
# Setup
46+
created_at = Timex.now()
47+
active_period = [{Timex.shift(created_at, days: 1), Timex.shift(created_at, days: 2)}]
48+
49+
{effect, severity} = diversion_effects() |> Faker.Util.pick()
50+
51+
alert =
52+
Factories.Alerts.Alert.build(:alert,
53+
active_period: active_period,
54+
created_at: created_at,
55+
effect: effect,
56+
severity: severity
57+
)
58+
59+
# Exercise/Verify
60+
assert diversion_alert?(alert)
61+
end
62+
63+
test "returns false when created at is after active period" do
64+
created_at = Timex.now()
65+
active_period = [{Timex.shift(created_at, days: -2), Timex.shift(created_at, days: -1)}]
66+
67+
{effect, severity} = diversion_effects() |> Faker.Util.pick()
68+
69+
alert =
70+
Factories.Alerts.Alert.build(:alert,
71+
active_period: active_period,
72+
created_at: created_at,
73+
effect: effect,
74+
severity: severity
75+
)
76+
77+
# Exercise/Verify
78+
refute diversion_alert?(alert)
79+
end
80+
end
81+
82+
describe "diversion_effects/0" do
83+
test "returns a list of the alert effects as keywords" do
84+
# Exercise/Verify
85+
assert Keyword.keyword?(diversion_effects())
86+
end
87+
end
88+
2789
describe "affected_stations/1" do
2890
test "returns a list of stations that are affected by the alert" do
2991
# Setup
@@ -52,15 +114,15 @@ defmodule Dotcom.AlertsTest do
52114
test "returns true if the alert has an effect that is considered service-impacting" do
53115
# Setup
54116
{effect, severity} = service_impacting_effects() |> Faker.Util.pick()
55-
alert = %Alert{effect: effect, severity: severity}
117+
alert = Factories.Alerts.Alert.build(:alert, effect: effect, severity: severity)
56118

57119
# Exercise/Verify
58120
assert service_impacting_alert?(alert)
59121
end
60122

61123
test "returns false if the alert does not have an effect that is considered service-impacting" do
62124
# Setup
63-
alert = %Alert{effect: :not_service_impacting}
125+
alert = Factories.Alerts.Alert.build(:alert, effect: :not_service_impacting)
64126

65127
# Exercise/Verify
66128
refute service_impacting_alert?(alert)

0 commit comments

Comments
 (0)