fix snmp v3 test

This commit is contained in:
Graham McIntire 2026-02-06 10:21:54 -06:00
parent 4d980ed58a
commit ed50257d8a
No known key found for this signature in database
12 changed files with 171 additions and 115 deletions

View file

@ -359,10 +359,20 @@ defmodule ToweropsWeb.AgentChannel do
{:noreply, socket}
else
{:error, {type, message}} ->
Logger.error("Invalid credential test result from agent",
Logger.error(
"Invalid credential test result from agent: #{type} - #{message}",
agent_token_id: socket.assigns.agent_token_id,
error_type: type,
error_message: message
error_message: message,
binary_size: byte_size(binary_b64)
)
{:noreply, socket}
{:error, :base64_decode_failed} ->
Logger.error("Failed to decode credential test result (invalid base64)",
agent_token_id: socket.assigns.agent_token_id,
binary_size: byte_size(binary_b64)
)
{:noreply, socket}

View file

@ -269,6 +269,8 @@ 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)
@ -278,6 +280,17 @@ defmodule ToweropsWeb.DeviceLive.Form do
device_map = build_device_map_with_credentials(form_data, resolved_credentials)
effective_agent_id = determine_effective_agent_id(device_map, socket.assigns)
# Debug logging for SNMPv3 credential testing
Logger.debug(
"SNMPv3 test credentials: version=#{device_map["snmp_version"]}, " <>
"security_level=#{inspect(device_map["snmpv3_security_level"])}, " <>
"username=#{inspect(device_map["snmpv3_username"])}, " <>
"auth_protocol=#{inspect(device_map["snmpv3_auth_protocol"])}, " <>
"auth_password_present=#{!is_nil(device_map["snmpv3_auth_password"])}, " <>
"priv_protocol=#{inspect(device_map["snmpv3_priv_protocol"])}, " <>
"priv_password_present=#{!is_nil(device_map["snmpv3_priv_password"])}"
)
handle_snmp_test(socket, device_map, effective_agent_id)
end
@ -312,17 +325,18 @@ defmodule ToweropsWeb.DeviceLive.Form do
defp resolve_snmpv3_credentials_for_test(form_data, changeset, assigns) do
changes = changeset.changes
# Check if credentials are explicitly set in form
if Map.has_key?(changes, :snmpv3_username) && form_data.snmpv3_username do
# Use form values
# Check if device has credentials (either from DB or form input)
if form_data.snmpv3_username && form_data.snmpv3_username != "" do
# Use device-level values
# For passwords, prefer changeset changes (newly entered), fall back to DB values
%{
version: "3",
security_level: form_data.snmpv3_security_level,
username: form_data.snmpv3_username,
auth_protocol: form_data.snmpv3_auth_protocol,
auth_password: Map.get(changes, :snmpv3_auth_password),
auth_password: Map.get(changes, :snmpv3_auth_password) || form_data.snmpv3_auth_password,
priv_protocol: form_data.snmpv3_priv_protocol,
priv_password: Map.get(changes, :snmpv3_priv_password)
priv_password: Map.get(changes, :snmpv3_priv_password) || form_data.snmpv3_priv_password
}
else
# Inherit from site or org
@ -422,7 +436,7 @@ defmodule ToweropsWeb.DeviceLive.Form do
end
defp handle_snmp_test(socket, device_map, effective_agent_id) do
test_id = "test:#{Ecto.UUID.generate()}"
test_id = Ecto.UUID.generate()
case send_credential_test_to_agent(effective_agent_id, device_map, test_id) do
:ok ->

View file

@ -216,7 +216,8 @@ defmodule SnmpKit.SnmpLib.MIB.ErrorTest do
# Should not crash with options
assert is_binary(Error.format(error, color: true))
assert is_binary(Error.format(error, verbose: true))
assert is_binary(Error.format(error, [])) end
assert is_binary(Error.format(error, []))
end
test "formats unexpected_token error with custom message" do
error = Error.new(:unexpected_token, message: "Custom error message", line: 5)
@ -407,13 +408,14 @@ defmodule SnmpKit.SnmpLib.MIB.ErrorTest do
end
test "unexpected_token with all fields" do
error = Error.new(:unexpected_token,
expected: :semicolon,
actual: :comma,
value: ",",
line: 10,
column: 5
)
error =
Error.new(:unexpected_token,
expected: :semicolon,
actual: :comma,
value: ",",
line: 10,
column: 5
)
assert error.message =~ "semicolon"
assert error.message =~ "comma"

View file

@ -3,8 +3,8 @@ defmodule SnmpKit.SnmpLib.MIB.LoggerTest do
import ExUnit.CaptureLog
alias SnmpKit.SnmpLib.MIB.Logger, as: MibLogger
alias SnmpKit.SnmpLib.MIB.Error
alias SnmpKit.SnmpLib.MIB.Logger, as: MibLogger
describe "log_compilation_start/2" do
test "logs compilation start with options" do

View file

@ -538,7 +538,7 @@ defmodule SnmpKit.SnmpLib.MIB.ParserTest do
end
test "tokenize handles many tokens" do
identifiers = Enum.map(1..500, fn i -> "id#{i}" end) |> Enum.join(" ")
identifiers = Enum.map_join(1..500, " ", fn i -> "id#{i}" end)
result = Parser.tokenize(identifiers)
assert {:ok, tokens} = result
assert is_list(tokens)

View file

@ -14,10 +14,11 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
token_types = Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
token_types =
Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
# TEST-MIB is tokenized as :variable (uppercase identifier)
assert :variable in token_types
@ -54,7 +55,7 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
atoms = tokens |> Enum.filter(&match?({:atom, _, _}, &1))
atoms = Enum.filter(tokens, &match?({:atom, _, _}, &1))
assert length(atoms) == 3
end
@ -63,7 +64,7 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
numbers = tokens |> Enum.filter(&match?({:integer, _, _}, &1))
numbers = Enum.filter(tokens, &match?({:integer, _, _}, &1))
assert length(numbers) == 3
end
@ -116,10 +117,11 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
token_types = Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
token_types =
Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
assert :"OBJECT-TYPE" in token_types
assert :SYNTAX in token_types
@ -183,10 +185,11 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
# Comments should be ignored
token_types = Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
token_types =
Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
assert :atom in token_types
assert :"OBJECT-TYPE" in token_types
@ -203,10 +206,11 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
token_types = Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
token_types =
Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
# TEST-MIB is tokenized as :variable (uppercase identifier)
assert :variable in token_types
@ -221,12 +225,13 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
# Tokens should have different line numbers
lines = Enum.map(tokens, fn
{_type, line} -> line
{_type, _value, line} -> line
end)
lines =
Enum.map(tokens, fn
{_type, line} -> line
{_type, _value, line} -> line
end)
assert Enum.uniq(lines) |> length() > 1
assert lines |> Enum.uniq() |> length() > 1
end
test "preserves token order" do
@ -234,7 +239,7 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
atoms = tokens |> Enum.filter(&match?({:atom, _, _}, &1))
atoms = Enum.filter(tokens, &match?({:atom, _, _}, &1))
# Should be in order
assert length(atoms) == 3
@ -255,10 +260,11 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
token_types = Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
token_types =
Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
assert :DEFINITIONS in token_types
assert :BEGIN in token_types
@ -273,10 +279,11 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
token_types = Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
token_types =
Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
assert :SIZE in token_types
end
@ -286,10 +293,11 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
token_types = Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
token_types =
Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
assert :SEQUENCE in token_types
assert :OF in token_types
@ -358,7 +366,7 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
describe "edge cases" do
test "handles very long identifiers" do
# Use a more reasonable length to avoid atom table limits (255 bytes max for atoms)
long_id = String.duplicate("a", 200) |> String.to_charlist()
long_id = "a" |> String.duplicate(200) |> String.to_charlist()
assert {:ok, tokens} = SnmpTokenizer.tokenize(long_id, &SnmpTokenizer.null_get_line/0)
assert length(tokens) >= 1
@ -366,11 +374,11 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
test "handles many tokens" do
# Create input with many identifiers
identifiers = Enum.map(1..100, fn i -> "id#{i}" end) |> Enum.join(" ")
identifiers = Enum.map_join(1..100, " ", fn i -> "id#{i}" end)
input = String.to_charlist(identifiers)
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
atoms = tokens |> Enum.filter(&match?({:atom, _, _}, &1))
atoms = Enum.filter(tokens, &match?({:atom, _, _}, &1))
assert length(atoms) == 100
end
@ -387,10 +395,11 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
token_types = Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
token_types =
Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
# Only "BEGIN" should be recognized as keyword
begin_count = Enum.count(token_types, &(&1 == :BEGIN))
@ -428,10 +437,11 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
token_types = Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
token_types =
Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
assert :atom in token_types
assert :"OBJECT-TYPE" in token_types
@ -443,7 +453,7 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
integers = tokens |> Enum.filter(&match?({:integer, _, _}, &1))
integers = Enum.filter(tokens, &match?({:integer, _, _}, &1))
assert length(integers) == 2
end
@ -452,7 +462,7 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
integers = tokens |> Enum.filter(&match?({:integer, _, _}, &1))
integers = Enum.filter(tokens, &match?({:integer, _, _}, &1))
assert length(integers) == 1
end
end
@ -506,16 +516,17 @@ defmodule SnmpKit.SnmpLib.MIB.SnmpTokenizerTest do
assert {:ok, tokens} = SnmpTokenizer.tokenize(input, &SnmpTokenizer.null_get_line/0)
token_types = Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
token_types =
Enum.map(tokens, fn
{type, _line} -> type
{type, _value, _line} -> type
end)
# OBJECT should be keyword
assert :OBJECT in token_types
# "object" should be an atom (lowercase identifier)
atoms = tokens |> Enum.filter(&match?({:atom, _, _}, &1))
atoms = Enum.filter(tokens, &match?({:atom, _, _}, &1))
assert length(atoms) >= 1
end
end

