aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/bot/exts/utils/snekbox/test_snekbox.py38
-rw-r--r--tests/bot/exts/utils/test_utils.py94
2 files changed, 116 insertions, 16 deletions
diff --git a/tests/bot/exts/utils/snekbox/test_snekbox.py b/tests/bot/exts/utils/snekbox/test_snekbox.py
index 9cfd75df8..69262bf61 100644
--- a/tests/bot/exts/utils/snekbox/test_snekbox.py
+++ b/tests/bot/exts/utils/snekbox/test_snekbox.py
@@ -1,6 +1,7 @@
import asyncio
import unittest
from base64 import b64encode
+from typing import get_args
from unittest.mock import AsyncMock, MagicMock, Mock, call, create_autospec, patch
from discord import AllowedMentions
@@ -10,7 +11,7 @@ from pydis_core.utils.paste_service import MAX_PASTE_SIZE
from bot import constants
from bot.errors import LockedResourceError
from bot.exts.utils import snekbox
-from bot.exts.utils.snekbox import EvalJob, EvalResult, Snekbox
+from bot.exts.utils.snekbox import EvalJob, EvalResult, Snekbox, SupportedPythonVersions
from bot.exts.utils.snekbox._io import FileAttachment
from tests.helpers import MockBot, MockContext, MockMember, MockMessage, MockReaction, MockUser
@@ -21,6 +22,7 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
self.bot = MockBot()
self.cog = Snekbox(bot=self.bot)
self.job = EvalJob.from_code("import random")
+ self.default_version = get_args(SupportedPythonVersions)[0]
@staticmethod
def code_args(code: str) -> tuple[EvalJob]:
@@ -35,7 +37,7 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
context_manager = MagicMock()
context_manager.__aenter__.return_value = resp
self.bot.http_session.post.return_value = context_manager
- py_version = "3.12"
+ py_version = self.default_version
job = EvalJob.from_code("import random").as_version(py_version)
self.assertEqual(await self.cog.post_job(job), EvalResult("Hi", 137))
@@ -104,9 +106,13 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
def test_eval_result_message(self):
"""EvalResult.get_message(), should return message."""
cases = (
- ("ERROR", None, ("Your 3.12 eval job has failed", "ERROR", "")),
- ("", 128 + snekbox._eval.SIGKILL, ("Your 3.12 eval job timed out or ran out of memory", "", "")),
- ("", 255, ("Your 3.12 eval job has failed", "A fatal NsJail error occurred", ""))
+ ("ERROR", None, (f"Your {self.default_version} eval job has failed", "ERROR", "")),
+ (
+ "",
+ 128 + snekbox._eval.SIGKILL,
+ (f"Your {self.default_version} eval job timed out or ran out of memory", "", "")
+ ),
+ ("", 255, (f"Your {self.default_version} eval job has failed", "A fatal NsJail error occurred", ""))
)
for stdout, returncode, expected in cases:
exp_msg, exp_err, exp_files_err = expected
@@ -178,8 +184,8 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
mock_signals.return_value.name = "SIGTEST"
result = EvalResult(stdout="", returncode=127)
self.assertEqual(
- result.get_status_message(EvalJob([], version="3.12")),
- "Your 3.12 eval job has completed with return code 127 (SIGTEST)"
+ result.get_status_message(EvalJob([])),
+ f"Your {self.default_version} eval job has completed with return code 127 (SIGTEST)"
)
def test_eval_result_status_emoji(self):
@@ -253,7 +259,7 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
self.cog.send_job = AsyncMock(return_value=response)
self.cog.continue_job = AsyncMock(return_value=None)
- await self.cog.eval_command(self.cog, ctx=ctx, python_version="3.12", code=["MyAwesomeCode"])
+ await self.cog.eval_command(self.cog, ctx=ctx, python_version=self.default_version, code=["MyAwesomeCode"])
job = EvalJob.from_code("MyAwesomeCode")
self.cog.send_job.assert_called_once_with(ctx, job)
self.cog.continue_job.assert_called_once_with(ctx, response, "eval")
@@ -267,7 +273,7 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
self.cog.continue_job = AsyncMock()
self.cog.continue_job.side_effect = (EvalJob.from_code("MyAwesomeFormattedCode"), None)
- await self.cog.eval_command(self.cog, ctx=ctx, python_version="3.12", code=["MyAwesomeCode"])
+ await self.cog.eval_command(self.cog, ctx=ctx, python_version=self.default_version, code=["MyAwesomeCode"])
expected_job = EvalJob.from_code("MyAwesomeFormattedCode")
self.cog.send_job.assert_called_with(ctx, expected_job)
@@ -311,7 +317,7 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
ctx.send.assert_called_once()
self.assertEqual(
ctx.send.call_args.args[0],
- ":warning: Your 3.12 eval job has completed "
+ f":warning: Your {self.default_version} eval job has completed "
"with return code 0.\n\n```ansi\n[No output]\n```"
)
allowed_mentions = ctx.send.call_args.kwargs["allowed_mentions"]
@@ -335,13 +341,13 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
mocked_filter_cog.filter_snekbox_output = AsyncMock(return_value=(False, []))
self.bot.get_cog.return_value = mocked_filter_cog
- job = EvalJob.from_code("MyAwesomeCode").as_version("3.12")
+ job = EvalJob.from_code("MyAwesomeCode").as_version(self.default_version)
await self.cog.send_job(ctx, job),
ctx.send.assert_called_once()
self.assertEqual(
ctx.send.call_args.args[0],
- ":white_check_mark: Your 3.12 eval job "
+ f":white_check_mark: Your {self.default_version} eval job "
"has completed with return code 0."
"\n\n```ansi\nWay too long beard\n```\nFull output: lookatmybeard.com"
)
@@ -362,13 +368,13 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
mocked_filter_cog.filter_snekbox_output = AsyncMock(return_value=(False, []))
self.bot.get_cog.return_value = mocked_filter_cog
- job = EvalJob.from_code("MyAwesomeCode").as_version("3.12")
+ job = EvalJob.from_code("MyAwesomeCode").as_version(self.default_version)
await self.cog.send_job(ctx, job),
ctx.send.assert_called_once()
self.assertEqual(
ctx.send.call_args.args[0],
- ":x: Your 3.12 eval job has completed with return code 127."
+ f":x: Your {self.default_version} eval job has completed with return code 127."
"\n\n```ansi\nERROR\n```"
)
@@ -395,13 +401,13 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
mocked_filter_cog.filter_snekbox_output = AsyncMock(return_value=(False, disallowed_exts))
self.bot.get_cog.return_value = mocked_filter_cog
- job = EvalJob.from_code("MyAwesomeCode").as_version("3.12")
+ job = EvalJob.from_code("MyAwesomeCode").as_version(self.default_version)
await self.cog.send_job(ctx, job),
ctx.send.assert_called_once()
res = ctx.send.call_args.args[0]
self.assertTrue(
- res.startswith(":white_check_mark: Your 3.12 eval job has completed with return code 0.")
+ res.startswith(f":white_check_mark: Your {self.default_version} eval job has completed with return code 0.")
)
self.assertIn("Files with disallowed extensions can't be uploaded: **.disallowed, .disallowed2, ...**", res)
diff --git a/tests/bot/exts/utils/test_utils.py b/tests/bot/exts/utils/test_utils.py
new file mode 100644
index 000000000..9b8ea4ade
--- /dev/null
+++ b/tests/bot/exts/utils/test_utils.py
@@ -0,0 +1,94 @@
+import unittest
+
+from discord import Colour, Embed
+from discord.ext.commands import BadArgument
+
+from bot.exts.utils.utils import Utils, ZEN_OF_PYTHON
+from tests.helpers import MockBot, MockContext
+
+
+class ZenTests(unittest.IsolatedAsyncioTestCase):
+ """ Tests for the `!zen` command. """
+
+
+ def setUp(self):
+ self.bot = MockBot()
+ self.cog = Utils(self.bot)
+ self.ctx = MockContext()
+
+ self.zen_list = ZEN_OF_PYTHON.splitlines()
+ self.template_embed = Embed(colour=Colour.og_blurple(), title="The Zen of Python", description=ZEN_OF_PYTHON)
+
+
+
+ async def test_zen_without_arguments(self):
+ """ Tests if the `!zen` command reacts properly to no arguments. """
+ self.template_embed.title += ", by Tim Peters"
+
+
+ await self.cog.zen.callback(self.cog,self.ctx, search_value = None)
+ self.ctx.send.assert_called_once_with(embed=self.template_embed)
+
+ async def test_zen_with_valid_index(self):
+ """ Tests if the `!zen` command reacts properly to a valid index as an argument. """
+ expected_results = {
+ 0: ("The Zen of Python (line 0):", "Beautiful is better than ugly."),
+ 10: ("The Zen of Python (line 10):", "Unless explicitly silenced."),
+ 18: ("The Zen of Python (line 18):", "Namespaces are one honking great idea -- let's do more of those!"),
+ -1: ("The Zen of Python (line 18):", "Namespaces are one honking great idea -- let's do more of those!"),
+ -10: ("The Zen of Python (line 9):", "Errors should never pass silently."),
+ -19: ("The Zen of Python (line 0):", "Beautiful is better than ugly.")
+
+ }
+
+ for index, (title, description) in expected_results.items():
+ self.template_embed.title = title
+ self.template_embed.description = description
+ ctx = MockContext()
+ with self.subTest(index = index, expected_title=title, expected_description = description):
+ await self.cog.zen.callback(self.cog, ctx, search_value = str(index))
+ ctx.send.assert_called_once_with(embed = self.template_embed)
+
+
+
+ async def test_zen_with_invalid_index(self):
+ """ Tests if the `!zen` command reacts properly to an out-of-bounds index as an argument. """
+ # Negative index
+ with self.subTest(index = -20), self.assertRaises(BadArgument):
+ await self.cog.zen.callback(self.cog, self.ctx, search_value="-20")
+
+ # Positive index
+ with self.subTest(index = len(ZEN_OF_PYTHON)), self.assertRaises(BadArgument):
+ await self.cog.zen.callback(self.cog, self.ctx, search_value=str(len(ZEN_OF_PYTHON)))
+
+ async def test_zen_with_valid_slices(self):
+ """ Tests if the `!zen` command reacts properly to valid slices for indexing as an argument. """
+
+ expected_results = {
+ "0:19": ("The Zen of Python, by Tim Peters", "\n".join(self.zen_list)),
+ ":": ("The Zen of Python, by Tim Peters", "\n".join(self.zen_list)),
+ "::": ("The Zen of Python, by Tim Peters", "\n".join(self.zen_list)),
+ "1:": ("The Zen of Python (lines 1-18):", "\n".join(self.zen_list[1:])),
+ "-2:-1": ("The Zen of Python (line 17):", self.zen_list[17]),
+ "0:-1": ("The Zen of Python (lines 0-17):", "\n".join(self.zen_list[0:-1])),
+ "10:13": ("The Zen of Python (lines 10-12):", "\n".join(self.zen_list[10:13])),
+ "::-1": ("The Zen of Python (step size -1):", "\n".join(self.zen_list[::-1])),
+ "10:5:-1": ("The Zen of Python (lines 6-10, step size -1):", "\n".join(self.zen_list[10:5:-1])),
+ }
+
+ for input_slice, (title, description) in expected_results.items():
+ self.template_embed.title = title
+ self.template_embed.description = description
+
+ ctx = MockContext()
+ with self.subTest(input_slice=input_slice, expected_title=title, expected_description=description):
+ await self.cog.zen.callback(self.cog, ctx, search_value=input_slice)
+ ctx.send.assert_called_once_with(embed = self.template_embed)
+
+ async def test_zen_with_invalid_slices(self):
+ """ Tests if the `!zen` command reacts properly to invalid slices for indexing as an argument. """
+ slices= ["19:18", "10:9", "-1:-2", "0:-100", "::0", "1:2:-1", "-5:-4:-1"]
+
+ for input_slice in slices:
+ with self.subTest(input_slice = input_slice), self.assertRaises(BadArgument):
+ await self.cog.zen.callback(self.cog, self.ctx, search_value=input_slice)