Skip to content

Commit 5cf7de3

Browse files
Merge branch 'master' into rm-haverhill-test-change
2 parents a897623 + 5d960ec commit 5cf7de3

40 files changed

+178
-1634
lines changed

.tool-versions

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
elixir 1.16.3-otp-25
2-
erlang 25.3.2.12
1+
elixir 1.17.3-otp-27
2+
erlang 27.2
33
python 3.9.16
44
poetry 1.7.0

Dockerfile

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
ARG ELIXIR_VERSION=1.16.3
2-
ARG ERLANG_VERSION=25.3.2.12
3-
ARG ALPINE_VERSION=3.17.7
1+
ARG ELIXIR_VERSION=1.17.3
2+
ARG ERLANG_VERSION=27.2
3+
ARG ALPINE_VERSION=3.21.0
44

55
FROM hexpm/elixir:${ELIXIR_VERSION}-erlang-${ERLANG_VERSION}-alpine-${ALPINE_VERSION} as builder
66

@@ -28,7 +28,7 @@ RUN mix release
2828
# The one the elixir image was built with
2929
FROM alpine:${ALPINE_VERSION}
3030

31-
RUN apk add --no-cache libssl1.1 dumb-init libstdc++ libgcc ncurses-libs && \
31+
RUN apk add --no-cache libssl3 dumb-init libstdc++ libgcc ncurses-libs && \
3232
mkdir /work /api && \
3333
adduser -D api && chown api /work
3434

apps/api_web/.sobelow-skips

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11

22
89AB244CFEA58A837123CC326E49CD13
3-
C925E5F931492531D9372392664AE12C
3+
C925E5F931492531D9372392664AE12C
4+
CB8E15060F63E711108608C13BA30278

apps/api_web/config/config.exs

+10-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,16 @@ config :api_web, :versions,
5151

5252
config :logger, :console,
5353
format: "$date $time $metadata[$level] $message\n",
54-
metadata: [:request_id]
54+
metadata: [
55+
:request_id,
56+
:api_key,
57+
:ip,
58+
:records,
59+
:api_version,
60+
:concurrent,
61+
:metadata_keep,
62+
:metadata_value
63+
]
5564

5665
# JSON-API configuration
5766
config :phoenix, json_library: Jason

apps/api_web/config/prod.exs

+1-3
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ config :logger,
4646
level: :info,
4747
backends: [:console, Sentry.LoggerBackend]
4848

49-
config :logger, :console,
50-
format: "$dateT$time [$level] node=$node $metadata$message\n",
51-
metadata: [:request_id, :api_key, :ip, :records, :api_version, :concurrent]
49+
config :logger, :console, format: "$dateT$time [$level] node=$node $metadata$message\n"
5250

5351
config :ehmon, :report_mf, {:ehmon, :info_report}
5452

apps/api_web/lib/api_web/api_controller_helpers.ex

+6-4
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@ defmodule ApiWeb.ApiControllerHelpers do
3939
end
4040

4141
def index(module, conn, params) do
42-
conn
43-
|> get_format()
44-
|> index_for_format()
45-
|> apply(:call, [conn, module, params])
42+
mod =
43+
conn
44+
|> get_format()
45+
|> index_for_format()
46+
47+
mod.call(conn, module, params)
4648
end
4749

4850
def call(conn, module, params) do

apps/api_web/lib/api_web/controllers/prediction_controller.ex

+8-10
Original file line numberDiff line numberDiff line change
@@ -102,19 +102,17 @@ defmodule ApiWeb.PredictionController do
102102
{:error, :only_route_type}
103103

104104
p when map_size(p) > 0 ->
105-
filtered_params
106-
|> Params.split_on_comma("trip")
105+
trip_ids = Params.split_on_comma(filtered_params, "trip")
106+
107+
{trip_ids, route_pattern_ids}
107108
|> case do
108-
[] ->
109-
case route_pattern_ids do
110-
[] ->
111-
all_stops_and_routes(stop_ids, route_ids, matchers)
109+
{[], []} ->
110+
all_stops_and_routes(stop_ids, route_ids, matchers)
112111

