Пример #1
0
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
Пример #2
0
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)
Пример #3
0
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, {})
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
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
Пример #7
0
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())
Пример #8
0
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
Пример #9
0
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)
Пример #10
0
    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()
Пример #11
0
    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()
Пример #12
0
 def func(text, event):
     event.text = alias.name + " " + text
     return call_with_args(crypto_command, event)
Пример #13
0
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)
Пример #14
0
 def func(event):
     try:
         return func_utils.call_with_args(f, event)
     except exc_type as e:
         return handler(event, e)
Пример #15
0
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]