prop/test/microwaveprop_web/live/pskr_spots_live_test.exs

190 lines
5.6 KiB
Elixir
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

defmodule MicrowavepropWeb.PskrSpotsLiveTest do
use MicrowavepropWeb.ConnCase, async: true
import Phoenix.LiveViewTest
alias Microwaveprop.Repo
defp now, do: DateTime.utc_now()
defp dump_uuid, do: Ecto.UUID.dump!(Ecto.UUID.generate())
defp insert_spot(attrs) do
defaults = %{
hour_utc: now(),
band: "2m",
sender_grid: "EM12KL",
receiver_grid: "DM43ST",
spot_count: 1
}
fields = Map.merge(defaults, attrs)
Repo.query!(
"""
INSERT INTO pskr_spots_hourly
(id, hour_utc, band, sender_grid, receiver_grid,
sender_lat, sender_lon, receiver_lat, receiver_lon,
distance_km, spot_count, max_snr_db, min_snr_db,
modes, sender_callsigns, receiver_callsigns,
first_spot_at, last_spot_at,
inserted_at, updated_at)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $19)
""",
[
dump_uuid(),
fields.hour_utc,
fields.band,
fields.sender_grid,
fields.receiver_grid,
Map.get(fields, :sender_lat, 32.5),
Map.get(fields, :sender_lon, -96.5),
Map.get(fields, :receiver_lat, 33.5),
Map.get(fields, :receiver_lon, -110.5),
Map.get(fields, :distance_km, 1_200.0),
fields.spot_count,
Map.get(fields, :max_snr_db, 5),
Map.get(fields, :min_snr_db, 0),
Map.get(fields, :modes, ["FT8"]),
Map.get(fields, :sender_callsigns, []),
Map.get(fields, :receiver_callsigns, []),
Map.get(fields, :first_spot_at, fields.hour_utc),
Map.get(fields, :last_spot_at, fields.hour_utc)
]
)
end
describe "page rendering" do
test "renders the pskr spots page", %{conn: conn} do
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "PSK Reporter Spots"
end
test "sets page title", %{conn: conn} do
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "PSK Reporter Spots"
end
test "shows empty state when no spots exist", %{conn: conn} do
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "No PSK Reporter spots received yet"
end
test "shows total spots count of zero when empty", %{conn: conn} do
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "Total spots stored:"
assert html =~ "0"
end
end
describe "with spots in the database" do
test "displays total spots count and per-band counts", %{conn: conn} do
insert_spot(%{band: "2m", spot_count: 42})
insert_spot(%{band: "70cm", spot_count: 7})
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "Total spots stored:"
# 42 + 7 = 49 total
assert html =~ "49"
# Band badges show per-band counts
assert html =~ "2m"
assert html =~ "70cm"
end
test "displays band as badge", %{conn: conn} do
insert_spot(%{band: "70cm"})
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "70cm"
end
test "displays SNR range", %{conn: conn} do
insert_spot(%{min_snr_db: -5, max_snr_db: 12})
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "-512 dB"
end
test "displays single SNR when min equals max", %{conn: conn} do
insert_spot(%{min_snr_db: 3, max_snr_db: 3})
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "3 dB"
refute html =~ "33 dB"
end
test "displays sender and receiver callsigns", %{conn: conn} do
insert_spot(%{sender_callsigns: ["K5ABC"], receiver_callsigns: ["K7XYZ"]})
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "K5ABC"
assert html =~ "K7XYZ"
end
test "displays multiple callsigns comma-separated", %{conn: conn} do
insert_spot(%{sender_callsigns: ["K5ABC", "W1AW"], receiver_callsigns: ["K7XYZ"]})
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "K5ABC, W1AW"
end
test "shows dash for empty callsigns", %{conn: conn} do
insert_spot(%{sender_callsigns: [], receiver_callsigns: []})
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ ""
end
test "displays modes", %{conn: conn} do
insert_spot(%{modes: ["FT8", "FT4"]})
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
assert html =~ "FT8"
assert html =~ "FT4"
end
test "shows most recent spots first", %{conn: conn} do
t1 = ~U[2026-07-01 12:00:00Z]
t2 = ~U[2026-07-01 13:00:00Z]
insert_spot(%{sender_grid: "EARLIER", last_spot_at: t1, hour_utc: t1})
insert_spot(%{sender_grid: "LATER", last_spot_at: t2, hour_utc: t2})
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
# LATER should appear before EARLIER in the HTML
assert String.contains?(html, "LATER")
assert String.contains?(html, "EARLIER")
assert String.index(html, "LATER") < String.index(html, "EARLIER")
end
test "limits to 100 most recent spots", %{conn: conn} do
# Insert 105 spots — only the 100 most recent should render
for i <- 1..105 do
t = DateTime.add!(now(), i - 105, :second)
insert_spot(%{sender_grid: "GRID#{i}", last_spot_at: t, hour_utc: t})
end
{:ok, _lv, html} = live(conn, ~p"/pskreporter")
# The oldest 5 should be excluded (GRID1GRID5 have the earliest timestamps)
refute html =~ "GRID1"
refute html =~ "GRID2"
refute html =~ "GRID3"
refute html =~ "GRID4"
refute html =~ "GRID5"
# The most recent 100 should be present
assert html =~ "GRID105"
assert html =~ "GRID6"
end
end
end