mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
feat(dashboard): test a message against the chat filter
GET /api/chat_filter/test?message=&chat=normal|free says whether the filter would stop a message from a player below GM 2, word by word and why: blocked or allowed on the staff lists, in chatplus_en_us.txt, an approved character name, not allowed, in blocklist.dcf, or no blocklist.dcf (free chat then stops everything). It follows dChatFilter::IsSentenceOkay: words split at spaces, normalized the same way. ModerationTools::ExplainMessage, unit tested. Check: dWebTests ChatFilterWordsTest.Explain*; the API with a word from each list, in normal and free chat. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -81,3 +81,43 @@ TEST(ChatFilterWordsTest, DcfHashes) {
|
||||
ASSERT_FALSE(ModerationTools::DcfHashes(bytes.substr(0, bytes.size() - sizeof(size_t) * 2)).has_value());
|
||||
ASSERT_FALSE(ModerationTools::DcfHashes("DCFB").has_value());
|
||||
}
|
||||
|
||||
namespace {
|
||||
ModerationTools::WordSources Sources(bool blockFileLoaded = true) {
|
||||
ModerationTools::WordSources sources;
|
||||
sources.dashboard = [](const std::string& w) -> std::optional<bool> {
|
||||
if (w == "darn") return false;
|
||||
if (w == "brickbuild") return true;
|
||||
return std::nullopt;
|
||||
};
|
||||
sources.allowFile = [](const std::string& w) { return w == "hello" || w == "darn"; };
|
||||
sources.characterName = [](const std::string& w) { return w == "bob"; };
|
||||
sources.blockFile = [](const std::string& w) { return w == "rude"; };
|
||||
sources.blockFileLoaded = blockFileLoaded;
|
||||
return sources;
|
||||
}
|
||||
|
||||
std::vector<std::string> Reasons(const std::vector<ModerationTools::WordVerdict>& verdicts) {
|
||||
std::vector<std::string> reasons;
|
||||
for (const auto& v : verdicts) reasons.push_back((v.stopped ? "x " : "ok ") + v.reason);
|
||||
return reasons;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ChatFilterWordsTest, ExplainNormalChat) {
|
||||
const auto verdicts = ModerationTools::ExplainMessage("Hello, Bob! brickbuild darn zzz", true, Sources());
|
||||
ASSERT_EQ(verdicts.size(), 5u);
|
||||
EXPECT_EQ(verdicts[0].text, "Hello,");
|
||||
EXPECT_EQ(verdicts[0].word, "hello");
|
||||
// A blocked word is stopped even though the file allows it
|
||||
EXPECT_EQ(Reasons(verdicts), (std::vector<std::string>{ "ok allow_file", "ok character_name", "ok allowed_here", "x blocked_here", "x not_allowed" }));
|
||||
EXPECT_TRUE(ModerationTools::ExplainMessage("", true, Sources()).empty());
|
||||
}
|
||||
|
||||
TEST(ChatFilterWordsTest, ExplainFreeChat) {
|
||||
EXPECT_EQ(Reasons(ModerationTools::ExplainMessage("rude zzz darn", false, Sources())),
|
||||
(std::vector<std::string>{ "x block_file", "ok not_in_block_file", "x blocked_here" }));
|
||||
// Without blocklist.dcf free chat stops every word
|
||||
EXPECT_EQ(Reasons(ModerationTools::ExplainMessage("zzz darn", false, Sources(false))),
|
||||
(std::vector<std::string>{ "x no_block_file", "x no_block_file" }));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user