Contact detail page now renders an atmospheric profile section backed by HRRR when available and ERA5 (reanalysis) otherwise, labeled with the data source. When both sources are missing and HRRR is known-unavailable (pre-2014 contacts), the Era5FetchWorker is enqueued so the month-tile backfill gets triggered from a user visit. Status page ERA5 progress previously computed "complete" as (total_contacts - hrrr_unavailable_contacts), which treated every contact with any HRRR status as ERA5-complete — inflating the bar to 76% while era5_profiles had 0 rows. Replaced with a per-candidate EXISTS query against era5_profiles using the same 0.15°/30-min tolerance Weather.find_nearest_era5/3 uses at lookup time.
68 lines
2.1 KiB
Elixir
68 lines
2.1 KiB
Elixir
defmodule MicrowavepropWeb.StatusLiveTest do
|
|
use MicrowavepropWeb.ConnCase, async: false
|
|
|
|
import Microwaveprop.AccountsFixtures
|
|
import Phoenix.LiveViewTest
|
|
|
|
alias Microwaveprop.Cache
|
|
alias Microwaveprop.Radio.Contact
|
|
alias Microwaveprop.Repo
|
|
alias Microwaveprop.Weather.Era5Profile
|
|
|
|
setup %{conn: conn} do
|
|
Cache.invalidate({MicrowavepropWeb.StatusLive, :count_unprocessed})
|
|
Cache.invalidate({MicrowavepropWeb.StatusLive, :stats})
|
|
Cache.invalidate({MicrowavepropWeb.StatusLive, :db_stats})
|
|
|
|
user = user_fixture()
|
|
{:ok, admin} = user |> Ecto.Changeset.change(%{is_admin: true}) |> Repo.update()
|
|
conn = log_in_user(conn, admin)
|
|
{:ok, conn: conn}
|
|
end
|
|
|
|
defp create_era5_candidate do
|
|
{:ok, contact} =
|
|
%Contact{}
|
|
|> Contact.changeset(%{
|
|
station1: "W5TEST",
|
|
station2: "K5TEST",
|
|
qso_timestamp: ~U[2010-06-15 18:00:00Z],
|
|
mode: "CW",
|
|
band: Decimal.new("1296"),
|
|
grid1: "EM12",
|
|
grid2: "EM00",
|
|
pos1: %{"lat" => 33.0, "lon" => -97.0},
|
|
pos2: %{"lat" => 30.3, "lon" => -97.7},
|
|
distance_km: Decimal.new("300")
|
|
})
|
|
|> Ecto.Changeset.change(%{hrrr_status: :unavailable})
|
|
|> Repo.insert()
|
|
|
|
contact
|
|
end
|
|
|
|
test "ERA5 progress bar numerator is actual era5 profile matches not total-minus-candidates", %{conn: conn} do
|
|
create_era5_candidate()
|
|
|
|
# No ERA5 profile yet — candidates = 1, done = 0
|
|
{:ok, lv, _html} = live(conn, ~p"/status")
|
|
era5_row = lv |> element(~s|[data-progress-key="era5"]|) |> render()
|
|
assert era5_row =~ "ERA5"
|
|
assert era5_row =~ "0 / 1"
|
|
|
|
# Insert a matching era5_profile row — done should become 1
|
|
{:ok, _} =
|
|
Repo.insert(%Era5Profile{
|
|
valid_time: ~U[2010-06-15 18:00:00Z],
|
|
lat: 33.0,
|
|
lon: -97.0,
|
|
ducting_detected: false
|
|
})
|
|
|
|
Cache.invalidate({MicrowavepropWeb.StatusLive, :count_unprocessed})
|
|
|
|
{:ok, lv, _html} = live(conn, ~p"/status")
|
|
era5_row = lv |> element(~s|[data-progress-key="era5"]|) |> render()
|
|
assert era5_row =~ "1 / 1"
|
|
end
|
|
end
|