credo fixes
This commit is contained in:
parent
9c3319050f
commit
d0160f7d8a
109 changed files with 273 additions and 656 deletions
20
.credo.exs
20
.credo.exs
|
|
@ -188,16 +188,16 @@
|
|||
# {:erlang, :binary_to_term, "Use Plug.Crypto.non_executable_binary_to_term/2 instead."}
|
||||
# ]
|
||||
# ]},
|
||||
{Jump.CredoChecks.LiveViewFormCanBeRehydrated}
|
||||
# {Jump.CredoChecks.UndeclaredExternalResource},
|
||||
# {Jump.CredoChecks.PreferChangeOverUpDownMigrations, [start_after: "20250101000000"]},
|
||||
# {Jump.CredoChecks.PreferTextColumns, [start_after: "20250101000000"]},
|
||||
# {Jump.CredoChecks.SafeBinaryToTerm},
|
||||
# {Jump.CredoChecks.TestHasNoAssertions,
|
||||
# [custom_assertion_functions: [:assert_has, :refute_has, :assert_eventually]]},
|
||||
# {Jump.CredoChecks.TooManyAssertions, [max_assertions: 20]},
|
||||
# {Jump.CredoChecks.TopLevelAliasImportRequire},
|
||||
# {Jump.CredoChecks.UnusedLiveViewAssign, [ignored_assigns: [:active_path, :current_scope]]},
|
||||
{Jump.CredoChecks.LiveViewFormCanBeRehydrated},
|
||||
{Jump.CredoChecks.UndeclaredExternalResource},
|
||||
{Jump.CredoChecks.PreferChangeOverUpDownMigrations, [start_after: "20250101000000"]},
|
||||
{Jump.CredoChecks.PreferTextColumns, [start_after: "20250101000000"]},
|
||||
{Jump.CredoChecks.SafeBinaryToTerm},
|
||||
{Jump.CredoChecks.TestHasNoAssertions,
|
||||
[custom_assertion_functions: [:assert_has, :refute_has, :assert_eventually]]},
|
||||
{Jump.CredoChecks.TooManyAssertions, [max_assertions: 20]},
|
||||
{Jump.CredoChecks.TopLevelAliasImportRequire},
|
||||
{Jump.CredoChecks.UnusedLiveViewAssign, [ignored_assigns: [:active_path, :current_scope, :current_token]]}
|
||||
# {Jump.CredoChecks.UseObanProWorker},
|
||||
# {Jump.CredoChecks.VacuousTest,
|
||||
# [
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ defmodule SnmpKit.SnmpLib.ASN1 do
|
|||
|
||||
import Bitwise
|
||||
|
||||
require Logger
|
||||
|
||||
@type tag :: non_neg_integer()
|
||||
@type length :: non_neg_integer()
|
||||
@type content :: binary()
|
||||
|
|
@ -154,8 +156,6 @@ defmodule SnmpKit.SnmpLib.ASN1 do
|
|||
end
|
||||
|
||||
def encode_octet_string(value) when not is_binary(value) do
|
||||
require Logger
|
||||
|
||||
Logger.error("encode_octet_string received non-binary value: #{inspect(value)}")
|
||||
{:error, {:invalid_type, value}}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ defmodule SnmpKit.SnmpMgr.Bulk do
|
|||
alias SnmpKit.SnmpMgr.Core
|
||||
alias SnmpKit.SnmpMgr.Format
|
||||
|
||||
require Logger
|
||||
|
||||
@default_max_repetitions 30
|
||||
@default_non_repeaters 0
|
||||
|
||||
|
|
@ -232,8 +234,6 @@ defmodule SnmpKit.SnmpMgr.Bulk do
|
|||
end
|
||||
|
||||
defp bulk_walk_subtree(target, current_oid, root_oid, acc, remaining, opts) when remaining > 0 do
|
||||
require Logger
|
||||
|
||||
max_repetitions =
|
||||
min(remaining, Keyword.get(opts, :max_repetitions, @default_max_repetitions))
|
||||
|
||||
|
|
@ -290,8 +290,6 @@ defmodule SnmpKit.SnmpMgr.Bulk do
|
|||
end
|
||||
|
||||
defp filter_table_results(results, root_oid) do
|
||||
require Logger
|
||||
|
||||
in_scope_results =
|
||||
Enum.filter(results, fn
|
||||
# Only accept 3-tuple format with proper type information
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ defmodule Towerops.Accounts do
|
|||
alias Towerops.Accounts.UserNotifier
|
||||
alias Towerops.Accounts.UserToken
|
||||
alias Towerops.Admin.AuditLogger
|
||||
alias Towerops.Organizations.Membership
|
||||
alias Towerops.Organizations.Organization
|
||||
alias Towerops.Repo
|
||||
|
||||
require Logger
|
||||
|
|
@ -489,11 +491,8 @@ defmodule Towerops.Accounts do
|
|||
Used to check if a user can safely delete their account without
|
||||
orphaning organizations.
|
||||
"""
|
||||
@spec sole_owner_organizations(String.t()) :: [Towerops.Organizations.Organization.t()]
|
||||
@spec sole_owner_organizations(String.t()) :: [Organization.t()]
|
||||
def sole_owner_organizations(user_id) do
|
||||
alias Towerops.Organizations.Membership
|
||||
alias Towerops.Organizations.Organization
|
||||
|
||||
user_owner_org_ids =
|
||||
Membership
|
||||
|> where([m], m.user_id == ^user_id and m.role == :owner)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,12 @@ defmodule Towerops.Admin do
|
|||
|
||||
alias Towerops.Accounts.User
|
||||
alias Towerops.Admin.AuditLog
|
||||
alias Towerops.Billing
|
||||
alias Towerops.Billing.StripeClient
|
||||
alias Towerops.Organizations.Organization
|
||||
alias Towerops.Repo
|
||||
alias Towerops.Settings
|
||||
alias Towerops.Settings.ApplicationSetting
|
||||
|
||||
require Logger
|
||||
|
||||
|
|
@ -403,11 +407,6 @@ defmodule Towerops.Admin do
|
|||
Returns {:ok, migration_report} or {:error, reason}.
|
||||
"""
|
||||
def update_global_pricing(attrs, superuser_id, ip_address) do
|
||||
alias Towerops.Billing
|
||||
alias Towerops.Billing.StripeClient
|
||||
alias Towerops.Settings
|
||||
alias Towerops.Settings.ApplicationSetting
|
||||
|
||||
with {:ok, validated} <- validate_pricing_attrs(attrs),
|
||||
old_values = get_current_pricing(),
|
||||
{:ok, new_price_id, migration_report} <- maybe_update_stripe_price(validated, old_values),
|
||||
|
|
@ -454,8 +453,6 @@ defmodule Towerops.Admin do
|
|||
end
|
||||
|
||||
defp get_current_pricing do
|
||||
alias Towerops.Settings
|
||||
|
||||
%{
|
||||
free_devices: Settings.get_setting("default_free_devices"),
|
||||
price: Settings.get_setting("default_price_per_device")
|
||||
|
|
@ -463,9 +460,6 @@ defmodule Towerops.Admin do
|
|||
end
|
||||
|
||||
defp maybe_update_stripe_price(validated, old_values) do
|
||||
alias Towerops.Billing
|
||||
alias Towerops.Billing.StripeClient
|
||||
|
||||
price_changed = validated.price && validated.price != old_values.price
|
||||
|
||||
if price_changed do
|
||||
|
|
@ -483,9 +477,6 @@ defmodule Towerops.Admin do
|
|||
end
|
||||
|
||||
defp update_pricing_settings(validated, new_price_id) do
|
||||
alias Towerops.Settings
|
||||
alias Towerops.Settings.ApplicationSetting
|
||||
|
||||
if validated.free_devices do
|
||||
Settings.update_setting("default_free_devices", validated.free_devices)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ defmodule Towerops.Agents do
|
|||
alias Towerops.Agents.AgentTokenQuery
|
||||
alias Towerops.Agents.ReleaseChecker
|
||||
alias Towerops.Devices.Device
|
||||
alias Towerops.Preseem.Insight
|
||||
alias Towerops.Repo
|
||||
|
||||
require Logger
|
||||
|
|
@ -237,8 +238,6 @@ defmodule Towerops.Agents do
|
|||
end
|
||||
|
||||
defp dismiss_agent_offline_insights(agent_token_id) do
|
||||
alias Towerops.Preseem.Insight
|
||||
|
||||
now = Towerops.Time.now()
|
||||
|
||||
{count, _} =
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule Towerops.Billing do
|
|||
Pricing: $2/device/month after first 10 free devices (configurable via ApplicationSettings).
|
||||
"""
|
||||
|
||||
import Ecto.Query, warn: false
|
||||
|
||||
alias Towerops.Billing.StripeClient
|
||||
alias Towerops.Organizations.Organization
|
||||
alias Towerops.Organizations.SubscriptionLimits
|
||||
|
|
@ -240,8 +242,6 @@ defmodule Towerops.Billing do
|
|||
- failures: list of {:error, org, reason} tuples
|
||||
"""
|
||||
def migrate_all_subscriptions_to_price(new_price_id) do
|
||||
import Ecto.Query
|
||||
|
||||
orgs =
|
||||
Repo.all(
|
||||
from o in Organization,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ defmodule Towerops.Coverages.Antenna do
|
|||
|
||||
alias Towerops.Coverages.AntennaCatalog
|
||||
|
||||
require Logger
|
||||
|
||||
@enforce_keys [:slug, :model, :h_pattern, :v_pattern, :gain_dbi]
|
||||
defstruct [
|
||||
:slug,
|
||||
|
|
@ -187,8 +189,6 @@ defmodule Towerops.Coverages.Antenna do
|
|||
Map.put(acc, antenna.slug, antenna)
|
||||
|
||||
{:error, reason} ->
|
||||
require Logger
|
||||
|
||||
Logger.warning("Failed to synthesize antenna #{spec.slug}: #{inspect(reason)}")
|
||||
acc
|
||||
end
|
||||
|
|
@ -314,8 +314,6 @@ defmodule Towerops.Coverages.Antenna do
|
|||
Map.put(acc, slug, antenna)
|
||||
|
||||
{:error, reason} ->
|
||||
require Logger
|
||||
|
||||
Logger.warning("Failed to parse antenna #{filename}: #{inspect(reason)}")
|
||||
acc
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,11 +15,14 @@ defmodule Towerops.Devices do
|
|||
alias Towerops.Organizations
|
||||
alias Towerops.Organizations.Organization
|
||||
alias Towerops.Organizations.SubscriptionLimits
|
||||
alias Towerops.Preseem.Insight
|
||||
alias Towerops.Repo
|
||||
alias Towerops.Sites
|
||||
alias Towerops.Workers.DeviceMonitorWorker
|
||||
alias Towerops.Workers.DiscoveryWorker
|
||||
|
||||
require Logger
|
||||
|
||||
@device_preloads [:organization, site: :organization]
|
||||
|
||||
@doc """
|
||||
|
|
@ -270,8 +273,6 @@ defmodule Towerops.Devices do
|
|||
# Guard against NotLoaded to prevent crashes if association isn't preloaded
|
||||
case device.organization do
|
||||
%Ecto.Association.NotLoaded{} ->
|
||||
require Logger
|
||||
|
||||
Logger.error(
|
||||
"Organization not preloaded for device #{device.id} in get_org_default_agent",
|
||||
device_id: device.id
|
||||
|
|
@ -554,8 +555,6 @@ defmodule Towerops.Devices do
|
|||
* `:bypass_limits` - When true, bypasses subscription device limits (for superusers)
|
||||
"""
|
||||
def create_device(attrs, opts \\ []) do
|
||||
require Logger
|
||||
|
||||
bypass_limits = Keyword.get(opts, :bypass_limits, false)
|
||||
changeset = build_device_changeset(attrs)
|
||||
|
||||
|
|
@ -787,8 +786,6 @@ defmodule Towerops.Devices do
|
|||
|
||||
# Log warning if community is empty
|
||||
defp log_empty_community(device, community) when community in [nil, ""] do
|
||||
require Logger
|
||||
|
||||
Logger.warning("Empty SNMP community resolved for device",
|
||||
device_id: device.id,
|
||||
device_name: device.name,
|
||||
|
|
@ -964,8 +961,6 @@ defmodule Towerops.Devices do
|
|||
end
|
||||
|
||||
defp dismiss_poll_gap_insights(device_id) do
|
||||
alias Towerops.Preseem.Insight
|
||||
|
||||
now = Towerops.Time.now()
|
||||
|
||||
{count, _} =
|
||||
|
|
@ -974,8 +969,6 @@ defmodule Towerops.Devices do
|
|||
|> Repo.update_all(set: [status: "dismissed", dismissed_at: now])
|
||||
|
||||
if count > 0 do
|
||||
require Logger
|
||||
|
||||
Logger.info("Auto-dismissed #{count} poll gap insight(s) for device #{device_id}")
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ defmodule Towerops.Gaiia.Sync do
|
|||
alias Towerops.Gaiia.Client
|
||||
alias Towerops.Gaiia.SubscriberMatching
|
||||
alias Towerops.Integrations
|
||||
alias Towerops.Repo
|
||||
alias Towerops.Sites.Site
|
||||
|
||||
require Logger
|
||||
|
||||
|
|
@ -119,11 +121,6 @@ defmodule Towerops.Gaiia.Sync do
|
|||
end
|
||||
|
||||
defp find_matching_site_id(org_id, gaiia_name) when is_binary(gaiia_name) and gaiia_name != "" do
|
||||
import Ecto.Query
|
||||
|
||||
alias Towerops.Repo
|
||||
alias Towerops.Sites.Site
|
||||
|
||||
search = "%#{Towerops.QueryHelpers.sanitize_like(gaiia_name)}%"
|
||||
|
||||
Repo.one(
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ defmodule Towerops.Monitoring do
|
|||
alias Towerops.Monitoring.CheckResult
|
||||
alias Towerops.Monitoring.MonitoringCheck
|
||||
alias Towerops.Repo
|
||||
alias Towerops.Snmp.SensorReading
|
||||
alias Towerops.Workers.CheckExecutorWorker
|
||||
alias Towerops.Workers.PollingOffset
|
||||
|
||||
## Checks
|
||||
|
|
@ -254,8 +256,6 @@ defmodule Towerops.Monitoring do
|
|||
Queues a CheckExecutorWorker job with polling offset to distribute load.
|
||||
"""
|
||||
def schedule_check(%Check{} = check) do
|
||||
alias Towerops.Workers.CheckExecutorWorker
|
||||
|
||||
offset = PollingOffset.calculate_offset(check.id, check.interval_seconds)
|
||||
|
||||
%{check_id: check.id}
|
||||
|
|
@ -355,7 +355,6 @@ defmodule Towerops.Monitoring do
|
|||
# If SNMP check with source_id, also query old snmp_sensor_readings for backfill
|
||||
historical_results =
|
||||
if check.check_type == "snmp_sensor" && check.source_id do
|
||||
alias Towerops.Snmp.SensorReading
|
||||
# Find earliest check_result timestamp to avoid overlap
|
||||
earliest_check_result =
|
||||
recent_results
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ defmodule Towerops.Preseem do
|
|||
|
||||
import Ecto.Query
|
||||
|
||||
alias Towerops.Devices
|
||||
alias Towerops.Preseem.AccessPoint
|
||||
alias Towerops.Preseem.Insights
|
||||
alias Towerops.Preseem.SubscriberMetric
|
||||
|
|
@ -126,8 +127,6 @@ defmodule Towerops.Preseem do
|
|||
Returns a map with average QoE, latency, capacity info, and per-AP breakdowns.
|
||||
"""
|
||||
def get_site_qoe_summary(site_id) do
|
||||
alias Towerops.Devices
|
||||
|
||||
device_ids =
|
||||
site_id
|
||||
|> Devices.list_site_devices()
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ defmodule Towerops.Preseem.FleetIntelligence do
|
|||
alias Towerops.Preseem.FleetProfile
|
||||
alias Towerops.Repo
|
||||
|
||||
require Logger
|
||||
|
||||
@doc "Compute fleet profiles for all matched APs in an organization."
|
||||
def compute_fleet_profiles(organization_id) do
|
||||
require Logger
|
||||
|
||||
now = Towerops.Time.now()
|
||||
|
||||
matched_aps =
|
||||
|
|
@ -94,8 +94,6 @@ defmodule Towerops.Preseem.FleetIntelligence do
|
|||
# PostgreSQL treats NULLs as distinct in unique indexes, so ON CONFLICT won't match
|
||||
# rows with NULL firmware_version. Ecto's get_by also rejects nil values.
|
||||
defp upsert_fleet_profile(organization_id, attrs) do
|
||||
require Logger
|
||||
|
||||
full_attrs = Map.put(attrs, :organization_id, organization_id)
|
||||
|
||||
existing =
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ defmodule Towerops.Preseem.Sync do
|
|||
alias Towerops.Preseem.AccessPoint
|
||||
alias Towerops.Preseem.Client
|
||||
alias Towerops.Preseem.DeviceMatcher
|
||||
alias Towerops.Preseem.SubscriberMetric
|
||||
alias Towerops.Preseem.SyncLog
|
||||
alias Towerops.Repo
|
||||
|
||||
|
|
@ -75,8 +76,6 @@ defmodule Towerops.Preseem.Sync do
|
|||
Inserts a subscriber metric record for the given access point.
|
||||
"""
|
||||
def insert_metrics(access_point_id, metrics_data) do
|
||||
alias Towerops.Preseem.SubscriberMetric
|
||||
|
||||
recorded_at =
|
||||
case metrics_data["recorded_at"] do
|
||||
nil -> Towerops.Time.now()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ defmodule Towerops.Proto.TupleDecode do
|
|||
Converts Elixir structs to tagged tuples for backward compatibility.
|
||||
"""
|
||||
|
||||
alias Towerops.Agent.AgentJob
|
||||
alias Towerops.Agent.MikrotikCommand
|
||||
alias Towerops.Agent.MikrotikDevice
|
||||
alias Towerops.Agent.SnmpDevice
|
||||
|
|
@ -211,8 +212,6 @@ defmodule Towerops.Proto.TupleDecode do
|
|||
|
||||
# Convert from Types.AgentJob to Agent.AgentJob
|
||||
defp types_job_to_agent_job(%Types.AgentJob{} = j) do
|
||||
alias Towerops.Agent.AgentJob
|
||||
|
||||
%AgentJob{
|
||||
job_id: j.job_id,
|
||||
job_type: j.job_type,
|
||||
|
|
|
|||
|
|
@ -138,8 +138,6 @@ defmodule Towerops.Snmp do
|
|||
end
|
||||
|
||||
defp create_sensor_check(device, sensor) do
|
||||
alias Towerops.Monitoring
|
||||
|
||||
attrs = %{
|
||||
organization_id: device.organization_id,
|
||||
device_id: device.id,
|
||||
|
|
@ -156,10 +154,10 @@ defmodule Towerops.Snmp do
|
|||
}
|
||||
}
|
||||
|
||||
case Monitoring.create_check(attrs) do
|
||||
case Towerops.Monitoring.create_check(attrs) do
|
||||
{:ok, check} ->
|
||||
# Schedule first execution
|
||||
_ = Monitoring.schedule_check(check)
|
||||
_ = Towerops.Monitoring.schedule_check(check)
|
||||
{:ok, check}
|
||||
|
||||
error ->
|
||||
|
|
@ -168,8 +166,6 @@ defmodule Towerops.Snmp do
|
|||
end
|
||||
|
||||
defp create_interface_check(device, interface) do
|
||||
alias Towerops.Monitoring
|
||||
|
||||
name = interface.if_alias || interface.if_name || interface.if_descr || "Interface #{interface.if_index}"
|
||||
|
||||
attrs = %{
|
||||
|
|
@ -187,9 +183,9 @@ defmodule Towerops.Snmp do
|
|||
}
|
||||
}
|
||||
|
||||
case Monitoring.create_check(attrs) do
|
||||
case Towerops.Monitoring.create_check(attrs) do
|
||||
{:ok, check} ->
|
||||
_ = Monitoring.schedule_check(check)
|
||||
_ = Towerops.Monitoring.schedule_check(check)
|
||||
{:ok, check}
|
||||
|
||||
error ->
|
||||
|
|
@ -198,8 +194,6 @@ defmodule Towerops.Snmp do
|
|||
end
|
||||
|
||||
defp create_processor_check(device, processor) do
|
||||
alias Towerops.Monitoring
|
||||
|
||||
attrs = %{
|
||||
organization_id: device.organization_id,
|
||||
device_id: device.id,
|
||||
|
|
@ -215,9 +209,9 @@ defmodule Towerops.Snmp do
|
|||
}
|
||||
}
|
||||
|
||||
case Monitoring.create_check(attrs) do
|
||||
case Towerops.Monitoring.create_check(attrs) do
|
||||
{:ok, check} ->
|
||||
_ = Monitoring.schedule_check(check)
|
||||
_ = Towerops.Monitoring.schedule_check(check)
|
||||
{:ok, check}
|
||||
|
||||
error ->
|
||||
|
|
@ -226,8 +220,6 @@ defmodule Towerops.Snmp do
|
|||
end
|
||||
|
||||
defp create_storage_check(device, storage) do
|
||||
alias Towerops.Monitoring
|
||||
|
||||
name = storage.description || storage.device_name || "Storage #{storage.storage_index}"
|
||||
|
||||
attrs = %{
|
||||
|
|
@ -245,9 +237,9 @@ defmodule Towerops.Snmp do
|
|||
}
|
||||
}
|
||||
|
||||
case Monitoring.create_check(attrs) do
|
||||
case Towerops.Monitoring.create_check(attrs) do
|
||||
{:ok, check} ->
|
||||
_ = Monitoring.schedule_check(check)
|
||||
_ = Towerops.Monitoring.schedule_check(check)
|
||||
{:ok, check}
|
||||
|
||||
error ->
|
||||
|
|
|
|||
|
|
@ -27,12 +27,15 @@ defmodule Towerops.Snmp.Discovery do
|
|||
alias Towerops.Snmp.EntityPhysical
|
||||
alias Towerops.Snmp.Interface
|
||||
alias Towerops.Snmp.IpAddress
|
||||
alias Towerops.Snmp.Mempool
|
||||
alias Towerops.Snmp.NeighborDiscovery
|
||||
alias Towerops.Snmp.PrinterSupply
|
||||
alias Towerops.Snmp.Processor
|
||||
alias Towerops.Snmp.Profiles.Base
|
||||
alias Towerops.Snmp.Profiles.Dynamic
|
||||
alias Towerops.Snmp.Sensor
|
||||
alias Towerops.Snmp.Storage
|
||||
alias Towerops.Snmp.Transceiver
|
||||
alias Towerops.Snmp.Vlan
|
||||
# alias Towerops.Topology # Commented out - auto-inference disabled
|
||||
alias Towerops.Workers.DiscoveryWorker
|
||||
|
|
@ -1387,8 +1390,6 @@ defmodule Towerops.Snmp.Discovery do
|
|||
Sync memory pools from discovery/polling results to database.
|
||||
"""
|
||||
def sync_mempools(device, discovered_mempools) do
|
||||
alias Towerops.Snmp.Mempool
|
||||
|
||||
# Get existing mempools for this device, indexed by mempool_index
|
||||
existing_mempools =
|
||||
from(m in Mempool, where: m.snmp_device_id == ^device.id)
|
||||
|
|
@ -1463,8 +1464,6 @@ defmodule Towerops.Snmp.Discovery do
|
|||
Creates, updates, or deletes transceiver entries to match discovered state.
|
||||
"""
|
||||
def sync_transceivers(snmp_device, discovered_transceivers) do
|
||||
alias Towerops.Snmp.Transceiver
|
||||
|
||||
# Get existing transceivers for this device, indexed by port_index
|
||||
existing_transceivers =
|
||||
from(t in Transceiver, where: t.snmp_device_id == ^snmp_device.id)
|
||||
|
|
@ -1521,8 +1520,6 @@ defmodule Towerops.Snmp.Discovery do
|
|||
- Deletes supplies that are no longer discovered
|
||||
"""
|
||||
def sync_printer_supplies(snmp_device, discovered_supplies) do
|
||||
alias Towerops.Snmp.PrinterSupply
|
||||
|
||||
# Get existing supplies for this device, indexed by supply_index
|
||||
existing_supplies =
|
||||
from(s in PrinterSupply, where: s.snmp_device_id == ^snmp_device.id)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ defmodule Towerops.Snmp.Profiles.Dynamic do
|
|||
|
||||
alias Towerops.Snmp.Client
|
||||
alias Towerops.Snmp.Discovery
|
||||
alias Towerops.Snmp.Profiles.Base
|
||||
alias Towerops.Snmp.Profiles.Vendors.Arista
|
||||
alias Towerops.Snmp.Profiles.Vendors.Powervault
|
||||
alias Towerops.Snmp.Profiles.Vendors.Registry, as: VendorRegistry
|
||||
|
||||
require Logger
|
||||
|
|
@ -66,8 +69,6 @@ defmodule Towerops.Snmp.Profiles.Dynamic do
|
|||
@spec discover_sensors(map(), Client.connection_opts()) ::
|
||||
{:ok, [Discovery.sensor_data()]}
|
||||
def discover_sensors(profile, client_opts) do
|
||||
alias Towerops.Snmp.Profiles.Base
|
||||
|
||||
# Always discover ENTITY-SENSOR-MIB sensors (most devices support this)
|
||||
{:ok, base_sensors} = Base.discover_sensors(client_opts)
|
||||
|
||||
|
|
@ -119,8 +120,6 @@ defmodule Towerops.Snmp.Profiles.Dynamic do
|
|||
@spec discover_interfaces(map(), Client.connection_opts()) ::
|
||||
{:ok, [Discovery.interface_data()]}
|
||||
def discover_interfaces(_profile, client_opts) do
|
||||
alias Towerops.Snmp.Profiles.Base
|
||||
|
||||
Base.discover_interfaces(client_opts)
|
||||
end
|
||||
|
||||
|
|
@ -540,20 +539,14 @@ defmodule Towerops.Snmp.Profiles.Dynamic do
|
|||
case name do
|
||||
"arista_eos" ->
|
||||
# Apply Arista-specific enhancements
|
||||
alias Towerops.Snmp.Profiles.Vendors.Arista
|
||||
|
||||
Arista.post_process_sensors(sensors, client_opts)
|
||||
|
||||
"arista-mos" ->
|
||||
# Apply Arista-specific enhancements
|
||||
alias Towerops.Snmp.Profiles.Vendors.Arista
|
||||
|
||||
Arista.post_process_sensors(sensors, client_opts)
|
||||
|
||||
"dell-powervault" ->
|
||||
# Parse text-based sensor messages from FCMGMT-MIB
|
||||
alias Towerops.Snmp.Profiles.Vendors.Powervault
|
||||
|
||||
Powervault.post_process_sensors(sensors, client_opts)
|
||||
|
||||
_ ->
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ defmodule Towerops.Workers.AlertDigestWorker do
|
|||
queue: :notifications,
|
||||
max_attempts: 3
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
alias Towerops.Alerts
|
||||
alias Towerops.Alerts.NotificationRateLimiter
|
||||
|
||||
|
|
@ -19,7 +21,6 @@ defmodule Towerops.Workers.AlertDigestWorker do
|
|||
@impl Oban.Worker
|
||||
def perform(%Oban.Job{args: %{"user_id" => "__cron__"}}) do
|
||||
# Cron mode: find all pending digests and enqueue delivery
|
||||
import Ecto.Query
|
||||
|
||||
pending =
|
||||
Towerops.Repo.all(
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ defmodule Towerops.Workers.CheckWorker do
|
|||
states: [:available, :scheduled, :executing, :retryable, :suspended]
|
||||
]
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
alias Towerops.Agents
|
||||
alias Towerops.Alerts
|
||||
alias Towerops.Monitoring
|
||||
|
|
@ -114,8 +116,6 @@ defmodule Towerops.Workers.CheckWorker do
|
|||
Stops executing a check by cancelling its jobs.
|
||||
"""
|
||||
def stop_check(check_id) do
|
||||
import Ecto.Query
|
||||
|
||||
Oban.cancel_all_jobs(
|
||||
from(j in Oban.Job,
|
||||
where: j.worker == "Towerops.Workers.CheckWorker",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ defmodule Towerops.Workers.DeviceMonitorWorker do
|
|||
available: [:scheduled_at]
|
||||
]
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
alias Towerops.Agents
|
||||
alias Towerops.Alerts
|
||||
alias Towerops.Alerts.StormDetector
|
||||
|
|
@ -105,8 +107,6 @@ defmodule Towerops.Workers.DeviceMonitorWorker do
|
|||
Stops monitoring for a device by cancelling its jobs.
|
||||
"""
|
||||
def stop_monitoring(device_id) do
|
||||
import Ecto.Query
|
||||
|
||||
Oban.cancel_all_jobs(
|
||||
from(j in Oban.Job,
|
||||
where: j.worker == "Towerops.Workers.DeviceMonitorWorker",
|
||||
|
|
@ -227,8 +227,6 @@ defmodule Towerops.Workers.DeviceMonitorWorker do
|
|||
:ok
|
||||
|
||||
{:error, reason} ->
|
||||
require Logger
|
||||
|
||||
Logger.error("Failed to create device up alert for #{device.name}: #{inspect(reason)}",
|
||||
device_id: device.id
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ defmodule Towerops.Workers.DevicePollerWorker do
|
|||
available: [:scheduled_at]
|
||||
]
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
alias Towerops.Agents
|
||||
alias Towerops.Devices
|
||||
alias Towerops.Gaiia.SubscriberMatching
|
||||
|
|
@ -129,8 +131,6 @@ defmodule Towerops.Workers.DevicePollerWorker do
|
|||
Stops polling for a device by cancelling its jobs.
|
||||
"""
|
||||
def stop_polling(device_id) do
|
||||
import Ecto.Query
|
||||
|
||||
Oban.cancel_all_jobs(
|
||||
from(j in Oban.Job,
|
||||
where: j.worker == "Towerops.Workers.DevicePollerWorker",
|
||||
|
|
|
|||
|
|
@ -8,9 +8,15 @@ defmodule Towerops.Workers.GaiiaInsightWorker do
|
|||
use Oban.Worker, queue: :maintenance
|
||||
use Gettext, backend: ToweropsWeb.Gettext
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
alias Towerops.Gaiia.Reconciliation
|
||||
alias Towerops.Integrations
|
||||
alias Towerops.Preseem.Insight
|
||||
alias Towerops.Preseem.Insights
|
||||
alias Towerops.Repo
|
||||
|
||||
require Logger
|
||||
|
||||
@impl Oban.Worker
|
||||
def perform(%Oban.Job{}) do
|
||||
|
|
@ -39,11 +45,6 @@ defmodule Towerops.Workers.GaiiaInsightWorker do
|
|||
defp maybe_dismiss_resolved_insights(organization_id, dedup_key, current_items) do
|
||||
# If the issue is resolved (no items), dismiss any active insights
|
||||
if Enum.empty?(current_items) do
|
||||
import Ecto.Query
|
||||
|
||||
alias Towerops.Preseem.Insight
|
||||
alias Towerops.Repo
|
||||
|
||||
now = Towerops.Time.now()
|
||||
|
||||
{count, _} =
|
||||
|
|
@ -57,8 +58,6 @@ defmodule Towerops.Workers.GaiiaInsightWorker do
|
|||
|> Repo.update_all(set: [status: "dismissed", dismissed_at: now])
|
||||
|
||||
if count > 0 do
|
||||
require Logger
|
||||
|
||||
Logger.info(
|
||||
"Auto-dismissed #{count} reconciliation_finding insight(s) for #{dedup_key} in org #{organization_id}"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ defmodule ToweropsNative do
|
|||
- Throughput: ~50,000-100,000 resolutions/second per core
|
||||
"""
|
||||
|
||||
require Logger
|
||||
|
||||
@on_load :load_nif
|
||||
|
||||
def load_nif do
|
||||
|
|
@ -22,8 +24,6 @@ defmodule ToweropsNative do
|
|||
:ok
|
||||
|
||||
{:error, _reason} ->
|
||||
require Logger
|
||||
|
||||
Logger.warning("ToweropsNative NIF not available, using stubs")
|
||||
:ok
|
||||
end
|
||||
|
|
|
|||
|
|
@ -50,7 +50,11 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
alias Towerops.Monitoring
|
||||
alias Towerops.Snmp
|
||||
alias Towerops.Snmp.AgentDiscovery
|
||||
alias Towerops.Snmp.ArpDiscovery
|
||||
alias Towerops.Snmp.Discovery
|
||||
alias Towerops.Snmp.MacDiscovery
|
||||
alias Towerops.Snmp.NeighborDiscovery
|
||||
alias Towerops.Snmp.Profiles.Base, as: SnmpProfiles
|
||||
alias Towerops.Snmp.SensorChangeDetector
|
||||
alias Towerops.Snmp.SensorScale
|
||||
alias Towerops.Topology
|
||||
|
|
@ -2042,11 +2046,6 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
|
||||
Task.Supervisor.start_child(Towerops.TaskSupervisor, fn ->
|
||||
try do
|
||||
alias Towerops.Snmp.ArpDiscovery
|
||||
alias Towerops.Snmp.MacDiscovery
|
||||
alias Towerops.Snmp.NeighborDiscovery
|
||||
alias Towerops.Snmp.Profiles.Base
|
||||
|
||||
# Fetch interfaces once for reuse across multiple operations
|
||||
interfaces = Snmp.list_interfaces(snmp_device_id)
|
||||
|
||||
|
|
@ -2082,8 +2081,6 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
end
|
||||
|
||||
defp process_neighbors(client_opts, device_id, interfaces_with_device_id) do
|
||||
alias Towerops.Snmp.NeighborDiscovery
|
||||
|
||||
case NeighborDiscovery.discover_neighbors(client_opts, interfaces_with_device_id) do
|
||||
{:ok, neighbors} when neighbors != [] ->
|
||||
Discovery.save_neighbors(device_id, neighbors)
|
||||
|
|
@ -2094,8 +2091,6 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
end
|
||||
|
||||
defp process_arp_entries(client_opts, device_id, interfaces) do
|
||||
alias Towerops.Snmp.ArpDiscovery
|
||||
|
||||
case ArpDiscovery.discover_arp_table(client_opts) do
|
||||
{:ok, arp_entries} when arp_entries != [] ->
|
||||
Discovery.save_arp_entries(device_id, arp_entries, interfaces)
|
||||
|
|
@ -2106,8 +2101,6 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
end
|
||||
|
||||
defp process_mac_addresses(client_opts, device_id, interfaces) do
|
||||
alias Towerops.Snmp.MacDiscovery
|
||||
|
||||
case MacDiscovery.discover_mac_table(client_opts) do
|
||||
{:ok, mac_addresses} when mac_addresses != [] ->
|
||||
Snmp.upsert_mac_addresses(device_id, mac_addresses, interfaces)
|
||||
|
|
@ -2118,9 +2111,7 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
end
|
||||
|
||||
defp process_ip_addresses(client_opts, device_id, interfaces) do
|
||||
alias Towerops.Snmp.Profiles.Base
|
||||
|
||||
case Base.discover_all_ip_addresses(client_opts) do
|
||||
case SnmpProfiles.discover_all_ip_addresses(client_opts) do
|
||||
{:ok, ip_addresses} when ip_addresses != [] ->
|
||||
discovered_device = %{
|
||||
device_id: device_id,
|
||||
|
|
@ -2135,9 +2126,7 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
end
|
||||
|
||||
defp process_processors(client_opts, snmp_device_id) do
|
||||
alias Towerops.Snmp.Profiles.Base
|
||||
|
||||
case Base.discover_processors(client_opts) do
|
||||
case SnmpProfiles.discover_processors(client_opts) do
|
||||
{:ok, processors} when processors != [] ->
|
||||
discovered_device = %{id: snmp_device_id}
|
||||
Discovery.sync_processors(discovered_device, processors)
|
||||
|
|
@ -2148,9 +2137,7 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
end
|
||||
|
||||
defp process_storage(client_opts, snmp_device_id) do
|
||||
alias Towerops.Snmp.Profiles.Base
|
||||
|
||||
case Base.discover_storage(client_opts) do
|
||||
case SnmpProfiles.discover_storage(client_opts) do
|
||||
{:ok, storage} when storage != [] ->
|
||||
discovered_device = %{id: snmp_device_id}
|
||||
Discovery.sync_storage(discovered_device, storage)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ defmodule ToweropsWeb.Layouts do
|
|||
alias ToweropsWeb.Components.CookieConsent
|
||||
alias ToweropsWeb.Helpers.StatusHelpers
|
||||
alias ToweropsWeb.Live.Components.GlobalSearchComponent
|
||||
alias ToweropsWeb.TimeHelpers
|
||||
|
||||
# Embed all files in layouts/* within this module.
|
||||
# The default root.html.heex file contains the HTML
|
||||
|
|
@ -988,8 +989,6 @@ defmodule ToweropsWeb.Layouts do
|
|||
attr :timezone, :string, default: "UTC"
|
||||
|
||||
def footer(assigns) do
|
||||
alias ToweropsWeb.TimeHelpers
|
||||
|
||||
build_time = Towerops.Application.build_timestamp()
|
||||
timezone = Map.get(assigns, :timezone, "UTC")
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,12 @@ defmodule ToweropsWeb.AdminController do
|
|||
"""
|
||||
use ToweropsWeb, :controller
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
alias ToweropsWeb.UserAuth
|
||||
|
||||
require Logger
|
||||
|
||||
@doc """
|
||||
Start impersonating a user.
|
||||
"""
|
||||
|
|
@ -30,10 +34,6 @@ defmodule ToweropsWeb.AdminController do
|
|||
POST /admin/oban/flush?states=scheduled,retryable
|
||||
"""
|
||||
def flush_oban(conn, %{"states" => states_param}) do
|
||||
import Ecto.Query
|
||||
|
||||
require Logger
|
||||
|
||||
valid_states = ~w(scheduled retryable available)
|
||||
requested = states_param |> String.split(",") |> Enum.map(&String.trim/1)
|
||||
states = Enum.filter(requested, &(&1 in valid_states))
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ defmodule ToweropsWeb.Api.V1.CoveragesController do
|
|||
|
||||
alias Towerops.Coverages
|
||||
|
||||
require Logger
|
||||
|
||||
@doc """
|
||||
GET /api/v1/coverages
|
||||
|
||||
|
|
@ -199,8 +201,6 @@ defmodule ToweropsWeb.Api.V1.CoveragesController do
|
|||
|> json(%{error: "Coverage is not ready yet"})
|
||||
|
||||
{:error, reason} ->
|
||||
require Logger
|
||||
|
||||
# Log the underlying reason server-side so we can debug, but don't
|
||||
# leak filesystem paths / zip errors / IO details to the caller.
|
||||
Logger.error("Failed to build KMZ for coverage: #{inspect(reason)}")
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ defmodule ToweropsWeb.Api.V1.EscalationPoliciesController do
|
|||
alias ToweropsWeb.Api.ParamFilter
|
||||
alias ToweropsWeb.ScopedResource
|
||||
|
||||
require Logger
|
||||
|
||||
# --- Policy CRUD ---
|
||||
|
||||
@doc "GET /api/v1/escalation_policies"
|
||||
|
|
@ -238,8 +240,6 @@ defmodule ToweropsWeb.Api.V1.EscalationPoliciesController do
|
|||
json(conn, %{success: true})
|
||||
|
||||
{:error, reason} ->
|
||||
require Logger
|
||||
|
||||
Logger.error("Failed to delete escalation target #{target_id}: #{inspect(reason)}")
|
||||
conn |> put_status(:internal_server_error) |> json(%{error: "Failed to delete escalation target"})
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule ToweropsWeb.HealthController do
|
|||
alias Ecto.Adapters.SQL
|
||||
alias Towerops.Repo
|
||||
|
||||
require Logger
|
||||
|
||||
# Liveness probe: confirms the BEAM/web stack is responsive. Deliberately does
|
||||
# NOT touch the database or redis — liveness failure causes k8s to kill the
|
||||
# pod, so it must not react to transient dependency outages. Dependency health
|
||||
|
|
@ -18,8 +20,6 @@ defmodule ToweropsWeb.HealthController do
|
|||
end
|
||||
|
||||
def index(conn, _params) do
|
||||
require Logger
|
||||
|
||||
db_status = check_database()
|
||||
redis_status = check_redis()
|
||||
|
||||
|
|
@ -61,8 +61,6 @@ defmodule ToweropsWeb.HealthController do
|
|||
end
|
||||
|
||||
defp check_redis do
|
||||
require Logger
|
||||
|
||||
redis_config = Application.get_env(:towerops, :redis, [])
|
||||
|
||||
if Keyword.has_key?(redis_config, :host) do
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do
|
|||
|
||||
alias Towerops.Accounts
|
||||
|
||||
require Logger
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
require Logger
|
||||
|
||||
user = socket.assigns.current_scope.user
|
||||
|
||||
# If user already has TOTP enabled, redirect them
|
||||
|
|
@ -45,9 +45,7 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do
|
|||
|> assign(:page_title, t("Set Up Two-Factor Authentication"))
|
||||
|> assign(:secret_base32, secret_base32)
|
||||
|> assign(:qr_code, qr_code)
|
||||
|> assign(:code, "")
|
||||
|> assign(:error, nil)
|
||||
|> assign(:enrollment_complete, false)
|
||||
|> assign(:recovery_codes, [])
|
||||
|> assign(:show_recovery_codes, false)
|
||||
|
||||
|
|
@ -60,9 +58,7 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do
|
|||
|> assign(:page_title, t("Set Up Two-Factor Authentication"))
|
||||
|> assign(:secret_base32, nil)
|
||||
|> assign(:qr_code, nil)
|
||||
|> assign(:code, "")
|
||||
|> assign(:error, nil)
|
||||
|> assign(:enrollment_complete, false)
|
||||
|> assign(:recovery_codes, [])
|
||||
|> assign(:show_recovery_codes, false)
|
||||
|
||||
|
|
@ -73,8 +69,6 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do
|
|||
|
||||
@impl true
|
||||
def handle_event("verify_code", %{"code" => code}, socket) do
|
||||
require Logger
|
||||
|
||||
user = socket.assigns.current_scope.user
|
||||
secret_base32 = socket.assigns.secret_base32
|
||||
|
||||
|
|
@ -123,7 +117,6 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do
|
|||
# Show recovery codes to user - they can only be displayed once
|
||||
{:noreply,
|
||||
socket
|
||||
|> assign(:enrollment_complete, true)
|
||||
|> assign(:recovery_codes, codes)
|
||||
|> assign(:show_recovery_codes, true)}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,10 +31,7 @@ defmodule ToweropsWeb.Admin.MonitoringLive do
|
|||
|> assign(:active_jobs, [])
|
||||
|> assign(:executing_jobs, [])
|
||||
|> assign(:stuck_jobs, [])
|
||||
|> assign(:stuck_jobs_count, 0)
|
||||
|> assign(:failed_jobs, [])
|
||||
|> assign(:failed_jobs_count, 0)
|
||||
|> assign(:recent_jobs, [])
|
||||
|> assign(:recent_events, [])
|
||||
|> assign(:metrics, %{})
|
||||
|> assign(:health_metrics, %{})
|
||||
|
|
@ -77,10 +74,7 @@ defmodule ToweropsWeb.Admin.MonitoringLive do
|
|||
socket
|
||||
|> assign(:executing_jobs, executing_jobs)
|
||||
|> assign(:stuck_jobs, stuck_jobs)
|
||||
|> assign(:stuck_jobs_count, length(stuck_jobs))
|
||||
|> assign(:failed_jobs, failed_jobs)
|
||||
|> assign(:failed_jobs_count, length(failed_jobs))
|
||||
|> assign(:recent_jobs, recent_jobs)
|
||||
|> assign(:recent_events, recent_jobs)
|
||||
|> assign(:metrics, metrics)
|
||||
|> assign(:health_metrics, metrics)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ defmodule ToweropsWeb.Admin.OrgLive.Index do
|
|||
alias Towerops.Admin
|
||||
alias Towerops.Billing
|
||||
alias Towerops.Organizations.Organization
|
||||
alias Towerops.Repo
|
||||
|
||||
on_mount {ToweropsWeb.UserAuth, :require_superuser}
|
||||
|
||||
|
|
@ -262,8 +263,6 @@ defmodule ToweropsWeb.Admin.OrgLive.Index do
|
|||
end
|
||||
|
||||
defp count_active_subscriptions do
|
||||
alias Towerops.Repo
|
||||
|
||||
Repo.one(
|
||||
from o in Organization,
|
||||
where: o.subscription_status == "active" and not is_nil(o.stripe_subscription_id),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ defmodule ToweropsWeb.AgentLive.Index do
|
|||
|
||||
alias Towerops.Accounts.Scope
|
||||
alias Towerops.Agents
|
||||
alias Towerops.Agents.Stats
|
||||
alias Towerops.Settings
|
||||
|
||||
@impl true
|
||||
|
|
@ -45,11 +44,6 @@ defmodule ToweropsWeb.AgentLive.Index do
|
|||
%{}
|
||||
end
|
||||
|
||||
# Get organization-wide agent health statistics
|
||||
agent_health_stats = Stats.get_organization_agent_health(organization.id)
|
||||
assignment_breakdown = Stats.get_device_assignment_breakdown(organization.id)
|
||||
offline_agents = Stats.get_offline_agents(organization.id)
|
||||
|
||||
# Get agent image URL from config or use default
|
||||
agent_image =
|
||||
Application.get_env(
|
||||
|
|
@ -72,9 +66,6 @@ defmodule ToweropsWeb.AgentLive.Index do
|
|||
|> assign(:selected_global_default, global_default_cloud_poller_id || "")
|
||||
|> assign(:device_counts, equipment_counts)
|
||||
|> assign(:cloud_poller_counts, cloud_poller_counts)
|
||||
|> assign(:agent_health_stats, agent_health_stats)
|
||||
|> assign(:assignment_breakdown, assignment_breakdown)
|
||||
|> assign(:offline_agents, offline_agents)
|
||||
|> assign(:agent_image, agent_image)
|
||||
|> assign(:new_token, nil)
|
||||
|> assign(:show_token_modal, false)
|
||||
|
|
@ -223,10 +214,6 @@ defmodule ToweropsWeb.AgentLive.Index do
|
|||
equipment_counts = calculate_device_counts(agent_tokens)
|
||||
cloud_poller_counts = calculate_device_counts(cloud_pollers)
|
||||
|
||||
agent_health_stats = Stats.get_organization_agent_health(organization.id)
|
||||
assignment_breakdown = Stats.get_device_assignment_breakdown(organization.id)
|
||||
offline_agents = Stats.get_offline_agents(organization.id)
|
||||
|
||||
success_message = get_success_message(is_cloud_poller)
|
||||
|
||||
{:noreply,
|
||||
|
|
@ -238,9 +225,6 @@ defmodule ToweropsWeb.AgentLive.Index do
|
|||
|> assign(:has_cloud_pollers, cloud_pollers != [])
|
||||
|> assign(:device_counts, equipment_counts)
|
||||
|> assign(:cloud_poller_counts, cloud_poller_counts)
|
||||
|> assign(:agent_health_stats, agent_health_stats)
|
||||
|> assign(:assignment_breakdown, assignment_breakdown)
|
||||
|> assign(:offline_agents, offline_agents)
|
||||
|> assign(:new_token, %{agent_token: agent_token, token: token})
|
||||
|> assign(:agent_form, to_form(%{"name" => "", "is_cloud_poller" => false}))
|
||||
|> put_flash(:info, success_message)
|
||||
|
|
@ -338,10 +322,6 @@ defmodule ToweropsWeb.AgentLive.Index do
|
|||
equipment_counts = calculate_device_counts(agent_tokens)
|
||||
cloud_poller_counts = calculate_device_counts(cloud_pollers)
|
||||
|
||||
agent_health_stats = Stats.get_organization_agent_health(organization.id)
|
||||
assignment_breakdown = Stats.get_device_assignment_breakdown(organization.id)
|
||||
offline_agents = Stats.get_offline_agents(organization.id)
|
||||
|
||||
socket
|
||||
|> stream(:agent_tokens, agent_tokens, reset: true)
|
||||
|> assign(:has_agents, agent_tokens != [])
|
||||
|
|
@ -350,9 +330,6 @@ defmodule ToweropsWeb.AgentLive.Index do
|
|||
|> assign(:has_cloud_pollers, cloud_pollers != [])
|
||||
|> assign(:device_counts, equipment_counts)
|
||||
|> assign(:cloud_poller_counts, cloud_poller_counts)
|
||||
|> assign(:agent_health_stats, agent_health_stats)
|
||||
|> assign(:assignment_breakdown, assignment_breakdown)
|
||||
|> assign(:offline_agents, offline_agents)
|
||||
end
|
||||
|
||||
defp maybe_update_agent(socket, agent_token_id, organization_id) do
|
||||
|
|
@ -388,14 +365,7 @@ defmodule ToweropsWeb.AgentLive.Index do
|
|||
end
|
||||
|
||||
defp update_health_stats(socket) do
|
||||
organization = socket.assigns.current_scope.organization
|
||||
|
||||
agent_health_stats = Stats.get_organization_agent_health(organization.id)
|
||||
offline_agents = Stats.get_offline_agents(organization.id)
|
||||
|
||||
socket
|
||||
|> assign(:agent_health_stats, agent_health_stats)
|
||||
|> assign(:offline_agents, offline_agents)
|
||||
end
|
||||
|
||||
defp agent_authorized_for_deletion?(socket, agent_token) do
|
||||
|
|
@ -429,10 +399,6 @@ defmodule ToweropsWeb.AgentLive.Index do
|
|||
equipment_counts = calculate_device_counts(agent_tokens)
|
||||
cloud_poller_counts = calculate_device_counts(cloud_pollers)
|
||||
|
||||
agent_health_stats = Stats.get_organization_agent_health(organization.id)
|
||||
assignment_breakdown = Stats.get_device_assignment_breakdown(organization.id)
|
||||
offline_agents = Stats.get_offline_agents(organization.id)
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> stream(:agent_tokens, agent_tokens, reset: true)
|
||||
|
|
@ -444,9 +410,6 @@ defmodule ToweropsWeb.AgentLive.Index do
|
|||
|> assign(:selected_global_default, global_default_cloud_poller_id || "")
|
||||
|> assign(:device_counts, equipment_counts)
|
||||
|> assign(:cloud_poller_counts, cloud_poller_counts)
|
||||
|> assign(:agent_health_stats, agent_health_stats)
|
||||
|> assign(:assignment_breakdown, assignment_breakdown)
|
||||
|> assign(:offline_agents, offline_agents)
|
||||
|> put_flash(
|
||||
:info,
|
||||
t_equipment("Agent deleted successfully. Devices now fall back to site/org defaults or cloud polling.")
|
||||
|
|
|
|||
|
|
@ -196,7 +196,6 @@ defmodule ToweropsWeb.AlertLive.Index do
|
|||
|
||||
site_subscribers = load_site_subscribers(filtered_alerts)
|
||||
sorted_alerts = sort_alerts(filtered_alerts, socket.assigns.sort_by, site_subscribers)
|
||||
grouped = group_by_site(sorted_alerts, site_subscribers)
|
||||
|
||||
counts = %{
|
||||
all: Alerts.count_organization_alerts(organization_id),
|
||||
|
|
@ -208,7 +207,6 @@ defmodule ToweropsWeb.AlertLive.Index do
|
|||
socket
|
||||
|> assign(:alerts, sorted_alerts)
|
||||
|> assign(:site_subscribers, site_subscribers)
|
||||
|> assign(:grouped_alerts, grouped)
|
||||
|> assign(:counts, counts)
|
||||
end
|
||||
|
||||
|
|
@ -245,32 +243,6 @@ defmodule ToweropsWeb.AlertLive.Index do
|
|||
def severity_weight(%{alert_type: "device_down"}), do: 1
|
||||
def severity_weight(_alert), do: 2
|
||||
|
||||
defp group_by_site(alerts, site_subscribers) do
|
||||
alerts
|
||||
|> Enum.group_by(fn alert ->
|
||||
if alert.device.site do
|
||||
{alert.device.site.id, alert.device.site.name}
|
||||
else
|
||||
{nil, "No Site"}
|
||||
end
|
||||
end)
|
||||
|> Enum.map(fn {{site_id, site_name}, site_alerts} ->
|
||||
sub_info = if site_id, do: site_subscribers[site_id]
|
||||
critical_count = Enum.count(site_alerts, &(&1.alert_type == "device_down" and is_nil(&1.resolved_at)))
|
||||
|
||||
%{
|
||||
site_id: site_id,
|
||||
site_name: site_name,
|
||||
alerts: site_alerts,
|
||||
total_count: length(site_alerts),
|
||||
critical_count: critical_count,
|
||||
subscriber_info: sub_info,
|
||||
total_subscribers: get_site_subscriber_count(sub_info)
|
||||
}
|
||||
end)
|
||||
|> Enum.sort_by(fn group -> {-group.critical_count, -group.total_subscribers, -group.total_count} end)
|
||||
end
|
||||
|
||||
@doc false
|
||||
def get_site_subscriber_count(%{account_count: count}) when is_integer(count), do: count
|
||||
def get_site_subscriber_count(_), do: 0
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ defmodule ToweropsWeb.ChangelogLive do
|
|||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
entries = ToweropsWeb.ChangelogParser.parse()
|
||||
{:ok, assign(socket, entries: entries, page_title: "What's New", active_page: "changelog")}
|
||||
{:ok, assign(socket, entries: entries, page_title: "What's New")}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
|
|||
|
|
@ -309,16 +309,12 @@ defmodule ToweropsWeb.CheckLive.FormComponent do
|
|||
|> assign(assigns)
|
||||
|> assign(:action, action)
|
||||
|> assign(:selected_type, selected_type)
|
||||
|> assign(:form, to_form(changeset))
|
||||
|> assign_default_config(selected_type)}
|
||||
|> assign(:form, to_form(changeset))}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("change_type", %{"check" => %{"check_type" => type}}, socket) do
|
||||
socket =
|
||||
socket
|
||||
|> assign(:selected_type, type)
|
||||
|> assign_default_config(type)
|
||||
socket = assign(socket, :selected_type, type)
|
||||
|
||||
# Auto-fill host from device IP for TCP and SSL checks
|
||||
socket =
|
||||
|
|
@ -451,20 +447,6 @@ defmodule ToweropsWeb.CheckLive.FormComponent do
|
|||
|
||||
def config_to_form_fields(_config, _type), do: %{}
|
||||
|
||||
defp assign_default_config(socket, type) do
|
||||
assign(socket, :default_config, default_config_for_type(socket, type))
|
||||
end
|
||||
|
||||
defp default_config_for_type(_socket, "http"), do: default_config_by_type("http", "")
|
||||
|
||||
defp default_config_for_type(socket, "tcp"), do: default_config_by_type("tcp", device_host_from_socket(socket))
|
||||
|
||||
defp default_config_for_type(_socket, "dns"), do: default_config_by_type("dns", "")
|
||||
|
||||
defp default_config_for_type(socket, "ssl"), do: default_config_by_type("ssl", device_host_from_socket(socket))
|
||||
|
||||
defp default_config_for_type(_socket, _type), do: %{}
|
||||
|
||||
@doc false
|
||||
def default_config_by_type("http", _host) do
|
||||
%{
|
||||
|
|
@ -489,10 +471,6 @@ defmodule ToweropsWeb.CheckLive.FormComponent do
|
|||
def device_host(%{ip_address: ip}), do: to_string(ip)
|
||||
def device_host(_), do: ""
|
||||
|
||||
defp device_host_from_socket(socket) do
|
||||
device_host(socket.assigns[:device])
|
||||
end
|
||||
|
||||
@doc false
|
||||
def merge_config_params(check_params, type) do
|
||||
check_params
|
||||
|
|
|
|||
|
|
@ -69,9 +69,6 @@ defmodule ToweropsWeb.Live.Components.GlobalSearchComponent do
|
|||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
flat = flat_results(assigns.results)
|
||||
assigns = assign(assigns, flat_results: flat)
|
||||
|
||||
~H"""
|
||||
<div id="global-search" phx-hook="GlobalSearch" phx-target={@myself}>
|
||||
<%= if @open do %>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ defmodule ToweropsWeb.ConfigTimelineLive do
|
|||
device -> device
|
||||
end
|
||||
|
||||
{:ok, assign(socket, device: device, page_title: "Config Timeline — #{device.name}", active_page: "devices")}
|
||||
{:ok, assign(socket, device: device, page_title: "Config Timeline — #{device.name}")}
|
||||
|
||||
{:error, _} ->
|
||||
{:ok,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ defmodule ToweropsWeb.CoverageLive.Form do
|
|||
socket
|
||||
|> assign(:organization, organization)
|
||||
|> assign(:sites, sites)
|
||||
|> assign(:antennas, antennas)
|
||||
|> assign(:antenna_options, antenna_options(antennas))
|
||||
|> assign(:devices, [])}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ defmodule ToweropsWeb.DashboardLive do
|
|||
|
||||
alias Towerops.ActivityFeed
|
||||
alias Towerops.Alerts
|
||||
alias Towerops.ConfigChanges
|
||||
alias Towerops.Dashboard
|
||||
alias Towerops.Devices
|
||||
alias Towerops.Preseem
|
||||
|
|
@ -27,7 +28,6 @@ defmodule ToweropsWeb.DashboardLive do
|
|||
|> assign(:device_count, 0)
|
||||
|> assign(:insight_source, nil)
|
||||
|> assign(:timezone, socket.assigns.current_scope.timezone)
|
||||
|> assign(:time_format, socket.assigns.current_scope.time_format)
|
||||
|> assign(:pending_dashboard_reload_ref, nil)}
|
||||
end
|
||||
|
||||
|
|
@ -118,13 +118,6 @@ defmodule ToweropsWeb.DashboardLive do
|
|||
|
||||
has_subscribers = summary.subscribers.total > 0
|
||||
|
||||
site_summaries =
|
||||
if organization.use_sites do
|
||||
Dashboard.list_site_summaries(organization_id)
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
# Impact data
|
||||
impact_summary = Dashboard.get_impact_summary(organization_id)
|
||||
active_incidents = Dashboard.list_active_incidents(organization_id)
|
||||
|
|
@ -174,7 +167,6 @@ defmodule ToweropsWeb.DashboardLive do
|
|||
|> assign(:device_down, Map.get(status_counts, :down, 0))
|
||||
|> assign(:device_unknown, Map.get(status_counts, :unknown, 0))
|
||||
|> assign(:has_subscribers, has_subscribers)
|
||||
|> assign(:site_summaries, site_summaries)
|
||||
|> assign(:impact_summary, impact_summary)
|
||||
|> assign(:active_incidents, active_incidents)
|
||||
|> assign(:site_impact_summaries, site_impact_summaries)
|
||||
|
|
@ -239,8 +231,6 @@ defmodule ToweropsWeb.DashboardLive do
|
|||
end
|
||||
|
||||
defp load_recent_config_changes(socket, organization_id) do
|
||||
alias Towerops.ConfigChanges
|
||||
|
||||
changes =
|
||||
ConfigChanges.list_org_changes(organization_id,
|
||||
limit: 10,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ defmodule ToweropsWeb.DeviceLive.Form do
|
|||
alias Towerops.Workers.DiscoveryWorker
|
||||
alias ToweropsWeb.Live.Helpers.AccessControl
|
||||
|
||||
require Logger
|
||||
|
||||
@impl true
|
||||
def mount(params, _session, socket) do
|
||||
organization = socket.assigns.current_scope.organization
|
||||
|
|
@ -161,7 +163,6 @@ defmodule ToweropsWeb.DeviceLive.Form do
|
|||
|> assign(:mikrotik_config_source, mikrotik_config.source)
|
||||
|> assign(:effective_mikrotik_username, mikrotik_config.username || "(not set)")
|
||||
|> assign(:is_mikrotik_device, is_mikrotik)
|
||||
|> assign(:mikrotik_test_result, nil)
|
||||
|> assign(:monitoring_mode, monitoring_mode)
|
||||
end
|
||||
|
||||
|
|
@ -190,8 +191,6 @@ defmodule ToweropsWeb.DeviceLive.Form do
|
|||
|
||||
@impl true
|
||||
def handle_event("validate", %{"device" => device_params}, socket) do
|
||||
require Logger
|
||||
|
||||
device_params = sanitize_device_params(device_params)
|
||||
|
||||
changeset =
|
||||
|
|
@ -252,8 +251,6 @@ defmodule ToweropsWeb.DeviceLive.Form do
|
|||
|
||||
@impl true
|
||||
def handle_event("test_snmp", _params, socket) do
|
||||
require Logger
|
||||
|
||||
changeset = socket.assigns.form.source
|
||||
form_data = Ecto.Changeset.apply_changes(changeset)
|
||||
|
||||
|
|
@ -645,8 +642,6 @@ defmodule ToweropsWeb.DeviceLive.Form do
|
|||
|
||||
@impl true
|
||||
def handle_info({:credential_test_result, result}, socket) do
|
||||
require Logger
|
||||
|
||||
Logger.info(
|
||||
"LiveView received credential test result: test_id=#{result.test_id} success=#{result.success} system_description=#{inspect(result.system_description)} error=#{inspect(result.error_message)}"
|
||||
)
|
||||
|
|
@ -709,8 +704,6 @@ defmodule ToweropsWeb.DeviceLive.Form do
|
|||
def get_org_agent(_), do: nil
|
||||
|
||||
defp send_credential_test_to_agent(agent_token_id, device_map, test_id) do
|
||||
require Logger
|
||||
|
||||
snmp_config = build_snmp_test_config(device_map)
|
||||
|
||||
Logger.info("Broadcasting credential test request",
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ defmodule ToweropsWeb.DeviceLive.Index do
|
|||
{:ok,
|
||||
socket
|
||||
|> assign(:page_title, t_equipment("Devices"))
|
||||
|> assign(:timezone, socket.assigns.current_scope.timezone)
|
||||
|> assign(:has_devices, devices != [])
|
||||
|> assign(:device_rows, build_device_rows(devices))
|
||||
|> assign(:sites_enabled, organization.use_sites)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
|||
@moduledoc false
|
||||
use ToweropsWeb, :live_view
|
||||
|
||||
import ToweropsWeb.Permissions
|
||||
|
||||
alias Towerops.Agents
|
||||
alias Towerops.Devices
|
||||
alias Towerops.Devices.BackupRequests
|
||||
alias Towerops.Devices.MikrotikBackups
|
||||
alias Towerops.Devices.VersionComparator
|
||||
alias Towerops.Monitoring
|
||||
|
|
@ -15,6 +18,7 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
|||
alias ToweropsWeb.DeviceLive.Helpers.Formatters
|
||||
alias ToweropsWeb.DeviceLive.Helpers.SensorClassifiers
|
||||
alias ToweropsWeb.Live.Helpers.AccessControl
|
||||
alias ToweropsWeb.TimeHelpers
|
||||
|
||||
# SNMP interface type to category mappings
|
||||
@interface_type_categories %{
|
||||
|
|
@ -413,8 +417,6 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
|||
end
|
||||
|
||||
defp can_view_financials?(socket) do
|
||||
import ToweropsWeb.Permissions
|
||||
|
||||
owner?(socket) || admin?(socket)
|
||||
end
|
||||
|
||||
|
|
@ -466,34 +468,15 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
|||
latency_chart_data = ChartBuilders.load_latency_chart_data(device_id)
|
||||
processor_chart_data = ChartBuilders.load_processor_chart_data(processors)
|
||||
memory_chart_data = ChartBuilders.load_sensor_chart_data(snmp_device, ["memory_usage"])
|
||||
storage_chart_data = ChartBuilders.load_sensor_chart_data(snmp_device, ["disk_usage"])
|
||||
storage_volume_chart_data = ChartBuilders.load_storage_volume_chart_data(storage)
|
||||
traffic_chart_data = ChartBuilders.load_overall_traffic_chart_data(snmp_device)
|
||||
|
||||
wireless_chart_data =
|
||||
ChartBuilders.load_sensor_chart_data(snmp_device, [
|
||||
"frequency",
|
||||
"power",
|
||||
"rssi",
|
||||
"ccq",
|
||||
"clients",
|
||||
"distance",
|
||||
"noise-floor",
|
||||
"quality",
|
||||
"rate",
|
||||
"utilization"
|
||||
])
|
||||
|
||||
# Classify sensors by type
|
||||
{transceiver_sensors, non_transceiver_sensors} =
|
||||
SensorClassifiers.split_transceiver_sensors(sensors)
|
||||
|
||||
temperature_sensors = Enum.filter(non_transceiver_sensors, &SensorClassifiers.temperature_sensor?/1)
|
||||
voltage_sensors = Enum.filter(non_transceiver_sensors, &SensorClassifiers.voltage_sensor?/1)
|
||||
current_sensors = Enum.filter(non_transceiver_sensors, &SensorClassifiers.current_sensor?/1)
|
||||
power_sensors = Enum.filter(non_transceiver_sensors, &SensorClassifiers.power_sensor?/1)
|
||||
fan_sensors = Enum.filter(non_transceiver_sensors, &SensorClassifiers.fan_sensor?/1)
|
||||
load_sensors = Enum.filter(non_transceiver_sensors, &SensorClassifiers.load_sensor?/1)
|
||||
storage_sensors = Enum.filter(non_transceiver_sensors, &(&1.sensor_type in ["disk_usage"]))
|
||||
count_sensors = Enum.filter(non_transceiver_sensors, &SensorClassifiers.counter_sensor?/1)
|
||||
|
||||
|
|
@ -501,34 +484,23 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
|||
Enum.split_with(count_sensors, &SensorClassifiers.firewall_counter?/1)
|
||||
|
||||
wireless_sensors = Enum.filter(non_transceiver_sensors, &SensorClassifiers.wireless_sensor?/1)
|
||||
signal_sensors = Enum.filter(non_transceiver_sensors, &SensorClassifiers.signal_sensor?/1)
|
||||
grouped_transceivers = SensorClassifiers.group_transceiver_sensors(transceiver_sensors)
|
||||
metrics = DataLoaders.calculate_metrics([], device)
|
||||
available_firmware = DataLoaders.get_available_firmware(snmp_device)
|
||||
|
||||
socket
|
||||
|> assign(:metrics, metrics)
|
||||
|> assign(:processors, processors)
|
||||
|> assign(:storage, storage)
|
||||
|> assign(:latency_chart_data, latency_chart_data)
|
||||
|> assign(:processor_chart_data, processor_chart_data)
|
||||
|> assign(:memory_chart_data, memory_chart_data)
|
||||
|> assign(:storage_chart_data, storage_chart_data)
|
||||
|> assign(:storage_volume_chart_data, storage_volume_chart_data)
|
||||
|> assign(:traffic_chart_data, traffic_chart_data)
|
||||
|> assign(:wireless_chart_data, wireless_chart_data)
|
||||
|> assign(:temperature_sensors, temperature_sensors)
|
||||
|> assign(:voltage_sensors, voltage_sensors)
|
||||
|> assign(:current_sensors, current_sensors)
|
||||
|> assign(:power_sensors, power_sensors)
|
||||
|> assign(:fan_sensors, fan_sensors)
|
||||
|> assign(:load_sensors, load_sensors)
|
||||
|> assign(:storage_sensors, storage_sensors)
|
||||
|> assign(:count_sensors, count_sensors)
|
||||
|> assign(:general_counters, general_counters)
|
||||
|> assign(:firewall_counters, firewall_counters)
|
||||
|> assign(:wireless_sensors, wireless_sensors)
|
||||
|> assign(:signal_sensors, signal_sensors)
|
||||
|> assign(:grouped_transceivers, grouped_transceivers)
|
||||
|> assign(:available_firmware, available_firmware)
|
||||
|> assign(:connected_devices, DataLoaders.load_connected_devices(device_id))
|
||||
|
|
@ -896,8 +868,6 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
|||
|
||||
@impl true
|
||||
def handle_event("delete_backup", %{"id" => backup_id}, socket) do
|
||||
import ToweropsWeb.Permissions
|
||||
|
||||
if owner?(socket) do
|
||||
do_delete_backup(backup_id, socket)
|
||||
else
|
||||
|
|
@ -963,8 +933,6 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
|||
end
|
||||
|
||||
defp trigger_manual_backup(socket, device, agent_token_id) do
|
||||
alias Towerops.Devices.BackupRequests
|
||||
|
||||
job_id = "backup:#{device.id}:#{DateTime.to_unix(DateTime.utc_now())}"
|
||||
|
||||
case BackupRequests.create_request(device.id, job_id, "manual") do
|
||||
|
|
@ -1151,8 +1119,6 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
|||
end
|
||||
|
||||
defp format_relative_time(datetime) do
|
||||
alias ToweropsWeb.TimeHelpers
|
||||
|
||||
TimeHelpers.format_time_ago(datetime)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ defmodule ToweropsWeb.EscalationPolicyLive.Form do
|
|||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
{:ok, assign(socket, :active_page, "schedules")}
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ defmodule ToweropsWeb.EscalationPolicyLive.Index do
|
|||
{:ok,
|
||||
socket
|
||||
|> assign(:page_title, t("Escalation Policies"))
|
||||
|> assign(:active_page, "schedules")
|
||||
|> assign(:policies, policies)}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ defmodule ToweropsWeb.EscalationPolicyLive.Show do
|
|||
{:ok,
|
||||
socket
|
||||
|> assign(:page_title, policy.name)
|
||||
|> assign(:active_page, "schedules")
|
||||
|> assign(:policy, policy)
|
||||
|> assign(:org_users, users)
|
||||
|> assign(:org_schedules, schedules)
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@ defmodule ToweropsWeb.GraphLive.Show do
|
|||
socket
|
||||
|> assign(:device, device)
|
||||
|> assign(:device_id, device.id)
|
||||
|> assign(:check, check)
|
||||
|> assign(:check_id, check.id)
|
||||
|> assign(:range, range)
|
||||
|> assign(:page_title, "#{device.name} - #{check.name}")
|
||||
|
|
@ -131,7 +130,6 @@ defmodule ToweropsWeb.GraphLive.Show do
|
|||
|> assign(:max_value, max_value)
|
||||
|> assign(:min_value, min_value)
|
||||
|> assign(:is_live_mode, false)
|
||||
|> assign(:has_agent_assignment, false)
|
||||
end
|
||||
|
||||
defp build_check_chart_data(%{check_type: "dns"} = check, from_time, to_time) do
|
||||
|
|
@ -223,9 +221,6 @@ defmodule ToweropsWeb.GraphLive.Show do
|
|||
sensor_id = Map.get(params, "sensor_id")
|
||||
storage_id = Map.get(params, "storage_id")
|
||||
|
||||
# Check if device has agent assignment
|
||||
has_agent = Agents.get_device_assignment(device_id) != nil
|
||||
|
||||
socket
|
||||
|> assign(:device_id, device_id)
|
||||
|> assign(:sensor_type, sensor_type)
|
||||
|
|
@ -234,7 +229,6 @@ defmodule ToweropsWeb.GraphLive.Show do
|
|||
|> assign(:sensor_id, sensor_id)
|
||||
|> assign(:storage_id, storage_id)
|
||||
|> assign(:is_live_mode, range == "live")
|
||||
|> assign(:has_agent_assignment, has_agent)
|
||||
|> maybe_start_live_polling()
|
||||
|> load_graph_data()
|
||||
end
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ defmodule ToweropsWeb.HelpLive.Index do
|
|||
|> assign(:current_user, current_user)
|
||||
|> assign(:is_authenticated, is_authenticated)
|
||||
|> assign(:current_scope, current_scope)
|
||||
|> assign(:timezone, if(current_user, do: current_user.timezone, else: "UTC"))
|
||||
|> assign(:generated_password, nil)
|
||||
|> assign(:password_generating, false)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ defmodule ToweropsWeb.InsightsLive.Index do
|
|||
alias Towerops.Preseem
|
||||
alias Towerops.Repo
|
||||
|
||||
require Logger
|
||||
|
||||
@regeneration_workers [
|
||||
Towerops.Workers.PreseemBaselineWorker,
|
||||
Towerops.Workers.CapacityInsightWorker,
|
||||
|
|
@ -149,8 +151,6 @@ defmodule ToweropsWeb.InsightsLive.Index do
|
|||
end
|
||||
|
||||
defp insert_regeneration_jobs do
|
||||
require Logger
|
||||
|
||||
Enum.reduce(@regeneration_workers, {0, 0}, fn worker, {ok, fail} ->
|
||||
case %{} |> worker.new() |> Oban.insert() do
|
||||
{:ok, _} ->
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ defmodule ToweropsWeb.MaintenanceLive.Form do
|
|||
{:ok,
|
||||
socket
|
||||
|> assign(:sites, sites)
|
||||
|> assign(:devices, devices)
|
||||
|> assign(:timezone, socket.assigns.current_scope.timezone)}
|
||||
|> assign(:devices, devices)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ defmodule ToweropsWeb.MobileQRLive do
|
|||
|
||||
alias Towerops.MobileSessions
|
||||
|
||||
require Logger
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
user = socket.assigns.current_scope.user
|
||||
|
|
@ -20,8 +22,6 @@ defmodule ToweropsWeb.MobileQRLive do
|
|||
token
|
||||
|
||||
{:error, reason} ->
|
||||
require Logger
|
||||
|
||||
Logger.error("Failed to create QR login token: #{inspect(reason)}")
|
||||
raise "Could not create QR login token"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ defmodule ToweropsWeb.Org.IntegrationsLive do
|
|||
|> assign(:page_title, t("Integrations"))
|
||||
|> assign(:organization, organization)
|
||||
|> assign(:timezone, socket.assigns.current_scope.timezone)
|
||||
|> assign(:providers, @providers)
|
||||
|> assign(:provider_categories, @provider_categories)
|
||||
|> assign(:integrations, integrations)
|
||||
|> assign(:configuring, nil)
|
||||
|
|
|
|||
|
|
@ -264,8 +264,7 @@ defmodule ToweropsWeb.Org.SettingsLive do
|
|||
{:noreply,
|
||||
socket
|
||||
|> assign(:configuring, nil)
|
||||
|> assign(:integration_form, nil)
|
||||
|> assign(:test_result, nil)}
|
||||
|> assign(:integration_form, nil)}
|
||||
else
|
||||
integration = Map.get(socket.assigns.integrations, provider)
|
||||
|
||||
|
|
@ -286,14 +285,13 @@ defmodule ToweropsWeb.Org.SettingsLive do
|
|||
if provider == "netbox" do
|
||||
assign(socket, :netbox_config, load_netbox_config(integration))
|
||||
else
|
||||
assign(socket, :integration_credentials, load_integration_credentials(integration, provider))
|
||||
socket
|
||||
end
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> assign(:configuring, provider)
|
||||
|> assign(:integration_form, form)
|
||||
|> assign(:test_result, nil)}
|
||||
|> assign(:integration_form, form)}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -302,8 +300,7 @@ defmodule ToweropsWeb.Org.SettingsLive do
|
|||
{:noreply,
|
||||
socket
|
||||
|> assign(:configuring, nil)
|
||||
|> assign(:integration_form, nil)
|
||||
|> assign(:test_result, nil)}
|
||||
|> assign(:integration_form, nil)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
@ -337,8 +334,8 @@ defmodule ToweropsWeb.Org.SettingsLive do
|
|||
"tag_filter" => Map.get(params, "tag_filter", "")
|
||||
})
|
||||
|
||||
provider ->
|
||||
assign(socket, :integration_credentials, extract_credentials_from_params(params, provider))
|
||||
_provider ->
|
||||
socket
|
||||
end
|
||||
|
||||
{:noreply, assign(socket, :integration_form, to_form(changeset))}
|
||||
|
|
@ -370,10 +367,8 @@ defmodule ToweropsWeb.Org.SettingsLive do
|
|||
{:noreply,
|
||||
socket
|
||||
|> assign(:integrations, integrations)
|
||||
|> assign(:active_billing_provider, active_billing_provider(integrations))
|
||||
|> assign(:configuring, nil)
|
||||
|> assign(:integration_form, nil)
|
||||
|> assign(:test_result, nil)
|
||||
|> put_flash(:info, t("Integration saved successfully"))}
|
||||
|
||||
{:error, changeset} ->
|
||||
|
|
@ -383,8 +378,8 @@ defmodule ToweropsWeb.Org.SettingsLive do
|
|||
|
||||
@impl true
|
||||
def handle_event("test_connection", _params, socket) do
|
||||
result = do_test_connection(socket.assigns.configuring, socket)
|
||||
{:noreply, assign(socket, :test_result, result)}
|
||||
_ = do_test_connection(socket.assigns.configuring, socket)
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
@ -404,7 +399,6 @@ defmodule ToweropsWeb.Org.SettingsLive do
|
|||
{:noreply,
|
||||
socket
|
||||
|> assign(:integrations, integrations)
|
||||
|> assign(:active_billing_provider, active_billing_provider(integrations))
|
||||
|> put_flash(:info, t("Webhook secret saved"))}
|
||||
|
||||
{:error, _changeset} ->
|
||||
|
|
@ -429,7 +423,6 @@ defmodule ToweropsWeb.Org.SettingsLive do
|
|||
{:noreply,
|
||||
socket
|
||||
|> assign(:integrations, integrations)
|
||||
|> assign(:active_billing_provider, active_billing_provider(integrations))
|
||||
|> put_flash(:info, t("Gaiia app URL saved"))}
|
||||
|
||||
{:error, _changeset} ->
|
||||
|
|
@ -452,7 +445,6 @@ defmodule ToweropsWeb.Org.SettingsLive do
|
|||
{:noreply,
|
||||
socket
|
||||
|> assign(:integrations, integrations)
|
||||
|> assign(:active_billing_provider, active_billing_provider(integrations))
|
||||
|> put_flash(:info, t("Integration updated"))}
|
||||
|
||||
{:error, _changeset} ->
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ defmodule ToweropsWeb.ScheduleLive.Form do
|
|||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
{:ok, assign(socket, :active_page, "schedules")}
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ defmodule ToweropsWeb.ScheduleLive.Index do
|
|||
{:ok,
|
||||
socket
|
||||
|> assign(:page_title, t("Schedules"))
|
||||
|> assign(:active_page, "schedules")
|
||||
|> assign(:tab, "schedules")
|
||||
|> assign(:start_date, default_start_date())
|
||||
|> assign(:range_days, @default_range)
|
||||
|
|
|
|||
|
|
@ -24,10 +24,8 @@ defmodule ToweropsWeb.ScheduleLive.Show do
|
|||
{:ok,
|
||||
socket
|
||||
|> assign(:page_title, schedule.name)
|
||||
|> assign(:active_page, "schedules")
|
||||
|> assign(:schedule, schedule)
|
||||
|> assign(:on_call, on_call)
|
||||
|> assign(:timezone, socket.assigns.current_scope.timezone)
|
||||
|> assign(:org_users, users)
|
||||
# Pre-open the Add Layer form for freshly-created schedules so the
|
||||
# new-schedule -> add-layers flow lands in a state ready to act on.
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ defmodule ToweropsWeb.SiteLive.Index do
|
|||
|> assign(:page_title, t("Sites"))
|
||||
|> assign(:sites, sites)
|
||||
|> assign(:summary_map, summary_map)
|
||||
|> assign(:insights, insights)
|
||||
|> assign(:timezone, socket.assigns.current_scope.timezone)}
|
||||
|> assign(:insights, insights)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
|
|||
|
|
@ -74,9 +74,7 @@ defmodule ToweropsWeb.TraceLive.Index do
|
|||
|> assign(:query, "")
|
||||
|> assign(:results, [])
|
||||
|> assign(:trace, nil)
|
||||
|> assign(:trace_type, nil)
|
||||
|> assign(:trace_id, nil)
|
||||
|> assign(:searching, false)}
|
||||
|> assign(:trace_type, nil)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
@ -92,7 +90,6 @@ defmodule ToweropsWeb.TraceLive.Index do
|
|||
socket
|
||||
|> assign(:trace, trace)
|
||||
|> assign(:trace_type, type_atom)
|
||||
|> assign(:trace_id, id)
|
||||
|
||||
_ ->
|
||||
socket
|
||||
|
|
@ -117,8 +114,7 @@ defmodule ToweropsWeb.TraceLive.Index do
|
|||
|> assign(:query, query)
|
||||
|> assign(:results, results)
|
||||
|> assign(:trace, nil)
|
||||
|> assign(:trace_type, nil)
|
||||
|> assign(:trace_id, nil)}
|
||||
|> assign(:trace_type, nil)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
@ -134,7 +130,6 @@ defmodule ToweropsWeb.TraceLive.Index do
|
|||
|> assign(:results, [])
|
||||
|> assign(:trace, nil)
|
||||
|> assign(:trace_type, nil)
|
||||
|> assign(:trace_id, nil)
|
||||
|> push_patch(to: ~p"/trace")}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ defmodule ToweropsWeb.UserRegistrationLive do
|
|||
|> assign(:invitation_token, invitation_token)
|
||||
|> assign(:password_breach_count, nil)
|
||||
|> assign(:detected_timezone, detected_timezone)
|
||||
|> assign(:trigger_action, false)
|
||||
|> assign(:privacy_policy_consent, false)
|
||||
|> assign(:terms_of_service_consent, false)}
|
||||
end
|
||||
|
|
@ -106,8 +105,7 @@ defmodule ToweropsWeb.UserRegistrationLive do
|
|||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, t("Account created! Please check your email to verify your account."))
|
||||
|> redirect(to: ~p"/users/log-in?email=#{user.email}")
|
||||
|> assign(:trigger_action, true)}
|
||||
|> redirect(to: ~p"/users/log-in?email=#{user.email}")}
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:noreply, assign(socket, :form, to_form(changeset))}
|
||||
|
|
@ -132,8 +130,7 @@ defmodule ToweropsWeb.UserRegistrationLive do
|
|||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, t("Account created! Please check your email to verify your account."))
|
||||
|> redirect(to: ~p"/users/log-in?email=#{user.email}")
|
||||
|> assign(:trigger_action, true)}
|
||||
|> redirect(to: ~p"/users/log-in?email=#{user.email}")}
|
||||
else
|
||||
{:error, :invalid_invitation} ->
|
||||
{:noreply,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ defmodule ToweropsWeb.UserResetPasswordLive do
|
|||
socket
|
||||
|> assign(:page_title, t("Reset Password"))
|
||||
|> assign(:form, to_form(changeset))
|
||||
|> assign(:token, token)
|
||||
|> assign(:user, user)
|
||||
|> assign(:password_breach_count, nil)}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
|> assign_mobile_sessions()
|
||||
|> assign_api_tokens()
|
||||
|> assign_organizations()
|
||||
|> assign_default_organization()
|
||||
|> assign_browser_sessions()
|
||||
|> assign_login_history()
|
||||
|> assign_security_alerts()
|
||||
|
|
@ -42,8 +41,6 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
|> assign(:show_add_device_modal, false)
|
||||
|> assign(:show_device_qr_modal, false)
|
||||
|> assign(:show_recovery_codes_modal, false)
|
||||
|> assign(:new_device_id, nil)
|
||||
|> assign(:new_device_secret, nil)
|
||||
|> assign(:new_device_qr_code, nil)
|
||||
|> assign(:generated_recovery_codes, nil)
|
||||
|> assign(:password_breach_count, nil)
|
||||
|
|
@ -383,21 +380,6 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
assign(socket, :organizations, Towerops.Organizations.list_user_organizations(user.id))
|
||||
end
|
||||
|
||||
defp assign_default_organization(socket) do
|
||||
user = socket.assigns.current_scope.user
|
||||
organizations = socket.assigns.organizations
|
||||
|
||||
# Get user's preferred default org, or fall back to first org
|
||||
default_org =
|
||||
if user.default_organization_id do
|
||||
Enum.find(organizations, &(&1.id == user.default_organization_id)) || List.first(organizations)
|
||||
else
|
||||
List.first(organizations)
|
||||
end
|
||||
|
||||
assign(socket, :default_organization, default_org)
|
||||
end
|
||||
|
||||
defp assign_login_history(socket) do
|
||||
user = socket.assigns.current_scope.user
|
||||
page = socket.assigns[:login_history_page] || 1
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ defmodule ToweropsWeb.Permissions do
|
|||
alias Towerops.Accounts.Scope
|
||||
alias Towerops.Organizations.Policy
|
||||
|
||||
require Logger
|
||||
|
||||
@doc """
|
||||
Checks if the current user can perform an action on a resource.
|
||||
|
||||
|
|
@ -145,8 +147,6 @@ defmodule ToweropsWeb.Permissions do
|
|||
# treats the user as having no role and denies access. That used
|
||||
# to look indistinguishable from a real denial; surface it so
|
||||
# missing preloads are noticed and fixed at the call site.
|
||||
require Logger
|
||||
|
||||
Logger.warning(
|
||||
"Permission check on user=#{user.id} org=#{org.id} without preloaded memberships — denying access by default"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ defmodule ToweropsWeb.Plugs.WebhookAuth do
|
|||
import Phoenix.Controller, only: [json: 2]
|
||||
import Plug.Conn
|
||||
|
||||
require Logger
|
||||
|
||||
def init(opts), do: opts
|
||||
|
||||
def call(conn, _opts) do
|
||||
|
|
@ -33,8 +35,6 @@ defmodule ToweropsWeb.Plugs.WebhookAuth do
|
|||
|
||||
cond do
|
||||
is_nil(secret) or secret == "" ->
|
||||
require Logger
|
||||
|
||||
Logger.error("agent_webhook_secret not configured — rejecting webhook request")
|
||||
|
||||
# Log the real reason server-side; don't echo it to the caller —
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@ defmodule ToweropsWeb.Telemetry do
|
|||
@moduledoc false
|
||||
use Supervisor
|
||||
|
||||
import Ecto.Query
|
||||
import Telemetry.Metrics
|
||||
|
||||
require Logger
|
||||
|
||||
def start_link(arg) do
|
||||
Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
|
||||
end
|
||||
|
|
@ -139,8 +142,6 @@ defmodule ToweropsWeb.Telemetry do
|
|||
:ok
|
||||
else
|
||||
try do
|
||||
import Ecto.Query
|
||||
|
||||
queues = ["default", "discovery", "pollers", "monitors", "maintenance"]
|
||||
|
||||
# Query queue sizes
|
||||
|
|
@ -283,8 +284,6 @@ defmodule ToweropsWeb.Telemetry do
|
|||
|
||||
# Telemetry handler for router exceptions
|
||||
def handle_router_exception(_event, _measurements, metadata, _config) do
|
||||
require Logger
|
||||
|
||||
Logger.error(
|
||||
"Router exception on #{metadata.plug} #{metadata.conn.method} #{metadata.conn.request_path}",
|
||||
kind: metadata.kind,
|
||||
|
|
@ -296,8 +295,6 @@ defmodule ToweropsWeb.Telemetry do
|
|||
|
||||
# Telemetry handler for endpoint stop events (log slow requests and errors)
|
||||
def handle_endpoint_stop(_event, measurements, metadata, _config) do
|
||||
require Logger
|
||||
|
||||
duration_ms = System.convert_time_unit(measurements.duration, :native, :millisecond)
|
||||
|
||||
# Log slow requests (over 5 seconds)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ defmodule ToweropsWeb.UserAuth do
|
|||
alias Towerops.Accounts
|
||||
alias Towerops.Accounts.Scope
|
||||
alias Towerops.Admin.AuditLogger
|
||||
alias Towerops.Organizations.Policy
|
||||
alias ToweropsWeb.Helpers.StatusHelpers
|
||||
|
||||
# Make the remember me cookie valid for 14 days. This should match
|
||||
|
|
@ -485,8 +486,6 @@ defmodule ToweropsWeb.UserAuth do
|
|||
membership = Towerops.Organizations.get_membership(organization.id, scope.user.id)
|
||||
|
||||
if membership do
|
||||
alias Towerops.Organizations.Policy
|
||||
|
||||
conn
|
||||
|> assign(:current_scope, Scope.put_organization(scope, organization))
|
||||
|> assign(:current_membership, membership)
|
||||
|
|
@ -822,8 +821,6 @@ defmodule ToweropsWeb.UserAuth do
|
|||
halt_with_error(socket, "You don't have access to any organizations.")
|
||||
|
||||
mem ->
|
||||
alias Towerops.Organizations.Policy
|
||||
|
||||
scope = socket.assigns.current_scope
|
||||
|
||||
{:cont,
|
||||
|
|
|
|||
|
|
@ -11,8 +11,11 @@ defmodule Towerops.Integration.SnmpIntegrationTest do
|
|||
"""
|
||||
use ExUnit.Case, async: false
|
||||
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Towerops.Snmp.Client
|
||||
alias Towerops.Snmp.Poller
|
||||
alias Towerops.Snmp.Profiles.Base
|
||||
alias Towerops.Workers.DeviceMonitorWorker
|
||||
|
||||
@moduletag :real_device
|
||||
|
|
@ -81,8 +84,6 @@ defmodule Towerops.Integration.SnmpIntegrationTest do
|
|||
describe "Discovery against real device" do
|
||||
@tag :full_discovery
|
||||
test "can discover device using Base profile" do
|
||||
alias Towerops.Snmp.Profiles.Base
|
||||
|
||||
# Discover system info using Base profile
|
||||
{:ok, system_info} = Base.discover_system_info(@test_device_opts)
|
||||
assert is_binary(system_info.sys_descr)
|
||||
|
|
@ -106,8 +107,6 @@ defmodule Towerops.Integration.SnmpIntegrationTest do
|
|||
describe "Device Monitor with SNMP" do
|
||||
test "creates SNMP-specific alert messages when device goes down" do
|
||||
# This test makes real SNMP calls to an unreachable IP to verify timeout handling
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ defmodule SnmpKit.SnmpLib.CacheTest do
|
|||
device_id = "192.168.1.1"
|
||||
oids = ["1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.3.0"]
|
||||
|
||||
:ok = Cache.warm_cache(device_id, oids, strategy: :immediate)
|
||||
assert :ok = Cache.warm_cache(device_id, oids, strategy: :immediate)
|
||||
|
||||
# Allow time for async processing
|
||||
:timer.sleep(10)
|
||||
|
|
@ -294,7 +294,7 @@ defmodule SnmpKit.SnmpLib.CacheTest do
|
|||
test "performs predictive cache warming" do
|
||||
device_id = "192.168.1.1"
|
||||
|
||||
:ok = Cache.warm_cache(device_id, :auto, strategy: :predictive)
|
||||
assert :ok = Cache.warm_cache(device_id, :auto, strategy: :predictive)
|
||||
|
||||
# Allow time for async processing
|
||||
:timer.sleep(10)
|
||||
|
|
@ -304,7 +304,7 @@ defmodule SnmpKit.SnmpLib.CacheTest do
|
|||
device_id = "192.168.1.1"
|
||||
oids = ["1.3.6.1.2.1.1.1.0"]
|
||||
|
||||
:ok = Cache.warm_cache(device_id, oids, strategy: :scheduled)
|
||||
assert :ok = Cache.warm_cache(device_id, oids, strategy: :scheduled)
|
||||
|
||||
# Allow time for async processing
|
||||
:timer.sleep(10)
|
||||
|
|
|
|||
|
|
@ -168,10 +168,10 @@ defmodule SnmpKit.SnmpLib.ConfigTest do
|
|||
test_pid = self()
|
||||
callback = fn _old, _new -> send(test_pid, :config_changed) end
|
||||
|
||||
:ok = Config.watch(:snmp, callback)
|
||||
assert :ok = Config.watch(:snmp, callback)
|
||||
|
||||
# Change configuration to trigger watcher
|
||||
:ok = Config.put(:snmp, :test_value, "changed")
|
||||
assert :ok = Config.put(:snmp, :test_value, "changed")
|
||||
|
||||
# Note: In a real implementation, this would trigger the callback
|
||||
# For now, we just test that the watcher registration succeeds
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ defmodule SnmpKit.SnmpLib.DashboardTest do
|
|||
|
||||
# Allow time for async processing
|
||||
:timer.sleep(10)
|
||||
|
||||
assert true
|
||||
end
|
||||
|
||||
test "records SNMP operation metrics" do
|
||||
|
|
@ -89,6 +91,8 @@ defmodule SnmpKit.SnmpLib.DashboardTest do
|
|||
device: "192.168.1.1",
|
||||
error_type: "timeout"
|
||||
})
|
||||
|
||||
assert true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -116,6 +120,8 @@ defmodule SnmpKit.SnmpLib.DashboardTest do
|
|||
|
||||
# Allow time for async processing
|
||||
:timer.sleep(10)
|
||||
|
||||
assert true
|
||||
end
|
||||
|
||||
test "creates device-specific alerts" do
|
||||
|
|
@ -132,6 +138,8 @@ defmodule SnmpKit.SnmpLib.DashboardTest do
|
|||
avg_response_time: 5000,
|
||||
threshold: 2000
|
||||
})
|
||||
|
||||
assert true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -279,7 +287,7 @@ defmodule SnmpKit.SnmpLib.DashboardTest do
|
|||
:timer.sleep(10)
|
||||
|
||||
# Acknowledge the alert
|
||||
:ok = Dashboard.acknowledge_alert(:device_down, "192.168.1.1")
|
||||
assert :ok = Dashboard.acknowledge_alert(:device_down, "192.168.1.1")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
defmodule Towerops.AccountsTest do
|
||||
use Towerops.DataCase
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Towerops.Accounts
|
||||
|
|
@ -2079,8 +2080,6 @@ defmodule Towerops.AccountsTest do
|
|||
|
||||
describe "verify_totp/2 failure logging" do
|
||||
test "logs debug info when TOTP verification fails" do
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
secret = Accounts.generate_totp_secret()
|
||||
|
||||
# Temporarily enable info logging to exercise the failure log path
|
||||
|
|
|
|||
|
|
@ -2,10 +2,15 @@ defmodule Towerops.AdminTest do
|
|||
use Towerops.DataCase
|
||||
|
||||
import Towerops.AccountsFixtures
|
||||
import Towerops.OrganizationsFixtures
|
||||
|
||||
alias Towerops.Accounts.User
|
||||
alias Towerops.Admin
|
||||
alias Towerops.Admin.AuditLog
|
||||
alias Towerops.Billing.StripeClient
|
||||
alias Towerops.Organizations.Organization
|
||||
alias Towerops.Settings
|
||||
alias Towerops.Settings.ApplicationSetting
|
||||
|
||||
doctest Admin, except: [delete_user: 3, delete_organization: 3, create_audit_log: 1]
|
||||
|
||||
|
|
@ -589,7 +594,7 @@ defmodule Towerops.AdminTest do
|
|||
|
||||
# Update the old log's timestamp directly to simulate it being older
|
||||
Towerops.Repo.update_all(
|
||||
from(l in Towerops.Admin.AuditLog, where: l.id == ^old_log.id),
|
||||
from(l in AuditLog, where: l.id == ^old_log.id),
|
||||
set: [inserted_at: old_time]
|
||||
)
|
||||
|
||||
|
|
@ -780,13 +785,6 @@ defmodule Towerops.AdminTest do
|
|||
|
||||
describe "update_global_pricing/3" do
|
||||
test "updates settings, creates Stripe price, migrates subscriptions, and audits" do
|
||||
import Towerops.OrganizationsFixtures
|
||||
|
||||
alias Towerops.Admin.AuditLog
|
||||
alias Towerops.Billing.StripeClient
|
||||
alias Towerops.Settings
|
||||
alias Towerops.Settings.ApplicationSetting
|
||||
|
||||
superuser = user_fixture(%{superuser: true})
|
||||
user = user_fixture()
|
||||
_org1 = organization_fixture(user.id, %{subscription_status: "active", stripe_subscription_id: "sub_1"})
|
||||
|
|
@ -861,9 +859,6 @@ defmodule Towerops.AdminTest do
|
|||
end
|
||||
|
||||
test "returns ok when price unchanged and no migration needed" do
|
||||
alias Towerops.Settings
|
||||
alias Towerops.Settings.ApplicationSetting
|
||||
|
||||
superuser = user_fixture(%{superuser: true})
|
||||
|
||||
Repo.delete_all(from s in ApplicationSetting, where: s.key in ["default_free_devices", "default_price_per_device"])
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ defmodule Towerops.Alerts.StormDetectorTest do
|
|||
use Towerops.DataCase, async: false
|
||||
use ExUnitProperties
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
alias Towerops.Alerts.StormDetector
|
||||
|
||||
defp queue_of(list), do: Enum.reduce(list, :queue.new(), fn x, q -> :queue.in(x, q) end)
|
||||
|
|
@ -121,8 +123,6 @@ defmodule Towerops.Alerts.StormDetectorTest do
|
|||
end
|
||||
|
||||
test "creates a site outage alert when threshold devices go down at the same site" do
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
user = Towerops.AccountsFixtures.user_fixture()
|
||||
{:ok, org} = Towerops.Organizations.create_organization(%{name: "SD Outage"}, user.id)
|
||||
{:ok, site} = Towerops.Sites.create_site(%{name: "Tower 7", organization_id: org.id})
|
||||
|
|
@ -172,8 +172,6 @@ defmodule Towerops.Alerts.StormDetectorTest do
|
|||
end
|
||||
|
||||
test "register_device_down enters storm mode when alert rate exceeds threshold" do
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
user = Towerops.AccountsFixtures.user_fixture()
|
||||
{:ok, org} = Towerops.Organizations.create_organization(%{name: "SD Storm"}, user.id)
|
||||
{:ok, site} = Towerops.Sites.create_site(%{name: "Storm Site", organization_id: org.id})
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
defmodule Towerops.AlertsTest do
|
||||
use Towerops.DataCase
|
||||
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Towerops.Alerts
|
||||
alias Towerops.Alerts.Alert
|
||||
|
||||
describe "alerts" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Towerops.Alerts.Alert
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -370,8 +369,6 @@ defmodule Towerops.AlertsTest do
|
|||
end
|
||||
|
||||
describe "GDPR data access - list_alerts_for_organizations/2" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, org1} = Towerops.Organizations.create_organization(%{name: "Org 1"}, user.id)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ defmodule Towerops.Coverages.RasterTest do
|
|||
|
||||
alias Towerops.Coverages.Coverage
|
||||
alias Towerops.Coverages.Raster
|
||||
alias Towerops.Lidar.Reader
|
||||
|
||||
describe "query_rssi/3" do
|
||||
test "returns :not_ready when raster_path is nil and status is computing" do
|
||||
|
|
@ -67,8 +68,6 @@ defmodule Towerops.Coverages.RasterTest do
|
|||
end
|
||||
|
||||
describe "parse_aaigrid/1 (header parsing — public for testability)" do
|
||||
alias Towerops.Lidar.Reader
|
||||
|
||||
test "parses a small ASCII grid into the expected map shape" do
|
||||
grid = """
|
||||
ncols 3
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
defmodule Towerops.Devices.DeviceFirmwareHistoryTest do
|
||||
use Towerops.DataCase, async: true
|
||||
|
||||
import Towerops.AccountsFixtures
|
||||
import Towerops.OrganizationsFixtures
|
||||
|
||||
alias Towerops.Devices
|
||||
alias Towerops.Devices.DeviceFirmwareHistory
|
||||
alias Towerops.Sites
|
||||
alias Towerops.Snmp.Device
|
||||
|
||||
describe "changeset/2" do
|
||||
|
|
@ -215,12 +220,6 @@ defmodule Towerops.Devices.DeviceFirmwareHistoryTest do
|
|||
|
||||
# Helper function to create a test SNMP device
|
||||
defp insert_snmp_device do
|
||||
import Towerops.AccountsFixtures
|
||||
import Towerops.OrganizationsFixtures
|
||||
|
||||
alias Towerops.Devices
|
||||
alias Towerops.Sites
|
||||
|
||||
# Create organization and site
|
||||
user = user_fixture()
|
||||
organization = organization_fixture(user.id)
|
||||
|
|
|
|||
|
|
@ -2,17 +2,18 @@ defmodule Towerops.EquipmentTest do
|
|||
use Towerops.DataCase
|
||||
use ExUnitProperties
|
||||
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Device, as: DeviceSchema
|
||||
alias Towerops.Alerts.Alert
|
||||
alias Towerops.Devices
|
||||
alias Towerops.Devices.Device
|
||||
alias Towerops.Devices.Event
|
||||
alias Towerops.Monitoring
|
||||
|
||||
doctest Devices
|
||||
|
||||
describe "device" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Device, as: DeviceSchema
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -563,8 +564,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "SNMP configuration inheritance" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -704,10 +703,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "events" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Towerops.Devices.Event
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -801,8 +796,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "additional coverage tests" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -997,8 +990,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "automatic rediscovery on device updates" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -1230,8 +1221,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "property-based tests" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
property "creating devices with valid IPs always succeeds" do
|
||||
# Create fixtures once outside the property check
|
||||
user = user_fixture()
|
||||
|
|
@ -1261,7 +1250,7 @@ defmodule Towerops.EquipmentTest do
|
|||
}
|
||||
|
||||
# Use bypass_limits since property tests may create > 10 devices
|
||||
assert {:ok, %Device{} = device} = Devices.create_device(attrs, bypass_limits: true)
|
||||
assert {:ok, %DeviceSchema{} = device} = Devices.create_device(attrs, bypass_limits: true)
|
||||
assert device.ip_address == ip_address
|
||||
assert device.status == :unknown
|
||||
end
|
||||
|
|
@ -1385,8 +1374,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "device creation with subscription limits" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -1537,8 +1524,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "GDPR data access - list_devices_for_organizations/1" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, org1} = Towerops.Organizations.create_organization(%{name: "Org 1"}, user.id)
|
||||
|
|
@ -1695,8 +1680,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "PubSub broadcasts" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -1807,8 +1790,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "get_device_by_ip/3" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -1857,8 +1838,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "get_mikrotik_config/1" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -1925,8 +1904,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "get_snmpv3_config/1" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -1995,8 +1972,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "propagate_site_community_change/2" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -2051,8 +2026,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "propagate_organization_community_change/2" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
|
||||
|
|
@ -2111,8 +2084,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "propagate_site_mikrotik_change/2" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -2151,8 +2122,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "propagate_organization_mikrotik_change/2" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -2193,8 +2162,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "propagate_site_snmpv3_change/2" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -2243,8 +2210,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "propagate_organization_snmpv3_change/2" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -2297,8 +2262,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "resolve_snmp_community/1" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -2360,8 +2323,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "list_mikrotik_devices_with_api/0" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
@ -2407,10 +2368,6 @@ defmodule Towerops.EquipmentTest do
|
|||
end
|
||||
|
||||
describe "auto ICMP ping check" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Towerops.Monitoring
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
defmodule Towerops.SitesTest do
|
||||
use Towerops.DataCase
|
||||
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Towerops.Sites
|
||||
alias Towerops.Sites.Site
|
||||
|
||||
describe "sites" do
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||
|
|
|
|||
|
|
@ -11,8 +11,13 @@ defmodule Towerops.Snmp.DiscoverySyncTest do
|
|||
alias Towerops.Repo
|
||||
alias Towerops.Snmp
|
||||
alias Towerops.Snmp.Discovery
|
||||
alias Towerops.Snmp.EntityPhysical
|
||||
alias Towerops.Snmp.Interface
|
||||
alias Towerops.Snmp.Mempool
|
||||
alias Towerops.Snmp.PrinterSupply
|
||||
alias Towerops.Snmp.Processor
|
||||
alias Towerops.Snmp.Storage
|
||||
alias Towerops.Snmp.Transceiver
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
|
|
@ -122,8 +127,6 @@ defmodule Towerops.Snmp.DiscoverySyncTest do
|
|||
end
|
||||
|
||||
describe "sync_mempools/2" do
|
||||
alias Towerops.Snmp.Mempool
|
||||
|
||||
test "inserts new mempools and removes missing ones", %{snmp_device: snmp_device} do
|
||||
now = Towerops.Time.now()
|
||||
|
||||
|
|
@ -168,8 +171,6 @@ defmodule Towerops.Snmp.DiscoverySyncTest do
|
|||
end
|
||||
|
||||
describe "sync_transceivers/2" do
|
||||
alias Towerops.Snmp.Transceiver
|
||||
|
||||
test "inserts, updates, and removes transceivers", %{snmp_device: snmp_device} do
|
||||
{:ok, [_, _]} =
|
||||
Discovery.sync_transceivers(snmp_device, [
|
||||
|
|
@ -191,8 +192,6 @@ defmodule Towerops.Snmp.DiscoverySyncTest do
|
|||
end
|
||||
|
||||
describe "sync_printer_supplies/2" do
|
||||
alias Towerops.Snmp.PrinterSupply
|
||||
|
||||
test "inserts, updates, and removes supplies", %{snmp_device: snmp_device} do
|
||||
Discovery.sync_printer_supplies(snmp_device, [
|
||||
%{
|
||||
|
|
@ -235,8 +234,6 @@ defmodule Towerops.Snmp.DiscoverySyncTest do
|
|||
end
|
||||
|
||||
describe "sync_entity_physical/2" do
|
||||
alias Towerops.Snmp.EntityPhysical
|
||||
|
||||
test "inserts and removes entities", %{snmp_device: snmp_device} do
|
||||
Discovery.sync_entity_physical(snmp_device, [
|
||||
%{
|
||||
|
|
@ -272,8 +269,6 @@ defmodule Towerops.Snmp.DiscoverySyncTest do
|
|||
end
|
||||
|
||||
describe "save_neighbors/2 + save_arp_entries/3" do
|
||||
alias Towerops.Snmp.Interface
|
||||
|
||||
setup %{snmp_device: snmp_device} do
|
||||
{:ok, iface} =
|
||||
Repo.insert(%Interface{
|
||||
|
|
@ -326,7 +321,7 @@ defmodule Towerops.Snmp.DiscoverySyncTest do
|
|||
device = Repo.preload(snmp_device, :device).device
|
||||
|
||||
{:ok, _interface} =
|
||||
Repo.insert(%Towerops.Snmp.Interface{
|
||||
Repo.insert(%Interface{
|
||||
snmp_device_id: snmp_device.id,
|
||||
if_index: 1,
|
||||
if_name: "eth0",
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ defmodule Towerops.Snmp.DiscoveryTest do
|
|||
alias Towerops.Snmp.Device
|
||||
alias Towerops.Snmp.Discovery
|
||||
alias Towerops.Snmp.Interface
|
||||
alias Towerops.Snmp.InterfaceStat
|
||||
alias Towerops.Snmp.Sensor
|
||||
alias Towerops.Snmp.SensorReading
|
||||
alias Towerops.Snmp.SnmpMock
|
||||
|
||||
doctest Discovery
|
||||
|
|
@ -521,8 +523,6 @@ defmodule Towerops.Snmp.DiscoveryTest do
|
|||
organization: organization,
|
||||
site: site
|
||||
} do
|
||||
alias Towerops.Snmp.SensorReading
|
||||
|
||||
{:ok, device} =
|
||||
Towerops.Devices.create_device(%{
|
||||
name: "Device With Sensors",
|
||||
|
|
@ -673,8 +673,6 @@ defmodule Towerops.Snmp.DiscoveryTest do
|
|||
organization: organization,
|
||||
site: site
|
||||
} do
|
||||
alias Towerops.Snmp.InterfaceStat
|
||||
|
||||
{:ok, device} =
|
||||
Towerops.Devices.create_device(%{
|
||||
name: "Device With Interfaces",
|
||||
|
|
|
|||
|
|
@ -117,6 +117,8 @@ defmodule Towerops.Snmp.MibTranslatorTest do
|
|||
|
||||
# Cleanup
|
||||
Application.delete_env(:towerops, :mib_dirs)
|
||||
|
||||
assert true
|
||||
end
|
||||
|
||||
test "handles nonexistent directory" do
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ defmodule Towerops.Snmp.MibValidationTest do
|
|||
]
|
||||
|
||||
validate_oids(mib_file, validations)
|
||||
assert true
|
||||
end
|
||||
|
||||
test "sensor OIDs match ENTITY-SENSOR-MIB" do
|
||||
|
|
@ -79,6 +80,7 @@ defmodule Towerops.Snmp.MibValidationTest do
|
|||
]
|
||||
|
||||
validate_oids(mib_file, validations)
|
||||
assert true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -94,6 +96,7 @@ defmodule Towerops.Snmp.MibValidationTest do
|
|||
]
|
||||
|
||||
validate_oids(mib_file, validations)
|
||||
assert true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -111,6 +114,7 @@ defmodule Towerops.Snmp.MibValidationTest do
|
|||
]
|
||||
|
||||
validate_oids(mib_file, validations)
|
||||
assert true
|
||||
end
|
||||
|
||||
test "UCD-SNMP OIDs match UCD-SNMP-MIB" do
|
||||
|
|
@ -131,6 +135,7 @@ defmodule Towerops.Snmp.MibValidationTest do
|
|||
end)
|
||||
|
||||
validate_oids(mib_file, validations)
|
||||
assert true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -80,9 +80,8 @@ defmodule Towerops.Snmp.Profiles.Vendors.RegistryTest do
|
|||
]
|
||||
|
||||
describe "list_vendors/0" do
|
||||
test "returns all registered vendor modules" do
|
||||
test "returns vendor modules A-I" do
|
||||
vendors = Registry.list_vendors()
|
||||
|
||||
assert is_list(vendors)
|
||||
assert Epmp in vendors
|
||||
assert Airos in vendors
|
||||
|
|
@ -95,6 +94,10 @@ defmodule Towerops.Snmp.Profiles.Vendors.RegistryTest do
|
|||
assert Unifi in vendors
|
||||
assert Ligoos in vendors
|
||||
assert Cnpilot in vendors
|
||||
end
|
||||
|
||||
test "returns vendor modules J-Z" do
|
||||
vendors = Registry.list_vendors()
|
||||
assert Saf in vendors
|
||||
assert Ruckus in vendors
|
||||
assert Dragonwave in vendors
|
||||
|
|
@ -106,22 +109,29 @@ defmodule Towerops.Snmp.Profiles.Vendors.RegistryTest do
|
|||
assert Proxim in vendors
|
||||
assert Stellar in vendors
|
||||
assert Xirrus in vendors
|
||||
assert Ceragon in vendors
|
||||
assert Cmm in vendors
|
||||
end
|
||||
|
||||
test "returns vendor modules D-F" do
|
||||
vendors = Registry.list_vendors()
|
||||
assert Pepwave in vendors
|
||||
assert Tranzeo in vendors
|
||||
assert ZyxelWlc in vendors
|
||||
assert Dlinkap in vendors
|
||||
assert Fortiap in vendors
|
||||
assert MoxaAwk in vendors
|
||||
assert Ceragon in vendors
|
||||
assert Cmm in vendors
|
||||
assert Pepwave in vendors
|
||||
assert Tranzeo in vendors
|
||||
assert Fortiwlc in vendors
|
||||
assert Meraki in vendors
|
||||
end
|
||||
|
||||
test "returns vendor modules G-M" do
|
||||
vendors = Registry.list_vendors()
|
||||
assert Apc in vendors
|
||||
assert Arista in vendors
|
||||
assert Calix in vendors
|
||||
assert Adtran in vendors
|
||||
assert AlliedTelesis in vendors
|
||||
# New auto-generated vendors
|
||||
assert Cisco in vendors
|
||||
assert Juniper in vendors
|
||||
assert Hp in vendors
|
||||
|
|
@ -129,6 +139,11 @@ defmodule Towerops.Snmp.Profiles.Vendors.RegistryTest do
|
|||
assert Fortinet in vendors
|
||||
assert Huawei in vendors
|
||||
assert Nokia in vendors
|
||||
assert Mikrotik in vendors
|
||||
end
|
||||
|
||||
test "returns vendor modules N-Z" do
|
||||
vendors = Registry.list_vendors()
|
||||
assert Omnitron in vendors
|
||||
assert Paloalto in vendors
|
||||
assert F5 in vendors
|
||||
|
|
@ -145,17 +160,14 @@ defmodule Towerops.Snmp.Profiles.Vendors.RegistryTest do
|
|||
assert Vertiv in vendors
|
||||
assert Riverbed in vendors
|
||||
assert Sonicwall in vendors
|
||||
assert Mikrotik in vendors
|
||||
assert Adva in vendors
|
||||
end
|
||||
end
|
||||
|
||||
describe "list_profile_names/0" do
|
||||
test "returns all profile names from all vendors" do
|
||||
test "returns profile names A-C" do
|
||||
names = Registry.list_profile_names()
|
||||
|
||||
assert is_list(names)
|
||||
# Check for some known profile names
|
||||
assert "epmp" in names
|
||||
assert "airos" in names
|
||||
assert "airos-af" in names
|
||||
|
|
@ -171,6 +183,10 @@ defmodule Towerops.Snmp.Profiles.Vendors.RegistryTest do
|
|||
assert "saf" in names
|
||||
assert "ruckuswireless" in names
|
||||
assert "horizon-compact" in names
|
||||
end
|
||||
|
||||
test "returns profile names D-M" do
|
||||
names = Registry.list_profile_names()
|
||||
assert "ray" in names
|
||||
assert "extendair" in names
|
||||
assert "alfo80hd" in names
|
||||
|
|
@ -187,6 +203,10 @@ defmodule Towerops.Snmp.Profiles.Vendors.RegistryTest do
|
|||
assert "cmm" in names
|
||||
assert "pepwave" in names
|
||||
assert "tranzeo" in names
|
||||
end
|
||||
|
||||
test "returns profile names N-Z" do
|
||||
names = Registry.list_profile_names()
|
||||
assert "fortiwlc" in names
|
||||
assert "merakimr" in names
|
||||
assert "merakims" in names
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ defmodule Towerops.Snmp.WirelessClientsTest do
|
|||
# Skipped: WirelessClientReading.device_id references snmp_devices, not devices,
|
||||
# which makes a minimal fixture awkward. The empty-list path covers the function head we care about.
|
||||
_ = {device, org_id}
|
||||
:ok
|
||||
assert true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
defmodule Towerops.SnmpTest do
|
||||
use Towerops.DataCase
|
||||
|
||||
import Mox
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Towerops.Snmp
|
||||
|
|
@ -56,8 +57,6 @@ defmodule Towerops.SnmpTest do
|
|||
end
|
||||
|
||||
describe "test_connection/4" do
|
||||
import Mox
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
test "delegates to Client.test_connection" do
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
defmodule Towerops.TopologyTest do
|
||||
use Towerops.DataCase
|
||||
|
||||
import Mox
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
alias Towerops.Snmp.Device
|
||||
alias Towerops.Snmp.Interface
|
||||
alias Towerops.Snmp.IpAddress
|
||||
alias Towerops.Snmp.Sensor
|
||||
alias Towerops.Snmp.SnmpMock
|
||||
alias Towerops.Snmp.WirelessClient
|
||||
alias Towerops.Topology
|
||||
alias Towerops.Topology.DeviceLink
|
||||
|
||||
|
|
@ -1418,8 +1422,6 @@ defmodule Towerops.TopologyTest do
|
|||
end
|
||||
|
||||
describe "compute_wireless_stats/1" do
|
||||
alias Towerops.Snmp.WirelessClient
|
||||
|
||||
test "returns empty map when device_ids list is empty" do
|
||||
assert Topology.compute_wireless_stats([]) == %{}
|
||||
end
|
||||
|
|
@ -1505,8 +1507,6 @@ defmodule Towerops.TopologyTest do
|
|||
end
|
||||
|
||||
describe "compute_rf_link_stats/1" do
|
||||
alias Towerops.Snmp.Sensor
|
||||
|
||||
test "returns empty map when device_ids list is empty" do
|
||||
assert Topology.compute_rf_link_stats([]) == %{}
|
||||
end
|
||||
|
|
@ -1667,10 +1667,6 @@ defmodule Towerops.TopologyTest do
|
|||
end
|
||||
|
||||
describe "discover_lldp_neighbors/1" do
|
||||
import Mox
|
||||
|
||||
alias Towerops.Snmp.SnmpMock
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
test "returns :device_not_found for missing device" do
|
||||
|
|
@ -2223,8 +2219,6 @@ defmodule Towerops.TopologyTest do
|
|||
end
|
||||
|
||||
describe "compute_rf_link_stats/1 - edge enrichment via get_topology_for_map" do
|
||||
alias Towerops.Snmp.Sensor
|
||||
|
||||
test "edges receive worse-of signal_health from source/target SNR readings",
|
||||
%{router: router, switch: switch, router_iface: iface, router_snmp: router_snmp, organization: org} do
|
||||
switch_snmp =
|
||||
|
|
@ -2280,10 +2274,6 @@ defmodule Towerops.TopologyTest do
|
|||
end
|
||||
|
||||
describe "discover_lldp_neighbors/1 - error path" do
|
||||
import Mox
|
||||
|
||||
alias Towerops.Snmp.SnmpMock
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
test "propagates SNMP errors from the LLDP discovery layer", %{router: router} do
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ defmodule Towerops.Workers.AlertDigestWorkerTest do
|
|||
use Oban.Testing, repo: Towerops.Repo
|
||||
|
||||
import Towerops.AccountsFixtures
|
||||
import Towerops.DevicesFixtures
|
||||
|
||||
alias Towerops.Alerts.NotificationDigest
|
||||
alias Towerops.Workers.AlertDigestWorker
|
||||
|
|
@ -69,8 +70,6 @@ defmodule Towerops.Workers.AlertDigestWorkerTest do
|
|||
end
|
||||
|
||||
test "delivers digest when real alerts exist for the user" do
|
||||
import Towerops.DevicesFixtures
|
||||
|
||||
user = user_fixture()
|
||||
device = device_fixture()
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ defmodule Towerops.Workers.DevicePollerTransceiverTest do
|
|||
now = DateTime.utc_now()
|
||||
|
||||
# Should not crash
|
||||
:ok = DevicePollerWorker.poll_transceivers(transceivers, client_opts, now)
|
||||
assert :ok = DevicePollerWorker.poll_transceivers(transceivers, client_opts, now)
|
||||
|
||||
# May or may not create a reading with nil values, depending on implementation
|
||||
# At minimum, should not crash
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
defmodule Towerops.Workers.DiscoveryWorkerTest do
|
||||
use Towerops.DataCase, async: true
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
import Mox
|
||||
import Towerops.AccountsFixtures
|
||||
|
||||
|
|
@ -186,8 +187,6 @@ defmodule Towerops.Workers.DiscoveryWorkerTest do
|
|||
end
|
||||
|
||||
test "logs error when discovery fails", %{device: device} do
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
stub(SnmpMock, :get, fn _target, _oid, _opts ->
|
||||
{:error, :network_unreachable}
|
||||
end)
|
||||
|
|
@ -415,8 +414,6 @@ defmodule Towerops.Workers.DiscoveryWorkerTest do
|
|||
# Pass a non-string device_id so get_device_with_details raises a
|
||||
# Postgrex/Ecto error inside the rescue block. The worker should log
|
||||
# and return :discard rather than re-raising.
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
log =
|
||||
capture_log(fn ->
|
||||
assert :discard =
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ defmodule Towerops.Workers.JobHealthCheckWorkerTest do
|
|||
test "recovers missing poller jobs (DEPRECATED: per-check jobs now)" do
|
||||
# This test is deprecated - SNMP polling is now handled by per-check
|
||||
# CheckExecutorWorker jobs, not device-level DevicePollerWorker jobs
|
||||
assert true
|
||||
end
|
||||
|
||||
test "does not create duplicate jobs if they already exist" do
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ defmodule ToweropsWeb.AgentChannelExtraCoverageTest do
|
|||
"""
|
||||
use Towerops.DataCase, async: false
|
||||
|
||||
import Ecto.Query, only: [from: 2]
|
||||
import Phoenix.ChannelTest
|
||||
|
||||
alias Towerops.AccountsFixtures
|
||||
|
|
@ -476,8 +477,6 @@ defmodule ToweropsWeb.AgentChannelExtraCoverageTest do
|
|||
describe "device with explicitly disabled assignment" do
|
||||
test "result for device whose assignment is disabled is treated as reassigned",
|
||||
%{socket: socket, agent_token: agent_token, device: device} do
|
||||
import Ecto.Query, only: [from: 2]
|
||||
|
||||
device = discover_device!(device)
|
||||
|
||||
# Disable the existing assignment (it was created in the parent setup as enabled)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
defmodule ToweropsWeb.AgentChannelTest do
|
||||
use Towerops.DataCase, async: false
|
||||
|
||||
import Ecto.Query
|
||||
import Phoenix.ChannelTest
|
||||
|
||||
alias Towerops.AccountsFixtures
|
||||
|
|
@ -318,8 +319,6 @@ defmodule ToweropsWeb.AgentChannelTest do
|
|||
|
||||
describe "handle_in monitoring_check" do
|
||||
test "valid monitoring check creates check record", %{socket: socket, device: device} do
|
||||
import Ecto.Query
|
||||
|
||||
check = build_monitoring_check(device.id, "success")
|
||||
payload = encode_payload(check)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule ToweropsWeb.Api.MobileControllerTest do
|
|||
alias Towerops.MobileSessions
|
||||
alias Towerops.Organizations
|
||||
alias Towerops.Snmp.Device
|
||||
alias Towerops.Snmp.Interface
|
||||
alias ToweropsWeb.Api.MobileController
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
|
|
@ -87,8 +89,6 @@ defmodule ToweropsWeb.Api.MobileControllerTest do
|
|||
end
|
||||
|
||||
describe "format_alert_status/1" do
|
||||
alias ToweropsWeb.Api.MobileController
|
||||
|
||||
test "resolved wins over acknowledged" do
|
||||
alert = %{resolved_at: ~U[2026-01-01 00:00:00Z], acknowledged_at: ~U[2026-01-01 00:00:00Z]}
|
||||
assert "resolved" == MobileController.format_alert_status(alert)
|
||||
|
|
@ -106,8 +106,6 @@ defmodule ToweropsWeb.Api.MobileControllerTest do
|
|||
end
|
||||
|
||||
describe "timeticks_to_string/1" do
|
||||
alias ToweropsWeb.Api.MobileController
|
||||
|
||||
test "days when over a day" do
|
||||
timeticks = (2 * 86_400 + 3 * 3600) * 100
|
||||
assert "2d 3h" == MobileController.timeticks_to_string(timeticks)
|
||||
|
|
@ -143,8 +141,6 @@ defmodule ToweropsWeb.Api.MobileControllerTest do
|
|||
end
|
||||
|
||||
test "get_device handler 404s on unknown id (direct call)" do
|
||||
alias ToweropsWeb.Api.MobileController
|
||||
|
||||
user = user_fixture()
|
||||
conn = Plug.Conn.assign(build_conn(), :current_user, user)
|
||||
conn = MobileController.get_device(conn, %{"id" => Ecto.UUID.generate()})
|
||||
|
|
@ -152,8 +148,6 @@ defmodule ToweropsWeb.Api.MobileControllerTest do
|
|||
end
|
||||
|
||||
test "get_device handler returns 403 for cross-org device (direct call)" do
|
||||
alias ToweropsWeb.Api.MobileController
|
||||
|
||||
user = user_fixture()
|
||||
other_user = user_fixture()
|
||||
{:ok, other_org} = Organizations.create_organization(%{name: "Other2"}, other_user.id)
|
||||
|
|
@ -174,8 +168,6 @@ defmodule ToweropsWeb.Api.MobileControllerTest do
|
|||
|
||||
test "get_device direct call formats sensors and interfaces from SNMP device",
|
||||
%{user: user, organization: org} do
|
||||
alias ToweropsWeb.Api.MobileController
|
||||
|
||||
{:ok, site} =
|
||||
Towerops.Sites.create_site(%{name: "Detail Site", organization_id: org.id})
|
||||
|
||||
|
|
@ -211,9 +203,6 @@ defmodule ToweropsWeb.Api.MobileControllerTest do
|
|||
|
||||
test "get_device direct call maps interfaces when SNMP device has them",
|
||||
%{user: user, organization: org} do
|
||||
alias Towerops.Snmp.Interface
|
||||
alias ToweropsWeb.Api.MobileController
|
||||
|
||||
{:ok, site} =
|
||||
Towerops.Sites.create_site(%{name: "Iface Site", organization_id: org.id})
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ defmodule ToweropsWeb.Api.V1.AgentReleaseWebhookControllerTest do
|
|||
use Oban.Testing, repo: Towerops.Repo
|
||||
|
||||
alias Towerops.Workers.AgentReleaseWebhookWorker
|
||||
alias ToweropsWeb.Api.V1.AgentReleaseWebhookController
|
||||
|
||||
setup do
|
||||
conn =
|
||||
|
|
@ -62,8 +63,6 @@ defmodule ToweropsWeb.Api.V1.AgentReleaseWebhookControllerTest do
|
|||
end
|
||||
|
||||
describe "check_timestamp/1" do
|
||||
alias ToweropsWeb.Api.V1.AgentReleaseWebhookController
|
||||
|
||||
test "valid recent timestamp is :ok" do
|
||||
now = System.system_time(:second)
|
||||
assert :ok == AgentReleaseWebhookController.check_timestamp(to_string(now))
|
||||
|
|
@ -91,8 +90,6 @@ defmodule ToweropsWeb.Api.V1.AgentReleaseWebhookControllerTest do
|
|||
end
|
||||
|
||||
describe "parse_signature_header/1" do
|
||||
alias ToweropsWeb.Api.V1.AgentReleaseWebhookController
|
||||
|
||||
test "parses standard header" do
|
||||
header = "t=1234567890,v1=abcdef123"
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ defmodule ToweropsWeb.GraphQL.Resolvers.CheckTest do
|
|||
|
||||
alias Towerops.ApiTokens
|
||||
alias Towerops.Monitoring
|
||||
alias ToweropsWeb.GraphQL.Resolvers.Check, as: Resolver
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
|
|
@ -274,8 +275,6 @@ defmodule ToweropsWeb.GraphQL.Resolvers.CheckTest do
|
|||
end
|
||||
|
||||
describe "resolver fallback clauses (no organization in context)" do
|
||||
alias ToweropsWeb.GraphQL.Resolvers.Check, as: Resolver
|
||||
|
||||
test "list/3 returns auth error" do
|
||||
assert {:error, _} = Resolver.list(nil, %{}, %{context: %{}})
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ defmodule ToweropsWeb.Admin.OrgLive.IndexTest do
|
|||
use ToweropsWeb.ConnCase, async: true
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
import Towerops.OrganizationsFixtures
|
||||
|
||||
alias Towerops.Organizations.Organization
|
||||
|
||||
|
|
@ -204,8 +205,6 @@ defmodule ToweropsWeb.Admin.OrgLive.IndexTest do
|
|||
end
|
||||
|
||||
test "shows confirmation dialog before saving", %{conn: conn, user: user} do
|
||||
import Towerops.OrganizationsFixtures
|
||||
|
||||
_org1 =
|
||||
organization_fixture(user.id, %{
|
||||
subscription_status: "active",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ defmodule ToweropsWeb.CoverageLive.IndexTest do
|
|||
import Towerops.CoveragesFixtures
|
||||
import Towerops.OrganizationsFixtures
|
||||
|
||||
alias ToweropsWeb.CoverageLive.Index, as: Idx
|
||||
|
||||
setup :register_and_log_in_user
|
||||
|
||||
setup %{conn: conn, user: user} do
|
||||
|
|
@ -62,8 +64,6 @@ defmodule ToweropsWeb.CoverageLive.IndexTest do
|
|||
end
|
||||
|
||||
describe "status_badge_class/1" do
|
||||
alias ToweropsWeb.CoverageLive.Index, as: Idx
|
||||
|
||||
test "maps known statuses to themed classes" do
|
||||
assert Idx.status_badge_class("ready") =~ "bg-green"
|
||||
assert Idx.status_badge_class("failed") =~ "bg-red"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ defmodule ToweropsWeb.CoverageLive.MapTest do
|
|||
import Towerops.OrganizationsFixtures
|
||||
|
||||
alias Towerops.Coverages
|
||||
alias ToweropsWeb.CoverageLive.Map, as: M
|
||||
|
||||
setup :register_and_log_in_user
|
||||
|
||||
|
|
@ -111,8 +112,6 @@ defmodule ToweropsWeb.CoverageLive.MapTest do
|
|||
end
|
||||
|
||||
describe "format helpers" do
|
||||
alias ToweropsWeb.CoverageLive.Map, as: M
|
||||
|
||||
test "fmt_distance converts to mi or km" do
|
||||
assert M.fmt_distance(1609.344, "ft") == "1.00 mi"
|
||||
assert M.fmt_distance(1000, "m") == "1.00 km"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ defmodule ToweropsWeb.CoverageLive.ShowTest do
|
|||
import Towerops.OrganizationsFixtures
|
||||
|
||||
alias Towerops.Coverages
|
||||
alias ToweropsWeb.CoverageLive.Show
|
||||
|
||||
setup :register_and_log_in_user
|
||||
|
||||
|
|
@ -128,8 +129,6 @@ defmodule ToweropsWeb.CoverageLive.ShowTest do
|
|||
end
|
||||
|
||||
describe "coverage_lat / coverage_lon helpers" do
|
||||
alias ToweropsWeb.CoverageLive.Show
|
||||
|
||||
test "coverage_lat returns the coverage's latitude when present", %{org: org, site: site} do
|
||||
cov = coverage_fixture(org.id, site.id)
|
||||
valid? = is_number(Show.coverage_lat(cov)) or Show.coverage_lat(cov) == nil
|
||||
|
|
@ -144,8 +143,6 @@ defmodule ToweropsWeb.CoverageLive.ShowTest do
|
|||
end
|
||||
|
||||
describe "format helpers" do
|
||||
alias ToweropsWeb.CoverageLive.Show
|
||||
|
||||
test "format_ft converts metres to feet" do
|
||||
assert Show.format_ft(30.0) == "98 ft"
|
||||
assert Show.format_ft(nil) == "—"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ defmodule ToweropsWeb.DeviceLive.FormTest do
|
|||
import Phoenix.LiveViewTest
|
||||
|
||||
alias Towerops.Snmp.Device
|
||||
alias Towerops.Snmp.Device, as: SnmpDevice
|
||||
|
||||
setup :register_and_log_in_user
|
||||
|
||||
|
|
@ -77,8 +78,8 @@ defmodule ToweropsWeb.DeviceLive.FormTest do
|
|||
|
||||
# Create SNMP device with MikroTik manufacturer (using Towerops.Snmp.Device schema)
|
||||
_snmp_device =
|
||||
%Device{}
|
||||
|> Device.changeset(%{
|
||||
%SnmpDevice{}
|
||||
|> SnmpDevice.changeset(%{
|
||||
device_id: device.id,
|
||||
manufacturer: "MikroTik",
|
||||
sys_descr: "RouterOS 7.8",
|
||||
|
|
@ -104,8 +105,6 @@ defmodule ToweropsWeb.DeviceLive.FormTest do
|
|||
site: site,
|
||||
organization: organization
|
||||
} do
|
||||
alias Device, as: SnmpDevice
|
||||
|
||||
# Create a device with non-MikroTik SNMP discovery data
|
||||
{:ok, device} =
|
||||
Towerops.Devices.create_device(%{
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue