towerops/test/towerops_web/live/activity_feed_live_test.exs
Graham McIntire 332ee37706 test: GraphLive live mode + Show snmp_sensor format + Alert/Activity events
Bumps coverage by exercising several previously-uncovered branches:

- GraphLive.Show: new test file driving `range=live` for every
  sensor_type (latency, processors, memory, traffic, temperature,
  storage, voltage, count, pppoe_sessions, connections, wireless,
  unknown), plus `get_title_suffix/1` across sensor_id / interface_id
  / storage_id, and `change_range` flipping into live mode.
- DeviceLive.Show: format_check_value/2 now covers the snmp_sensor
  branch across temperature, voltage, current, power, frequency,
  humidity, fanspeed (default + custom unit), and an unknown
  sensor_type with/without a configured unit.
- ActivityFeedLive: clear_search and load_more events; PubSub
  handle_info clauses for new_alert / alert_resolved / device_added
  / config_changed / sync_completed / device_event / :tick / catch-all.
- AlertLive.Index: acknowledge / resolve event handlers across
  success, not-found, and cross-org unauthorized branches.

Coverage: 86.42% → 86.52%.
2026-05-08 18:12:32 -05:00

116 lines
4.5 KiB
Elixir

defmodule ToweropsWeb.ActivityFeedLiveTest do
use ToweropsWeb.ConnCase, async: true
import Phoenix.LiveViewTest
alias ToweropsWeb.ActivityFeedLive
setup :register_and_log_in_user
setup %{user: user} do
{:ok, organization} =
Towerops.Organizations.create_organization(%{name: "Activity Org"}, user.id)
%{organization: organization}
end
describe "mount and renders" do
test "renders the activity feed page", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/activity")
assert html =~ "Activity"
end
test "deep-linking to ?type=alert_fired filters", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/activity?type=alert_fired")
assert html =~ "Activity"
end
test "deep-linking to ?type=alert_resolved filters", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/activity?type=alert_resolved")
assert html =~ "Activity"
end
test "deep-linking to ?type=device_event filters", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/activity?type=device_event")
assert html =~ "Activity"
end
test "toggle_type events keep the view alive", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/activity")
_ = render_hook(view, "toggle_type", %{"type" => "alert_fired"})
_ = render_hook(view, "toggle_type", %{"type" => "config_change"})
_ = render_hook(view, "toggle_type", %{"type" => "alert_fired"})
assert render(view) =~ "Activity"
end
test "search filters the feed", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/activity")
_ = render_hook(view, "search", %{"search" => "router"})
assert render(view) =~ "Activity"
end
test "clear_search resets the search box", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/activity")
_ = render_hook(view, "search", %{"search" => "anything"})
_ = render_hook(view, "clear_search", %{})
assert render(view) =~ "Activity"
end
test "load_more bumps the limit and re-loads", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/activity")
_ = render_hook(view, "load_more", %{})
assert render(view) =~ "Activity"
end
end
describe "PubSub broadcasts trigger reloads" do
test "new_alert / alert_resolved / device_added / config_changed / sync_completed / device_event / tick all keep the view alive",
%{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/activity")
pid = view.pid
send(pid, {:new_alert, "device-1", "device_down"})
send(pid, {:alert_resolved, "device-1", "device_down"})
send(pid, {:device_added, "device-2"})
send(pid, {:config_changed, "device-1"})
send(pid, {:sync_completed, :ok})
send(pid, {:device_event, "device-1", "interface_down"})
send(pid, :tick)
send(pid, {:unknown_message, :ignored})
# Force a render after the messages have been processed.
assert render(view) =~ "Activity"
end
end
describe "severity / type helpers" do
test "severity_dot_color covers critical/warning/info combinations" do
assert ActivityFeedLive.severity_dot_color(:critical, :anything) =~ "bg-red"
assert ActivityFeedLive.severity_dot_color(:warning, :anything) =~ "bg-yellow"
assert ActivityFeedLive.severity_dot_color(:info, :alert_resolved) =~ "bg-green"
assert ActivityFeedLive.severity_dot_color(:info, :sync) =~ "bg-blue"
assert ActivityFeedLive.severity_dot_color(:info, :device_added) =~ "bg-cyan"
assert ActivityFeedLive.severity_dot_color(:info, :other) =~ "bg-gray"
assert ActivityFeedLive.severity_dot_color(nil, nil) =~ "bg-gray"
end
test "severity_icon_color covers all branches" do
assert ActivityFeedLive.severity_icon_color(:critical, :x) =~ "text-red"
assert ActivityFeedLive.severity_icon_color(:warning, :x) =~ "text-yellow"
assert ActivityFeedLive.severity_icon_color(:info, :alert_resolved) =~ "text-green"
assert ActivityFeedLive.severity_icon_color(:info, :sync) =~ "text-blue"
assert ActivityFeedLive.severity_icon_color(:info, :device_added) =~ "text-cyan"
assert ActivityFeedLive.severity_icon_color(:info, :other) =~ "text-gray"
end
test "severity_text_color covers all branches" do
assert ActivityFeedLive.severity_text_color(:critical, :x) =~ "text-red"
assert ActivityFeedLive.severity_text_color(:warning, :x) =~ "text-yellow"
assert ActivityFeedLive.severity_text_color(:info, :alert_resolved) =~ "text-green"
assert ActivityFeedLive.severity_text_color(:info, :other) =~ "text-gray-900"
end
end
end