1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
from __future__ import annotations
import os
import re
import shutil
import tempfile
from posixpath import basename
import pytest
from django.conf import settings
from django.contrib.staticfiles.storage import HashedFilesMixin
from django.contrib.staticfiles.storage import staticfiles_storage
from django.core.management import call_command
from django.test.utils import override_settings
from django.utils.functional import empty
from tests.utils import Files
from whitenoise.storage import CompressedManifestStaticFilesStorage
from whitenoise.storage import MissingFileError
@pytest.fixture()
def setup():
staticfiles_storage._wrapped = empty
files = Files("static")
tmp = tempfile.mkdtemp()
with override_settings(
STATICFILES_DIRS=[files.directory],
STATIC_ROOT=tmp,
):
yield settings
staticfiles_storage._wrapped = empty
shutil.rmtree(tmp)
@pytest.fixture()
def _compressed_storage(setup):
backend = "whitenoise.storage.CompressedStaticFilesStorage"
storages = {
"STORAGES": {
**settings.STORAGES,
"staticfiles": {"BACKEND": backend},
}
}
with override_settings(**storages):
yield
@pytest.fixture()
def _compressed_manifest_storage(setup):
backend = "whitenoise.storage.CompressedManifestStaticFilesStorage"
storages = {
"STORAGES": {
**settings.STORAGES,
"staticfiles": {"BACKEND": backend},
}
}
with override_settings(**storages, WHITENOISE_KEEP_ONLY_HASHED_FILES=True):
call_command("collectstatic", verbosity=0, interactive=False)
def test_compressed_static_files_storage(_compressed_storage):
call_command("collectstatic", verbosity=0, interactive=False)
for name in ["styles.css.gz", "styles.css.br"]:
path = os.path.join(settings.STATIC_ROOT, name)
assert os.path.exists(path)
def test_compressed_static_files_storage_dry_run(_compressed_storage):
call_command("collectstatic", "--dry-run", verbosity=0, interactive=False)
for name in ["styles.css.gz", "styles.css.br"]:
path = os.path.join(settings.STATIC_ROOT, name)
assert not os.path.exists(path)
def test_make_helpful_exception(_compressed_manifest_storage):
class TriggerException(HashedFilesMixin):
def exists(self, path):
return False
exception = None
try:
TriggerException().hashed_name("/missing/file.png")
except ValueError as e:
exception = e
helpful_exception = CompressedManifestStaticFilesStorage().make_helpful_exception(
exception, "styles/app.css"
)
assert isinstance(helpful_exception, MissingFileError)
def test_unversioned_files_are_deleted(_compressed_manifest_storage):
name = "styles.css"
versioned_url = staticfiles_storage.url(name)
versioned_name = basename(versioned_url)
name_pattern = re.compile("^" + name.replace(".", r"\.([0-9a-f]+\.)?") + "$")
remaining_files = [
f for f in os.listdir(settings.STATIC_ROOT) if name_pattern.match(f)
]
assert [versioned_name] == remaining_files
def test_manifest_file_is_left_in_place(_compressed_manifest_storage):
manifest_file = os.path.join(settings.STATIC_ROOT, "staticfiles.json")
assert os.path.exists(manifest_file)
def test_manifest_strict_attribute_is_set():
with override_settings(WHITENOISE_MANIFEST_STRICT=True):
storage = CompressedManifestStaticFilesStorage()
assert storage.manifest_strict is True
with override_settings(WHITENOISE_MANIFEST_STRICT=False):
storage = CompressedManifestStaticFilesStorage()
assert storage.manifest_strict is False
|