defmodule MicrowavepropWeb.WeatherMapLiveTest do # async: false because we write to the shared ProfilesFile directory # which the WeatherMapLive reads at mount. use MicrowavepropWeb.ConnCase, async: false import Phoenix.LiveViewTest alias Microwaveprop.Propagation.ProfilesFile alias Microwaveprop.Weather.GridCache setup do GridCache.clear() on_exit(fn -> GridCache.clear() # Scrub any profile files our tests wrote so other async tests # that enumerate the ProfilesFile dir (e.g. latest_valid_time) # aren't affected. ProfilesFile.prune_older_than(~U[2099-12-31 23:59:59Z]) end) :ok end defp write_profile(valid_time, lat, lon) do profile = for level <- [1000, 925, 850, 700], do: %{"pres" => level * 1.0, "tmpc" => 15.0, "dwpc" => 5.0} grid_data = %{ {lat, lon} => %{ surface_temp_c: 22.0, surface_dewpoint_c: 12.0, surface_pressure_mb: 1010.0, hpbl_m: 800.0, pwat_mm: 25.0, profile: profile } } ProfilesFile.write!(valid_time, grid_data) end describe "layer description in sidebar" do test "renders Group · Label header and description in the desktop sidebar", %{conn: conn} do {:ok, _lv, html} = live(conn, ~p"/weather") # Default layer is refractivity_gradient → group Surface, label N-Gradient. assert html =~ "Surface" assert html =~ "N-Gradient" assert html =~ "Minimum refractivity gradient" end end describe "forecast timeline" do test "mount pushes data-valid-times for every persisted profile", %{conn: conn} do base = DateTime.utc_now() |> DateTime.truncate(:second) |> Map.put(:minute, 0) |> Map.put(:second, 0) times = for h <- 0..2, do: DateTime.add(base, h * 3600, :second) # Seed a profile file at each forecast hour. Enum.each(times, &write_profile(&1, 33.0, -97.0)) {:ok, _lv, html} = live(conn, ~p"/weather") # Timeline container exists. assert html =~ ~s(id="weather-forecast-timeline") # Each valid_time is present in the map element's data attribute. Enum.each(times, fn t -> iso = DateTime.to_iso8601(t) assert html =~ iso end) end test "select_time replaces the rendered weather data with the new hour's grid", %{conn: conn} do base = DateTime.utc_now() |> DateTime.truncate(:second) |> Map.put(:minute, 0) |> Map.put(:second, 0) now_t = base future_t = DateTime.add(base, 3 * 3600, :second) # Seed f00 with a 22°C surface and f03 with a 10°C surface so we # can tell them apart in the push_event payload. write_profile(now_t, 33.0, -97.0) grid_data = %{ {33.0, -97.0} => %{ surface_temp_c: 10.0, surface_dewpoint_c: 5.0, surface_pressure_mb: 1010.0, hpbl_m: 500.0, pwat_mm: 20.0, profile: [] } } ProfilesFile.write!(future_t, grid_data) {:ok, lv, _html} = live(conn, ~p"/weather") # Select the future hour. render_hook(lv, "select_time", %{"time" => DateTime.to_iso8601(future_t)}) assert_push_event(lv, "update_weather", %{data: data}) assert Enum.any?(data, fn r -> r.temperature == 10.0 end) end end end