Example #1
0
def test_say_no_repeat_protection(bot):
    # five is fine
    bot.say('hello', '#sopel')
    bot.say('hello', '#sopel')
    bot.say('hello', '#sopel')
    bot.say('hello', '#sopel')
    bot.say('hello', '#sopel')

    assert bot.backend.message_sent == rawlist(
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
    )

    # six: replaced by '...'
    bot.say('hello', '#sopel')

    assert bot.backend.message_sent == rawlist(
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        # the extra hello is replaced by '...'
        'PRIVMSG #sopel :...',
    )

    # these one will add more '...'
    bot.say('hello', '#sopel')
    bot.say('hello', '#sopel')

    assert bot.backend.message_sent == rawlist(
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :...',
        # the new ones are also replaced by '...'
        'PRIVMSG #sopel :...',
        'PRIVMSG #sopel :...',
    )

    # but at some point it just stops talking
    bot.say('hello', '#sopel')

    assert bot.backend.message_sent == rawlist(
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        'PRIVMSG #sopel :hello',
        #  three time, then stop
        'PRIVMSG #sopel :...',
        'PRIVMSG #sopel :...',
        'PRIVMSG #sopel :...',
    )
Example #2
0
def test_call_rule_rate_limited_user(mockbot):
    items = []

    # setup
    def testrule(bot, trigger):
        bot.say('hi')
        items.append(1)
        return "Return Value"

    rule_hello = rules.Rule(
        [re.compile(r'(hi|hello|hey|sup)')],
        plugin='testplugin',
        label='testrule',
        handler=testrule,
        rate_limit=100,
        threaded=False,
    )

    # trigger
    line = ':[email protected] PRIVMSG #channel :hello'
    pretrigger = trigger.PreTrigger(mockbot.nick, line)

    # match
    matches = list(rule_hello.match(mockbot, pretrigger))
    match = matches[0]

    # trigger and wrapper
    rule_trigger = trigger.Trigger(mockbot.settings,
                                   pretrigger,
                                   match,
                                   account=None)
    wrapper = bot.SopelWrapper(mockbot, rule_trigger)

    # call rule
    mockbot.call_rule(rule_hello, wrapper, rule_trigger)

    # assert the rule has been executed
    assert mockbot.backend.message_sent == rawlist('PRIVMSG #channel :hi')
    assert items == [1]

    # assert the rule is now rate limited
    assert rule_hello.is_rate_limited(Identifier('Test'))
    assert not rule_hello.is_channel_rate_limited('#channel')
    assert not rule_hello.is_global_rate_limited()

    # call rule again
    mockbot.call_rule(rule_hello, wrapper, rule_trigger)

    # assert no new message
    assert mockbot.backend.message_sent == rawlist(
        'PRIVMSG #channel :hi'), 'There must not be any new message sent'
    assert items == [1], 'There must not be any new item'
Example #3
0
def test_require_bot_privilege(configfactory, botfactory, triggerfactory,
                               ircfactory):
    settings = configfactory('default.cfg', TMP_CONFIG)
    mockbot = botfactory.preloaded(settings)
    mockserver = ircfactory(mockbot)

    bot = triggerfactory.wrapper(mockbot, BAN_MESSAGE)
    mockserver.channel_joined('#chan')
    mockserver.join('Foo', '#chan')
    mockserver.mode_set('#chan', '+vo', ['Foo', bot.nick])

    @plugin.command('ban')
    @plugin.require_bot_privilege(plugin.VOICE)
    def mock(bot, trigger):
        return True

    assert mock(bot, bot._trigger) is True, (
        'Bot must meet the requirement when having a higher privilege level.')

    @plugin.command('ban')
    @plugin.require_bot_privilege(plugin.OP)
    def mock(bot, trigger):
        return True

    assert mock(bot, bot._trigger) is True

    @plugin.command('ban')
    @plugin.require_bot_privilege(plugin.OWNER)
    def mock(bot, trigger):
        return True

    assert mock(bot, bot._trigger) is not True
    assert not bot.backend.message_sent

    @plugin.command('ban')
    @plugin.require_bot_privilege(plugin.OWNER, message='Nope')
    def mock(bot, trigger):
        return True

    assert mock(bot, bot._trigger) is not True
    assert bot.backend.message_sent == rawlist('PRIVMSG #chan :Nope')

    @plugin.command('ban')
    @plugin.require_bot_privilege(plugin.OWNER, message='Nope', reply=True)
    def mock(bot, trigger):
        return True

    assert mock(bot, bot._trigger) is not True
    assert bot.backend.message_sent[1:] == rawlist('PRIVMSG #chan :Foo: Nope')
