diff --git a/irctest/cases.py b/irctest/cases.py index 14ddd08..51fd2a5 100644 --- a/irctest/cases.py +++ b/irctest/cases.py @@ -40,6 +40,7 @@ class _IrcTestCase(unittest.TestCase): Deals with subcommands (eg. `CAP`) if any of `subcommand`, `subparams`, and `target` are given.""" + fail_msg = fail_msg or '{msg}' for (key, value) in kwargs.items(): self.assertEqual(getattr(msg, key), value, msg, fail_msg) if subcommand is not None or subparams is not None: diff --git a/irctest/server_tests/test_channel_operations.py b/irctest/server_tests/test_channel_operations.py index f618ff5..394893e 100644 --- a/irctest/server_tests/test_channel_operations.py +++ b/irctest/server_tests/test_channel_operations.py @@ -134,6 +134,89 @@ class JoinTestCase(cases.BaseServerTestCase): '"foo" with an optional "+" or "@" prefix, but got: ' '{msg}') + def testTopic(self): + """“Once a user has joined a channel, he receives information about + all commands his server receives affecting the channel. This + includes […] TOPIC” + -- + and + """ + self.connectClient('foo') + self.connectClient('bar') + self.sendLine(1, 'JOIN #chan') + self.sendLine(2, 'JOIN #chan') + # TODO: check foo is opped OR +t is unset + + self.getMessages(1) + self.getMessages(2) + self.getMessages(1) + + self.sendLine(1, 'TOPIC #chan :T0P1C') + try: + m = self.getMessage(1) + if m.command == '482': + print(m) + raise optionality.ImplementationChoice( + 'Channel creators are not opped by default, and ' + 'channel modes to no allow regular users to change ' + 'topic.') + self.assertMessageEqual(m, command='TOPIC') + except client_mock.NoMessageException: + # The RFCs do not say TOPIC must be echoed + pass + m = self.getMessage(2) + self.assertMessageEqual(m, command='TOPIC', params=['#chan', 'T0P1C']) + + def testTopicMode(self): + """“Once a user has joined a channel, he receives information about + all commands his server receives affecting the channel. This + includes […] TOPIC” + -- + and + """ + self.connectClient('foo') + self.connectClient('bar') + self.sendLine(1, 'JOIN #chan') + self.sendLine(2, 'JOIN #chan') + # TODO: check foo is opped + + self.getMessages(1) + self.getMessages(2) + self.getMessages(1) + + self.sendLine(1, 'MODE #chan +t') + try: + m = self.getMessage(1) + if m.command == '482': + print(m) + raise optionality.ImplementationChoice( + 'Channel creators are not opped by default.') + self.assertMessageEqual(m, command='TOPIC') + except client_mock.NoMessageException: + # The RFCs do not say TOPIC must be echoed + pass + self.sendLine(2, 'TOPIC #chan :T0P1C') + m = self.getMessage(2) + self.assertMessageEqual(m, command='482', + fail_msg='Non-op user was not refused use of TOPIC: {msg}') + self.assertEqual(self.getMessages(1), []) + + self.sendLine(1, 'MODE #chan -t') + self.getMessages(1) + self.sendLine(2, 'TOPIC #chan :T0P1C') + try: + m = self.getMessage(2) + self.assertNotEqual(m.command, '482', + msg='User was refused TOPIC whereas +t was not ' + 'set: {}'.format(m)) + except client_mock.NoMessageException: + # The RFCs do not say TOPIC must be echoed + pass + m = self.getMessage(1) + self.assertMessageEqual(m, command='TOPIC', params=['#chan', 'T0P1C']) + + + def testListEmpty(self): """ @@ -211,7 +294,7 @@ class JoinTestCase(cases.BaseServerTestCase): 'Channel creators are not opped by default.') self.assertMessageEqual(m, command='KICK') except client_mock.NoMessageException: - # The RFCs do not say KICK should be echoed + # The RFCs do not say KICK must be echoed pass m = self.getMessage(2) self.assertMessageEqual(m, command='KICK', @@ -253,7 +336,7 @@ class JoinTestCase(cases.BaseServerTestCase): raise optionality.NotImplementedByController( 'Multi-target KICK') except client_mock.NoMessageException: - # The RFCs do not say KICK should be echoed + # The RFCs do not say KICK must be echoed pass # TODO: could be in the other order