mirror of https://github.com/progval/irctest.git
Compare commits
11 Commits
e1b56b87ed
...
b69fad7c42
Author | SHA1 | Date | |
---|---|---|---|
Val Lorentz | b69fad7c42 | ||
Val Lorentz | d7bc01c656 | ||
Val Lorentz | 038d1fff07 | ||
Val Lorentz | bd72b514d0 | ||
Val Lorentz | f4a01cfe49 | ||
Val Lorentz | e6dfb87759 | ||
Val Lorentz | 2ae612c68f | ||
Val Lorentz | d908699674 | ||
Sadie Powell | 61ae4bcf9e | ||
Sadie Powell | 0c5c91368a | ||
Shivaram Lingamneni | c0e6ca4dde |
|
@ -1106,7 +1106,7 @@ jobs:
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: sable
|
path: sable
|
||||||
ref: dcf8b53cac54f460b86861908d36d67969cf1eb2
|
ref: fe337a036c3ab5f8548e2578b65568e628f4c32f
|
||||||
repository: Libera-Chat/sable
|
repository: Libera-Chat/sable
|
||||||
- name: Install rust toolchain
|
- name: Install rust toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -83,10 +83,16 @@ LIMNORIA_SELECTORS := \
|
||||||
(foo or not foo) \
|
(foo or not foo) \
|
||||||
$(EXTRA_SELECTORS)
|
$(EXTRA_SELECTORS)
|
||||||
|
|
||||||
|
# Tests marked with arbitrary_client_tags or react_tag can't pass because Sable does not support client tags yet
|
||||||
|
# Tests marked with private_chathistory can't pass because Sable does not implement CHATHISTORY for DMs
|
||||||
|
|
||||||
SABLE_SELECTORS := \
|
SABLE_SELECTORS := \
|
||||||
not Ergo \
|
not Ergo \
|
||||||
and not deprecated \
|
and not deprecated \
|
||||||
and not strict \
|
and not strict \
|
||||||
|
and not arbitrary_client_tags \
|
||||||
|
and not react_tag \
|
||||||
|
and not private_chathistory \
|
||||||
and not whowas and not list and not lusers and not userhost and not time and not info \
|
and not whowas and not list and not lusers and not userhost and not time and not info \
|
||||||
$(EXTRA_SELECTORS)
|
$(EXTRA_SELECTORS)
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,7 @@ class _IrcTestCase(Generic[TController]):
|
||||||
def messageDiffers(
|
def messageDiffers(
|
||||||
self,
|
self,
|
||||||
msg: Message,
|
msg: Message,
|
||||||
|
command: Union[str, None, patma.Operator] = None,
|
||||||
params: Optional[List[Union[str, None, patma.Operator]]] = None,
|
params: Optional[List[Union[str, None, patma.Operator]]] = None,
|
||||||
target: Optional[str] = None,
|
target: Optional[str] = None,
|
||||||
tags: Optional[
|
tags: Optional[
|
||||||
|
@ -186,6 +187,14 @@ class _IrcTestCase(Generic[TController]):
|
||||||
msg=msg,
|
msg=msg,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if command is not None and not patma.match_string(msg.command, command):
|
||||||
|
fail_msg = (
|
||||||
|
fail_msg or "expected command to match {expects}, got {got}: {msg}"
|
||||||
|
)
|
||||||
|
return fail_msg.format(
|
||||||
|
*extra_format, got=msg.command, expects=command, msg=msg
|
||||||
|
)
|
||||||
|
|
||||||
if prefix is not None and not patma.match_string(msg.prefix, prefix):
|
if prefix is not None and not patma.match_string(msg.prefix, prefix):
|
||||||
fail_msg = (
|
fail_msg = (
|
||||||
fail_msg or "expected prefix to match {expects}, got {got}: {msg}"
|
fail_msg or "expected prefix to match {expects}, got {got}: {msg}"
|
||||||
|
@ -214,7 +223,7 @@ class _IrcTestCase(Generic[TController]):
|
||||||
or "expected nick to be {expects}, got {got} instead: {msg}"
|
or "expected nick to be {expects}, got {got} instead: {msg}"
|
||||||
)
|
)
|
||||||
return fail_msg.format(
|
return fail_msg.format(
|
||||||
*extra_format, got=got_nick, expects=nick, param=key, msg=msg
|
*extra_format, got=got_nick, expects=nick, msg=msg
|
||||||
)
|
)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -132,14 +132,16 @@ class AnopeController(BaseServicesController, DirectoryBasedController):
|
||||||
|
|
||||||
# Config and code need to be in the same directory, *obviously*
|
# Config and code need to be in the same directory, *obviously*
|
||||||
(self.directory / "lib").symlink_to(Path(services_path).parent.parent / "lib")
|
(self.directory / "lib").symlink_to(Path(services_path).parent.parent / "lib")
|
||||||
|
(self.directory / "modules").symlink_to(
|
||||||
|
Path(services_path).parent.parent / "modules"
|
||||||
|
)
|
||||||
|
|
||||||
self.proc = subprocess.Popen(
|
self.proc = subprocess.Popen(
|
||||||
[
|
[
|
||||||
"anope",
|
"anope",
|
||||||
"-n", # don't fork
|
"--config=services.conf", # can't be an absolute path in 2.0
|
||||||
"--config=services.conf", # can't be an absolute path
|
"--nofork", # don't fork
|
||||||
# "--logdir",
|
"--nopid", # don't write a pid
|
||||||
# f"/tmp/services-{server_port}.log",
|
|
||||||
],
|
],
|
||||||
cwd=self.directory,
|
cwd=self.directory,
|
||||||
# stdout=subprocess.DEVNULL,
|
# stdout=subprocess.DEVNULL,
|
||||||
|
|
|
@ -173,7 +173,7 @@ MESSAGE_SPECS: List[Tuple[Dict, List[str], List[str], List[str]]] = [
|
||||||
],
|
],
|
||||||
# and they each error with:
|
# and they each error with:
|
||||||
[
|
[
|
||||||
"expected command to be PRIVMSG, got PRIVMG",
|
"expected command to match PRIVMSG, got PRIVMG",
|
||||||
"expected tags to match {'tag1': 'bar', RemainingKeys(ANYSTR): ANYOPTSTR}, got {'tag1': 'value1'}",
|
"expected tags to match {'tag1': 'bar', RemainingKeys(ANYSTR): ANYOPTSTR}, got {'tag1': 'value1'}",
|
||||||
"expected params to match ['#chan', 'hello'], got ['#chan', 'hello2']",
|
"expected params to match ['#chan', 'hello'], got ['#chan', 'hello2']",
|
||||||
"expected params to match ['#chan', 'hello'], got ['#chan2', 'hello']",
|
"expected params to match ['#chan', 'hello'], got ['#chan2', 'hello']",
|
||||||
|
@ -206,7 +206,7 @@ MESSAGE_SPECS: List[Tuple[Dict, List[str], List[str], List[str]]] = [
|
||||||
],
|
],
|
||||||
# and they each error with:
|
# and they each error with:
|
||||||
[
|
[
|
||||||
"expected command to be PRIVMSG, got PRIVMG",
|
"expected command to match PRIVMSG, got PRIVMG",
|
||||||
"expected tags to match {StrRe(r'tag[12]'): 'bar', RemainingKeys(ANYSTR): ANYOPTSTR}, got {'tag1': 'value1'}",
|
"expected tags to match {StrRe(r'tag[12]'): 'bar', RemainingKeys(ANYSTR): ANYOPTSTR}, got {'tag1': 'value1'}",
|
||||||
"expected params to match ['#chan', 'hello'], got ['#chan', 'hello2']",
|
"expected params to match ['#chan', 'hello'], got ['#chan', 'hello2']",
|
||||||
"expected params to match ['#chan', 'hello'], got ['#chan2', 'hello']",
|
"expected params to match ['#chan', 'hello'], got ['#chan2', 'hello']",
|
||||||
|
@ -235,7 +235,7 @@ MESSAGE_SPECS: List[Tuple[Dict, List[str], List[str], List[str]]] = [
|
||||||
],
|
],
|
||||||
# and they each error with:
|
# and they each error with:
|
||||||
[
|
[
|
||||||
"expected command to be PRIVMSG, got PRIVMG",
|
"expected command to match PRIVMSG, got PRIVMG",
|
||||||
"expected tags to match {'tag1': 'bar', RemainingKeys(NotStrRe(r'tag2')): ANYOPTSTR}, got {'tag1': 'value1'}",
|
"expected tags to match {'tag1': 'bar', RemainingKeys(NotStrRe(r'tag2')): ANYOPTSTR}, got {'tag1': 'value1'}",
|
||||||
"expected tags to match {'tag1': 'bar', RemainingKeys(NotStrRe(r'tag2')): ANYOPTSTR}, got {'tag1': 'bar', 'tag2': ''}",
|
"expected tags to match {'tag1': 'bar', RemainingKeys(NotStrRe(r'tag2')): ANYOPTSTR}, got {'tag1': 'bar', 'tag2': ''}",
|
||||||
"expected tags to match {'tag1': 'bar', RemainingKeys(NotStrRe(r'tag2')): ANYOPTSTR}, got {'tag1': 'bar', 'tag2': 'baz'}",
|
"expected tags to match {'tag1': 'bar', RemainingKeys(NotStrRe(r'tag2')): ANYOPTSTR}, got {'tag1': 'bar', 'tag2': 'baz'}",
|
||||||
|
@ -345,7 +345,7 @@ MESSAGE_SPECS: List[Tuple[Dict, List[str], List[str], List[str]]] = [
|
||||||
],
|
],
|
||||||
# and they each error with:
|
# and they each error with:
|
||||||
[
|
[
|
||||||
"expected command to be PING, got PONG"
|
"expected command to match PING, got PONG"
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -56,10 +56,6 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@cases.mark_specifications("IRCv3")
|
@cases.mark_specifications("IRCv3")
|
||||||
@cases.xfailIfSoftware(
|
|
||||||
["Sable"],
|
|
||||||
"does not support multi-prefix",
|
|
||||||
)
|
|
||||||
def testReqOne(self):
|
def testReqOne(self):
|
||||||
"""Tests requesting a single capability"""
|
"""Tests requesting a single capability"""
|
||||||
self.addClient(1)
|
self.addClient(1)
|
||||||
|
@ -93,7 +89,7 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||||
|
|
||||||
@cases.mark_specifications("IRCv3")
|
@cases.mark_specifications("IRCv3")
|
||||||
@cases.xfailIfSoftware(
|
@cases.xfailIfSoftware(
|
||||||
["ngIRCd", "Sable"],
|
["ngIRCd"],
|
||||||
"does not support userhost-in-names",
|
"does not support userhost-in-names",
|
||||||
)
|
)
|
||||||
def testReqTwo(self):
|
def testReqTwo(self):
|
||||||
|
@ -135,7 +131,7 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||||
|
|
||||||
@cases.mark_specifications("IRCv3")
|
@cases.mark_specifications("IRCv3")
|
||||||
@cases.xfailIfSoftware(
|
@cases.xfailIfSoftware(
|
||||||
["ngIRCd", "Sable"],
|
["ngIRCd"],
|
||||||
"does not support userhost-in-names",
|
"does not support userhost-in-names",
|
||||||
)
|
)
|
||||||
def testReqOneThenOne(self):
|
def testReqOneThenOne(self):
|
||||||
|
@ -187,7 +183,7 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||||
|
|
||||||
@cases.mark_specifications("IRCv3")
|
@cases.mark_specifications("IRCv3")
|
||||||
@cases.xfailIfSoftware(
|
@cases.xfailIfSoftware(
|
||||||
["ngIRCd", "Sable"],
|
["ngIRCd"],
|
||||||
"does not support userhost-in-names",
|
"does not support userhost-in-names",
|
||||||
)
|
)
|
||||||
def testReqPostRegistration(self):
|
def testReqPostRegistration(self):
|
||||||
|
|
|
@ -58,6 +58,16 @@ class ChathistoryTestCase(cases.BaseServerTestCase):
|
||||||
def config() -> cases.TestCaseControllerConfig:
|
def config() -> cases.TestCaseControllerConfig:
|
||||||
return cases.TestCaseControllerConfig(chathistory=True)
|
return cases.TestCaseControllerConfig(chathistory=True)
|
||||||
|
|
||||||
|
def _supports_msgid(self):
|
||||||
|
return "msgid" in self.server_support.get(
|
||||||
|
"MSGREFTYPES", "msgid,timestamp"
|
||||||
|
).split(",")
|
||||||
|
|
||||||
|
def _supports_timestamp(self):
|
||||||
|
return "timestamp" in self.server_support.get(
|
||||||
|
"MSGREFTYPES", "msgid,timestamp"
|
||||||
|
).split(",")
|
||||||
|
|
||||||
@skip_ngircd
|
@skip_ngircd
|
||||||
def testInvalidTargets(self):
|
def testInvalidTargets(self):
|
||||||
bar, pw = random_name("bar"), random_name("pw")
|
bar, pw = random_name("bar"), random_name("pw")
|
||||||
|
@ -460,172 +470,195 @@ class ChathistoryTestCase(cases.BaseServerTestCase):
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
self.assertEqual(echo_messages[-1:], result)
|
self.assertEqual(echo_messages[-1:], result)
|
||||||
|
|
||||||
self.sendLine(
|
if self._supports_msgid():
|
||||||
user,
|
self.sendLine(
|
||||||
"CHATHISTORY LATEST %s msgid=%s %d"
|
user,
|
||||||
% (chname, echo_messages[4].msgid, INCLUSIVE_LIMIT),
|
"CHATHISTORY LATEST %s msgid=%s %d"
|
||||||
)
|
% (chname, echo_messages[4].msgid, INCLUSIVE_LIMIT),
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
)
|
||||||
self.assertEqual(echo_messages[5:], result)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[5:], result)
|
||||||
|
|
||||||
self.sendLine(
|
if self._supports_timestamp():
|
||||||
user,
|
self.sendLine(
|
||||||
"CHATHISTORY LATEST %s timestamp=%s %d"
|
user,
|
||||||
% (chname, echo_messages[4].time, INCLUSIVE_LIMIT),
|
"CHATHISTORY LATEST %s timestamp=%s %d"
|
||||||
)
|
% (chname, echo_messages[4].time, INCLUSIVE_LIMIT),
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
)
|
||||||
self.assertEqual(echo_messages[5:], result)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[5:], result)
|
||||||
|
|
||||||
def _validate_chathistory_BEFORE(self, echo_messages, user, chname):
|
def _validate_chathistory_BEFORE(self, echo_messages, user, chname):
|
||||||
INCLUSIVE_LIMIT = len(echo_messages) * 2
|
INCLUSIVE_LIMIT = len(echo_messages) * 2
|
||||||
self.sendLine(
|
if self._supports_msgid():
|
||||||
user,
|
self.sendLine(
|
||||||
"CHATHISTORY BEFORE %s msgid=%s %d"
|
user,
|
||||||
% (chname, echo_messages[6].msgid, INCLUSIVE_LIMIT),
|
"CHATHISTORY BEFORE %s msgid=%s %d"
|
||||||
)
|
% (chname, echo_messages[6].msgid, INCLUSIVE_LIMIT),
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
)
|
||||||
self.assertEqual(echo_messages[:6], result)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[:6], result)
|
||||||
|
|
||||||
self.sendLine(
|
if self._supports_timestamp():
|
||||||
user,
|
self.sendLine(
|
||||||
"CHATHISTORY BEFORE %s timestamp=%s %d"
|
user,
|
||||||
% (chname, echo_messages[6].time, INCLUSIVE_LIMIT),
|
"CHATHISTORY BEFORE %s timestamp=%s %d"
|
||||||
)
|
% (chname, echo_messages[6].time, INCLUSIVE_LIMIT),
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
)
|
||||||
self.assertEqual(echo_messages[:6], result)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[:6], result)
|
||||||
|
|
||||||
self.sendLine(
|
self.sendLine(
|
||||||
user,
|
user,
|
||||||
"CHATHISTORY BEFORE %s timestamp=%s %d"
|
"CHATHISTORY BEFORE %s timestamp=%s %d"
|
||||||
% (chname, echo_messages[6].time, 2),
|
% (chname, echo_messages[6].time, 2),
|
||||||
)
|
)
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
self.assertEqual(echo_messages[4:6], result)
|
self.assertEqual(echo_messages[4:6], result)
|
||||||
|
|
||||||
def _validate_chathistory_AFTER(self, echo_messages, user, chname):
|
def _validate_chathistory_AFTER(self, echo_messages, user, chname):
|
||||||
INCLUSIVE_LIMIT = len(echo_messages) * 2
|
INCLUSIVE_LIMIT = len(echo_messages) * 2
|
||||||
self.sendLine(
|
if self._supports_msgid():
|
||||||
user,
|
self.sendLine(
|
||||||
"CHATHISTORY AFTER %s msgid=%s %d"
|
user,
|
||||||
% (chname, echo_messages[3].msgid, INCLUSIVE_LIMIT),
|
"CHATHISTORY AFTER %s msgid=%s %d"
|
||||||
)
|
% (chname, echo_messages[3].msgid, INCLUSIVE_LIMIT),
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
)
|
||||||
self.assertEqual(echo_messages[4:], result)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[4:], result)
|
||||||
|
|
||||||
self.sendLine(
|
if self._supports_timestamp():
|
||||||
user,
|
self.sendLine(
|
||||||
"CHATHISTORY AFTER %s timestamp=%s %d"
|
user,
|
||||||
% (chname, echo_messages[3].time, INCLUSIVE_LIMIT),
|
"CHATHISTORY AFTER %s timestamp=%s %d"
|
||||||
)
|
% (chname, echo_messages[3].time, INCLUSIVE_LIMIT),
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
)
|
||||||
self.assertEqual(echo_messages[4:], result)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[4:], result)
|
||||||
|
|
||||||
self.sendLine(
|
self.sendLine(
|
||||||
user,
|
user,
|
||||||
"CHATHISTORY AFTER %s timestamp=%s %d" % (chname, echo_messages[3].time, 3),
|
"CHATHISTORY AFTER %s timestamp=%s %d"
|
||||||
)
|
% (chname, echo_messages[3].time, 3),
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
)
|
||||||
self.assertEqual(echo_messages[4:7], result)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[4:7], result)
|
||||||
|
|
||||||
def _validate_chathistory_BETWEEN(self, echo_messages, user, chname):
|
def _validate_chathistory_BETWEEN(self, echo_messages, user, chname):
|
||||||
INCLUSIVE_LIMIT = len(echo_messages) * 2
|
INCLUSIVE_LIMIT = len(echo_messages) * 2
|
||||||
# BETWEEN forwards and backwards
|
if self._supports_msgid():
|
||||||
self.sendLine(
|
# BETWEEN forwards and backwards
|
||||||
user,
|
self.sendLine(
|
||||||
"CHATHISTORY BETWEEN %s msgid=%s msgid=%s %d"
|
user,
|
||||||
% (
|
"CHATHISTORY BETWEEN %s msgid=%s msgid=%s %d"
|
||||||
chname,
|
% (
|
||||||
echo_messages[0].msgid,
|
chname,
|
||||||
echo_messages[-1].msgid,
|
echo_messages[0].msgid,
|
||||||
INCLUSIVE_LIMIT,
|
echo_messages[-1].msgid,
|
||||||
),
|
INCLUSIVE_LIMIT,
|
||||||
)
|
),
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
)
|
||||||
self.assertEqual(echo_messages[1:-1], result)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[1:-1], result)
|
||||||
|
|
||||||
self.sendLine(
|
self.sendLine(
|
||||||
user,
|
user,
|
||||||
"CHATHISTORY BETWEEN %s msgid=%s msgid=%s %d"
|
"CHATHISTORY BETWEEN %s msgid=%s msgid=%s %d"
|
||||||
% (
|
% (
|
||||||
chname,
|
chname,
|
||||||
echo_messages[-1].msgid,
|
echo_messages[-1].msgid,
|
||||||
echo_messages[0].msgid,
|
echo_messages[0].msgid,
|
||||||
INCLUSIVE_LIMIT,
|
INCLUSIVE_LIMIT,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
self.assertEqual(echo_messages[1:-1], result)
|
self.assertEqual(echo_messages[1:-1], result)
|
||||||
|
|
||||||
# BETWEEN forwards and backwards with a limit, should get
|
# BETWEEN forwards and backwards with a limit, should get
|
||||||
# different results this time
|
# different results this time
|
||||||
self.sendLine(
|
self.sendLine(
|
||||||
user,
|
user,
|
||||||
"CHATHISTORY BETWEEN %s msgid=%s msgid=%s %d"
|
"CHATHISTORY BETWEEN %s msgid=%s msgid=%s %d"
|
||||||
% (chname, echo_messages[0].msgid, echo_messages[-1].msgid, 3),
|
% (chname, echo_messages[0].msgid, echo_messages[-1].msgid, 3),
|
||||||
)
|
)
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
self.assertEqual(echo_messages[1:4], result)
|
self.assertEqual(echo_messages[1:4], result)
|
||||||
|
|
||||||
self.sendLine(
|
self.sendLine(
|
||||||
user,
|
user,
|
||||||
"CHATHISTORY BETWEEN %s msgid=%s msgid=%s %d"
|
"CHATHISTORY BETWEEN %s msgid=%s msgid=%s %d"
|
||||||
% (chname, echo_messages[-1].msgid, echo_messages[0].msgid, 3),
|
% (chname, echo_messages[-1].msgid, echo_messages[0].msgid, 3),
|
||||||
)
|
)
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
self.assertEqual(echo_messages[-4:-1], result)
|
self.assertEqual(echo_messages[-4:-1], result)
|
||||||
|
|
||||||
# same stuff again but with timestamps
|
if self._supports_timestamp():
|
||||||
self.sendLine(
|
# same stuff again but with timestamps
|
||||||
user,
|
self.sendLine(
|
||||||
"CHATHISTORY BETWEEN %s timestamp=%s timestamp=%s %d"
|
user,
|
||||||
% (chname, echo_messages[0].time, echo_messages[-1].time, INCLUSIVE_LIMIT),
|
"CHATHISTORY BETWEEN %s timestamp=%s timestamp=%s %d"
|
||||||
)
|
% (
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
chname,
|
||||||
self.assertEqual(echo_messages[1:-1], result)
|
echo_messages[0].time,
|
||||||
self.sendLine(
|
echo_messages[-1].time,
|
||||||
user,
|
INCLUSIVE_LIMIT,
|
||||||
"CHATHISTORY BETWEEN %s timestamp=%s timestamp=%s %d"
|
),
|
||||||
% (chname, echo_messages[-1].time, echo_messages[0].time, INCLUSIVE_LIMIT),
|
)
|
||||||
)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
self.assertEqual(echo_messages[1:-1], result)
|
||||||
self.assertEqual(echo_messages[1:-1], result)
|
self.sendLine(
|
||||||
self.sendLine(
|
user,
|
||||||
user,
|
"CHATHISTORY BETWEEN %s timestamp=%s timestamp=%s %d"
|
||||||
"CHATHISTORY BETWEEN %s timestamp=%s timestamp=%s %d"
|
% (
|
||||||
% (chname, echo_messages[0].time, echo_messages[-1].time, 3),
|
chname,
|
||||||
)
|
echo_messages[-1].time,
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
echo_messages[0].time,
|
||||||
self.assertEqual(echo_messages[1:4], result)
|
INCLUSIVE_LIMIT,
|
||||||
self.sendLine(
|
),
|
||||||
user,
|
)
|
||||||
"CHATHISTORY BETWEEN %s timestamp=%s timestamp=%s %d"
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
% (chname, echo_messages[-1].time, echo_messages[0].time, 3),
|
self.assertEqual(echo_messages[1:-1], result)
|
||||||
)
|
self.sendLine(
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
user,
|
||||||
self.assertEqual(echo_messages[-4:-1], result)
|
"CHATHISTORY BETWEEN %s timestamp=%s timestamp=%s %d"
|
||||||
|
% (chname, echo_messages[0].time, echo_messages[-1].time, 3),
|
||||||
|
)
|
||||||
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[1:4], result)
|
||||||
|
self.sendLine(
|
||||||
|
user,
|
||||||
|
"CHATHISTORY BETWEEN %s timestamp=%s timestamp=%s %d"
|
||||||
|
% (chname, echo_messages[-1].time, echo_messages[0].time, 3),
|
||||||
|
)
|
||||||
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[-4:-1], result)
|
||||||
|
|
||||||
def _validate_chathistory_AROUND(self, echo_messages, user, chname):
|
def _validate_chathistory_AROUND(self, echo_messages, user, chname):
|
||||||
self.sendLine(
|
if self._supports_msgid():
|
||||||
user,
|
self.sendLine(
|
||||||
"CHATHISTORY AROUND %s msgid=%s %d" % (chname, echo_messages[7].msgid, 1),
|
user,
|
||||||
)
|
"CHATHISTORY AROUND %s msgid=%s %d"
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
% (chname, echo_messages[7].msgid, 1),
|
||||||
self.assertEqual([echo_messages[7]], result)
|
)
|
||||||
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual([echo_messages[7]], result)
|
||||||
|
|
||||||
self.sendLine(
|
self.sendLine(
|
||||||
user,
|
user,
|
||||||
"CHATHISTORY AROUND %s msgid=%s %d" % (chname, echo_messages[7].msgid, 3),
|
"CHATHISTORY AROUND %s msgid=%s %d"
|
||||||
)
|
% (chname, echo_messages[7].msgid, 3),
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
)
|
||||||
self.assertEqual(echo_messages[6:9], result)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertEqual(echo_messages[6:9], result)
|
||||||
|
|
||||||
self.sendLine(
|
if self._supports_timestamp():
|
||||||
user,
|
self.sendLine(
|
||||||
"CHATHISTORY AROUND %s timestamp=%s %d"
|
user,
|
||||||
% (chname, echo_messages[7].time, 3),
|
"CHATHISTORY AROUND %s timestamp=%s %d"
|
||||||
)
|
% (chname, echo_messages[7].time, 3),
|
||||||
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
)
|
||||||
self.assertIn(echo_messages[7], result)
|
result = self.validate_chathistory_batch(self.getMessages(user), chname)
|
||||||
|
self.assertIn(echo_messages[7], result)
|
||||||
|
|
||||||
@pytest.mark.arbitrary_client_tags
|
@pytest.mark.arbitrary_client_tags
|
||||||
@skip_ngircd
|
@skip_ngircd
|
||||||
|
|
|
@ -8,6 +8,7 @@ import pytest
|
||||||
from irctest import cases, runner
|
from irctest import cases, runner
|
||||||
from irctest.client_mock import NoMessageException
|
from irctest.client_mock import NoMessageException
|
||||||
from irctest.numerics import (
|
from irctest.numerics import (
|
||||||
|
ERR_ERRONEUSNICKNAME,
|
||||||
RPL_ENDOFMONLIST,
|
RPL_ENDOFMONLIST,
|
||||||
RPL_MONLIST,
|
RPL_MONLIST,
|
||||||
RPL_MONOFFLINE,
|
RPL_MONOFFLINE,
|
||||||
|
@ -190,14 +191,15 @@ class MonitorTestCase(_BaseMonitorTestCase):
|
||||||
self.check_server_support()
|
self.check_server_support()
|
||||||
self.sendLine(1, "MONITOR + *!username@localhost")
|
self.sendLine(1, "MONITOR + *!username@localhost")
|
||||||
self.sendLine(1, "MONITOR + *!username@127.0.0.1")
|
self.sendLine(1, "MONITOR + *!username@127.0.0.1")
|
||||||
|
expected_command = StrRe(f"({RPL_MONOFFLINE}|{ERR_ERRONEUSNICKNAME})")
|
||||||
try:
|
try:
|
||||||
m = self.getMessage(1)
|
m = self.getMessage(1)
|
||||||
self.assertMessageMatch(m, command="731")
|
self.assertMessageMatch(m, command=expected_command)
|
||||||
except NoMessageException:
|
except NoMessageException:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
m = self.getMessage(1)
|
m = self.getMessage(1)
|
||||||
self.assertMessageMatch(m, command="731")
|
self.assertMessageMatch(m, command=expected_command)
|
||||||
self.connectClient("bar")
|
self.connectClient("bar")
|
||||||
try:
|
try:
|
||||||
m = self.getMessage(1)
|
m = self.getMessage(1)
|
||||||
|
|
|
@ -11,7 +11,7 @@ from irctest.patma import ANYSTR, StrRe
|
||||||
|
|
||||||
|
|
||||||
class NamesTestCase(cases.BaseServerTestCase):
|
class NamesTestCase(cases.BaseServerTestCase):
|
||||||
def _testNames(self, symbol):
|
def _testNames(self, symbol: bool, allow_trailing_space: bool):
|
||||||
self.connectClient("nick1")
|
self.connectClient("nick1")
|
||||||
self.sendLine(1, "JOIN #chan")
|
self.sendLine(1, "JOIN #chan")
|
||||||
self.getMessages(1)
|
self.getMessages(1)
|
||||||
|
@ -31,7 +31,10 @@ class NamesTestCase(cases.BaseServerTestCase):
|
||||||
"nick1",
|
"nick1",
|
||||||
*(["="] if symbol else []),
|
*(["="] if symbol else []),
|
||||||
"#chan",
|
"#chan",
|
||||||
StrRe("(nick2 @nick1|@nick1 nick2)"),
|
StrRe(
|
||||||
|
"(nick2 @nick1|@nick1 nick2)"
|
||||||
|
+ (" ?" if allow_trailing_space else "")
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,20 +47,26 @@ class NamesTestCase(cases.BaseServerTestCase):
|
||||||
@cases.mark_specifications("RFC1459", deprecated=True)
|
@cases.mark_specifications("RFC1459", deprecated=True)
|
||||||
def testNames1459(self):
|
def testNames1459(self):
|
||||||
"""
|
"""
|
||||||
https://modern.ircdocs.horse/#names-message
|
|
||||||
https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.5
|
https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.5
|
||||||
https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.5
|
|
||||||
"""
|
"""
|
||||||
self._testNames(symbol=False)
|
self._testNames(symbol=False, allow_trailing_space=True)
|
||||||
|
|
||||||
@cases.mark_specifications("RFC1459", "RFC2812", "Modern")
|
@cases.mark_specifications("RFC2812", "Modern")
|
||||||
def testNames2812(self):
|
def testNames2812(self):
|
||||||
"""
|
"""
|
||||||
https://modern.ircdocs.horse/#names-message
|
|
||||||
https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.5
|
|
||||||
https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.5
|
https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.5
|
||||||
"""
|
"""
|
||||||
self._testNames(symbol=True)
|
self._testNames(symbol=True, allow_trailing_space=True)
|
||||||
|
|
||||||
|
@cases.mark_specifications("Modern")
|
||||||
|
@cases.xfailIfSoftware(
|
||||||
|
["Bahamut", "irc2"], "Bahamut and irc2 send a trailing space in RPL_NAMREPLY"
|
||||||
|
)
|
||||||
|
def testNamesModern(self):
|
||||||
|
"""
|
||||||
|
https://modern.ircdocs.horse/#names-message
|
||||||
|
"""
|
||||||
|
self._testNames(symbol=True, allow_trailing_space=False)
|
||||||
|
|
||||||
def _testNamesMultipleChannels(self, symbol):
|
def _testNamesMultipleChannels(self, symbol):
|
||||||
self.connectClient("nick1")
|
self.connectClient("nick1")
|
||||||
|
|
|
@ -8,6 +8,7 @@ import pytest
|
||||||
|
|
||||||
from irctest import cases
|
from irctest import cases
|
||||||
from irctest.numerics import (
|
from irctest.numerics import (
|
||||||
|
ERR_NOSUCHNICK,
|
||||||
RPL_AWAY,
|
RPL_AWAY,
|
||||||
RPL_ENDOFWHOIS,
|
RPL_ENDOFWHOIS,
|
||||||
RPL_WHOISACCOUNT,
|
RPL_WHOISACCOUNT,
|
||||||
|
@ -219,6 +220,25 @@ class WhoisTestCase(_WhoisTestMixin, cases.BaseServerTestCase):
|
||||||
whois_user.params[3], [nick, username, "~" + username, realname]
|
whois_user.params[3], [nick, username, "~" + username, realname]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@cases.mark_specifications("RFC2812")
|
||||||
|
@cases.xfailIfSoftware(["Sable"], "https://github.com/Libera-Chat/sable/issues/101")
|
||||||
|
def testWhoisMissingUser(self):
|
||||||
|
"""Test WHOIS on a nonexistent nickname."""
|
||||||
|
self.connectClient("qux", name="qux")
|
||||||
|
self.sendLine("qux", "WHOIS bar")
|
||||||
|
messages = self.getMessages("qux")
|
||||||
|
self.assertEqual(len(messages), 2)
|
||||||
|
self.assertMessageMatch(
|
||||||
|
messages[0],
|
||||||
|
command=ERR_NOSUCHNICK,
|
||||||
|
params=["qux", "bar", ANYSTR],
|
||||||
|
)
|
||||||
|
self.assertMessageMatch(
|
||||||
|
messages[1],
|
||||||
|
command=RPL_ENDOFWHOIS,
|
||||||
|
params=["qux", "bar", ANYSTR],
|
||||||
|
)
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"away,oper",
|
"away,oper",
|
||||||
[(False, False), (True, False), (False, True)],
|
[(False, False), (True, False), (False, True)],
|
||||||
|
|
|
@ -249,7 +249,7 @@ software:
|
||||||
name: Sable
|
name: Sable
|
||||||
repository: Libera-Chat/sable
|
repository: Libera-Chat/sable
|
||||||
refs:
|
refs:
|
||||||
stable: dcf8b53cac54f460b86861908d36d67969cf1eb2
|
stable: fe337a036c3ab5f8548e2578b65568e628f4c32f
|
||||||
release: null
|
release: null
|
||||||
devel: master
|
devel: master
|
||||||
devel_release: null
|
devel_release: null
|
||||||
|
|
Loading…
Reference in New Issue