mardi 26 juillet 2016

Django testing, mock valid requests to urls

I have a bunch of urls in my urls.py file that have the login_required decorator

# Index Page
url(r'^$', login_required(views.IndexPage.as_view()), name='index'),

# Schedule urls
url(r'^schedules/$', login_required(views.ScheduleListView.as_view()),
    name='schedule-list'),
url(r'^schedule/(?P<pk>[\d]+)/$',
    login_required(views.ScheduleDetailView.as_view()),
    name='schedule-detail'),
url(r'^schedule-freeze/(?P<pk>[\d]+)/$',
    login_required(views.freezeSchedule),
    name='schedule-freeze'),
url(r'^schedule-create/$', login_required(views.ScheduleCreate.as_view()),
    name='schedule-create'),
url(r'^schedule-delete/(?P<pk>[\d]+)$',
    login_required(views.ScheduleDelete.as_view()),
    name='schedule-delete'),
url(r'^schedule-update/(?P<pk>[\d]+)/$',
    login_required(views.ScheduleUpdate.as_view()),
    name='schedule-update'),
url(r'^schedule-generate/(?P<pk>[\d]+)/$',
    login_required(views.scheduleGenerate), name='schedule-generate'),

# Client urls
url(r'^clients/$', login_required(views.ClientList.as_view()),
    name='client-list'),
url(r'^client/(?P<slug>[\w-]+)/$',
    login_required(views.ClientDetail.as_view()), name='client-detail'),
url(r'^client-create/$', login_required(views.ClientCreate.as_view()),
    name='client-create'),
url(r'^client-delete/(?P<slug>[\w-]+)/$',
    login_required(views.ClientDelete.as_view()), name='client-delete'),
url(r'^client-update/(?P<slug>[\w-]+)/$',
    login_required(views.ClientUpdate.as_view()), name='client-update'),

# And so on ....

For every restricted view I'm trying to write a test which ensures unauthorized users are redirected to the login page when trying to access the view. If possible I'd like to be able to achieve this in a single block of code, instead of writing a single test for every single URL.

I've tried something like the following:

list_urls = [e for e in get_resolver(urls).reverse_dict.keys() if isinstance(e, str)]

for url in list_urls:
    # Fetches the urlpath e.g. 'client-list'
    namedspaced_url = 'reports:' + url
    path = reverse(namedspaced_url)
    response = self.client.get(path)
    self.assertEqual(response.status_code, 302)
    self.assertRedirects(response, reverse('login') + '?next=' + path)

list_urls returns a list of all the named urls inside my urls.py file i.e. ['schedule-create', 'server-detail', 'schedule-list', 'schedule-update', 'index', ....]

However, this is where I'm running into problems. Each url has a different regular expression pattern, i.e. some take slugs some take pk's

so the line path = reverse(namedspaced_url) will work for simple URLs like those which point at ListViews but will fail for more complex URLs, such as those that point at DetailViews which require slug's/pk's, i.e. path = reverse(namedspaces_url, args=[1945])

Is it possible to temporarily override / ignore Django's pattern matching / routing to force a request to go through (regardless of passed args)

Or do I have to manually write a test for each URL with valid kwargs/args to satisfy regex?

Is there another completely different approach I can take to write tests for all my login_required() views?

Aucun commentaire:

Enregistrer un commentaire