From dc72689aa9d8e84a3890291403db31a58f5a955f Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sat, 9 May 2026 12:49:53 -0500 Subject: [PATCH] test: DataLoaders DB-backed paths for agent_info, snmp_data, neighbor lookups --- .../helpers/data_loaders_db_test.exs | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 test/towerops_web/live/device_live/helpers/data_loaders_db_test.exs diff --git a/test/towerops_web/live/device_live/helpers/data_loaders_db_test.exs b/test/towerops_web/live/device_live/helpers/data_loaders_db_test.exs new file mode 100644 index 00000000..1e9ae060 --- /dev/null +++ b/test/towerops_web/live/device_live/helpers/data_loaders_db_test.exs @@ -0,0 +1,122 @@ +defmodule ToweropsWeb.DeviceLive.Helpers.DataLoadersDbTest do + @moduledoc """ + Database-backed tests for DataLoaders that exercise the agent-token, + SNMP-device, and miscellaneous list_* loaders. + """ + use Towerops.DataCase, async: true + + alias Towerops.AccountsFixtures + alias Towerops.AgentsFixtures + alias Towerops.DevicesFixtures + alias Towerops.Organizations + alias Towerops.Repo + alias Towerops.Snmp.Device, as: SnmpDevice + alias ToweropsWeb.DeviceLive.Helpers.DataLoaders + + setup do + user = AccountsFixtures.user_fixture() + {:ok, organization} = Organizations.create_organization(%{name: "DataLoaders Org"}, user.id) + %{user: user, organization: organization} + end + + describe "load_agent_info/2" do + test "with nil agent + :none source returns cloud polling defaults" do + info = DataLoaders.load_agent_info(nil, :none) + assert info.agent_token_id == nil + assert info.type == :cloud + assert info.is_offline == false + assert info.name == "Cloud Polling" + end + + test "with valid token id returns the token's attributes", + %{organization: organization} do + {:ok, token, _raw} = AgentsFixtures.agent_token_fixture(organization.id, "Tower Edge") + + info = DataLoaders.load_agent_info(token.id, :site) + + assert info.agent_token_id == token.id + assert info.name == "Tower Edge" + assert info.source == :site + # never seen, so offline + assert info.is_offline == true + end + + test "with deleted token id falls back to cloud polling sentinel" do + info = DataLoaders.load_agent_info(Ecto.UUID.generate(), :organization) + assert info.agent_token_id == nil + assert info.name =~ "Cloud Polling" + assert info.is_offline == false + end + end + + describe "load_snmp_data/1" do + test "returns empty shape for unknown device" do + data = DataLoaders.load_snmp_data(Ecto.UUID.generate()) + assert data.device == nil + assert data.interfaces == [] + assert data.sensors == [] + end + + test "returns enriched device when SNMP device exists", + %{organization: organization} do + device = + DevicesFixtures.device_fixture(%{ + organization_id: organization.id, + name: "DL Router", + ip_address: "10.20.0.1" + }) + + {:ok, _snmp} = + %SnmpDevice{} + |> SnmpDevice.changeset(%{ + device_id: device.id, + sys_name: "snmp-host", + sys_descr: "Test", + sys_object_id: "1.3.6.1.4.1.9" + }) + |> Repo.insert() + + data = DataLoaders.load_snmp_data(device.id) + assert data.device.sys_name == "snmp-host" + assert is_list(data.interfaces) + assert is_list(data.sensors) + end + end + + describe "load_vlans / load_ip_addresses / load_processors / load_storage" do + test "all return empty list for nil snmp_device" do + assert DataLoaders.load_vlans(nil) == [] + assert DataLoaders.load_ip_addresses(nil) == [] + assert DataLoaders.load_processors(nil) == [] + assert DataLoaders.load_storage(nil) == [] + end + end + + describe "load_neighbors / load_arp_entries / load_mac_addresses" do + test "return empty lists for a device with no SNMP discovery data", + %{organization: organization} do + device = + DevicesFixtures.device_fixture(%{ + organization_id: organization.id, + name: "EmptyNeighbors" + }) + + assert DataLoaders.load_neighbors(device.id) == [] + assert DataLoaders.load_arp_entries(device.id) == [] + assert DataLoaders.load_mac_addresses(device.id) == [] + end + end + + describe "load_recent_config_changes/1" do + test "returns empty list when no config changes", + %{organization: organization} do + device = + DevicesFixtures.device_fixture(%{ + organization_id: organization.id, + name: "NoChanges" + }) + + assert DataLoaders.load_recent_config_changes(device) == [] + end + end +end