disagreement/tests/test_command_checks.py
Slipstream 81ea79a94d
Refactor: Move permission calculation to Channel model
The _compute_permissions helper function has been simplified by delegating the complex permission calculation logic to a new channel.permissions_for(member) method.

This refactoring encapsulates the permission logic within the Channel model, where it belongs. It removes duplicate and complex code from the command decorator, improving maintainability and separation of concerns.

The tests for requires_permissions have been updated to mock the new permissions_for method, resulting in cleaner tests that are no longer concerned with the internal implementation details of how permissions are calculated.
2025-06-10 16:05:33 -06:00

135 lines
3.0 KiB
Python

import asyncio
import pytest
from disagreement.ext.commands.core import Command, CommandContext
from disagreement.ext.commands.decorators import (
check,
cooldown,
requires_permissions,
)
from disagreement.ext.commands.errors import CheckFailure, CommandOnCooldown
from disagreement.permissions import Permissions
@pytest.mark.asyncio
async def test_check_decorator_blocks(message):
async def cb(ctx):
pass
cmd = Command(check(lambda c: False)(cb))
ctx = CommandContext(
message=message,
bot=message._client,
prefix="!",
command=cmd,
invoked_with="test",
)
with pytest.raises(CheckFailure):
await cmd.invoke(ctx)
@pytest.mark.asyncio
async def test_cooldown_per_user(message):
uses = []
@cooldown(1, 0.05)
async def cb(ctx):
uses.append(1)
cmd = Command(cb)
ctx = CommandContext(
message=message,
bot=message._client,
prefix="!",
command=cmd,
invoked_with="test",
)
await cmd.invoke(ctx)
with pytest.raises(CommandOnCooldown):
await cmd.invoke(ctx)
await asyncio.sleep(0.05)
await cmd.invoke(ctx)
assert len(uses) == 2
@pytest.mark.asyncio
@pytest.mark.asyncio
async def test_requires_permissions_pass(message):
class Guild:
id = "g"
owner_id = "owner"
roles = []
def get_member(self, mid):
return message.author
class Channel:
def __init__(self, perms):
self.perms = perms
self.guild_id = "g"
def permissions_for(self, member):
return self.perms
message.author.roles = []
message._client.get_channel = lambda cid: Channel(Permissions.SEND_MESSAGES)
message._client.get_guild = lambda gid: Guild()
@requires_permissions(Permissions.SEND_MESSAGES)
async def cb(ctx):
pass
cmd = Command(cb)
ctx = CommandContext(
message=message,
bot=message._client,
prefix="!",
command=cmd,
invoked_with="test",
)
await cmd.invoke(ctx)
@pytest.mark.asyncio
@pytest.mark.asyncio
async def test_requires_permissions_fail(message):
class Guild:
id = "g"
owner_id = "owner"
roles = []
def get_member(self, mid):
return message.author
class Channel:
def __init__(self, perms):
self.perms = perms
self.guild_id = "g"
def permissions_for(self, member):
return self.perms
message.author.roles = []
message._client.get_channel = lambda cid: Channel(Permissions.SEND_MESSAGES)
message._client.get_guild = lambda gid: Guild()
@requires_permissions(Permissions.MANAGE_MESSAGES)
async def cb(ctx):
pass
cmd = Command(cb)
ctx = CommandContext(
message=message,
bot=message._client,
prefix="!",
command=cmd,
invoked_with="test",
)
with pytest.raises(CheckFailure):
await cmd.invoke(ctx)