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.
350 lines
10 KiB
Elixir
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
|