diff options
author | 2019-04-05 18:24:32 +0100 | |
---|---|---|
committer | 2019-04-05 18:24:32 +0100 | |
commit | ab8b798547e82ca79882ba28b1920077c803425f (patch) | |
tree | b28a9005d05dfd2c9da62351671bf2aa6e37f7dc /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.py | 69 |
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', + email='[email protected]', + 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) |