Previous Entry Share Next Entry
A Django view used in just one test
salgado
So today I had to change a test in Launch Control to make sure we were protected against CSRF attacks. The existing test was using the login form, which is being removed, so I had to use another form in the test. Given that Launch Control doesn't have any forms now, I had to write a new one, but since it was only going to be used in that test I wanted all the code (specially the urlpatterns) for it in the same file as the test.

After reading/struggling a bit, this is what I came up with. It doesn't look too bad to me, but I'm wondering if there are any simpler/cleaner ways of doing this?

# CSRFTestCase is just a custom test case which provides a TestClient with an
# UnprotectedClientHandler.
class CSRFConfigurationTestCase(CSRFTestCase):

    @property
    def urls(self):
        urlpatterns = patterns('', url(r'^test-form/', test_form))
        return type('urls', (), dict(urlpatterns=urlpatterns))

    def test_csrf_token_present_in_form(self):
        if django.VERSION[:2] == (1, 1):
            # This feature is not supported on django 1.1
            return
        form_path = reverse("dashboard_app.tests.other.csrf.test_form")
        response = self.client.get(self.form_path)
        self.assertContains(response, "csrfmiddlewaretoken")

    def test_cross_site_form_submission_fails(self):
        if django.VERSION[:2] == (1, 1):
            # This feature is not supported on django 1.1
            return
        form_path = reverse("dashboard_app.tests.other.csrf.test_form")
        response = self.client.post(self.form_path, {'text': 'text'})
        self.assertEquals(response.status_code, 403)

def test_form(request):
    t = Template(template)
    html = t.render(Context({'form': SingleTextFieldForm()}))
    return HttpResponse(html)

class SingleTextFieldForm(forms.Form):
    text = forms.CharField()

template = """
    <html>
     <body>
      <form action="." method="POST">
       <table>{{ form.as_table }}</table>
      </form>
     </body>
    </html>
    """