Add comprehensive AgentAuth plug tests

Added 8 tests covering all plug functionality:
- init/1 option passing
- Valid token authentication
- Invalid authorization header scenarios
- Malformed Bearer token handling
- Invalid token value rejection
- Asynchronous heartbeat updates
- Token verification error handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Graham McIntire 2026-01-13 08:35:13 -06:00
parent 5bd24b09f9
commit 3fe051fd19
No known key found for this signature in database

View file

@ -0,0 +1,122 @@
defmodule ToweropsWeb.Plugs.AgentAuthTest do
use ToweropsWeb.ConnCase, async: false
import Towerops.AccountsFixtures
alias Towerops.Agents
alias ToweropsWeb.Plugs.AgentAuth
setup %{conn: conn} do
user = user_fixture()
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
{:ok, agent_token, token_string} = Agents.create_agent_token(organization.id, "Test Agent")
# Set format to json for API endpoint
conn =
conn
|> Plug.Conn.fetch_query_params()
|> Phoenix.Controller.put_format("json")
%{conn: conn, organization: organization, agent_token: agent_token, token_string: token_string}
end
describe "init/1" do
test "returns options unchanged" do
opts = [some: :option]
assert AgentAuth.init(opts) == opts
end
end
describe "call/2" do
test "authenticates valid Bearer token", %{conn: conn, agent_token: agent_token, token_string: token_string} do
conn =
conn
|> put_req_header("authorization", "Bearer #{token_string}")
|> AgentAuth.call([])
assert conn.assigns.current_agent_token.id == agent_token.id
refute conn.halted
end
test "rejects missing authorization header", %{conn: conn} do
conn = AgentAuth.call(conn, [])
assert conn.status == 401
assert conn.halted
end
test "rejects invalid Bearer token format", %{conn: conn} do
conn =
conn
|> put_req_header("authorization", "InvalidFormat token123")
|> AgentAuth.call([])
assert conn.status == 401
assert conn.halted
end
test "rejects malformed Bearer token", %{conn: conn} do
conn =
conn
|> put_req_header("authorization", "Bearer")
|> AgentAuth.call([])
assert conn.status == 401
assert conn.halted
end
test "rejects invalid token value", %{conn: conn} do
conn =
conn
|> put_req_header("authorization", "Bearer invalid_token_value")
|> AgentAuth.call([])
assert conn.status == 401
assert conn.halted
end
test "updates agent token heartbeat asynchronously", %{
conn: conn,
agent_token: agent_token,
token_string: token_string
} do
# Get initial last_seen_at
initial_agent_token = Agents.get_agent_token!(agent_token.id)
initial_last_seen = initial_agent_token.last_seen_at
conn =
conn
|> put_req_header("authorization", "Bearer #{token_string}")
|> AgentAuth.call([])
# Wait for async task to complete
Process.sleep(100)
# Verify heartbeat was updated
updated_agent_token = Agents.get_agent_token!(agent_token.id)
if initial_last_seen do
assert DateTime.compare(updated_agent_token.last_seen_at, initial_last_seen) in [:gt, :eq]
else
assert updated_agent_token.last_seen_at
end
assert updated_agent_token.last_ip == "127.0.0.1"
refute conn.halted
end
test "handles token verification error gracefully", %{conn: conn} do
# Use a token that looks valid but doesn't exist
fake_token = String.duplicate("a", 32)
conn =
conn
|> put_req_header("authorization", "Bearer #{fake_token}")
|> AgentAuth.call([])
assert conn.status == 401
assert conn.halted
end
end
end