towerops/test/towerops_web/live/device_live/index_helpers_test.exs
Graham McIntire 3ca0834ef0 tests: raise coverage to 70% via helper promotion + new unit/property tests
Promoted pure presentation and utility helpers from `defp` to `def @doc false`
across ~20 LiveViews, Oban workers, and sync modules so they're reachable from
unit tests. Refactored several `cond` blocks into idiomatic function heads with
guards. Added ~250 new test cases in new files under test/towerops and
test/towerops_web, including DB-backed tests for CnMaestro.Sync and
AlertNotificationWorker, and removed dead LiveView tab components and
CapacityLive (no callers anywhere in lib/test).

Configured mix.exs test_coverage.ignore_modules to exclude vendored third-party
code (SnmpKit, protobuf-generated Towerops.Agent.*, Absinthe GraphQL types,
Phoenix HTML modules, Inspect protocol impls) from coverage calculations —
these are not our project code.

Coverage: 66.93% → 70.09%. Full suite: 10,127 tests, 0 failures.
2026-04-24 09:49:06 -05:00

122 lines
3.5 KiB
Elixir

defmodule ToweropsWeb.DeviceLive.IndexHelpersTest do
use ExUnit.Case, async: true
alias ToweropsWeb.DeviceLive.Index
defp dev(attrs), do: Map.merge(%{name: "", ip_address: nil, status: :unknown}, attrs)
describe "filter_by_search/2" do
setup do
devices = [
dev(%{name: "Router-01", ip_address: "10.0.0.1"}),
dev(%{name: "Switch-02", ip_address: "10.0.0.2"}),
dev(%{name: nil, ip_address: "192.168.1.1"})
]
%{devices: devices}
end
test "empty string returns all", %{devices: devices} do
assert devices == Index.filter_by_search(devices, "")
end
test "nil returns all", %{devices: devices} do
assert devices == Index.filter_by_search(devices, nil)
end
test "matches by name (case-insensitive)", %{devices: devices} do
[d] = Index.filter_by_search(devices, "ROUTER")
assert d.name == "Router-01"
end
test "matches by IP substring", %{devices: devices} do
[d] = Index.filter_by_search(devices, "192.168")
assert d.ip_address == "192.168.1.1"
end
test "no match returns empty", %{devices: devices} do
assert [] == Index.filter_by_search(devices, "zzzz")
end
test "handles nil name safely", %{devices: devices} do
# searching for the IP of the nil-named device should still find it
result = Index.filter_by_search(devices, "192.168.1.1")
assert length(result) == 1
end
end
describe "filter_by_status/2" do
setup do
devices = [
dev(%{status: :up}),
dev(%{status: :up}),
dev(%{status: :down}),
dev(%{status: :unknown})
]
%{devices: devices}
end
test "all returns everything", %{devices: devices} do
assert devices == Index.filter_by_status(devices, "all")
assert devices == Index.filter_by_status(devices, "garbage")
end
test "up filters to up devices only", %{devices: devices} do
result = Index.filter_by_status(devices, "up")
assert length(result) == 2
assert Enum.all?(result, &(&1.status == :up))
end
test "down filters to down devices", %{devices: devices} do
[d] = Index.filter_by_status(devices, "down")
assert d.status == :down
end
test "unknown filters to unknown devices", %{devices: devices} do
[d] = Index.filter_by_status(devices, "unknown")
assert d.status == :unknown
end
end
describe "calculate_site_stats/1" do
test "empty list gives zeros" do
assert %{total: 0, up: 0, down: 0, unknown: 0} == Index.calculate_site_stats([])
end
test "counts by status" do
devices = [
dev(%{status: :up}),
dev(%{status: :up}),
dev(%{status: :down}),
dev(%{status: :unknown})
]
stats = Index.calculate_site_stats(devices)
assert stats.total == 4
assert stats.up == 2
assert stats.down == 1
assert stats.unknown == 1
end
end
describe "device_type_label/1" do
test "nil is Unknown" do
assert "Unknown" == Index.device_type_label(nil)
end
test "access_point is special cased" do
assert "Access Point" == Index.device_type_label("access_point")
end
test "other strings are capitalized" do
assert "Router" == Index.device_type_label("router")
assert "Switch" == Index.device_type_label("switch")
end
test "non-string falls through to Unknown" do
assert "Unknown" == Index.device_type_label(:access_point)
assert "Unknown" == Index.device_type_label(123)
end
end
end