aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps/api/tests/base.py
diff options
context:
space:
mode:
authorGravatar Gareth Coles <[email protected]>2019-04-05 18:24:32 +0100
committerGravatar Gareth Coles <[email protected]>2019-04-05 18:24:32 +0100
commitab8b798547e82ca79882ba28b1920077c803425f (patch)
treeb28a9005d05dfd2c9da62351671bf2aa6e37f7dc /pydis_site/apps/api/tests/base.py
parent[#158 #160] Automatically run collectstatic in containers/setup script (diff)
pysite -> pydis_site
Diffstat (limited to 'pydis_site/apps/api/tests/base.py')
-rw-r--r--pydis_site/apps/api/tests/base.py69
1 files changed, 69 insertions, 0 deletions
diff --git a/pydis_site/apps/api/tests/base.py b/pydis_site/apps/api/tests/base.py
new file mode 100644
index 00000000..0290fa69
--- /dev/null
+++ b/pydis_site/apps/api/tests/base.py
@@ -0,0 +1,69 @@
+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 pydis_site.apps.api 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 pydis_site.apps.api 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 pydis_site.apps.api 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)