Fix LiveView crashes and stabilize test suite
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 4m31s
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 4m31s
This commit is contained in:
parent
db57b3a1c7
commit
959f3a3f69
24 changed files with 54 additions and 41 deletions
3
Makefile
3
Makefile
|
|
@ -25,9 +25,6 @@ deps-audit:
|
|||
cargo-audit:
|
||||
cargo audit --file rust/prop_grid_rs/Cargo.lock
|
||||
|
||||
sobelow:
|
||||
MIX_ENV=test mix sobelow --config --quiet
|
||||
|
||||
format:
|
||||
MIX_ENV=test mix format --check-formatted
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,12 @@ defmodule MicrowavepropWeb.Admin.ContactEditLive do
|
|||
end
|
||||
end
|
||||
|
||||
# Swoosh's test adapter delivers the email back to the calling process.
|
||||
# Approval/rejection notifications are sent from this LiveView process,
|
||||
# so consume the adapter message instead of crashing on an unknown info.
|
||||
@impl true
|
||||
def handle_info({:email, %Swoosh.Email{}}, socket), do: {:noreply, socket}
|
||||
|
||||
defp normalize_note(""), do: nil
|
||||
defp normalize_note(note), do: String.trim(note)
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ defmodule MicrowavepropWeb.Admin.MonitorLive.Index do
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody id="monitors" phx-update="stream">
|
||||
<tr :for={{id, monitor} <- @streams.monitors}>
|
||||
<tr :for={{id, monitor} <- @streams.monitors} id={id}>
|
||||
<td class="font-semibold">{monitor.name}</td>
|
||||
<td class="text-sm">
|
||||
<%= if monitor.hardware_type do %>
|
||||
|
|
|
|||
|
|
@ -433,7 +433,11 @@ defmodule MicrowavepropWeb.RoverLocationsLive do
|
|||
</.form>
|
||||
</div>
|
||||
|
||||
<form phx-change="filter_status" class="mb-4 flex items-center gap-2">
|
||||
<form
|
||||
id="rover-status-filter-form"
|
||||
phx-change="filter_status"
|
||||
class="mb-4 flex items-center gap-2"
|
||||
>
|
||||
<label for="status-filter" class="text-sm font-medium">Show:</label>
|
||||
<select
|
||||
id="status-filter"
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ defmodule Microwaveprop.Beacons.RangeEstimateTest do
|
|||
assert result.band_mhz == 10_000
|
||||
assert result.center_score == 50
|
||||
assert is_float(result.eirp_dbm)
|
||||
assert result.cells != []
|
||||
assert Enum.any?(result.cells)
|
||||
assert result.grid_step == 0.125
|
||||
assert result.tiers != []
|
||||
assert Enum.any?(result.tiers)
|
||||
end
|
||||
|
||||
test "each cell carries lat/lon, distance, rx_dbm, tier label/color" do
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ defmodule Microwaveprop.LoggerFormatTest do
|
|||
|
||||
alias LoggerJSON.Formatters.Basic
|
||||
|
||||
require Logger
|
||||
|
||||
@moduletag capture_log: false
|
||||
|
||||
describe "structured JSON formatter" do
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ defmodule Microwaveprop.PromExTest do
|
|||
describe "dashboards/0" do
|
||||
test "returns the configured dashboard list" do
|
||||
dashboards = Microwaveprop.PromEx.dashboards()
|
||||
assert dashboards != []
|
||||
assert Enum.any?(dashboards)
|
||||
assert {:prom_ex, "application.json"} in dashboards
|
||||
end
|
||||
end
|
||||
|
|
@ -12,7 +12,7 @@ defmodule Microwaveprop.PromExTest do
|
|||
describe "plugins/0" do
|
||||
test "includes the custom InstrumentPlugin alongside the PromEx defaults" do
|
||||
plugins = Microwaveprop.PromEx.plugins()
|
||||
assert plugins != []
|
||||
assert Enum.any?(plugins)
|
||||
assert Microwaveprop.PromEx.InstrumentPlugin in plugins
|
||||
assert PromEx.Plugins.Beam in plugins
|
||||
end
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ defmodule Microwaveprop.Propagation.EmeTest do
|
|||
for {_label, mhz_str} <- BandConfig.band_options() do
|
||||
{mhz, _} = Integer.parse(mhz_str)
|
||||
rho = Eme.moon_albedo(mhz)
|
||||
assert is_number(rho) and rho > 0.0 and rho < 0.2
|
||||
assert rho > 0.0 and rho < 0.2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
defmodule Microwaveprop.Propagation.RecalibratorTest do
|
||||
use Microwaveprop.DataCase, async: true
|
||||
|
||||
alias Microwaveprop.Propagation.BandWeights
|
||||
alias Microwaveprop.Propagation.Recalibrator
|
||||
alias Microwaveprop.Radio.Contact
|
||||
alias Microwaveprop.Weather.HrrrProfile
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ defmodule Microwaveprop.Radio.ContactEditTest do
|
|||
alias Microwaveprop.Radio
|
||||
alias Microwaveprop.Radio.Contact
|
||||
alias Microwaveprop.Radio.ContactEdit
|
||||
alias Microwaveprop.Radio.Contacts
|
||||
alias Microwaveprop.Terrain.ElevationClient
|
||||
alias Microwaveprop.Weather.HrrrClient
|
||||
alias Microwaveprop.Weather.IemClient
|
||||
|
|
@ -538,14 +539,15 @@ defmodule Microwaveprop.Radio.ContactEditTest do
|
|||
sentinel = :stale_payload
|
||||
ten_min = 10 * 60 * 1_000
|
||||
|
||||
Cache.put({Radio, :total_contact_count}, sentinel, ten_min)
|
||||
Cache.put({Radio, :contact_map_payload}, sentinel, ten_min)
|
||||
Cache.put({Contacts, :total_contact_count}, sentinel, ten_min)
|
||||
Cache.put({Contacts, :contact_map_payload}, sentinel, ten_min)
|
||||
Cache.put({MicrowavepropWeb.ContactMapController, :gzipped_payload}, sentinel, ten_min)
|
||||
|
||||
{:ok, _} = Radio.apply_owner_edit(contact, user, %{"private" => true})
|
||||
|
||||
assert :ets.lookup(:microwaveprop_cache, {Radio, :total_contact_count}) == []
|
||||
assert :ets.lookup(:microwaveprop_cache, {Radio, :contact_map_payload}) == []
|
||||
assert :ets.lookup(:microwaveprop_cache, {Contacts, :total_contact_count}) == []
|
||||
|
||||
assert :ets.lookup(:microwaveprop_cache, {Contacts, :contact_map_payload}) == []
|
||||
|
||||
assert :ets.lookup(:microwaveprop_cache, {MicrowavepropWeb.ContactMapController, :gzipped_payload}) ==
|
||||
[]
|
||||
|
|
|
|||
|
|
@ -36,11 +36,12 @@ defmodule Microwaveprop.Weather.GridCacheValkey.EmptyCacheTest do
|
|||
GridCache.clear()
|
||||
|
||||
on_exit(fn ->
|
||||
if pid && Process.alive?(pid) do
|
||||
if Process.whereis(Conn) == pid do
|
||||
Process.unregister(Conn)
|
||||
Process.exit(pid, :kill)
|
||||
end
|
||||
|
||||
Process.exit(pid, :kill)
|
||||
|
||||
if prev_url,
|
||||
do: Application.put_env(:microwaveprop, :valkey_url, prev_url),
|
||||
else: Application.delete_env(:microwaveprop, :valkey_url)
|
||||
|
|
@ -153,11 +154,12 @@ defmodule Microwaveprop.Weather.GridCacheValkey.DataCacheTest do
|
|||
GridCache.clear()
|
||||
|
||||
on_exit(fn ->
|
||||
if pid && Process.alive?(pid) do
|
||||
if Process.whereis(Conn) == pid do
|
||||
Process.unregister(Conn)
|
||||
Process.exit(pid, :kill)
|
||||
end
|
||||
|
||||
Process.exit(pid, :kill)
|
||||
|
||||
if prev_url,
|
||||
do: Application.put_env(:microwaveprop, :valkey_url, prev_url),
|
||||
else: Application.delete_env(:microwaveprop, :valkey_url)
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ defmodule Microwaveprop.Weather.NexradClientTest do
|
|||
Enum.reduce(48..52, pixels, fn y, acc ->
|
||||
Enum.reduce(48..52, acc, fn x, inner_acc ->
|
||||
offset = y * width + x
|
||||
<<pre::binary-size(offset), _::8, post::binary>> = inner_acc
|
||||
<<pre::binary-size(^offset), _::8, post::binary>> = inner_acc
|
||||
<<pre::binary, 120::8, post::binary>>
|
||||
end)
|
||||
end)
|
||||
|
|
@ -149,7 +149,7 @@ defmodule Microwaveprop.Weather.NexradClientTest do
|
|||
Enum.reduce(48..52, acc, fn x, inner_acc ->
|
||||
offset = y * width + x
|
||||
value = if rem(x + y, 2) == 0, do: 100, else: 200
|
||||
<<pre::binary-size(offset), _::8, post::binary>> = inner_acc
|
||||
<<pre::binary-size(^offset), _::8, post::binary>> = inner_acc
|
||||
<<pre::binary, value::8, post::binary>>
|
||||
end)
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ defmodule Microwaveprop.Workers.IonosphereFetchWorkerTest do
|
|||
test "exposes a non-empty list of CONUS ionosonde stations" do
|
||||
stations = IonosphereFetchWorker.stations()
|
||||
|
||||
assert stations != []
|
||||
assert Enum.any?(stations)
|
||||
|
||||
# Every station entry has the shape the fetcher expects, with a
|
||||
# plausible CONUS lat/lon envelope.
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ defmodule MicrowavepropWeb.UserSettingsControllerTest do
|
|||
|
||||
assert get_session(new_password_conn, :user_token) != get_session(conn, :user_token)
|
||||
|
||||
assert get_flash(new_password_conn, :info) =~
|
||||
assert Phoenix.Flash.get(new_password_conn.assigns.flash, :info) =~
|
||||
"Password updated successfully"
|
||||
|
||||
assert Accounts.get_user_by_email_and_password(user.email, "new valid password")
|
||||
|
|
|
|||
|
|
@ -7,10 +7,13 @@ defmodule MicrowavepropWeb.WeatherTileControllerTest do
|
|||
|
||||
setup do
|
||||
GridCache.clear()
|
||||
ProfilesFile.prune_older_than(~U[2099-12-31 23:59:59Z])
|
||||
ScalarFile.prune_older_than(~U[2099-12-31 23:59:59Z])
|
||||
|
||||
on_exit(fn ->
|
||||
GridCache.clear()
|
||||
ProfilesFile.prune_older_than(~U[2099-12-31 23:59:59Z])
|
||||
ScalarFile.prune_older_than(~U[2099-12-31 23:59:59Z])
|
||||
end)
|
||||
|
||||
:ok
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
defmodule MicrowavepropWeb.AboutLiveTest do
|
||||
use MicrowavepropWeb.ConnCase, async: true
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
|
||||
alias Microwaveprop.Repo
|
||||
|
||||
describe "page content" do
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ defmodule MicrowavepropWeb.ContactLive.IndexTest do
|
|||
alias Microwaveprop.Radio.Contact
|
||||
alias Microwaveprop.Repo
|
||||
alias Microwaveprop.Terrain.ElevationClient
|
||||
alias Microwaveprop.Weather.HrrrNativeProfile
|
||||
alias Microwaveprop.Weather.NarrProfile
|
||||
|
||||
setup do
|
||||
Req.Test.stub(ElevationClient, fn conn ->
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ defmodule MicrowavepropWeb.ContactLive.ShowCoverageTest do
|
|||
alias Microwaveprop.Terrain.ElevationClient
|
||||
alias Microwaveprop.Terrain.TerrainProfile
|
||||
alias Microwaveprop.Weather
|
||||
alias Microwaveprop.Weather.HrrrNativeProfile
|
||||
alias Microwaveprop.Weather.HrrrProfile
|
||||
alias Microwaveprop.Weather.NarrProfile
|
||||
alias Microwaveprop.Weather.SolarIndex
|
||||
|
|
|
|||
|
|
@ -12,10 +12,8 @@ defmodule MicrowavepropWeb.ContactLive.ShowHydrationTest do
|
|||
alias Microwaveprop.Terrain.ElevationClient
|
||||
alias Microwaveprop.Terrain.TerrainProfile
|
||||
alias Microwaveprop.Weather
|
||||
alias Microwaveprop.Weather.HrrrNativeProfile
|
||||
alias Microwaveprop.Weather.HrrrProfile
|
||||
alias Microwaveprop.Weather.IemreObservation
|
||||
alias Microwaveprop.Weather.NarrProfile
|
||||
alias Microwaveprop.Weather.Sounding
|
||||
alias Microwaveprop.Weather.SurfaceObservation
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ defmodule MicrowavepropWeb.ImportLiveTest do
|
|||
alias Microwaveprop.Radio.ImportRun
|
||||
alias Microwaveprop.Repo
|
||||
|
||||
defp log_in_submitter(conn, email) do
|
||||
user = Microwaveprop.AccountsFixtures.user_fixture(%{email: email})
|
||||
log_in_user(conn, user)
|
||||
end
|
||||
|
||||
defp insert_run(attrs) do
|
||||
defaults = %{
|
||||
submitter_email: "importer@example.com",
|
||||
|
|
@ -30,6 +35,7 @@ defmodule MicrowavepropWeb.ImportLiveTest do
|
|||
describe "mount" do
|
||||
test "renders the initial state of a pending import", %{conn: conn} do
|
||||
run = insert_run(%{total_rows: 25, submitter_email: "alice@example.com"})
|
||||
conn = log_in_submitter(conn, run.submitter_email)
|
||||
|
||||
{:ok, _lv, html} = live(conn, ~p"/imports/#{run.id}")
|
||||
|
||||
|
|
@ -43,17 +49,17 @@ defmodule MicrowavepropWeb.ImportLiveTest do
|
|||
assert html =~ ~s(id="import-error-count")
|
||||
end
|
||||
|
||||
test "redirects to /submit with a flash when the import is not found", %{conn: conn} do
|
||||
test "redirects to / with a flash when the import is not found", %{conn: conn} do
|
||||
missing_id = Ecto.UUID.generate()
|
||||
|
||||
assert {:error, {:live_redirect, %{to: "/submit", flash: flash}}} =
|
||||
assert {:error, {:live_redirect, %{to: "/", flash: flash}}} =
|
||||
live(conn, ~p"/imports/#{missing_id}")
|
||||
|
||||
assert flash["error"] =~ "Import not found"
|
||||
end
|
||||
|
||||
test "redirects to /submit for an obviously bad id", %{conn: conn} do
|
||||
assert {:error, {:live_redirect, %{to: "/submit"}}} =
|
||||
test "redirects to / for an obviously bad id", %{conn: conn} do
|
||||
assert {:error, {:live_redirect, %{to: "/"}}} =
|
||||
live(conn, ~p"/imports/not-a-uuid")
|
||||
end
|
||||
end
|
||||
|
|
@ -61,6 +67,7 @@ defmodule MicrowavepropWeb.ImportLiveTest do
|
|||
describe "live updates" do
|
||||
test "updates counters when an import_progress message is broadcast", %{conn: conn} do
|
||||
run = insert_run(%{total_rows: 100})
|
||||
conn = log_in_submitter(conn, run.submitter_email)
|
||||
|
||||
{:ok, lv, _html} = live(conn, ~p"/imports/#{run.id}")
|
||||
|
||||
|
|
@ -91,6 +98,7 @@ defmodule MicrowavepropWeb.ImportLiveTest do
|
|||
|
||||
test "shows the complete UI once status flips to complete", %{conn: conn} do
|
||||
run = insert_run(%{total_rows: 3})
|
||||
conn = log_in_submitter(conn, run.submitter_email)
|
||||
|
||||
{:ok, lv, _html} = live(conn, ~p"/imports/#{run.id}")
|
||||
|
||||
|
|
@ -127,6 +135,8 @@ defmodule MicrowavepropWeb.ImportLiveTest do
|
|||
errors: %{"2" => ["band is invalid"]}
|
||||
})
|
||||
|
||||
conn = log_in_submitter(conn, run.submitter_email)
|
||||
|
||||
{:ok, _lv, html} = live(conn, ~p"/imports/#{run.id}")
|
||||
|
||||
assert html =~ ~s(id="import-errors-section")
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ defmodule MicrowavepropWeb.StatusLiveTest do
|
|||
end
|
||||
end
|
||||
|
||||
defp create_narr_candidate(attrs \\ []) do
|
||||
defp create_narr_candidate(attrs) do
|
||||
lat = Keyword.get(attrs, :lat, 33.0)
|
||||
lon = Keyword.get(attrs, :lon, -97.0)
|
||||
ts = Keyword.get(attrs, :qso_timestamp, ~U[2010-06-15 18:00:00Z])
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ defmodule MicrowavepropWeb.UserProfileLiveTest do
|
|||
test "owners see their assigned beacon monitors", %{conn: conn} do
|
||||
user = user_fixture(%{callsign: "W5ISP"})
|
||||
|
||||
{:ok, monitor} =
|
||||
{:ok, _monitor} =
|
||||
BeaconMonitors.create_hardware(user, %{
|
||||
"name" => "Shack Pi",
|
||||
"hardware_type" => "RTL-SDR",
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ defmodule MicrowavepropWeb.Plugs.RemoteIpPropertyTest do
|
|||
defp in_cidr?({a, b, c, d}, {{na, nb, nc, nd}, prefix}) do
|
||||
host = <<a, b, c, d>>
|
||||
network = <<na, nb, nc, nd>>
|
||||
<<host_prefix::bitstring-size(prefix), _::bitstring>> = host
|
||||
<<net_prefix::bitstring-size(prefix), _::bitstring>> = network
|
||||
<<host_prefix::bitstring-size(^prefix), _::bitstring>> = host
|
||||
<<net_prefix::bitstring-size(^prefix), _::bitstring>> = network
|
||||
host_prefix == net_prefix
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ defmodule MicrowavepropWeb.TelemetryTest do
|
|||
test "returns a flat list of Telemetry.Metrics structs" do
|
||||
metrics = Telemetry.metrics()
|
||||
|
||||
assert metrics != []
|
||||
assert Enum.any?(metrics)
|
||||
|
||||
for m <- metrics do
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue