towerops/test/towerops_web/graphql/resolvers/escalation_policy_test.exs

182 lines
6.1 KiB
Elixir

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 Enum.any?([is_list(errors), is_binary(errors), 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