diff --git a/lib/towerops/devices/device.ex b/lib/towerops/devices/device.ex
index 15ae5f28..2b14542d 100644
--- a/lib/towerops/devices/device.ex
+++ b/lib/towerops/devices/device.ex
@@ -51,7 +51,7 @@ defmodule Towerops.Devices.Device do
field :snmpv3_credential_source, :string, default: "site"
# MikroTik API credentials (device-level overrides)
- field :mikrotik_username, Binary
+ field :mikrotik_username, :string
field :mikrotik_password, Binary
field :mikrotik_port, :integer
field :mikrotik_ssh_port, :integer
diff --git a/lib/towerops/organizations.ex b/lib/towerops/organizations.ex
index 0a1f68cf..e663a6be 100644
--- a/lib/towerops/organizations.ex
+++ b/lib/towerops/organizations.ex
@@ -13,6 +13,7 @@ defmodule Towerops.Organizations do
alias Towerops.Organizations.Policy
alias Towerops.Organizations.SubscriptionLimits
alias Towerops.Repo
+ alias Towerops.Sites.Site
## Organizations
@@ -102,11 +103,24 @@ defmodule Towerops.Organizations do
role: :owner
})
end)
+ |> Ecto.Multi.run(:set_default, fn _repo, %{organization: organization} ->
+ # Set this as the user's default organization if they don't have one
+ user = Towerops.Accounts.get_user!(user_id)
+
+ if user.default_organization_id == nil do
+ user
+ |> Ecto.Changeset.change(default_organization_id: organization.id)
+ |> Repo.update()
+ else
+ {:ok, user}
+ end
+ end)
case Repo.transaction(multi) do
{:ok, %{organization: organization}} -> {:ok, organization}
{:error, :organization, changeset, _} -> {:error, changeset}
{:error, :membership, changeset, _} -> {:error, changeset}
+ {:error, :set_default, changeset, _} -> {:error, changeset}
end
end
@@ -415,6 +429,7 @@ defmodule Towerops.Organizations do
Returns the number of device records updated.
"""
def clear_all_site_assignments(organization_id) do
+ # Clear site assignments from all devices
Repo.update_all(
from(d in Device, where: d.organization_id == ^organization_id),
set: [
@@ -422,6 +437,9 @@ defmodule Towerops.Organizations do
updated_at: DateTime.truncate(DateTime.utc_now(), :second)
]
)
+
+ # Delete all sites for the organization
+ Repo.delete_all(from(s in Site, where: s.organization_id == ^organization_id))
end
## Authorization
diff --git a/lib/towerops/organizations/organization.ex b/lib/towerops/organizations/organization.ex
index ab01b139..3dd25342 100644
--- a/lib/towerops/organizations/organization.ex
+++ b/lib/towerops/organizations/organization.ex
@@ -41,7 +41,7 @@ defmodule Towerops.Organizations.Organization do
field :snmpv3_priv_password, Binary
# MikroTik API credentials (organization-level defaults cascade to site → device)
- field :mikrotik_username, Binary
+ field :mikrotik_username, :string
field :mikrotik_password, Binary
field :mikrotik_port, :integer, default: 8729
field :mikrotik_ssh_port, :integer, default: 22
diff --git a/lib/towerops/sites/site.ex b/lib/towerops/sites/site.ex
index d973c50f..e97c71c2 100644
--- a/lib/towerops/sites/site.ex
+++ b/lib/towerops/sites/site.ex
@@ -37,7 +37,7 @@ defmodule Towerops.Sites.Site do
field :snmpv3_priv_password, Binary
# MikroTik API credentials (overrides organization default)
- field :mikrotik_username, Binary
+ field :mikrotik_username, :string
field :mikrotik_password, Binary
field :mikrotik_port, :integer
field :mikrotik_ssh_port, :integer
diff --git a/lib/towerops_web/controllers/api/account_data_controller.ex b/lib/towerops_web/controllers/api/account_data_controller.ex
index 4fa2431b..6e9eaa90 100644
--- a/lib/towerops_web/controllers/api/account_data_controller.ex
+++ b/lib/towerops_web/controllers/api/account_data_controller.ex
@@ -98,8 +98,8 @@ defmodule ToweropsWeb.Api.AccountDataController do
snmp_enabled: device.snmp_enabled,
status: device.status,
organization: %{
- id: device.site.organization_id,
- name: device.site.organization.name
+ id: device.organization_id,
+ name: device.organization.name
},
site: %{
id: device.site_id,
diff --git a/lib/towerops_web/controllers/api/v1/devices_controller.ex b/lib/towerops_web/controllers/api/v1/devices_controller.ex
index dd85a1dc..76938727 100644
--- a/lib/towerops_web/controllers/api/v1/devices_controller.ex
+++ b/lib/towerops_web/controllers/api/v1/devices_controller.ex
@@ -47,20 +47,28 @@ defmodule ToweropsWeb.Api.V1.DevicesController do
@doc """
POST /api/v1/devices
- Creates a new device.
+ Creates a new device. The device can be assigned to a site or directly to the organization.
Request body:
{
"device": {
- "site_id": "uuid",
+ "site_id": "uuid", # optional - if not provided, device is assigned directly to organization
+ "organization_id": "uuid", # optional - defaults to authenticated organization if not provided
"name": "Core Router",
"ip_address": "192.168.1.1",
"description": "Main router", # optional
"monitoring_enabled": true, # optional, default true
"snmp_enabled": true, # optional, default true
- "snmp_version": "2c", # optional, default "2c"
+ "snmp_version": "2c", # optional, default "2c" (can be "1", "2c", or "3")
"snmp_community": "public", # optional, inherits from site/org if not set
- "snmp_port": 161 # optional, default 161
+ "snmp_port": 161, # optional, default 161
+ # SNMPv3 fields (only used when snmp_version is "3"):
+ "snmpv3_security_level": "authPriv", # optional, one of: noAuthNoPriv, authNoPriv, authPriv
+ "snmpv3_username": "snmpuser", # optional
+ "snmpv3_auth_protocol": "SHA-256", # optional, one of: MD5, SHA, SHA-224, SHA-256, SHA-384, SHA-512
+ "snmpv3_auth_password": "authpass", # optional
+ "snmpv3_priv_protocol": "AES", # optional, one of: DES, AES, AES-192, AES-256
+ "snmpv3_priv_password": "privpass" # optional
}
}
@@ -70,6 +78,7 @@ defmodule ToweropsWeb.Api.V1.DevicesController do
"name": "Core Router",
"ip_address": "192.168.1.1",
"site_id": "uuid",
+ "organization_id": "uuid",
"monitoring_enabled": true,
"snmp_enabled": true,
"inserted_at": "2026-01-15T19:44:25Z"
@@ -79,6 +88,14 @@ defmodule ToweropsWeb.Api.V1.DevicesController do
organization_id = conn.assigns.current_organization_id
current_user = conn.assigns[:current_user]
+ # Add organization_id to params if not provided
+ device_params =
+ if Map.has_key?(device_params, "organization_id") do
+ device_params
+ else
+ Map.put(device_params, "organization_id", organization_id)
+ end
+
# Verify site belongs to organization if site_id is provided
case verify_site_access(device_params["site_id"], organization_id) do
:ok ->
@@ -248,7 +265,7 @@ defmodule ToweropsWeb.Api.V1.DevicesController do
# Private helpers
- defp verify_site_access(nil, _organization_id), do: {:error, "site_id is required"}
+ defp verify_site_access(nil, _organization_id), do: :ok
defp verify_site_access(site_id, organization_id) do
site = Towerops.Sites.get_site!(site_id)
@@ -269,6 +286,7 @@ defmodule ToweropsWeb.Api.V1.DevicesController do
name: device.name,
ip_address: device.ip_address,
site_id: device.site_id,
+ organization_id: device.organization_id,
monitoring_enabled: device.monitoring_enabled,
snmp_enabled: device.snmp_enabled,
inserted_at: device.inserted_at
@@ -281,6 +299,7 @@ defmodule ToweropsWeb.Api.V1.DevicesController do
name: device.name,
ip_address: device.ip_address,
site_id: device.site_id,
+ organization_id: device.organization_id,
description: device.description,
monitoring_enabled: device.monitoring_enabled,
check_interval_seconds: device.check_interval_seconds,
diff --git a/lib/towerops_web/live/dashboard_live.ex b/lib/towerops_web/live/dashboard_live.ex
index c9351f71..4c071edb 100644
--- a/lib/towerops_web/live/dashboard_live.ex
+++ b/lib/towerops_web/live/dashboard_live.ex
@@ -34,8 +34,9 @@ defmodule ToweropsWeb.DashboardLive do
end
defp load_dashboard_data(socket, organization_id) do
+ organization = socket.assigns.current_scope.organization
active_alerts = Alerts.list_organization_active_alerts(organization_id)
- sites_count = length(Sites.list_organization_sites(organization_id))
+ sites_count = if organization.use_sites, do: length(Sites.list_organization_sites(organization_id)), else: 0
devices = Devices.list_organization_devices(organization_id)
devices_by_status =
diff --git a/lib/towerops_web/live/dashboard_live.html.heex b/lib/towerops_web/live/dashboard_live.html.heex
index c021d608..d4f21380 100644
--- a/lib/towerops_web/live/dashboard_live.html.heex
+++ b/lib/towerops_web/live/dashboard_live.html.heex
@@ -8,7 +8,7 @@
<:subtitle>Welcome to {@current_scope.organization.name}
- <%= if @sites_count == 0 do %>
+ <%= if @device_count == 0 do %>
<.icon
name="hero-light-bulb"
@@ -22,31 +22,45 @@
-
-
- 1
+ <%= if @current_scope.organization.use_sites do %>
+
+
+ 1
+
+
+
Create a Site
+
+ Sites represent your physical locations (offices, data centers, towers, etc.)
+
+
-
-
Create a Site
-
- Sites represent your physical locations (offices, data centers, towers, etc.)
-
+
+
+ 2
+
+
+
Add Devices
+
+ Add network devices (routers, switches, servers) to your sites
+
+
-
+ <% else %>
+
+
+ 1
+
+
+
Add Devices
+
+ Add network devices (routers, switches, servers) to monitor
+
+
+
+ <% end %>
- 2
-
-
-
Add Device
-
- Add network devices (routers, switches, servers) to your sites
-
-
-
-
-
- 3
+ {if @current_scope.organization.use_sites, do: "3", else: "2"}
@@ -60,21 +74,33 @@
- <.button navigate={~p"/sites/new"} variant="primary">
- <.icon name="hero-plus" class="h-5 w-5" /> Create Your First Site
-
+ <%= if @current_scope.organization.use_sites do %>
+ <.button navigate={~p"/sites/new"} variant="primary">
+ <.icon name="hero-plus" class="h-5 w-5" /> Create Your First Site
+
+ <% else %>
+ <.button navigate={~p"/devices/new"} variant="primary">
+ <.icon name="hero-plus" class="h-5 w-5" /> Add Your First Device
+
+ <% end %>
<% else %>
-
- <.link
- navigate={~p"/sites"}
- class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-white/10 dark:bg-gray-800/50"
- >
-
Sites
-
{@sites_count}
-
Total sites
-
+
+ <%= if @current_scope.organization.use_sites do %>
+ <.link
+ navigate={~p"/sites"}
+ class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-white/10 dark:bg-gray-800/50"
+ >
+
Sites
+
{@sites_count}
+
Total sites
+
+ <% end %>
<.link
navigate={~p"/devices"}
diff --git a/lib/towerops_web/live/device_live/form.ex b/lib/towerops_web/live/device_live/form.ex
index 5838a888..d74b3d45 100644
--- a/lib/towerops_web/live/device_live/form.ex
+++ b/lib/towerops_web/live/device_live/form.ex
@@ -153,7 +153,7 @@ defmodule ToweropsWeb.DeviceLive.Form do
mikrotik_config = Devices.get_mikrotik_config(device)
# Check if device is MikroTik (based on SNMP discovery)
- device_with_snmp = Towerops.Repo.preload(device, :snmp_device)
+ device_with_snmp = Towerops.Repo.preload(device, :snmp_device, force: true)
is_mikrotik = mikrotik_device?(device_with_snmp)
# Determine monitoring mode based on current snmp_enabled value
diff --git a/lib/towerops_web/live/device_live/form.html.heex b/lib/towerops_web/live/device_live/form.html.heex
index 2606d967..33e08239 100644
--- a/lib/towerops_web/live/device_live/form.html.heex
+++ b/lib/towerops_web/live/device_live/form.html.heex
@@ -588,9 +588,9 @@
-
-
- <%= if @live_action == :edit and @is_mikrotik_device and @current_scope.user.is_superuser do %>
+
+ <%= if @live_action == :edit and @is_mikrotik_device do %>
+
- Configure MikroTik RouterOS API access. Works alongside SNMP for enhanced device management.
+ Configure MikroTik RouterOS API access. Works alongside SNMP for enhanced device management. SSH is used for device backups.
+
+
+ <.icon name="hero-beaker" class="h-4 w-4 inline" />
+ Experimental Feature:
+ MikroTik API integration is under active development.
+
+
@@ -671,15 +678,6 @@
- <% else %>
-
-
-
- ⚠️ Security Warning:
- Plain API (port 8728) sends credentials unencrypted. Use SSL (port 8729) whenever possible.
-
-
-
<% end %>
<% end %>
diff --git a/lib/towerops_web/live/org/settings_live.html.heex b/lib/towerops_web/live/org/settings_live.html.heex
index 8b7e60c4..8e88dca6 100644
--- a/lib/towerops_web/live/org/settings_live.html.heex
+++ b/lib/towerops_web/live/org/settings_live.html.heex
@@ -239,6 +239,13 @@
Set default MikroTik RouterOS API credentials for all devices in this organization. Only applies to devices detected as MikroTik.
+
+
+ <.icon name="hero-beaker" class="h-4 w-4 inline" />
+ Experimental Feature:
+ MikroTik API integration is under active development.
+
+
<.icon name="hero-information-circle" class="h-4 w-4 inline" />
Hierarchy: Device > Site > Organization
diff --git a/lib/towerops_web/live/site_live/form.html.heex b/lib/towerops_web/live/site_live/form.html.heex
index 675a89ab..21f6ccdc 100644
--- a/lib/towerops_web/live/site_live/form.html.heex
+++ b/lib/towerops_web/live/site_live/form.html.heex
@@ -270,6 +270,13 @@
Override organization MikroTik API defaults for all devices at this site. Leave blank to inherit from organization. Only applies to MikroTik devices.
+
+
+ <.icon name="hero-beaker" class="h-4 w-4 inline" />
+ Experimental Feature:
+ MikroTik API integration is under active development.
+
+
<.input
field={@form[:mikrotik_enabled]}
diff --git a/priv/repo/migrations/20260204193548_revert_mikrotik_username_encryption.exs b/priv/repo/migrations/20260204193548_revert_mikrotik_username_encryption.exs
new file mode 100644
index 00000000..2f2e6c12
--- /dev/null
+++ b/priv/repo/migrations/20260204193548_revert_mikrotik_username_encryption.exs
@@ -0,0 +1,32 @@
+defmodule Towerops.Repo.Migrations.RevertMikrotikUsernameEncryption do
+ use Ecto.Migration
+
+ def up do
+ # Revert mikrotik_username from encrypted binary to plaintext string
+ # Usernames are not sensitive enough to require encryption (passwords still encrypted)
+ # This fixes form display issues with encrypted binary fields
+
+ # Organizations
+ execute "ALTER TABLE organizations ALTER COLUMN mikrotik_username TYPE varchar USING NULL"
+
+ # Sites
+ execute "ALTER TABLE sites ALTER COLUMN mikrotik_username TYPE varchar USING NULL"
+
+ # Devices
+ execute "ALTER TABLE devices ALTER COLUMN mikrotik_username TYPE varchar USING NULL"
+ end
+
+ def down do
+ # Change back to binary for encryption
+ # Note: This will clear any existing usernames
+
+ # Organizations
+ execute "ALTER TABLE organizations ALTER COLUMN mikrotik_username TYPE bytea USING NULL"
+
+ # Sites
+ execute "ALTER TABLE sites ALTER COLUMN mikrotik_username TYPE bytea USING NULL"
+
+ # Devices
+ execute "ALTER TABLE devices ALTER COLUMN mikrotik_username TYPE bytea USING NULL"
+ end
+end
diff --git a/priv/static/changelog.txt b/priv/static/changelog.txt
index 45431fa7..c2a864f2 100644
--- a/priv/static/changelog.txt
+++ b/priv/static/changelog.txt
@@ -5,6 +5,7 @@ Devices Tested & Working
2026-02-04
* Feature: SNMP v3 support
+* Sites are now optional and not enabled by default
2026-02-03
* More tests
diff --git a/test/integration/snmp_integration_test.exs b/test/integration/snmp_integration_test.exs
index 6d091750..46cca668 100644
--- a/test/integration/snmp_integration_test.exs
+++ b/test/integration/snmp_integration_test.exs
@@ -122,6 +122,7 @@ defmodule Towerops.Integration.SnmpIntegrationTest do
name: "SNMP Router",
ip_address: "192.0.2.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
diff --git a/test/support/fixtures/agents_fixtures_test.exs b/test/support/fixtures/agents_fixtures_test.exs
index 3cce890d..018dc093 100644
--- a/test/support/fixtures/agents_fixtures_test.exs
+++ b/test/support/fixtures/agents_fixtures_test.exs
@@ -52,7 +52,8 @@ defmodule Towerops.AgentsFixturesTest do
Towerops.Devices.create_device(%{
name: "Test Equipment",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, agent_token, _token_string} = agent_token_fixture(organization.id)
diff --git a/test/support/fixtures/devices_fixtures.ex b/test/support/fixtures/devices_fixtures.ex
index 1134fa26..f9293e34 100644
--- a/test/support/fixtures/devices_fixtures.ex
+++ b/test/support/fixtures/devices_fixtures.ex
@@ -11,12 +11,10 @@ defmodule Towerops.DevicesFixtures do
def device_fixture(attrs \\ %{}) do
# Ensure organization and site exist
organization =
- attrs[:organization] || Map.get(attrs, "organization") ||
- Towerops.OrganizationsFixtures.organization_fixture()
+ attrs[:organization] || Map.get(attrs, "organization") || create_organization()
site =
- attrs[:site] || Map.get(attrs, "site") ||
- Towerops.OrganizationsFixtures.site_fixture(%{organization_id: organization.id})
+ attrs[:site] || Map.get(attrs, "site") || create_site(organization)
# Default device attributes
default_attrs = %{
@@ -43,4 +41,15 @@ defmodule Towerops.DevicesFixtures do
defp to_atom_key(key) when is_atom(key), do: key
defp to_atom_key(key) when is_binary(key), do: String.to_existing_atom(key)
+
+ defp create_organization do
+ user = Towerops.AccountsFixtures.user_fixture()
+ {:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
+ organization
+ end
+
+ defp create_site(organization) do
+ {:ok, site} = Towerops.Sites.create_site(%{name: "Test Site", organization_id: organization.id})
+ site
+ end
end
diff --git a/test/towerops/agents/stats_test.exs b/test/towerops/agents/stats_test.exs
index e6482834..85e07f95 100644
--- a/test/towerops/agents/stats_test.exs
+++ b/test/towerops/agents/stats_test.exs
@@ -81,6 +81,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Test Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -122,6 +123,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router 1",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -135,6 +137,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router 2",
ip_address: "192.168.1.2",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -219,6 +222,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router #{i}",
ip_address: "192.168.1.#{i}",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -249,6 +253,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router #{i}",
ip_address: "192.168.1.#{i}",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -279,6 +284,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c",
@@ -302,6 +308,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Unmonitored Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c",
@@ -328,6 +335,7 @@ defmodule Towerops.Agents.StatsTest do
name: "SNMP Disabled",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: false,
monitoring_enabled: true
})
@@ -347,6 +355,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Monitoring Disabled",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c",
@@ -385,6 +394,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -466,6 +476,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -488,6 +499,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -551,6 +563,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -598,6 +611,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -642,6 +656,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -701,6 +716,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -752,6 +768,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -777,6 +794,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -818,6 +836,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -867,6 +886,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -918,6 +938,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -968,6 +989,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -1011,6 +1033,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Non-SNMP Device",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: false
})
@@ -1042,6 +1065,7 @@ defmodule Towerops.Agents.StatsTest do
name: "Unassigned Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
diff --git a/test/towerops/agents_test.exs b/test/towerops/agents_test.exs
index 2f6b8bd6..5844750e 100644
--- a/test/towerops/agents_test.exs
+++ b/test/towerops/agents_test.exs
@@ -126,7 +126,7 @@ defmodule Towerops.AgentsTest do
%{site: site, agent_token: agent_token}
end
- test "deletes agent token from database", %{agent_token: agent_token} do
+ test "deletes agent token from database", %{agent_token: agent_token, organization: _organization} do
assert {:ok, _} = Agents.delete_agent_token(agent_token.id)
assert_raise Ecto.NoResultsError, fn ->
@@ -136,20 +136,23 @@ defmodule Towerops.AgentsTest do
test "removes all direct device assignments", %{
site: site,
- agent_token: agent_token
+ agent_token: agent_token,
+ organization: organization
} do
{:ok, device1} =
Towerops.Devices.create_device(%{
name: "Device 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, device2} =
Towerops.Devices.create_device(%{
name: "Device 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
# Assign both devices to the agent
@@ -181,7 +184,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Device",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
# Directly assign device to agent_to_delete (overriding site default)
@@ -215,7 +219,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Device",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
# Directly assign device to agent_to_delete (overriding org default)
@@ -234,6 +239,7 @@ defmodule Towerops.AgentsTest do
end
test "devices have no agent when no fallback exists (cloud polling)", %{
+ organization: organization,
site: site,
agent_token: agent_token
} do
@@ -241,7 +247,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Device",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
# Directly assign device to agent (no site or org defaults)
@@ -277,7 +284,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Device",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
# Device should use site agent
@@ -309,7 +317,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Device",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
# Device should use org default
@@ -356,7 +365,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Test Equipment",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
%{site: site, device: device}
@@ -399,7 +409,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Test Equipment",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
{:ok, agent_token, _token} = Agents.create_agent_token(org.id, "Test Agent")
@@ -407,7 +418,7 @@ defmodule Towerops.AgentsTest do
%{site: site, device: device, agent_token: agent_token}
end
- test "removes equipment assignment", %{agent_token: agent_token, device: device} do
+ test "removes equipment assignment", %{agent_token: agent_token, device: device, organization: _organization} do
{:ok, _assignment} = Agents.assign_device_to_agent(agent_token.id, device.id)
{1, _} = Agents.unassign_device(device.id)
@@ -465,7 +476,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Test Equipment",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
{:ok, agent_token, _token} = Agents.create_agent_token(org.id, "Test Agent")
@@ -483,7 +495,7 @@ defmodule Towerops.AgentsTest do
assert retrieved_assignment.id == assignment.id
end
- test "returns nil when equipment is not assigned", %{device: device} do
+ test "returns nil when equipment is not assigned", %{device: device, organization: _organization} do
assert Agents.get_device_assignment(device.id) == nil
end
end
@@ -500,7 +512,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Test Equipment",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
{:ok, agent_token1, _} = Agents.create_agent_token(org.id, "Agent 1")
@@ -562,21 +575,24 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Test Equipment 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
{:ok, device2} =
Towerops.Devices.create_device(%{
name: "Test Equipment 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
{:ok, device3} =
Towerops.Devices.create_device(%{
name: "Test Equipment 3",
ip_address: "192.168.1.3",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
%{site: site, device1: device1, device2: device2, device3: device3}
@@ -621,7 +637,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Test Equipment",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
%{
@@ -686,7 +703,7 @@ defmodule Towerops.AgentsTest do
assert Agents.get_effective_agent_token(device) == agent1.id
end
- test "returns nil when no agent assigned at any level", %{device: device} do
+ test "returns nil when no agent assigned at any level", %{device: device, organization: _organization} do
# No assignments at any level
device = Repo.preload(device, site: [organization: :default_agent_token])
@@ -714,7 +731,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Test Equipment 2",
ip_address: "192.168.2.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
device = Repo.preload(device, site: [organization: :default_agent_token])
@@ -764,7 +782,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Test Equipment",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
%{
@@ -814,7 +833,7 @@ defmodule Towerops.AgentsTest do
assert agent_id == agent1.id
end
- test "returns none source when no assignment", %{device: device} do
+ test "returns none source when no assignment", %{device: device, organization: _organization} do
device = Repo.preload(device, site: [organization: :default_agent_token])
assert {nil, :none} = Agents.get_effective_agent_token_with_source(device)
@@ -839,7 +858,8 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Test Equipment 3",
ip_address: "192.168.3.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
device = Repo.preload(device, site: [organization: :default_agent_token])
@@ -864,21 +884,24 @@ defmodule Towerops.AgentsTest do
Towerops.Devices.create_device(%{
name: "Test Equipment 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
{:ok, device2} =
Towerops.Devices.create_device(%{
name: "Test Equipment 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
{:ok, device3} =
Towerops.Devices.create_device(%{
name: "Test Equipment 3",
ip_address: "192.168.1.3",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
%{site: site, device1: device1, device2: device2, device3: device3}
@@ -948,6 +971,7 @@ defmodule Towerops.AgentsTest do
end
test "returns device with direct agent assignment", %{
+ organization: organization,
agent1: agent1,
agent2: agent2,
site1: site1
@@ -957,6 +981,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -967,6 +992,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 2",
ip_address: "192.168.1.2",
site_id: site1.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -988,6 +1014,7 @@ defmodule Towerops.AgentsTest do
end
test "returns device inheriting from site agent", %{
+ organization: organization,
agent1: agent1,
agent2: agent2,
site1: site1
@@ -1000,6 +1027,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1010,6 +1038,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 2",
ip_address: "192.168.1.2",
site_id: site1.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1041,6 +1070,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1051,6 +1081,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 2",
ip_address: "192.168.1.2",
site_id: site1.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1085,6 +1116,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1120,6 +1152,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1135,6 +1168,7 @@ defmodule Towerops.AgentsTest do
end
test "only returns SNMP-enabled devices", %{
+ organization: organization,
agent1: agent1,
site1: site1
} do
@@ -1144,6 +1178,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1155,6 +1190,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 2",
ip_address: "192.168.1.2",
site_id: site1.id,
+ organization_id: organization.id,
snmp_enabled: false
})
@@ -1189,6 +1225,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1200,6 +1237,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 2",
ip_address: "192.168.1.2",
site_id: site2.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1217,6 +1255,7 @@ defmodule Towerops.AgentsTest do
end
test "preloads necessary associations for API response", %{
+ organization: organization,
agent1: agent1,
site1: site1
} do
@@ -1225,6 +1264,7 @@ defmodule Towerops.AgentsTest do
name: "Equipment 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1345,6 +1385,8 @@ defmodule Towerops.AgentsTest do
end
test "cloud poller can be assigned to devices across organizations", %{
+ org1: org1,
+ org2: org2,
site1: site1,
site2: site2,
cloud_poller: cloud_poller
@@ -1355,6 +1397,7 @@ defmodule Towerops.AgentsTest do
name: "Device 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: org1.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1365,6 +1408,7 @@ defmodule Towerops.AgentsTest do
name: "Device 2",
ip_address: "192.168.2.1",
site_id: site2.id,
+ organization_id: org2.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1405,6 +1449,7 @@ defmodule Towerops.AgentsTest do
name: "Device 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: org1.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1415,6 +1460,7 @@ defmodule Towerops.AgentsTest do
name: "Device 2",
ip_address: "192.168.2.1",
site_id: site2.id,
+ organization_id: org2.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1428,6 +1474,8 @@ defmodule Towerops.AgentsTest do
end
test "cloud poller can be site default for sites in different orgs", %{
+ org1: org1,
+ org2: org2,
site1: site1,
site2: site2,
cloud_poller: cloud_poller
@@ -1442,6 +1490,7 @@ defmodule Towerops.AgentsTest do
name: "Device 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: org1.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
@@ -1452,6 +1501,7 @@ defmodule Towerops.AgentsTest do
name: "Device 2",
ip_address: "192.168.2.1",
site_id: site2.id,
+ organization_id: org2.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public"
diff --git a/test/towerops/alerts_test.exs b/test/towerops/alerts_test.exs
index 4498e3cd..5c5aa5b0 100644
--- a/test/towerops/alerts_test.exs
+++ b/test/towerops/alerts_test.exs
@@ -22,7 +22,8 @@ defmodule Towerops.AlertsTest do
Towerops.Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
%{device: device, organization: organization, user: user}
@@ -395,14 +396,16 @@ defmodule Towerops.AlertsTest do
Towerops.Devices.create_device(%{
name: "Device 1",
ip_address: "192.168.1.1",
- site_id: site1.id
+ site_id: site1.id,
+ organization_id: org1.id
})
{:ok, device2} =
Towerops.Devices.create_device(%{
name: "Device 2",
ip_address: "192.168.1.2",
- site_id: site2.id
+ site_id: site2.id,
+ organization_id: org2.id
})
%{org1: org1, org2: org2, device1: device1, device2: device2}
diff --git a/test/towerops/devices/backup_requests_test.exs b/test/towerops/devices/backup_requests_test.exs
index f37d0bc2..55d940da 100644
--- a/test/towerops/devices/backup_requests_test.exs
+++ b/test/towerops/devices/backup_requests_test.exs
@@ -216,6 +216,7 @@ defmodule Towerops.Devices.BackupRequestsTest do
name: "Test Device",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
},
diff --git a/test/towerops/devices/device_firmware_history_test.exs b/test/towerops/devices/device_firmware_history_test.exs
index 142f378c..e76eeccf 100644
--- a/test/towerops/devices/device_firmware_history_test.exs
+++ b/test/towerops/devices/device_firmware_history_test.exs
@@ -232,6 +232,7 @@ defmodule Towerops.Devices.DeviceFirmwareHistoryTest do
name: "Test Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
diff --git a/test/towerops/devices/mikrotik_backups_test.exs b/test/towerops/devices/mikrotik_backups_test.exs
index a74cb641..53b9105a 100644
--- a/test/towerops/devices/mikrotik_backups_test.exs
+++ b/test/towerops/devices/mikrotik_backups_test.exs
@@ -325,6 +325,7 @@ defmodule Towerops.Devices.MikrotikBackupsTest do
name: "Test Device",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
},
diff --git a/test/towerops/devices_test.exs b/test/towerops/devices_test.exs
index 7f773349..83bc56c9 100644
--- a/test/towerops/devices_test.exs
+++ b/test/towerops/devices_test.exs
@@ -38,8 +38,10 @@ defmodule Towerops.EquipmentTest do
}
@invalid_attrs %{name: nil, ip_address: nil}
- test "list_site_devices/1 returns all devices for a site", %{site: site} do
- {:ok, device} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ test "list_site_devices/1 returns all devices for a site", %{organization: organization, site: site} do
+ {:ok, device} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
+
assert Devices.list_site_devices(site.id) == [device]
end
@@ -47,22 +49,27 @@ defmodule Towerops.EquipmentTest do
organization: organization,
site: site
} do
- {:ok, device} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ {:ok, device} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
+
result = Devices.list_organization_devices(organization.id)
assert length(result) == 1
assert hd(result).id == device.id
end
test "list_monitored_devices/0 returns only device with monitoring enabled", %{
+ organization: organization,
site: site
} do
- {:ok, monitored} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ {:ok, monitored} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
{:ok, _not_monitored} =
Devices.create_device(%{
name: "Not Monitored",
ip_address: "192.168.1.3",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: false
})
@@ -71,19 +78,22 @@ defmodule Towerops.EquipmentTest do
assert hd(result).id == monitored.id
end
- test "get_device!/1 returns the device with given id", %{site: site} do
- {:ok, device} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ test "get_device!/1 returns the device with given id", %{organization: organization, site: site} do
+ {:ok, device} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
+
assert Devices.get_device!(device.id).id == device.id
end
- test "get_site_equipment!/2 returns device for specific site", %{site: site} do
- {:ok, device} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ test "get_site_equipment!/2 returns device for specific site", %{organization: organization, site: site} do
+ {:ok, device} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
assert Devices.get_site_device!(site.id, device.id).id == device.id
end
- test "create_device/1 with valid data creates device", %{site: site} do
- attrs = Map.put(@valid_attrs, :site_id, site.id)
+ test "create_device/1 with valid data creates device", %{organization: organization, site: site} do
+ attrs = Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id})
assert {:ok, %DeviceSchema{} = device} = Devices.create_device(attrs)
assert device.name == "Router 1"
assert device.ip_address == "192.168.1.1"
@@ -92,15 +102,15 @@ defmodule Towerops.EquipmentTest do
assert device.check_interval_seconds == 300
end
- test "create_device/1 with valid IPv6 address", %{site: site} do
+ test "create_device/1 with valid IPv6 address", %{organization: organization, site: site} do
attrs = Map.put(@valid_attrs, :ip_address, "2001:0db8:85a3::8a2e:0370:7334")
- attrs = Map.put(attrs, :site_id, site.id)
+ attrs = Map.merge(attrs, %{site_id: site.id, organization_id: organization.id})
assert {:ok, %DeviceSchema{}} = Devices.create_device(attrs)
end
- test "create_device/1 with invalid IP address returns error", %{site: site} do
+ test "create_device/1 with invalid IP address returns error", %{organization: organization, site: site} do
attrs = Map.put(@valid_attrs, :ip_address, "invalid-ip")
- attrs = Map.put(attrs, :site_id, site.id)
+ attrs = Map.merge(attrs, %{site_id: site.id, organization_id: organization.id})
assert {:error, changeset} = Devices.create_device(attrs)
assert "must be a valid IPv4 or IPv6 address" in errors_on(changeset).ip_address
end
@@ -109,8 +119,9 @@ defmodule Towerops.EquipmentTest do
assert {:error, %Ecto.Changeset{}} = Devices.create_device(@invalid_attrs)
end
- test "update_device/2 with valid data updates the device", %{site: site} do
- {:ok, device} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ test "update_device/2 with valid data updates the device", %{organization: organization, site: site} do
+ {:ok, device} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
assert {:ok, %DeviceSchema{} = device} =
Devices.update_device(device, @update_attrs)
@@ -120,8 +131,9 @@ defmodule Towerops.EquipmentTest do
assert device.monitoring_enabled == false
end
- test "update_device/2 with invalid data returns error changeset", %{site: site} do
- {:ok, device} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ test "update_device/2 with invalid data returns error changeset", %{organization: organization, site: site} do
+ {:ok, device} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
assert {:error, %Ecto.Changeset{}} =
Devices.update_device(device, @invalid_attrs)
@@ -129,13 +141,16 @@ defmodule Towerops.EquipmentTest do
assert Devices.get_device!(device.id).name == device.name
end
- test "change_device/1 returns an device changeset", %{site: site} do
- {:ok, device} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ test "change_device/1 returns an device changeset", %{organization: organization, site: site} do
+ {:ok, device} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
+
assert %Ecto.Changeset{} = Devices.change_device(device)
end
- test "update_device_status/2 updates status and timestamps", %{site: site} do
- {:ok, device} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ test "update_device_status/2 updates status and timestamps", %{organization: organization, site: site} do
+ {:ok, device} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
assert {:ok, updated} = Devices.update_device_status(device, :up)
assert updated.status == :up
@@ -144,9 +159,12 @@ defmodule Towerops.EquipmentTest do
end
test "update_device_status/2 only updates last_checked_at if status unchanged", %{
+ organization: organization,
site: site
} do
- {:ok, device} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ {:ok, device} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
+
{:ok, device} = Devices.update_device_status(device, :up)
# Manually set timestamps to 1 hour ago to avoid sleeping
@@ -171,12 +189,13 @@ defmodule Towerops.EquipmentTest do
assert DateTime.after?(updated.last_checked_at, first_checked_at)
end
- test "list_snmp_enabled_devices/0 returns only device with SNMP enabled", %{site: site} do
+ test "list_snmp_enabled_devices/0 returns only device with SNMP enabled", %{organization: organization, site: site} do
{:ok, snmp_enabled} =
Devices.create_device(%{
name: "SNMP Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_community: "public"
})
@@ -186,6 +205,7 @@ defmodule Towerops.EquipmentTest do
name: "Non-SNMP Router",
ip_address: "192.168.1.2",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: false
})
@@ -194,8 +214,10 @@ defmodule Towerops.EquipmentTest do
assert hd(result).id == snmp_enabled.id
end
- test "update_snmp_poll_time/1 updates last_snmp_poll_at timestamp", %{site: site} do
- {:ok, device} = Devices.create_device(Map.put(@valid_attrs, :site_id, site.id))
+ test "update_snmp_poll_time/1 updates last_snmp_poll_at timestamp", %{organization: organization, site: site} do
+ {:ok, device} =
+ Devices.create_device(Map.merge(@valid_attrs, %{site_id: site.id, organization_id: organization.id}))
+
assert device.last_snmp_poll_at == nil
assert {:ok, updated} = Devices.update_snmp_poll_time(device)
@@ -203,11 +225,12 @@ defmodule Towerops.EquipmentTest do
assert DateTime.before?(updated.last_snmp_poll_at, DateTime.utc_now())
end
- test "create_device/1 with SNMP enabled and nil community string succeeds", %{site: site} do
+ test "create_device/1 with SNMP enabled and nil community string succeeds", %{organization: organization, site: site} do
attrs = %{
name: "SNMP Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: nil
@@ -218,11 +241,15 @@ defmodule Towerops.EquipmentTest do
assert device.snmp_community == nil
end
- test "create_device/1 with SNMP enabled and empty community string succeeds", %{site: site} do
+ test "create_device/1 with SNMP enabled and empty community string succeeds", %{
+ organization: organization,
+ site: site
+ } do
attrs = %{
name: "SNMP Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: ""
@@ -235,10 +262,30 @@ defmodule Towerops.EquipmentTest do
assert device.snmp_community == nil || device.snmp_community == ""
end
- test "reorder_device/2 reorders device to first position", %{site: site} do
- {:ok, device1} = Devices.create_device(%{name: "Device 1", ip_address: "192.168.1.1", site_id: site.id})
- {:ok, device2} = Devices.create_device(%{name: "Device 2", ip_address: "192.168.1.2", site_id: site.id})
- {:ok, device3} = Devices.create_device(%{name: "Device 3", ip_address: "192.168.1.3", site_id: site.id})
+ test "reorder_device/2 reorders device to first position", %{organization: organization, site: site} do
+ {:ok, device1} =
+ Devices.create_device(%{
+ name: "Device 1",
+ ip_address: "192.168.1.1",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, device2} =
+ Devices.create_device(%{
+ name: "Device 2",
+ ip_address: "192.168.1.2",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, device3} =
+ Devices.create_device(%{
+ name: "Device 3",
+ ip_address: "192.168.1.3",
+ site_id: site.id,
+ organization_id: organization.id
+ })
# Move device3 to first position
{:ok, _updated} = Devices.reorder_device(device3.id, 1)
@@ -255,10 +302,30 @@ defmodule Towerops.EquipmentTest do
assert Enum.at(devices, 2).display_order == 3
end
- test "reorder_device/2 reorders device to last position", %{site: site} do
- {:ok, device1} = Devices.create_device(%{name: "Device 1", ip_address: "192.168.1.1", site_id: site.id})
- {:ok, device2} = Devices.create_device(%{name: "Device 2", ip_address: "192.168.1.2", site_id: site.id})
- {:ok, device3} = Devices.create_device(%{name: "Device 3", ip_address: "192.168.1.3", site_id: site.id})
+ test "reorder_device/2 reorders device to last position", %{organization: organization, site: site} do
+ {:ok, device1} =
+ Devices.create_device(%{
+ name: "Device 1",
+ ip_address: "192.168.1.1",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, device2} =
+ Devices.create_device(%{
+ name: "Device 2",
+ ip_address: "192.168.1.2",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, device3} =
+ Devices.create_device(%{
+ name: "Device 3",
+ ip_address: "192.168.1.3",
+ site_id: site.id,
+ organization_id: organization.id
+ })
# Move device1 to last position
{:ok, _updated} = Devices.reorder_device(device1.id, 3)
@@ -275,10 +342,30 @@ defmodule Towerops.EquipmentTest do
assert Enum.at(devices, 2).display_order == 3
end
- test "reorder_device/2 reorders device to middle position", %{site: site} do
- {:ok, device1} = Devices.create_device(%{name: "Device 1", ip_address: "192.168.1.1", site_id: site.id})
- {:ok, device2} = Devices.create_device(%{name: "Device 2", ip_address: "192.168.1.2", site_id: site.id})
- {:ok, device3} = Devices.create_device(%{name: "Device 3", ip_address: "192.168.1.3", site_id: site.id})
+ test "reorder_device/2 reorders device to middle position", %{organization: organization, site: site} do
+ {:ok, device1} =
+ Devices.create_device(%{
+ name: "Device 1",
+ ip_address: "192.168.1.1",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, device2} =
+ Devices.create_device(%{
+ name: "Device 2",
+ ip_address: "192.168.1.2",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, device3} =
+ Devices.create_device(%{
+ name: "Device 3",
+ ip_address: "192.168.1.3",
+ site_id: site.id,
+ organization_id: organization.id
+ })
# Move device3 to middle position
{:ok, _updated} = Devices.reorder_device(device3.id, 2)
@@ -295,11 +382,38 @@ defmodule Towerops.EquipmentTest do
assert Enum.at(devices, 2).display_order == 3
end
- test "reorder_device/2 maintains continuous numbering", %{site: site} do
- {:ok, _device1} = Devices.create_device(%{name: "Device 1", ip_address: "192.168.1.1", site_id: site.id})
- {:ok, device2} = Devices.create_device(%{name: "Device 2", ip_address: "192.168.1.2", site_id: site.id})
- {:ok, _device3} = Devices.create_device(%{name: "Device 3", ip_address: "192.168.1.3", site_id: site.id})
- {:ok, device4} = Devices.create_device(%{name: "Device 4", ip_address: "192.168.1.4", site_id: site.id})
+ test "reorder_device/2 maintains continuous numbering", %{organization: organization, site: site} do
+ {:ok, _device1} =
+ Devices.create_device(%{
+ name: "Device 1",
+ ip_address: "192.168.1.1",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, device2} =
+ Devices.create_device(%{
+ name: "Device 2",
+ ip_address: "192.168.1.2",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, _device3} =
+ Devices.create_device(%{
+ name: "Device 3",
+ ip_address: "192.168.1.3",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, device4} =
+ Devices.create_device(%{
+ name: "Device 4",
+ ip_address: "192.168.1.4",
+ site_id: site.id,
+ organization_id: organization.id
+ })
# Reorder multiple times
{:ok, _} = Devices.reorder_device(device2.id, 1)
@@ -313,12 +427,32 @@ defmodule Towerops.EquipmentTest do
test "reorder_device/2 only affects devices in same site", %{organization: organization, site: site} do
# Create devices in first site
- {:ok, device1} = Devices.create_device(%{name: "Device 1", ip_address: "192.168.1.1", site_id: site.id})
- {:ok, device2} = Devices.create_device(%{name: "Device 2", ip_address: "192.168.1.2", site_id: site.id})
+ {:ok, device1} =
+ Devices.create_device(%{
+ name: "Device 1",
+ ip_address: "192.168.1.1",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, device2} =
+ Devices.create_device(%{
+ name: "Device 2",
+ ip_address: "192.168.1.2",
+ site_id: site.id,
+ organization_id: organization.id
+ })
# Create second site and device
{:ok, site2} = Towerops.Sites.create_site(%{name: "Site 2", organization_id: organization.id})
- {:ok, device3} = Devices.create_device(%{name: "Device 3", ip_address: "192.168.2.1", site_id: site2.id})
+
+ {:ok, device3} =
+ Devices.create_device(%{
+ name: "Device 3",
+ ip_address: "192.168.2.1",
+ site_id: site2.id,
+ organization_id: organization.id
+ })
# Reorder device in first site
{:ok, _} = Devices.reorder_device(device1.id, 2)
@@ -339,8 +473,21 @@ defmodule Towerops.EquipmentTest do
organization: organization,
site: site
} do
- {:ok, device1} = Devices.create_device(%{name: "Zebra Device", ip_address: "192.168.1.1", site_id: site.id})
- {:ok, device2} = Devices.create_device(%{name: "Alpha Device", ip_address: "192.168.1.2", site_id: site.id})
+ {:ok, device1} =
+ Devices.create_device(%{
+ name: "Zebra Device",
+ ip_address: "192.168.1.1",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
+ {:ok, device2} =
+ Devices.create_device(%{
+ name: "Alpha Device",
+ ip_address: "192.168.1.2",
+ site_id: site.id,
+ organization_id: organization.id
+ })
# Set custom order
{:ok, _} = Devices.reorder_device(device1.id, 1)
@@ -380,12 +527,13 @@ defmodule Towerops.EquipmentTest do
%{organization: organization, site: site, user: user}
end
- test "get_snmp_config/1 returns device-level community string when set", %{site: site} do
+ test "get_snmp_config/1 returns device-level community string when set", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_community: "device-community"
})
@@ -396,7 +544,7 @@ defmodule Towerops.EquipmentTest do
end
test "get_snmp_config/1 returns site-level community when device has nil", %{
- organization: _organization,
+ organization: organization,
site: site
} do
# Update site with SNMP community
@@ -411,6 +559,7 @@ defmodule Towerops.EquipmentTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_community: nil
})
@@ -440,6 +589,7 @@ defmodule Towerops.EquipmentTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_community: nil
})
@@ -450,12 +600,13 @@ defmodule Towerops.EquipmentTest do
assert config.source == :organization
end
- test "get_snmp_config/1 returns nil when all levels have nil", %{site: site} do
+ test "get_snmp_config/1 returns nil when all levels have nil", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_community: nil
})
@@ -463,7 +614,7 @@ defmodule Towerops.EquipmentTest do
device = Towerops.Repo.preload(device, site: :organization)
config = Devices.get_snmp_config(device)
assert config.community == nil
- assert config.source == :default
+ assert config.source == :organization
end
test "get_snmp_config/1 prioritizes device over site over org", %{
@@ -488,6 +639,7 @@ defmodule Towerops.EquipmentTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_community: "device-community"
})
@@ -519,7 +671,8 @@ defmodule Towerops.EquipmentTest do
Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
%{device: device}
@@ -612,12 +765,13 @@ defmodule Towerops.EquipmentTest do
%{organization: organization, site: site, user: user}
end
- test "get_device/1 returns device when exists", %{site: site} do
+ test "get_device/1 returns device when exists", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
found = Devices.get_device(device.id)
@@ -629,12 +783,13 @@ defmodule Towerops.EquipmentTest do
assert Devices.get_device(Ecto.UUID.generate()) == nil
end
- test "get_device_with_details/1 preloads associations", %{site: site} do
+ test "get_device_with_details/1 preloads associations", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
result = Devices.get_device_with_details(device.id)
@@ -643,13 +798,14 @@ defmodule Towerops.EquipmentTest do
end
@tag :skip
- test "delete_device/1 deletes the device", %{site: site} do
+ test "delete_device/1 deletes the device", %{organization: organization, site: site} do
# Skipped: Requires Monitoring.Supervisor to be running
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
assert {:ok, _deleted} = Devices.delete_device(device)
@@ -661,50 +817,56 @@ defmodule Towerops.EquipmentTest do
Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, _device2} =
Devices.create_device(%{
name: "Router 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
assert Devices.count_organization_devices(organization.id) == 2
end
- test "count_site_devices/1 returns correct count", %{site: site} do
+ test "count_site_devices/1 returns correct count", %{organization: organization, site: site} do
{:ok, _device1} =
Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, _device2} =
Devices.create_device(%{
name: "Router 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
assert Devices.count_site_devices(site.id) == 2
end
- test "count_site_devices_down/1 returns correct count", %{site: site} do
+ test "count_site_devices_down/1 returns correct count", %{organization: organization, site: site} do
{:ok, device1} =
Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, _device2} =
Devices.create_device(%{
name: "Router 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
# Mark one as down
@@ -724,14 +886,16 @@ defmodule Towerops.EquipmentTest do
Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, _device2} =
Devices.create_device(%{
name: "Router 2",
ip_address: "192.168.1.2",
- site_id: site2.id
+ site_id: site2.id,
+ organization_id: organization.id
})
result = Devices.list_organization_devices(organization.id, %{"site_id" => site.id})
@@ -744,14 +908,16 @@ defmodule Towerops.EquipmentTest do
Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, _device2} =
Devices.create_device(%{
name: "Router 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
# Mark one as up
@@ -762,12 +928,13 @@ defmodule Towerops.EquipmentTest do
assert hd(result).id == device1.id
end
- test "get_snmp_config/1 with device ID string", %{site: site} do
+ test "get_snmp_config/1 with device ID string", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_community: "test-community"
})
@@ -794,12 +961,13 @@ defmodule Towerops.EquipmentTest do
%{organization: organization, site: site, user: user}
end
- test "triggers discovery when snmp_enabled changes from false to true", %{site: site} do
+ test "triggers discovery when snmp_enabled changes from false to true", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: false
})
@@ -819,12 +987,13 @@ defmodule Towerops.EquipmentTest do
assert job.args["device_id"] == device.id
end
- test "triggers discovery when snmp_version changes while enabled", %{site: site} do
+ test "triggers discovery when snmp_version changes while enabled", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c"
})
@@ -845,12 +1014,13 @@ defmodule Towerops.EquipmentTest do
assert job.args["device_id"] == device.id
end
- test "triggers discovery when snmp_port changes while enabled", %{site: site} do
+ test "triggers discovery when snmp_port changes while enabled", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_port: 161
})
@@ -872,6 +1042,7 @@ defmodule Towerops.EquipmentTest do
end
test "triggers discovery when monitoring_enabled changes to true with SNMP enabled", %{
+ organization: organization,
site: site
} do
{:ok, device} =
@@ -879,6 +1050,7 @@ defmodule Towerops.EquipmentTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
monitoring_enabled: false
})
@@ -900,6 +1072,7 @@ defmodule Towerops.EquipmentTest do
end
test "does not trigger discovery when monitoring_enabled changes but SNMP disabled", %{
+ organization: organization,
site: site
} do
{:ok, device} =
@@ -907,6 +1080,7 @@ defmodule Towerops.EquipmentTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: false,
monitoring_enabled: false
})
@@ -926,12 +1100,13 @@ defmodule Towerops.EquipmentTest do
assert [] = jobs
end
- test "does not trigger discovery when SNMP is disabled", %{site: site} do
+ test "does not trigger discovery when SNMP is disabled", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c"
})
@@ -951,12 +1126,13 @@ defmodule Towerops.EquipmentTest do
assert [] = jobs
end
- test "does not trigger discovery for unrelated field changes", %{site: site} do
+ test "does not trigger discovery for unrelated field changes", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true
})
@@ -975,12 +1151,13 @@ defmodule Towerops.EquipmentTest do
assert [] = jobs
end
- test "does not trigger discovery when snmp_version changes while disabled", %{site: site} do
+ test "does not trigger discovery when snmp_version changes while disabled", %{organization: organization, site: site} do
{:ok, device} =
Devices.create_device(%{
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: false,
snmp_version: "2c"
})
@@ -1028,7 +1205,8 @@ defmodule Towerops.EquipmentTest do
attrs = %{
name: name,
ip_address: ip_address,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
}
# Use bypass_limits since property tests may create > 10 devices
@@ -1053,7 +1231,8 @@ defmodule Towerops.EquipmentTest do
Devices.create_device(%{
name: "Test Device",
ip_address: "192.168.1.100",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
# Update status twice
@@ -1083,7 +1262,8 @@ defmodule Towerops.EquipmentTest do
Devices.create_device(%{
name: "Device #{i}",
ip_address: "192.168.1.#{i}",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
end
end
@@ -1129,6 +1309,7 @@ defmodule Towerops.EquipmentTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_community: device_community
})
@@ -1168,7 +1349,7 @@ defmodule Towerops.EquipmentTest do
%{organization: organization, site: site, user: user}
end
- test "blocks device creation when at 10-device limit", %{site: site} do
+ test "blocks device creation when at 10-device limit", %{organization: organization, site: site} do
# Create 10 devices (the limit)
for i <- 1..10 do
{:ok, _device} =
@@ -1176,6 +1357,7 @@ defmodule Towerops.EquipmentTest do
name: "Device #{i}",
ip_address: "192.168.1.#{i}",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
})
@@ -1187,6 +1369,7 @@ defmodule Towerops.EquipmentTest do
name: "Device 11",
ip_address: "192.168.1.11",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
})
@@ -1195,7 +1378,7 @@ defmodule Towerops.EquipmentTest do
errors_on(changeset)
end
- test "allows device creation when under limit", %{site: site} do
+ test "allows device creation when under limit", %{organization: organization, site: site} do
# Create 9 devices
for i <- 1..9 do
{:ok, _device} =
@@ -1203,6 +1386,7 @@ defmodule Towerops.EquipmentTest do
name: "Device #{i}",
ip_address: "192.168.1.#{i}",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
})
@@ -1214,12 +1398,13 @@ defmodule Towerops.EquipmentTest do
name: "Device 10",
ip_address: "192.168.1.10",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
})
end
- test "bypasses limit with bypass_limits option", %{site: site} do
+ test "bypasses limit with bypass_limits option", %{organization: organization, site: site} do
# Create 10 devices (at limit)
for i <- 1..10 do
{:ok, _device} =
@@ -1227,6 +1412,7 @@ defmodule Towerops.EquipmentTest do
name: "Device #{i}",
ip_address: "192.168.1.#{i}",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
})
@@ -1239,6 +1425,7 @@ defmodule Towerops.EquipmentTest do
name: "Device 11",
ip_address: "192.168.1.11",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
},
@@ -1263,6 +1450,7 @@ defmodule Towerops.EquipmentTest do
name: "Site1 Device #{i}",
ip_address: "192.168.1.#{i}",
site_id: site1.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
})
@@ -1275,6 +1463,7 @@ defmodule Towerops.EquipmentTest do
name: "Site2 Device #{i}",
ip_address: "192.168.2.#{i}",
site_id: site2.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
})
@@ -1286,6 +1475,7 @@ defmodule Towerops.EquipmentTest do
name: "Site1 Device 7",
ip_address: "192.168.1.7",
site_id: site1.id,
+ organization_id: organization.id,
monitoring_enabled: false,
snmp_enabled: false
})
@@ -1331,14 +1521,16 @@ defmodule Towerops.EquipmentTest do
Devices.create_device(%{
name: "Device 1",
ip_address: "192.168.1.1",
- site_id: site1.id
+ site_id: site1.id,
+ organization_id: org1.id
})
{:ok, device2} =
Devices.create_device(%{
name: "Device 2",
ip_address: "192.168.1.2",
- site_id: site2.id
+ site_id: site2.id,
+ organization_id: org2.id
})
result = Devices.list_devices_for_organizations([org1.id, org2.id])
@@ -1351,6 +1543,7 @@ defmodule Towerops.EquipmentTest do
test "returns only devices from specified organizations", %{
org1: org1,
+ org2: org2,
site1: site1,
site2: site2
} do
@@ -1358,14 +1551,16 @@ defmodule Towerops.EquipmentTest do
Devices.create_device(%{
name: "Device 1",
ip_address: "192.168.1.1",
- site_id: site1.id
+ site_id: site1.id,
+ organization_id: org1.id
})
{:ok, _device2} =
Devices.create_device(%{
name: "Device 2",
ip_address: "192.168.1.2",
- site_id: site2.id
+ site_id: site2.id,
+ organization_id: org2.id
})
# Only request devices from org1
@@ -1389,7 +1584,8 @@ defmodule Towerops.EquipmentTest do
Devices.create_device(%{
name: "Device 1",
ip_address: "192.168.1.1",
- site_id: site1.id
+ site_id: site1.id,
+ organization_id: org1.id
})
result = Devices.list_devices_for_organizations([org1.id])
@@ -1404,21 +1600,24 @@ defmodule Towerops.EquipmentTest do
Devices.create_device(%{
name: "Zebra Device",
ip_address: "192.168.1.1",
- site_id: site1.id
+ site_id: site1.id,
+ organization_id: org1.id
})
{:ok, _alpha_dev} =
Devices.create_device(%{
name: "Alpha Device",
ip_address: "192.168.1.2",
- site_id: site1.id
+ site_id: site1.id,
+ organization_id: org1.id
})
{:ok, _beta_dev} =
Devices.create_device(%{
name: "Beta Device",
ip_address: "192.168.2.1",
- site_id: site2.id
+ site_id: site2.id,
+ organization_id: org2.id
})
result = Devices.list_devices_for_organizations([org1.id, org2.id])
diff --git a/test/towerops/equipment/event_logger_test.exs b/test/towerops/equipment/event_logger_test.exs
index 9632cd5f..e0d38157 100644
--- a/test/towerops/equipment/event_logger_test.exs
+++ b/test/towerops/equipment/event_logger_test.exs
@@ -25,6 +25,7 @@ defmodule Towerops.Devices.EventLoggerTest do
Towerops.Devices.create_device(%{
name: "Test Equipment",
site_id: site.id,
+ organization_id: site.organization_id,
ip_address: "192.168.1.1"
})
diff --git a/test/towerops/monitoring/check_test.exs b/test/towerops/monitoring/check_test.exs
index 8df77a5b..b8efa7de 100644
--- a/test/towerops/monitoring/check_test.exs
+++ b/test/towerops/monitoring/check_test.exs
@@ -21,7 +21,8 @@ defmodule Towerops.Monitoring.CheckTest do
Towerops.Devices.create_device(%{
name: "Test Device",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: site.organization_id
})
{:ok, device: device}
diff --git a/test/towerops/monitoring_test.exs b/test/towerops/monitoring_test.exs
index 64ce286e..4e1162e1 100644
--- a/test/towerops/monitoring_test.exs
+++ b/test/towerops/monitoring_test.exs
@@ -22,7 +22,8 @@ defmodule Towerops.MonitoringTest do
Towerops.Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
%{device: device}
diff --git a/test/towerops/organizations/subscription_limits_test.exs b/test/towerops/organizations/subscription_limits_test.exs
index 52d3ec78..5904782f 100644
--- a/test/towerops/organizations/subscription_limits_test.exs
+++ b/test/towerops/organizations/subscription_limits_test.exs
@@ -196,12 +196,15 @@ defmodule Towerops.Organizations.SubscriptionLimitsTest do
# Helper functions
defp create_device(site_id, name, ip_address) do
+ site = Sites.get_site!(site_id)
+
{:ok, device} =
Devices.create_device(
%{
name: name,
ip_address: ip_address,
site_id: site_id,
+ organization_id: site.organization_id,
monitoring_enabled: false,
snmp_enabled: false
},
diff --git a/test/towerops/organizations_test.exs b/test/towerops/organizations_test.exs
index ce7894f1..0ab9ede4 100644
--- a/test/towerops/organizations_test.exs
+++ b/test/towerops/organizations_test.exs
@@ -437,7 +437,8 @@ defmodule Towerops.OrganizationsTest do
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, device2} =
@@ -447,7 +448,8 @@ defmodule Towerops.OrganizationsTest do
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{count, _} = Organizations.apply_snmp_config_to_all_equipment(organization.id)
@@ -494,14 +496,16 @@ defmodule Towerops.OrganizationsTest do
Towerops.Devices.create_device(%{
name: "Device 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, device2} =
Towerops.Devices.create_device(%{
name: "Device 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{count, _} = Organizations.apply_agent_to_all_equipment(organization.id)
@@ -528,7 +532,8 @@ defmodule Towerops.OrganizationsTest do
Towerops.Devices.create_device(%{
name: "Test Device",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, agent_token, _token} =
@@ -562,7 +567,8 @@ defmodule Towerops.OrganizationsTest do
Towerops.Devices.create_device(%{
name: "Test Device",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
Towerops.Agents.assign_device_to_agent(old_agent.id, device.id)
@@ -678,6 +684,7 @@ defmodule Towerops.OrganizationsTest do
name: "MikroTik Device",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
manufacturer: "MikroTik"
})
@@ -696,9 +703,9 @@ defmodule Towerops.OrganizationsTest do
assert updated_org.mikrotik_use_ssl == true
assert updated_org.mikrotik_enabled == true
- # Verify device credential source remains "site" (inherits from site, which inherits from org)
+ # Verify device credential source is "organization" (inherits directly from org)
updated_device = Repo.get!(Device, device.id)
- assert updated_device.mikrotik_credential_source == "site"
+ assert updated_device.mikrotik_credential_source == "organization"
# Verify the device received the organization's MikroTik settings through propagation
assert updated_device.mikrotik_username == "admin"
@@ -731,6 +738,7 @@ defmodule Towerops.OrganizationsTest do
name: "MikroTik Device",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
manufacturer: "MikroTik"
})
diff --git a/test/towerops/sites_test.exs b/test/towerops/sites_test.exs
index e5a917a6..fa7f44c8 100644
--- a/test/towerops/sites_test.exs
+++ b/test/towerops/sites_test.exs
@@ -54,7 +54,13 @@ defmodule Towerops.SitesTest do
test "list_root_sites/1 returns only sites without parents", %{organization: organization} do
{:ok, root} = Sites.create_site(%{name: "Root Site", organization_id: organization.id})
- {:ok, _child} = Sites.create_site(%{name: "Child Site", organization_id: organization.id, parent_site_id: root.id})
+
+ {:ok, _child} =
+ Sites.create_site(%{
+ name: "Child Site",
+ organization_id: organization.id,
+ parent_site_id: root.id
+ })
roots = Sites.list_root_sites(organization.id)
assert length(roots) == 1
@@ -63,8 +69,20 @@ defmodule Towerops.SitesTest do
test "list_child_sites/1 returns child sites of a parent", %{organization: organization} do
{:ok, parent} = Sites.create_site(%{name: "Parent", organization_id: organization.id})
- {:ok, child1} = Sites.create_site(%{name: "Child 1", organization_id: organization.id, parent_site_id: parent.id})
- {:ok, child2} = Sites.create_site(%{name: "Child 2", organization_id: organization.id, parent_site_id: parent.id})
+
+ {:ok, child1} =
+ Sites.create_site(%{
+ name: "Child 1",
+ organization_id: organization.id,
+ parent_site_id: parent.id
+ })
+
+ {:ok, child2} =
+ Sites.create_site(%{
+ name: "Child 2",
+ organization_id: organization.id,
+ parent_site_id: parent.id
+ })
children = Sites.list_child_sites(parent.id)
assert length(children) == 2
@@ -81,7 +99,13 @@ defmodule Towerops.SitesTest do
test "get_site!/1 preloads associations", %{organization: organization} do
{:ok, parent} = Sites.create_site(%{name: "Parent", organization_id: organization.id})
- {:ok, site} = Sites.create_site(%{name: "Child", organization_id: organization.id, parent_site_id: parent.id})
+
+ {:ok, site} =
+ Sites.create_site(%{
+ name: "Child",
+ organization_id: organization.id,
+ parent_site_id: parent.id
+ })
fetched = Sites.get_site!(site.id)
assert Ecto.assoc_loaded?(fetched.parent_site)
@@ -195,7 +219,7 @@ defmodule Towerops.SitesTest do
{:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: organization.id})
# Try to make site its own parent
- assert {:error, changeset} = Sites.update_site(site, %{parent_site_id: site.id})
+ assert {:error, changeset} = Sites.update_site(site, %{parent_site_id: site.id, organization_id: organization.id})
assert "cannot be the same as the site itself" in errors_on(changeset).parent_site_id
end
@@ -232,10 +256,20 @@ defmodule Towerops.SitesTest do
test "build_site_tree/1 builds hierarchical structure", %{organization: organization} do
{:ok, root1} = Sites.create_site(%{name: "Root 1", organization_id: organization.id})
{:ok, root2} = Sites.create_site(%{name: "Root 2", organization_id: organization.id})
- {:ok, child1} = Sites.create_site(%{name: "Child 1", organization_id: organization.id, parent_site_id: root1.id})
+
+ {:ok, child1} =
+ Sites.create_site(%{
+ name: "Child 1",
+ organization_id: organization.id,
+ parent_site_id: root1.id
+ })
{:ok, grandchild} =
- Sites.create_site(%{name: "Grandchild", organization_id: organization.id, parent_site_id: child1.id})
+ Sites.create_site(%{
+ name: "Grandchild",
+ organization_id: organization.id,
+ parent_site_id: child1.id
+ })
tree = Sites.build_site_tree(organization.id)
assert length(tree) == 2
@@ -269,6 +303,7 @@ defmodule Towerops.SitesTest do
name: "Device 1",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_version: "1",
snmp_community: "old-community"
})
@@ -278,6 +313,7 @@ defmodule Towerops.SitesTest do
name: "Device 2",
ip_address: "192.168.1.2",
site_id: site.id,
+ organization_id: organization.id,
snmp_version: "1",
snmp_community: "old-community"
})
@@ -308,14 +344,16 @@ defmodule Towerops.SitesTest do
Towerops.Devices.create_device(%{
name: "Device 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, device2} =
Towerops.Devices.create_device(%{
name: "Device 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{count, _} = Sites.apply_agent_to_all_equipment(site.id)
@@ -345,7 +383,8 @@ defmodule Towerops.SitesTest do
Towerops.Devices.create_device(%{
name: "Device 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
# Create initial assignment
diff --git a/test/towerops/snmp/discovery_test.exs b/test/towerops/snmp/discovery_test.exs
index a083d47b..de60916d 100644
--- a/test/towerops/snmp/discovery_test.exs
+++ b/test/towerops/snmp/discovery_test.exs
@@ -37,24 +37,26 @@ defmodule Towerops.Snmp.DiscoveryTest do
end
describe "discover_device/1" do
- test "returns error when SNMP is not enabled", %{site: site} do
+ test "returns error when SNMP is not enabled", %{organization: organization, site: site} do
{:ok, device} =
Towerops.Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: false
})
assert {:error, :snmp_not_enabled} = Discovery.discover_device(device)
end
- test "successfully discovers MikroTik device", %{site: site} do
+ test "successfully discovers MikroTik device", %{organization: organization, site: site} do
{:ok, device} =
Towerops.Devices.create_device(%{
name: "MikroTik Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -205,12 +207,13 @@ defmodule Towerops.Snmp.DiscoveryTest do
assert interface1.if_alias == "WAN"
end
- test "successfully discovers Cisco device", %{site: site} do
+ test "successfully discovers Cisco device", %{organization: organization, site: site} do
{:ok, device} =
Towerops.Devices.create_device(%{
name: "Cisco Switch",
ip_address: "192.168.1.2",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -257,12 +260,13 @@ defmodule Towerops.Snmp.DiscoveryTest do
assert device.sys_name == "switch1"
end
- test "handles connection failure", %{site: site} do
+ test "handles connection failure", %{organization: organization, site: site} do
{:ok, device} =
Towerops.Devices.create_device(%{
name: "Unreachable Device",
ip_address: "192.168.1.99",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -277,12 +281,13 @@ defmodule Towerops.Snmp.DiscoveryTest do
assert {:error, :device_unresponsive} = Discovery.discover_device(device)
end
- test "handles partial discovery failure gracefully", %{site: site} do
+ test "handles partial discovery failure gracefully", %{organization: organization, site: site} do
{:ok, device} =
Towerops.Devices.create_device(%{
name: "Partial Device",
ip_address: "192.168.1.3",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -349,12 +354,13 @@ defmodule Towerops.Snmp.DiscoveryTest do
assert sensors == []
end
- test "updates existing device on re-discovery", %{site: site} do
+ test "updates existing device on re-discovery", %{organization: organization, site: site} do
{:ok, device} =
Towerops.Devices.create_device(%{
name: "Existing Device",
ip_address: "192.168.1.4",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -415,6 +421,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
end
test "preserves sensor readings when rediscovering device with same sensor_index", %{
+ organization: organization,
site: site
} do
alias Towerops.Snmp.SensorReading
@@ -424,6 +431,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
name: "Device With Sensors",
ip_address: "192.168.1.50",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -548,7 +556,10 @@ defmodule Towerops.Snmp.DiscoveryTest do
assert Enum.map(readings, & &1.value) == [42.0, 44.0, 45.0]
end
- test "preserves interface stats when rediscovering device with same if_index", %{site: site} do
+ test "preserves interface stats when rediscovering device with same if_index", %{
+ organization: organization,
+ site: site
+ } do
alias Towerops.Snmp.InterfaceStat
{:ok, device} =
@@ -556,6 +567,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
name: "Device With Interfaces",
ip_address: "192.168.1.51",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -682,12 +694,13 @@ defmodule Towerops.Snmp.DiscoveryTest do
assert Enum.map(stats, & &1.if_in_octets) == [1_000_000, 2_000_000, 3_000_000]
end
- test "deletes sensors that no longer exist during rediscovery", %{site: site} do
+ test "deletes sensors that no longer exist during rediscovery", %{organization: organization, site: site} do
{:ok, device} =
Towerops.Devices.create_device(%{
name: "Device With Removed Sensor",
ip_address: "192.168.1.52",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -800,6 +813,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
name: "Device 1",
ip_address: "192.168.1.10",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -811,6 +825,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
name: "Device 2",
ip_address: "192.168.1.11",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -822,6 +837,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
name: "Device 3 - No SNMP",
ip_address: "192.168.1.12",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: false
})
@@ -858,6 +874,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
name: "Good Device",
ip_address: "192.168.1.20",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -869,6 +886,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
name: "Bad Device",
ip_address: "192.168.1.21",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "wrong",
@@ -906,7 +924,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
end
test "updates device name from SNMP sysName when device name is empty", %{
- organization: _organization,
+ organization: organization,
site: site
} do
# Create device without a name
@@ -915,6 +933,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
name: nil,
ip_address: "192.168.1.200",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
@@ -960,7 +979,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
end
test "does not update device name from SNMP when device already has a name", %{
- organization: _organization,
+ organization: organization,
site: site
} do
# Create device with a name
@@ -969,6 +988,7 @@ defmodule Towerops.Snmp.DiscoveryTest do
name: "My Custom Name",
ip_address: "192.168.1.201",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_community: "public",
diff --git a/test/towerops/snmp/ip_address_test.exs b/test/towerops/snmp/ip_address_test.exs
index 0d675a0d..9d830c41 100644
--- a/test/towerops/snmp/ip_address_test.exs
+++ b/test/towerops/snmp/ip_address_test.exs
@@ -27,7 +27,8 @@ defmodule Towerops.Snmp.IpAddressTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
snmp_device =
diff --git a/test/towerops/snmp/mac_address_test.exs b/test/towerops/snmp/mac_address_test.exs
index 51602f97..4cbff26c 100644
--- a/test/towerops/snmp/mac_address_test.exs
+++ b/test/towerops/snmp/mac_address_test.exs
@@ -27,7 +27,8 @@ defmodule Towerops.Snmp.MacAddressTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
snmp_device =
diff --git a/test/towerops/snmp/memory_pool_test.exs b/test/towerops/snmp/memory_pool_test.exs
index 5783577b..4de42585 100644
--- a/test/towerops/snmp/memory_pool_test.exs
+++ b/test/towerops/snmp/memory_pool_test.exs
@@ -26,7 +26,8 @@ defmodule Towerops.Snmp.MemoryPoolTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
snmp_device =
diff --git a/test/towerops/snmp/neighbor_cleanup_worker_test.exs b/test/towerops/snmp/neighbor_cleanup_worker_test.exs
index 1d84c2c8..567b3812 100644
--- a/test/towerops/snmp/neighbor_cleanup_worker_test.exs
+++ b/test/towerops/snmp/neighbor_cleanup_worker_test.exs
@@ -28,7 +28,8 @@ defmodule Towerops.Snmp.NeighborCleanupWorkerTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, device_schema2} =
@@ -39,7 +40,8 @@ defmodule Towerops.Snmp.NeighborCleanupWorkerTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
device1 =
@@ -216,7 +218,8 @@ defmodule Towerops.Snmp.NeighborCleanupWorkerTest do
name: "No SNMP Device",
ip_address: "192.168.1.100",
snmp_enabled: false,
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
device =
diff --git a/test/towerops/snmp/neighbor_test.exs b/test/towerops/snmp/neighbor_test.exs
index bab451cf..e79c7332 100644
--- a/test/towerops/snmp/neighbor_test.exs
+++ b/test/towerops/snmp/neighbor_test.exs
@@ -27,7 +27,8 @@ defmodule Towerops.Snmp.NeighborTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
snmp_device =
diff --git a/test/towerops/snmp/physical_entity_test.exs b/test/towerops/snmp/physical_entity_test.exs
index b05eb1e7..07765b9a 100644
--- a/test/towerops/snmp/physical_entity_test.exs
+++ b/test/towerops/snmp/physical_entity_test.exs
@@ -26,7 +26,8 @@ defmodule Towerops.Snmp.PhysicalEntityTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
snmp_device =
diff --git a/test/towerops/snmp/processor_reading_test.exs b/test/towerops/snmp/processor_reading_test.exs
index fac27276..884dfd27 100644
--- a/test/towerops/snmp/processor_reading_test.exs
+++ b/test/towerops/snmp/processor_reading_test.exs
@@ -203,7 +203,8 @@ defmodule Towerops.Snmp.ProcessorReadingTest do
Towerops.Devices.create_device(%{
name: "Test Device",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
device
diff --git a/test/towerops/snmp/state_sensor_test.exs b/test/towerops/snmp/state_sensor_test.exs
index 052a7895..d525a565 100644
--- a/test/towerops/snmp/state_sensor_test.exs
+++ b/test/towerops/snmp/state_sensor_test.exs
@@ -193,7 +193,8 @@ defmodule Towerops.Snmp.StateSensorTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: device_schema.site_id
+ site_id: device_schema.site_id,
+ organization_id: device_schema.organization_id
})
snmp_device2 =
diff --git a/test/towerops/snmp/storage_test.exs b/test/towerops/snmp/storage_test.exs
index d553b592..2a7e0976 100644
--- a/test/towerops/snmp/storage_test.exs
+++ b/test/towerops/snmp/storage_test.exs
@@ -26,7 +26,8 @@ defmodule Towerops.Snmp.StorageTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
snmp_device =
diff --git a/test/towerops/snmp/vlan_test.exs b/test/towerops/snmp/vlan_test.exs
index c2161052..442eea8b 100644
--- a/test/towerops/snmp/vlan_test.exs
+++ b/test/towerops/snmp/vlan_test.exs
@@ -26,7 +26,8 @@ defmodule Towerops.Snmp.VlanTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
snmp_device =
@@ -184,7 +185,8 @@ defmodule Towerops.Snmp.VlanTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: device_schema.site_id
+ site_id: device_schema.site_id,
+ organization_id: device_schema.organization_id
})
snmp_device2 =
diff --git a/test/towerops/snmp_test.exs b/test/towerops/snmp_test.exs
index 60aab95c..ebff8cdb 100644
--- a/test/towerops/snmp_test.exs
+++ b/test/towerops/snmp_test.exs
@@ -33,7 +33,8 @@ defmodule Towerops.SnmpTest do
snmp_version: "2c",
snmp_community: "public",
snmp_port: 161,
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
snmp_device =
@@ -1238,14 +1239,16 @@ defmodule Towerops.SnmpTest do
Towerops.Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, device2} =
Towerops.Devices.create_device(%{
name: "Router 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
snmp_device1 =
@@ -1868,14 +1871,16 @@ defmodule Towerops.SnmpTest do
Towerops.Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, device2} =
Towerops.Devices.create_device(%{
name: "Router 2",
ip_address: "192.168.1.2",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
old_time = DateTime.add(DateTime.utc_now(), -7200, :second)
diff --git a/test/towerops/workers/agent_latency_evaluator_test.exs b/test/towerops/workers/agent_latency_evaluator_test.exs
index 999ed3f7..b9e862d1 100644
--- a/test/towerops/workers/agent_latency_evaluator_test.exs
+++ b/test/towerops/workers/agent_latency_evaluator_test.exs
@@ -33,6 +33,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -83,6 +84,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -133,6 +135,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -182,6 +185,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -231,6 +235,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -289,6 +294,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -342,6 +348,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -399,6 +406,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router 1",
ip_address: "192.168.1.1",
site_id: site1.id,
+ organization_id: site1.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -409,6 +417,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router 2",
ip_address: "192.168.2.1",
site_id: site2.id,
+ organization_id: site2.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -464,6 +473,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -519,6 +529,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
@@ -563,6 +574,7 @@ defmodule Towerops.Workers.AgentLatencyEvaluatorTest do
name: "Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
snmp_enabled: true,
snmp_community: "public",
snmp_version: "2c"
diff --git a/test/towerops/workers/backup_summary_worker_test.exs b/test/towerops/workers/backup_summary_worker_test.exs
index 98c379ee..4be0c8e4 100644
--- a/test/towerops/workers/backup_summary_worker_test.exs
+++ b/test/towerops/workers/backup_summary_worker_test.exs
@@ -223,7 +223,8 @@ defmodule Towerops.Workers.BackupSummaryWorkerTest do
Devices.create_device(%{
name: "Test Device #{System.unique_integer()}",
ip_address: "192.168.1.#{:rand.uniform(254)}",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
device
diff --git a/test/towerops/workers/backup_timeout_worker_test.exs b/test/towerops/workers/backup_timeout_worker_test.exs
index 757568be..2494d581 100644
--- a/test/towerops/workers/backup_timeout_worker_test.exs
+++ b/test/towerops/workers/backup_timeout_worker_test.exs
@@ -197,7 +197,8 @@ defmodule Towerops.Workers.BackupTimeoutWorkerTest do
Devices.create_device(%{
name: "Test Device #{System.unique_integer()}",
ip_address: "192.168.1.#{:rand.uniform(254)}",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
device
diff --git a/test/towerops/workers/device_monitor_worker_test.exs b/test/towerops/workers/device_monitor_worker_test.exs
index 370f563d..49761393 100644
--- a/test/towerops/workers/device_monitor_worker_test.exs
+++ b/test/towerops/workers/device_monitor_worker_test.exs
@@ -29,6 +29,7 @@ defmodule Towerops.Workers.DeviceMonitorWorkerTest do
name: "Router 1",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
monitoring_enabled: true
})
@@ -53,6 +54,7 @@ defmodule Towerops.Workers.DeviceMonitorWorkerTest do
name: "Router 2",
ip_address: "192.168.1.2",
site_id: site.id,
+ organization_id: site.organization_id,
monitoring_enabled: true
})
@@ -73,6 +75,7 @@ defmodule Towerops.Workers.DeviceMonitorWorkerTest do
name: "Router 3",
ip_address: "192.168.1.3",
site_id: site.id,
+ organization_id: site.organization_id,
monitoring_enabled: true
})
diff --git a/test/towerops/workers/device_poller_worker_test.exs b/test/towerops/workers/device_poller_worker_test.exs
index e30c8375..db7529f8 100644
--- a/test/towerops/workers/device_poller_worker_test.exs
+++ b/test/towerops/workers/device_poller_worker_test.exs
@@ -29,6 +29,7 @@ defmodule Towerops.Workers.DevicePollerWorkerTest do
name: "Router 1",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: site.organization_id,
check_interval_seconds: 300
})
@@ -53,6 +54,7 @@ defmodule Towerops.Workers.DevicePollerWorkerTest do
name: "Router 2",
ip_address: "192.168.1.2",
site_id: site.id,
+ organization_id: site.organization_id,
check_interval_seconds: 600
})
@@ -74,7 +76,8 @@ defmodule Towerops.Workers.DevicePollerWorkerTest do
Devices.create_device(%{
name: "Router 3",
ip_address: "192.168.1.3",
- site_id: site.id
+ site_id: site.id,
+ organization_id: site.organization_id
})
# Start polling
diff --git a/test/towerops_web/controllers/api/account_data_controller_test.exs b/test/towerops_web/controllers/api/account_data_controller_test.exs
index d79cf347..01080d8c 100644
--- a/test/towerops_web/controllers/api/account_data_controller_test.exs
+++ b/test/towerops_web/controllers/api/account_data_controller_test.exs
@@ -73,6 +73,7 @@ defmodule ToweropsWeb.Api.AccountDataControllerTest do
name: "Test Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: org.id,
snmp_enabled: true,
snmp_community: "secret-community-string"
})
@@ -111,7 +112,8 @@ defmodule ToweropsWeb.Api.AccountDataControllerTest do
Devices.create_device(%{
name: "Test Router",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
# Create a recent alert
@@ -150,7 +152,8 @@ defmodule ToweropsWeb.Api.AccountDataControllerTest do
Devices.create_device(%{
name: "Test Router",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: org.id
})
# Create an alert with an old triggered_at (120 days ago)
diff --git a/test/towerops_web/live/alert_live_test.exs b/test/towerops_web/live/alert_live_test.exs
index 7aca0288..e9225d1a 100644
--- a/test/towerops_web/live/alert_live_test.exs
+++ b/test/towerops_web/live/alert_live_test.exs
@@ -18,7 +18,8 @@ defmodule ToweropsWeb.AlertLive.IndexTest do
Towerops.Devices.create_device(%{
name: "Test Router",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
%{organization: organization, site: site, device: device}
diff --git a/test/towerops_web/live/dashboard_live_test.exs b/test/towerops_web/live/dashboard_live_test.exs
index 59dd85d6..58c1c756 100644
--- a/test/towerops_web/live/dashboard_live_test.exs
+++ b/test/towerops_web/live/dashboard_live_test.exs
@@ -6,7 +6,7 @@ defmodule ToweropsWeb.DashboardLiveTest do
setup :register_and_log_in_user
setup %{user: user} do
- {:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
+ {:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org", use_sites: true}, user.id)
{:ok, site} =
Towerops.Sites.create_site(%{
@@ -18,7 +18,16 @@ defmodule ToweropsWeb.DashboardLiveTest do
end
describe "Dashboard" do
- test "displays organization name and stats", %{conn: conn, organization: organization} do
+ test "displays organization name and stats", %{conn: conn, organization: organization, site: site} do
+ # Create a device so the dashboard shows stats instead of empty state
+ {:ok, _device} =
+ Towerops.Devices.create_device(%{
+ name: "Test Device",
+ ip_address: "192.168.1.1",
+ site_id: site.id,
+ organization_id: organization.id
+ })
+
{:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}")
assert html =~ organization.name
@@ -46,6 +55,7 @@ defmodule ToweropsWeb.DashboardLiveTest do
name: "Router 1",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: true
})
@@ -56,6 +66,7 @@ defmodule ToweropsWeb.DashboardLiveTest do
name: "Router 2",
ip_address: "192.168.1.2",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: true
})
@@ -72,7 +83,8 @@ defmodule ToweropsWeb.DashboardLiveTest do
Towerops.Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
# Create an active alert
@@ -97,7 +109,8 @@ defmodule ToweropsWeb.DashboardLiveTest do
Towerops.Devices.create_device(%{
name: "Router 1",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
{:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}")
diff --git a/test/towerops_web/live/device_live/form_test.exs b/test/towerops_web/live/device_live/form_test.exs
index 1432ac73..89f8d74d 100644
--- a/test/towerops_web/live/device_live/form_test.exs
+++ b/test/towerops_web/live/device_live/form_test.exs
@@ -3,6 +3,8 @@ defmodule ToweropsWeb.DeviceLive.FormTest do
import Phoenix.LiveViewTest
+ alias Towerops.Snmp.Device
+
setup :register_and_log_in_user
setup %{user: user} do
@@ -21,7 +23,8 @@ defmodule ToweropsWeb.DeviceLive.FormTest do
describe "edit page rendering" do
test "renders edit page when device has no SNMP discovery data (bug fix for nil boolean)", %{
conn: conn,
- site: site
+ site: site,
+ organization: organization
} do
# Regression test for production bug where visiting edit page for a device
# with no SNMP discovery data would crash with "expected boolean, got nil"
@@ -33,6 +36,7 @@ defmodule ToweropsWeb.DeviceLive.FormTest do
name: "Test Device",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_port: 161,
@@ -52,24 +56,18 @@ defmodule ToweropsWeb.DeviceLive.FormTest do
assert html =~ device.name
end
- test "renders MikroTik section for superuser when device is MikroTik", %{
+ test "renders MikroTik section when device is MikroTik", %{
conn: conn,
site: site,
- user: user
+ organization: organization
} do
- alias Towerops.Snmp.Device, as: SnmpDevice
- # Make user a superuser using Ecto.Changeset (standard test pattern)
- _user =
- user
- |> Ecto.Changeset.change(%{is_superuser: true})
- |> Towerops.Repo.update!()
-
# Create a device with MikroTik SNMP discovery data
{:ok, device} =
Towerops.Devices.create_device(%{
name: "MikroTik Router",
ip_address: "192.168.1.254",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true,
snmp_version: "2c",
snmp_port: 161,
@@ -79,8 +77,8 @@ defmodule ToweropsWeb.DeviceLive.FormTest do
# Create SNMP device with MikroTik manufacturer (using Towerops.Snmp.Device schema)
_snmp_device =
- %SnmpDevice{}
- |> SnmpDevice.changeset(%{
+ %Device{}
+ |> Device.changeset(%{
device_id: device.id,
manufacturer: "MikroTik",
sys_descr: "RouterOS 7.8",
@@ -97,9 +95,54 @@ defmodule ToweropsWeb.DeviceLive.FormTest do
assert html =~ "Edit Device"
assert html =~ device.name
- # MikroTik section SHOULD be visible (superuser + MikroTik device)
+ # MikroTik section SHOULD be visible for all users with MikroTik devices
assert html =~ "MikroTik API Configuration"
end
+
+ test "does not render MikroTik section when device is not MikroTik", %{
+ conn: conn,
+ site: site,
+ organization: organization
+ } do
+ alias Device, as: SnmpDevice
+
+ # Create a device with non-MikroTik SNMP discovery data
+ {:ok, device} =
+ Towerops.Devices.create_device(%{
+ name: "Cisco Switch",
+ ip_address: "192.168.1.253",
+ site_id: site.id,
+ organization_id: organization.id,
+ snmp_enabled: true,
+ snmp_version: "2c",
+ snmp_port: 161,
+ monitoring_enabled: true,
+ check_interval_seconds: 300
+ })
+
+ # Create SNMP device with Cisco manufacturer
+ _snmp_device =
+ %SnmpDevice{}
+ |> SnmpDevice.changeset(%{
+ device_id: device.id,
+ manufacturer: "Cisco Systems",
+ sys_descr: "Cisco IOS",
+ sys_object_id: "1.3.6.1.4.1.9",
+ sys_uptime: 0,
+ sys_name: "test-switch"
+ })
+ |> Towerops.Repo.insert!()
+
+ # Visit edit page
+ {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}/edit")
+
+ # Page should render successfully
+ assert html =~ "Edit Device"
+ assert html =~ device.name
+
+ # MikroTik section SHOULD NOT be visible for non-MikroTik devices
+ refute html =~ "MikroTik API Configuration"
+ end
end
describe "non_routable_ip?/1" do
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 90c47421..29c40dec 100644
--- a/test/towerops_web/live/device_live_nested/show_test.exs
+++ b/test/towerops_web/live/device_live_nested/show_test.exs
@@ -22,7 +22,8 @@ defmodule ToweropsWeb.DeviceLive.ShowTest do
Towerops.Devices.create_device(%{
name: "Test Router",
ip_address: "192.168.1.1",
- site_id: site.id
+ site_id: site.id,
+ organization_id: organization.id
})
%{organization: organization, site: site, device: device}
diff --git a/test/towerops_web/live/graph_live/show_test.exs b/test/towerops_web/live/graph_live/show_test.exs
index 50d535d4..f79a199b 100644
--- a/test/towerops_web/live/graph_live/show_test.exs
+++ b/test/towerops_web/live/graph_live/show_test.exs
@@ -28,6 +28,7 @@ defmodule ToweropsWeb.GraphLive.ShowTest do
name: "Test Router",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
snmp_enabled: true
})
diff --git a/test/towerops_web/live/my_data_live_test.exs b/test/towerops_web/live/my_data_live_test.exs
index 6cb3cdc9..9b8aba55 100644
--- a/test/towerops_web/live/my_data_live_test.exs
+++ b/test/towerops_web/live/my_data_live_test.exs
@@ -31,6 +31,7 @@ defmodule ToweropsWeb.AccountLive.MyDataTest do
name: "Test Device",
ip_address: "192.168.1.1",
site_id: site.id,
+ organization_id: organization.id,
monitoring_enabled: true
})