Commit 2730dad0 authored by mlavin's avatar mlavin Committed by Tim Graham
Browse files

Fixed #24197 -- Added clearing of staticfiles caches on settings changes during tests

Cleared caching in staticfiles_storage and get_finder when
relevant settings are changed.
parent 4444ff39
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -156,3 +156,24 @@ def root_urlconf_changed(**kwargs):
        from django.core.urlresolvers import clear_url_caches, set_urlconf
        clear_url_caches()
        set_urlconf(None)


@receiver(setting_changed)
def static_storage_changed(**kwargs):
    if kwargs['setting'] in {
        'STATICFILES_STORAGE',
        'STATIC_ROOT',
        'STATIC_URL',
    }:
        from django.contrib.staticfiles.storage import staticfiles_storage
        staticfiles_storage._wrapped = empty


@receiver(setting_changed)
def static_finders_changed(**kwargs):
    if kwargs['setting'] in {
        'STATICFILES_DIRS',
        'STATIC_ROOT',
    }:
        from django.contrib.staticfiles.finders import get_finder
        get_finder.cache_clear()
+7 −12
Original line number Diff line number Diff line
@@ -60,14 +60,6 @@ class BaseStaticFilesTestCase(object):
    Test case with a couple utility assertions.
    """
    def setUp(self):
        # Clear the cached staticfiles_storage out, this is because when it first
        # gets accessed (by some other test), it evaluates settings.STATIC_ROOT,
        # since we're planning on changing that we need to clear out the cache.
        storage.staticfiles_storage._wrapped = empty
        # Clear the cached staticfile finders, so they are reinitialized every
        # run and pick up changes in settings.STATICFILES_DIRS.
        finders.get_finder.cache_clear()

        self.testfiles_path = os.path.join(TEST_ROOT, 'apps', 'test', 'static', 'test')
        # To make sure SVN doesn't hangs itself with the non-ASCII characters
        # during checkout, we actually create one file dynamically.
@@ -130,15 +122,18 @@ class BaseCollectionTestCase(BaseStaticFilesTestCase):
    """
    def setUp(self):
        super(BaseCollectionTestCase, self).setUp()
        self.old_root = settings.STATIC_ROOT
        settings.STATIC_ROOT = tempfile.mkdtemp(dir=os.environ['DJANGO_TEST_TEMP_DIR'])
        temp_dir = tempfile.mkdtemp(dir=os.environ['DJANGO_TEST_TEMP_DIR'])
        # Override the STATIC_ROOT for all tests from setUp to tearDown
        # rather than as a context manager
        self.patched_settings = self.settings(STATIC_ROOT=temp_dir)
        self.patched_settings.enable()
        self.run_collectstatic()
        # Use our own error handler that can handle .svn dirs on Windows
        self.addCleanup(shutil.rmtree, settings.STATIC_ROOT,
        self.addCleanup(shutil.rmtree, temp_dir,
                        ignore_errors=True, onerror=rmtree_errorhandler)

    def tearDown(self):
        settings.STATIC_ROOT = self.old_root
        self.patched_settings.disable()
        super(BaseCollectionTestCase, self).tearDown()

    def run_collectstatic(self, **kwargs):
+56 −0
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@ from __future__ import unicode_literals
import unittest

from django.conf.urls import url
from django.contrib.staticfiles.finders import get_finders, get_finder
from django.contrib.staticfiles.storage import staticfiles_storage
from django.core.files.storage import default_storage
from django.core.urlresolvers import NoReverseMatch, reverse
from django.db import connection, router
@@ -14,6 +16,7 @@ from django.test import SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBF
from django.test.html import HTMLParseError, parse_html
from django.test.utils import CaptureQueriesContext, override_settings
from django.utils import six
from django.utils._os import abspathu

from .models import Car, Person, PossessedCar
from .views import empty_response
@@ -850,3 +853,56 @@ class OverrideSettingsTests(TestCase):
        test_routers = (object(),)
        with self.settings(DATABASE_ROUTERS=test_routers):
            self.assertSequenceEqual(router.routers, test_routers)

    def test_override_static_url(self):
        """
        Overriding the STATIC_URL setting should be reflected in the
        base_url attribute of
        django.contrib.staticfiles.storage.staticfiles_storage.
        """
        with self.settings(STATIC_URL='/test/'):
            self.assertEqual(staticfiles_storage.base_url, '/test/')

    def test_override_static_root(self):
        """
        Overriding the STATIC_ROOT setting should be reflected in the
        location attribute of
        django.contrib.staticfiles.storage.staticfiles_storage.
        """
        with self.settings(STATIC_ROOT='/tmp/test'):
            self.assertEqual(staticfiles_storage.location, abspathu('/tmp/test'))

    def test_override_staticfiles_storage(self):
        """
        Overriding the STATICFILES_STORAGE setting should be reflected in
        the value of django.contrib.staticfiles.storage.staticfiles_storage.
        """
        new_class = 'CachedStaticFilesStorage'
        new_storage = 'django.contrib.staticfiles.storage.' + new_class
        with self.settings(STATICFILES_STORAGE=new_storage):
            self.assertEqual(staticfiles_storage.__class__.__name__, new_class)

    def test_override_staticfiles_finders(self):
        """
        Overriding the STATICFILES_FINDERS setting should be reflected in
        the return value of django.contrib.staticfiles.finders.get_finders.
        """
        current = get_finders()
        self.assertGreater(len(list(current)), 1)
        finders = ['django.contrib.staticfiles.finders.FileSystemFinder']
        with self.settings(STATICFILES_FINDERS=finders):
            self.assertEqual(len(list(get_finders())), len(finders))

    def test_override_staticfiles_dirs(self):
        """
        Overriding the STATICFILES_DIRS setting should be reflected in
        the locations attribute of the
        django.contrib.staticfiles.finders.FileSystemFinder instance.
        """
        finder = get_finder('django.contrib.staticfiles.finders.FileSystemFinder')
        test_path = '/tmp/test'
        expected_location = ('', test_path)
        self.assertNotIn(expected_location, finder.locations)
        with self.settings(STATICFILES_DIRS=[test_path]):
            finder = get_finder('django.contrib.staticfiles.finders.FileSystemFinder')
            self.assertIn(expected_location, finder.locations)