towerops/test/towerops_web/live/smoke_test.exs
Graham McIntire fde6158251 ci: enable PostGIS in test workflows + add tests covering ~3pp more
CI: switch postgres service image to timescale/timescaledb-ha:pg17-all
which bundles PostGIS, fixing the lidar migration failure in PR and
production workflows.

Tests: ~30 new test files / extensions, ~600+ new tests, taking total
coverage from 70.42% to 73.4%. Targets included GraphQL resolver
unauthenticated paths, SNMP context queries (mempools, processors,
ip_addresses, neighbors, wireless_clients, arp_entries), worker
routing/lifecycle (alert notification, alert digest, weather sync,
job cleanup, cn_maestro, uisp, mikrotik backup, report worker),
SNMP monitoring executors (storage, interface, processor) end-to-end
via stub adapter, NetBox + Sonar sync integration paths, ConfigChanges
listing and correlator, organizations membership query, and live-view
smoke tests for org-scoped settings, integrations, maintenance, agent,
device deep paths, schedules. Property tests used for query
composition and pure helpers where natural.
2026-05-05 10:35:22 -05:00

350 lines
10 KiB
Elixir

defmodule ToweropsWeb.LiveViewSmokeTest do
@moduledoc """
Smoke tests for LiveView pages.
For each routed LiveView, verify that it mounts successfully and renders
without raising. These tests exist primarily for coverage of happy-path
mount/render code.
"""
use ToweropsWeb.ConnCase, async: true
import Phoenix.LiveViewTest
setup :register_and_log_in_user
setup %{user: user} do
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Smoke Org"}, user.id)
%{organization: organization}
end
describe "smoke: informational pages" do
test "GET /changelog", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/changelog")
end
test "GET /activity", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/activity")
end
test "GET /insights", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/insights")
end
test "GET /rf-links", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/rf-links")
end
test "GET /reports", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/reports")
end
test "GET /weathermap", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/weathermap")
end
test "GET /sites-map", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/sites-map")
end
test "GET /network-map", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/network-map")
end
end
describe "smoke: maintenance pages" do
test "GET /maintenance", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/maintenance")
end
test "GET /maintenance/new", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/maintenance/new")
end
end
describe "smoke: on-call pages" do
test "GET /schedules", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/schedules")
end
test "GET /schedules/escalation-policies", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/schedules/escalation-policies")
end
end
describe "smoke: devices/sites" do
test "GET /sites", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/sites")
end
test "GET /devices", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/devices")
end
end
describe "smoke: trace/help" do
test "GET /trace", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/trace")
end
test "GET /help", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/help")
end
end
describe "smoke: account pages" do
test "GET /mobile/qr-login", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/mobile/qr-login")
end
end
describe "smoke: other top-level" do
test "GET /alerts", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/alerts")
end
test "GET /dashboard", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/dashboard")
end
end
describe "smoke: schedule new forms" do
test "GET /schedules/new", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/schedules/new")
end
test "GET /schedules/escalation-policies/new", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/schedules/escalation-policies/new")
end
end
describe "smoke: sites/devices new forms" do
test "GET /sites/new", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/sites/new")
end
test "GET /devices/new", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/devices/new")
end
end
describe "smoke: orgs page" do
test "GET /orgs", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/orgs")
end
test "GET /orgs/new", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/orgs/new")
end
end
describe "smoke: specific-resource paths" do
defp assert_mount_or_redirect(result) do
assert match?({:ok, _, _}, result) or
match?({:error, {:redirect, _}}, result) or
match?({:error, {:live_redirect, _}}, result)
end
test "GET /sites/:id", %{conn: conn, organization: org} do
{:ok, site} =
Towerops.Sites.create_site(%{
name: "S-#{System.unique_integer([:positive])}",
organization_id: org.id
})
assert_mount_or_redirect(live(conn, ~p"/sites/#{site.id}"))
end
test "GET /sites/:id/edit", %{conn: conn, organization: org} do
{:ok, site} =
Towerops.Sites.create_site(%{
name: "S-#{System.unique_integer([:positive])}",
organization_id: org.id
})
assert_mount_or_redirect(live(conn, ~p"/sites/#{site.id}/edit"))
end
test "GET /orgs/:id/settings", %{conn: conn, organization: org} do
assert_mount_or_redirect(live(conn, ~p"/orgs/#{org.id}/settings"))
end
end
describe "smoke: alert-specific paths" do
test "GET /alerts with query filter", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/alerts?severity=critical")
end
test "GET /dashboard with tab param", %{conn: conn} do
assert {:ok, _view, _html} = live(conn, ~p"/dashboard")
end
end
describe "smoke: extra pages" do
test "GET /trace", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/trace"))
end
test "GET /alerts?status=resolved", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/alerts?status=resolved"))
end
test "GET /devices?tab=monitored", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/devices?tab=monitored"))
end
test "GET /devices?search=foo", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/devices?search=foo"))
end
test "GET /activity?filter=all", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/activity?filter=all"))
end
test "GET /reports?page=1", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/reports?page=1"))
end
test "GET /rf-links?health=warning", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/rf-links?health=warning"))
end
test "GET /insights?filter=unresolved", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/insights?filter=unresolved"))
end
test "GET /maintenance?filter=active", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/maintenance?filter=active"))
end
test "GET /maintenance?filter=upcoming", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/maintenance?filter=upcoming"))
end
test "GET /maintenance?filter=past", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/maintenance?filter=past"))
end
end
describe "smoke: maintenance show & edit" do
setup %{organization: org, user: user} do
window =
Towerops.MaintenanceFixtures.maintenance_window_fixture(%{
name: "Smoke Window",
organization_id: org.id,
created_by_id: user.id
})
%{window: window}
end
test "GET /maintenance/:id", %{conn: conn, window: window} do
assert_mount_or_redirect(live(conn, ~p"/maintenance/#{window.id}"))
end
test "GET /maintenance/:id/edit", %{conn: conn, window: window} do
assert_mount_or_redirect(live(conn, ~p"/maintenance/#{window.id}/edit"))
end
end
describe "smoke: agents specific paths" do
setup %{organization: org} do
{:ok, agent_token, _raw} =
Towerops.Agents.create_agent_token(org.id, "Smoke Agent")
%{agent_token: agent_token}
end
test "GET /agents/:id", %{conn: conn, agent_token: token} do
assert_mount_or_redirect(live(conn, ~p"/agents/#{token.id}"))
end
test "GET /agents/:id/edit", %{conn: conn, agent_token: token} do
assert_mount_or_redirect(live(conn, ~p"/agents/#{token.id}/edit"))
end
end
describe "smoke: org-scoped settings" do
test "GET /orgs/:slug/settings", %{conn: conn, organization: org} do
assert_mount_or_redirect(live(conn, ~p"/orgs/#{org.slug}/settings"))
end
test "GET /orgs/:slug/settings/integrations", %{conn: conn, organization: org} do
assert_mount_or_redirect(live(conn, ~p"/orgs/#{org.slug}/settings/integrations"))
end
end
describe "smoke: more top-level pages" do
test "GET /agents", %{conn: conn} do
assert {:ok, _, _} = live(conn, ~p"/agents")
end
test "GET /sites", %{conn: conn} do
assert {:ok, _, _} = live(conn, ~p"/sites")
end
test "GET /devices", %{conn: conn} do
assert {:ok, _, _} = live(conn, ~p"/devices")
end
test "GET /mobile/qr-login", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/mobile/qr-login"))
end
test "GET /account/activity", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/account/activity"))
end
test "GET /account/totp-enrollment", %{conn: conn} do
assert_mount_or_redirect(live(conn, ~p"/account/totp-enrollment"))
end
end
describe "smoke: device-related deep paths" do
setup %{organization: org} do
device =
Towerops.DevicesFixtures.device_fixture(%{
organization_id: org.id,
name: "Smoke Device"
})
%{device: device}
end
test "GET /devices/:id", %{conn: conn, device: device} do
assert_mount_or_redirect(live(conn, ~p"/devices/#{device.id}"))
end
test "GET /devices/:id/edit", %{conn: conn, device: device} do
assert_mount_or_redirect(live(conn, ~p"/devices/#{device.id}/edit"))
end
test "GET /devices/:id/config-timeline", %{conn: conn, device: device} do
assert_mount_or_redirect(live(conn, ~p"/devices/#{device.id}/config-timeline"))
end
test "GET /devices/:id/graph/temperature", %{conn: conn, device: device} do
assert_mount_or_redirect(live(conn, ~p"/devices/#{device.id}/graph/temperature"))
end
end
describe "smoke: schedules deep paths" do
setup %{organization: org} do
{:ok, schedule} =
Towerops.OnCall.create_schedule(%{
name: "Smoke Schedule",
organization_id: org.id,
timezone: "America/Chicago"
})
%{schedule: schedule}
end
test "GET /schedules/:id", %{conn: conn, schedule: schedule} do
assert_mount_or_redirect(live(conn, ~p"/schedules/#{schedule.id}"))
end
test "GET /schedules/:id/edit", %{conn: conn, schedule: schedule} do
assert_mount_or_redirect(live(conn, ~p"/schedules/#{schedule.id}/edit"))
end
end
end