Write tests

django_downloadview embeds test utilities:

temporary_media_root

django_downloadview.test.temporary_media_root(**kwargs)

Temporarily override settings.MEDIA_ROOT with a temporary directory.

The temporary directory is automatically created and destroyed.

Use this function as a context manager:

>>> from django_downloadview.test import temporary_media_root
>>> from django.conf import settings  # NoQA
>>> global_media_root = settings.MEDIA_ROOT
>>> with temporary_media_root():
...     global_media_root == settings.MEDIA_ROOT
False
>>> global_media_root == settings.MEDIA_ROOT
True

Or as a decorator:

>>> @temporary_media_root()
... def use_temporary_media_root():
...     return settings.MEDIA_ROOT
>>> tmp_media_root = use_temporary_media_root()
>>> global_media_root == tmp_media_root
False
>>> global_media_root == settings.MEDIA_ROOT
True

assert_download_response

django_downloadview.test.assert_download_response(test_case, response, **assertions)

Make test_case assert that response meets assertions.

Optional assertions dictionary can be used to check additional items:

  • basename: the basename of the file in the response.
  • content_type: the value of “Content-Type” header.
  • mime_type: the MIME type part of “Content-Type” header (without charset).
  • content: the contents of the file.
  • attachment: whether the file is returned as attachment or not.

Examples, related to StorageDownloadView demo:


from django.core.files.base import ContentFile
from django.http.response import HttpResponseNotModified
import django.test

    assert_download_response,
    setup_view,
    temporary_media_root,
)

from demoproject.compat import reverse
from demoproject.storage import views

# Fixtures.
file_content = "Hello world!\n"


def setup_file(path):
    views.storage.save(path, ContentFile(file_content))


class StaticPathTestCase(django.test.TestCase):
    @temporary_media_root()
    def test_download_response(self):
        """'storage:static_path' streams file by path."""
        setup_file("1.txt")
        url = reverse("storage:static_path", kwargs={"path": "1.txt"})
        response = self.client.get(url)
        assert_download_response(
            self,
            response,
            content=file_content,
            basename="1.txt",
            mime_type="text/plain",
        )

    @temporary_media_root()
    def test_not_modified_download_response(self):
        """'storage:static_path' sends not modified response if unmodified."""
        setup_file("1.txt")
        url = reverse("storage:static_path", kwargs={"path": "1.txt"})
        year = datetime.date.today().year + 4
        response = self.client.get(
            url, HTTP_IF_MODIFIED_SINCE=f"Sat, 29 Oct {year} 19:43:31 GMT",
        )
        self.assertTrue(isinstance(response, HttpResponseNotModified))

    @temporary_media_root()
    def test_modified_since_download_response(self):
        """'storage:static_path' streams file if modified."""
        setup_file("1.txt")
        url = reverse("storage:static_path", kwargs={"path": "1.txt"})
        response = self.client.get(
            url, HTTP_IF_MODIFIED_SINCE="Sat, 29 Oct 1980 19:43:31 GMT"

setup_view

django_downloadview.test.setup_view(view, request, *args, **kwargs)

Mimic as_view(), but returns view instance.

Use this function to get view instances on which you can run unit tests, by testing specific methods.

This is an early implementation of https://code.djangoproject.com/ticket/20456

view
A view instance, such as TemplateView(template_name='dummy.html'). Initialization arguments are the same you would pass to as_view().
request
A request object, typically built with RequestFactory.
args and kwargs
“URLconf” positional and keyword arguments, the same you would pass to reverse().

Example, related to StorageDownloadView demo:

import datetime
import unittest
from django_downloadview import (
    assert_download_response,
    setup_view,
    temporary_media_root,
)
        assert_download_response(
            self,
            response,
            content=file_content,
            basename="1.txt",
            mime_type="text/plain",
        )


class DynamicPathIntegrationTestCase(django.test.TestCase):
    """Integration tests around ``storage:dynamic_path`` URL."""

    @temporary_media_root()
    def test_download_response(self):
        """'dynamic_path' streams file by generated path.

        As we use ``self.client``, this test involves the whole Django stack,
        including settings, middlewares, decorators... So we need to setup a
        file, the storage, and an URL.

        This test actually asserts the URL ``storage:dynamic_path`` streams a
        file in storage.

        """
        setup_file("1.TXT")
        url = reverse("storage:dynamic_path", kwargs={"path": "1.txt"})
        response = self.client.get(url)
        assert_download_response(
            self,
            response,
            content=file_content,
            basename="1.TXT",
            mime_type="text/plain",
        )


class DynamicPathUnitTestCase(unittest.TestCase):
    """Unit tests around ``views.DynamicStorageDownloadView``."""

    def test_get_path(self):
        """DynamicStorageDownloadView.get_path() returns uppercase path.

        Uses :func:`~django_downloadview.test.setup_view` to target only
        overriden methods.

        This test does not involve URLconf, middlewares or decorators. It is
        fast. It has clear scope. It does not assert ``storage:dynamic_path``
        URL works. It targets only custom ``DynamicStorageDownloadView`` class.

        """
        view = setup_view(
            views.DynamicStorageDownloadView(),
            django.test.RequestFactory().get("/fake-url"),
            path="dummy path",
        )
        path = view.get_path()
        self.assertEqual(path, "DUMMY PATH")