mirror of https://github.com/progval/irctest.git
Add more tests for CAP + allow trailing spaces (#216)
This commit is contained in:
parent
50d3a8e6da
commit
1c6a7188d6
|
@ -73,6 +73,7 @@ TEMPLATE_CONFIG = """
|
||||||
<module name="m_muteban"> # for testing mute extbans
|
<module name="m_muteban"> # for testing mute extbans
|
||||||
<module name="namesx"> # For multi-prefix
|
<module name="namesx"> # For multi-prefix
|
||||||
<module name="sasl">
|
<module name="sasl">
|
||||||
|
<module name="uhnames"> # For userhost-in-names
|
||||||
|
|
||||||
# HELP/HELPOP
|
# HELP/HELPOP
|
||||||
<module name="alias"> # for the HELP alias
|
<module name="alias"> # for the HELP alias
|
||||||
|
|
|
@ -4,11 +4,32 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from irctest import cases
|
from irctest import cases
|
||||||
from irctest.patma import ANYSTR
|
from irctest.patma import ANYSTR, StrRe
|
||||||
from irctest.runner import CapabilityNotSupported, ImplementationChoice
|
from irctest.runner import CapabilityNotSupported, ImplementationChoice
|
||||||
|
|
||||||
|
|
||||||
class CapTestCase(cases.BaseServerTestCase):
|
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")
|
@cases.mark_specifications("IRCv3")
|
||||||
def testNoReq(self):
|
def testNoReq(self):
|
||||||
"""Test the server handles gracefully clients which do not send
|
"""Test the server handles gracefully clients which do not send
|
||||||
|
@ -23,12 +44,206 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||||
self.getCapLs(1)
|
self.getCapLs(1)
|
||||||
self.sendLine(1, "USER foo foo foo :foo")
|
self.sendLine(1, "USER foo foo foo :foo")
|
||||||
self.sendLine(1, "NICK 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")
|
self.sendLine(1, "CAP END")
|
||||||
m = self.getRegistrationMessage(1)
|
m = self.getRegistrationMessage(1)
|
||||||
self.assertMessageMatch(
|
self.assertMessageMatch(
|
||||||
m, command="001", fail_msg="Expected 001 after sending CAP END, got {msg}."
|
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")
|
@cases.mark_specifications("IRCv3")
|
||||||
def testReqUnavailable(self):
|
def testReqUnavailable(self):
|
||||||
"""Test the server handles gracefully clients which request
|
"""Test the server handles gracefully clients which request
|
||||||
|
@ -45,7 +260,7 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||||
self.assertMessageMatch(
|
self.assertMessageMatch(
|
||||||
m,
|
m,
|
||||||
command="CAP",
|
command="CAP",
|
||||||
params=[ANYSTR, "NAK", "foo"],
|
params=[ANYSTR, "NAK", StrRe("foo ?")],
|
||||||
fail_msg="Expected CAP NAK after requesting non-existing "
|
fail_msg="Expected CAP NAK after requesting non-existing "
|
||||||
"capability, got {msg}.",
|
"capability, got {msg}.",
|
||||||
)
|
)
|
||||||
|
@ -78,10 +293,6 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@cases.mark_specifications("IRCv3")
|
@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):
|
def testNakWhole(self):
|
||||||
"""“The capability identifier set must be accepted as a whole, or
|
"""“The capability identifier set must be accepted as a whole, or
|
||||||
rejected entirely.”
|
rejected entirely.”
|
||||||
|
@ -123,16 +334,12 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||||
self.assertMessageMatch(
|
self.assertMessageMatch(
|
||||||
m,
|
m,
|
||||||
command="CAP",
|
command="CAP",
|
||||||
params=[ANYSTR, "ACK", "multi-prefix"],
|
params=[ANYSTR, "ACK", StrRe("multi-prefix ?")],
|
||||||
fail_msg="Expected “CAP ACK :multi-prefix” after "
|
fail_msg="Expected “CAP ACK :multi-prefix” after "
|
||||||
"sending “CAP REQ :multi-prefix”, but got {msg}.",
|
"sending “CAP REQ :multi-prefix”, but got {msg}.",
|
||||||
)
|
)
|
||||||
|
|
||||||
@cases.mark_specifications("IRCv3")
|
@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):
|
def testCapRemovalByClient(self):
|
||||||
"""Test CAP LIST and removal of caps via CAP REQ :-tagname."""
|
"""Test CAP LIST and removal of caps via CAP REQ :-tagname."""
|
||||||
cap1 = "echo-message"
|
cap1 = "echo-message"
|
||||||
|
@ -167,17 +374,19 @@ class CapTestCase(cases.BaseServerTestCase):
|
||||||
m = self.getMessage(1)
|
m = self.getMessage(1)
|
||||||
self.assertIn("time", m.tags, m)
|
self.assertIn("time", m.tags, m)
|
||||||
|
|
||||||
# remove the server-time cap
|
# remove the multi-prefix cap
|
||||||
self.sendLine(1, f"CAP REQ :-{cap2}")
|
self.sendLine(1, f"CAP REQ :-{cap2}")
|
||||||
m = self.getMessage(1)
|
m = self.getMessage(1)
|
||||||
# Must be either ACK or NAK
|
# 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(
|
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}")
|
raise ImplementationChoice(f"Does not support CAP REQ -{cap2}")
|
||||||
|
|
||||||
# server-time should be disabled
|
# multi-prefix should be disabled
|
||||||
self.sendLine(1, "CAP LIST")
|
self.sendLine(1, "CAP LIST")
|
||||||
messages = self.getMessages(1)
|
messages = self.getMessages(1)
|
||||||
cap_list = [m for m in messages if m.command == "CAP"][0]
|
cap_list = [m for m in messages if m.command == "CAP"][0]
|
||||||
|
|
Loading…
Reference in New Issue