View file

@ -44,7 +44,7 @@ defmodule SnmpKit.SnmpLib.PDU.EncoderTest do
message = %{
version: 3,
msgID: 1,
msgMaxSize: 65507,
msgMaxSize: 65_507,
msgFlags: <<0x04>>,
msgSecurityModel: 3,
msgSecurityParameters: "",
@ -114,7 +114,7 @@ defmodule SnmpKit.SnmpLib.PDU.EncoderTest do
message = %{
version: 3,
msgID: 1,
msgMaxSize: 65507,
msgMaxSize: 65_507,
msgFlags: <<0x04>>,
msgSecurityModel: 3,
msgSecurityParameters: "",
@ -444,7 +444,7 @@ defmodule SnmpKit.SnmpLib.PDU.EncoderTest do
request_id: 1,
error_status: 0,
error_index: 0,
varbinds: [{[1, 3, 6, 1, 2, 1, 1, 3, 0], :timeticks, 12345678}]
varbinds: [{[1, 3, 6, 1, 2, 1, 1, 3, 0], :timeticks, 12_345_678}]
}
}
@ -653,7 +653,7 @@ defmodule SnmpKit.SnmpLib.PDU.EncoderTest do
varbinds: [
{[1, 3, 6, 1, 2, 1, 2, 1, 10, 1], :auto, {:counter32, 1_234_567}},
{[1, 3, 6, 1, 2, 1, 2, 1, 5, 1], :auto, {:gauge32, 1_000_000}},
{[1, 3, 6, 1, 2, 1, 1, 3, 0], :auto, {:timeticks, 12345}},
{[1, 3, 6, 1, 2, 1, 1, 3, 0], :auto, {:timeticks, 12_345}},
{[1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 6, 1], :auto, {:counter64, 9_876_543_210}}
]
}
@ -1461,7 +1461,7 @@ defmodule SnmpKit.SnmpLib.PDU.EncoderTest do
community: "public",
pdu: %{
type: :get_request,
request_id: 12345,
request_id: 12_345,
error_status: 0,
error_index: 0,
varbinds: [
@ -1483,15 +1483,15 @@ defmodule SnmpKit.SnmpLib.PDU.EncoderTest do
community: "public",
pdu: %{
type: :get_response,
request_id: 12345,
request_id: 12_345,
error_status: 0,
error_index: 0,
varbinds: [
{[1, 3, 6, 1, 2, 1, 1, 1, 0], :octet_string, "Linux router 4.19.0"},
{[1, 3, 6, 1, 2, 1, 1, 3, 0], :timeticks, 123456789},
{[1, 3, 6, 1, 2, 1, 1, 3, 0], :timeticks, 123_456_789},
{[1, 3, 6, 1, 2, 1, 1, 5, 0], :octet_string, "router1.example.com"},
{[1, 3, 6, 1, 2, 1, 1, 7, 0], :integer, 72},
{[1, 3, 6, 1, 2, 1, 2, 1, 10, 1], :counter32, 987654321}
{[1, 3, 6, 1, 2, 1, 2, 1, 10, 1], :counter32, 987_654_321}
]
}
}

View file

@ -19,9 +19,9 @@ defmodule SnmpKit.SnmpLib.PDU.V3EncoderTest do
end
test "creates discovery message with custom msg_id" do
msg = V3Encoder.create_discovery_message(12345)
msg = V3Encoder.create_discovery_message(12_345)
assert msg.msg_id == 12345
assert msg.msg_id == 12_345
assert msg.version == 3
end
@ -84,7 +84,7 @@ defmodule SnmpKit.SnmpLib.PDU.V3EncoderTest do
describe "roundtrip encoding/decoding" do
test "discovery message roundtrip without security" do
original_msg = V3Encoder.create_discovery_message(12345)
original_msg = V3Encoder.create_discovery_message(12_345)
case V3Encoder.encode_message(original_msg, nil) do
{:ok, encoded} ->
@ -450,7 +450,7 @@ defmodule SnmpKit.SnmpLib.PDU.V3EncoderTest do
test "encodes v3 message with multiple varbinds" do
msg = %{
version: 3,
msg_id: 12345,
msg_id: 12_345,
msg_max_size: 65_507,
msg_flags: %{auth: false, priv: false, reportable: true},
msg_security_model: 3,
@ -459,7 +459,7 @@ defmodule SnmpKit.SnmpLib.PDU.V3EncoderTest do
context_name: <<>>,
pdu: %{
type: :get_request,
request_id: 12345,
request_id: 12_345,
error_status: 0,
error_index: 0,
varbinds: [
@ -478,7 +478,7 @@ defmodule SnmpKit.SnmpLib.PDU.V3EncoderTest do
test "encodes v3 response with various value types" do
msg = %{
version: 3,
msg_id: 99999,
msg_id: 99_999,
msg_max_size: 65_507,
msg_flags: %{auth: false, priv: false, reportable: true},
msg_security_model: 3,
@ -487,14 +487,14 @@ defmodule SnmpKit.SnmpLib.PDU.V3EncoderTest do
context_name: <<>>,
pdu: %{
type: :get_response,
request_id: 99999,
request_id: 99_999,
error_status: 0,
error_index: 0,
varbinds: [
{[1, 3, 6, 1, 2, 1, 1, 1, 0], :octet_string, "System description"},
{[1, 3, 6, 1, 2, 1, 1, 3, 0], :timeticks, 123456789},
{[1, 3, 6, 1, 2, 1, 1, 3, 0], :timeticks, 123_456_789},
{[1, 3, 6, 1, 2, 1, 1, 7, 0], :integer, 72},
{[1, 3, 6, 1, 2, 1, 2, 1, 10, 1], :counter32, 987654321}
{[1, 3, 6, 1, 2, 1, 2, 1, 10, 1], :counter32, 987_654_321}
]
}
}

View file

@ -36,5 +36,4 @@ defmodule SnmpKitTest do
end
end
end
end

View file

@ -16,7 +16,7 @@ defmodule Towerops.DevicesFixtures do
# Ensure organization and site exist
organization =
attrs[:organization] || Map.get(attrs, "organization") ||
(if organization_id, do: get_organization(organization_id), else: create_organization())
if organization_id, do: get_organization(organization_id), else: create_organization()
site =
attrs[:site] || Map.get(attrs, "site") || create_site(organization)
@ -58,10 +58,12 @@ defmodule Towerops.DevicesFixtures do
end
defp create_site(organization) do
{:ok, site} = Towerops.Sites.create_site(%{
name: "Test Site #{System.unique_integer([:positive])}",
organization_id: organization.id
})
{:ok, site} =
Towerops.Sites.create_site(%{
name: "Test Site #{System.unique_integer([:positive])}",
organization_id: organization.id
})
site
end
end

View file

@ -470,9 +470,10 @@ defmodule Towerops.Agent.ValidatorTest do
end
test "rejects too many sentences" do
sentences = Enum.map(1..1100, fn _ ->
%MikrotikSentence{attributes: %{}}
end)
sentences =
Enum.map(1..1100, fn _ ->
%MikrotikSentence{attributes: %{}}
end)
result = %MikrotikResult{
device_id: "550e8400-e29b-41d4-a716-446655440000",

View file

@ -16,7 +16,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships)
scope =
Scope.for_user(user)
user
|> Scope.for_user()
|> Scope.put_organization(organization)
%{scope: scope, user: user, organization: organization}
@ -47,7 +48,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships)
scope =
Scope.for_user(user)
user
|> Scope.for_user()
|> Scope.put_organization(organization)
%{scope: scope, user: user, organization: organization}
@ -74,7 +76,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships, force: true)
scope =
Scope.for_user(admin_user)
admin_user
|> Scope.for_user()
|> Scope.put_organization(organization)
%{scope: scope, user: admin_user, organization: organization}
@ -105,7 +108,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships, force: true)
scope =
Scope.for_user(member_user)
member_user
|> Scope.for_user()
|> Scope.put_organization(organization)
%{scope: scope, user: member_user, organization: organization}
@ -167,7 +171,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships, force: true)
scope =
Scope.for_user(viewer_user)
viewer_user
|> Scope.for_user()
|> Scope.put_organization(organization)
%{scope: scope, user: viewer_user, organization: organization}
@ -217,7 +222,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships)
scope =
Scope.for_user(user)
user
|> Scope.for_user()
|> Scope.put_organization(organization)
assert Permissions.owner?(scope)
@ -229,7 +235,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships)
scope =
Scope.for_user(user)
user
|> Scope.for_user()
|> Scope.put_organization(organization)
assert Permissions.owner?(scope)
@ -245,7 +252,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships, force: true)
scope =
Scope.for_user(admin_user)
admin_user
|> Scope.for_user()
|> Scope.put_organization(organization)
refute Permissions.owner?(scope)
@ -261,7 +269,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships, force: true)
scope =
Scope.for_user(member_user)
member_user
|> Scope.for_user()
|> Scope.put_organization(organization)
refute Permissions.owner?(scope)
@ -277,7 +286,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships, force: true)
scope =
Scope.for_user(viewer_user)
viewer_user
|> Scope.for_user()
|> Scope.put_organization(organization)
refute Permissions.owner?(scope)
@ -300,7 +310,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships)
scope =
Scope.for_user(user)
user
|> Scope.for_user()
|> Scope.put_organization(organization)
socket = %Socket{assigns: %{current_scope: scope}}
@ -316,7 +327,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships)
scope =
Scope.for_user(user)
user
|> Scope.for_user()
|> Scope.put_organization(organization)
assert Permissions.admin?(scope)
@ -328,7 +340,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships)
scope =
Scope.for_user(user)
user
|> Scope.for_user()
|> Scope.put_organization(organization)
assert Permissions.admin?(scope)
@ -344,7 +357,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships, force: true)
scope =
Scope.for_user(admin_user)
admin_user
|> Scope.for_user()
|> Scope.put_organization(organization)
assert Permissions.admin?(scope)
@ -360,7 +374,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships, force: true)
scope =
Scope.for_user(member_user)
member_user
|> Scope.for_user()
|> Scope.put_organization(organization)
refute Permissions.admin?(scope)
@ -376,7 +391,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships, force: true)
scope =
Scope.for_user(viewer_user)
viewer_user
|> Scope.for_user()
|> Scope.put_organization(organization)
refute Permissions.admin?(scope)
@ -399,7 +415,8 @@ defmodule ToweropsWeb.PermissionsTest do
organization = Repo.preload(organization, :memberships)
scope =
Scope.for_user(user)
user
|> Scope.for_user()
|> Scope.put_organization(organization)
socket = %Socket{assigns: %{current_scope: scope}}