0

I want to write a Django test that looks at all the urls in one particular app, and makes sure that hitting them without being authenticated redirects me to the login page.

Something like:

from django.test import TestCase
from django.urls import reverse
from my_app.urls import urlpatterns

class AuthTest(TestCase):
    def _test_url(self, url):
        response = self.client.get(url)
        self.assertRedirects(response, expected_url=reverse("login_app:login")+ "?next=" + url)

    def test_auth(self):
        for url in urlpatterns.SOMETHING:
            with self.subTest(url=url):
                self._test_url(url)

Is there a way to get the actual list of urls in each urlpattern for my app?

And, related question: for those URLs that require a pk, is there a way to automatically use pk=1? My fixtures will make sure that pk=1 exists for all those urls.

John
  • 2,551
  • 3
  • 30
  • 55
  • See [here](https://stackoverflow.com/questions/1275486/django-how-can-i-see-a-list-of-urlpatterns) for URLs. On the second question, you control the invocation of the URL so can you simply append `?pk=1`? – jarmod Jun 27 '22 at 15:12
  • You could write an api spec or use [Django REST Swagger](https://django-rest-swagger.readthedocs.io/en/latest/) and use [Mayhem for API](https://mayhem4api.forallsecure.com/) – Ross Rogers Jun 27 '22 at 15:14

1 Answers1

0

As our applications needs authentication by default, we used a middleware to make sure the user is login except in case of some exempted paths like API Endpoints that are secure by our means

The middleware goes like this

from django.http import HttpResponseRedirect, HttpResponse
from django.conf import settings

class UserMiddleware:
    
    def __init__(self, get_response):
         self.get_response = get_response

    def __call__(self, request):
        state = request.user.is_authenticated
        path = request.META["PATH_INFO"]
        if not state and not path in settings.EXEMPTED_PATHS:
            url = settings.LOGIN_URL
            if not "next" in path:
                if "?" in URL:
                   url += '&'
                else: url += "?"
                url += "next=%s" % (
                    settings.BASE_URL + path).replace("//", "/")
            if len(request.GET) > 0:
                if "?" in URL:
                    url += "?"
               else: url += "&"
               url += "%s" % request.GET.urlencode().replace("//", "/")
           return HttpResponseRedirect(url)
      return self.get_response(request)
Mohamed ElKalioby
  • 1,908
  • 1
  • 12
  • 13
  • Thanks. I just use [decorator_include](https://pypi.org/project/django-decorator-include/), and `django.contrib.auth.decorators.login_required`. Your answer doesn't really explain how to write tests to make sure that the views require authentication, which is the main question. Just because you have middleware that enables authentication doesn't mean that at some point, something won't change that will bypass authentication on some, or all of your views. – John Jun 28 '22 at 01:31