diff --git a/lib/towerops/snmp/adapters/replay.ex b/lib/towerops/snmp/adapters/replay.ex index e6c245c2..d8c7baad 100644 --- a/lib/towerops/snmp/adapters/replay.ex +++ b/lib/towerops/snmp/adapters/replay.ex @@ -143,22 +143,26 @@ defmodule Towerops.Snmp.Adapters.Replay do Regex.match?(~r/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, value) -> value - # OID-like string (contains dots but not IPv4) - check FOURTH - # Keep as string rather than parsing to avoid issues with SNMP shorthand notation - # Example: "1.3.6.1.4.1.9" => "1.3.6.1.4.1.9" (not parsed) - # Note: Leading dots (relative OIDs) and other SNMP notation are preserved - Regex.match?(~r/^\.?[\d\.]+$/, value) and String.contains?(value, ".") -> - value + # Float - check FOURTH (before OID check!) + # Example: "98.6" => 98.6 + # Must have exactly one dot with digits before and after + Regex.match?(~r/^-?\d+\.\d+$/, value) -> + String.to_float(value) # Pure integer (no dots) - check FIFTH # Example: "42" => 42 Regex.match?(~r/^\d+$/, value) -> String.to_integer(value) - # Float - check SIXTH - # Example: "98.6" => 98.6 - Regex.match?(~r/^-?\d+\.\d+$/, value) -> - String.to_float(value) + # OID-like string (multiple dots) - check SIXTH + # Parse to list of integers per module documentation + # Example: "1.3.6.1.4.1.9" => [1, 3, 6, 1, 4, 1, 9] + # Requires at least 2 dots (3+ components) to distinguish from floats + Regex.match?(~r/^\.?\d+(\.\d+){2,}$/, value) -> + value + |> String.trim_leading(".") + |> String.split(".") + |> Enum.map(&String.to_integer/1) # Default: string # Example: "Cisco IOS", "GigabitEthernet0/1" diff --git a/lib/towerops_web/user_auth.ex b/lib/towerops_web/user_auth.ex index f709ad5f..132fbcd7 100644 --- a/lib/towerops_web/user_auth.ex +++ b/lib/towerops_web/user_auth.ex @@ -890,7 +890,7 @@ defmodule ToweropsWeb.UserAuth do |> assign(:current_scope, Scope.for_user(superuser)) |> maybe_set_default_organization(superuser) |> put_flash(:info, t_admin("Stopped impersonating")) - |> redirect(to: ~p"/devices") + |> redirect(to: signed_in_path(superuser)) end ## Login tracking helpers diff --git a/test/towerops/snmp/profiles/vendors/routeros_test.exs b/test/towerops/snmp/profiles/vendors/routeros_test.exs index a37eb018..d65950df 100644 --- a/test/towerops/snmp/profiles/vendors/routeros_test.exs +++ b/test/towerops/snmp/profiles/vendors/routeros_test.exs @@ -394,7 +394,8 @@ defmodule Towerops.Snmp.Profiles.Vendors.RouterosTest do sensors = Routeros.discover_wireless_sensors(@client_opts) # Find the voltage sensor - voltage_sensor = Enum.find(sensors, &(&1.sensor_descr == "psu-voltage")) + # Note: format_gauge_description prefixes with "System " for non-generic names + voltage_sensor = Enum.find(sensors, &(&1.sensor_descr == "System psu-voltage")) assert voltage_sensor assert voltage_sensor.sensor_type == "voltage" assert voltage_sensor.sensor_unit == "V" @@ -403,7 +404,7 @@ defmodule Towerops.Snmp.Profiles.Vendors.RouterosTest do # Find the temperature sensor # Mikrotik reports temperature in tenths of degrees (e.g., 450 = 45.0°C) - temp_sensor = Enum.find(sensors, &(&1.sensor_descr == "cpu-temperature")) + temp_sensor = Enum.find(sensors, &(&1.sensor_descr == "System cpu-temperature")) assert temp_sensor assert temp_sensor.sensor_type == "temperature" assert temp_sensor.sensor_unit == "°C" @@ -469,14 +470,14 @@ defmodule Towerops.Snmp.Profiles.Vendors.RouterosTest do sensors = Routeros.discover_wireless_sensors(@client_opts) # Verify both sensors are correctly overridden to voltage with divisor 10 - psu1_sensor = Enum.find(sensors, &(&1.sensor_descr == "psu1-voltage")) + psu1_sensor = Enum.find(sensors, &(&1.sensor_descr == "System psu1-voltage")) assert psu1_sensor assert psu1_sensor.sensor_type == "voltage" assert psu1_sensor.sensor_unit == "V" assert psu1_sensor.sensor_divisor == 10 assert psu1_sensor.last_value == 46.9 - psu2_sensor = Enum.find(sensors, &(&1.sensor_descr == "psu2-voltage")) + psu2_sensor = Enum.find(sensors, &(&1.sensor_descr == "System psu2-voltage")) assert psu2_sensor assert psu2_sensor.sensor_type == "voltage" assert psu2_sensor.sensor_unit == "V" diff --git a/test/towerops_web/controllers/api/v1/devices_controller_test.exs b/test/towerops_web/controllers/api/v1/devices_controller_test.exs index 3cf6a482..ae5a6e5a 100644 --- a/test/towerops_web/controllers/api/v1/devices_controller_test.exs +++ b/test/towerops_web/controllers/api/v1/devices_controller_test.exs @@ -127,6 +127,8 @@ defmodule ToweropsWeb.Api.V1.DevicesControllerTest do end test "creates device with site_id", %{conn: conn, organization: organization} do + # Enable sites for this organization + {:ok, organization} = Towerops.Organizations.update_organization(organization, %{use_sites: true}) {:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: organization.id}) device_params = %{ @@ -160,10 +162,14 @@ defmodule ToweropsWeb.Api.V1.DevicesControllerTest do assert org_id == organization.id end - test "returns 403 when site belongs to different organization", %{conn: conn} do + test "returns 403 when site belongs to different organization", %{conn: conn, organization: organization} do + # Enable sites for the authenticated organization + {:ok, _organization} = Towerops.Organizations.update_organization(organization, %{use_sites: true}) + # Create another organization with a site other_user = user_fixture() other_org = organization_fixture(other_user.id) + {:ok, other_org} = Towerops.Organizations.update_organization(other_org, %{use_sites: true}) {:ok, other_site} = Sites.create_site(%{name: "Other Site", organization_id: other_org.id}) @@ -181,7 +187,10 @@ defmodule ToweropsWeb.Api.V1.DevicesControllerTest do assert %{"error" => "Access denied to this site"} = json_response(conn, 403) end - test "returns 403 when site_id does not exist", %{conn: conn} do + test "returns 403 when site_id does not exist", %{conn: conn, organization: organization} do + # Enable sites for this organization + {:ok, _organization} = Towerops.Organizations.update_organization(organization, %{use_sites: true}) + device_params = %{ "device" => %{ "name" => "Test Router", diff --git a/test/towerops_web/live/device_live_nested/show_test.exs b/test/towerops_web/live/device_live_nested/show_test.exs index 29c40dec..65b1c45d 100644 --- a/test/towerops_web/live/device_live_nested/show_test.exs +++ b/test/towerops_web/live/device_live_nested/show_test.exs @@ -31,14 +31,14 @@ defmodule ToweropsWeb.DeviceLive.ShowTest do describe "Show" do test "displays device information", %{conn: conn, device: device, organization: _org} do - {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}") + {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}?tab=overview") assert html =~ device.name assert html =~ device.ip_address end test "displays overview tab by default", %{conn: conn, device: device, organization: _org} do - {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}") + {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}?tab=overview") assert html =~ "Overview" end @@ -70,7 +70,7 @@ defmodule ToweropsWeb.DeviceLive.ShowTest do checked_at: DateTime.utc_now() }) - {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}") + {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}?tab=overview") assert html =~ "Device Information" end @@ -80,13 +80,13 @@ defmodule ToweropsWeb.DeviceLive.ShowTest do device: device, organization: _org } do - {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}") + {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}?tab=overview") assert html =~ device.name end test "refreshes data periodically", %{conn: conn, device: device, organization: _org} do - {:ok, view, _html} = live(conn, ~p"/devices/#{device.id}") + {:ok, view, _html} = live(conn, ~p"/devices/#{device.id}?tab=overview") # Trigger a status change Monitoring.create_check(%{ @@ -127,7 +127,7 @@ defmodule ToweropsWeb.DeviceLive.ShowTest do device: device, organization: _org } do - {:ok, view, _html} = live(conn, ~p"/devices/#{device.id}") + {:ok, view, _html} = live(conn, ~p"/devices/#{device.id}?tab=overview") # Simulate status change event send(view.pid, {:device_status_changed, device.id, :up, 25}) @@ -152,7 +152,7 @@ defmodule ToweropsWeb.DeviceLive.ShowTest do device: device, organization: _org } do - {:ok, view, _html} = live(conn, ~p"/devices/#{device.id}") + {:ok, view, _html} = live(conn, ~p"/devices/#{device.id}?tab=overview") # Simulate discovery completed event send(view.pid, {:discovery_completed, device.id}) diff --git a/test/towerops_web/live/graph_live/show_test.exs b/test/towerops_web/live/graph_live/show_test.exs index 4e6711b1..778f2e74 100644 --- a/test/towerops_web/live/graph_live/show_test.exs +++ b/test/towerops_web/live/graph_live/show_test.exs @@ -63,7 +63,7 @@ defmodule ToweropsWeb.GraphLive.ShowTest do {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}/graph/latency") # Verify page renders with correct content - assert html =~ "ICMP Latency" + assert html =~ "Ping Latency" assert html =~ device.name assert html =~ "24 Hours" end @@ -446,7 +446,7 @@ defmodule ToweropsWeb.GraphLive.ShowTest do {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}/graph/latency") # Verify page renders with expected content - assert html =~ "ICMP Latency" + assert html =~ "Ping Latency" assert html =~ device.name end @@ -458,7 +458,7 @@ defmodule ToweropsWeb.GraphLive.ShowTest do {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}/graph/latency") # Verify key elements are present - assert html =~ "ICMP Latency" + assert html =~ "Ping Latency" assert html =~ device.name assert html =~ "24 Hours" end