From ab8b798547e82ca79882ba28b1920077c803425f Mon Sep 17 00:00:00 2001 From: Gareth Coles Date: Fri, 5 Apr 2019 18:24:32 +0100 Subject: pysite -> pydis_site --- pydis_site/apps/api/tests/base.py | 69 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 pydis_site/apps/api/tests/base.py (limited to 'pydis_site/apps/api/tests/base.py') 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='test@example.com', + 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) -- cgit v1.2.3 From d06fd493b865ae2936709cc0875bbb9d56e58c62 Mon Sep 17 00:00:00 2001 From: Gareth Coles Date: Sun, 7 Apr 2019 18:35:37 +0100 Subject: Address review by @jchristgit --- pydis_site/apps/api/tests/base.py | 6 +++--- pydis_site/apps/api/validators.py | 2 +- pydis_site/apps/api/viewsets.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'pydis_site/apps/api/tests/base.py') diff --git a/pydis_site/apps/api/tests/base.py b/pydis_site/apps/api/tests/base.py index 0290fa69..8f8ace56 100644 --- a/pydis_site/apps/api/tests/base.py +++ b/pydis_site/apps/api/tests/base.py @@ -28,7 +28,7 @@ class APISubdomainTestCase(APITestCase): 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 + >>> from pydis_site.apps.api.tests.base import APISubdomainTestCase >>> class UnauthedUserTestCase(APISubdomainTestCase): ... def setUp(self): ... super().setUp() @@ -46,7 +46,7 @@ class APISubdomainTestCase(APITestCase): ## Example Using this in a test case is rather straightforward: - >>> from pydis_site.apps.api import APISubdomainTestCase + >>> from pydis_site.apps.api.tests.base import APISubdomainTestCase >>> class MyAPITestCase(APISubdomainTestCase): ... def test_that_it_works(self): ... response = self.client.get('/my-endpoint') @@ -55,7 +55,7 @@ class APISubdomainTestCase(APITestCase): 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 + >>> from pydis_site.apps.api.tests.base import APISubdomainTestCase >>> class MyReversedTestCase(APISubdomainTestCase): ... def test_my_endpoint(self): ... url = reverse('user-detail', host='api') diff --git a/pydis_site/apps/api/validators.py b/pydis_site/apps/api/validators.py index ac2fb739..69a8d1ef 100644 --- a/pydis_site/apps/api/validators.py +++ b/pydis_site/apps/api/validators.py @@ -86,7 +86,7 @@ def validate_tag_embed(embed): >>> from django.contrib.postgres import fields as pgfields >>> from django.db import models - >>> from pydis_site.apps.api import validate_tag_embed + >>> from pydis_site.apps.api.validators import validate_tag_embed >>> class MyMessage(models.Model): ... embed = pgfields.JSONField( ... validators=( diff --git a/pydis_site/apps/api/viewsets.py b/pydis_site/apps/api/viewsets.py index 17024fe8..949ffaaa 100644 --- a/pydis_site/apps/api/viewsets.py +++ b/pydis_site/apps/api/viewsets.py @@ -383,7 +383,7 @@ class ReminderViewSet(CreateModelMixin, ListModelMixin, DestroyModelMixin, Gener ... 'active': True, ... 'author': 1020103901030, ... 'content': "Make dinner", - ... 'expiration': '5018-11-20T15:52:00Z' + ... 'expiration': '5018-11-20T15:52:00Z', ... 'id': 11 ... }, ... ... -- cgit v1.2.3