mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-11-11 15:54:52 +09:00
Players on the watch list are announced to every online admin on every instance when they join, and the join is posted to the Discord and JSON webhooks. The Reports page has a second table for the watch list with an Add button and a Delete button per row. Reports can be marked read or unread from the web interface. Each report row also has an Add to watch list button which opens the add form filled in with the player and reason. Setting exp_reports.watch_unread_reports treats players with unread reports as watched. Reports now store created_at_ms because marking them read changes updated_at_ms. Old reports.json files migrate on load with updated_at_ms as the creation time. The report webhook moved from the datastore update listener to the create handler so reading a report is not posted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
133 lines
6.1 KiB
Lua
133 lines
6.1 KiB
Lua
local Suite = ... --- @type Suite<ExpReports.TestEnv>
|
|
|
|
Suite.test("receive_created() tells everyone and raises on_player_reported", function(env)
|
|
env.add_player{ name = "alice", admin = true }
|
|
local bob = env.add_player{ name = "bob" }
|
|
env.add_player{ name = "carol" }
|
|
local report = env.report("bob", "alice")
|
|
env.Reports.receive_created{ report = report, reports = { report, env.report("bob", "carol") } }
|
|
|
|
Suite.eq(env.printed, {
|
|
{ to = "alice", { "exp-reports.created-admin", "bob", "alice", "griefing" } },
|
|
{ to = "bob", { "exp-reports.created", "bob", "griefing" } },
|
|
{ to = "carol", { "exp-reports.created", "bob", "griefing" } },
|
|
}, "admins see who reported, everyone else only the reason")
|
|
Suite.eq(env.events, {
|
|
{
|
|
name = env.Reports.on_player_reported,
|
|
tick = 1,
|
|
player_index = bob.index,
|
|
by_player_name = "alice",
|
|
reason = "griefing",
|
|
report_count = 2,
|
|
by_player_names = { "alice", "carol" },
|
|
},
|
|
}, "the event carries every report against the player")
|
|
end)
|
|
|
|
Suite.test("receive_created() raises nothing when the reported player has left", function(env)
|
|
env.add_player{ name = "alice" }
|
|
env.add_player{ name = "bob", connected = false }
|
|
local report = env.report("bob", "alice")
|
|
env.Reports.receive_created{ report = report, reports = { report } }
|
|
Suite.eq(env.printed, { { to = "alice", { "exp-reports.created", "bob", "griefing" } } }, "the report is still announced")
|
|
Suite.empty(env.events, "there is nobody to act on")
|
|
end)
|
|
|
|
Suite.test("receive_list() prints the reports against a player to the caller", function(env)
|
|
env.add_player{ name = "alice" }
|
|
env.Reports.receive_list{
|
|
caller = "alice",
|
|
player_name = "bob",
|
|
reports = { env.report("bob", "carol", "spam"), env.report("bob", "dave", "griefing") },
|
|
}
|
|
Suite.eq(env.printed, {
|
|
{ to = "alice", { "exp-reports.list-title", "bob", 2 } },
|
|
{ to = "alice", { "exp-reports.list-entry", "carol", "spam" } },
|
|
{ to = "alice", { "exp-reports.list-entry", "dave", "griefing" } },
|
|
}, "the title is followed by one line per report")
|
|
end)
|
|
|
|
Suite.test("receive_list() prints how many reports each player has", function(env)
|
|
env.add_player{ name = "alice" }
|
|
env.Reports.receive_list{
|
|
caller = "alice",
|
|
reports = { env.report("dave", "alice"), env.report("bob", "carol"), env.report("dave", "carol") },
|
|
}
|
|
Suite.eq(env.printed, {
|
|
{ to = "alice", { "exp-reports.list-all-title" } },
|
|
{ to = "alice", { "exp-reports.list-all-entry", "bob", 1 } },
|
|
{ to = "alice", { "exp-reports.list-all-entry", "dave", 2 } },
|
|
}, "players are listed by name with their count")
|
|
end)
|
|
|
|
Suite.test("receive_list() says when nobody is reported", function(env)
|
|
env.add_player{ name = "alice" }
|
|
env.Reports.receive_list{ caller = "alice", reports = {} }
|
|
Suite.eq(env.printed, { { to = "alice", { "exp-reports.list-all-none" } } }, "the caller is told there are none")
|
|
end)
|
|
|
|
Suite.test("receive_list() prints nothing once the caller has left", function(env)
|
|
env.add_player{ name = "alice", connected = false }
|
|
env.Reports.receive_list{ caller = "alice", reports = { env.report("bob", "carol") } }
|
|
Suite.empty(env.printed, "nothing is printed")
|
|
end)
|
|
|
|
Suite.test("receive_deleted() announces the deletion and raises on_reports_deleted", function(env)
|
|
env.add_player{ name = "alice" }
|
|
local bob = env.add_player{ name = "bob" }
|
|
env.Reports.receive_deleted{ caller = "alice", player_name = "bob", count = 2 }
|
|
Suite.eq(env.printed, { { "exp-reports.deleted", "bob", 2, "alice" } }, "everyone is told")
|
|
Suite.eq(env.events, {
|
|
{ name = env.Reports.on_reports_deleted, tick = 1, player_index = bob.index, by_player_name = "alice", count = 2 },
|
|
}, "the event names who deleted how many")
|
|
end)
|
|
|
|
Suite.test("receive_deleted() tells the caller when there was nothing to delete", function(env)
|
|
env.add_player{ name = "alice" }
|
|
env.add_player{ name = "bob" }
|
|
env.Reports.receive_deleted{ caller = "alice", player_name = "bob", count = 0 }
|
|
Suite.eq(env.printed, { { to = "alice", { "exp-reports.deleted-none", "bob" } } }, "only the caller is told")
|
|
Suite.empty(env.events, "nothing was deleted")
|
|
end)
|
|
|
|
Suite.test("receive_error() prints the refusal to the caller while they are online", function(env)
|
|
env.add_player{ name = "alice" }
|
|
env.add_player{ name = "bob", connected = false }
|
|
env.Reports.receive_error{ caller = "alice", message = "alice has already reported bob" }
|
|
env.Reports.receive_error{ caller = "bob", message = "gone" }
|
|
Suite.eq(env.printed, { { to = "alice", "alice has already reported bob" } }, "the offline player is skipped")
|
|
end)
|
|
|
|
Suite.test("receive_watched_joined() tells only admins why the player is watched", function(env)
|
|
env.add_player{ name = "alice", admin = true }
|
|
env.add_player{ name = "dave", admin = true, connected = false }
|
|
env.add_player{ name = "carol" }
|
|
env.Reports.receive_watched_joined{
|
|
player_name = "bob",
|
|
instance_name = "EXP 2",
|
|
watch_list_entry = { player_name = "bob", reason = "griefing", by_player_name = "admin", created_at_ms = 1000 },
|
|
unread_reports = { env.report("bob", "carol", "spam") },
|
|
}
|
|
Suite.eq(env.printed, {
|
|
{ to = "alice", { "exp-reports.watched-joined", "bob", "EXP 2" } },
|
|
{ to = "alice", { "exp-reports.watched-entry", "admin", "griefing" } },
|
|
{ to = "alice", { "exp-reports.watched-report", "carol", "spam" } },
|
|
}, "the online admin sees the entry and each unread report")
|
|
end)
|
|
|
|
Suite.test("receive_watched_joined() works with only unread reports", function(env)
|
|
env.add_player{ name = "alice", admin = true }
|
|
env.Reports.receive_watched_joined{
|
|
player_name = "bob",
|
|
instance_name = "EXP",
|
|
unread_reports = { env.report("bob", "carol", "spam") },
|
|
}
|
|
Suite.eq(env.printed, {
|
|
{ to = "alice", { "exp-reports.watched-joined", "bob", "EXP" } },
|
|
{ to = "alice", { "exp-reports.watched-report", "carol", "spam" } },
|
|
}, "there is no watch list line")
|
|
end)
|
|
|
|
return Suite.run()
|