Adds tests covering: - Aprsme.Packet edge cases (already committed) - Encoding valid_codepoint? branches via slow grapheme path and encoding_info shapes - ErrorHandler database/network error categorization (CastError, ConstraintError, QueryError, Postgrex.Error, RuntimeError circuit_open/timeout, custom map :reason) - HealthCheck plug ask_shutting_down? nil and unresponsive-pid paths - SpatialPubSub ensure_float branches, dateline broadcast wrap-around, monitored client DOWN handler, no-coordinate broadcast skip - DataBuilder weather popup, weather-only fallback, tuple value conversion, string weather convert_unit branches - DeviceIdentification fetch_devices_from_url default-arg head - PageController format_uptime branches via fake Aprsme.Is GenServer - WeatherLive.CallsignView compare_timestamps branches via :weather_packet messages - PacketConsumer field-conversion private helpers via crafted handle_events events
100 lines
3.1 KiB
Elixir
100 lines
3.1 KiB
Elixir
defmodule AprsmeWeb.PageControllerUptimeTest do
|
|
@moduledoc """
|
|
Direct tests for the four `format_uptime_parts/4` branches in PageController.
|
|
|
|
We can't call the private function directly. Instead, register a fake
|
|
`Aprsme.Is` process that responds to `:get_status` with a chosen
|
|
`uptime_seconds`, then hit the controller and check the formatted string.
|
|
"""
|
|
use AprsmeWeb.ConnCase, async: false
|
|
|
|
defmodule FakeIs do
|
|
@moduledoc false
|
|
use GenServer
|
|
|
|
def start_link(uptime_seconds) do
|
|
GenServer.start_link(__MODULE__, uptime_seconds, name: Aprsme.Is)
|
|
end
|
|
|
|
@impl true
|
|
def init(uptime_seconds), do: {:ok, uptime_seconds}
|
|
|
|
@impl true
|
|
def handle_call(:get_status, _from, uptime_seconds) do
|
|
now = DateTime.utc_now()
|
|
connected_at = DateTime.add(now, -uptime_seconds, :second)
|
|
|
|
reply = %{
|
|
connected: true,
|
|
server: "test.local",
|
|
port: 14_580,
|
|
connected_at: connected_at,
|
|
uptime_seconds: uptime_seconds,
|
|
login_id: "N0CALL",
|
|
filter: "r/0/0/100",
|
|
packet_stats: %{total_packets: 0, packets_per_second: 0, last_packet_at: nil},
|
|
stored_packet_count: 0,
|
|
oldest_packet_timestamp: nil
|
|
}
|
|
|
|
{:reply, reply, uptime_seconds}
|
|
end
|
|
end
|
|
|
|
setup do
|
|
# The real Aprsme.Is doesn't start in :test env, so the name is free.
|
|
# Defensive: if some prior test registered something under it, unregister.
|
|
if pid = Process.whereis(Aprsme.Is) do
|
|
:erlang.unregister(Aprsme.Is)
|
|
_ = pid
|
|
end
|
|
|
|
original_cluster = Application.get_env(:aprsme, :cluster_enabled)
|
|
Application.put_env(:aprsme, :cluster_enabled, false)
|
|
|
|
on_exit(fn -> Application.put_env(:aprsme, :cluster_enabled, original_cluster) end)
|
|
:ok
|
|
end
|
|
|
|
defp call_with_uptime(uptime_seconds) do
|
|
{:ok, fake} = FakeIs.start_link(uptime_seconds)
|
|
|
|
try do
|
|
conn = Phoenix.ConnTest.build_conn()
|
|
result = AprsmeWeb.PageController.status_json(conn, %{})
|
|
Jason.decode!(result.resp_body)
|
|
after
|
|
if Process.alive?(fake), do: GenServer.stop(fake)
|
|
end
|
|
end
|
|
|
|
describe "format_uptime branches via status_json" do
|
|
test "formats multi-day uptime as 'Xd Yh Zm Ss'" do
|
|
body = call_with_uptime(2 * 86_400 + 3 * 3600 + 15 * 60 + 5)
|
|
display = body["aprs_is"]["uptime_display"]
|
|
assert display =~ ~r/^\d+d \d+h \d+m \d+s$/
|
|
assert String.starts_with?(display, "2d ")
|
|
end
|
|
|
|
test "formats sub-day, multi-hour uptime as 'Yh Zm Ss'" do
|
|
body = call_with_uptime(5 * 3600 + 30 * 60 + 12)
|
|
display = body["aprs_is"]["uptime_display"]
|
|
assert display =~ ~r/^\d+h \d+m \d+s$/
|
|
refute display =~ "d "
|
|
end
|
|
|
|
test "formats sub-hour, multi-minute uptime as 'Zm Ss'" do
|
|
body = call_with_uptime(30 * 60 + 7)
|
|
display = body["aprs_is"]["uptime_display"]
|
|
assert display =~ ~r/^\d+m \d+s$/
|
|
refute display =~ "h "
|
|
end
|
|
|
|
test "formats sub-minute uptime as 'Ss'" do
|
|
body = call_with_uptime(45)
|
|
display = body["aprs_is"]["uptime_display"]
|
|
assert display =~ ~r/^\d+s$/
|
|
refute display =~ "m "
|
|
end
|
|
end
|
|
end
|