test fixes

This commit is contained in:
Graham McIntire 2026-01-26 15:27:59 -06:00
parent 756a6b4cd4
commit b20a58aec4
No known key found for this signature in database
13 changed files with 169 additions and 69 deletions

View file

@ -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

View file

@ -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

View file

@ -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"]

View file

@ -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

View file

@ -738,6 +738,46 @@
</div>
</div>
<% end %>
<!-- Wireless Sensors (Frequency, Power, CCQ, etc.) -->
<%= if @wireless_sensors && length(@wireless_sensors) > 0 do %>
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">Wireless</h3>
</div>
<div class="p-4">
<dl class="space-y-1">
<%= for sensor <- @wireless_sensors do %>
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
<dt class="text-sm text-gray-600 dark:text-gray-400">
<.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}
</.link>
</dt>
<dd class="text-sm font-medium text-gray-900 dark:text-white">
<%= 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 %>
</dd>
</div>
<% end %>
</dl>
</div>
</div>
<% end %>
</div>
</div>
<% "ports" -> %>

View file

@ -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}

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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