def test_account_tag(): bot = MagicMock() bot.loop = asyncio.get_event_loop() conn = MockConn(bot) data = { "conn": conn, "irc_tags": TagList.from_dict({"account": "foo"}), "nick": "bar", } user = chan_track.get_users(conn).getuser("bar") assert user.account is None res = call_with_args(chan_track.handle_tags, data) assert res is None assert dict(chan_track.get_users(conn)) == {"bar": user} assert user.account == "foo" data = { "conn": conn, "irc_tags": TagList.from_dict({"account": "*"}), "nick": "bar", } res = call_with_args(chan_track.handle_tags, data) assert res is None assert dict(chan_track.get_users(conn)) == {"bar": user} assert user.account is None
def test_names_handling(): handlers = { "JOIN": chan_track.on_join, "PART": chan_track.on_part, "QUIT": chan_track.on_quit, "KICK": chan_track.on_kick, "353": chan_track.on_names, "366": chan_track.on_names, } bot = MagicMock() bot.loop = asyncio.get_event_loop() conn = MockConn(bot) serv_info = conn.memory["server_info"] server_info.handle_prefixes("(YohvV)!@%+-", serv_info) server_info.handle_chan_modes( "IXZbegw,k,FHJLWdfjlx,ABCDKMNOPQRSTcimnprstuz", serv_info ) for line in NAMES_MOCK_TRAFFIC: from cloudbot.clients.irc import _IrcProtocol event = _IrcProtocol(conn=conn).parse_line(line) call_with_args(handlers[event.irc_command], event)
def test_call_with_args(): args = [] def func(arg1, arg2=None, _arg3=None): nonlocal args args = [arg1, arg2, _arg3] from cloudbot.util.func_utils import call_with_args, ParameterError call_with_args(func, {'arg1': 1, 'arg2': 3}) assert args == [1, 3, None] with pytest.raises(ParameterError): call_with_args(func, {})
def test_names_handling(): from plugins.core.server_info import handle_prefixes, handle_chan_modes from plugins.core.chan_track import on_join, on_part, on_kick, on_quit, on_names handlers = { "JOIN": on_join, "PART": on_part, "QUIT": on_quit, "KICK": on_kick, "353": on_names, "366": on_names, } chan_pos = { "JOIN": 0, "PART": 0, "KICK": 0, "353": 2, "366": 1, } bot = MagicMock() bot.loop = asyncio.get_event_loop() conn = MockConn(bot) serv_info = conn.memory["server_info"] handle_prefixes("(YohvV)!@%+-", serv_info) handle_chan_modes("IXZbegw,k,FHJLWdfjlx,ABCDKMNOPQRSTcimnprstuz", serv_info) for line in NAMES_MOCK_TRAFFIC: line = Message.parse(line) data = { "nick": line.prefix.nick, "user": line.prefix.ident, "host": line.prefix.host, "conn": conn, "irc_paramlist": line.parameters, "irc_command": line.command, "chan": None, "target": None, } if line.command in chan_pos: data["chan"] = line.parameters[chan_pos[line.command]] if line.command == "KICK": data["target"] = line.parameters[1] call_with_args(handlers[line.command], data)
def test_names_handling(): from plugins.core.server_info import handle_prefixes, handle_chan_modes from plugins.chan_track import on_join, on_part, on_kick, on_quit, on_names handlers = { 'JOIN': on_join, 'PART': on_part, 'QUIT': on_quit, 'KICK': on_kick, '353': on_names, '366': on_names, } chan_pos = { 'JOIN': 0, 'PART': 0, 'KICK': 0, '353': 2, '366': 1, } bot = MagicMock() bot.loop = asyncio.get_event_loop() conn = MockConn(bot) serv_info = conn.memory['server_info'] handle_prefixes('(YohvV)!@%+-', serv_info) handle_chan_modes('IXZbegw,k,FHJLWdfjlx,ABCDKMNOPQRSTcimnprstuz', serv_info) for line in NAMES_MOCK_TRAFFIC: line = Message.parse(line) data = { 'nick': line.prefix.nick, 'user': line.prefix.ident, 'host': line.prefix.host, 'conn': conn, 'irc_paramlist': line.parameters, 'irc_command': line.command, 'chan': None, 'target': None, } if line.command in chan_pos: data['chan'] = line.parameters[chan_pos[line.command]] if line.command == 'KICK': data['target'] = line.parameters[1] call_with_args(handlers[line.command], data)
def wrap_hook_response(func, event, results=None): """ Wrap the response from a hook, allowing easy assertion against calls to event.notice(), event.reply(), etc instead of just returning a string """ if results is None: results = [] def add_result(name, value, data=None): results.append(HookResult(name, value, data)) def notice(*args, **kwargs): # pragma: no cover add_result('notice', args, kwargs) def message(*args, **kwargs): # pragma: no cover add_result('message', args, kwargs) def action(*args, **kwargs): # pragma: no cover add_result('action', args, kwargs) patch_notice = patch.object(event.conn, 'notice', notice) patch_message = patch.object(event.conn, 'message', message) patch_action = patch.object(event.conn, 'action', action) with patch_action, patch_message, patch_notice: res = call_with_args(func, event) if res is not None: add_result('return', res) return results
def display_scores(score_type: ScoreType, event, text, chan, conn, db): if is_opt_out(conn.name, chan): return global_pfx = "Duck {noun} scores across the network: ".format( noun=score_type.noun) chan_pfx = "Duck {noun} scores in {chan}: ".format(noun=score_type.noun, chan=chan) no_ducks = "It appears no one has {verb} any ducks yet." out = global_pfx if text else chan_pfx try: func = DISPLAY_FUNCS[text.lower() or None] except KeyError: event.notice_doc() return scores_dict = call_with_args(func, { 'db': db, 'score_type': score_type, 'conn': conn, 'chan': chan, }) if not scores_dict: return no_ducks return top_list(out, scores_dict.items())
def wrap_result(func, event, results=None): """ Wrap the response from a hook, allowing easy assertion against calls to event.notice(), event.reply(), etc instead of just returning a string """ if results is None: results = [] def notice(*args, **kwargs): # pragma: no cover results.append(('notice', args, kwargs)) def message(*args, **kwargs): # pragma: no cover results.append(('message', args, kwargs)) def action(*args, **kwargs): # pragma: no cover results.append(('action', args, kwargs)) with patch.object(event.conn, 'notice', notice), \ patch.object(event.conn, 'message', message), \ patch.object(event.conn, 'action', action): res = call_with_args(func, event) if res is not None: results.append(('return', res)) return results
def run_func_with_args(loop, func, arg_data, executor=None): if asyncio.iscoroutine(func): raise TypeError('A coroutine function or a normal, non-async callable are required') if asyncio.iscoroutinefunction(func): coro = call_with_args(func, arg_data) else: coro = loop.run_in_executor(executor, call_with_args, func, arg_data) return (yield from coro)
def _execute_hook_threaded(self, hook, event): """ :type hook: cloudbot.plugin_hooks.Hook :type event: cloudbot.event.Event """ event.prepare_threaded() try: return call_with_args(hook.function, event) finally: event.close_threaded()
def _execute_hook_sync(self, hook, event): """ :type hook: Hook :type event: cloudbot.event.Event """ yield from event.prepare() try: return (yield from call_with_args(hook.function, event)) finally: yield from event.close()
def func(text, event): event.text = alias.name + " " + text return call_with_args(crypto_command, event)
def _call(func, event): if asyncio.iscoroutinefunction(func): return event.loop.run_until_complete(call_with_args(func, event)) return call_with_args(func, event)
def func(event): try: return func_utils.call_with_args(f, event) except exc_type as e: return handler(event, e)
def test_find_location(mock_requests, patch_try_shorten, mock_db): from plugins import weather bot = MockBot({}, mock_db) weather.create_maps_api(bot) weather.location_cache.clear() assert weather.data.maps_api is None bot = setup_api(mock_requests, mock_db) assert weather.find_location('Foo Bar') == { 'lat': 30.123, 'lng': 123.456, 'address': '123 Test St, Example City, CA', } conn = MagicMock() conn.config = {} conn.bot = bot cmd_event = CommandEvent(text='', cmd_prefix='.', triggered_command='we', hook=MagicMock(), bot=bot, conn=conn, channel='#foo', nick='foobar') cmd_event.hook.required_args = ['db'] cmd_event.hook.doc = "- foobar" cmd_event.prepare_threaded() assert wrap_hook_response(weather.weather, cmd_event) == [ ('notice', ('foobar', '.we - foobar'), {}) ] weather.location_cache.append(('foobar', 'test location')) mock_requests.add(mock_requests.GET, re.compile(r'^https://api\.darksky\.net/forecast/.*'), **FIO_DATA) assert wrap_hook_response(weather.weather, cmd_event) == [( 'message', ( '#foo', '(foobar) \x02Current\x02: foobar, 68F/20C\x0f; \x02High\x02: 64F/18C\x0f; ' '\x02Low\x02: 57F/14C\x0f; \x02Humidity\x02: 45%\x0f; ' '\x02Wind\x02: 12MPH/20KPH SE\x0f ' '-- 123 Test St, Example City, CA - ' '\x1fhttps://darksky.net/forecast/30.123,123.456\x0f ' '(\x1dTo get a forecast, use .fc\x1d)', ), {}, )] assert wrap_hook_response(weather.forecast, cmd_event) == [( 'message', ( '#foo', '(foobar) \x02Today\x02: foobar; High: 64F/18C; Low: 57F/14C; ' 'Humidity: 45%; Wind: 15MPH/24KPH SE | ' '\x02Tomorrow\x02: foobar; High: 64F/18C; ' 'Low: 57F/14C; Humidity: 45%; Wind: 15MPH/24KPH SE ' '-- 123 Test St, Example City, CA - ' '\x1fhttps://darksky.net/forecast/30.123,123.456\x0f', ), {}, )] mock_requests.reset() mock_requests.add(mock_requests.GET, 'https://maps.googleapis.com/maps/api/geocode/json', json={'status': 'foobar'}) response = [] with pytest.raises(ApiError): wrap_hook_response(weather.weather, cmd_event, response) assert response == [('message', ('#foo', '(foobar) API Error occurred.'), {})] bot.config['api_keys']['google_dev_key'] = None bot.config.load_config() weather.create_maps_api(bot) assert wrap_hook_response(weather.weather, cmd_event) == [ ('return', 'This command requires a Google Developers Console API key.') ] assert wrap_hook_response(weather.forecast, cmd_event) == [ ('return', 'This command requires a Google Developers Console API key.') ] bot.config['api_keys']['darksky'] = None bot.config.load_config() weather.create_maps_api(bot) assert wrap_hook_response(weather.weather, cmd_event) == [ ('return', 'This command requires a DarkSky API key.') ] assert wrap_hook_response(weather.forecast, cmd_event) == [ ('return', 'This command requires a DarkSky API key.') ] # Test DB storage bot.config.update({ 'api_keys': { 'google_dev_key': 'AIzatestapikey', 'darksky': 'abc12345' * 4, } }) bot.config.load_config() weather.create_maps_api(bot) weather.table.create(mock_db.engine, checkfirst=True) cmd_event.db = mock_db.session() cmd_event.text = 'my location' weather.load_cache(mock_db.session()) mock_requests.reset() setup_api(mock_requests, mock_db) mock_requests.add(mock_requests.GET, re.compile(r'^https://api\.darksky\.net/forecast/.*'), **FIO_DATA) (loc, data), err = call_with_args(weather.check_and_parse, cmd_event) assert loc == { 'address': '123 Test St, Example City, CA', 'lat': 30.123, 'lng': 123.456 } assert data is not None assert err is None assert weather.location_cache == [(cmd_event.nick, cmd_event.text)] db_data = mock_db.session().execute(weather.table.select()).fetchall() assert len(db_data) == 1 assert list(db_data[0]) == [cmd_event.nick, cmd_event.text]