113-
route_pattern_ids ->
114-
all_stops_and_route_patterns(stop_ids, route_pattern_ids, matchers)
115-
end
112+
{[], route_pattern_ids} ->
113+
all_stops_and_route_patterns(stop_ids, route_pattern_ids, matchers)
116114

117-
trip_ids ->
115+
{trip_ids, _} ->
118116
all_stops_and_trips(stop_ids, trip_ids, matchers)
119117
end
120118
|> Prediction.filter_by_route_type(route_types)

apps/api_web/lib/api_web/event_stream/diff.ex

+12-11
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,7 @@ defmodule ApiWeb.EventStream.Diff do
2323
if update_size <= map_size(list_2_map) do
2424
add = Enum.filter(map_list_2, &item_in_map(added_map, &1))
2525
update = Map.values(updated_map)
26-
27-
remove =
28-
map_list_1
29-
|> Enum.flat_map(fn item ->
30-
if item_in_map(removed_map, item) do
31-
[Map.take(item, ~w(id type))]
32-
else
33-
[]
34-
end
35-
end)
36-
|> Enum.reverse()
26+
remove = find_removed_items(map_list_1, removed_map)
3727

3828
%{
3929
add: add,
@@ -50,6 +40,17 @@ defmodule ApiWeb.EventStream.Diff do
5040
%{reset: [map_list_2]}
5141
end
5242

43+
defp find_removed_items(map, removed_map) do
44+
map
45+
|> Enum.flat_map(fn item ->
46+
if(item_in_map(removed_map, item),
47+
do: [Map.take(item, ~w(id type))],
48+
else: []
49+
)
50+
end)
51+
|> Enum.reverse()
52+
end
53+
5354
defp by_key(%{"type" => type, "id" => id} = item), do: {{type, id}, item}
5455

5556
defp item_in_map(map, %{"type" => type, "id" => id}) do

apps/api_web/lib/api_web/plugs/modified_since_handler.ex

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ defmodule ApiWeb.Plugs.ModifiedSinceHandler do
5151
last_modified_header = State.Metadata.last_modified_header(mod),
5252
conn = Plug.Conn.put_resp_header(conn, "last-modified", last_modified_header),
5353
{conn, [if_modified_since_header]} <- {conn, get_req_header(conn, "if-modified-since")},
54-
{conn, false} <- {conn, is_modified?(last_modified_header, if_modified_since_header)} do
54+
{conn, false} <- {conn, modified?(last_modified_header, if_modified_since_header)} do
5555
conn
5656
|> send_resp(:not_modified, "")
5757
|> halt()
@@ -64,12 +64,12 @@ defmodule ApiWeb.Plugs.ModifiedSinceHandler do
6464
end
6565
end
6666

67-
def is_modified?(same, same) do
67+
def modified?(same, same) do
6868
# shortcut if the headers have the same value
6969
false
7070
end
7171

72-
def is_modified?(first, second) do
72+
def modified?(first, second) do
7373
with {:ok, first_val} <- modified_value(first),
7474
{:ok, second_val} <- modified_value(second) do
7575
first_val > second_val

apps/api_web/lib/api_web/swagger_helpers.ex

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ defmodule ApiWeb.SwaggerHelpers do
8080
@spec carriages_description() :: String.t()
8181
def carriages_description do
8282
"""
83-
Carriage-level crowding details. See [GTFS-realtime multi_carriage_details](https://gtfs.org/realtime/reference/#message-CarriageDetails).
83+
Carriage-level crowding details. See [GTFS-realtime multi_carriage_details](https://gtfs.org/documentation/realtime/reference/#message-carriagedetails).
8484
"""
8585
end
8686

@@ -141,7 +141,7 @@ defmodule ApiWeb.SwaggerHelpers do
141141
:query,
142142
:string,
143143
"""
144-
Filter by route_type: https://developers.google.com/transit/gtfs/reference/routes-file.
144+
Filter by route_type: https://gtfs.org/documentation/schedule/reference/#routestxt.
145145
146146
Multiple `route_type` #{comma_separated_list()}.
147147

apps/api_web/mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ defmodule ApiWeb.Mixfile do
8181
{:jason, "~> 1.4"},
8282
{:stream_data, "~> 0.5", only: :test},
8383
{:sobelow, "~> 0.11", only: :dev, runtime: false},
84-
{:recaptcha, git: "https://github.com/samueljseay/recaptcha.git", tag: "71cd746"},
84+
{:recaptcha, git: "https://github.com/samueljseay/recaptcha.git", ref: "71cd746be987f6834c1a933f5d2f934350e55060"},
8585
{:sentry, "~> 8.0"},
8686
{:qr_code, "~> 3.0"},
8787
{:nimble_totp, "~> 1.0"}

apps/api_web/test/api_web/canary_test.exs

-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,5 @@ defmodule ApiWeb.CanaryTest do
4242

4343
assert {:error, "expect function/0 for notify_fn, got nil"} =
4444
Canary.start_link(notify_fn: nil)
45-
46-
assert_receive {:EXIT, _, "expect function/0 for notify_fn, got nil"}
4745
end
4846
end

apps/api_web/test/api_web/controllers/alert_controller_test.exs

-3
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ defmodule ApiWeb.AlertControllerTest do
5050

5151
setup tags do
5252
State.Stop.new_state([%Model.Stop{}])
53-
State.Trip.new_state([])
54-
State.Route.new_state([])
55-
State.Schedule.new_state([])
5653
State.RoutesPatternsAtStop.update!()
5754

5855
Facility.new_state([

apps/api_web/test/api_web/controllers/health_controller_test.exs

-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ defmodule ApiWeb.HealthControllerTest do
66
end
77

88
test "defaults to 503", %{conn: conn} do
9-
State.Alert.new_state([])
10-
State.Schedule.new_state([])
119
State.StopsOnRoute.update!()
1210
conn = get(conn, health_path(conn, :index))
1311
assert json_response(conn, 503)

apps/api_web/test/api_web/controllers/prediction_controller/sort_by_arrival_time_test.exs

+1-6
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,11 @@ defmodule ApiWeb.PredictionController.SortByArrivalTimeTest do
6161
}
6262
]
6363

64-
setup_all do
64+
setup %{conn: conn} do
6565
# stop is needed since we look up parent stops
6666
State.Stop.new_state([@stop, @parent_stop])
67-
State.Trip.new_state([])
6867
State.Route.new_state([@route1, @route2, @route3])
6968
State.Prediction.new_state(Enum.shuffle(@cr_predictions))
70-
:ok
71-
end
72-
73-
setup %{conn: conn} do
7469
{:ok, conn: put_req_header(conn, "accept", "application/json")}
7570
end
7671

apps/api_web/test/api_web/controllers/prediction_controller_test.exs

-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ defmodule ApiWeb.PredictionControllerTest do
4444
@cr_prediction hd(@cr_predictions)
4545

4646
setup %{conn: conn} do
47-
State.Trip.new_state([])
4847
# stop is needed since we look up parent stops
4948
State.Stop.new_state([@stop, @parent_stop, %Stop{id: "2"}])
5049
State.Prediction.new_state(@cr_predictions)
@@ -584,7 +583,6 @@ defmodule ApiWeb.PredictionControllerTest do
584583

585584
test "does not return alerts when no alerts exist", %{conn: conn} do
586585
different_route_prediction = %{@cr_prediction | route_id: "red", trip_id: "trip2"}
587-
State.Alert.new_state([])
588586
State.Prediction.new_state([different_route_prediction, @cr_prediction])
589587

590588
include_nothing_conn =
@@ -626,7 +624,6 @@ defmodule ApiWeb.PredictionControllerTest do
626624
%{conn: conn} do
627625
# run it 100 times since it's a race condition between State.Prediction and State.Trip.Added
628626
for _ <- 0..100 do
629-
State.Prediction.new_state([])
630627
# wait for State,Trip.Added to clear
631628
State.Trip.Added.last_updated()
632629
# need a stop ID to generate an Added trip

apps/api_web/test/api_web/controllers/route_pattern_controller_test.exs

+26-20
Original file line numberDiff line numberDiff line change
@@ -261,42 +261,48 @@ defmodule ApiWeb.RoutePatternControllerTest do
261261
route_id: "route1",
262262
direction_id: 0,
263263
canonical: true,
264-
typicality: 5
264+
typicality: 5,
265+
sort_order: 1
265266
},
266267
%RoutePattern{
267268
id: "rp2",
268269
route_id: "route1",
269270
direction_id: 1,
270271
canonical: true,
271-
typicality: 5
272+
typicality: 5,
273+
sort_order: 2
272274
},
273275
%RoutePattern{
274276
id: "rp3",
275277
route_id: "route2",
276278
direction_id: 0,
277279
canonical: false,
278-
typicality: 5
280+
typicality: 5,
281+
sort_order: 3
279282
},
280283
%RoutePattern{
281284
id: "rp4",
282285
route_id: "route2",
283286
direction_id: 1,
284287
canonical: false,
285-
typicality: 5
288+
typicality: 5,
289+
sort_order: 4
286290
},
287291
%RoutePattern{
288292
id: "rp5",
289293
route_id: "route3",
290294
direction_id: 0,
291295
canonical: false,
292-
typicality: 5
296+
typicality: 5,
297+
sort_order: 5
293298
},
294299
%RoutePattern{
295300
id: "rp6",
296301
route_id: "route3",
297302
direction_id: 1,
298303
canonical: false,
299-
typicality: 5
304+
typicality: 5,
305+
sort_order: 6
300306
}
301307
]
302308
end
@@ -336,6 +342,10 @@ defmodule ApiWeb.RoutePatternControllerTest do
336342
)
337343

338344
assert [
345+
%{
346+
"id" => "rp3",
347+
"attributes" => %{"direction_id" => 0, "canonical" => false}
348+
},
339349
%{
340350
"id" => "rp4",
341351
"attributes" => %{"direction_id" => 1, "canonical" => false}
@@ -344,10 +354,6 @@ defmodule ApiWeb.RoutePatternControllerTest do
344354
"id" => "rp5",
345355
"attributes" => %{"direction_id" => 0, "canonical" => false}
346356
},
347-
%{
348-
"id" => "rp3",
349-
"attributes" => %{"direction_id" => 0, "canonical" => false}
350-
},
351357
%{
352358
"id" => "rp6",
353359
"attributes" => %{"direction_id" => 1, "canonical" => false}
@@ -368,28 +374,28 @@ defmodule ApiWeb.RoutePatternControllerTest do
368374

369375
assert [
370376
%{
371-
"id" => "rp4",
372-
"attributes" => %{"direction_id" => 1, "canonical" => false}
377+
"id" => "rp1",
378+
"attributes" => %{"direction_id" => 0, "canonical" => true}
373379
},
374380
%{
375-
"id" => "rp5",
381+
"id" => "rp2",
382+
"attributes" => %{"direction_id" => 1, "canonical" => true}
383+
},
384+
%{
385+
"id" => "rp3",
376386
"attributes" => %{"direction_id" => 0, "canonical" => false}
377387
},
378388
%{
379-
"id" => "rp1",
380-
"attributes" => %{"direction_id" => 0, "canonical" => true}
389+
"id" => "rp4",
390+
"attributes" => %{"direction_id" => 1, "canonical" => false}
381391
},
382392
%{
383-
"id" => "rp3",
393+
"id" => "rp5",
384394
"attributes" => %{"direction_id" => 0, "canonical" => false}
385395
},
386396
%{
387397
"id" => "rp6",
388398
"attributes" => %{"direction_id" => 1, "canonical" => false}
389-
},
390-
%{
391-
"id" => "rp2",
392-
"attributes" => %{"direction_id" => 1, "canonical" => true}
393399
}
394400
] = json_response(conn, 200)["data"]
395401
end

apps/api_web/test/api_web/controllers/stop_controller_test.exs

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ defmodule ApiWeb.StopControllerTest do
33
alias Model.{Facility, Schedule, Stop, Trip}
44

55
setup %{conn: conn} do
6-
State.Stop.new_state([])
76
{:ok, conn: put_req_header(conn, "accept", "application/json")}
87
end
98

apps/api_web/test/api_web/controllers/trip_controller_test.exs

-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ defmodule ApiWeb.TripControllerTest do
44
alias Model.Trip
55

66
setup %{conn: conn} do
7-
State.Trip.new_state([])
8-
97
{:ok, conn: put_req_header(conn, "accept", "application/json")}
108
end
119

0 commit comments

Comments
 (0)