aboutsummaryrefslogtreecommitdiffstats
path: root/api/tests
diff options
context:
space:
mode:
authorGravatar Gareth Coles <[email protected]>2019-04-05 12:11:31 +0100
committerGravatar Gareth Coles <[email protected]>2019-04-05 12:11:31 +0100
commitebda74029355ce3236ca9266acde40fd40329df7 (patch)
treeaba491f902c874328c88b8e7ccb9772b5414c17f /api/tests
parentSet `harakiri = 30`. (diff)
[#176] Redo project layout
Diffstat (limited to 'api/tests')
-rw-r--r--api/tests/__init__.py0
-rw-r--r--api/tests/base.py69
-rw-r--r--api/tests/test_deleted_messages.py43
-rw-r--r--api/tests/test_documentation_links.py161
-rw-r--r--api/tests/test_healthcheck.py16
-rw-r--r--api/tests/test_infractions.py359
-rw-r--r--api/tests/test_models.py113
-rw-r--r--api/tests/test_nominations.py41
-rw-r--r--api/tests/test_off_topic_channel_names.py152
-rw-r--r--api/tests/test_rules.py35
-rw-r--r--api/tests/test_snake_names.py67
-rw-r--r--api/tests/test_users.py121
-rw-r--r--api/tests/test_validators.py213
13 files changed, 0 insertions, 1390 deletions
diff --git a/api/tests/__init__.py b/api/tests/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/api/tests/__init__.py
+++ /dev/null
diff --git a/api/tests/base.py b/api/tests/base.py
deleted file mode 100644
index 5d8ccf8c..00000000
--- a/api/tests/base.py
+++ /dev/null
@@ -1,69 +0,0 @@
-from django.contrib.auth.models import User
-from rest_framework.test import APITestCase
-
-
-test_user, _created = User.objects.get_or_create(
- username='test',
- password='testpass', # noqa: S106
- is_superuser=True,
- is_staff=True
-)
-
-
-class APISubdomainTestCase(APITestCase):
- """
- Configures the test client to use the proper subdomain
- for requests and forces authentication for the test user.
-
- The test user is considered staff and superuser.
- If you want to test for a custom user (for example, to test model permissions),
- create the user, assign the relevant permissions, and use
- `self.client.force_authenticate(user=created_user)` to force authentication
- through the created user.
-
- Using this performs the following niceties for you which ease writing tests:
- - setting the `HTTP_HOST` request header to `api.pythondiscord.local:8000`, and
- - forcing authentication for the test user.
- If you don't want to force authentication (for example, to test a route's response
- for an unauthenticated user), un-force authentication by using the following:
-
- >>> from api.test.base import APISubdomainTestCase
- >>> class UnauthedUserTestCase(APISubdomainTestCase):
- ... def setUp(self):
- ... super().setUp()
- ... self.client.force_authentication(user=None)
- ... def test_can_read_objects_at_my_endpoint(self):
- ... resp = self.client.get('/my-publicly-readable-endpoint')
- ... self.assertEqual(resp.status_code, 200)
- ... def test_cannot_delete_objects_at_my_endpoint(self):
- ... resp = self.client.delete('/my-publicly-readable-endpoint/42')
- ... self.assertEqual(resp.status_code, 401)
-
- Make sure to include the `super().setUp(self)` call, otherwise, you may get
- status code 404 for some URLs due to the missing `HTTP_HOST` header.
-
- ## Example
- Using this in a test case is rather straightforward:
-
- >>> from api.tests.base import APISubdomainTestCase
- >>> class MyAPITestCase(APISubdomainTestCase):
- ... def test_that_it_works(self):
- ... response = self.client.get('/my-endpoint')
- ... self.assertEqual(response.status_code, 200)
-
- To reverse URLs of the API host, you need to use `django_hosts`:
-
- >>> from django_hosts.resolvers import reverse
- >>> from api.test.base import APISubdomainTestCase
- >>> class MyReversedTestCase(APISubdomainTestCase):
- ... def test_my_endpoint(self):
- ... url = reverse('user-detail', host='api')
- ... response = self.client.get(url)
- ... self.assertEqual(response.status_code, 200)
- """
-
- def setUp(self):
- super().setUp()
- self.client.defaults['HTTP_HOST'] = 'api.pythondiscord.local:8000'
- self.client.force_authenticate(test_user)
diff --git a/api/tests/test_deleted_messages.py b/api/tests/test_deleted_messages.py
deleted file mode 100644
index cd5acab0..00000000
--- a/api/tests/test_deleted_messages.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from datetime import datetime
-
-from django_hosts.resolvers import reverse
-
-from .base import APISubdomainTestCase
-from ..models import User
-
-
-class DeletedMessagesTests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.author = User.objects.create(
- id=55,
- name='Robbie Rotten',
- discriminator=55,
- avatar_hash=None
- )
-
- cls.data = {
- 'actor': None,
- 'creation': datetime.utcnow().isoformat(),
- 'deletedmessage_set': [
- {
- 'author': cls.author.id,
- 'id': 55,
- 'channel_id': 5555,
- 'content': "Terror Billy is a meanie",
- 'embeds': []
- },
- {
- 'author': cls.author.id,
- 'id': 56,
- 'channel_id': 5555,
- 'content': "If you purge this, you're evil",
- 'embeds': []
- }
- ]
- }
-
- def test_accepts_valid_data(self):
- url = reverse('bot:messagedeletioncontext-list', host='api')
- response = self.client.post(url, data=self.data)
- self.assertEqual(response.status_code, 201)
diff --git a/api/tests/test_documentation_links.py b/api/tests/test_documentation_links.py
deleted file mode 100644
index f6c78391..00000000
--- a/api/tests/test_documentation_links.py
+++ /dev/null
@@ -1,161 +0,0 @@
-from django_hosts.resolvers import reverse
-
-from .base import APISubdomainTestCase
-from ..models import DocumentationLink
-
-
-class UnauthedDocumentationLinkAPITests(APISubdomainTestCase):
- def setUp(self):
- super().setUp()
- self.client.force_authenticate(user=None)
-
- def test_detail_lookup_returns_401(self):
- url = reverse('bot:documentationlink-detail', args=('whatever',), host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 401)
-
- def test_list_returns_401(self):
- url = reverse('bot:documentationlink-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 401)
-
- def test_create_returns_401(self):
- url = reverse('bot:documentationlink-list', host='api')
- response = self.client.post(url, data={'hi': 'there'})
-
- self.assertEqual(response.status_code, 401)
-
- def test_delete_returns_401(self):
- url = reverse('bot:documentationlink-detail', args=('whatever',), host='api')
- response = self.client.delete(url)
-
- self.assertEqual(response.status_code, 401)
-
-
-class EmptyDatabaseDocumentationLinkAPITests(APISubdomainTestCase):
- def test_detail_lookup_returns_404(self):
- url = reverse('bot:documentationlink-detail', args=('whatever',), host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 404)
-
- def test_list_all_returns_empty_list(self):
- url = reverse('bot:documentationlink-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), [])
-
- def test_delete_returns_404(self):
- url = reverse('bot:documentationlink-detail', args=('whatever',), host='api')
- response = self.client.delete(url)
-
- self.assertEqual(response.status_code, 404)
-
-
-class DetailLookupDocumentationLinkAPITests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.doc_link = DocumentationLink.objects.create(
- package='testpackage',
- base_url='https://example.com',
- inventory_url='https://example.com'
- )
-
- cls.doc_json = {
- 'package': cls.doc_link.package,
- 'base_url': cls.doc_link.base_url,
- 'inventory_url': cls.doc_link.inventory_url
- }
-
- def test_detail_lookup_unknown_package_returns_404(self):
- url = reverse('bot:documentationlink-detail', args=('whatever',), host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 404)
-
- def test_detail_lookup_created_package_returns_package(self):
- url = reverse('bot:documentationlink-detail', args=(self.doc_link.package,), host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), self.doc_json)
-
- def test_list_all_packages_shows_created_package(self):
- url = reverse('bot:documentationlink-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), [self.doc_json])
-
- def test_create_invalid_body_returns_400(self):
- url = reverse('bot:documentationlink-list', host='api')
- response = self.client.post(url, data={'i': 'am', 'totally': 'valid'})
-
- self.assertEqual(response.status_code, 400)
-
- def test_create_invalid_url_returns_400(self):
- body = {
- 'package': 'example',
- 'base_url': 'https://example.com',
- 'inventory_url': 'totally an url'
- }
-
- url = reverse('bot:documentationlink-list', host='api')
- response = self.client.post(url, data=body)
-
- self.assertEqual(response.status_code, 400)
-
-
-class DocumentationLinkCreationTests(APISubdomainTestCase):
- def setUp(self):
- super().setUp()
-
- self.body = {
- 'package': 'example',
- 'base_url': 'https://example.com',
- 'inventory_url': 'https://docs.example.com'
- }
-
- url = reverse('bot:documentationlink-list', host='api')
- response = self.client.post(url, data=self.body)
-
- self.assertEqual(response.status_code, 201)
-
- def test_package_in_full_list(self):
- url = reverse('bot:documentationlink-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), [self.body])
-
- def test_detail_lookup_works_with_package(self):
- url = reverse('bot:documentationlink-detail', args=(self.body['package'],), host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), self.body)
-
-
-class DocumentationLinkDeletionTests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.doc_link = DocumentationLink.objects.create(
- package='example',
- base_url='https://example.com',
- inventory_url='https://docs.example.com'
- )
-
- def test_unknown_package_returns_404(self):
- url = reverse('bot:documentationlink-detail', args=('whatever',), host='api')
- response = self.client.delete(url)
-
- self.assertEqual(response.status_code, 404)
-
- def test_delete_known_package_returns_204(self):
- url = reverse('bot:documentationlink-detail', args=(self.doc_link.package,), host='api')
- response = self.client.delete(url)
-
- self.assertEqual(response.status_code, 204)
diff --git a/api/tests/test_healthcheck.py b/api/tests/test_healthcheck.py
deleted file mode 100644
index b0fd71bf..00000000
--- a/api/tests/test_healthcheck.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from django_hosts.resolvers import reverse
-
-from .base import APISubdomainTestCase
-
-
-class UnauthedHealthcheckAPITests(APISubdomainTestCase):
- def setUp(self):
- super().setUp()
- self.client.force_authenticate(user=None)
-
- def test_can_access_healthcheck_view(self):
- url = reverse('healthcheck', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), {'status': 'ok'})
diff --git a/api/tests/test_infractions.py b/api/tests/test_infractions.py
deleted file mode 100644
index 7c370c17..00000000
--- a/api/tests/test_infractions.py
+++ /dev/null
@@ -1,359 +0,0 @@
-from datetime import datetime as dt, timedelta, timezone
-from urllib.parse import quote
-
-from django_hosts.resolvers import reverse
-
-from .base import APISubdomainTestCase
-from ..models import Infraction, User
-
-
-class UnauthenticatedTests(APISubdomainTestCase):
- def setUp(self):
- super().setUp()
- self.client.force_authenticate(user=None)
-
- def test_detail_lookup_returns_401(self):
- url = reverse('bot:infraction-detail', args=(5,), host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 401)
-
- def test_list_returns_401(self):
- url = reverse('bot:infraction-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 401)
-
- def test_create_returns_401(self):
- url = reverse('bot:infraction-list', host='api')
- response = self.client.post(url, data={'reason': 'Have a nice day.'})
-
- self.assertEqual(response.status_code, 401)
-
- def test_partial_update_returns_401(self):
- url = reverse('bot:infraction-detail', args=(5,), host='api')
- response = self.client.patch(url, data={'reason': 'Have a nice day.'})
-
- self.assertEqual(response.status_code, 401)
-
-
-class InfractionTests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.user = User.objects.create(
- id=5,
- name='james',
- discriminator=1,
- avatar_hash=None
- )
- cls.ban_hidden = Infraction.objects.create(
- user_id=cls.user.id,
- actor_id=cls.user.id,
- type='ban',
- reason='He terk my jerb!',
- hidden=True,
- expires_at=dt(5018, 11, 20, 15, 52, tzinfo=timezone.utc)
- )
- cls.ban_inactive = Infraction.objects.create(
- user_id=cls.user.id,
- actor_id=cls.user.id,
- type='ban',
- reason='James is an ass, and we won\'t be working with him again.',
- active=False
- )
-
- def test_list_all(self):
- url = reverse('bot:infraction-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- infractions = response.json()
-
- self.assertEqual(len(infractions), 2)
- self.assertEqual(infractions[0]['id'], self.ban_hidden.id)
- self.assertEqual(infractions[1]['id'], self.ban_inactive.id)
-
- def test_filter_search(self):
- url = reverse('bot:infraction-list', host='api')
- pattern = quote(r'^James(\s\w+){3},')
- response = self.client.get(f'{url}?search={pattern}')
-
- self.assertEqual(response.status_code, 200)
- infractions = response.json()
-
- self.assertEqual(len(infractions), 1)
- self.assertEqual(infractions[0]['id'], self.ban_inactive.id)
-
- def test_filter_field(self):
- url = reverse('bot:infraction-list', host='api')
- response = self.client.get(f'{url}?type=ban&hidden=true')
-
- self.assertEqual(response.status_code, 200)
- infractions = response.json()
-
- self.assertEqual(len(infractions), 1)
- self.assertEqual(infractions[0]['id'], self.ban_hidden.id)
-
- def test_returns_empty_for_no_match(self):
- url = reverse('bot:infraction-list', host='api')
- response = self.client.get(f'{url}?type=ban&search=poop')
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(len(response.json()), 0)
-
- def test_ignores_bad_filters(self):
- url = reverse('bot:infraction-list', host='api')
- response = self.client.get(f'{url}?type=ban&hidden=maybe&foo=bar')
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(len(response.json()), 2)
-
- def test_retrieve_single_from_id(self):
- url = reverse('bot:infraction-detail', args=(self.ban_inactive.id,), host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json()['id'], self.ban_inactive.id)
-
- def test_retrieve_returns_404_for_absent_id(self):
- url = reverse('bot:infraction-detail', args=(1337,), host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 404)
-
- def test_partial_update(self):
- url = reverse('bot:infraction-detail', args=(self.ban_hidden.id,), host='api')
- data = {
- 'expires_at': '4143-02-15T21:04:31+00:00',
- 'active': False,
- 'reason': 'durka derr'
- }
-
- response = self.client.patch(url, data=data)
- self.assertEqual(response.status_code, 200)
- infraction = Infraction.objects.get(id=self.ban_hidden.id)
-
- # These fields were updated.
- self.assertEqual(infraction.expires_at.isoformat(), data['expires_at'])
- self.assertEqual(infraction.active, data['active'])
- self.assertEqual(infraction.reason, data['reason'])
-
- # These fields are still the same.
- self.assertEqual(infraction.id, self.ban_hidden.id)
- self.assertEqual(infraction.inserted_at, self.ban_hidden.inserted_at)
- self.assertEqual(infraction.user.id, self.ban_hidden.user.id)
- self.assertEqual(infraction.actor.id, self.ban_hidden.actor.id)
- self.assertEqual(infraction.type, self.ban_hidden.type)
- self.assertEqual(infraction.hidden, self.ban_hidden.hidden)
-
- def test_partial_update_returns_400_for_frozen_field(self):
- url = reverse('bot:infraction-detail', args=(self.ban_hidden.id,), host='api')
- data = {'user': 6}
-
- response = self.client.patch(url, data=data)
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'user': ['This field cannot be updated.']
- })
-
-
-class CreationTests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.user = User.objects.create(
- id=5,
- name='james',
- discriminator=1,
- avatar_hash=None
- )
-
- def test_accepts_valid_data(self):
- url = reverse('bot:infraction-list', host='api')
- data = {
- 'user': self.user.id,
- 'actor': self.user.id,
- 'type': 'ban',
- 'reason': 'He terk my jerb!',
- 'hidden': True,
- 'expires_at': '5018-11-20T15:52:00+00:00'
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 201)
-
- infraction = Infraction.objects.get(id=response.json()['id'])
- self.assertAlmostEqual(
- infraction.inserted_at,
- dt.now(timezone.utc),
- delta=timedelta(seconds=2)
- )
- self.assertEqual(infraction.expires_at.isoformat(), data['expires_at'])
- self.assertEqual(infraction.user.id, data['user'])
- self.assertEqual(infraction.actor.id, data['actor'])
- self.assertEqual(infraction.type, data['type'])
- self.assertEqual(infraction.reason, data['reason'])
- self.assertEqual(infraction.hidden, data['hidden'])
- self.assertEqual(infraction.active, True)
-
- def test_returns_400_for_missing_user(self):
- url = reverse('bot:infraction-list', host='api')
- data = {
- 'actor': self.user.id,
- 'type': 'kick'
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'user': ['This field is required.']
- })
-
- def test_returns_400_for_bad_user(self):
- url = reverse('bot:infraction-list', host='api')
- data = {
- 'user': 1337,
- 'actor': self.user.id,
- 'type': 'kick'
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'user': ['Invalid pk "1337" - object does not exist.']
- })
-
- def test_returns_400_for_bad_type(self):
- url = reverse('bot:infraction-list', host='api')
- data = {
- 'user': self.user.id,
- 'actor': self.user.id,
- 'type': 'hug'
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'type': ['"hug" is not a valid choice.']
- })
-
- def test_returns_400_for_bad_expired_at_format(self):
- url = reverse('bot:infraction-list', host='api')
- data = {
- 'user': self.user.id,
- 'actor': self.user.id,
- 'type': 'ban',
- 'expires_at': '20/11/5018 15:52:00'
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'expires_at': [
- 'Datetime has wrong format. Use one of these formats instead: '
- 'YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z].'
- ]
- })
-
- def test_returns_400_for_expiring_non_expirable_type(self):
- url = reverse('bot:infraction-list', host='api')
- data = {
- 'user': self.user.id,
- 'actor': self.user.id,
- 'type': 'kick',
- 'expires_at': '5018-11-20T15:52:00+00:00'
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'expires_at': [f'{data["type"]} infractions cannot expire.']
- })
-
- def test_returns_400_for_hidden_non_hideable_type(self):
- url = reverse('bot:infraction-list', host='api')
- data = {
- 'user': self.user.id,
- 'actor': self.user.id,
- 'type': 'superstar',
- 'hidden': True
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'hidden': [f'{data["type"]} infractions cannot be hidden.']
- })
-
-
-class ExpandedTests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.user = User.objects.create(
- id=5,
- name='james',
- discriminator=1,
- avatar_hash=None
- )
- cls.kick = Infraction.objects.create(
- user_id=cls.user.id,
- actor_id=cls.user.id,
- type='kick'
- )
- cls.warning = Infraction.objects.create(
- user_id=cls.user.id,
- actor_id=cls.user.id,
- type='warning'
- )
-
- def check_expanded_fields(self, infraction):
- for key in ('user', 'actor'):
- obj = infraction[key]
- for field in ('id', 'name', 'discriminator', 'avatar_hash', 'roles', 'in_guild'):
- self.assertTrue(field in obj, msg=f'field "{field}" missing from {key}')
-
- def test_list_expanded(self):
- url = reverse('bot:infraction-list-expanded', host='api')
-
- response = self.client.get(url)
- self.assertEqual(response.status_code, 200)
-
- response_data = response.json()
- self.assertEqual(len(response_data), 2)
-
- for infraction in response_data:
- self.check_expanded_fields(infraction)
-
- def test_create_expanded(self):
- url = reverse('bot:infraction-list-expanded', host='api')
- data = {
- 'user': self.user.id,
- 'actor': self.user.id,
- 'type': 'warning'
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 201)
-
- self.assertEqual(len(Infraction.objects.all()), 3)
- self.check_expanded_fields(response.json())
-
- def test_retrieve_expanded(self):
- url = reverse('bot:infraction-detail-expanded', args=(self.warning.id,), host='api')
-
- response = self.client.get(url)
- self.assertEqual(response.status_code, 200)
-
- infraction = response.json()
- self.assertEqual(infraction['id'], self.warning.id)
- self.check_expanded_fields(infraction)
-
- def test_partial_update_expanded(self):
- url = reverse('bot:infraction-detail-expanded', args=(self.kick.id,), host='api')
- data = {'active': False}
-
- response = self.client.patch(url, data=data)
- self.assertEqual(response.status_code, 200)
-
- infraction = Infraction.objects.get(id=self.kick.id)
- self.assertEqual(infraction.active, data['active'])
- self.check_expanded_fields(response.json())
diff --git a/api/tests/test_models.py b/api/tests/test_models.py
deleted file mode 100644
index 43d1eb41..00000000
--- a/api/tests/test_models.py
+++ /dev/null
@@ -1,113 +0,0 @@
-from datetime import datetime as dt, timezone
-
-from django.test import SimpleTestCase
-
-from ..models import (
- BotSetting, DeletedMessage,
- DocumentationLink, Infraction,
- Message, MessageDeletionContext,
- ModelReprMixin, OffTopicChannelName,
- Reminder, Role,
- SnakeFact, SnakeIdiom,
- SnakeName, SpecialSnake,
- Tag, User
-)
-
-
-class SimpleClass(ModelReprMixin):
- def __init__(self, is_what):
- self.the_cake = is_what
-
-
-class ReprMixinTests(SimpleTestCase):
- def setUp(self):
- self.klass = SimpleClass('is a lie')
-
- def test_shows_attributes(self):
- expected = "<SimpleClass(the_cake='is a lie')>"
- self.assertEqual(repr(self.klass), expected)
-
-
-class StringDunderMethodTests(SimpleTestCase):
- def setUp(self):
- self.objects = (
- DeletedMessage(
- id=45,
- author=User(
- id=444, name='bill',
- discriminator=5, avatar_hash=None
- ),
- channel_id=666,
- content="wooey",
- deletion_context=MessageDeletionContext(
- actor=User(
- id=5555, name='shawn',
- discriminator=555, avatar_hash=None
- ),
- creation=dt.utcnow()
- ),
- embeds=[]
- ),
- DocumentationLink(
- 'test', 'http://example.com', 'http://example.com'
- ),
- OffTopicChannelName(name='bob-the-builders-playground'),
- SnakeFact(fact='snakes are cute'),
- SnakeIdiom(idiom='snake snacks'),
- SnakeName(name='python', scientific='3'),
- SpecialSnake(
- name='Pythagoras Pythonista',
- info='The only python snake that is born a triangle'
- ),
- Role(
- id=5, name='test role',
- colour=0x5, permissions=0
- ),
- Message(
- id=45,
- author=User(
- id=444, name='bill',
- discriminator=5, avatar_hash=None
- ),
- channel_id=666,
- content="wooey",
- embeds=[]
- ),
- MessageDeletionContext(
- actor=User(
- id=5555, name='shawn',
- discriminator=555, avatar_hash=None
- ),
- creation=dt.utcnow()
- ),
- Tag(
- title='bob',
- embed={'content': "the builder"}
- ),
- User(
- id=5, name='bob',
- discriminator=1, avatar_hash=None
- ),
- Infraction(
- user_id=5, actor_id=5,
- type='kick', reason='He terk my jerb!'
- ),
- Infraction(
- user_id=5, actor_id=5, hidden=True,
- type='kick', reason='He terk my jerb!',
- expires_at=dt(5018, 11, 20, 15, 52, tzinfo=timezone.utc)
- ),
- Reminder(
- author=User(
- id=452, name='billy',
- discriminator=5, avatar_hash=None
- ),
- channel_id=555,
- content="oh no",
- expiration=dt(5018, 11, 20, 15, 52, tzinfo=timezone.utc)
- )
- )
-
- def test_returns_string(self):
- for instance in self.objects:
- self.assertIsInstance(str(instance), str)
diff --git a/api/tests/test_nominations.py b/api/tests/test_nominations.py
deleted file mode 100644
index 1f03d1b0..00000000
--- a/api/tests/test_nominations.py
+++ /dev/null
@@ -1,41 +0,0 @@
-from django_hosts.resolvers import reverse
-
-from .base import APISubdomainTestCase
-from ..models import Nomination, User
-
-
-class NominationTests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.author = User.objects.create(
- id=5152,
- name='Ro Bert',
- discriminator=256,
- avatar_hash=None
- )
- cls.user = cls.author
-
- cls.nomination = Nomination.objects.create(
- author=cls.author,
- reason="he's good",
- user=cls.author
- )
-
- def test_returns_400_on_attempt_to_update_frozen_field(self):
- url = reverse('bot:nomination-detail', args=(self.user.id,), host='api')
- response = self.client.put(
- url,
- data={'inserted_at': 'something bad'}
- )
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'inserted_at': ['This field cannot be updated.']
- })
-
- def test_returns_200_on_successful_update(self):
- url = reverse('bot:nomination-detail', args=(self.user.id,), host='api')
- response = self.client.patch(
- url,
- data={'reason': 'there are many like it, but this test is mine'}
- )
- self.assertEqual(response.status_code, 200)
diff --git a/api/tests/test_off_topic_channel_names.py b/api/tests/test_off_topic_channel_names.py
deleted file mode 100644
index 60af1f62..00000000
--- a/api/tests/test_off_topic_channel_names.py
+++ /dev/null
@@ -1,152 +0,0 @@
-from django_hosts.resolvers import reverse
-
-from .base import APISubdomainTestCase
-from ..models import OffTopicChannelName
-
-
-class UnauthenticatedTests(APISubdomainTestCase):
- def setUp(self):
- super().setUp()
- self.client.force_authenticate(user=None)
-
- def test_cannot_read_off_topic_channel_name_list(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 401)
-
- def test_cannot_read_off_topic_channel_name_list_with_random_item_param(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.get(f'{url}?random_items=no')
-
- self.assertEqual(response.status_code, 401)
-
-
-class EmptyDatabaseTests(APISubdomainTestCase):
- def test_returns_empty_object(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), [])
-
- def test_returns_empty_list_with_get_all_param(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.get(f'{url}?random_items=5')
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), [])
-
- def test_returns_400_for_bad_random_items_param(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.get(f'{url}?random_items=totally-a-valid-integer')
-
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'random_items': ["Must be a valid integer."]
- })
-
- def test_returns_400_for_negative_random_items_param(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.get(f'{url}?random_items=-5')
-
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'random_items': ["Must be a positive integer."]
- })
-
-
-class ListTests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.test_name = OffTopicChannelName.objects.create(name='lemons-lemonade-stand')
- cls.test_name_2 = OffTopicChannelName.objects.create(name='bbq-with-bisk')
-
- def test_returns_name_in_list(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(
- response.json(),
- [
- self.test_name.name,
- self.test_name_2.name
- ]
- )
-
- def test_returns_single_item_with_random_items_param_set_to_1(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.get(f'{url}?random_items=1')
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(len(response.json()), 1)
-
-
-class CreationTests(APISubdomainTestCase):
- def setUp(self):
- super().setUp()
-
- url = reverse('bot:offtopicchannelname-list', host='api')
- self.name = "lemonade-shop"
- response = self.client.post(f'{url}?name={self.name}')
- self.assertEqual(response.status_code, 201)
-
- def test_name_in_full_list(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), [self.name])
-
- def test_returns_400_for_missing_name_param(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.post(url)
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'name': ["This query parameter is required."]
- })
-
- def test_returns_400_for_bad_name_param(self):
- url = reverse('bot:offtopicchannelname-list', host='api')
- invalid_names = (
- 'space between words',
- 'UPPERCASE',
- '$$$$$$$$'
- )
-
- for name in invalid_names:
- response = self.client.post(f'{url}?name={name}')
- self.assertEqual(response.status_code, 400)
- self.assertEqual(response.json(), {
- 'name': ["Enter a valid value."]
- })
-
-
-class DeletionTests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.test_name = OffTopicChannelName.objects.create(name='lemons-lemonade-stand')
- cls.test_name_2 = OffTopicChannelName.objects.create(name='bbq-with-bisk')
-
- def test_deleting_unknown_name_returns_404(self):
- url = reverse('bot:offtopicchannelname-detail', args=('unknown-name',), host='api')
- response = self.client.delete(url)
-
- self.assertEqual(response.status_code, 404)
-
- def test_deleting_known_name_returns_204(self):
- url = reverse('bot:offtopicchannelname-detail', args=(self.test_name.name,), host='api')
- response = self.client.delete(url)
-
- self.assertEqual(response.status_code, 204)
-
- def test_name_gets_deleted(self):
- url = reverse('bot:offtopicchannelname-detail', args=(self.test_name_2.name,), host='api')
- response = self.client.delete(url)
-
- self.assertEqual(response.status_code, 204)
-
- url = reverse('bot:offtopicchannelname-list', host='api')
- response = self.client.get(url)
- self.assertNotIn(self.test_name_2.name, response.json())
diff --git a/api/tests/test_rules.py b/api/tests/test_rules.py
deleted file mode 100644
index c94f89cc..00000000
--- a/api/tests/test_rules.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from django_hosts.resolvers import reverse
-
-from .base import APISubdomainTestCase
-from ..views import RulesView
-
-
-class RuleAPITests(APISubdomainTestCase):
- def setUp(self):
- super().setUp()
- self.client.force_authenticate(user=None)
-
- def test_can_access_rules_view(self):
- url = reverse('rules', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertIsInstance(response.json(), list)
-
- def test_link_format_query_param_produces_different_results(self):
- url = reverse('rules', host='api')
- markdown_links_response = self.client.get(url + '?link_format=md')
- html_links_response = self.client.get(url + '?link_format=html')
- self.assertNotEqual(
- markdown_links_response.json(),
- html_links_response.json()
- )
-
- def test_format_link_raises_value_error_for_invalid_target(self):
- with self.assertRaises(ValueError):
- RulesView._format_link("a", "b", "c")
-
- def test_get_returns_400_for_wrong_link_format(self):
- url = reverse('rules', host='api')
- response = self.client.get(url + '?link_format=unknown')
- self.assertEqual(response.status_code, 400)
diff --git a/api/tests/test_snake_names.py b/api/tests/test_snake_names.py
deleted file mode 100644
index 41dfae63..00000000
--- a/api/tests/test_snake_names.py
+++ /dev/null
@@ -1,67 +0,0 @@
-from django_hosts.resolvers import reverse
-
-from .base import APISubdomainTestCase
-from ..models import SnakeName
-
-
-class StatusTests(APISubdomainTestCase):
- def setUp(self):
- super().setUp()
- self.client.force_authenticate(user=None)
-
- def test_cannot_read_snake_name_list(self):
- url = reverse('bot:snakename-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 401)
-
- def test_cannot_read_snake_names_with_get_all_param(self):
- url = reverse('bot:snakename-list', host='api')
- response = self.client.get(f'{url}?get_all=True')
-
- self.assertEqual(response.status_code, 401)
-
-
-class EmptyDatabaseSnakeNameTests(APISubdomainTestCase):
- def test_endpoint_returns_empty_object(self):
- url = reverse('bot:snakename-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), {})
-
- def test_endpoint_returns_empty_list_with_get_all_param(self):
- url = reverse('bot:snakename-list', host='api')
- response = self.client.get(f'{url}?get_all=True')
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json(), [])
-
-
-class SnakeNameListTests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.snake_python = SnakeName.objects.create(name='Python', scientific='Totally.')
-
- def test_endpoint_returns_all_snakes_with_get_all_param(self):
- url = reverse('bot:snakename-list', host='api')
- response = self.client.get(f'{url}?get_all=True')
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(
- response.json(),
- [
- {
- 'name': self.snake_python.name,
- 'scientific': self.snake_python.scientific
- }
- ]
- )
-
- def test_endpoint_returns_single_snake_without_get_all_param(self):
- url = reverse('bot:snakename-list', host='api')
- response = self.client.get(url)
- self.assertEqual(response.json(), {
- 'name': self.snake_python.name,
- 'scientific': self.snake_python.scientific
- })
diff --git a/api/tests/test_users.py b/api/tests/test_users.py
deleted file mode 100644
index 90bc3d30..00000000
--- a/api/tests/test_users.py
+++ /dev/null
@@ -1,121 +0,0 @@
-from django_hosts.resolvers import reverse
-
-from .base import APISubdomainTestCase
-from ..models import Role, User
-
-
-class UnauthedUserAPITests(APISubdomainTestCase):
- def setUp(self):
- super().setUp()
- self.client.force_authenticate(user=None)
-
- def test_detail_lookup_returns_401(self):
- url = reverse('bot:user-detail', args=('whatever',), host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 401)
-
- def test_list_returns_401(self):
- url = reverse('bot:user-list', host='api')
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 401)
-
- def test_create_returns_401(self):
- url = reverse('bot:user-list', host='api')
- response = self.client.post(url, data={'hi': 'there'})
-
- self.assertEqual(response.status_code, 401)
-
- def test_delete_returns_401(self):
- url = reverse('bot:user-detail', args=('whatever',), host='api')
- response = self.client.delete(url)
-
- self.assertEqual(response.status_code, 401)
-
-
-class CreationTests(APISubdomainTestCase):
- @classmethod
- def setUpTestData(cls): # noqa
- cls.role = Role.objects.create(
- id=5,
- name="Test role pls ignore",
- colour=2,
- permissions=0b01010010101
- )
-
- def test_accepts_valid_data(self):
- url = reverse('bot:user-list', host='api')
- data = {
- 'id': 42,
- 'avatar_hash': "validavatarhashiswear",
- 'name': "Test",
- 'discriminator': 42,
- 'roles': [
- self.role.id
- ],
- 'in_guild': True
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 201)
- self.assertEqual(response.json(), data)
-
- user = User.objects.get(id=42)
- self.assertEqual(user.avatar_hash, data['avatar_hash'])
- self.assertEqual(user.name, data['name'])
- self.assertEqual(user.discriminator, data['discriminator'])
- self.assertEqual(user.in_guild, data['in_guild'])
-
- def test_supports_multi_creation(self):
- url = reverse('bot:user-list', host='api')
- data = [
- {
- 'id': 5,
- 'avatar_hash': "hahayes",
- 'name': "test man",
- 'discriminator': 42,
- 'roles': [
- self.role.id
- ],
- 'in_guild': True
- },
- {
- 'id': 8,
- 'avatar_hash': "maybenot",
- 'name': "another test man",
- 'discriminator': 555,
- 'roles': [],
- 'in_guild': False
- }
- ]
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 201)
- self.assertEqual(response.json(), data)
-
- def test_returns_400_for_unknown_role_id(self):
- url = reverse('bot:user-list', host='api')
- data = {
- 'id': 5,
- 'avatar_hash': "hahayes",
- 'name': "test man",
- 'discriminator': 42,
- 'roles': [
- 190810291
- ]
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 400)
-
- def test_returns_400_for_bad_data(self):
- url = reverse('bot:user-list', host='api')
- data = {
- 'id': True,
- 'avatar_hash': 1902831,
- 'discriminator': "totally!"
- }
-
- response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 400)
diff --git a/api/tests/test_validators.py b/api/tests/test_validators.py
deleted file mode 100644
index d2c0a136..00000000
--- a/api/tests/test_validators.py
+++ /dev/null
@@ -1,213 +0,0 @@
-from django.core.exceptions import ValidationError
-from django.test import TestCase
-
-from ..validators import (
- validate_bot_setting_name,
- validate_tag_embed
-)
-
-
-REQUIRED_KEYS = (
- 'content', 'fields', 'image', 'title', 'video'
-)
-
-
-class BotSettingValidatorTests(TestCase):
- def test_accepts_valid_names(self):
- validate_bot_setting_name('defcon')
-
- def test_rejects_bad_names(self):
- with self.assertRaises(ValidationError):
- validate_bot_setting_name('bad name')
-
-class TagEmbedValidatorTests(TestCase):
- def test_rejects_non_mapping(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed('non-empty non-mapping')
-
- def test_rejects_missing_required_keys(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'unknown': "key"
- })
-
- def test_rejects_one_correct_one_incorrect(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'provider': "??",
- 'title': ""
- })
-
- def test_rejects_empty_required_key(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'title': ''
- })
-
- def test_rejects_list_as_embed(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed([])
-
- def test_rejects_required_keys_and_unknown_keys(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'title': "the duck walked up to the lemonade stand",
- 'and': "he said to the man running the stand"
- })
-
- def test_rejects_too_long_title(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'title': 'a' * 257
- })
-
- def test_rejects_too_many_fields(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'fields': [{} for _ in range(26)]
- })
-
- def test_rejects_too_long_description(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'description': 'd' * 2049
- })
-
- def test_allows_valid_embed(self):
- validate_tag_embed({
- 'title': "My embed",
- 'description': "look at my embed, my embed is amazing"
- })
-
- def test_allows_unvalidated_fields(self):
- validate_tag_embed({
- 'title': "My embed",
- 'provider': "what am I??"
- })
-
- def test_rejects_fields_as_list_of_non_mappings(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'fields': ['abc']
- })
-
- def test_rejects_fields_with_unknown_fields(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'fields': [
- {
- 'what': "is this field"
- }
- ]
- })
-
- def test_rejects_fields_with_too_long_name(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'fields': [
- {
- 'name': "a" * 257
- }
- ]
- })
-
- def test_rejects_one_correct_one_incorrect_field(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'fields': [
- {
- 'name': "Totally valid",
- 'value': "LOOK AT ME"
- },
- {
- 'oh': "what is this key?"
- }
- ]
- })
-
- def test_allows_valid_fields(self):
- validate_tag_embed({
- 'fields': [
- {
- 'name': "valid",
- 'value': "field"
- }
- ]
- })
-
- def test_rejects_footer_as_non_mapping(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'title': "whatever",
- 'footer': []
- })
-
- def test_rejects_footer_with_unknown_fields(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'title': "whatever",
- 'footer': {
- 'duck': "quack"
- }
- })
-
- def test_rejects_footer_with_empty_text(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'title': "whatever",
- 'footer': {
- 'text': ""
- }
- })
-
- def test_allows_footer_with_proper_values(self):
- validate_tag_embed({
- 'title': "whatever",
- 'footer': {
- 'text': "django good"
- }
- })
-
- def test_rejects_author_as_non_mapping(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'title': "whatever",
- 'author': []
- })
-
- def test_rejects_author_with_unknown_field(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'title': "whatever",
- 'author': {
- 'field': "that is unknown"
- }
- })
-
- def test_rejects_author_with_empty_name(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'title': "whatever",
- 'author': {
- 'name': ""
- }
- })
-
- def test_rejects_author_with_one_correct_one_incorrect(self):
- with self.assertRaises(ValidationError):
- validate_tag_embed({
- 'title': "whatever",
- 'author': {
- # Relies on "dictionary insertion order remembering" (D.I.O.R.) behaviour
- 'url': "bobswebsite.com",
- 'name': ""
- }
- })
-
- def test_allows_author_with_proper_values(self):
- validate_tag_embed({
- 'title': "whatever",
- 'author': {
- 'name': "Bob"
- }
- })