Add the Tools > Ban List window
Reimplements the official client's ban list: a searchable table of the server's bans with Add / Remove / Edit, an own-ban filter and highlight, choosable columns, and the Add/Edit dialog whose IP and name patterns can be read as IPv4/IPv6 wildcards, fixed strings or regular expressions (translated to the regexes banadd takes exactly as the official client does). Editing is add-then-delete, since the protocol has no banedit. The ban list is read from the notifybanlist burst that answers banlist, like channelpermlist. The menu item is only shown where the server grants b_client_ban_list. Also fixes ServerModel numbering permissions from 0 instead of 1, which had every selfPermissionValue() lookup reading the neighbouring permission — including the group-assignment menus. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package com.ts3client.net.ban;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class BanPatternTest {
|
||||
|
||||
@Test
|
||||
void wildcardIpv4TurnsStarsIntoAddressGroups() {
|
||||
assertEquals("192\\.168\\.[0-9]+\\.[0-9]+", BanPattern.WILDCARD_IPV4.ipToRegex("192.168.*.*"));
|
||||
assertEquals("2001:db8:[0-9a-fA-F]+:[0-9a-fA-F]+", BanPattern.WILDCARD_IPV6.ipToRegex("2001:db8:*:*"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void wildcardNamesMatchAnything() {
|
||||
assertEquals("Troll.*", BanPattern.WILDCARD_IPV4.nameToRegex("Troll*"));
|
||||
assertEquals("\\[Bot\\].*", BanPattern.WILDCARD_IPV6.nameToRegex("[Bot]*"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void fixedStringsAreTakenLiterally() {
|
||||
assertEquals("10\\.0\\.0\\.1", BanPattern.FIXED_STRING.ipToRegex("10.0.0.1"));
|
||||
assertEquals("a\\*b\\?\\(c\\)\\$\\^\\|\\\\", BanPattern.FIXED_STRING.nameToRegex("a*b?(c)$^|\\"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void regularExpressionsPassThrough() {
|
||||
assertEquals("^Troll[0-9]{2}$", BanPattern.REGULAR_EXPRESSION.nameToRegex("^Troll[0-9]{2}$"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void decodeRecoversTheNotationThatProducedTheExpression() {
|
||||
BanPattern.Decoded d = BanPattern.decode("192\\.168\\.[0-9]+\\.[0-9]+", "Troll.*");
|
||||
assertEquals(BanPattern.WILDCARD_IPV4, d.pattern);
|
||||
assertEquals("192.168.*.*", d.ip);
|
||||
assertEquals("Troll*", d.name);
|
||||
|
||||
d = BanPattern.decode("fe80:[0-9a-fA-F]+", "");
|
||||
assertEquals(BanPattern.WILDCARD_IPV6, d.pattern);
|
||||
assertEquals("fe80:*", d.ip);
|
||||
|
||||
d = BanPattern.decode("", "a\\*b");
|
||||
assertEquals(BanPattern.FIXED_STRING, d.pattern);
|
||||
assertEquals("a*b", d.name);
|
||||
|
||||
d = BanPattern.decode("", "^Troll[0-9]{2}$");
|
||||
assertEquals(BanPattern.REGULAR_EXPRESSION, d.pattern);
|
||||
assertEquals("^Troll[0-9]{2}$", d.name);
|
||||
}
|
||||
|
||||
@Test
|
||||
void plainAddressesDecodeAsWildcardsLikeTheDialogDefault() {
|
||||
BanPattern.Decoded d = BanPattern.decode("10\\.0\\.0\\.1", "");
|
||||
assertEquals(BanPattern.WILDCARD_IPV4, d.pattern);
|
||||
assertEquals("10.0.0.1", d.ip);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validityFollowsJavaRegexSyntax() {
|
||||
assertTrue(BanPattern.isValidRegex(""));
|
||||
assertTrue(BanPattern.isValidRegex("^a.*$"));
|
||||
assertFalse(BanPattern.isValidRegex("(unclosed"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user