aboutsummaryrefslogtreecommitdiffstats
path: root/tests/pydis_core
diff options
context:
space:
mode:
Diffstat (limited to 'tests/pydis_core')
-rw-r--r--tests/pydis_core/test_api.py69
-rw-r--r--tests/pydis_core/utils/test_cooldown.py49
-rw-r--r--tests/pydis_core/utils/test_regex.py65
3 files changed, 183 insertions, 0 deletions
diff --git a/tests/pydis_core/test_api.py b/tests/pydis_core/test_api.py
new file mode 100644
index 00000000..92444e19
--- /dev/null
+++ b/tests/pydis_core/test_api.py
@@ -0,0 +1,69 @@
+import unittest
+from unittest.mock import MagicMock
+
+from pydis_core import site_api
+
+
+class APIClientTests(unittest.IsolatedAsyncioTestCase):
+ """Tests for pydis_core's site API client."""
+
+ @classmethod
+ def setUpClass(cls):
+ """Sets up the shared fixtures for the tests."""
+ cls.error_api_response = MagicMock()
+ cls.error_api_response.status = 999
+
+ def test_response_code_error_default_initialization(self):
+ """Test the default initialization of `ResponseCodeError` without `text` or `json`"""
+ error = site_api.ResponseCodeError(response=self.error_api_response)
+
+ self.assertIs(error.status, self.error_api_response.status)
+ self.assertEqual(error.response_json, {})
+ self.assertEqual(error.response_text, None)
+ self.assertIs(error.response, self.error_api_response)
+
+ def test_response_code_error_string_representation_default_initialization(self):
+ """Test the string representation of `ResponseCodeError` initialized without text or json."""
+ error = site_api.ResponseCodeError(response=self.error_api_response)
+ self.assertEqual(
+ str(error),
+ f"Status: {self.error_api_response.status} Response: {None}"
+ )
+
+ def test_response_code_error_initialization_with_json(self):
+ """Test the initialization of `ResponseCodeError` with json."""
+ json_data = {'hello': 'world'}
+ error = site_api.ResponseCodeError(
+ response=self.error_api_response,
+ response_json=json_data,
+ )
+ self.assertEqual(error.response_json, json_data)
+ self.assertEqual(error.response_text, None)
+
+ def test_response_code_error_string_representation_with_nonempty_response_json(self):
+ """Test the string representation of `ResponseCodeError` initialized with json."""
+ json_data = {'hello': 'world'}
+ error = site_api.ResponseCodeError(
+ response=self.error_api_response,
+ response_json=json_data
+ )
+ self.assertEqual(str(error), f"Status: {self.error_api_response.status} Response: {json_data}")
+
+ def test_response_code_error_initialization_with_text(self):
+ """Test the initialization of `ResponseCodeError` with text."""
+ text_data = 'Lemon will eat your soul'
+ error = site_api.ResponseCodeError(
+ response=self.error_api_response,
+ response_text=text_data,
+ )
+ self.assertEqual(error.response_text, text_data)
+ self.assertEqual(error.response_json, {})
+
+ def test_response_code_error_string_representation_with_nonempty_response_text(self):
+ """Test the string representation of `ResponseCodeError` initialized with text."""
+ text_data = 'Lemon will eat your soul'
+ error = site_api.ResponseCodeError(
+ response=self.error_api_response,
+ response_text=text_data
+ )
+ self.assertEqual(str(error), f"Status: {self.error_api_response.status} Response: {text_data}")
diff --git a/tests/pydis_core/utils/test_cooldown.py b/tests/pydis_core/utils/test_cooldown.py
new file mode 100644
index 00000000..eed16da3
--- /dev/null
+++ b/tests/pydis_core/utils/test_cooldown.py
@@ -0,0 +1,49 @@
+import unittest
+from unittest.mock import patch
+
+from pydis_core.utils.cooldown import _CommandCooldownManager, _create_argument_tuple
+
+
+class CommandCooldownManagerTests(unittest.IsolatedAsyncioTestCase):
+ test_call_args = (
+ _create_argument_tuple(0),
+ _create_argument_tuple(a=0),
+ _create_argument_tuple([]),
+ _create_argument_tuple(a=[]),
+ _create_argument_tuple(1, 2, 3, a=4, b=5, c=6),
+ _create_argument_tuple([1], [2], [3], a=[4], b=[5], c=[6]),
+ _create_argument_tuple([1], 2, [3], a=4, b=[5], c=6),
+ )
+
+ async def asyncSetUp(self):
+ self.cooldown_manager = _CommandCooldownManager(cooldown_duration=5)
+
+ def test_no_cooldown_on_unset(self):
+ for call_args in self.test_call_args:
+ with self.subTest(arguments_tuple=call_args, channel=0):
+ self.assertFalse(self.cooldown_manager.is_on_cooldown(0, call_args))
+
+ for call_args in self.test_call_args:
+ with self.subTest(arguments_tuple=call_args, channel=1):
+ self.assertFalse(self.cooldown_manager.is_on_cooldown(1, call_args))
+
+ @patch("time.monotonic")
+ def test_cooldown_is_set(self, monotonic):
+ monotonic.side_effect = lambda: 0
+ for call_args in self.test_call_args:
+ with self.subTest(arguments_tuple=call_args):
+ self.cooldown_manager.set_cooldown(0, call_args)
+ self.assertTrue(self.cooldown_manager.is_on_cooldown(0, call_args))
+
+ @patch("time.monotonic")
+ def test_cooldown_expires(self, monotonic):
+ for call_args in self.test_call_args:
+ monotonic.side_effect = (0, 1000)
+ with self.subTest(arguments_tuple=call_args):
+ self.cooldown_manager.set_cooldown(0, call_args)
+ self.assertFalse(self.cooldown_manager.is_on_cooldown(0, call_args))
+
+ def test_keywords_and_tuples_differentiated(self):
+ self.cooldown_manager.set_cooldown(0, _create_argument_tuple(("a", 0)))
+ self.assertFalse(self.cooldown_manager.is_on_cooldown(0, _create_argument_tuple(a=0)))
+ self.assertTrue(self.cooldown_manager.is_on_cooldown(0, _create_argument_tuple(("a", 0))))
diff --git a/tests/pydis_core/utils/test_regex.py b/tests/pydis_core/utils/test_regex.py
new file mode 100644
index 00000000..01a2412b
--- /dev/null
+++ b/tests/pydis_core/utils/test_regex.py
@@ -0,0 +1,65 @@
+import unittest
+from typing import Optional
+
+from pydis_core.utils.regex import DISCORD_INVITE
+
+
+def match_regex(s: str) -> Optional[str]:
+ """Helper function to run re.match on a string.
+
+ Return the invite capture group, if the string matches the pattern
+ else return None
+ """
+ result = DISCORD_INVITE.match(s)
+ return result if result is None else result.group("invite")
+
+
+def search_regex(s: str) -> Optional[str]:
+ """Helper function to run re.search on a string.
+
+ Return the invite capture group, if the string matches the pattern
+ else return None
+ """
+ result = DISCORD_INVITE.search(s)
+ return result if result is None else result.group("invite")
+
+
+class UtilsRegexTests(unittest.TestCase):
+
+ def test_discord_invite_positives(self):
+ """Test the DISCORD_INVITE regex on a set of strings we would expect to capture."""
+
+ self.assertEqual(match_regex("discord.gg/python"), "python")
+ self.assertEqual(match_regex("https://discord.gg/python"), "python")
+ self.assertEqual(match_regex("https://www.discord.gg/python"), "python")
+ self.assertEqual(match_regex("discord.com/invite/python"), "python")
+ self.assertEqual(match_regex("www.discord.com/invite/python"), "python")
+ self.assertEqual(match_regex("discordapp.com/invite/python"), "python")
+ self.assertEqual(match_regex("discord.me/python"), "python")
+ self.assertEqual(match_regex("discord.li/python"), "python")
+ self.assertEqual(match_regex("discord.io/python"), "python")
+ self.assertEqual(match_regex(".gg/python"), "python")
+
+ self.assertEqual(match_regex("discord.gg/python/but/extra"), "python/but/extra")
+ self.assertEqual(match_regex("discord.me/this/isnt/python"), "this/isnt/python")
+ self.assertEqual(match_regex(".gg/a/a/a/a/a/a/a/a/a/a/a"), "a/a/a/a/a/a/a/a/a/a/a")
+ self.assertEqual(match_regex("discordapp.com/invite/python/snakescord"), "python/snakescord")
+ self.assertEqual(match_regex("http://discord.gg/python/%20/notpython"), "python/%20/notpython")
+ self.assertEqual(match_regex("discord.gg/python?=ts/notpython"), "python?=ts/notpython")
+ self.assertEqual(match_regex("https://discord.gg/python#fragment/notpython"), "python#fragment/notpython")
+ self.assertEqual(match_regex("https://discord.gg/python/~/notpython"), "python/~/notpython")
+
+ self.assertEqual(search_regex("https://discord.gg/python with whitespace"), "python")
+ self.assertEqual(search_regex(" https://discord.gg/python "), "python")
+
+ def test_discord_invite_negatives(self):
+ """Test the DISCORD_INVITE regex on a set of strings we would expect to not capture."""
+
+ self.assertEqual(match_regex("another string"), None)
+ self.assertEqual(match_regex("https://pythondiscord.com"), None)
+ self.assertEqual(match_regex("https://discord.com"), None)
+ self.assertEqual(match_regex("https://discord.gg"), None)
+ self.assertEqual(match_regex("https://discord.gg/ python"), None)
+
+ self.assertEqual(search_regex("https://discord.com with whitespace"), None)
+ self.assertEqual(search_regex(" https://discord.com "), None)