8.4 KiB · text 5af55d9
defmodule GitGud.ReportsActionsTest do
@moduledoc """
Preview + moderation-action surface used by the admin reports queue.
"""
use GitGud.DataCase, async: false
alias GitGud.Federation.Actor
alias GitGud.Reports
import GitGud.AccountsFixtures
import GitGud.ForgeFixtures
setup do
user = user_fixture()
{_, repo} = repository_fixture(%{owner: user})
{:ok, user: user, repo: repo}
end
describe "preview/1" do
test "issue → title + excerpt + author + url", %{user: user, repo: repo} do
issue = issue_fixture(repo, user, %{"title" => "broken thing", "body" => "wat is this"})
{:ok, report} = Reports.open(user, {"issue", issue.id}, "abuse")
preview = Reports.preview(report)
assert preview.kind == :issue
assert preview.title =~ "broken thing"
assert preview.excerpt =~ "wat is this"
assert preview.url =~ "/issues/#{issue.number}"
assert preview.moderatable?
refute preview.moderated?
refute preview.suspendable_actor_id
end
test "actor → URL + summary; suspendable when remote", %{user: user} do
actor =
GitGud.Repo.insert!(%Actor{
kind: "remote",
actor_type: "Person",
actor_url: "https://remote.example/@spam",
inbox_url: "https://remote.example/@spam/inbox",
preferred_username: "spam",
name: "spam",
summary: "annoying",
public_key_pem: "stub",
public_key_id: "https://remote.example/@spam#k",
remote_doc: %{},
last_fetched_at: DateTime.utc_now(:second)
})
{:ok, report} = Reports.open(user, {"actor", actor.id}, "abuse")
preview = Reports.preview(report)
assert preview.kind == :actor
assert preview.title == "spam@remote.example"
assert preview.url == "/actors/#{actor.id}"
assert preview.suspendable_actor_id == actor.id
refute preview.moderatable?
refute preview.moderated?
end
test "missing target → :missing", %{user: user} do
{:ok, report} = Reports.open(user, {"issue", 999_999}, "abuse")
assert Reports.preview(report) == :missing
end
end
describe "moderate_target/3" do
test "replaces body with mod message, preserves original", %{user: user, repo: repo} do
issue = issue_fixture(repo, user, %{"title" => "x", "body" => "the original body"})
{:ok, report} = Reports.open(user, {"issue", issue.id}, "spam")
admin = user_fixture()
assert {:ok, moderated} = Reports.moderate_target(report, admin, "off-topic")
assert moderated.body == ""
assert moderated.original_body == "the original body"
assert moderated.moderation_note == "off-topic"
assert moderated.moderated_by_id == admin.id
assert moderated.moderated_at
end
test "nil note → default 'Removed by moderator'", %{user: user, repo: repo} do
issue = issue_fixture(repo, user, %{"title" => "x", "body" => "hi"})
{:ok, report} = Reports.open(user, {"issue", issue.id}, "spam")
admin = user_fixture()
assert {:ok, moderated} = Reports.moderate_target(report, admin, nil)
assert moderated.moderation_note == "Removed by moderator"
end
test "whitespace-only note → default", %{user: user, repo: repo} do
issue = issue_fixture(repo, user, %{"title" => "x", "body" => "hi"})
{:ok, report} = Reports.open(user, {"issue", issue.id}, "spam")
admin = user_fixture()
assert {:ok, moderated} = Reports.moderate_target(report, admin, " ")
assert moderated.moderation_note == "Removed by moderator"
end
test "long note clipped to 500 chars", %{user: user, repo: repo} do
issue = issue_fixture(repo, user, %{"title" => "x", "body" => "hi"})
{:ok, report} = Reports.open(user, {"issue", issue.id}, "spam")
admin = user_fixture()
long = String.duplicate("a", 700)
assert {:ok, moderated} = Reports.moderate_target(report, admin, long)
assert String.length(moderated.moderation_note) == 500
end
test "missing row → :not_found", %{user: user} do
{:ok, report} = Reports.open(user, {"issue", 999_999}, "abuse")
admin = user_fixture()
assert {:error, :not_found} = Reports.moderate_target(report, admin, "n")
end
test "unmoderatable target type → :unmoderatable_target_type", %{user: user} do
actor =
GitGud.Repo.insert!(%Actor{
kind: "remote",
actor_type: "Person",
actor_url: "https://example/@x",
inbox_url: "https://example/@x/inbox",
preferred_username: "x",
name: "x",
public_key_pem: "k",
public_key_id: "https://example/@x#k",
remote_doc: %{},
last_fetched_at: DateTime.utc_now(:second)
})
{:ok, report} = Reports.open(user, {"actor", actor.id}, "abuse")
admin = user_fixture()
assert {:error, :unmoderatable_target_type} = Reports.moderate_target(report, admin, "n")
end
test "re-moderating doesn't clobber original_body", %{user: user, repo: repo} do
issue = issue_fixture(repo, user, %{"title" => "x", "body" => "the real text"})
{:ok, report} = Reports.open(user, {"issue", issue.id}, "spam")
admin = user_fixture()
{:ok, _} = Reports.moderate_target(report, admin, "first pass")
{:ok, again} = Reports.moderate_target(report, admin, "second pass")
# Original body should still be the very first body, not "".
assert again.original_body == "the real text"
assert again.moderation_note == "second pass"
end
end
describe "open/4 vs already-moderated content" do
test "refuses new reports once the target is moderated", %{user: user, repo: repo} do
issue = issue_fixture(repo, user)
{:ok, report} = Reports.open(user, {"issue", issue.id}, "spam")
admin = user_fixture()
{:ok, _} = Reports.moderate_target(report, admin, "spam")
another_user = user_fixture()
assert {:error, :already_moderated} =
Reports.open(another_user, {"issue", issue.id}, "spam")
end
test "non-moderatable targets are unaffected (e.g. actors)", %{user: user} do
actor =
GitGud.Repo.insert!(%Actor{
kind: "remote",
actor_type: "Person",
actor_url: "https://example/@y",
inbox_url: "https://example/@y/inbox",
preferred_username: "y",
name: "y",
public_key_pem: "k",
public_key_id: "https://example/@y#k",
remote_doc: %{},
last_fetched_at: DateTime.utc_now(:second)
})
assert {:ok, _} = Reports.open(user, {"actor", actor.id}, "abuse")
end
end
describe "restore_target/1" do
test "puts body back, clears moderation fields", %{user: user, repo: repo} do
issue = issue_fixture(repo, user, %{"title" => "x", "body" => "hello world"})
{:ok, report} = Reports.open(user, {"issue", issue.id}, "spam")
admin = user_fixture()
{:ok, _} = Reports.moderate_target(report, admin, "spam")
assert {:ok, restored} = Reports.restore_target(report)
assert restored.body == "hello world"
refute restored.moderated_at
refute restored.moderation_note
refute restored.moderated_by_id
refute restored.original_body
end
test "non-moderated target → :not_moderated", %{user: user, repo: repo} do
issue = issue_fixture(repo, user)
{:ok, report} = Reports.open(user, {"issue", issue.id}, "spam")
assert {:error, :not_moderated} = Reports.restore_target(report)
end
test "missing row → :not_found", %{user: user} do
{:ok, report} = Reports.open(user, {"issue", 999_999}, "spam")
assert {:error, :not_found} = Reports.restore_target(report)
end
end
describe "suspend_actor/1" do
test "flips status to suspended" do
actor =
GitGud.Repo.insert!(%Actor{
kind: "remote",
actor_type: "Person",
actor_url: "https://example/@x",
inbox_url: "https://example/@x/inbox",
preferred_username: "x",
name: "x",
public_key_pem: "k",
public_key_id: "https://example/@x#k",
remote_doc: %{},
last_fetched_at: DateTime.utc_now(:second)
})
assert {:ok, %Actor{status: "suspended"}} = Reports.suspend_actor(actor.id)
end
test "missing actor → :not_found" do
assert {:error, :not_found} = Reports.suspend_actor(999_999)
end
end
end