Skip to content

Commit

Permalink
cleanup: Add more alert factories for use in SystemStatus.SubwayTests (
Browse files Browse the repository at this point in the history
…#2347)

* cleanup: Add more alert factories for use in SystemStatus.SubwayTests

* fix: Use InformedEntitySet.new/1 rather than its factory

...in order to make sure that the informed entity set is consistent,
since new/1 does some processing that gets bypassed by the factory
  • Loading branch information
joshlarson authored Feb 13, 2025
1 parent 60d191c commit 75829cb
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 93 deletions.
161 changes: 71 additions & 90 deletions test/dotcom/system_status/subway_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ defmodule Dotcom.SystemStatus.SubwayTest do
alias Dotcom.Alerts
alias Dotcom.SystemStatus.Subway
alias Test.Support.Factories.Alerts.Alert
alias Test.Support.Factories.Alerts.InformedEntity
alias Test.Support.Factories.Alerts.InformedEntitySet

@lines_without_branches List.delete(Subway.lines(), "Green")

Expand All @@ -30,7 +28,11 @@ defmodule Dotcom.SystemStatus.SubwayTest do
affected_route_id = Faker.Util.pick(@lines_without_branches)
time = time_today()
effect = Faker.Util.pick(Alerts.service_impacting_effects())
alerts = [current_alert(route_id: affected_route_id, time: time, effect: effect)]

alerts = [
Alert.build(:alert_for_route, route_id: affected_route_id, effect: effect)
|> Alert.active_during(time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand All @@ -49,7 +51,11 @@ defmodule Dotcom.SystemStatus.SubwayTest do
affected_route_id = Faker.Util.pick(@lines_without_branches)
time = time_today()
effect = Faker.Util.pick(Alerts.service_impacting_effects())
alerts = [current_alert(route_id: affected_route_id, time: time, effect: effect)]

alerts = [
Alert.build(:alert_for_route, route_id: affected_route_id, effect: effect)
|> Alert.active_during(time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand All @@ -67,7 +73,11 @@ defmodule Dotcom.SystemStatus.SubwayTest do
# Setup
affected_route_id = Faker.Util.pick(@lines_without_branches)
time = time_today()
alerts = [current_alert(route_id: affected_route_id, time: time)]

alerts = [
Alert.build(:alert_for_route, route_id: affected_route_id)
|> Alert.active_during(time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand All @@ -86,7 +96,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
affected_route_id = Faker.Util.pick(@lines_without_branches)
time = time_today()

alerts = [current_alert(route_id: affected_route_id, time: time)]
alerts = [
Alert.build(:alert_for_route, route_id: affected_route_id)
|> Alert.active_during(time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand All @@ -111,7 +124,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
time = time_today()
alert_start_time = time_after(time)

alerts = [future_alert(route_id: affected_route_id, start_time: alert_start_time)]
alerts = [
Alert.build(:alert_for_route, route_id: affected_route_id)
|> Alert.active_starting_at(alert_start_time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand All @@ -134,7 +150,7 @@ defmodule Dotcom.SystemStatus.SubwayTest do
alert_start_time = time_before(time)

alerts = [
alert(
Alert.build(:alert_for_route,
route_id: affected_route_id,
effect: effect,
active_period: [{alert_start_time, nil}]
Expand Down Expand Up @@ -165,7 +181,7 @@ defmodule Dotcom.SystemStatus.SubwayTest do
expired_alert_start_time = time_before(expired_alert_end_time)

alerts = [
alert(
Alert.build(:alert_for_route,
route_id: affected_route_id,
active_period: [
{expired_alert_start_time, expired_alert_end_time},
Expand Down Expand Up @@ -199,8 +215,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
|> Enum.sort(:desc)

alerts = [
current_alert(route_id: affected_route_id, time: time, effect: effect1),
current_alert(route_id: affected_route_id, time: time, effect: effect2)
Alert.build(:alert_for_route, route_id: affected_route_id, effect: effect1)
|> Alert.active_during(time),
Alert.build(:alert_for_route, route_id: affected_route_id, effect: effect2)
|> Alert.active_during(time)
]

# Exercise
Expand All @@ -224,8 +242,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
future_alert_start_time = time_after(time)

alerts = [
future_alert(route_id: affected_route_id, start_time: future_alert_start_time),
current_alert(route_id: affected_route_id, time: time)
Alert.build(:alert_for_route, route_id: affected_route_id)
|> Alert.active_starting_at(future_alert_start_time),
Alert.build(:alert_for_route, route_id: affected_route_id)
|> Alert.active_during(time)
]

# Exercise
Expand All @@ -249,8 +269,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
effect = Faker.Util.pick(Alerts.service_impacting_effects())

alerts = [
current_alert(route_id: affected_route_id, time: time, effect: effect),
current_alert(route_id: affected_route_id, time: time, effect: effect)
Alert.build(:alert_for_route, route_id: affected_route_id, effect: effect)
|> Alert.active_during(time),
Alert.build(:alert_for_route, route_id: affected_route_id, effect: effect)
|> Alert.active_during(time)
]

# Exercise
Expand All @@ -275,8 +297,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
effect = Faker.Util.pick(Alerts.service_impacting_effects())

alerts = [
future_alert(route_id: affected_route_id, start_time: start_time, effect: effect),
future_alert(route_id: affected_route_id, start_time: start_time, effect: effect)
Alert.build(:alert_for_route, route_id: affected_route_id, effect: effect)
|> Alert.active_starting_at(start_time),
Alert.build(:alert_for_route, route_id: affected_route_id, effect: effect)
|> Alert.active_starting_at(start_time)
]

# Exercise
Expand All @@ -302,7 +326,8 @@ defmodule Dotcom.SystemStatus.SubwayTest do
alerts =
GreenLine.branch_ids()
|> Enum.map(fn route_id ->
current_alert(route_id: route_id, time: time, effect: effect)
Alert.build(:alert_for_route, route_id: route_id, effect: effect)
|> Alert.active_during(time)
end)

# Exercise
Expand All @@ -324,7 +349,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
time = time_today()
effect = Faker.Util.pick(Alerts.service_impacting_effects())

alerts = [current_alert(route_id: affected_branch_id, effect: effect, time: time)]
alerts = [
Alert.build(:alert_for_route, route_id: affected_branch_id, effect: effect)
|> Alert.active_during(time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand All @@ -345,7 +373,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
time = time_today()
effect = Faker.Util.pick(Alerts.service_impacting_effects())

alerts = [current_alert(route_id: affected_branch_id, effect: effect, time: time)]
alerts = [
Alert.build(:alert_for_route, route_id: affected_branch_id, effect: effect)
|> Alert.active_during(time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand All @@ -368,7 +399,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
time = time_today()
effect = Faker.Util.pick(Alerts.service_impacting_effects())

alerts = [current_alert(route_id: affected_branch_id, effect: effect, time: time)]
alerts = [
Alert.build(:alert_for_route, route_id: affected_branch_id, effect: effect)
|> Alert.active_during(time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand Down Expand Up @@ -398,8 +432,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
Faker.Util.sample_uniq(2, fn -> Faker.Util.pick(Alerts.service_impacting_effects()) end)

alerts = [
current_alert(route_id: affected_branch_id1, effect: effect1, time: time),
current_alert(route_id: affected_branch_id2, effect: effect2, time: time)
Alert.build(:alert_for_route, route_id: affected_branch_id1, effect: effect1)
|> Alert.active_during(time),
Alert.build(:alert_for_route, route_id: affected_branch_id2, effect: effect2)
|> Alert.active_during(time)
]

# Exercise
Expand All @@ -421,7 +457,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
# Setup
time = time_today()

alerts = [current_alert(route_id: "Red", time: time)]
alerts = [
Alert.build(:alert_for_route, route_id: "Red")
|> Alert.active_during(time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand All @@ -441,7 +480,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
time = time_today()
effect = Faker.Util.pick(Alerts.service_impacting_effects())

alerts = [current_alert(route_id: "Mattapan", effect: effect, time: time)]
alerts = [
Alert.build(:alert_for_route, route_id: "Mattapan", effect: effect)
|> Alert.active_during(time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand All @@ -459,7 +501,10 @@ defmodule Dotcom.SystemStatus.SubwayTest do
# Setup
time = time_today()

alerts = [current_alert(route_id: "Mattapan", time: time)]
alerts = [
Alert.build(:alert_for_route, route_id: "Mattapan")
|> Alert.active_during(time)
]

# Exercise
groups = Subway.subway_status(alerts, time)
Expand Down Expand Up @@ -513,68 +558,4 @@ defmodule Dotcom.SystemStatus.SubwayTest do
defp between(time1, time2) do
Faker.DateTime.between(time1, time2) |> Timex.to_datetime("America/New_York")
end

# Returns a random alert that will be active at the time given by
# the required `:time` opt.
#
# Required opts:
# - route_id
# - time
#
# Optional opts:
# - effect (default behavior is to choose an effect at random)
defp current_alert(opts) do
{time, opts} = opts |> Keyword.pop!(:time)

start_time = time_before(time)
end_time = time_after(time)

opts
|> Keyword.put_new(:active_period, [{start_time, end_time}])
|> alert()
end

# Returns a random alert whose active_period starts at the provided
# `:start_time` opt.
#
# Required opts:
# - route_id
# - start_time
#
# Optional opts:
# - effect (default behavior is to choose an effect at random)
defp future_alert(opts) do
{start_time, opts} = opts |> Keyword.pop!(:start_time)

opts
|> Keyword.put_new(:active_period, [{start_time, time_after(start_time)}])
|> alert()
end

# Returns a random alert for the given `:route_id` and
# `:active_period` opts.
#
# Required opts:
# - route_id
# - active_period (Note that this is an array)
#
# Optional opts:
# - effect (default behavior is to choose an effect at random)
defp alert(opts) do
route_id = opts |> Keyword.fetch!(:route_id)
effect = opts[:effect] || Faker.Util.pick(Alerts.service_impacting_effects())
active_period = opts |> Keyword.fetch!(:active_period)

Alert.build(:alert,
effect: effect,
informed_entity:
InformedEntitySet.build(:informed_entity_set,
route: route_id,
entities: [
InformedEntity.build(:informed_entity, route: route_id)
]
),
active_period: active_period
)
end
end
44 changes: 41 additions & 3 deletions test/support/factories/alerts/alert.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ defmodule Test.Support.Factories.Alerts.Alert do

use ExMachina

alias Alerts.{Alert, Priority}
alias Test.Support.Factories.Alerts.InformedEntitySet
alias Alerts.{Alert, InformedEntitySet, Priority}
alias Test.Support.Factories

def alert_factory do
%Alert{
Expand All @@ -20,12 +20,50 @@ defmodule Test.Support.Factories.Alerts.Alert do
header: Faker.Lorem.Shakespeare.king_richard_iii(),
image: Faker.Internet.image_url(),
image_alternative_text: Faker.Lorem.Shakespeare.king_richard_iii(),
informed_entity: InformedEntitySet.build(:informed_entity_set),
informed_entity: Factories.Alerts.InformedEntitySet.build(:informed_entity_set),
lifecycle: Alert.lifecycles() |> Faker.Util.pick(),
priority: Priority.priority_levels() |> Faker.Util.pick(),
severity: :rand.uniform(10),
updated_at: Timex.now(),
url: Faker.Internet.url()
}
end

def alert_for_route_factory(attrs) do
{route_id, attrs} = Map.pop(attrs, :route_id)

build(
:alert,
attrs
|> Map.put(
:informed_entity,
InformedEntitySet.new([
Factories.Alerts.InformedEntity.build(:informed_entity, route: route_id)
])
)
)
end

def active_during(alert, time) do
%{alert | active_period: [{time_before(time), time_after(time)}]}
end

def active_starting_at(alert, start_time) do
%{alert | active_period: [{start_time, time_after(start_time)}]}
end

# Returns a random time during the day today before the time provided.
defp time_before(time) do
between(Timex.beginning_of_day(time), time)
end

# Returns a random time during the day today after the time provided.
defp time_after(time) do
between(time, Timex.end_of_day(time))
end

# Returns a random time between the times provided in the Eastern time zone.
defp between(time1, time2) do
Faker.DateTime.between(time1, time2) |> Timex.to_datetime("America/New_York")
end
end

0 comments on commit 75829cb

Please sign in to comment.