def test_settz_create_and_update(self): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.settz America/Chicago'])) self.bot.reply_to.assert_called_with( NickMask('[email protected]'), '#test', 'Your timezone has been set to America/Chicago') c = self.bot.db.cursor() c.execute('SELECT tz FROM tz_info WHERE nick = ?', ('test', )) tz, = next(c) assert tz == 'America/Chicago' self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.settz America/New_York'])) self.bot.reply_to.assert_called_with( NickMask('[email protected]'), '#test', 'Your timezone has been set to America/New_York') c = self.bot.db.cursor() c.execute('SELECT tz FROM tz_info WHERE nick = ?', ('test', )) tz, = next(c) assert tz == 'America/New_York'
def test_time_for_other(self): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.settz America/Chicago'])) self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.time other'])) response = self.bot.say.call_args[0][1] assert response.startswith('Current time in America/Chicago is: ')
def __init__(self, string, user='******', source='pubmsg'): if isinstance(user, Player): user = '******'.format(user.nick, user.user) mask = NickMask(user) source = '#test' if source == 'pubmsg' else mask.nick event = Event('privmsg', mask, source, [string]) super().__init__(event)
def test_command_alias_works(self): def handler(bot, source, target, message, **kwargs): bot.say(target, 'This is an example') self.bot.add_command('example', handler, aliases=['a1', 'a2']) self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['.a1'])) self.bot.connection.privmsg.assert_called_with('#test', 'This is an example') self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['.a2'])) self.bot.connection.privmsg.assert_called_with('#test', 'This is an example')
def test_channel_joins(config, bot, nickmask, monkeypatch): class FakeSocket: def getpeername(self): return ('10.0.0.99', 6667) socket = FakeSocket() conn = ServerConnection(None) welcome_event = Event(type='welcome', source=config.server.host, target=config.nickname) def join(self, channel, key=''): join_event = Event(type='join', source=nickmask, target=channel) bot.on_join(conn, join_event) received_signal_data = [] @irc_channel_joined.connect def handle_irc_channel_joined(sender, **data): received_signal_data.append(data) with monkeypatch.context() as mpc: mpc.setattr(ServerConnection, 'socket', socket) mpc.setattr(ServerConnection, 'join', join) bot.on_welcome(conn, welcome_event) assert received_signal_data == [ { 'channel_name': '#one' }, { 'channel_name': '#two' }, ]
def test_command_not_found_replies_to_user(self): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['.notacommand 1 2'])) self.bot.connection.privmsg.assert_called_with( '#test', "user: I don't know about that command.")
def test_time_in_tz_utc(self): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.time UTC'])) response = self.bot.say.call_args[0][1] assert response.startswith('Current time in UTC is: ')
def action(self, user_host, channel, msg): # check if private message if channel != self.nickname: return # create pseudo-event object e = Event("action", NickMask(user_host), channel, ("!action " + msg).split()) logger.info(f"ACTION: BOT:{self.nickname} <- USER:{e.source.nick} {msg}") self.on_msg(e)
def test_on_welcome(self): event = Event('welcome', 'freenode.net', 'me', ['WELCOME!']) # Expect an IDENTIFY message to NickServ self.mycli.on_welcome(self.connection, event) self.assertEqual(self.connection.privmsgs['NickServ'][-1], "(NickServ) IDENTIFY p4ssw0rd") # Expect some channels joined self.assertEqual(self.connection.channels, [self.target])
def test_time_in_tz_not_found(self): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.time NotA/Timezone'])) self.bot.reply_to.assert_called_with( NickMask('[email protected]'), '#test', "I don't know about that timezone.")
def test_time_for_other_not_found(self): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.time other'])) self.bot.reply_to.assert_called_with(NickMask('[email protected]'), '#test', "I don't know other's timezone.")
def privmsg(self, user_host, channel, msg): # check if private message if channel != self.nickname: return # create pseudo-event object e = Event("privmsg", NickMask(user_host), channel, msg.split()) logger.info(f"MESSAGE: BOT:{self.nickname} <- USER:{e.source.nick}: {msg}") self.on_msg(e)
def test_url_match_trigger(self): with mock.patch('bavi.modules.url.requests.get', return_value=fake_get("only the shittiest")): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['http://shitty.vodka'])) self.bot.say.assert_called_with( '#test', '[ only the shittiest ] - shitty.vodka')
def test_command_failure_replies_with_error(self): def handler(bot, source, target, message, **kwargs): raise KeyError('frobulator') self.bot.add_command('example', handler) self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['.example'])) self.bot.connection.privmsg.assert_called_with( '#test', "KeyError: 'frobulator'")
def test_url_command_trigger(self): with mock.patch('bavi.modules.url.requests.get', return_value=fake_get("sample page")): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.title http://example.com'])) self.bot.say.assert_called_with('#test', '[ sample page ] - example.com')
def test_random_normal(self): with mock.patch('bavi.modules.random.choice', return_value=4) as mock_random: self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['.choose 1,2,3,4,5'])) self.bot.reply_to.assert_called_with( NickMask('user!ident@host'), '#test', 'Your choices: 1, 2, 3, 4, 5, I chose: 4.')
def test_add_matcher(self): def handler(bot, source, target, message, match): bot.say(target, 'Matched {}'.format(match.group(1))) self.bot.add_matcher(re.compile(r'matchme:([0-9]+)'), handler) self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['this is an matchme:123 example'])) self.bot.connection.privmsg.assert_called_with('#test', 'Matched 123')
def test_on_pubmsg_irrelevant(self): event = Event('pubmsg', '@somebody', self.target, ['a message']) # Receive a pubmsg self.mycli.on_pubmsg(self.connection, event) self.assertEqual(self.mycli.count_per_channel[self.target], 1) # Receive a second pubmsg self.mycli.on_pubmsg(self.connection, event) self.assertEqual(self.mycli.count_per_channel[self.target], 2) self.assertEqual(self.connection.privmsgs, {})
def test_matcher_raises_error_prints_error(self): def handler(bot, source, target, message, match): raise ValueError('Something is wrong') self.bot.add_matcher(re.compile(r'matchme:([0-9]+)'), handler) self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['this is an matchme:123 example'])) self.bot.connection.privmsg.assert_called_with( '#test', 'ValueError: Something is wrong')
def test_random_trailing_whitespace(self): with mock.patch('bavi.modules.random.choice', return_value='blue fish') as mock_random: self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['.pick one fish, two fish, red fish, blue fish'])) self.bot.reply_to.assert_called_with( NickMask('user!ident@host'), '#test', 'Your choices: one fish, two fish,' ' red fish, blue fish, I chose: blue fish.')
def test_random_pick(self): with mock.patch('bavi.modules.random.choice', return_value='g') as mock_random: self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['.pick a|b|c|d|e|f|g'])) self.bot.reply_to.assert_called_with( NickMask('user!ident@host'), '#test', 'Your choices: a, b, c, d,' ' e, f, g, I chose: g.')
def test_settz_missing_timezone(self): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.settz'])) self.bot.reply_to.assert_called_with( NickMask('[email protected]'), '#test', 'Give me a timezone, for example .settz America/Los_Angeles') c = self.bot.db.cursor() c.execute('SELECT tz FROM tz_info WHERE nick = ?', ('test', )) assert len(list(c)) == 0
def test_settz_invalid_timezone(self): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.settz NotA/RealTimezone'])) self.bot.reply_to.assert_called_with( NickMask('[email protected]'), '#test', "I don't know about that timezone") c = self.bot.db.cursor() c.execute('SELECT tz FROM tz_info WHERE nick = ?', ('test', )) assert len(list(c)) == 0
def test_command_with_no_args_works(self): def handler(bot, source, target, message, **kwargs): bot.say(target, 'This is an example') def handler2(bot, source, target, message, **kwargs): bot.say(target, 'This is a second example') self.bot.add_command('example', handler) self.bot.add_command('example2', handler2) self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['.example'])) self.bot.connection.privmsg.assert_called_with('#test', 'This is an example') self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['TestBot: example2'])) self.bot.connection.privmsg.assert_called_with( '#test', 'This is a second example')
def say(self, channel, message): if isinstance(message, str): message = message.decode('utf-8', errors='replace') message = re.sub(r'\n', ' | ', message) source = NickMask('%s!%s@%s' % (self.nick, self.nick, self.nick)) target = channel arguments = [message] if target.startswith('#'): type = 'pubmsg' else: type = 'privmsg' e = Event(type, source, target, arguments) self.connection.privmsg(channel, message) logger.log_event(self.server, e)
def test_multiple_url_match_trigger(self): with mock.patch('bavi.modules.url.requests.get', side_effect=[ fake_get("first webpage"), fake_get("second webpage") ]): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('user!ident@host'), '#test', ['http://first.web.site http://second.web.io'])) self.bot.say.assert_has_calls([ mock.call('#test', '[ first webpage ] - first.web.site'), mock.call('#test', '[ second webpage ] - second.web.io') ], any_order=False)
def do_command(self, user_host, target, msg): cmd = msg.split()[0] e = Event("", NickMask(user_host), target, [msg]) if cmd == "reload": logger.debug("Command incurred: " + cmd) if e.source.nick == self.Config().main.owner: self.msg(e.source.nick, "Attempting a reload...") try: utils.reload_all(utils, 3) self.reload_init(self.start_time, self.users) self.msg(e.source.nick, "Reload successful!") except: logger.exception("Reload Exception") self.msg( e.source.nick, "Reload failed! Killing bot due to possible errors.") self.quit() reactor.callFromThread(reactor.stop) else: if cmd.split()[0] in self.command_funcs or \ any((cmd.split()[0] in s and s[:4] == "cmd_") for s in self.command_funcs): logger.debug("Command incurred: " + cmd) # check if user in database in_f_db = utils.Utils.check_user_in_db(e.source, self, "ftm") if not in_f_db: self.msg(e.source.nick, self.FIRST_TIME_MSG) in_u_db = utils.Utils.check_user_in_db(e.source, self, "um") if not in_u_db: self.msg(e.source.nick, self.UPDATE_MSG) i = cmd.split()[0] if any((cmd.split()[0] in s and s[:4] == "cmd_") for s in self.command_funcs): i = "cmd_" + i func = getattr(utils.Commands, i) func(self.Commands, self, e) else: self.msg( e.source.nick, "Invalid command: " + cmd + ". " + self.Config().main.prefix + "h for help.")
def _test_on_pubmsg_generic(self, msg, expected): event = Event('pubmsg', '@somebody', self.target, [msg]) # Receive a message with an issue number tag self.mycli.on_pubmsg(self.connection, event) # Expect an answer from the bot self.assertEqual(self.mycli.count_per_channel[self.target], 1) self.assertEqual(len(self.connection.privmsgs[self.target]), 1) self.assertEqual(self.connection.privmsgs[self.target][-1], expected) # Receive 'spam_threshold' more messages for i in range(self.mycli.spam_threshold): self.mycli.on_pubmsg(self.connection, event) self.assertEqual(self.mycli.count_per_channel[self.target], 2 + i) # Expect the bot to stay quiet self.assertEqual(len(self.connection.privmsgs[self.target]), 1) # Receive the same message once more self.mycli.on_pubmsg(self.connection, event) # Expect the bot to reply again self.assertEqual(self.mycli.count_per_channel[self.target], 17) self.assertEqual(len(self.connection.privmsgs[self.target]), 2) self.assertEqual(self.connection.privmsgs[self.target][-1], expected)
def handle_data(self, clientsocket, bot): commits = [] ''' Read in and parse data from socket ''' try: # make a file object to do the buffering socketfile = clientsocket.makefile() commit = '' for line in socketfile.readlines(): line = line.strip() if line == COMMIT_BREAK: commits.append(commit) commit = '' continue commit += line + ' ' # Add final entry commits.append(commit) finally: socketfile.close() ''' Now post commits to the channel ''' for post in commits: ''' Chunk the string if it is too long ''' for chunk in chunker( post, 450): # Should be safe for the 512-byte constraint # Post the commit! bot.connection.action(bot.channel, chunk) # Log it event = Event("action", bot.connection.get_nickname(), bot.channel, [chunk]) bot.on_action(bot.connection, event) # Don't spam too fast time.sleep(COMMIT_POST_DELAY)
def test_execute_command(self): self.bot.on_pubmsg( None, Event('pubmsg', NickMask('[email protected]'), '#test', ['.test 1 2 3'])) self.bot.say.assert_called_with('#test', 'The test result is: 1')