Exemplo n.º 1
0
def test_parse_command():
    assert parse_command("+test") == Command("test")
    assert parse_command("+test 123") == Command("test", "123")
    assert parse_command("+test 1 2 3") == Command("test", "1", "2", "3")
    assert not parse_command("123")
    assert not parse_command("+ test")
    assert not parse_command("++test")
    assert not parse_command("123 +test")
Exemplo n.º 2
0
def test_prefix_custom():
    command = Command("test",
                      context=MockMessage(
                          channel=MockChannel(_id=6, guild=MockGuild(_id=7))))

    set_prefix(guild_id=7, prefix="&")
    assert command.prefix() == "&"

    set_prefix(guild_id=7, prefix=None)
    assert command.prefix() == DEFAULT_PREFIX
Exemplo n.º 3
0
def on_reaction_remove(reaction, user):
    if user == client.user:
        return
    if reaction.emoji == '🎁':
        Command.leaveInvisibleFriend(reaction.message.id, user)
    if reaction.emoji == '🔫':
        Command.shootRusseRoulette(reaction.message.id, user)

    # From here random reactions
    if reaction.message.author == client.user:
        return
    if random.randint(0, 50) == 0:
        yield from reaction.message.add_reaction(reaction.emoji)
Exemplo n.º 4
0
def parse_command(content: str, context: Message=None, client: Client=None) -> Command:
    """Returns the given content string as a command, if it's formatted as one, else None.
    Optionally with the given message as context."""
    match = regex.search(r"^" + regex.escape(get_prefix(context)) + r"([A-Za-z]+) ?(.+)?", content)
    if match:
        name = match.group(1)
        args = match.group(2)

        if args:
            args_respecting_quotes = [unescape(arg) for arg, _ in split_unescaped(args, (" ",))]
            return Command(name, *args_respecting_quotes, context=context, client=client)
        return Command(name, context=context, client=client)
    return None
Exemplo n.º 5
0
async def cmd_disable(command: Command, commands_str: str):
    if not command.guild_id():
        await command.respond_err("Cannot change permissions in DM channels.")
        return

    command_wrappers = get_command_wrappers(commands_str)
    for command_wrapper in command_wrappers:
        permissions.set_permission_filter(guild_id=command.guild_id(),
                                          command_wrapper=command_wrapper,
                                          permission_filter=None)

    await command.respond(response="✓ Command permissions changed.",
                          embed=permissions_embed(
                              guild_id=command.guild_id(),
                              command_wrappers=command_wrappers))
Exemplo n.º 6
0
def test_can_execute_admin():
    mock_message = MockMessage(channel=MockChannel(_id=44,
                                                   guild=MockGuild(_id=3)),
                               author=MockUser(_id=2, is_admin=True))
    command = Command(name="test2", context=mock_message)

    assert permissions.can_execute(command)
Exemplo n.º 7
0
async def receive_command(command: Command) -> bool:
    """Returns whether the received command was recognized and executed."""
    if command.name not in registered_aliases:
        return False
    
    name = registered_aliases[command.name]
    func_wrapper = registered_commands[name]
    
    # Let the user know the command was recognized, and that a response should follow.
    await command.trigger_typing()

    if not permissions.can_execute(command):
        await command.respond(
            response = f"✗ Lacking permission.",
            embed = permissions_embed(
                # Can only lack permission in a guild.
                guild_id         = command.guild_id(),
                command_wrappers = [func_wrapper]
            )
        )
        return False

    if len(func_wrapper.required_args) > len(command.args):
        missing_args = func_wrapper.required_args[len(command.args):]
        missing_arg_str = "`<" + "`>, <`".join(missing_args) + ">`"
        await command.respond_err(f"Missing required argument(s) {missing_arg_str}.")
        return False

    parsed_args = parse_args(command.args, arg_count=len(func_wrapper.required_args) + len(func_wrapper.optional_args))
    await func_wrapper.execute(command, *parsed_args)

    return True
Exemplo n.º 8
0
async def test_validate_filter_complex():
    command = Command(name="test", context=MockMessage(channel=MockChannel()))
    assert await validate_filter(
        command        = command,
        _filter        = "type:(nom or qual or reset or dq) and not user:(banchobot or peppy)",
        filter_context = filter_context
    )
Exemplo n.º 9
0
async def test_receive_command_without_optional_arg():
    mock_channel = MockChannel()
    mock_message = MockMessage("+greet someone", channel=mock_channel)

    assert await receive_command(
        Command("greet", "someone", context=mock_message))
    assert mock_channel.messages[0].content == "hi someone"
Exemplo n.º 10
0
async def cmd_help(command: Command, name: str = None):
    if name:
        # Clean up the argument so that `+help +ping` works, as the user would expect.
        name = name.replace("+", "")

        embed = help_embed(name, prefix=command.prefix())
        content = f"Type `{command.prefix()}help` for a list of commands."
    else:
        embed = general_help_embed(prefix=command.prefix())
        content = f"Type `{command.prefix()}help <command>` for usage."

    if not embed:
        await command.respond_err(f"No command `{name}` exists.")
        return

    await command.respond(content, embed=embed)
Exemplo n.º 11
0
async def test_receive_command_lacking_permission():
    mock_channel = MockChannel(guild=MockGuild(_id=3))
    mock_message = MockMessage("+test",
                               channel=mock_channel,
                               author=MockUser(is_admin=False))

    assert not await receive_command(Command("test", context=mock_message))
    assert mock_channel.typing_triggered
    assert "✗ lacking permission" in mock_channel.messages[0].content.lower()
Exemplo n.º 12
0
async def test_receive_command_missing_arg():
    mock_channel = MockChannel()
    mock_message = MockMessage("+greet", channel=mock_channel)

    assert not await receive_command(Command("greet", context=mock_message))
    assert mock_channel.messages[0].content.startswith("✗")
    assert "missing required argument" in mock_channel.messages[
        0].content.lower()
    assert "`<name>`" in mock_channel.messages[0].content.lower()
Exemplo n.º 13
0
async def cmd_prefix(command: Command, symbol: str):
    if not command.guild_id():
        await command.respond_err("Cannot change prefix in DM channels.")
        return
    
    if " " in symbol:
        await command.respond_err("`<symbol>` cannot include whitespace.")
        return
    
    # The discord message character limit is 2000.
    # Need enough characters to write `{prefix}prefix +` to reset it.
    len_limit = 2000 - len("prefix +")
    if len(symbol) > len_limit:
        await command.respond_err(f"`<symbol>` cannot exceed {len_limit} characters.")
        return

    old_prefix = command.prefix()
    set_prefix(command.guild_id(), symbol)
    await command.respond(f"✓ Command prefix changed from `{old_prefix}` to `{command.prefix()}`.")
Exemplo n.º 14
0
async def test_command_respond():
    mock_channel = MockChannel()
    mock_message = MockMessage("+test 1 2 3", channel=mock_channel)
    command = Command("test", "1", "2", "3", context=mock_message)

    assert await command.respond("success")
    assert command.response == "success"
    assert command.response_embed is None
    assert mock_channel.messages[0].content == "success"
    assert mock_channel.messages[0].embed is None
Exemplo n.º 15
0
def on_message(message):
    command = message.content.lower()
    if message.author == client.user:
        return
    elif command == '!':
        yield from client.send_message(
            message.channel,
            '<@{0}>, No command has been passed.'.format(message.author.id))
    elif command.startswith('!leet'):
        response = Command.leet_speak(command.replace('!leet', ''))
        yield from client.send_message(message.channel, '{0}'.format(response))
Exemplo n.º 16
0
def test_can_execute_user_perm_fail():
    command_wrapper = get_wrapper(name="test1")
    mock_message = MockMessage(channel=MockChannel(_id=44,
                                                   guild=MockGuild(_id=3)),
                               author=MockUser(_id=2, is_admin=False))
    command = Command(name="test2", context=mock_message)

    set_permission_filter(guild_id=3,
                          command_wrapper=command_wrapper,
                          permission_filter="user:<@88>")

    assert not permissions.can_execute(command)
Exemplo n.º 17
0
def test_parse_command_custom_prefix():
    context = MockMessage(channel=MockChannel(guild=MockGuild(_id=3)))
    set_prefix(guild_id=3, prefix="&")

    assert not parse_command("+test", context=context)
    assert parse_command("&test", context=context) == Command("test",
                                                              context=context)
    assert parse_command("&test 123",
                         context=context) == Command("test",
                                                     "123",
                                                     context=context)
    assert parse_command("&test 1 2 3",
                         context=context) == Command("test",
                                                     "1",
                                                     "2",
                                                     "3",
                                                     context=context)
    assert not parse_command("123", context=context)
    assert not parse_command("& test", context=context)
    assert not parse_command("&&test", context=context)
    assert not parse_command("123 &test", context=context)
Exemplo n.º 18
0
async def test_command_respond_forbidden():
    mock_error = Forbidden(MockResponse(status=403, reason="forbidden"),
                           "lacking permissions")
    mock_channel = MockErrorChannel(raise_on_send=mock_error)
    mock_message = MockMessage("+test 1 2 3", channel=mock_channel)
    command = Command("test", "1", "2", "3", context=mock_message)

    assert not await command.respond(
        "e.g. lacking send message permissions in the channel")
    assert command.response is None
    assert command.response_embed is None
    assert not mock_channel.messages
Exemplo n.º 19
0
async def test_command_respond_embed():
    mock_channel = MockChannel()
    mock_message = MockMessage("+test 1 2 3", channel=mock_channel)
    command = Command("test", "1", "2", "3", context=mock_message)

    embed = Embed()
    embed.add_field(name="test", value="success")

    assert await command.respond("", embed=embed)
    assert command.response == ""
    assert command.response_embed == embed
    assert mock_channel.messages[0].content == ""
    assert mock_channel.messages[0].embed == embed
Exemplo n.º 20
0
async def test_validate_filter_invalid_key():
    command = Command(name="test", context=MockMessage(channel=MockChannel()))
    assert not await validate_filter(command=command, _filter="undefined:undefined", filter_context=filter_context)
    assert "✗" in command.response
    assert "invalid key" in command.response.lower()

    embed = filters_embed(filter_context=filter_context)
    assert command.response_embed.title == embed.title
    assert command.response_embed.description == embed.description
    assert command.response_embed.fields[0].name == embed.fields[0].name
    assert command.response_embed.fields[0].value == embed.fields[0].value
    assert command.response_embed.fields[1].name == embed.fields[1].name
    assert command.response_embed.fields[1].value == embed.fields[1].value
Exemplo n.º 21
0
async def test_validate_filter_invalid_value():
    command = Command(name="test", context=MockMessage(channel=MockChannel()))
    assert not await validate_filter(command=command, _filter="type:undefined", filter_context=filter_context)
    assert "✗" in command.response
    assert "invalid value" in command.response.lower()

    embed = filter_embed(key="type", filter_context=filter_context)
    assert command.response_embed.fields[0].name == embed.fields[0].name
    assert command.response_embed.fields[0].value == embed.fields[0].value
    assert command.response_embed.fields[1].name == embed.fields[1].name
    assert command.response_embed.fields[1].value == embed.fields[1].value
    assert command.response_embed.fields[2].name == embed.fields[2].name
    assert command.response_embed.fields[2].value == embed.fields[2].value
Exemplo n.º 22
0
async def test_command_respond_httpexception():
    mock_error = HTTPException(MockResponse(status=404, reason="not found"),
                               "e.g. some channel doesn't exist")
    mock_channel = MockErrorChannel(raise_on_send=mock_error)
    mock_message = MockMessage("+test 1 2 3", channel=mock_channel)
    command = Command("test", "1", "2", "3", context=mock_message)

    with pytest.raises(HTTPException):
        await command.respond("e.g. API did not respond with 200: OK")

    assert command.response is None
    assert command.response_embed is None
    assert not mock_channel.messages
Exemplo n.º 23
0
def on_reaction_add(reaction, user):
    if user == client.user:
        return
    if reaction.emoji == '🎁':
        Command.joinInvisibleFriend(reaction.message.id, user)
    if reaction.emoji == '▶️':
        Command.startInvisibleFriend(reaction.message.id, user)
    if reaction.emoji == '⚙️':
        Command.sendSettingsInvisibleFriend(reaction.message.id, user)
    if reaction.emoji == '🔫':
        Command.shootRusseRoulette(reaction.message.id, user)

    if user.bot:
        kakeraType = re.findall('^<:(kakera.?):', str(reaction.emoji))
        if len(kakeraType) > 0:
            Command.kakeraBroadcast(reaction.message.channel, kakeraType[0])

    # From here random reactions
    if reaction.message.author == client.user:
        return
    if random.randint(0, 100) == 0:
        yield from reaction.message.add_reaction(reaction.emoji)
Exemplo n.º 24
0
async def test_validate_filter_invalid_word():
    command = Command(name="test", context=MockMessage(channel=MockChannel()))
    assert not await validate_filter(command=command, _filter="user:sometwo annd type:qualify", filter_context=filter_context)
    assert "✗" in command.response
    assert "invalid word" in command.response.lower()

    embed = filters_embed(filter_context=filter_context)
    assert command.response_embed.title == embed.title
    assert command.response_embed.description == embed.description
    assert command.response_embed.fields[0].name == embed.fields[0].name
    assert command.response_embed.fields[0].value == embed.fields[0].value
    assert command.response_embed.fields[1].name == embed.fields[1].name
    assert command.response_embed.fields[1].value == embed.fields[1].value
Exemplo n.º 25
0
def can_execute(command: Command) -> bool:
    """Returns whether the given command has permissions to execute within its current context
    (channel/author/roles of that guild). Administrators bypass any permission."""
    command_wrapper = commands.get_wrapper(command.name)
    perm_filter = get_permission_filter(command.guild_id(), command_wrapper)
    has_permission = filter_context.test(
        perm_filter, command.context) if perm_filter else False

    caller = command.context.author
    # The `guild_permissions` attribute is only available in guilds, for DM channels we skip this.
    is_admin_or_dm = not hasattr(
        caller, "guild_permissions") or caller.guild_permissions.administrator

    return has_permission or is_admin_or_dm
Exemplo n.º 26
0
def test_can_execute_role_perm():
    command_wrapper = get_wrapper(name="test1")
    mock_message = MockMessage(channel=MockChannel(_id=44,
                                                   guild=MockGuild(_id=3)),
                               author=MockUser(_id=2,
                                               roles=[MockRole(_id=66)],
                                               is_admin=False))
    command = Command(name="test2", context=mock_message)

    set_permission_filter(guild_id=3,
                          command_wrapper=command_wrapper,
                          permission_filter="role:<@&66>")

    assert permissions.can_execute(command)
Exemplo n.º 27
0
async def test_validate_filter_missing_gate():
    command = Command(name="test", context=MockMessage(channel=MockChannel()))
    assert not await validate_filter(command=command, _filter="user:sometwo type:qualify", filter_context=filter_context)
    assert "✗" in command.response
    assert "missing gate" in command.response.lower()
    assert "between `user:sometwo` and `type:qualify`" in command.response.lower()

    embed = filters_embed(filter_context=filter_context)
    assert command.response_embed.title == embed.title
    assert command.response_embed.description == embed.description
    assert command.response_embed.fields[0].name == embed.fields[0].name
    assert command.response_embed.fields[0].value == embed.fields[0].value
    assert command.response_embed.fields[1].name == embed.fields[1].name
    assert command.response_embed.fields[1].value == embed.fields[1].value
Exemplo n.º 28
0
async def cmd_enable(command: Command, commands_str: str, perms_filter: Optional[str]=None):
    if not command.guild_id():
        await command.respond_err("Cannot change permissions in DM channels.")
        return
    
    if perms_filter and not await validate_filter(command, perms_filter, filter_context):
        # `validate_filter` responds for us.
        return

    command_wrappers = get_command_wrappers(commands_str)
    for command_wrapper in command_wrappers:
        permissions.set_permission_filter(
            guild_id          = command.guild_id(),
            command_wrapper   = command_wrapper,
            permission_filter = perms_filter or f"role:<@&{command.context.guild.default_role.id}>"
        )
    
    await command.respond(
        response = "✓ Command permissions changed.",
        embed    = permissions_embed(
            guild_id         = command.guild_id(),
            command_wrappers = command_wrappers
        )
    )
Exemplo n.º 29
0
def test_command_help_embed():
    register(
        category="Some Category",
        names=["test"],
        required_args=["one", "two"],
        optional_args=["three"],
        description=
        "A command that uses `<one>`, `<two>`, and `[three]` to do stuff.",
        example_args=["one two", "1 2 3", "\"o n e\" two three"])(None)

    embed1 = Command("test").help_embed()
    embed2 = help_embed("test")

    assert embed1.fields[0].name == embed2.fields[0].name
    assert embed1.fields[0].value == embed2.fields[0].value
Exemplo n.º 30
0
def on_reaction_add(reaction, user):
    if user == client.user:
        return
    if reaction.emoji == '🎁':
        Command.joinInvisibleFriend(reaction.message.id, user)
    if reaction.emoji == '▶️':
        Command.startInvisibleFriend(reaction.message.id, user)
    if reaction.emoji == '⚙️':
        Command.sendSettingsInvisibleFriend(reaction.message.id, user)
    if reaction.emoji == '🔫':
        Command.shootRusseRoulette(reaction.message.id, user)

    # From here random reactions
    if reaction.message.author == client.user:
        return
    if random.randint(0, 100) == 0:
        yield from reaction.message.add_reaction(reaction.emoji)
Exemplo n.º 31
0
 def testSetCmd(self):
     user = User(_admin_sender)
     user.makeAdmin()
     Command.dispatch(self.admin_msg)
Exemplo n.º 32
0
 def testNoCmd(self):
     Command.dispatch(self.msg)
Exemplo n.º 33
0
 def testSetCmd(self):
     Command.dispatch(self.user_msg)
     user = User(_user_sender)
     val = user.getVariable(_var)
     self.assertEqual(val, None)
Exemplo n.º 34
0
 def testEchoCmd(self):
     Command.dispatch(self.user_msg)
Exemplo n.º 35
0
 def testSetCmd(self):
     user = User(_admin_sender)
     user.makeAdmin()
     Command.dispatch(self.admin_msg)
     self.assertEqual(user.getAdminVariable(_var), _val)
Exemplo n.º 36
0
 def testHeLLoCmd(self):
     Command.dispatch(self.user_msg)
Exemplo n.º 37
0
 def post(self):
     message = xmpp.Message(self.request.POST)
     Command.dispatch(message)
Exemplo n.º 38
0
 def testSetCmd(self):
     Command.dispatch(self.admin_msg)
     self.assertEqual(self.var.get(), None)
Exemplo n.º 39
0
 def testSetCmdAgain(self):
     Command.dispatch(self.admin_msg)
     self.assertEqual(User(_user_sender).getAdminVariable(_var), None)