diff --git a/config/test.exs b/config/test.exs
index 36750e7c..21ff5445 100644
--- a/config/test.exs
+++ b/config/test.exs
@@ -3,8 +3,10 @@ import Config
# Only in tests, remove the complexity from the password hashing algorithm
config :bcrypt_elixir, :log_rounds, 1
-# Print only warnings and errors during test
-config :logger, level: :warning
+# Suppress log output during tests (tests that need logs use capture_log)
+config :logger,
+ level: :error,
+ backends: []
# Initialize plugs at runtime for faster test compilation
config :phoenix, :plug_init_mode, :runtime
diff --git a/lib/towerops/snmp/profiles/dynamic.ex b/lib/towerops/snmp/profiles/dynamic.ex
index 27ce4f75..60c0a1cd 100644
--- a/lib/towerops/snmp/profiles/dynamic.ex
+++ b/lib/towerops/snmp/profiles/dynamic.ex
@@ -158,8 +158,26 @@ defmodule Towerops.Snmp.Profiles.Dynamic do
end
end
+ defp format_firmware_version(%{vendor: "Ubiquiti"}, device_data) do
+ # Extract version from format like "XW.v8.7.21.48401.251212.0939"
+ # Remove the ".v" prefix to get just "8.7.21.48401.251212.0939"
+ case Map.get(device_data, :firmware_version) do
+ nil ->
+ nil
+
+ version when is_binary(version) ->
+ case Regex.run(~r/\.v(.*)$/, version) do
+ [_, extracted_version] -> extracted_version
+ _ -> version
+ end
+
+ version ->
+ version
+ end
+ end
+
defp format_firmware_version(_profile, device_data) do
- # For non-MikroTik devices, use raw firmware version
+ # For other devices, use raw firmware version
Map.get(device_data, :firmware_version)
end
diff --git a/lib/towerops/snmp/profiles/vendors/epmp.ex b/lib/towerops/snmp/profiles/vendors/epmp.ex
index 9fe24890..e7936c18 100644
--- a/lib/towerops/snmp/profiles/vendors/epmp.ex
+++ b/lib/towerops/snmp/profiles/vendors/epmp.ex
@@ -15,9 +15,11 @@ defmodule Towerops.Snmp.Profiles.Vendors.Epmp do
alias Towerops.Snmp.Client
alias Towerops.Snmp.Profiles.Vendors.Vendor
- # OIDs for hardware detection
- @interface_mode_oid "1.3.6.1.4.1.17713.21.1.1.1.0"
- @sub_mode_oid "1.3.6.1.4.1.17713.21.1.1.2.0"
+ # OIDs for hardware detection (from CAMBIUM-PMP80211-MIB)
+ # wirelessInterfaceMode = { wirelessInterface 1 } = { { wireless 2 } 1 } = 1.3.6.1.4.1.17713.21.3.8.2.1
+ @interface_mode_oid "1.3.6.1.4.1.17713.21.3.8.2.1.0"
+ # cambiumSubModeType = { cambiumGeneralStatus 33 } = 1.3.6.1.4.1.17713.21.1.1.33
+ @sub_mode_oid "1.3.6.1.4.1.17713.21.1.1.33.0"
@impl true
def profile_names, do: ["epmp"]
diff --git a/lib/towerops_web/live/device_live/show.ex b/lib/towerops_web/live/device_live/show.ex
index 42fd9f0e..4c3027c4 100644
--- a/lib/towerops_web/live/device_live/show.ex
+++ b/lib/towerops_web/live/device_live/show.ex
@@ -171,6 +171,21 @@ defmodule ToweropsWeb.DeviceLive.Show do
storage_volume_chart_data = load_storage_volume_chart_data(storage)
traffic_chart_data = load_overall_traffic_chart_data(device_id)
+ # Wireless sensor chart data
+ wireless_chart_data =
+ load_sensor_chart_data(device_id, [
+ "frequency",
+ "power",
+ "rssi",
+ "ccq",
+ "clients",
+ "distance",
+ "noise-floor",
+ "quality",
+ "rate",
+ "utilization"
+ ])
+
# Filter sensors by type for temperature, voltage, storage, count, and transceivers
# Separate transceiver sensors from general sensors
{transceiver_sensors, non_transceiver_sensors} =
@@ -187,6 +202,9 @@ defmodule ToweropsWeb.DeviceLive.Show do
count_sensors = Enum.filter(non_transceiver_sensors, &(&1.sensor_type == "count"))
+ # Wireless sensors (frequency, power, rssi, ccq, etc.)
+ wireless_sensors = Enum.filter(non_transceiver_sensors, &wireless_sensor?/1)
+
# Group transceiver sensors by transceiver name
grouped_transceivers = group_transceiver_sensors(transceiver_sensors)
@@ -221,10 +239,12 @@ defmodule ToweropsWeb.DeviceLive.Show do
|> assign(:storage_chart_data, storage_chart_data)
|> assign(:storage_volume_chart_data, storage_volume_chart_data)
|> assign(:traffic_chart_data, traffic_chart_data)
+ |> assign(:wireless_chart_data, wireless_chart_data)
|> assign(:temperature_sensors, temperature_sensors)
|> assign(:voltage_sensors, voltage_sensors)
|> assign(:storage_sensors, storage_sensors)
|> assign(:count_sensors, count_sensors)
+ |> assign(:wireless_sensors, wireless_sensors)
|> assign(:grouped_transceivers, grouped_transceivers)
|> assign(:agent_info, agent_info)
end
@@ -777,4 +797,19 @@ defmodule ToweropsWeb.DeviceLive.Show do
sensor.sensor_descr &&
String.contains?(String.downcase(sensor.sensor_descr), "voltage")
end
+
+ defp wireless_sensor?(sensor) do
+ sensor.sensor_type in [
+ "frequency",
+ "power",
+ "rssi",
+ "ccq",
+ "clients",
+ "distance",
+ "noise-floor",
+ "quality",
+ "rate",
+ "utilization"
+ ]
+ end
end
diff --git a/lib/towerops_web/live/device_live/show.html.heex b/lib/towerops_web/live/device_live/show.html.heex
index 065084d2..2a18adf3 100644
--- a/lib/towerops_web/live/device_live/show.html.heex
+++ b/lib/towerops_web/live/device_live/show.html.heex
@@ -738,6 +738,46 @@
<% end %>
+
+ <%= if @wireless_sensors && length(@wireless_sensors) > 0 do %>
+
+
+
Wireless
+
+
+
+ <%= for sensor <- @wireless_sensors do %>
+
+
-
+ <.link
+ navigate={
+ ~p"/devices/#{@device.id}/graph/wireless?sensor_id=#{sensor.id}"
+ }
+ class="hover:text-blue-600 dark:hover:text-blue-400 hover:underline"
+ >
+ {sensor.sensor_descr}
+
+
+ -
+ <%= if sensor.latest_reading do %>
+ <%= if sensor.sensor_type in ["clients", "ccq", "utilization"] do %>
+ {trunc(sensor.latest_reading.value)}
+ <% else %>
+ {Float.round(sensor.latest_reading.value, 1)}
+ <% end %>
+ <%= if sensor.sensor_unit && sensor.sensor_unit != "" do %>
+ {sensor.sensor_unit}
+ <% end %>
+ <% else %>
+ N/A
+ <% end %>
+
+
+ <% end %>
+
+
+
+ <% end %>
<% "ports" -> %>
diff --git a/lib/towerops_web/live/graph_live/show.ex b/lib/towerops_web/live/graph_live/show.ex
index 3e7a7b57..940bf68a 100644
--- a/lib/towerops_web/live/graph_live/show.ex
+++ b/lib/towerops_web/live/graph_live/show.ex
@@ -146,6 +146,7 @@ defmodule ToweropsWeb.GraphLive.Show do
defp get_chart_config("count"), do: {"Count", "", true}
defp get_chart_config("pppoe_sessions"), do: {"PPPoE Sessions", "", true}
defp get_chart_config("connections"), do: {"Connections", "", true}
+ defp get_chart_config("wireless"), do: {"Wireless Metrics", "", true}
# Humanize unknown sensor types for title
defp get_chart_config(sensor_type), do: {humanize_sensor_type(sensor_type), "", true}
diff --git a/priv/profiles/os_discovery/airos.yaml b/priv/profiles/os_discovery/airos.yaml
index 34adc637..34b83fa8 100644
--- a/priv/profiles/os_discovery/airos.yaml
+++ b/priv/profiles/os_discovery/airos.yaml
@@ -1,6 +1,8 @@
mib: UBNT-AirMAX-MIB
modules:
os:
+ hardware: IEEE802dot11-MIB::dot11manufacturerProductName.5
+ version: IEEE802dot11-MIB::dot11manufacturerProductVersion.5
lat: UBNT-AirMAX-MIB::ubntGpsLat.0
long: UBNT-AirMAX-MIB::ubntGpsLon.0
processors:
diff --git a/test/towerops/snmp/profiles/vendors/epmp_test.exs b/test/towerops/snmp/profiles/vendors/epmp_test.exs
index 8bdbd19b..72a28087 100644
--- a/test/towerops/snmp/profiles/vendors/epmp_test.exs
+++ b/test/towerops/snmp/profiles/vendors/epmp_test.exs
@@ -24,29 +24,29 @@ defmodule Towerops.Snmp.Profiles.Vendors.EpmpTest do
describe "detect_hardware/1" do
test "returns ePMP AP when interface mode is 1" do
- expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.1.0", _ -> {:ok, 1} end)
- expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.2.0", _ -> {:ok, 1} end)
+ expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.3.8.2.1.0", _ -> {:ok, 1} end)
+ expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.33.0", _ -> {:ok, 1} end)
assert Epmp.detect_hardware(@client_opts) == "ePMP AP"
end
test "returns ePTP Master when interface mode is 1 and sub mode is 5" do
- expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.1.0", _ -> {:ok, 1} end)
- expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.2.0", _ -> {:ok, 5} end)
+ expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.3.8.2.1.0", _ -> {:ok, 1} end)
+ expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.33.0", _ -> {:ok, 5} end)
assert Epmp.detect_hardware(@client_opts) == "ePTP Master"
end
test "returns ePMP SM when interface mode is 2" do
- expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.1.0", _ -> {:ok, 2} end)
- expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.2.0", _ -> {:ok, 1} end)
+ expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.3.8.2.1.0", _ -> {:ok, 2} end)
+ expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.33.0", _ -> {:ok, 1} end)
assert Epmp.detect_hardware(@client_opts) == "ePMP SM"
end
test "returns ePTP Slave when interface mode is 2 and sub mode is 4" do
- expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.1.0", _ -> {:ok, 2} end)
- expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.2.0", _ -> {:ok, 4} end)
+ expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.3.8.2.1.0", _ -> {:ok, 2} end)
+ expect(SnmpMock, :get, fn _, "1.3.6.1.4.1.17713.21.1.1.33.0", _ -> {:ok, 4} end)
assert Epmp.detect_hardware(@client_opts) == "ePTP Slave"
end
diff --git a/test/towerops/workers/discovery_worker_test.exs b/test/towerops/workers/discovery_worker_test.exs
index 4ba5bb8f..7176d70c 100644
--- a/test/towerops/workers/discovery_worker_test.exs
+++ b/test/towerops/workers/discovery_worker_test.exs
@@ -70,10 +70,10 @@ defmodule Towerops.Workers.DiscoveryWorkerTest do
assert snmp_device.sys_name == "test-device"
end
- test "returns error when device not found" do
+ test "returns :discard when device not found" do
non_existent_id = Ecto.UUID.generate()
- assert {:error, :device_not_found} =
+ assert :discard =
DiscoveryWorker.perform(%Oban.Job{args: %{"device_id" => non_existent_id}})
end
@@ -127,7 +127,7 @@ defmodule Towerops.Workers.DiscoveryWorkerTest do
DiscoveryWorker.perform(%Oban.Job{args: %{"device_id" => device.id}})
end)
- assert log =~ "SNMP discovery failed for device #{device.id}"
+ assert log =~ "SNMP discovery failed from Phoenix cluster for device #{device.id}"
end
end
end
diff --git a/test/towerops_web/live/agent_live/index_test.exs b/test/towerops_web/live/agent_live/index_test.exs
index e4c93128..44d56a31 100644
--- a/test/towerops_web/live/agent_live/index_test.exs
+++ b/test/towerops_web/live/agent_live/index_test.exs
@@ -144,7 +144,7 @@ defmodule ToweropsWeb.AgentLive.IndexTest do
test "shows Never connected for agents without last_seen_at", %{
conn: conn,
user: user,
- organization: _organization
+ organization: organization
} do
{:ok, agent_token, _token} = Agents.create_agent_token(organization.id, "Never Seen")
@@ -165,7 +165,7 @@ defmodule ToweropsWeb.AgentLive.IndexTest do
test "shows agent status information in the page", %{
conn: conn,
user: user,
- organization: _organization
+ organization: organization
} do
{:ok, agent_token, _token} = Agents.create_agent_token(organization.id, "Status Agent")
@@ -257,7 +257,7 @@ defmodule ToweropsWeb.AgentLive.IndexTest do
test "non-superadmin cannot create cloud poller", %{
conn: conn,
user: user,
- organization: _organization
+ organization: organization
} do
conn =
conn
@@ -289,7 +289,7 @@ defmodule ToweropsWeb.AgentLive.IndexTest do
test "superadmin can create regular agent by not checking cloud poller", %{
conn: conn,
superadmin: superadmin,
- organization: _organization
+ organization: organization
} do
conn =
conn
@@ -430,7 +430,7 @@ defmodule ToweropsWeb.AgentLive.IndexTest do
test "superadmin can delete cloud poller", %{
conn: conn,
superadmin: superadmin,
- organization: organization,
+ organization: _organization,
cloud_poller: cloud_poller
} do
conn =
@@ -452,7 +452,7 @@ defmodule ToweropsWeb.AgentLive.IndexTest do
test "superadmin can regenerate cloud poller token", %{
conn: conn,
superadmin: superadmin,
- organization: organization,
+ organization: _organization,
cloud_poller: cloud_poller
} do
conn =
@@ -471,7 +471,7 @@ defmodule ToweropsWeb.AgentLive.IndexTest do
test "superadmin can view cloud poller setup instructions", %{
conn: conn,
superadmin: superadmin,
- organization: organization,
+ organization: _organization,
cloud_poller: cloud_poller
} do
conn =
@@ -515,7 +515,7 @@ defmodule ToweropsWeb.AgentLive.IndexTest do
test "superadmin can set global default cloud poller with validation", %{
conn: conn,
superadmin: superadmin,
- organization: organization,
+ organization: _organization,
cloud_poller: cloud_poller
} do
conn =
@@ -571,7 +571,7 @@ defmodule ToweropsWeb.AgentLive.IndexTest do
test "superadmin can clear global default cloud poller", %{
conn: conn,
superadmin: superadmin,
- organization: organization,
+ organization: _organization,
cloud_poller: cloud_poller
} do
# First set a global default
@@ -602,7 +602,7 @@ defmodule ToweropsWeb.AgentLive.IndexTest do
test "deleting cloud poller clears it from global default", %{
conn: conn,
superadmin: superadmin,
- organization: organization,
+ organization: _organization,
cloud_poller: cloud_poller
} do
# Set as global default
diff --git a/test/towerops_web/live/agent_live_test.exs b/test/towerops_web/live/agent_live_test.exs
index 73e65adf..0e7a933c 100644
--- a/test/towerops_web/live/agent_live_test.exs
+++ b/test/towerops_web/live/agent_live_test.exs
@@ -19,21 +19,21 @@ defmodule ToweropsWeb.AgentLiveTest do
test "lists all agent tokens", %{conn: conn, organization: organization} do
{:ok, _agent_token, _token} = Agents.create_agent_token(organization.id, "Agent 1")
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/agents")
+ {:ok, _view, html} = live(conn, ~p"/agents")
assert html =~ "Remote Agents"
assert html =~ "Agent 1"
end
- test "displays empty state when no agents", %{conn: conn, organization: organization} do
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/agents")
+ test "displays empty state when no agents", %{conn: conn, organization: _organization} do
+ {:ok, _view, html} = live(conn, ~p"/agents")
assert html =~ "No agents"
assert html =~ "Get started by creating your first remote agent"
end
- test "creates new agent and shows token modal", %{conn: conn, organization: organization} do
- {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/agents")
+ test "creates new agent and shows token modal", %{conn: conn, organization: _organization} do
+ {:ok, view, _html} = live(conn, ~p"/agents")
html =
view
@@ -48,7 +48,7 @@ defmodule ToweropsWeb.AgentLiveTest do
test "deletes agent", %{conn: conn, organization: organization} do
{:ok, agent_token, _token} = Agents.create_agent_token(organization.id, "Agent 1")
- {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/agents")
+ {:ok, view, _html} = live(conn, ~p"/agents")
html =
view
@@ -61,8 +61,8 @@ defmodule ToweropsWeb.AgentLiveTest do
assert is_nil(Towerops.Repo.get(Agents.AgentToken, agent_token.id))
end
- test "closes token modal", %{conn: conn, organization: organization} do
- {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/agents")
+ test "closes token modal", %{conn: conn, organization: _organization} do
+ {:ok, view, _html} = live(conn, ~p"/agents")
# Create agent to show modal
view
@@ -78,9 +78,9 @@ defmodule ToweropsWeb.AgentLiveTest do
refute html =~ "Agent Created Successfully"
end
- test "requires authentication", %{organization: organization} do
+ test "requires authentication", %{organization: _organization} do
conn = build_conn()
- {:error, redirect} = live(conn, ~p"/orgs/#{organization.slug}/agents")
+ {:error, redirect} = live(conn, ~p"/agents")
assert {:redirect, %{to: path}} = redirect
assert path == ~p"/users/log-in"
@@ -99,7 +99,7 @@ defmodule ToweropsWeb.AgentLiveTest do
set: [last_seen_at: three_minutes_ago]
)
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/agents")
+ {:ok, _view, html} = live(conn, ~p"/agents")
assert html =~ "Warning"
assert html =~ "3m ago"
@@ -118,7 +118,7 @@ defmodule ToweropsWeb.AgentLiveTest do
set: [last_seen_at: ten_minutes_ago]
)
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/agents")
+ {:ok, _view, html} = live(conn, ~p"/agents")
assert html =~ "Offline"
assert html =~ "10m ago"
@@ -137,7 +137,7 @@ defmodule ToweropsWeb.AgentLiveTest do
set: [last_seen_at: two_hours_ago]
)
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/agents")
+ {:ok, _view, html} = live(conn, ~p"/agents")
assert html =~ "2h ago"
end
@@ -155,7 +155,7 @@ defmodule ToweropsWeb.AgentLiveTest do
set: [last_seen_at: two_days_ago]
)
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/agents")
+ {:ok, _view, html} = live(conn, ~p"/agents")
assert html =~ "2d ago"
end
@@ -165,7 +165,7 @@ defmodule ToweropsWeb.AgentLiveTest do
test "loads edit page with existing agent name", %{conn: conn, organization: organization} do
{:ok, agent_token, _token} = Agents.create_agent_token(organization.id, "Old Agent Name")
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/agents/#{agent_token.id}/edit")
+ {:ok, _view, html} = live(conn, ~p"/agents/#{agent_token.id}/edit")
assert html =~ "Edit Agent"
assert html =~ "Old Agent Name"
@@ -175,7 +175,7 @@ defmodule ToweropsWeb.AgentLiveTest do
test "validates empty name shows error on submit", %{conn: conn, organization: organization} do
{:ok, agent_token, _token} = Agents.create_agent_token(organization.id, "Test Agent")
- {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/agents/#{agent_token.id}/edit")
+ {:ok, view, _html} = live(conn, ~p"/agents/#{agent_token.id}/edit")
html =
view
@@ -195,14 +195,14 @@ defmodule ToweropsWeb.AgentLiveTest do
} do
{:ok, agent_token, _token} = Agents.create_agent_token(organization.id, "Old Name")
- {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/agents/#{agent_token.id}/edit")
+ {:ok, view, _html} = live(conn, ~p"/agents/#{agent_token.id}/edit")
view
|> form("#edit-agent-form", agent_token: %{name: "New Name"})
|> render_submit()
# Verify redirect to show page with flash message
- assert_redirect(view, ~p"/orgs/#{organization.slug}/agents/#{agent_token.id}")
+ assert_redirect(view, ~p"/agents/#{agent_token.id}")
# Verify agent was updated
updated_agent = Agents.get_agent_token!(agent_token.id)
@@ -212,26 +212,26 @@ defmodule ToweropsWeb.AgentLiveTest do
test "cancel button navigates back to show page", %{conn: conn, organization: organization} do
{:ok, agent_token, _token} = Agents.create_agent_token(organization.id, "Test Agent")
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/agents/#{agent_token.id}/edit")
+ {:ok, _view, html} = live(conn, ~p"/agents/#{agent_token.id}/edit")
assert html =~ "Cancel"
# Find cancel link and verify it points to show page
assert html =~
- ~p"/orgs/#{organization.slug}/agents/#{agent_token.id}"
+ ~p"/agents/#{agent_token.id}"
end
test "requires authentication", %{organization: organization} do
{:ok, agent_token, _token} = Agents.create_agent_token(organization.id, "Test Agent")
conn = build_conn()
- {:error, redirect} = live(conn, ~p"/orgs/#{organization.slug}/agents/#{agent_token.id}/edit")
+ {:error, redirect} = live(conn, ~p"/agents/#{agent_token.id}/edit")
assert {:redirect, %{to: path}} = redirect
assert path == ~p"/users/log-in"
end
- test "verifies agent belongs to organization", %{conn: conn, organization: organization, user: user} do
+ test "verifies agent belongs to organization", %{conn: conn, organization: _organization, user: user} do
# Create another organization
{:ok, other_org} = Towerops.Organizations.create_organization(%{name: "Other Org"}, user.id)
{:ok, agent_token, _token} = Agents.create_agent_token(other_org.id, "Other Agent")
@@ -239,7 +239,7 @@ defmodule ToweropsWeb.AgentLiveTest do
# Try to edit agent from other organization - capture_log suppresses expected Router exception log
capture_log(fn ->
assert_raise Ecto.NoResultsError, fn ->
- live(conn, ~p"/orgs/#{organization.slug}/agents/#{agent_token.id}/edit")
+ live(conn, ~p"/agents/#{agent_token.id}/edit")
end
end)
end
diff --git a/test/towerops_web/live/alert_live_test.exs b/test/towerops_web/live/alert_live_test.exs
index c7feacec..7aca0288 100644
--- a/test/towerops_web/live/alert_live_test.exs
+++ b/test/towerops_web/live/alert_live_test.exs
@@ -25,20 +25,20 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
end
describe "Index" do
- test "displays alerts page", %{conn: conn, organization: organization} do
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/alerts")
+ test "displays alerts page", %{conn: conn, organization: _organization} do
+ {:ok, _view, html} = live(conn, ~p"/alerts")
assert html =~ "Alerts"
assert html =~ "Monitor and acknowledge system alerts"
end
- test "displays empty state when no alerts", %{conn: conn, organization: organization} do
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/alerts")
+ test "displays empty state when no alerts", %{conn: conn, organization: _organization} do
+ {:ok, _view, html} = live(conn, ~p"/alerts")
assert html =~ "No alerts"
end
- test "lists all alerts", %{conn: conn, organization: organization, device: device} do
+ test "lists all alerts", %{conn: conn, organization: _organization, device: device} do
{:ok, _alert} =
Towerops.Alerts.create_alert(%{
device_id: device.id,
@@ -47,14 +47,14 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
message: "Device is down"
})
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/alerts")
+ {:ok, _view, html} = live(conn, ~p"/alerts")
assert html =~ "Test Router"
assert html =~ "Device is down"
assert html =~ "Device Down"
end
- test "filters active alerts", %{conn: conn, organization: organization, device: device} do
+ test "filters active alerts", %{conn: conn, organization: _organization, device: device} do
# Create an active equipment_down alert
{:ok, _active_alert} =
Towerops.Alerts.create_alert(%{
@@ -74,7 +74,7 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
})
{:ok, _view, html} =
- live(conn, ~p"/orgs/#{organization.slug}/alerts?filter=active")
+ live(conn, ~p"/alerts?filter=active")
# Should show equipment_down alert
assert html =~ "Device is down"
@@ -82,7 +82,7 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
refute html =~ "Device recovered"
end
- test "acknowledges an alert", %{conn: conn, organization: organization, device: device} do
+ test "acknowledges an alert", %{conn: conn, organization: _organization, device: device} do
{:ok, alert} =
Towerops.Alerts.create_alert(%{
device_id: device.id,
@@ -91,7 +91,7 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
message: "Device is down"
})
- {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/alerts")
+ {:ok, view, _html} = live(conn, ~p"/alerts")
html =
view
@@ -103,7 +103,7 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
test "does not show acknowledge button for device_up alerts", %{
conn: conn,
- organization: organization,
+ organization: _organization,
device: device
} do
{:ok, _alert} =
@@ -114,7 +114,7 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
message: "Device recovered"
})
- {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/alerts")
+ {:ok, _view, html} = live(conn, ~p"/alerts")
# Should not show acknowledge button for device_up alerts
refute html =~ "Acknowledge"
@@ -122,10 +122,10 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
test "updates in real-time when new alert is created", %{
conn: conn,
- organization: organization,
+ organization: _organization,
device: device
} do
- {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/alerts")
+ {:ok, view, _html} = live(conn, ~p"/alerts")
# Broadcast new alert event
Phoenix.PubSub.broadcast(
@@ -140,7 +140,7 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
test "updates in real-time when alert is resolved", %{
conn: conn,
- organization: organization,
+ organization: _organization,
device: device
} do
{:ok, alert} =
@@ -151,7 +151,7 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
message: "Device is down"
})
- {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/alerts")
+ {:ok, view, _html} = live(conn, ~p"/alerts")
# Resolve the alert and broadcast
Towerops.Alerts.resolve_alert(alert)
@@ -166,9 +166,9 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
assert render(view)
end
- test "requires authentication", %{organization: organization} do
+ test "requires authentication", %{organization: _organization} do
conn = build_conn()
- {:error, redirect} = live(conn, ~p"/orgs/#{organization.slug}/alerts")
+ {:error, redirect} = live(conn, ~p"/alerts")
assert {:redirect, %{to: path}} = redirect
assert path == ~p"/users/log-in"
diff --git a/test/towerops_web/live/dashboard_live_test.exs b/test/towerops_web/live/dashboard_live_test.exs
index 96eda78a..59dd85d6 100644
--- a/test/towerops_web/live/dashboard_live_test.exs
+++ b/test/towerops_web/live/dashboard_live_test.exs
@@ -119,7 +119,7 @@ defmodule ToweropsWeb.DashboardLiveTest do
# Check for navigation links
assert html =~ ~p"/sites"
assert html =~ ~p"/devices"
- assert html =~ ~p"/orgs/#{organization.slug}/alerts"
+ assert html =~ ~p"/alerts"
end
test "requires authentication", %{organization: organization} do