def test_help_command_unknown(irc, userfactory):
    user = userfactory('Exirel')
    irc.pm(user, '.help doesnotexist')

    assert irc.bot.backend.message_sent == rawlist(
        "PRIVMSG Exirel :Unknown command \"doesnotexist\"",
    )
Example #5
0
def test_bot_mixed_mode_types(mockbot, ircfactory):
    """Ensure mixed argument-required and -not-required modes are handled.

    Sopel 6.6.6 and older did not behave well.

    .. seealso::

        GitHub issue #1575 (https://github.com/sopel-irc/sopel/pull/1575).
    """
    irc = ircfactory(mockbot)
    irc.channel_joined(
        '#test', ['Uvoice', 'Uop', 'Uadmin', 'Uvoice2', 'Uop2', 'Uadmin2'])
    irc.mode_set('#test', '+amov', ['Uadmin', 'Uop', 'Uvoice'])

    assert mockbot.channels["#test"].privileges[Identifier("Uadmin")] == ADMIN
    assert mockbot.channels["#test"].privileges[Identifier("Uop")] == OP
    assert mockbot.channels["#test"].privileges[Identifier("Uvoice")] == VOICE

    irc.mode_set('#test', '+abov', ['Uadmin2', 'x!y@z', 'Uop2', 'Uvoice2'])

    assert mockbot.channels["#test"].privileges[Identifier("Uadmin2")] == 0
    assert mockbot.channels["#test"].privileges[Identifier("Uop2")] == 0
    assert mockbot.channels["#test"].privileges[Identifier("Uvoice2")] == 0

    assert mockbot.backend.message_sent == rawlist('WHO #test'), (
        'Upon finding an unexpected nick, the bot must send a WHO request.')
Example #6
0
def test_help_command_too_long(mockbot, triggerfactory):
    provider = providers.Base()
    provider.setup(mockbot)

    wrapper = triggerfactory.wrapper(
        mockbot, ':[email protected] PRIVMSG #channel :.help test')

    mockbot.doc['test'] = ([
            'The command test docstring.',
            'Second line of docstring.',
            'Third line of docstring.',
            'Fourth line of docstring.',
        ], [
            '.test', '.test arg', '.test else',
        ]
    )

    provider.help_command(wrapper, wrapper._trigger, 'test')

    assert mockbot.backend.message_sent == rawlist(
        "PRIVMSG #channel :Test: The help for command test is too long; "
        "I'm sending it to you in a private message.",
        "PRIVMSG Test :The command test docstring.",
        "PRIVMSG Test :Second line of docstring.",
        "PRIVMSG Test :Third line of docstring.",
        "PRIVMSG Test :Fourth line of docstring.",
        "PRIVMSG Test :e.g. .test, .test arg or .test else",
    )
Example #7
0
def test_wrapper_action_override_destination(mockbot, triggerfactory):
    wrapper = triggerfactory.wrapper(
        mockbot, ':[email protected] PRIVMSG #channel :test message')
    wrapper.action('Hi!', destination='#different')

    assert mockbot.backend.message_sent == rawlist(
        'PRIVMSG #different :\x01ACTION Hi!\x01')
Example #8
0
def test_wrapper_reply_override_destination_reply_to(mockbot, triggerfactory):
    wrapper = triggerfactory.wrapper(
        mockbot, ':[email protected] PRIVMSG #channel :test message')
    wrapper.reply('Hi!', destination='#another', reply_to='Admin')

    assert mockbot.backend.message_sent == rawlist(
        'PRIVMSG #another :Admin: Hi!')
Example #9
0
def test_wrapper_reply(mockbot, triggerfactory):
    wrapper = triggerfactory.wrapper(
        mockbot, ':[email protected] PRIVMSG #channel :test message')
    wrapper.reply('Hi!')

    assert mockbot.backend.message_sent == rawlist(
        'PRIVMSG #channel :Test: Hi!')
Example #10
0
def test_ignore_replay_servertime(mockbot):
    """Test ignoring messages sent before bot joined a channel."""
    @plugin.rule("$nickname!")
    @plugin.thread(False)
    def ping(bot, trigger):
        bot.say(trigger.nick + "!")

    ping.plugin_name = "testplugin"
    mockbot.register_callables([ping])

    test_channel = Identifier("#test")
    mockbot.channels[test_channel] = target.Channel(test_channel)
    mockbot.channels[test_channel].join_time = datetime(2021,
                                                        6,
                                                        1,
                                                        12,
                                                        0,
                                                        0,
                                                        15000,
                                                        tzinfo=timezone.utc)

    # replay
    mockbot.on_message(
        "@time=2021-06-01T12:00:00.010Z :user!user@user PRIVMSG #test :TestBot!"
    )
    assert mockbot.backend.message_sent == []

    # new message
    mockbot.on_message(
        "@time=2021-06-01T12:00:00.020Z :user2!user2@user PRIVMSG #test :TestBot!"
    )
    assert mockbot.backend.message_sent == rawlist("PRIVMSG #test :user2!")
Example #11
0
def test_help_command_too_long_settings(mockbot, triggerfactory):
    """Test settings can override message length in lines for command help."""
    mockbot.settings.help.line_threshold = 5

    provider = providers.Base()
    provider.setup(mockbot)

    wrapper = triggerfactory.wrapper(
        mockbot, ':[email protected] PRIVMSG #channel :.help test')

    mockbot.doc['test'] = ([
            'The command test docstring.',
            'Second line of docstring.',
            'Third line of docstring.',
            'Fourth line of docstring.',
        ], [
            '.test', '.test arg', '.test else',
        ]
    )

    provider.help_command(wrapper, wrapper._trigger, 'test')

    assert mockbot.backend.message_sent == rawlist(
        "PRIVMSG #channel :Test: The command test docstring.",
        "PRIVMSG #channel :Second line of docstring.",
        "PRIVMSG #channel :Third line of docstring.",
        "PRIVMSG #channel :Fourth line of docstring.",
        "PRIVMSG #channel :e.g. .test, .test arg or .test else",
    )
Example #12
0
def test_wrapper_kick_override_destination_message(mockbot, triggerfactory):
    wrapper = triggerfactory.wrapper(
        mockbot, ':[email protected] PRIVMSG #channel :test message')
    wrapper.kick('SpamUser', channel='#another', message='Test reason')

    assert mockbot.backend.message_sent == rawlist(
        'KICK #another SpamUser :Test reason')
Example #13
0
def test_help(irc, userfactory):
    user = userfactory('Exirel')
    irc.pm(user, '.help')

    assert irc.bot.backend.message_sent[0] == rawlist(
        "PRIVMSG Exirel :Here is my list of commands:", )[0]
    assert len(irc.bot.backend.message_sent) > 1, 'More than one line expected'
Example #14
0
def test_say_long_truncation_extra(bot):
    """Test optional truncation indicator with message that is too long."""
    text = 'a' * (512 - prefix_length(bot) - len('PRIVMSG #sopel :\r\n') - 3)
    bot.say(text + 'ttt' + 'b', '#sopel', truncation='...')

    assert bot.backend.message_sent == rawlist(
        # 'b' is truncated; 'ttt' is replaced by `truncation`
        'PRIVMSG #sopel :%s' % text + '...', )
Example #15
0
def test_say_long_extra(bot):
    """Test a long message that doesn't fit into the 512 bytes limit."""
    text = 'a' * (512 - len('PRIVMSG #sopel :\r\n'))
    bot.say(text + 'b', '#sopel')

    assert bot.backend.message_sent == rawlist(
        'PRIVMSG #sopel :%s' % text,  # the 'b' is truncated out
    )
Example #16
0
def test_on_connect(bot):
    bot.on_connect()

    assert bot.backend.message_sent == rawlist(
        'CAP LS 302',
        'NICK Sopel',
        'USER sopel 0 * :Sopel (https://sopel.chat)'
    )
Example #17
0
def test_wrapper_kick(mockbot, triggerfactory):
    wrapper = triggerfactory.wrapper(
        mockbot, ':[email protected] PRIVMSG #channel :test message')
    wrapper.kick('SpamUser')

    assert mockbot.backend.message_sent == rawlist(
        'KICK #channel SpamUser'
    )
Example #18
0
def test_wrapper_notice(mockbot, triggerfactory):
    wrapper = triggerfactory.wrapper(
        mockbot, ':[email protected] PRIVMSG #channel :test message')
    wrapper.notice('Hi!')

    assert mockbot.backend.message_sent == rawlist(
        'NOTICE #channel :Hi!'
    )
Example #19
0
def test_on_connect_server_auth_password(bot):
    bot.settings.core.server_auth_method = 'server'
    bot.settings.core.server_auth_password = '******'
    bot.on_connect()

    assert bot.backend.message_sent == rawlist(
        'CAP LS 302', 'PASS server_secret', 'NICK Sopel',
        'USER sopel 0 * :Sopel (https://sopel.chat)')
Example #20
0
def test_say_trailing(bot):
    """Test optional trailing string."""
    text = '"This is a test quote.'
    bot.say(text, '#sopel', trailing='"')

    assert bot.backend.message_sent == rawlist(
        # combined
        'PRIVMSG #sopel :%s' % text + '"')
Example #21
0
def test_write_args_many(bot):
    bot.write(['NICK', 'Sopel'])
    bot.write(['JOIN', '#sopel'])

    assert bot.backend.message_sent == rawlist(
        'NICK Sopel',
        'JOIN #sopel',
    )
Example #22
0
def test_write_text_many(bot):
    bot.write(['NICK', 'Sopel'])
    bot.write(['HELP'], '?')

    assert bot.backend.message_sent == rawlist(
        'NICK Sopel',
        'HELP :?',
    )
Example #23
0
def test_wrapper_notice_override_destination(mockbot, triggerfactory):
    wrapper = triggerfactory.wrapper(
        mockbot, ':[email protected] PRIVMSG #channel :test message')
    wrapper.notice('Hi!', destination='#different')

    assert mockbot.backend.message_sent == rawlist(
        'NOTICE #different :Hi!'
    )
def test_help_command_channel(irc, userfactory):
    user = userfactory('Exirel')
    irc.say(user, '#sopel', '.help help')

    assert irc.bot.backend.message_sent == rawlist(
        "PRIVMSG #sopel :Exirel: Generate help for Sopel's commands.",
        "PRIVMSG #sopel :e.g. .help help or .help",
    )
Example #25
0
def test_say_long_fit(bot):
    """Test a long message that fits into the 512 bytes limit."""
    text = 'a' * (512 - len('PRIVMSG #sopel :\r\n'))
    bot.say(text, '#sopel')

    assert bot.backend.message_sent == rawlist(
        'PRIVMSG #sopel :%s' % text,
    )
Example #26
0
def test_say_long_extra_multi_message(bot):
    """Test a long message that doesn't fit, with split allowed."""
    text = 'a' * (512 - prefix_length(bot) - len('PRIVMSG #sopel :\r\n'))
    bot.say(text + 'b', '#sopel', max_messages=2)

    assert bot.backend.message_sent == rawlist(
        'PRIVMSG #sopel :%s' % text,  # the 'b' is split from message
        'PRIVMSG #sopel :b',
    )
Example #27
0
def test_say_long_truncation_fit(bot):
    """Test optional truncation indicator with message that fits in one line."""
    text = 'a' * (512 - prefix_length(bot) - len('PRIVMSG #sopel :\r\n') - 3)
    bot.say(text + 'ttt', '#sopel', truncation='...')

    assert bot.backend.message_sent == rawlist(
        'PRIVMSG #sopel :%s' % text +
        'ttt',  # nothing is truncated or replaced
    )
Example #28
0
def test_get_reply_method_default_private(mockbot, triggerfactory):
    provider = providers.Base()
    wrapped = triggerfactory.wrapper(mockbot, QUERY_LINE)

    reply, recipient = provider.get_reply_method(wrapped, wrapped._trigger)
    reply('Test message.', recipient)

    assert wrapped.backend.message_sent == rawlist(
        "PRIVMSG Test :Test message.",
    )
Example #29
0
def test_isupinsecure_command(irc, bot, user, requests_mock):
    """Test working URL."""
    requests_mock.head('https://example.com', )

    irc.pm(user, '.isupinsecure https://example.com')

    assert len(bot.backend.message_sent) == 1, (
        '.isupinsecure command should output exactly one line')
    assert bot.backend.message_sent == rawlist(
        'PRIVMSG User :[isup] https://example.com looks fine to me.')
Example #30
0
def test_say_long_extra_multi_message_multibyte_recipient(bot):
    """Test a split-allowed message sent to recipient with multi-byte char."""
    text = 'a' * (512 - prefix_length(bot) -
                  len('PRIVMSG #sopel² :\r\n'.encode('utf-8')))
    bot.say(text + 'b', '#sopel²', max_messages=2)

    assert bot.backend.message_sent == rawlist(
        'PRIVMSG #sopel² :%s' % text,  # the 'b' is split from message
        'PRIVMSG #sopel² :b',
    )