mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-29 09:22:18 -07:00
[Utility] Add warning categories parser with infraction levels
Parses the server's 'officialwarnings' setting (comma-separated, optional '|IL' suffix) into WarningCategory structs so the client can display the infraction level of each warning category. Includes GTest coverage.
This commit is contained in:
parent
2b63bc46a7
commit
96ed16abee
5 changed files with 151 additions and 2 deletions
|
|
@ -5,8 +5,9 @@ set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|
||||||
set(UTILITY_SOURCES libcockatrice/utility/expression.cpp libcockatrice/utility/levenshtein.cpp
|
set(UTILITY_SOURCES
|
||||||
libcockatrice/utility/passwordhasher.cpp libcockatrice/utility/server_rate_limiter.cpp
|
libcockatrice/utility/expression.cpp libcockatrice/utility/levenshtein.cpp libcockatrice/utility/passwordhasher.cpp
|
||||||
|
libcockatrice/utility/server_rate_limiter.cpp libcockatrice/utility/warning_categories.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(UTILITY_HEADERS
|
set(UTILITY_HEADERS
|
||||||
|
|
@ -24,6 +25,7 @@ set(UTILITY_HEADERS
|
||||||
libcockatrice/utility/zone_names.h
|
libcockatrice/utility/zone_names.h
|
||||||
libcockatrice/utility/days_years_between.h
|
libcockatrice/utility/days_years_between.h
|
||||||
libcockatrice/utility/server_rate_limiter.h
|
libcockatrice/utility/server_rate_limiter.h
|
||||||
|
libcockatrice/utility/warning_categories.h
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(libcockatrice_utility STATIC ${UTILITY_SOURCES} ${UTILITY_HEADERS})
|
add_library(libcockatrice_utility STATIC ${UTILITY_SOURCES} ${UTILITY_HEADERS})
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "warning_categories.h"
|
||||||
|
|
||||||
|
QList<WarningCategory> parseWarningCategories(const QString &value)
|
||||||
|
{
|
||||||
|
QList<WarningCategory> categories;
|
||||||
|
const QStringList entries = value.split(',', Qt::SkipEmptyParts);
|
||||||
|
for (const QString &entry : entries) {
|
||||||
|
const QStringList parts = entry.split('|');
|
||||||
|
WarningCategory category;
|
||||||
|
category.name = parts.first().trimmed();
|
||||||
|
if (category.name.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (parts.size() > 1) {
|
||||||
|
bool ok = false;
|
||||||
|
const int il = parts.at(1).trimmed().toInt(&ok);
|
||||||
|
if (ok && il > 0) {
|
||||||
|
category.startingIl = il;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
categories.append(category);
|
||||||
|
}
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef WARNING_CATEGORIES_H
|
||||||
|
#define WARNING_CATEGORIES_H
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A warning category the server offers to moderators, optionally carrying a
|
||||||
|
* recommended starting intervention level (see the moderator guide).
|
||||||
|
*/
|
||||||
|
struct WarningCategory
|
||||||
|
{
|
||||||
|
QString name;
|
||||||
|
int startingIl = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the `server/officialwarnings` setting value into warning categories.
|
||||||
|
*
|
||||||
|
* Entries are separated by commas. Each entry is a category name, optionally
|
||||||
|
* followed by "|" and the recommended starting intervention level:
|
||||||
|
* "Abusive Language|1,Cheating|2,Spamming"
|
||||||
|
* Entries without an explicit level default to intervention level 1.
|
||||||
|
* Empty entries are skipped.
|
||||||
|
*/
|
||||||
|
QList<WarningCategory> parseWarningCategories(const QString &value);
|
||||||
|
|
||||||
|
#endif // WARNING_CATEGORIES_H
|
||||||
|
|
@ -11,6 +11,7 @@ add_test(NAME playmat_resolver_test COMMAND playmat_resolver_test)
|
||||||
add_test(NAME server_card_counter_test COMMAND server_card_counter_test)
|
add_test(NAME server_card_counter_test COMMAND server_card_counter_test)
|
||||||
add_test(NAME server_counter_test COMMAND server_counter_test)
|
add_test(NAME server_counter_test COMMAND server_counter_test)
|
||||||
add_test(NAME server_rate_limiter_test COMMAND server_rate_limiter_test)
|
add_test(NAME server_rate_limiter_test COMMAND server_rate_limiter_test)
|
||||||
|
add_test(NAME warning_categories_test COMMAND warning_categories_test)
|
||||||
|
|
||||||
add_test(NAME deck_hash_performance_test COMMAND deck_hash_performance_test)
|
add_test(NAME deck_hash_performance_test COMMAND deck_hash_performance_test)
|
||||||
set_tests_properties(deck_hash_performance_test PROPERTIES TIMEOUT 5)
|
set_tests_properties(deck_hash_performance_test PROPERTIES TIMEOUT 5)
|
||||||
|
|
@ -27,6 +28,7 @@ add_executable(deck_hash_performance_test deck_hash_performance_test.cpp)
|
||||||
add_executable(server_card_counter_test server_card_counter_test.cpp)
|
add_executable(server_card_counter_test server_card_counter_test.cpp)
|
||||||
add_executable(server_counter_test server_counter_test.cpp)
|
add_executable(server_counter_test server_counter_test.cpp)
|
||||||
add_executable(server_rate_limiter_test server_rate_limiter_test.cpp)
|
add_executable(server_rate_limiter_test server_rate_limiter_test.cpp)
|
||||||
|
add_executable(warning_categories_test warning_categories_test.cpp)
|
||||||
|
|
||||||
find_package(GTest)
|
find_package(GTest)
|
||||||
|
|
||||||
|
|
@ -63,6 +65,7 @@ if(NOT GTEST_FOUND)
|
||||||
add_dependencies(server_card_counter_test gtest)
|
add_dependencies(server_card_counter_test gtest)
|
||||||
add_dependencies(server_counter_test gtest)
|
add_dependencies(server_counter_test gtest)
|
||||||
add_dependencies(server_rate_limiter_test gtest)
|
add_dependencies(server_rate_limiter_test gtest)
|
||||||
|
add_dependencies(warning_categories_test gtest)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(${GTEST_INCLUDE_DIRS})
|
include_directories(${GTEST_INCLUDE_DIRS})
|
||||||
|
|
@ -94,6 +97,9 @@ target_link_libraries(
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
server_rate_limiter_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
server_rate_limiter_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
||||||
)
|
)
|
||||||
|
target_link_libraries(
|
||||||
|
warning_categories_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
||||||
|
)
|
||||||
|
|
||||||
add_subdirectory(card_zone_algorithms)
|
add_subdirectory(card_zone_algorithms)
|
||||||
add_subdirectory(carddatabase)
|
add_subdirectory(carddatabase)
|
||||||
|
|
|
||||||
89
tests/warning_categories_test.cpp
Normal file
89
tests/warning_categories_test.cpp
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include <QString>
|
||||||
|
#include <libcockatrice/utility/warning_categories.h>
|
||||||
|
|
||||||
|
TEST(WarningCategoriesTest, EmptyValueYieldsNoCategories)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(parseWarningCategories(QString()).isEmpty());
|
||||||
|
EXPECT_TRUE(parseWarningCategories(QString("")).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WarningCategoriesTest, PlainNamesDefaultToInterventionLevelOne)
|
||||||
|
{
|
||||||
|
const QList<WarningCategory> categories = parseWarningCategories("Flaming,Spamming,Causing Drama");
|
||||||
|
|
||||||
|
ASSERT_EQ(3, categories.size());
|
||||||
|
EXPECT_EQ("Flaming", categories.at(0).name);
|
||||||
|
EXPECT_EQ(1, categories.at(0).startingIl);
|
||||||
|
EXPECT_EQ("Spamming", categories.at(1).name);
|
||||||
|
EXPECT_EQ(1, categories.at(1).startingIl);
|
||||||
|
EXPECT_EQ("Causing Drama", categories.at(2).name);
|
||||||
|
EXPECT_EQ(1, categories.at(2).startingIl);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WarningCategoriesTest, ExplicitInterventionLevelsAreParsed)
|
||||||
|
{
|
||||||
|
const QList<WarningCategory> categories = parseWarningCategories("Cheating|2,Inappropriate Avatar|3");
|
||||||
|
|
||||||
|
ASSERT_EQ(2, categories.size());
|
||||||
|
EXPECT_EQ("Cheating", categories.at(0).name);
|
||||||
|
EXPECT_EQ(2, categories.at(0).startingIl);
|
||||||
|
EXPECT_EQ("Inappropriate Avatar", categories.at(1).name);
|
||||||
|
EXPECT_EQ(3, categories.at(1).startingIl);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WarningCategoriesTest, MixedEntriesKeepDefaultsForThoseWithoutLevels)
|
||||||
|
{
|
||||||
|
const QList<WarningCategory> categories = parseWarningCategories("Abusive Language|1,Cheating|2,Spamming");
|
||||||
|
|
||||||
|
ASSERT_EQ(3, categories.size());
|
||||||
|
EXPECT_EQ(1, categories.at(0).startingIl);
|
||||||
|
EXPECT_EQ(2, categories.at(1).startingIl);
|
||||||
|
EXPECT_EQ("Spamming", categories.at(2).name);
|
||||||
|
EXPECT_EQ(1, categories.at(2).startingIl);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WarningCategoriesTest, EmptyEntriesAreSkipped)
|
||||||
|
{
|
||||||
|
const QList<WarningCategory> categories = parseWarningCategories("Spamming,,Cheating|2,");
|
||||||
|
|
||||||
|
ASSERT_EQ(2, categories.size());
|
||||||
|
EXPECT_EQ("Spamming", categories.at(0).name);
|
||||||
|
EXPECT_EQ("Cheating", categories.at(1).name);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WarningCategoriesTest, WhitespaceIsTrimmed)
|
||||||
|
{
|
||||||
|
const QList<WarningCategory> categories = parseWarningCategories(" Abusive Language , Cheating | 2 ");
|
||||||
|
|
||||||
|
ASSERT_EQ(2, categories.size());
|
||||||
|
EXPECT_EQ("Abusive Language", categories.at(0).name);
|
||||||
|
EXPECT_EQ(1, categories.at(0).startingIl);
|
||||||
|
EXPECT_EQ("Cheating", categories.at(1).name);
|
||||||
|
EXPECT_EQ(2, categories.at(1).startingIl);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WarningCategoriesTest, InvalidInterventionLevelsFallBackToOne)
|
||||||
|
{
|
||||||
|
const QList<WarningCategory> categories = parseWarningCategories("Spamming|abc,Cheating|0,Targeted Harassment|-3");
|
||||||
|
|
||||||
|
ASSERT_EQ(3, categories.size());
|
||||||
|
EXPECT_EQ(1, categories.at(0).startingIl);
|
||||||
|
EXPECT_EQ(1, categories.at(1).startingIl);
|
||||||
|
EXPECT_EQ(1, categories.at(2).startingIl);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WarningCategoriesTest, EntryWithOnlyLevelIsSkipped)
|
||||||
|
{
|
||||||
|
const QList<WarningCategory> categories = parseWarningCategories("|2,Spamming|2");
|
||||||
|
|
||||||
|
ASSERT_EQ(1, categories.size());
|
||||||
|
EXPECT_EQ("Spamming", categories.at(0).name);
|
||||||
|
EXPECT_EQ(2, categories.at(0).startingIl);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue