From aa6ab6358f5c92b3f6a6eadc8492fe9f3eeabe0b Mon Sep 17 00:00:00 2001 From: Antoine Augusti Date: Fri, 22 Nov 2024 14:38:54 +0100 Subject: [PATCH] =?UTF-8?q?GBFSMetadata=20:=20fiabiliser=20le=20type=20de?= =?UTF-8?q?=20syst=C3=A8me=20(#4323)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * GBFSMetadata : fiabiliser le type de système * Improve description for tests Co-authored-by: Vincent Degove --------- Co-authored-by: Vincent Degove --- apps/transport/lib/transport/gbfs_metadata.ex | 37 ++++- .../test/transport/gbfs_metadata_test.exs | 136 ++++++++++++++++++ 2 files changed, 167 insertions(+), 6 deletions(-) diff --git a/apps/transport/lib/transport/gbfs_metadata.ex b/apps/transport/lib/transport/gbfs_metadata.ex index 194b3f15fa..4b1d4a442c 100644 --- a/apps/transport/lib/transport/gbfs_metadata.ex +++ b/apps/transport/lib/transport/gbfs_metadata.ex @@ -89,18 +89,18 @@ defmodule Transport.GBFSMetadata do end) end - defp types(%{"data" => _data} = payload) do - has_vehicle_status = has_feed?(payload, :vehicle_status) - has_station_information = has_feed?(payload, :station_information) + def types(%{"data" => _data} = payload) do + has_free_floating_vehicles = has_free_floating_vehicles?(payload) + has_stations = has_stations?(payload) cond do - has_vehicle_status and has_station_information -> + has_free_floating_vehicles and has_stations -> ["free_floating", "stations"] - has_vehicle_status -> + has_free_floating_vehicles -> ["free_floating"] - has_station_information -> + has_stations -> ["stations"] true -> @@ -109,6 +109,31 @@ defmodule Transport.GBFSMetadata do end end + defp has_stations?(%{"data" => _data} = payload) do + feed_url = feed_url_by_name(payload, :station_information) + + with {:feed_exists, true} <- {:feed_exists, not is_nil(feed_url)}, + {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- cached_http_get(feed_url), + {:ok, json} <- Jason.decode(body) do + not Enum.empty?(json["data"]["stations"]) + else + _ -> false + end + end + + defp has_free_floating_vehicles?(%{"data" => _data} = payload) do + feed_url = feed_url_by_name(payload, :vehicle_status) + + with {:feed_exists, true} <- {:feed_exists, not is_nil(feed_url)}, + {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- cached_http_get(feed_url), + {:ok, json} <- Jason.decode(body) do + (json["data"]["vehicles"] || json["data"]["bikes"]) + |> Enum.any?(&(not Map.has_key?(&1, "station_id"))) + else + _ -> false + end + end + defp ttl(%{"data" => _data} = payload) do feed_name = feed_to_use_for_ttl(types(payload)) diff --git a/apps/transport/test/transport/gbfs_metadata_test.exs b/apps/transport/test/transport/gbfs_metadata_test.exs index fe3c7d73e5..4f1b97aadd 100644 --- a/apps/transport/test/transport/gbfs_metadata_test.exs +++ b/apps/transport/test/transport/gbfs_metadata_test.exs @@ -73,6 +73,7 @@ defmodule Transport.GBFSMetadataTest do :system_information, :vehicle_types, :free_bike_status, + :station_information, :station_status ]) @@ -662,6 +663,141 @@ defmodule Transport.GBFSMetadataTest do end end + describe "types" do + test "vehicles feed with no station information and stations feeds should be considered mixed type" do + # `station_id` is not present in the response, the bike is considered as free floating + setup_response( + vehicle_status_url = "https://example.com/vehicle_status", + Jason.encode!(%{data: %{vehicles: [%{bike_id: Ecto.UUID.generate()}]}}) + ) + + setup_response( + station_information_url = "https://example.com/station_information", + Jason.encode!(%{data: %{stations: [%{station_id: Ecto.UUID.generate()}]}}) + ) + + gbfs_url = %{ + "version" => "3.0", + "data" => %{ + "feeds" => [ + %{"name" => "vehicle_status", "url" => vehicle_status_url}, + %{"name" => "station_information", "url" => station_information_url} + ] + } + } + + assert ["free_floating", "stations"] == types(gbfs_url) + end + + test "vehicles and stations feeds, empty stations should be considered as free floating" do + setup_response( + vehicle_status_url = "https://example.com/vehicle_status", + Jason.encode!(%{data: %{vehicles: [%{bike_id: Ecto.UUID.generate()}]}}) + ) + + setup_response( + station_information_url = "https://example.com/station_information", + Jason.encode!(%{data: %{stations: []}}) + ) + + gbfs_url = %{ + "version" => "3.0", + "data" => %{ + "feeds" => [ + %{"name" => "vehicle_status", "url" => vehicle_status_url}, + %{"name" => "station_information", "url" => station_information_url} + ] + } + } + + assert ["free_floating"] == types(gbfs_url) + end + + test "vehicles and stations feeds, vehicles are docked" do + setup_response( + vehicle_status_url = "https://example.com/vehicle_status", + Jason.encode!(%{data: %{vehicles: [%{station_id: Ecto.UUID.generate()}]}}) + ) + + setup_response( + station_information_url = "https://example.com/station_information", + Jason.encode!(%{data: %{stations: [%{station_id: Ecto.UUID.generate()}]}}) + ) + + gbfs_url = %{ + "version" => "3.0", + "data" => %{ + "feeds" => [ + %{"name" => "vehicle_status", "url" => vehicle_status_url}, + %{"name" => "station_information", "url" => station_information_url} + ] + } + } + + assert ["stations"] == types(gbfs_url) + end + + test "vehicles and stations feeds, no vehicles" do + setup_response( + vehicle_status_url = "https://example.com/vehicle_status", + Jason.encode!(%{data: %{vehicles: []}}) + ) + + setup_response( + station_information_url = "https://example.com/station_information", + Jason.encode!(%{data: %{stations: [%{station_id: Ecto.UUID.generate()}]}}) + ) + + gbfs_url = %{ + "version" => "3.0", + "data" => %{ + "feeds" => [ + %{"name" => "vehicle_status", "url" => vehicle_status_url}, + %{"name" => "station_information", "url" => station_information_url} + ] + } + } + + assert ["stations"] == types(gbfs_url) + end + + test "stations feed only" do + setup_response( + station_information_url = "https://example.com/station_information", + Jason.encode!(%{data: %{stations: [%{station_id: Ecto.UUID.generate()}]}}) + ) + + gbfs_url = %{ + "version" => "3.0", + "data" => %{ + "feeds" => [ + %{"name" => "station_information", "url" => station_information_url} + ] + } + } + + assert ["stations"] == types(gbfs_url) + end + + test "vehicles feed only" do + setup_response( + vehicle_status_url = "https://example.com/vehicle_status", + Jason.encode!(%{data: %{vehicles: [%{bike_id: Ecto.UUID.generate()}]}}) + ) + + gbfs_url = %{ + "version" => "3.0", + "data" => %{ + "feeds" => [ + %{"name" => "vehicle_status", "url" => vehicle_status_url} + ] + } + } + + assert ["free_floating"] == types(gbfs_url) + end + end + defp fixture_content(filename) do File.read!("#{__DIR__}/../fixture/gbfs/#{filename}.json") end