credo fixes
This commit is contained in:
parent
5bb55180a7
commit
0abe522582
55 changed files with 157 additions and 11 deletions
18
.credo.exs
18
.credo.exs
|
|
@ -173,15 +173,15 @@
|
||||||
{Jump.CredoChecks.AvoidFunctionLevelElse},
|
{Jump.CredoChecks.AvoidFunctionLevelElse},
|
||||||
{Jump.CredoChecks.AvoidLoggerConfigureInTest},
|
{Jump.CredoChecks.AvoidLoggerConfigureInTest},
|
||||||
{Jump.CredoChecks.AvoidSocketAssignsInTest, [excluded: ["test/support/live_view_test_helpers.ex"]]},
|
{Jump.CredoChecks.AvoidSocketAssignsInTest, [excluded: ["test/support/live_view_test_helpers.ex"]]},
|
||||||
{Jump.CredoChecks.ConditionalAssertion}
|
{Jump.CredoChecks.ConditionalAssertion},
|
||||||
# {Jump.CredoChecks.DoctestIExExamples,
|
{Jump.CredoChecks.DoctestIExExamples,
|
||||||
# [
|
[
|
||||||
# derive_test_path: fn filename ->
|
derive_test_path: fn filename ->
|
||||||
# filename
|
filename
|
||||||
# |> String.replace_leading("lib/", "test/")
|
|> String.replace_leading("lib/", "test/")
|
||||||
# |> String.replace_trailing(".ex", "_test.exs")
|
|> String.replace_trailing(".ex", "_test.exs")
|
||||||
# end
|
end
|
||||||
# ]},
|
]}
|
||||||
# {Jump.CredoChecks.ForbiddenFunction,
|
# {Jump.CredoChecks.ForbiddenFunction,
|
||||||
# [
|
# [
|
||||||
# functions: [
|
# functions: [
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ defmodule Towerops.Agents.Stats do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
iex> org_id = Ecto.UUID.generate()
|
||||||
iex> get_organization_agent_health(org_id)
|
iex> get_organization_agent_health(org_id)
|
||||||
[
|
[
|
||||||
%{
|
%{
|
||||||
|
|
@ -85,6 +86,7 @@ defmodule Towerops.Agents.Stats do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
iex> org_id = Ecto.UUID.generate()
|
||||||
iex> get_device_assignment_breakdown(org_id)
|
iex> get_device_assignment_breakdown(org_id)
|
||||||
%{
|
%{
|
||||||
direct: 50,
|
direct: 50,
|
||||||
|
|
@ -152,6 +154,7 @@ defmodule Towerops.Agents.Stats do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
iex> agent_id = Ecto.UUID.generate()
|
||||||
iex> get_agent_metric_stats(agent_id)
|
iex> get_agent_metric_stats(agent_id)
|
||||||
%{
|
%{
|
||||||
total_metrics: 1440,
|
total_metrics: 1440,
|
||||||
|
|
@ -225,6 +228,7 @@ defmodule Towerops.Agents.Stats do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
iex> org_id = Ecto.UUID.generate()
|
||||||
iex> get_offline_agents(org_id)
|
iex> get_offline_agents(org_id)
|
||||||
[
|
[
|
||||||
%{id: "uuid", name: "DC2 Agent", last_seen_at: ~U[2026-01-14 10:00:00Z]}
|
%{id: "uuid", name: "DC2 Agent", last_seen_at: ~U[2026-01-14 10:00:00Z]}
|
||||||
|
|
@ -252,6 +256,7 @@ defmodule Towerops.Agents.Stats do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
iex> org_id = Ecto.UUID.generate()
|
||||||
iex> get_high_load_agents(org_id)
|
iex> get_high_load_agents(org_id)
|
||||||
[
|
[
|
||||||
%{id: "uuid", name: "DC1 Agent", device_count: 75}
|
%{id: "uuid", name: "DC1 Agent", device_count: 75}
|
||||||
|
|
@ -284,6 +289,7 @@ defmodule Towerops.Agents.Stats do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
iex> org_id = Ecto.UUID.generate()
|
||||||
iex> get_unmonitored_devices(org_id)
|
iex> get_unmonitored_devices(org_id)
|
||||||
[
|
[
|
||||||
%{id: "uuid", name: "Switch-01", site_name: "DC1"}
|
%{id: "uuid", name: "Switch-01", site_name: "DC1"}
|
||||||
|
|
@ -325,6 +331,7 @@ defmodule Towerops.Agents.Stats do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
iex> device_id = Ecto.UUID.generate()
|
||||||
iex> get_device_latency_by_agent(device_id, min_checks: 10)
|
iex> get_device_latency_by_agent(device_id, min_checks: 10)
|
||||||
[
|
[
|
||||||
%{agent_token_id: "uuid-1", avg_latency_ms: 12.5, check_count: 120},
|
%{agent_token_id: "uuid-1", avg_latency_ms: 12.5, check_count: 120},
|
||||||
|
|
@ -363,6 +370,7 @@ defmodule Towerops.Agents.Stats do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
iex> device_id = Ecto.UUID.generate()
|
||||||
iex> get_device_assignment_with_latency(device_id)
|
iex> get_device_assignment_with_latency(device_id)
|
||||||
%{
|
%{
|
||||||
device_id: "uuid",
|
device_id: "uuid",
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ defmodule Towerops.EctoTypes.IpAddress do
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> IpAddress.new("192.168.1.1")
|
iex> IpAddress.new("192.168.1.1")
|
||||||
{:ok, %IpAddress{address: "192.168.1.1", version: :ipv4}}
|
{:ok, %IpAddress{address: "192.168.1.1", version: :ipv4, tuple: {192, 168, 1, 1}}}
|
||||||
|
|
||||||
iex> IpAddress.new("invalid")
|
iex> IpAddress.new("invalid")
|
||||||
:error
|
:error
|
||||||
|
|
@ -129,7 +129,7 @@ defmodule Towerops.EctoTypes.IpAddress do
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> IpAddress.new!("192.168.1.1")
|
iex> IpAddress.new!("192.168.1.1")
|
||||||
%IpAddress{address: "192.168.1.1", version: :ipv4}
|
%IpAddress{address: "192.168.1.1", version: :ipv4, tuple: {192, 168, 1, 1}}
|
||||||
|
|
||||||
iex> IpAddress.new!("invalid")
|
iex> IpAddress.new!("invalid")
|
||||||
** (ArgumentError) invalid IP address: "invalid"
|
** (ArgumentError) invalid IP address: "invalid"
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpLib.ASN1Test do
|
||||||
|
|
||||||
alias SnmpKit.SnmpLib.ASN1
|
alias SnmpKit.SnmpLib.ASN1
|
||||||
|
|
||||||
|
doctest ASN1
|
||||||
|
|
||||||
@moduletag :unit
|
@moduletag :unit
|
||||||
@moduletag :protocol
|
@moduletag :protocol
|
||||||
@moduletag :phase_2
|
@moduletag :phase_2
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpLib.HostParserTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpLib.HostParser
|
alias SnmpKit.SnmpLib.HostParser
|
||||||
|
|
||||||
|
doctest HostParser
|
||||||
|
|
||||||
@moduletag :unit
|
@moduletag :unit
|
||||||
@moduletag :host_parser
|
@moduletag :host_parser
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ defmodule SnmpKit.SnmpLib.MIB.CompilerTest do
|
||||||
alias SnmpKit.SnmpLib.MIB.Compiler
|
alias SnmpKit.SnmpLib.MIB.Compiler
|
||||||
alias SnmpKit.SnmpLib.MIB.Parser
|
alias SnmpKit.SnmpLib.MIB.Parser
|
||||||
|
|
||||||
|
doctest Compiler, except: [compile: 1, compile_string: 1, compile_string: 2, load_compiled: 1, compile_all: 1]
|
||||||
|
|
||||||
# Skip these tests if yecc is not available (requires :parsetools)
|
# Skip these tests if yecc is not available (requires :parsetools)
|
||||||
@moduletag :yecc_required
|
@moduletag :yecc_required
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpLib.MIB.ErrorTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpLib.MIB.Error
|
alias SnmpKit.SnmpLib.MIB.Error
|
||||||
|
|
||||||
|
doctest Error
|
||||||
|
|
||||||
describe "new/2" do
|
describe "new/2" do
|
||||||
test "creates error with type and message" do
|
test "creates error with type and message" do
|
||||||
error = Error.new(:syntax_error)
|
error = Error.new(:syntax_error)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpLib.MIB.RegistryTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpLib.MIB.Registry
|
alias SnmpKit.SnmpLib.MIB.Registry
|
||||||
|
|
||||||
|
doctest Registry, except: [walk_tree: 1]
|
||||||
|
|
||||||
describe "resolve_name/1" do
|
describe "resolve_name/1" do
|
||||||
test "resolves standard MIB names" do
|
test "resolves standard MIB names" do
|
||||||
assert {:ok, [1, 3, 6, 1, 2, 1, 1, 1]} = Registry.resolve_name("sysDescr")
|
assert {:ok, [1, 3, 6, 1, 2, 1, 1, 1]} = Registry.resolve_name("sysDescr")
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpLib.OIDTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpLib.OID
|
alias SnmpKit.SnmpLib.OID
|
||||||
|
|
||||||
|
doctest OID
|
||||||
|
|
||||||
@moduletag :unit
|
@moduletag :unit
|
||||||
@moduletag :protocol
|
@moduletag :protocol
|
||||||
@moduletag :phase_2
|
@moduletag :phase_2
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpLib.PDUTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpLib.PDU
|
alias SnmpKit.SnmpLib.PDU
|
||||||
|
|
||||||
|
doctest PDU
|
||||||
|
|
||||||
@moduletag :unit
|
@moduletag :unit
|
||||||
@moduletag :protocol
|
@moduletag :protocol
|
||||||
@moduletag :phase_1
|
@moduletag :phase_1
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ defmodule SnmpKit.SnmpLib.TransportTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpLib.Transport
|
alias SnmpKit.SnmpLib.Transport
|
||||||
|
|
||||||
|
doctest Transport
|
||||||
|
|
||||||
@moduletag :unit
|
@moduletag :unit
|
||||||
@moduletag :protocol
|
@moduletag :protocol
|
||||||
@moduletag :phase_2
|
@moduletag :phase_2
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpLib.TypesTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpLib.Types
|
alias SnmpKit.SnmpLib.Types
|
||||||
|
|
||||||
|
doctest Types
|
||||||
|
|
||||||
@moduletag :unit
|
@moduletag :unit
|
||||||
@moduletag :protocol
|
@moduletag :protocol
|
||||||
@moduletag :phase_2
|
@moduletag :phase_2
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpMgr.BulkTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpMgr.Bulk
|
alias SnmpKit.SnmpMgr.Bulk
|
||||||
|
|
||||||
|
doctest Bulk
|
||||||
|
|
||||||
describe "get_bulk/3 version validation" do
|
describe "get_bulk/3 version validation" do
|
||||||
test "rejects SNMPv1 with error" do
|
test "rejects SNMPv1 with error" do
|
||||||
result = Bulk.get_bulk("192.168.1.1", [1, 3, 6, 1, 2, 1, 1], version: :v1)
|
result = Bulk.get_bulk("192.168.1.1", [1, 3, 6, 1, 2, 1, 1], version: :v1)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpMgr.ErrorsTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpMgr.Errors
|
alias SnmpKit.SnmpMgr.Errors
|
||||||
|
|
||||||
|
doctest Errors
|
||||||
|
|
||||||
describe "code_to_atom/1" do
|
describe "code_to_atom/1" do
|
||||||
test "converts standard SNMP error codes to atoms" do
|
test "converts standard SNMP error codes to atoms" do
|
||||||
assert Errors.code_to_atom(0) == :no_error
|
assert Errors.code_to_atom(0) == :no_error
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpMgr.FormatTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpMgr.Format
|
alias SnmpKit.SnmpMgr.Format
|
||||||
|
|
||||||
|
doctest Format
|
||||||
|
|
||||||
describe "pretty_print/1 - new functionality" do
|
describe "pretty_print/1 - new functionality" do
|
||||||
test "formats 3-tuple results with type-aware formatting" do
|
test "formats 3-tuple results with type-aware formatting" do
|
||||||
# Test timeticks formatting (delegates to SnmpKit.SnmpLib.Types)
|
# Test timeticks formatting (delegates to SnmpKit.SnmpLib.Types)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ defmodule SnmpKit.SnmpMgr.MIBTest do
|
||||||
alias SnmpKit.SnmpLib.MIB.Parser
|
alias SnmpKit.SnmpLib.MIB.Parser
|
||||||
alias SnmpKit.SnmpMgr.MIB
|
alias SnmpKit.SnmpMgr.MIB
|
||||||
|
|
||||||
|
doctest MIB
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
# Start the MIB GenServer if not already running
|
# Start the MIB GenServer if not already running
|
||||||
case GenServer.whereis(MIB) do
|
case GenServer.whereis(MIB) do
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpMgr.TypesTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpMgr.Types
|
alias SnmpKit.SnmpMgr.Types
|
||||||
|
|
||||||
|
doctest Types
|
||||||
|
|
||||||
describe "encode_value/2 with automatic type inference" do
|
describe "encode_value/2 with automatic type inference" do
|
||||||
test "infers string type for printable binary" do
|
test "infers string type for printable binary" do
|
||||||
assert {:ok, {:string, "Hello World"}} = Types.encode_value("Hello World")
|
assert {:ok, {:string, "Hello World"}} = Types.encode_value("Hello World")
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule SnmpKit.SnmpMgr.WalkTest do
|
||||||
|
|
||||||
alias SnmpKit.SnmpMgr.Walk
|
alias SnmpKit.SnmpMgr.Walk
|
||||||
|
|
||||||
|
doctest Walk
|
||||||
|
|
||||||
# Test helpers to mock Core module behavior
|
# Test helpers to mock Core module behavior
|
||||||
defmodule CoreMock do
|
defmodule CoreMock do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.Accounts.HIBPTest do
|
||||||
|
|
||||||
alias Towerops.Accounts.HIBP
|
alias Towerops.Accounts.HIBP
|
||||||
|
|
||||||
|
doctest HIBP, except: [check_password: 1]
|
||||||
|
|
||||||
describe "check_password/1 with non-binary input" do
|
describe "check_password/1 with non-binary input" do
|
||||||
test "returns {:ok, :unknown} for nil" do
|
test "returns {:ok, :unknown} for nil" do
|
||||||
assert {:ok, :unknown} = HIBP.check_password(nil)
|
assert {:ok, :unknown} = HIBP.check_password(nil)
|
||||||
|
|
|
||||||
36
test/towerops/accounts/passwords_test.exs
Normal file
36
test/towerops/accounts/passwords_test.exs
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
defmodule Towerops.Accounts.PasswordsTest do
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
alias Towerops.Accounts.Passwords
|
||||||
|
|
||||||
|
# The module's @doc examples reference undefined variables (`user`, `url`) and
|
||||||
|
# use `...` placeholder syntax, which are not valid standalone doctests.
|
||||||
|
# Manual tests cover each function instead.
|
||||||
|
# doctest Towerops.Accounts.Passwords
|
||||||
|
|
||||||
|
alias Towerops.Accounts.User
|
||||||
|
|
||||||
|
describe "change_user_password/3" do
|
||||||
|
test "returns an Ecto.Changeset with default empty attrs" do
|
||||||
|
user = %User{}
|
||||||
|
|
||||||
|
assert %Ecto.Changeset{data: %User{}} =
|
||||||
|
Passwords.change_user_password(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns an Ecto.Changeset with provided attrs" do
|
||||||
|
user = %User{email: "test@example.com"}
|
||||||
|
attrs = %{password: "new-valid-password-123!", password_confirmation: "new-valid-password-123!"}
|
||||||
|
|
||||||
|
assert %Ecto.Changeset{data: %User{}} =
|
||||||
|
Passwords.change_user_password(user, attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns an Ecto.Changeset with opts" do
|
||||||
|
user = %User{email: "test@example.com"}
|
||||||
|
attrs = %{password: "new-valid-password-123!", password_confirmation: "new-valid-password-123!"}
|
||||||
|
|
||||||
|
assert %Ecto.Changeset{} = Passwords.change_user_password(user, attrs, [])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -10,6 +10,8 @@ defmodule Towerops.AccountsTest do
|
||||||
alias Towerops.GeoIP.Block
|
alias Towerops.GeoIP.Block
|
||||||
alias Towerops.GeoIP.Location
|
alias Towerops.GeoIP.Location
|
||||||
|
|
||||||
|
doctest Accounts
|
||||||
|
|
||||||
describe "get_user_by_email/1" do
|
describe "get_user_by_email/1" do
|
||||||
test "does not return the user if the email does not exist" do
|
test "does not return the user if the email does not exist" do
|
||||||
refute Accounts.get_user_by_email("unknown@example.com")
|
refute Accounts.get_user_by_email("unknown@example.com")
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ defmodule Towerops.Admin.AuditLoggerTest do
|
||||||
alias Towerops.Admin.AuditLog
|
alias Towerops.Admin.AuditLog
|
||||||
alias Towerops.Admin.AuditLogger
|
alias Towerops.Admin.AuditLogger
|
||||||
|
|
||||||
|
doctest AuditLogger
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
actor = user_fixture()
|
actor = user_fixture()
|
||||||
target = user_fixture()
|
target = user_fixture()
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ defmodule Towerops.AdminTest do
|
||||||
alias Towerops.Admin
|
alias Towerops.Admin
|
||||||
alias Towerops.Organizations.Organization
|
alias Towerops.Organizations.Organization
|
||||||
|
|
||||||
|
doctest Admin, except: [delete_user: 3, delete_organization: 3, create_audit_log: 1]
|
||||||
|
|
||||||
describe "create_audit_log/1" do
|
describe "create_audit_log/1" do
|
||||||
test "creates audit log with valid attributes" do
|
test "creates audit log with valid attributes" do
|
||||||
superuser = user_fixture(%{superuser: true})
|
superuser = user_fixture(%{superuser: true})
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.Agents.AgentTokenTest do
|
||||||
|
|
||||||
alias Towerops.Agents.AgentToken
|
alias Towerops.Agents.AgentToken
|
||||||
|
|
||||||
|
doctest AgentToken
|
||||||
|
|
||||||
describe "build_token/3" do
|
describe "build_token/3" do
|
||||||
test "generates a token with 48 bytes of entropy" do
|
test "generates a token with 48 bytes of entropy" do
|
||||||
org_id = Ecto.UUID.generate()
|
org_id = Ecto.UUID.generate()
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ defmodule Towerops.Agents.StatsTest do
|
||||||
alias Towerops.Snmp.Sensor
|
alias Towerops.Snmp.Sensor
|
||||||
alias Towerops.Snmp.SensorReading
|
alias Towerops.Snmp.SensorReading
|
||||||
|
|
||||||
|
doctest Stats
|
||||||
|
|
||||||
describe "get_organization_agent_health/1" do
|
describe "get_organization_agent_health/1" do
|
||||||
test "returns empty list for organization with no agents" do
|
test "returns empty list for organization with no agents" do
|
||||||
user = user_fixture()
|
user = user_fixture()
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ defmodule Towerops.AgentsTest do
|
||||||
alias Towerops.Agents.AgentCache
|
alias Towerops.Agents.AgentCache
|
||||||
alias Towerops.Agents.AgentToken
|
alias Towerops.Agents.AgentToken
|
||||||
|
|
||||||
|
doctest Agents
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
user = user_fixture()
|
user = user_fixture()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ defmodule Towerops.ApiTokensTest do
|
||||||
alias Towerops.ApiTokens
|
alias Towerops.ApiTokens
|
||||||
alias Towerops.ApiTokens.ApiToken
|
alias Towerops.ApiTokens.ApiToken
|
||||||
|
|
||||||
|
doctest ApiTokens
|
||||||
|
|
||||||
describe "create_api_token/1" do
|
describe "create_api_token/1" do
|
||||||
setup do
|
setup do
|
||||||
user = user_fixture()
|
user = user_fixture()
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ defmodule Towerops.BillingTest do
|
||||||
alias Towerops.Organizations.Organization
|
alias Towerops.Organizations.Organization
|
||||||
alias Towerops.Settings.ApplicationSetting
|
alias Towerops.Settings.ApplicationSetting
|
||||||
|
|
||||||
|
doctest Billing
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
user = user_fixture()
|
user = user_fixture()
|
||||||
organization = organization_fixture(user.id)
|
organization = organization_fixture(user.id)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ defmodule Towerops.Devices.FirmwareTest do
|
||||||
alias Towerops.Devices.Firmware
|
alias Towerops.Devices.Firmware
|
||||||
alias Towerops.Snmp.Device, as: SnmpDevice
|
alias Towerops.Snmp.Device, as: SnmpDevice
|
||||||
|
|
||||||
|
doctest Firmware
|
||||||
|
|
||||||
describe "upsert_firmware_release/1" do
|
describe "upsert_firmware_release/1" do
|
||||||
test "creates a new firmware release" do
|
test "creates a new firmware release" do
|
||||||
attrs = %{
|
attrs = %{
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.Devices.MikrotikBackups.DifferTest do
|
||||||
|
|
||||||
alias Towerops.Devices.MikrotikBackups.Differ
|
alias Towerops.Devices.MikrotikBackups.Differ
|
||||||
|
|
||||||
|
doctest Differ
|
||||||
|
|
||||||
describe "mask_sensitive_data/1" do
|
describe "mask_sensitive_data/1" do
|
||||||
test "masks passwords in user set commands" do
|
test "masks passwords in user set commands" do
|
||||||
config = "/user set admin password=SuperSecret123"
|
config = "/user set admin password=SuperSecret123"
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.Devices.VersionComparatorTest do
|
||||||
|
|
||||||
alias Towerops.Devices.VersionComparator
|
alias Towerops.Devices.VersionComparator
|
||||||
|
|
||||||
|
doctest VersionComparator
|
||||||
|
|
||||||
describe "compare/2" do
|
describe "compare/2" do
|
||||||
test "returns :eq for equal versions" do
|
test "returns :eq for equal versions" do
|
||||||
assert VersionComparator.compare("7.14.1", "7.14.1") == :eq
|
assert VersionComparator.compare("7.14.1", "7.14.1") == :eq
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ defmodule Towerops.EquipmentTest do
|
||||||
alias Towerops.Devices
|
alias Towerops.Devices
|
||||||
alias Towerops.Devices.Device
|
alias Towerops.Devices.Device
|
||||||
|
|
||||||
|
doctest Devices
|
||||||
|
|
||||||
describe "device" do
|
describe "device" do
|
||||||
import Towerops.AccountsFixtures
|
import Towerops.AccountsFixtures
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.EctoTypes.IpAddressTest do
|
||||||
|
|
||||||
alias Towerops.EctoTypes.IpAddress
|
alias Towerops.EctoTypes.IpAddress
|
||||||
|
|
||||||
|
doctest IpAddress
|
||||||
|
|
||||||
describe "type/0" do
|
describe "type/0" do
|
||||||
test "returns :string" do
|
test "returns :string" do
|
||||||
assert IpAddress.type() == :string
|
assert IpAddress.type() == :string
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.EctoTypes.MacAddressTest do
|
||||||
|
|
||||||
alias Towerops.EctoTypes.MacAddress
|
alias Towerops.EctoTypes.MacAddress
|
||||||
|
|
||||||
|
doctest MacAddress
|
||||||
|
|
||||||
describe "type/0" do
|
describe "type/0" do
|
||||||
test "returns :string" do
|
test "returns :string" do
|
||||||
assert MacAddress.type() == :string
|
assert MacAddress.type() == :string
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.EctoTypes.SnmpOidTest do
|
||||||
|
|
||||||
alias Towerops.EctoTypes.SnmpOid
|
alias Towerops.EctoTypes.SnmpOid
|
||||||
|
|
||||||
|
doctest SnmpOid
|
||||||
|
|
||||||
describe "type/0" do
|
describe "type/0" do
|
||||||
test "returns :string" do
|
test "returns :string" do
|
||||||
assert SnmpOid.type() == :string
|
assert SnmpOid.type() == :string
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ defmodule Towerops.Gaiia.SubscriberMatchingTest do
|
||||||
alias Towerops.Gaiia.SubscriberMatching
|
alias Towerops.Gaiia.SubscriberMatching
|
||||||
alias Towerops.Repo
|
alias Towerops.Repo
|
||||||
|
|
||||||
|
doctest SubscriberMatching, except: [normalize_mac: 1]
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
user = user_fixture()
|
user = user_fixture()
|
||||||
org = organization_fixture(user.id)
|
org = organization_fixture(user.id)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ defmodule Towerops.GaiiaTest do
|
||||||
alias Towerops.Gaiia
|
alias Towerops.Gaiia
|
||||||
alias Towerops.Snmp.Device
|
alias Towerops.Snmp.Device
|
||||||
|
|
||||||
|
doctest Gaiia
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
user = user_fixture()
|
user = user_fixture()
|
||||||
org = organization_fixture(user.id)
|
org = organization_fixture(user.id)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ defmodule Towerops.MobileSessionsTest do
|
||||||
alias Towerops.MobileSessions.MobileSession
|
alias Towerops.MobileSessions.MobileSession
|
||||||
alias Towerops.MobileSessions.QRLoginToken
|
alias Towerops.MobileSessions.QRLoginToken
|
||||||
|
|
||||||
|
doctest MobileSessions
|
||||||
|
|
||||||
defp valid_session_attrs(user) do
|
defp valid_session_attrs(user) do
|
||||||
%{
|
%{
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.NumericTest do
|
||||||
|
|
||||||
alias Towerops.Numeric
|
alias Towerops.Numeric
|
||||||
|
|
||||||
|
doctest Numeric
|
||||||
|
|
||||||
describe "parse_integer/1" do
|
describe "parse_integer/1" do
|
||||||
test "returns {:ok, int} for integer" do
|
test "returns {:ok, int} for integer" do
|
||||||
assert {:ok, 42} = Numeric.parse_integer(42)
|
assert {:ok, 42} = Numeric.parse_integer(42)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ defmodule Towerops.Organizations.PolicyTest do
|
||||||
alias Towerops.Organizations.Membership
|
alias Towerops.Organizations.Membership
|
||||||
alias Towerops.Organizations.Policy
|
alias Towerops.Organizations.Policy
|
||||||
|
|
||||||
|
doctest Policy
|
||||||
|
|
||||||
describe "can?/3" do
|
describe "can?/3" do
|
||||||
test "owner can do everything" do
|
test "owner can do everything" do
|
||||||
membership = %Membership{role: :owner}
|
membership = %Membership{role: :owner}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ defmodule Towerops.Organizations.SubscriptionLimitsTest do
|
||||||
alias Towerops.Organizations.SubscriptionLimits
|
alias Towerops.Organizations.SubscriptionLimits
|
||||||
alias Towerops.Sites
|
alias Towerops.Sites
|
||||||
|
|
||||||
|
doctest SubscriptionLimits
|
||||||
|
|
||||||
describe "device_limit/1" do
|
describe "device_limit/1" do
|
||||||
test "returns 10 for free plan" do
|
test "returns 10 for free plan" do
|
||||||
assert SubscriptionLimits.device_limit("free") == 10
|
assert SubscriptionLimits.device_limit("free") == 10
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ defmodule Towerops.OrganizationsTest do
|
||||||
alias Towerops.Organizations
|
alias Towerops.Organizations
|
||||||
alias Towerops.Organizations.Organization
|
alias Towerops.Organizations.Organization
|
||||||
|
|
||||||
|
doctest Organizations
|
||||||
|
|
||||||
describe "organizations" do
|
describe "organizations" do
|
||||||
setup do
|
setup do
|
||||||
user = user_fixture()
|
user = user_fixture()
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.Settings.ApplicationSettingTest do
|
||||||
|
|
||||||
alias Towerops.Settings.ApplicationSetting
|
alias Towerops.Settings.ApplicationSetting
|
||||||
|
|
||||||
|
doctest ApplicationSetting
|
||||||
|
|
||||||
describe "parse_value/1" do
|
describe "parse_value/1" do
|
||||||
test "returns nil for nil value" do
|
test "returns nil for nil value" do
|
||||||
setting = %ApplicationSetting{value: nil, value_type: "string"}
|
setting = %ApplicationSetting{value: nil, value_type: "string"}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ defmodule Towerops.SettingsTest do
|
||||||
alias Towerops.Settings
|
alias Towerops.Settings
|
||||||
alias Towerops.Settings.ApplicationSetting
|
alias Towerops.Settings.ApplicationSetting
|
||||||
|
|
||||||
|
doctest Settings
|
||||||
|
|
||||||
# Ensure the migration-seeded setting exists (CI may have stale test DB)
|
# Ensure the migration-seeded setting exists (CI may have stale test DB)
|
||||||
setup do
|
setup do
|
||||||
if !Settings.get_setting_record("global_default_cloud_poller_id") do
|
if !Settings.get_setting_record("global_default_cloud_poller_id") do
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ defmodule Towerops.Snmp.AgentDiscoveryTest do
|
||||||
alias Towerops.Snmp.AgentDiscovery
|
alias Towerops.Snmp.AgentDiscovery
|
||||||
alias Towerops.Snmp.Device, as: DiscoveredDevice
|
alias Towerops.Snmp.Device, as: DiscoveredDevice
|
||||||
|
|
||||||
|
doctest AgentDiscovery, except: [process_agent_discovery: 2]
|
||||||
|
|
||||||
describe "process_agent_discovery/2 — failure paths" do
|
describe "process_agent_discovery/2 — failure paths" do
|
||||||
test "empty oid_values returns :agent_collected_no_data" do
|
test "empty oid_values returns :agent_collected_no_data" do
|
||||||
device = DevicesFixtures.device_fixture()
|
device = DevicesFixtures.device_fixture()
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ defmodule Towerops.Snmp.ClientTest do
|
||||||
alias Towerops.Snmp.Client
|
alias Towerops.Snmp.Client
|
||||||
alias Towerops.Snmp.SnmpMock
|
alias Towerops.Snmp.SnmpMock
|
||||||
|
|
||||||
|
doctest Client
|
||||||
|
|
||||||
# Set up mocks
|
# Set up mocks
|
||||||
setup :verify_on_exit!
|
setup :verify_on_exit!
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ defmodule Towerops.Snmp.DiscoveryTest do
|
||||||
alias Towerops.Snmp.Sensor
|
alias Towerops.Snmp.Sensor
|
||||||
alias Towerops.Snmp.SnmpMock
|
alias Towerops.Snmp.SnmpMock
|
||||||
|
|
||||||
|
doctest Discovery
|
||||||
|
|
||||||
setup :verify_on_exit!
|
setup :verify_on_exit!
|
||||||
|
|
||||||
# Stub get_multiple and get to provide generic fallbacks
|
# Stub get_multiple and get to provide generic fallbacks
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.Snmp.SensorScaleTest do
|
||||||
|
|
||||||
alias Towerops.Snmp.SensorScale
|
alias Towerops.Snmp.SensorScale
|
||||||
|
|
||||||
|
doctest SensorScale
|
||||||
|
|
||||||
describe "normalize/2 — temperature" do
|
describe "normalize/2 — temperature" do
|
||||||
test "passes plausible whole-degree readings through unchanged" do
|
test "passes plausible whole-degree readings through unchanged" do
|
||||||
assert SensorScale.normalize("temperature", 36.0) == 36.0
|
assert SensorScale.normalize("temperature", 36.0) == 36.0
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ defmodule Towerops.SnmpTest do
|
||||||
alias Towerops.Snmp.WirelessClient
|
alias Towerops.Snmp.WirelessClient
|
||||||
alias Towerops.Snmp.WirelessClientReading
|
alias Towerops.Snmp.WirelessClientReading
|
||||||
|
|
||||||
|
doctest Snmp
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
user = user_fixture()
|
user = user_fixture()
|
||||||
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ defmodule Towerops.Topology.LldpTest do
|
||||||
alias Towerops.Topology.Lldp
|
alias Towerops.Topology.Lldp
|
||||||
alias Towerops.Topology.Lldp.Parser
|
alias Towerops.Topology.Lldp.Parser
|
||||||
|
|
||||||
|
doctest Lldp
|
||||||
|
|
||||||
setup :verify_on_exit!
|
setup :verify_on_exit!
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule Towerops.URLValidatorTest do
|
||||||
|
|
||||||
alias Towerops.URLValidator
|
alias Towerops.URLValidator
|
||||||
|
|
||||||
|
doctest URLValidator
|
||||||
|
|
||||||
describe "validate/1" do
|
describe "validate/1" do
|
||||||
test "accepts valid https URL" do
|
test "accepts valid https URL" do
|
||||||
assert :ok = URLValidator.validate("https://example.com")
|
assert :ok = URLValidator.validate("https://example.com")
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ defmodule Towerops.Workers.FirmwareVersionFetcherWorkerTest do
|
||||||
alias Towerops.Devices.Firmware
|
alias Towerops.Devices.Firmware
|
||||||
alias Towerops.Workers.FirmwareVersionFetcherWorker
|
alias Towerops.Workers.FirmwareVersionFetcherWorker
|
||||||
|
|
||||||
|
doctest FirmwareVersionFetcherWorker
|
||||||
|
|
||||||
describe "perform/1" do
|
describe "perform/1" do
|
||||||
test "returns :ok and inserts a release on a valid RSS response" do
|
test "returns :ok and inserts a release on a valid RSS response" do
|
||||||
Req.Test.stub(FirmwareVersionFetcherWorker, fn conn ->
|
Req.Test.stub(FirmwareVersionFetcherWorker, fn conn ->
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ defmodule ToweropsWeb.Helpers.StatusHelpersTest do
|
||||||
alias Towerops.Sites
|
alias Towerops.Sites
|
||||||
alias ToweropsWeb.Helpers.StatusHelpers
|
alias ToweropsWeb.Helpers.StatusHelpers
|
||||||
|
|
||||||
|
doctest StatusHelpers
|
||||||
|
|
||||||
describe "status_emoji/1" do
|
describe "status_emoji/1" do
|
||||||
test "returns green for nil organization" do
|
test "returns green for nil organization" do
|
||||||
assert StatusHelpers.status_emoji(nil) == "🟢"
|
assert StatusHelpers.status_emoji(nil) == "🟢"
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ defmodule ToweropsWeb.TimeHelpersTest do
|
||||||
|
|
||||||
alias ToweropsWeb.TimeHelpers
|
alias ToweropsWeb.TimeHelpers
|
||||||
|
|
||||||
|
doctest TimeHelpers
|
||||||
|
|
||||||
describe "to_user_timezone/2" do
|
describe "to_user_timezone/2" do
|
||||||
test "returns shifted datetime and abbreviation for known timezone" do
|
test "returns shifted datetime and abbreviation for known timezone" do
|
||||||
datetime = ~U[2026-01-15 14:34:00Z]
|
datetime = ~U[2026-01-15 14:34:00Z]
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ defmodule ToweropsWeb.PermissionsTest do
|
||||||
alias Towerops.Repo
|
alias Towerops.Repo
|
||||||
alias ToweropsWeb.Permissions
|
alias ToweropsWeb.Permissions
|
||||||
|
|
||||||
|
doctest Permissions, except: [can?: 3, owner?: 1, admin?: 1]
|
||||||
|
|
||||||
describe "can?/3 with superuser" do
|
describe "can?/3 with superuser" do
|
||||||
setup do
|
setup do
|
||||||
user = user_fixture(%{is_superuser: true})
|
user = user_fixture(%{is_superuser: true})
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue