Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2b55169
feat: add context menu for accepting solutions in forum threads
mystique09 Feb 22, 2025
ab09bcd
feat: add migration for enabling solution acceptance in forum threads
mystique09 Feb 22, 2025
ab34231
feat: update migration to add enable_accept_solutions column and enha…
mystique09 Mar 1, 2025
c1f2752
feat: implement acceptance solution functionality in forum posts
mystique09 Mar 1, 2025
7edc4a1
feat: add MarkAsSolution view and integrate acceptance feature in pos…
mystique09 Mar 1, 2025
22942b7
feat: enhance accept solution functionality in forum threads with con…
mystique09 Mar 1, 2025
d813c11
feat: add update_user_mark_as_solution method to mark posts as soluti…
mystique09 Mar 2, 2025
3c6ef90
feat: add confirmation message for solution acceptance in MarkAsSolut…
mystique09 Mar 2, 2025
42c3b88
feat: enhance solution marking functionality with thread author check…
mystique09 Mar 2, 2025
5df2d8b
refactor: mark as solution now uses the pinned messages to check if t…
mystique09 May 29, 2025
df72e5e
chore: updated deps
mystique09 Jul 23, 2025
8221b15
add: ignore test files
mystique09 Jul 23, 2025
794970e
feature: combine /dev-help and /forum-assist
mystique09 Jul 23, 2025
065ce0a
add: sample test for prefix and slash command
mystique09 Jul 23, 2025
94c0ff2
fix: remove set_config, non-existent method
mystique09 Jul 23, 2025
025a2c0
chore: remove configure command
mystique09 Jul 24, 2025
ea8563c
chore: update message
mystique09 Jul 24, 2025
c88943d
fix: config file
mystique09 Jul 29, 2025
19b570f
feat: add enable_mark_as_solved functionality and database support
mystique09 Aug 23, 2025
82318ff
fix: mark as solved and accept solution
mystique09 Aug 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions migrations/21_add_enable_accept_solutions.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- depends: 18_post_assist
ALTER TABLE pph_post_assist_config
ADD COLUMN IF NOT EXISTS enable_accept_solutions BOOLEAN DEFAULT FALSE;

CREATE TABLE
IF NOT EXISTS pph_post_assist_config_accept_solutions (
id SERIAL PRIMARY KEY,
thread_id BIGINT NOT NULL,
post_assist_config_id SERIAL NOT NULL,
user_id BIGINT NOT NULL,
message_id BIGINT NOT NULL,
FOREIGN KEY (post_assist_config_id) REFERENCES pph_post_assist_config (id) ON DELETE CASCADE
);

ALTER TABLE pph_post_assist_config_accept_solutions
ADD COLUMN IF NOT EXISTS message_id BIGINT NOT NULL;
2 changes: 2 additions & 0 deletions migrations/22_drop_accept_solutions_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- depends: 21_add_enable_accept_solutions
DROP TABLE IF EXISTS pph_post_assist_config_accept_solutions;
3 changes: 3 additions & 0 deletions migrations/add_enable_mark_as_solved.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- depends: 18_post_assist
ALTER TABLE pph_post_assist_config
ADD COLUMN IF NOT EXISTS enable_mark_as_solved BOOLEAN DEFAULT FALSE;
953 changes: 584 additions & 369 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ packages = [

[tool.poetry.dependencies]
python = "^3.10.14"
discord-py = "^2.4.0"
python-dotenv = "^1.0.1"
pyyaml = "^6.0"
flake8 = "^7.1.0"
Expand All @@ -29,6 +28,7 @@ python-levenshtein = "^0.25.1"
setuptools = "^70.1.0"
pydantic = "^2.8.0"
python-dateutil = "^2.9.0"
discord-py = "^2.5.2"

[tool.poetry.scripts]
progphil = "main:run"
Expand Down
4 changes: 4 additions & 0 deletions pyrightconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"venvPath": ".",
"venv": "C:/Users/benji/AppData/Local/pypoetry/Cache/virtualenvs/progphilbot-QxuRZnFx-py3.12"
}
2 changes: 1 addition & 1 deletion src/bot/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ async def load_cogs(self, module: str, cogs: list[str]) -> None:
:param cogs: list of cogs to load, basically the files under the cogs/<category> that ends with .py
"""
for cog in cogs:
if cog.startswith("__init__"):
if cog.startswith("__init__") or cog.startswith("test_"):
continue
if cog.endswith(".py"):
await self.load_extension(f"src.cogs.{module}.{cog[:-3]}")
Expand Down
53 changes: 53 additions & 0 deletions src/cogs/admin/test_announcements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import unittest
from unittest.async_case import IsolatedAsyncioTestCase
from unittest.mock import AsyncMock, MagicMock, patch

from discord import Interaction
from discord.app_commands import Choice

from src.cogs.admin.announcements import Announcements
from src.ui.modals.announcement import Announcement


class TestAnnouncements(IsolatedAsyncioTestCase):
@patch("src.cogs.admin.announcements.Announcement.wait", new_callable=AsyncMock)
async def test_announce_command(self, mock_wait):
mock_bot = MagicMock()
mock_interaction = AsyncMock(specs=Interaction)
mock_interaction.response = AsyncMock()
mock_interaction.response.send_modal = AsyncMock()
mock_interaction.user = MagicMock()
mock_interaction.user.name = "test_user"

mock_channel = MagicMock()
mock_channel.name = "test_channel"
mock_channel.send = MagicMock()

mock_photo = MagicMock()
mock_photo.filename = "image.jpg"
# mock_photo.filename.value = "image.jpg"

cog = Announcements(mock_bot)
mock_logger = MagicMock()
mock_logger.info = MagicMock()
cog.logger = mock_logger

mock_mention = MagicMock()
mock_mention.mention = "<@1234567890>"
mock_mention.value = "1234567890"

mock_submission_type = MagicMock()
mock_submission_type.value = "regular"

await cog.announce.callback(cog,interaction=mock_interaction, submission_type=mock_submission_type, channel=mock_channel, photo=mock_photo, mention=mock_mention)

mock_interaction.response.send_modal.assert_awaited_once()

cog.logger.info.assert_called_once_with(f"A announcement was made by {mock_interaction.user} in {mock_channel.name}")
sent_modal = mock_interaction.response.send_modal.call_args[0][0]

self.assertIsInstance(sent_modal, Announcement)
mock_wait.assert_awaited_once()

if __name__ == "__main__":
unittest.main()
Loading