mirror of
https://github.com/progval/irctest.git
synced 2025-04-04 22:39:50 +00:00
Add more tests for CAP + allow trailing spaces (#216)
This commit is contained in:
@ -73,6 +73,7 @@ TEMPLATE_CONFIG = """
|
||||
<module name="m_muteban"> # for testing mute extbans
|
||||
<module name="namesx"> # For multi-prefix
|
||||
<module name="sasl">
|
||||
<module name="uhnames"> # For userhost-in-names
|
||||
|
||||
# HELP/HELPOP
|
||||
<module name="alias"> # for the HELP alias
|
||||
|
@ -4,11 +4,32 @@
|
||||
"""
|
||||
|
||||
from irctest import cases
|
||||
from irctest.patma import ANYSTR
|
||||
from irctest.patma import ANYSTR, StrRe
|
||||
from irctest.runner import CapabilityNotSupported, ImplementationChoice
|
||||
|
||||
|
||||
class CapTestCase(cases.BaseServerTestCase):
|
||||
@cases.mark_specifications("IRCv3")
|
||||
def testInvalidCapSubcommand(self):
|
||||
"""“If no capabilities are active, an empty parameter must be sent.”
|
||||
-- <http://ircv3.net/specs/core/capability-negotiation-3.1.html#the-cap-list-subcommand>
|
||||
""" # noqa
|
||||
self.addClient()
|
||||
self.sendLine(1, "CAP NOTACOMMAND")
|
||||
self.sendLine(1, "PING test123")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertTrue(
|
||||
self.messageDiffers(m, command="PONG", params=[ANYSTR, "test123"]),
|
||||
"Sending “CAP NOTACOMMAND” as first message got no reply",
|
||||
)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="410",
|
||||
params=["*", "NOTACOMMAND", ANYSTR],
|
||||
fail_msg="Sending “CAP NOTACOMMAND” as first message got a reply "
|
||||
"that is not ERR_INVALIDCAPCMD: {msg}",
|
||||
)
|
||||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
def testNoReq(self):
|
||||
"""Test the server handles gracefully clients which do not send
|
||||
@ -23,12 +44,206 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||
self.getCapLs(1)
|
||||
self.sendLine(1, "USER foo foo foo :foo")
|
||||
self.sendLine(1, "NICK foo")
|
||||
|
||||
# Make sure the server didn't send anything yet
|
||||
self.sendLine(1, "CAP LS 302")
|
||||
self.getCapLs(1)
|
||||
|
||||
self.sendLine(1, "CAP END")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m, command="001", fail_msg="Expected 001 after sending CAP END, got {msg}."
|
||||
)
|
||||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
def testReqOne(self):
|
||||
"""Tests requesting a single capability"""
|
||||
self.addClient(1)
|
||||
self.sendLine(1, "CAP LS")
|
||||
self.getCapLs(1)
|
||||
self.sendLine(1, "USER foo foo foo :foo")
|
||||
self.sendLine(1, "NICK foo")
|
||||
self.sendLine(1, "CAP REQ :multi-prefix")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[ANYSTR, "ACK", StrRe("multi-prefix ?")],
|
||||
fail_msg="Expected CAP ACK after sending CAP REQ, got {msg}.",
|
||||
)
|
||||
|
||||
self.sendLine(1, "CAP LIST")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[ANYSTR, "LIST", StrRe("multi-prefix ?")],
|
||||
fail_msg="Expected CAP LIST after sending CAP LIST, got {msg}.",
|
||||
)
|
||||
|
||||
self.sendLine(1, "CAP END")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m, command="001", fail_msg="Expected 001 after sending CAP END, got {msg}."
|
||||
)
|
||||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
@cases.xfailIfSoftware(
|
||||
["ngIRCd"],
|
||||
"ngIRCd does not support userhost-in-names",
|
||||
)
|
||||
def testReqTwo(self):
|
||||
"""Tests requesting two capabilities at once"""
|
||||
self.addClient(1)
|
||||
self.sendLine(1, "CAP LS")
|
||||
self.getCapLs(1)
|
||||
self.sendLine(1, "USER foo foo foo :foo")
|
||||
self.sendLine(1, "NICK foo")
|
||||
self.sendLine(1, "CAP REQ :multi-prefix userhost-in-names")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[ANYSTR, "ACK", StrRe("multi-prefix userhost-in-names ?")],
|
||||
fail_msg="Expected CAP ACK after sending CAP REQ, got {msg}.",
|
||||
)
|
||||
|
||||
self.sendLine(1, "CAP LIST")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[
|
||||
ANYSTR,
|
||||
"LIST",
|
||||
StrRe(
|
||||
"(multi-prefix userhost-in-names|userhost-in-names multi-prefix) ?"
|
||||
),
|
||||
],
|
||||
fail_msg="Expected CAP LIST after sending CAP LIST, got {msg}.",
|
||||
)
|
||||
|
||||
self.sendLine(1, "CAP END")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m, command="001", fail_msg="Expected 001 after sending CAP END, got {msg}."
|
||||
)
|
||||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
@cases.xfailIfSoftware(
|
||||
["ngIRCd"],
|
||||
"ngIRCd does not support userhost-in-names",
|
||||
)
|
||||
def testReqOneThenOne(self):
|
||||
"""Tests requesting two capabilities in different messages"""
|
||||
self.addClient(1)
|
||||
self.sendLine(1, "CAP LS")
|
||||
self.getCapLs(1)
|
||||
self.sendLine(1, "USER foo foo foo :foo")
|
||||
self.sendLine(1, "NICK foo")
|
||||
|
||||
self.sendLine(1, "CAP REQ :multi-prefix")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[ANYSTR, "ACK", StrRe("multi-prefix ?")],
|
||||
fail_msg="Expected CAP ACK after sending CAP REQ, got {msg}.",
|
||||
)
|
||||
|
||||
self.sendLine(1, "CAP REQ :userhost-in-names")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[ANYSTR, "ACK", StrRe("userhost-in-names ?")],
|
||||
fail_msg="Expected CAP ACK after sending CAP REQ, got {msg}.",
|
||||
)
|
||||
|
||||
self.sendLine(1, "CAP LIST")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[
|
||||
ANYSTR,
|
||||
"LIST",
|
||||
StrRe(
|
||||
"(multi-prefix userhost-in-names|userhost-in-names multi-prefix) ?"
|
||||
),
|
||||
],
|
||||
fail_msg="Expected CAP LIST after sending CAP LIST, got {msg}.",
|
||||
)
|
||||
|
||||
self.sendLine(1, "CAP END")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m, command="001", fail_msg="Expected 001 after sending CAP END, got {msg}."
|
||||
)
|
||||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
@cases.xfailIfSoftware(
|
||||
["ngIRCd"],
|
||||
"ngIRCd does not support userhost-in-names",
|
||||
)
|
||||
def testReqPostRegistration(self):
|
||||
"""Tests requesting more capabilities after CAP END"""
|
||||
self.addClient(1)
|
||||
self.sendLine(1, "CAP LS")
|
||||
self.getCapLs(1)
|
||||
self.sendLine(1, "USER foo foo foo :foo")
|
||||
self.sendLine(1, "NICK foo")
|
||||
|
||||
self.sendLine(1, "CAP REQ :multi-prefix")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[ANYSTR, "ACK", StrRe("multi-prefix ?")],
|
||||
fail_msg="Expected CAP ACK after sending CAP REQ, got {msg}.",
|
||||
)
|
||||
|
||||
self.sendLine(1, "CAP LIST")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[ANYSTR, "LIST", StrRe("multi-prefix ?")],
|
||||
fail_msg="Expected CAP LIST after sending CAP LIST, got {msg}.",
|
||||
)
|
||||
|
||||
self.sendLine(1, "CAP END")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m, command="001", fail_msg="Expected 001 after sending CAP END, got {msg}."
|
||||
)
|
||||
|
||||
self.getMessages(1)
|
||||
|
||||
self.sendLine(1, "CAP REQ :userhost-in-names")
|
||||
m = self.getRegistrationMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[ANYSTR, "ACK", StrRe("userhost-in-names ?")],
|
||||
fail_msg="Expected CAP ACK after sending CAP REQ, got {msg}.",
|
||||
)
|
||||
|
||||
self.sendLine(1, "CAP LIST")
|
||||
m = self.getMessage(1)
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[
|
||||
ANYSTR,
|
||||
"LIST",
|
||||
StrRe(
|
||||
"(multi-prefix userhost-in-names|userhost-in-names multi-prefix) ?"
|
||||
),
|
||||
],
|
||||
fail_msg="Expected CAP LIST after sending CAP LIST, got {msg}.",
|
||||
)
|
||||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
def testReqUnavailable(self):
|
||||
"""Test the server handles gracefully clients which request
|
||||
@ -45,7 +260,7 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[ANYSTR, "NAK", "foo"],
|
||||
params=[ANYSTR, "NAK", StrRe("foo ?")],
|
||||
fail_msg="Expected CAP NAK after requesting non-existing "
|
||||
"capability, got {msg}.",
|
||||
)
|
||||
@ -78,10 +293,6 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||
)
|
||||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
@cases.xfailIfSoftware(
|
||||
["UnrealIRCd"],
|
||||
"UnrealIRCd sends a trailing space on CAP NAK: https://github.com/unrealircd/unrealircd/pull/148",
|
||||
)
|
||||
def testNakWhole(self):
|
||||
"""“The capability identifier set must be accepted as a whole, or
|
||||
rejected entirely.”
|
||||
@ -123,16 +334,12 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||
self.assertMessageMatch(
|
||||
m,
|
||||
command="CAP",
|
||||
params=[ANYSTR, "ACK", "multi-prefix"],
|
||||
params=[ANYSTR, "ACK", StrRe("multi-prefix ?")],
|
||||
fail_msg="Expected “CAP ACK :multi-prefix” after "
|
||||
"sending “CAP REQ :multi-prefix”, but got {msg}.",
|
||||
)
|
||||
|
||||
@cases.mark_specifications("IRCv3")
|
||||
@cases.xfailIfSoftware(
|
||||
["UnrealIRCd"],
|
||||
"UnrealIRCd sends a trailing space on CAP NAK: https://github.com/unrealircd/unrealircd/pull/148",
|
||||
)
|
||||
def testCapRemovalByClient(self):
|
||||
"""Test CAP LIST and removal of caps via CAP REQ :-tagname."""
|
||||
cap1 = "echo-message"
|
||||
@ -167,17 +374,19 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||
m = self.getMessage(1)
|
||||
self.assertIn("time", m.tags, m)
|
||||
|
||||
# remove the server-time cap
|
||||
# remove the multi-prefix cap
|
||||
self.sendLine(1, f"CAP REQ :-{cap2}")
|
||||
m = self.getMessage(1)
|
||||
# Must be either ACK or NAK
|
||||
if self.messageDiffers(m, command="CAP", params=[ANYSTR, "ACK", f"-{cap2}"]):
|
||||
if self.messageDiffers(
|
||||
m, command="CAP", params=[ANYSTR, "ACK", StrRe(f"-{cap2} ?")]
|
||||
):
|
||||
self.assertMessageMatch(
|
||||
m, command="CAP", params=[ANYSTR, "NAK", f"-{cap2}"]
|
||||
m, command="CAP", params=[ANYSTR, "NAK", StrRe(f"-{cap2} ?")]
|
||||
)
|
||||
raise ImplementationChoice(f"Does not support CAP REQ -{cap2}")
|
||||
|
||||
# server-time should be disabled
|
||||
# multi-prefix should be disabled
|
||||
self.sendLine(1, "CAP LIST")
|
||||
messages = self.getMessages(1)
|
||||
cap_list = [m for m in messages if m.command == "CAP"][0]
|
||||
|
Reference in New Issue
Block a user