-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* date_time module and tests * docs * linting * some cleanup * some cleanup * remove broken tests and add new tests * this week test * make service rollover time configurable * split into two modules * more tests * 100% coverage * some docs * some docs * format * helper funcs * move test to helper func * docs * format * move private funcs to factory * format * alphabetize config * remove unused import * service range and tests * PR feedback * microsecond fidelity * microsecond fidelity * nil in range and docs * more tests * docs * move in_range? * call it date time range * docs * docs * one hundred percent * spec ref * format * tests * type spec * more date time tests * typo * some renaming * docs * naming and tests * remove log and allow error * add a mock for date_time * mocks, tests, format * docs * one hundred percent coverage * make test more clear * move test * docs * start work * logic looks solid * use helper func * tests * tests * tests * one hundred * dialyzer * format * specs * tests * spec error * change tests * type check * type check * pr feedback * make behaviour load consistent * remove livebook
- Loading branch information
1 parent
177282b
commit 9c7a295
Showing
16 changed files
with
270 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
defmodule Alerts.Repo.Behaviour do | ||
@moduledoc """ | ||
Behaviour for the Alerts repo. | ||
""" | ||
|
||
alias Alerts.Alert | ||
|
||
@doc """ | ||
Return all alerts for the given route ids. | ||
""" | ||
@callback by_route_ids([String.t()], DateTime.t()) :: [Alert.t()] | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
defmodule Dotcom.Alerts do | ||
@moduledoc """ | ||
A collection of functions that help to work with alerts in a unified way. | ||
""" | ||
|
||
alias Alerts.Alert | ||
|
||
@service_impacting_effects [:delay, :shuttle, :suspension, :station_closure] | ||
|
||
@doc """ | ||
Does the alert have an effect that is considered service-impacting? | ||
""" | ||
@spec service_impacting_alert?(Alert.t()) :: boolean() | ||
def service_impacting_alert?(%Alert{effect: effect}) do | ||
effect in @service_impacting_effects | ||
end | ||
|
||
@doc """ | ||
Returns a list of the alert effects that are considered service-impacting. | ||
""" | ||
@spec service_impacting_effects() :: [atom()] | ||
def service_impacting_effects(), do: @service_impacting_effects | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
defmodule Dotcom.Alerts.Disruptions.Subway do | ||
@moduledoc """ | ||
Disruptions are alerts that have `service_impacting_effects` grouped by `service_range`. | ||
""" | ||
|
||
import Dotcom.Alerts, only: [service_impacting_alert?: 1] | ||
import Dotcom.Routes, only: [subway_route_ids: 0] | ||
import Dotcom.Utils.ServiceDateTime, only: [service_range: 1] | ||
|
||
alias Alerts.Alert | ||
alias Dotcom.Utils | ||
|
||
@alerts_repo Application.compile_env!(:dotcom, :repo_modules)[:alerts] | ||
|
||
@doc """ | ||
Disruptions that occur any time after today's service range. | ||
""" | ||
@spec future_disruptions() :: %{Utils.ServiceDateTime.named_service_range() => [Alert.t()]} | ||
def future_disruptions() do | ||
disruption_groups() |> Map.take([:later_this_week, :next_week, :after_next_week]) | ||
end | ||
|
||
@doc """ | ||
Disruptions that occur during today's service range. | ||
""" | ||
@spec todays_disruptions() :: %{today: [Alert.t()]} | ||
def todays_disruptions() do | ||
disruption_groups() |> Map.take([:today]) | ||
end | ||
|
||
# Groups all disruption alerts by service range. | ||
# | ||
# 1. Gets all alerts for subway routes. | ||
# 2. Filters out non-service-impacting alerts | ||
# 3. Groups them according to service range. | ||
defp disruption_groups() do | ||
subway_route_ids() | ||
|> @alerts_repo.by_route_ids(Utils.DateTime.now()) | ||
|> Enum.filter(&service_impacting_alert?/1) | ||
|> Enum.reduce(%{}, &group_alerts/2) | ||
end | ||
|
||
# Looks at every active period for an alert and groups that alert by service range. | ||
# Alerts can overlap service ranges, in which case we want them to appear in both. | ||
defp group_alerts(alert, groups) do | ||
alert | ||
|> Map.get(:active_period) | ||
|> Enum.map(fn {start, stop} -> [service_range(start), service_range(stop)] end) | ||
|> List.flatten() | ||
|> Enum.uniq() | ||
|> Enum.reduce(groups, fn service_range, groups -> | ||
Map.update(groups, service_range, [alert], &(&1 ++ [alert])) | ||
end) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
defmodule Dotcom.Routes do | ||
@moduledoc """ | ||
A collection of functions that help to work with routes in a unified way. | ||
""" | ||
|
||
@subway_route_ids ["Blue", "Green", "Orange", "Red"] | ||
|
||
@doc """ | ||
Returns a list of route ids for all subway routes. | ||
""" | ||
@spec subway_route_ids() :: [String.t()] | ||
def subway_route_ids(), do: @subway_route_ids | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
defmodule Dotcom.Alerts.Disruptions.SubwayTest do | ||
use ExUnit.Case | ||
|
||
import Dotcom.Alerts, only: [service_impacting_effects: 0] | ||
import Dotcom.Alerts.Disruptions.Subway | ||
|
||
import Dotcom.Utils.ServiceDateTime, | ||
only: [ | ||
service_range_day: 0, | ||
service_range_later_this_week: 0, | ||
service_range_next_week: 0, | ||
service_range_after_next_week: 0 | ||
] | ||
|
||
import Mox | ||
|
||
alias Test.Support.Factories | ||
|
||
setup :verify_on_exit! | ||
|
||
setup _ do | ||
stub_with(Dotcom.Utils.DateTime.Mock, Dotcom.Utils.DateTime) | ||
|
||
:ok | ||
end | ||
|
||
describe "future_disruptions/0" do | ||
test "returns an empty map when there are no alerts" do | ||
expect(Alerts.Repo.Mock, :by_route_ids, fn _route_ids, _now -> | ||
[] | ||
end) | ||
|
||
# Exercise/Verify | ||
assert %{} = future_disruptions() | ||
end | ||
|
||
test "returns alerts for later this week, next week, and after next week" do | ||
# Setup | ||
alert_today = service_range_day() |> disruption_alert() | ||
alert_later_this_week = service_range_later_this_week() |> disruption_alert() | ||
alert_next_week = service_range_next_week() |> disruption_alert() | ||
|
||
{alert_after_next_week_start, _} = service_range_after_next_week() | ||
|
||
alert_after_next_week = | ||
{alert_after_next_week_start, Timex.shift(alert_after_next_week_start, days: 1)} | ||
|> disruption_alert() | ||
|
||
expect(Alerts.Repo.Mock, :by_route_ids, fn _route_ids, _now -> | ||
[alert_today, alert_later_this_week, alert_next_week, alert_after_next_week] | ||
end) | ||
|
||
# Exercise/Verify | ||
assert %{ | ||
later_this_week: [^alert_later_this_week], | ||
next_week: [^alert_next_week], | ||
after_next_week: [^alert_after_next_week] | ||
} = future_disruptions() | ||
end | ||
end | ||
|
||
describe "todays_disruptions/0" do | ||
test "returns an empty map when there are no alerts" do | ||
expect(Alerts.Repo.Mock, :by_route_ids, fn _route_ids, _now -> | ||
[] | ||
end) | ||
|
||
# Exercise/Verify | ||
assert %{} = todays_disruptions() | ||
end | ||
|
||
test "returns alerts for today only" do | ||
# Setup | ||
alert_today = service_range_day() |> disruption_alert() | ||
alert_next_week = service_range_next_week() |> disruption_alert() | ||
|
||
expect(Alerts.Repo.Mock, :by_route_ids, fn _route_ids, _now -> | ||
[alert_today, alert_next_week] | ||
end) | ||
|
||
# Exercise/Verify | ||
assert %{today: [^alert_today]} = todays_disruptions() | ||
end | ||
end | ||
|
||
defp disruption_alert(active_period) do | ||
Factories.Alerts.Alert.build(:alert, | ||
active_period: [active_period], | ||
effect: service_impacting_effects() |> Faker.Util.pick() | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
defmodule Dotcom.AlertsTest do | ||
use ExUnit.Case | ||
|
||
import Dotcom.Alerts | ||
|
||
describe "service_impacting_alert?/1" do | ||
test "returns true if the alert has an effect that is considered service-impacting" do | ||
# Setup | ||
effect = service_impacting_effects() |> Faker.Util.pick() | ||
alert = %Alerts.Alert{effect: effect} | ||
|
||
# Exercise/Verify | ||
assert service_impacting_alert?(alert) | ||
end | ||
|
||
test "returns false if the alert does not have an effect that is considered service-impacting" do | ||
# Setup | ||
alert = %Alerts.Alert{effect: :not_service_impacting} | ||
|
||
# Exercise/Verify | ||
refute service_impacting_alert?(alert) | ||
end | ||
end | ||
|
||
describe "service_impacting_effects/0" do | ||
test "returns a list of the alert effects as atoms" do | ||
# Exercise/Verify | ||
assert Enum.all?(service_impacting_effects(), &is_atom/1) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
defmodule Dotcom.RoutesTest do | ||
use ExUnit.Case | ||
|
||
import Dotcom.Routes | ||
|
||
describe "subway_route_ids/0" do | ||
test "returns a list of route ids" do | ||
# Exercise/Verify | ||
assert Enum.all?(subway_route_ids(), &is_binary/1) | ||
end | ||
end | ||
end |
Oops, something went wrong.