Tests for agents, alerts, integrations, organization, members, and invitations controllers. Refactor alert filters to reduce complexity. 75 new tests, all passing.
187 lines
5.7 KiB
Elixir
187 lines
5.7 KiB
Elixir
defmodule ToweropsWeb.Api.V1.AgentsControllerTest do
|
|
use ToweropsWeb.ConnCase, async: true
|
|
|
|
import Towerops.AccountsFixtures
|
|
import Towerops.AgentsFixtures
|
|
import Towerops.OrganizationsFixtures
|
|
|
|
alias Towerops.ApiTokens
|
|
|
|
setup do
|
|
user = user_fixture()
|
|
organization = organization_fixture(user.id)
|
|
|
|
{:ok, {_token, raw_token}} =
|
|
ApiTokens.create_api_token(%{
|
|
organization_id: organization.id,
|
|
user_id: user.id,
|
|
name: "Test Token"
|
|
})
|
|
|
|
conn =
|
|
build_conn()
|
|
|> put_req_header("authorization", "Bearer #{raw_token}")
|
|
|> put_req_header("accept", "application/json")
|
|
|
|
%{
|
|
conn: conn,
|
|
user: user,
|
|
organization: organization
|
|
}
|
|
end
|
|
|
|
describe "index/2" do
|
|
test "lists agents for the authenticated organization", %{
|
|
conn: conn,
|
|
organization: organization
|
|
} do
|
|
{:ok, agent1, _raw1} = agent_token_fixture(organization.id, "Agent Alpha")
|
|
{:ok, agent2, _raw2} = agent_token_fixture(organization.id, "Agent Beta")
|
|
|
|
conn = get(conn, ~p"/api/v1/agents")
|
|
|
|
assert %{"data" => agents} = json_response(conn, 200)
|
|
assert length(agents) == 2
|
|
|
|
agent_ids = Enum.map(agents, & &1["id"])
|
|
assert agent1.id in agent_ids
|
|
assert agent2.id in agent_ids
|
|
|
|
agent_json = List.first(agents)
|
|
assert Map.has_key?(agent_json, "id")
|
|
assert Map.has_key?(agent_json, "name")
|
|
assert Map.has_key?(agent_json, "enabled")
|
|
assert Map.has_key?(agent_json, "last_seen_at")
|
|
assert Map.has_key?(agent_json, "last_ip")
|
|
assert Map.has_key?(agent_json, "metadata")
|
|
assert Map.has_key?(agent_json, "inserted_at")
|
|
end
|
|
|
|
test "returns empty list when organization has no agents", %{conn: conn} do
|
|
conn = get(conn, ~p"/api/v1/agents")
|
|
|
|
assert %{"data" => []} = json_response(conn, 200)
|
|
end
|
|
|
|
test "does not return agents from other organizations", %{conn: conn} do
|
|
other_user = user_fixture()
|
|
other_org = organization_fixture(other_user.id)
|
|
|
|
{:ok, _other_agent, _raw} = agent_token_fixture(other_org.id)
|
|
|
|
conn = get(conn, ~p"/api/v1/agents")
|
|
|
|
assert %{"data" => agents} = json_response(conn, 200)
|
|
assert Enum.empty?(agents)
|
|
end
|
|
end
|
|
|
|
describe "create/2" do
|
|
test "creates agent with valid name and returns token", %{
|
|
conn: conn,
|
|
organization: organization
|
|
} do
|
|
conn = post(conn, ~p"/api/v1/agents", %{"name" => "New Agent"})
|
|
|
|
assert %{"data" => agent} = json_response(conn, 201)
|
|
assert agent["name"] == "New Agent"
|
|
assert is_binary(agent["id"])
|
|
assert is_binary(agent["token"])
|
|
assert agent["enabled"] == true
|
|
|
|
# Verify the agent was created in the correct organization
|
|
created = Towerops.Agents.get_agent_token!(agent["id"])
|
|
assert created.organization_id == organization.id
|
|
end
|
|
|
|
test "returns 400 without name parameter", %{conn: conn} do
|
|
conn = post(conn, ~p"/api/v1/agents", %{})
|
|
|
|
assert %{"error" => "Missing 'name' parameter"} = json_response(conn, 400)
|
|
end
|
|
end
|
|
|
|
describe "show/2" do
|
|
test "returns agent with device_count", %{conn: conn, organization: organization} do
|
|
{:ok, agent, _raw} = agent_token_fixture(organization.id, "Show Agent")
|
|
|
|
conn = get(conn, ~p"/api/v1/agents/#{agent.id}")
|
|
|
|
assert %{"data" => data} = json_response(conn, 200)
|
|
assert data["id"] == agent.id
|
|
assert data["name"] == "Show Agent"
|
|
assert Map.has_key?(data, "device_count")
|
|
assert data["device_count"] == 0
|
|
end
|
|
|
|
test "returns 404 for non-existent agent", %{conn: conn} do
|
|
conn = get(conn, ~p"/api/v1/agents/#{Ecto.UUID.generate()}")
|
|
|
|
assert %{"error" => "Agent not found"} = json_response(conn, 404)
|
|
end
|
|
|
|
test "returns 404 for agent in another organization", %{conn: conn} do
|
|
other_user = user_fixture()
|
|
other_org = organization_fixture(other_user.id)
|
|
|
|
{:ok, other_agent, _raw} = agent_token_fixture(other_org.id)
|
|
|
|
conn = get(conn, ~p"/api/v1/agents/#{other_agent.id}")
|
|
|
|
assert %{"error" => "Agent not found"} = json_response(conn, 404)
|
|
end
|
|
end
|
|
|
|
describe "delete/2" do
|
|
test "removes agent and returns 204", %{conn: conn, organization: organization} do
|
|
{:ok, agent, _raw} = agent_token_fixture(organization.id)
|
|
|
|
conn = delete(conn, ~p"/api/v1/agents/#{agent.id}")
|
|
|
|
assert response(conn, 204)
|
|
|
|
# Verify the agent was deleted
|
|
assert_raise Ecto.NoResultsError, fn ->
|
|
Towerops.Agents.get_agent_token!(agent.id)
|
|
end
|
|
end
|
|
|
|
test "returns 404 for non-existent agent", %{conn: conn} do
|
|
conn = delete(conn, ~p"/api/v1/agents/#{Ecto.UUID.generate()}")
|
|
|
|
assert %{"error" => "Agent not found"} = json_response(conn, 404)
|
|
end
|
|
|
|
test "returns 404 for agent in another organization", %{conn: conn} do
|
|
other_user = user_fixture()
|
|
other_org = organization_fixture(other_user.id)
|
|
|
|
{:ok, other_agent, _raw} = agent_token_fixture(other_org.id)
|
|
|
|
conn = delete(conn, ~p"/api/v1/agents/#{other_agent.id}")
|
|
|
|
assert %{"error" => "Agent not found"} = json_response(conn, 404)
|
|
end
|
|
end
|
|
|
|
describe "authentication" do
|
|
test "returns 401 without authorization header" do
|
|
conn =
|
|
build_conn()
|
|
|> put_req_header("accept", "application/json")
|
|
|> get(~p"/api/v1/agents")
|
|
|
|
assert %{"error" => _message} = json_response(conn, 401)
|
|
end
|
|
|
|
test "returns 401 with invalid token" do
|
|
conn =
|
|
build_conn()
|
|
|> put_req_header("authorization", "Bearer towerops_invalid_token")
|
|
|> put_req_header("accept", "application/json")
|
|
|> get(~p"/api/v1/agents")
|
|
|
|
assert %{"error" => _message} = json_response(conn, 401)
|
|
end
|
|
end
|
|
end
|