test: GraphQL.Resolvers.EscalationPolicy + MobileController list_alerts formatting
This commit is contained in:
parent
f8af326deb
commit
91b0cac164
2 changed files with 215 additions and 1 deletions
|
|
@ -5,6 +5,7 @@ defmodule ToweropsWeb.Api.MobileControllerTest do
|
|||
|
||||
alias Towerops.MobileSessions
|
||||
alias Towerops.Organizations
|
||||
alias Towerops.Snmp.Device
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
|
|
@ -188,7 +189,7 @@ defmodule ToweropsWeb.Api.MobileControllerTest do
|
|||
})
|
||||
|
||||
{:ok, _snmp} =
|
||||
Towerops.Repo.insert(%Towerops.Snmp.Device{
|
||||
Towerops.Repo.insert(%Device{
|
||||
device_id: device.id,
|
||||
sys_uptime: (5 * 3600 + 30 * 60) * 100,
|
||||
sys_descr: "test"
|
||||
|
|
@ -208,4 +209,35 @@ defmodule ToweropsWeb.Api.MobileControllerTest do
|
|||
assert body["uptime"] =~ "h"
|
||||
end
|
||||
end
|
||||
|
||||
describe "list_alerts — formatting" do
|
||||
test "returns formatted alert with status mapping", %{conn: conn, organization: org} do
|
||||
{:ok, site} = Towerops.Sites.create_site(%{name: "Alert Site", organization_id: org.id})
|
||||
|
||||
{:ok, device} =
|
||||
Towerops.Devices.create_device(%{
|
||||
name: "Alert-Dev",
|
||||
ip_address: "10.20.30.40",
|
||||
site_id: site.id,
|
||||
organization_id: org.id
|
||||
})
|
||||
|
||||
{:ok, _alert} =
|
||||
Towerops.Alerts.create_alert(%{
|
||||
device_id: device.id,
|
||||
alert_type: "device_down",
|
||||
triggered_at: ~U[2026-01-01 00:00:00Z],
|
||||
message: "down"
|
||||
})
|
||||
|
||||
response = get(conn, ~p"/api/v1/mobile/organizations/#{org.id}/alerts")
|
||||
%{"alerts" => alerts} = json_response(response, 200)
|
||||
|
||||
[a] = alerts
|
||||
assert a["status"] == "active"
|
||||
assert a["message"] == "down"
|
||||
assert a["equipment_name"] == "Alert-Dev"
|
||||
assert a["device_id"] == device.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
182
test/towerops_web/graphql/resolvers/escalation_policy_test.exs
Normal file
182
test/towerops_web/graphql/resolvers/escalation_policy_test.exs
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
defmodule ToweropsWeb.GraphQL.Resolvers.EscalationPolicyTest do
|
||||
use Towerops.DataCase, async: true
|
||||
|
||||
import Towerops.AccountsFixtures
|
||||
import Towerops.OnCallFixtures
|
||||
import Towerops.OrganizationsFixtures
|
||||
|
||||
alias ToweropsWeb.GraphQL.Resolvers.EscalationPolicy, as: Resolver
|
||||
|
||||
setup do
|
||||
user = user_fixture()
|
||||
org = organization_fixture(user.id)
|
||||
other_user = user_fixture()
|
||||
other_org = organization_fixture(other_user.id)
|
||||
|
||||
%{user: user, org: org, other_org: other_org, ctx: %{organization_id: org.id}}
|
||||
end
|
||||
|
||||
describe "list/3" do
|
||||
test "returns policies for the org", %{org: org, ctx: ctx} do
|
||||
_p = escalation_policy_fixture(org.id, %{name: "P1"})
|
||||
assert {:ok, [policy]} = Resolver.list(nil, %{}, %{context: ctx})
|
||||
assert policy.name == "P1"
|
||||
end
|
||||
|
||||
test "without org context returns auth error" do
|
||||
assert {:error, _} = Resolver.list(nil, %{}, %{})
|
||||
end
|
||||
end
|
||||
|
||||
describe "get/3" do
|
||||
test "returns the policy preloaded with rules + targets", %{org: org, ctx: ctx} do
|
||||
policy = escalation_policy_fixture(org.id)
|
||||
assert {:ok, found} = Resolver.get(nil, %{id: policy.id}, %{context: ctx})
|
||||
assert found.id == policy.id
|
||||
end
|
||||
|
||||
test "returns error for cross-org id", %{other_org: other_org, ctx: ctx} do
|
||||
foreign = escalation_policy_fixture(other_org.id)
|
||||
|
||||
assert {:error, "Escalation policy not found"} =
|
||||
Resolver.get(nil, %{id: foreign.id}, %{context: ctx})
|
||||
end
|
||||
|
||||
test "without org context returns auth error" do
|
||||
assert {:error, _} = Resolver.get(nil, %{id: Ecto.UUID.generate()}, %{})
|
||||
end
|
||||
end
|
||||
|
||||
describe "create/3" do
|
||||
test "creates a policy under the resolved org", %{ctx: ctx} do
|
||||
assert {:ok, policy} =
|
||||
Resolver.create(nil, %{input: %{name: "Created"}}, %{context: ctx})
|
||||
|
||||
assert policy.name == "Created"
|
||||
assert policy.organization_id == ctx.organization_id
|
||||
end
|
||||
|
||||
test "returns formatted errors on invalid input", %{ctx: ctx} do
|
||||
assert {:error, errors} = Resolver.create(nil, %{input: %{name: ""}}, %{context: ctx})
|
||||
assert is_list(errors) or is_binary(errors) or is_map(errors)
|
||||
end
|
||||
|
||||
test "without org context returns auth error" do
|
||||
assert {:error, _} = Resolver.create(nil, %{input: %{name: "x"}}, %{})
|
||||
end
|
||||
end
|
||||
|
||||
describe "update/3 and delete/3" do
|
||||
test "update + delete a policy round-trip", %{org: org, ctx: ctx} do
|
||||
policy = escalation_policy_fixture(org.id, %{name: "Original"})
|
||||
|
||||
assert {:ok, updated} =
|
||||
Resolver.update(nil, %{id: policy.id, input: %{name: "Renamed"}}, %{context: ctx})
|
||||
|
||||
assert updated.name == "Renamed"
|
||||
|
||||
assert {:ok, %{success: true}} = Resolver.delete(nil, %{id: policy.id}, %{context: ctx})
|
||||
end
|
||||
|
||||
test "update without org context returns auth error" do
|
||||
assert {:error, _} =
|
||||
Resolver.update(nil, %{id: Ecto.UUID.generate(), input: %{name: "x"}}, %{})
|
||||
end
|
||||
|
||||
test "delete without org context returns auth error" do
|
||||
assert {:error, _} = Resolver.delete(nil, %{id: Ecto.UUID.generate()}, %{})
|
||||
end
|
||||
|
||||
test "delete returns 'not found' for cross-org id",
|
||||
%{other_org: other_org, ctx: ctx} do
|
||||
foreign = escalation_policy_fixture(other_org.id)
|
||||
assert {:error, _} = Resolver.delete(nil, %{id: foreign.id}, %{context: ctx})
|
||||
end
|
||||
end
|
||||
|
||||
describe "rule + target mutations" do
|
||||
setup %{org: org} do
|
||||
policy = escalation_policy_fixture(org.id)
|
||||
rule = escalation_rule_fixture(policy.id, %{position: 0, timeout_minutes: 5})
|
||||
%{policy: policy, rule: rule}
|
||||
end
|
||||
|
||||
test "create_rule attaches a rule to the policy",
|
||||
%{policy: policy, ctx: ctx} do
|
||||
assert {:ok, _rule} =
|
||||
Resolver.create_rule(
|
||||
nil,
|
||||
%{
|
||||
escalation_policy_id: policy.id,
|
||||
input: %{position: 1, timeout_minutes: 5}
|
||||
},
|
||||
%{context: ctx}
|
||||
)
|
||||
end
|
||||
|
||||
test "create_rule without context returns auth error" do
|
||||
assert {:error, _} =
|
||||
Resolver.create_rule(
|
||||
nil,
|
||||
%{escalation_policy_id: Ecto.UUID.generate(), input: %{}},
|
||||
%{}
|
||||
)
|
||||
end
|
||||
|
||||
test "update_rule and delete_rule round-trip",
|
||||
%{rule: rule, ctx: ctx} do
|
||||
assert {:ok, _} =
|
||||
Resolver.update_rule(nil, %{id: rule.id, input: %{timeout_minutes: 10}}, %{
|
||||
context: ctx
|
||||
})
|
||||
|
||||
assert {:ok, %{success: true}} = Resolver.delete_rule(nil, %{id: rule.id}, %{context: ctx})
|
||||
end
|
||||
|
||||
test "update_rule + delete_rule auth errors without context" do
|
||||
assert {:error, _} =
|
||||
Resolver.update_rule(nil, %{id: Ecto.UUID.generate(), input: %{}}, %{})
|
||||
|
||||
assert {:error, _} = Resolver.delete_rule(nil, %{id: Ecto.UUID.generate()}, %{})
|
||||
end
|
||||
|
||||
test "create_target attaches a target to a rule",
|
||||
%{rule: rule, user: user, ctx: ctx} do
|
||||
assert {:ok, _target} =
|
||||
Resolver.create_target(
|
||||
nil,
|
||||
%{
|
||||
escalation_rule_id: rule.id,
|
||||
input: %{target_type: "user", user_id: user.id}
|
||||
},
|
||||
%{context: ctx}
|
||||
)
|
||||
end
|
||||
|
||||
test "create_target auth error without context" do
|
||||
assert {:error, _} =
|
||||
Resolver.create_target(
|
||||
nil,
|
||||
%{escalation_rule_id: Ecto.UUID.generate(), input: %{}},
|
||||
%{}
|
||||
)
|
||||
end
|
||||
|
||||
test "delete_target removes the target",
|
||||
%{rule: rule, user: user, ctx: ctx} do
|
||||
target = escalation_target_fixture(rule.id, %{target_type: "user", user_id: user.id})
|
||||
|
||||
assert {:ok, %{success: true}} =
|
||||
Resolver.delete_target(nil, %{id: target.id}, %{context: ctx})
|
||||
end
|
||||
|
||||
test "delete_target on missing id returns 'not found'", %{ctx: ctx} do
|
||||
assert {:error, _} =
|
||||
Resolver.delete_target(nil, %{id: Ecto.UUID.generate()}, %{context: ctx})
|
||||
end
|
||||
|
||||
test "delete_target auth error without context" do
|
||||
assert {:error, _} = Resolver.delete_target(nil, %{id: Ecto.UUID.generate()}, %{})
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue