diff --git a/intbot/core/bot/main.py b/intbot/core/bot/main.py index 4cbc55c..4dd0c6f 100644 --- a/intbot/core/bot/main.py +++ b/intbot/core/bot/main.py @@ -38,6 +38,46 @@ async def wiki(ctx): suppress_embeds=True, ) +@bot.command() +async def close(ctx): + channel = ctx.channel + parent = channel.parent + author = ctx.message.author + + # Check if it's a public or private post (thread) + if channel.type in (discord.ChannelType.public_thread, discord.ChannelType.private_thread): + + # Check if the post (thread) was sent in a forum, + # so we can add a tag + if parent.type == discord.ChannelType.forum: + + # Get tag from forum + tag = None + for _tag in parent.available_tags: + if _tag.name.lower() == "done": + tag = _tag + break + + if tag is not None: + await channel.add_tags(tag) + + # Remove command message + await ctx.message.delete() + + # Send notification to the thread + await channel.send(f"# This was marked as done by {author.mention}", suppress_embeds=True) + + # We need to archive after adding tags in case it was a forum. + await channel.edit(archived=True) + else: + # Remove command message + await ctx.message.delete() + + await channel.send("The !close command is intended to be used inside a thread/post", + suppress_embeds=True, + delete_after=5) + + @bot.command() async def version(ctx): diff --git a/intbot/tests/test_bot/test_main.py b/intbot/tests/test_bot/test_main.py index 108edeb..393bc37 100644 --- a/intbot/tests/test_bot/test_main.py +++ b/intbot/tests/test_bot/test_main.py @@ -1,12 +1,13 @@ from unittest import mock from unittest.mock import AsyncMock, patch import contextlib +import discord from django.db import connections import pytest from asgiref.sync import sync_to_async -from core.bot.main import ping, poll_database, qlen, source, version, wiki +from core.bot.main import ping, poll_database, qlen, source, version, wiki, close from core.models import DiscordMessage from django.utils import timezone @@ -100,6 +101,40 @@ async def test_wiki_command(): suppress_embeds=True, ) +@pytest.mark.asyncio +async def test_close_command_working(): + # Mock context + ctx = AsyncMock() + ctx.channel = AsyncMock() + ctx.message.author = AsyncMock() + ctx.channel.type = discord.ChannelType.public_thread + + # Call the command + await close(ctx) + + # Assert that the command sent the expected message + ctx.channel.send.assert_called_once_with( + f"# This was marked as done by {ctx.message.author.mention}", + suppress_embeds=True, + ) + +@pytest.mark.asyncio +async def test_close_command_notworking(): + # Mock context + ctx = AsyncMock() + ctx.channel = AsyncMock() + ctx.message.author = AsyncMock() + + # Call the command + await close(ctx) + + # Assert that the command sent the expected message + ctx.channel.send.assert_called_once_with( + "The !close command is intended to be used inside a thread/post", + suppress_embeds=True, + delete_after=5 + ) + @pytest.mark.asyncio async def test_version_command():