2011-02-15 07:45:32 +08:00
# -*- encoding: utf-8 -*-
2012-06-08 00:08:47 +08:00
from __future__ import unicode_literals
2011-10-14 05:34:56 +08:00
2011-02-15 07:45:32 +08:00
import codecs
2010-10-20 09:33:24 +08:00
import os
import posixpath
2010-12-04 15:28:12 +08:00
import shutil
import sys
import tempfile
2010-10-20 09:33:24 +08:00
2011-08-11 22:07:39 +08:00
from django . template import loader , Context
2010-10-20 09:33:24 +08:00
from django . conf import settings
2012-05-16 19:21:46 +08:00
from django . core . cache . backends . base import BaseCache
2010-10-20 09:33:24 +08:00
from django . core . exceptions import ImproperlyConfigured
from django . core . management import call_command
2010-12-04 15:28:12 +08:00
from django . test import TestCase
2011-06-30 17:06:19 +08:00
from django . test . utils import override_settings
2012-12-08 18:13:52 +08:00
from django . utils . encoding import force_text
2011-06-02 04:45:47 +08:00
from django . utils . functional import empty
2012-12-08 18:13:52 +08:00
from django . utils . _os import rmtree_errorhandler , upath
2012-07-20 20:22:00 +08:00
from django . utils import six
2010-10-20 09:33:24 +08:00
2011-06-30 17:06:19 +08:00
from django . contrib . staticfiles import finders , storage
2010-10-20 09:33:24 +08:00
2012-12-08 18:13:52 +08:00
TEST_ROOT = os . path . dirname ( upath ( __file__ ) )
2011-08-11 22:07:39 +08:00
TEST_SETTINGS = {
' DEBUG ' : True ,
' MEDIA_URL ' : ' /media/ ' ,
' STATIC_URL ' : ' /static/ ' ,
' MEDIA_ROOT ' : os . path . join ( TEST_ROOT , ' project ' , ' site_media ' , ' media ' ) ,
' STATIC_ROOT ' : os . path . join ( TEST_ROOT , ' project ' , ' site_media ' , ' static ' ) ,
' STATICFILES_DIRS ' : (
os . path . join ( TEST_ROOT , ' project ' , ' documents ' ) ,
( ' prefix ' , os . path . join ( TEST_ROOT , ' project ' , ' prefixed ' ) ) ,
) ,
' STATICFILES_FINDERS ' : (
' django.contrib.staticfiles.finders.FileSystemFinder ' ,
' django.contrib.staticfiles.finders.AppDirectoriesFinder ' ,
' django.contrib.staticfiles.finders.DefaultStorageFinder ' ,
) ,
}
2012-02-13 18:51:17 +08:00
from django . contrib . staticfiles . management . commands . collectstatic import Command as CollectstaticCommand
2010-12-31 22:22:32 +08:00
2010-10-20 09:33:24 +08:00
2011-08-11 22:07:39 +08:00
class BaseStaticFilesTestCase ( object ) :
2010-10-20 09:33:24 +08:00
"""
Test case with a couple utility assertions .
"""
def setUp ( self ) :
2012-10-28 04:38:15 +08:00
# Clear the cached staticfiles_storage out, this is because when it first
# gets accessed (by some other test), it evaluates settings.STATIC_ROOT,
2010-10-31 07:39:53 +08:00
# since we're planning on changing that we need to clear out the cache.
2011-08-11 22:07:39 +08:00
storage . staticfiles_storage . _wrapped = empty
2012-07-25 15:57:00 +08:00
# Clear the cached staticfile finders, so they are reinitialized every
# run and pick up changes in settings.STATICFILES_DIRS.
finders . _finders . clear ( )
2010-10-31 07:39:53 +08:00
2012-02-13 18:51:17 +08:00
testfiles_path = os . path . join ( TEST_ROOT , ' apps ' , ' test ' , ' static ' , ' test ' )
2011-02-16 02:15:38 +08:00
# To make sure SVN doesn't hangs itself with the non-ASCII characters
# during checkout, we actually create one file dynamically.
2012-11-21 16:52:09 +08:00
self . _nonascii_filepath = os . path . join ( testfiles_path , ' \u2297 .txt ' )
2012-02-13 18:51:17 +08:00
with codecs . open ( self . _nonascii_filepath , ' w ' , ' utf-8 ' ) as f :
2012-11-21 16:52:09 +08:00
f . write ( " \u2297 in the app dir " )
2012-02-13 18:51:17 +08:00
# And also create the stupid hidden file to dwarf the setup.py's
# package data handling.
self . _hidden_filepath = os . path . join ( testfiles_path , ' .hidden ' )
with codecs . open ( self . _hidden_filepath , ' w ' , ' utf-8 ' ) as f :
f . write ( " should be ignored " )
self . _backup_filepath = os . path . join (
TEST_ROOT , ' project ' , ' documents ' , ' test ' , ' backup~ ' )
with codecs . open ( self . _backup_filepath , ' w ' , ' utf-8 ' ) as f :
f . write ( " should be ignored " )
def tearDown ( self ) :
os . unlink ( self . _nonascii_filepath )
os . unlink ( self . _hidden_filepath )
os . unlink ( self . _backup_filepath )
2010-10-20 09:33:24 +08:00
def assertFileContains ( self , filepath , text ) :
2012-12-08 18:13:52 +08:00
self . assertIn ( text , self . _get_file ( force_text ( filepath ) ) ,
2012-06-08 00:08:47 +08:00
" ' %s ' not in ' %s ' " % ( text , filepath ) )
2010-10-20 09:33:24 +08:00
def assertFileNotFound ( self , filepath ) :
self . assertRaises ( IOError , self . _get_file , filepath )
2011-08-11 22:07:39 +08:00
def render_template ( self , template , * * kwargs ) :
2012-07-20 20:22:00 +08:00
if isinstance ( template , six . string_types ) :
2011-08-11 22:07:39 +08:00
template = loader . get_template_from_string ( template )
return template . render ( Context ( kwargs ) ) . strip ( )
2012-07-07 21:30:25 +08:00
def static_template_snippet ( self , path , asvar = False ) :
if asvar :
return " { %% load static from staticfiles %% } { %% static ' %s ' as var %% } {{ var }} " % path
2011-11-03 18:51:02 +08:00
return " { %% load static from staticfiles %% } { %% static ' %s ' %% } " % path
2012-07-07 21:30:25 +08:00
def assertStaticRenders ( self , path , result , asvar = False , * * kwargs ) :
template = self . static_template_snippet ( path , asvar )
2011-08-11 22:07:39 +08:00
self . assertEqual ( self . render_template ( template , * * kwargs ) , result )
2011-06-30 17:06:19 +08:00
2012-07-07 21:30:25 +08:00
def assertStaticRaises ( self , exc , path , result , asvar = False , * * kwargs ) :
2011-11-03 18:51:02 +08:00
self . assertRaises ( exc , self . assertStaticRenders , path , result , * * kwargs )
2010-10-20 09:33:24 +08:00
2011-08-11 22:07:39 +08:00
2012-03-30 17:08:29 +08:00
@override_settings ( * * TEST_SETTINGS )
2011-08-11 22:07:39 +08:00
class StaticFilesTestCase ( BaseStaticFilesTestCase , TestCase ) :
pass
class BaseCollectionTestCase ( BaseStaticFilesTestCase ) :
2010-10-20 09:33:24 +08:00
"""
2011-08-11 22:07:39 +08:00
Tests shared by all file finding features ( collectstatic ,
2010-10-20 09:33:24 +08:00
findstatic , and static serve view ) .
2012-02-13 18:51:17 +08:00
This relies on the asserts defined in BaseStaticFilesTestCase , but
2010-10-20 09:33:24 +08:00
is separated because some test cases need those asserts without
all these tests .
"""
def setUp ( self ) :
2011-08-11 22:07:39 +08:00
super ( BaseCollectionTestCase , self ) . setUp ( )
2010-11-17 23:36:26 +08:00
self . old_root = settings . STATIC_ROOT
2011-11-14 03:05:02 +08:00
settings . STATIC_ROOT = tempfile . mkdtemp ( dir = os . environ [ ' DJANGO_TEST_TEMP_DIR ' ] )
2010-10-20 09:33:24 +08:00
self . run_collectstatic ( )
2011-06-30 17:06:19 +08:00
# Use our own error handler that can handle .svn dirs on Windows
2011-12-23 04:29:18 +08:00
self . addCleanup ( shutil . rmtree , settings . STATIC_ROOT ,
ignore_errors = True , onerror = rmtree_errorhandler )
2010-10-20 09:33:24 +08:00
def tearDown ( self ) :
2010-11-17 23:36:26 +08:00
settings . STATIC_ROOT = self . old_root
2011-08-11 22:07:39 +08:00
super ( BaseCollectionTestCase , self ) . tearDown ( )
2010-10-20 09:33:24 +08:00
def run_collectstatic ( self , * * kwargs ) :
call_command ( ' collectstatic ' , interactive = False , verbosity = ' 0 ' ,
ignore_patterns = [ ' *.ignoreme ' ] , * * kwargs )
def _get_file ( self , filepath ) :
assert filepath , ' filepath is empty. '
2010-11-17 23:36:26 +08:00
filepath = os . path . join ( settings . STATIC_ROOT , filepath )
2011-07-05 05:34:29 +08:00
with codecs . open ( filepath , " r " , " utf-8 " ) as f :
2010-10-30 12:24:24 +08:00
return f . read ( )
2010-10-20 09:33:24 +08:00
2011-06-30 17:06:19 +08:00
2011-08-11 22:07:39 +08:00
class CollectionTestCase ( BaseCollectionTestCase , StaticFilesTestCase ) :
pass
2010-10-20 09:33:24 +08:00
class TestDefaults ( object ) :
"""
A few standard test cases .
"""
def test_staticfiles_dirs ( self ) :
"""
Can find a file in a STATICFILES_DIRS directory .
"""
self . assertFileContains ( ' test.txt ' , ' Can we find ' )
2011-07-06 18:28:18 +08:00
self . assertFileContains ( os . path . join ( ' prefix ' , ' test.txt ' ) , ' Prefix ' )
2010-10-20 09:33:24 +08:00
def test_staticfiles_dirs_subdir ( self ) :
"""
Can find a file in a subdirectory of a STATICFILES_DIRS
directory .
"""
self . assertFileContains ( ' subdir/test.txt ' , ' Can we find ' )
def test_staticfiles_dirs_priority ( self ) :
"""
File in STATICFILES_DIRS has priority over file in app .
"""
self . assertFileContains ( ' test/file.txt ' , ' STATICFILES_DIRS ' )
def test_app_files ( self ) :
"""
2011-02-15 07:45:32 +08:00
Can find a file in an app static / directory .
2010-10-20 09:33:24 +08:00
"""
self . assertFileContains ( ' test/file1.txt ' , ' file1 in the app dir ' )
2011-02-15 07:45:32 +08:00
def test_nonascii_filenames ( self ) :
"""
Can find a file with non - ASCII character in an app static / directory .
"""
2012-11-21 16:52:09 +08:00
self . assertFileContains ( ' test/⊗.txt ' , ' ⊗ in the app dir ' )
2011-02-15 07:45:32 +08:00
2011-03-19 02:47:08 +08:00
def test_camelcase_filenames ( self ) :
"""
Can find a file with capital letters .
"""
2012-06-08 00:08:47 +08:00
self . assertFileContains ( ' test/camelCase.txt ' , ' camelCase ' )
2011-03-19 02:47:08 +08:00
2010-10-20 09:33:24 +08:00
2011-08-11 22:07:39 +08:00
class TestFindStatic ( CollectionTestCase , TestDefaults ) :
2010-10-23 22:32:54 +08:00
"""
Test ` ` findstatic ` ` management command .
"""
def _get_file ( self , filepath ) :
2012-08-12 00:56:14 +08:00
out = six . StringIO ( )
2012-05-28 17:55:38 +08:00
call_command ( ' findstatic ' , filepath , all = False , verbosity = 0 , stdout = out )
out . seek ( 0 )
lines = [ l . strip ( ) for l in out . readlines ( ) ]
2013-02-01 10:36:34 +08:00
with codecs . open ( force_text ( lines [ 0 ] . strip ( ) ) , " r " , " utf-8 " ) as f :
2012-08-15 16:25:01 +08:00
return f . read ( )
2010-10-23 22:32:54 +08:00
def test_all_files ( self ) :
"""
2013-02-01 10:36:34 +08:00
Test that findstatic returns all candidate files if run without - - first and - v1 .
2010-10-23 22:32:54 +08:00
"""
2012-08-12 00:56:14 +08:00
out = six . StringIO ( )
2013-02-01 10:36:34 +08:00
call_command ( ' findstatic ' , ' test/file.txt ' , verbosity = 1 , stdout = out )
2012-05-28 17:55:38 +08:00
out . seek ( 0 )
lines = [ l . strip ( ) for l in out . readlines ( ) ]
2011-08-11 22:07:39 +08:00
self . assertEqual ( len ( lines ) , 3 ) # three because there is also the "Found <file> here" line
2012-12-08 18:13:52 +08:00
self . assertIn ( ' project ' , force_text ( lines [ 1 ] ) )
self . assertIn ( ' apps ' , force_text ( lines [ 2 ] ) )
2010-10-23 22:32:54 +08:00
2013-02-01 10:36:34 +08:00
def test_all_files_less_verbose ( self ) :
"""
Test that findstatic returns all candidate files if run without - - first and - v0 .
"""
out = six . StringIO ( )
call_command ( ' findstatic ' , ' test/file.txt ' , verbosity = 0 , stdout = out )
out . seek ( 0 )
lines = [ l . strip ( ) for l in out . readlines ( ) ]
self . assertEqual ( len ( lines ) , 2 )
self . assertIn ( ' project ' , force_text ( lines [ 0 ] ) )
self . assertIn ( ' apps ' , force_text ( lines [ 1 ] ) )
2010-10-23 22:32:54 +08:00
2011-08-11 22:07:39 +08:00
class TestCollection ( CollectionTestCase , TestDefaults ) :
2010-10-20 09:33:24 +08:00
"""
Test ` ` collectstatic ` ` management command .
"""
def test_ignore ( self ) :
"""
Test that - i patterns are ignored .
"""
self . assertFileNotFound ( ' test/test.ignoreme ' )
def test_common_ignore_patterns ( self ) :
"""
Common ignore patterns ( * ~ , . * , CVS ) are ignored .
"""
self . assertFileNotFound ( ' test/.hidden ' )
self . assertFileNotFound ( ' test/backup~ ' )
self . assertFileNotFound ( ' test/CVS ' )
2011-08-11 22:07:39 +08:00
class TestCollectionClear ( CollectionTestCase ) :
2011-07-05 05:34:29 +08:00
"""
2013-04-28 22:45:05 +08:00
Test the ` ` - - clear ` ` option of the ` ` collectstatic ` ` management command .
2011-07-05 05:34:29 +08:00
"""
def run_collectstatic ( self , * * kwargs ) :
clear_filepath = os . path . join ( settings . STATIC_ROOT , ' cleared.txt ' )
with open ( clear_filepath , ' w ' ) as f :
f . write ( ' should be cleared ' )
2011-08-11 22:07:39 +08:00
super ( TestCollectionClear , self ) . run_collectstatic ( clear = True )
2011-07-05 05:34:29 +08:00
def test_cleared_not_found ( self ) :
self . assertFileNotFound ( ' cleared.txt ' )
2011-08-11 22:07:39 +08:00
class TestCollectionExcludeNoDefaultIgnore ( CollectionTestCase , TestDefaults ) :
2010-10-20 09:33:24 +08:00
"""
2011-07-05 05:34:29 +08:00
Test ` ` - - exclude - dirs ` ` and ` ` - - no - default - ignore ` ` options of the
2010-10-20 09:33:24 +08:00
` ` collectstatic ` ` management command .
"""
def run_collectstatic ( self ) :
2011-08-11 22:07:39 +08:00
super ( TestCollectionExcludeNoDefaultIgnore , self ) . run_collectstatic (
2010-10-20 09:33:24 +08:00
use_default_ignore_patterns = False )
def test_no_common_ignore_patterns ( self ) :
"""
With - - no - default - ignore , common ignore patterns ( * ~ , . * , CVS )
are not ignored .
"""
self . assertFileContains ( ' test/.hidden ' , ' should be ignored ' )
self . assertFileContains ( ' test/backup~ ' , ' should be ignored ' )
self . assertFileContains ( ' test/CVS ' , ' should be ignored ' )
2011-01-08 18:03:27 +08:00
class TestNoFilesCreated ( object ) :
def test_no_files_created ( self ) :
"""
Make sure no files were create in the destination directory .
"""
2011-03-03 23:04:39 +08:00
self . assertEqual ( os . listdir ( settings . STATIC_ROOT ) , [ ] )
2011-01-08 18:03:27 +08:00
2011-08-11 22:07:39 +08:00
class TestCollectionDryRun ( CollectionTestCase , TestNoFilesCreated ) :
2010-10-20 09:33:24 +08:00
"""
Test ` ` - - dry - run ` ` option for ` ` collectstatic ` ` management command .
"""
def run_collectstatic ( self ) :
2011-08-11 22:07:39 +08:00
super ( TestCollectionDryRun , self ) . run_collectstatic ( dry_run = True )
2010-10-20 09:33:24 +08:00
2011-01-08 18:03:27 +08:00
2012-03-02 07:02:38 +08:00
class TestCollectionFilesOverride ( CollectionTestCase ) :
"""
Test overriding duplicated files by ` ` collectstatic ` ` management command .
Check for proper handling of apps order in INSTALLED_APPS even if file modification
dates are in different order :
2013-02-26 20:19:18 +08:00
' staticfiles_tests.apps.test ' ,
' staticfiles_tests.apps.no_label ' ,
2012-03-02 07:02:38 +08:00
"""
def setUp ( self ) :
self . orig_path = os . path . join ( TEST_ROOT , ' apps ' , ' no_label ' , ' static ' , ' file2.txt ' )
# get modification and access times for no_label/static/file2.txt
self . orig_mtime = os . path . getmtime ( self . orig_path )
self . orig_atime = os . path . getatime ( self . orig_path )
# prepare duplicate of file2.txt from no_label app
# this file will have modification time older than no_label/static/file2.txt
# anyway it should be taken to STATIC_ROOT because 'test' app is before
# 'no_label' app in INSTALLED_APPS
self . testfile_path = os . path . join ( TEST_ROOT , ' apps ' , ' test ' , ' static ' , ' file2.txt ' )
with open ( self . testfile_path , ' w+ ' ) as f :
f . write ( ' duplicate of file2.txt ' )
os . utime ( self . testfile_path , ( self . orig_atime - 1 , self . orig_mtime - 1 ) )
super ( TestCollectionFilesOverride , self ) . setUp ( )
def tearDown ( self ) :
if os . path . exists ( self . testfile_path ) :
os . unlink ( self . testfile_path )
# set back original modification time
os . utime ( self . orig_path , ( self . orig_atime , self . orig_mtime ) )
2012-03-16 08:29:11 +08:00
super ( TestCollectionFilesOverride , self ) . tearDown ( )
2012-03-02 07:02:38 +08:00
def test_ordering_override ( self ) :
"""
Test if collectstatic takes files in proper order
"""
self . assertFileContains ( ' file2.txt ' , ' duplicate of file2.txt ' )
# run collectstatic again
self . run_collectstatic ( )
self . assertFileContains ( ' file2.txt ' , ' duplicate of file2.txt ' )
# and now change modification time of no_label/static/file2.txt
# test app is first in INSTALLED_APPS so file2.txt should remain unmodified
mtime = os . path . getmtime ( self . testfile_path )
atime = os . path . getatime ( self . testfile_path )
os . utime ( self . orig_path , ( mtime + 1 , atime + 1 ) )
# run collectstatic again
self . run_collectstatic ( )
self . assertFileContains ( ' file2.txt ' , ' duplicate of file2.txt ' )
2012-03-30 17:08:29 +08:00
@override_settings (
2013-02-26 20:19:18 +08:00
STATICFILES_STORAGE = ' staticfiles_tests.storage.DummyStorage ' ,
2012-03-30 17:08:29 +08:00
)
2011-08-11 22:07:39 +08:00
class TestCollectionNonLocalStorage ( CollectionTestCase , TestNoFilesCreated ) :
2011-01-08 18:03:27 +08:00
"""
Tests for #15035
"""
2011-06-30 17:06:19 +08:00
pass
2011-01-08 18:03:27 +08:00
2011-08-11 22:07:39 +08:00
2012-03-30 17:08:29 +08:00
# we set DEBUG to False here since the template tag wouldn't work otherwise
@override_settings ( * * dict ( TEST_SETTINGS ,
STATICFILES_STORAGE = ' django.contrib.staticfiles.storage.CachedStaticFilesStorage ' ,
DEBUG = False ,
) )
2011-08-11 22:07:39 +08:00
class TestCollectionCachedStorage ( BaseCollectionTestCase ,
BaseStaticFilesTestCase , TestCase ) :
"""
Tests for the Cache busting storage
"""
2011-11-03 18:51:02 +08:00
def cached_file_path ( self , path ) :
fullpath = self . render_template ( self . static_template_snippet ( path ) )
2011-08-11 22:07:39 +08:00
return fullpath . replace ( settings . STATIC_URL , ' ' )
def test_template_tag_return ( self ) :
"""
Test the CachedStaticFilesStorage backend .
"""
2011-11-03 18:51:02 +08:00
self . assertStaticRaises ( ValueError ,
" does/not/exist.png " ,
" /static/does/not/exist.png " )
self . assertStaticRenders ( " test/file.txt " ,
2012-03-02 07:02:38 +08:00
" /static/test/file.dad0999e4f8f.txt " )
2012-07-07 21:30:25 +08:00
self . assertStaticRenders ( " test/file.txt " ,
" /static/test/file.dad0999e4f8f.txt " , asvar = True )
2011-11-03 18:51:02 +08:00
self . assertStaticRenders ( " cached/styles.css " ,
" /static/cached/styles.93b1147e8552.css " )
2012-02-16 22:40:32 +08:00
self . assertStaticRenders ( " path/ " ,
" /static/path/ " )
self . assertStaticRenders ( " path/?query " ,
" /static/path/?query " )
2011-08-11 22:07:39 +08:00
def test_template_tag_simple_content ( self ) :
relpath = self . cached_file_path ( " cached/styles.css " )
2011-09-21 23:58:21 +08:00
self . assertEqual ( relpath , " cached/styles.93b1147e8552.css " )
2011-08-11 22:07:39 +08:00
with storage . staticfiles_storage . open ( relpath ) as relfile :
content = relfile . read ( )
2012-05-19 23:43:34 +08:00
self . assertNotIn ( b " cached/other.css " , content )
self . assertIn ( b " other.d41d8cd98f00.css " , content )
2011-11-03 18:51:02 +08:00
2012-07-09 00:25:12 +08:00
def test_path_ignored_completely ( self ) :
relpath = self . cached_file_path ( " cached/css/ignored.css " )
self . assertEqual ( relpath , " cached/css/ignored.6c77f2643390.css " )
with storage . staticfiles_storage . open ( relpath ) as relfile :
content = relfile . read ( )
self . assertIn ( b ' #foobar ' , content )
self . assertIn ( b ' http:foobar ' , content )
self . assertIn ( b ' https:foobar ' , content )
self . assertIn ( b ' data:foobar ' , content )
self . assertIn ( b ' //foobar ' , content )
2011-11-03 18:51:02 +08:00
def test_path_with_querystring ( self ) :
relpath = self . cached_file_path ( " cached/styles.css?spam=eggs " )
self . assertEqual ( relpath ,
" cached/styles.93b1147e8552.css?spam=eggs " )
with storage . staticfiles_storage . open (
" cached/styles.93b1147e8552.css " ) as relfile :
content = relfile . read ( )
2012-05-19 23:43:34 +08:00
self . assertNotIn ( b " cached/other.css " , content )
self . assertIn ( b " other.d41d8cd98f00.css " , content )
2011-11-03 18:51:02 +08:00
def test_path_with_fragment ( self ) :
relpath = self . cached_file_path ( " cached/styles.css#eggs " )
self . assertEqual ( relpath , " cached/styles.93b1147e8552.css#eggs " )
with storage . staticfiles_storage . open (
" cached/styles.93b1147e8552.css " ) as relfile :
content = relfile . read ( )
2012-05-19 23:43:34 +08:00
self . assertNotIn ( b " cached/other.css " , content )
self . assertIn ( b " other.d41d8cd98f00.css " , content )
2011-08-11 22:07:39 +08:00
2011-12-28 06:49:24 +08:00
def test_path_with_querystring_and_fragment ( self ) :
relpath = self . cached_file_path ( " cached/css/fragments.css " )
self . assertEqual ( relpath , " cached/css/fragments.75433540b096.css " )
with storage . staticfiles_storage . open ( relpath ) as relfile :
content = relfile . read ( )
2012-05-19 23:43:34 +08:00
self . assertIn ( b ' fonts/font.a4b0478549d0.eot?#iefix ' , content )
self . assertIn ( b ' fonts/font.b8d603e42714.svg#webfontIyfZbseF ' , content )
self . assertIn ( b ' data:font/woff;charset=utf-8;base64,d09GRgABAAAAADJoAA0AAAAAR2QAAQAAAAAAAAAAAAA ' , content )
self . assertIn ( b ' #default#VML ' , content )
2011-12-28 06:49:24 +08:00
2011-08-11 22:07:39 +08:00
def test_template_tag_absolute ( self ) :
relpath = self . cached_file_path ( " cached/absolute.css " )
2012-03-02 19:29:14 +08:00
self . assertEqual ( relpath , " cached/absolute.23f087ad823a.css " )
2011-08-11 22:07:39 +08:00
with storage . staticfiles_storage . open ( relpath ) as relfile :
content = relfile . read ( )
2012-05-19 23:43:34 +08:00
self . assertNotIn ( b " /static/cached/styles.css " , content )
self . assertIn ( b " /static/cached/styles.93b1147e8552.css " , content )
self . assertIn ( b ' /static/cached/img/relative.acae32e4532b.png ' , content )
2011-08-11 22:07:39 +08:00
def test_template_tag_denorm ( self ) :
relpath = self . cached_file_path ( " cached/denorm.css " )
2012-03-13 11:48:03 +08:00
self . assertEqual ( relpath , " cached/denorm.c5bd139ad821.css " )
2011-08-11 22:07:39 +08:00
with storage . staticfiles_storage . open ( relpath ) as relfile :
content = relfile . read ( )
2012-05-19 23:43:34 +08:00
self . assertNotIn ( b " ..//cached///styles.css " , content )
self . assertIn ( b " ../cached/styles.93b1147e8552.css " , content )
self . assertNotIn ( b " url(img/relative.png ) " , content )
self . assertIn ( b ' url( " img/relative.acae32e4532b.png ' , content )
2011-08-11 22:07:39 +08:00
def test_template_tag_relative ( self ) :
relpath = self . cached_file_path ( " cached/relative.css " )
2011-11-03 18:51:02 +08:00
self . assertEqual ( relpath , " cached/relative.2217ea7273c2.css " )
2011-08-11 22:07:39 +08:00
with storage . staticfiles_storage . open ( relpath ) as relfile :
content = relfile . read ( )
2012-05-19 23:43:34 +08:00
self . assertNotIn ( b " ../cached/styles.css " , content )
self . assertNotIn ( b ' @import " styles.css " ' , content )
self . assertNotIn ( b ' url(img/relative.png) ' , content )
self . assertIn ( b ' url( " img/relative.acae32e4532b.png " ) ' , content )
self . assertIn ( b " ../cached/styles.93b1147e8552.css " , content )
2011-09-21 23:58:21 +08:00
2012-07-09 00:17:53 +08:00
def test_import_replacement ( self ) :
" See #18050 "
relpath = self . cached_file_path ( " cached/import.css " )
self . assertEqual ( relpath , " cached/import.2b1d40b0bbd4.css " )
with storage . staticfiles_storage . open ( relpath ) as relfile :
self . assertIn ( b """ import url( " styles.93b1147e8552.css " ) """ , relfile . read ( ) )
2011-09-21 23:58:21 +08:00
def test_template_tag_deep_relative ( self ) :
relpath = self . cached_file_path ( " cached/css/window.css " )
self . assertEqual ( relpath , " cached/css/window.9db38d5169f3.css " )
with storage . staticfiles_storage . open ( relpath ) as relfile :
content = relfile . read ( )
2012-05-19 23:43:34 +08:00
self . assertNotIn ( b ' url(img/window.png) ' , content )
self . assertIn ( b ' url( " img/window.acae32e4532b.png " ) ' , content )
2011-08-11 22:07:39 +08:00
def test_template_tag_url ( self ) :
relpath = self . cached_file_path ( " cached/url.css " )
self . assertEqual ( relpath , " cached/url.615e21601e4b.css " )
with storage . staticfiles_storage . open ( relpath ) as relfile :
2012-05-19 23:43:34 +08:00
self . assertIn ( b " https:// " , relfile . read ( ) )
2011-08-11 22:07:39 +08:00
2011-11-03 01:45:32 +08:00
def test_cache_invalidation ( self ) :
name = " cached/styles.css "
hashed_name = " cached/styles.93b1147e8552.css "
# check if the cache is filled correctly as expected
cache_key = storage . staticfiles_storage . cache_key ( name )
cached_name = storage . staticfiles_storage . cache . get ( cache_key )
self . assertEqual ( self . cached_file_path ( name ) , cached_name )
# clearing the cache to make sure we re-set it correctly in the url method
storage . staticfiles_storage . cache . clear ( )
cached_name = storage . staticfiles_storage . cache . get ( cache_key )
self . assertEqual ( cached_name , None )
self . assertEqual ( self . cached_file_path ( name ) , hashed_name )
cached_name = storage . staticfiles_storage . cache . get ( cache_key )
self . assertEqual ( cached_name , hashed_name )
2012-02-13 18:51:17 +08:00
def test_post_processing ( self ) :
""" Test that post_processing behaves correctly.
Files that are alterable should always be post - processed ; files that
aren ' t should be skipped.
collectstatic has already been called once in setUp ( ) for this testcase ,
therefore we check by verifying behavior on a second run .
"""
collectstatic_args = {
' interactive ' : False ,
' verbosity ' : ' 0 ' ,
' link ' : False ,
' clear ' : False ,
' dry_run ' : False ,
' post_process ' : True ,
' use_default_ignore_patterns ' : True ,
' ignore_patterns ' : [ ' *.ignoreme ' ] ,
}
collectstatic_cmd = CollectstaticCommand ( )
collectstatic_cmd . set_options ( * * collectstatic_args )
stats = collectstatic_cmd . collect ( )
2012-07-08 18:56:49 +08:00
self . assertIn ( os . path . join ( ' cached ' , ' css ' , ' window.css ' ) , stats [ ' post_processed ' ] )
self . assertIn ( os . path . join ( ' cached ' , ' css ' , ' img ' , ' window.png ' ) , stats [ ' unmodified ' ] )
self . assertIn ( os . path . join ( ' test ' , ' nonascii.css ' ) , stats [ ' post_processed ' ] )
2012-02-13 18:51:17 +08:00
2012-03-13 04:28:09 +08:00
def test_cache_key_memcache_validation ( self ) :
"""
Handle cache key creation correctly , see #17861.
"""
2012-08-14 23:24:31 +08:00
name = " /some crazy/long filename/ with spaces Here and ?# % #$/other/stuff/some crazy/long filename/ with spaces Here and ?# % #$/other/stuff/some crazy/long filename/ with spaces Here and ?# % #$/other/stuff/some crazy/long filename/ with spaces Here and ?# % #$/other/stuff/some crazy/long filename/ with spaces Here and ?# % #$/other/stuff/some crazy/ " + " \x16 " + " \xb4 "
2012-03-13 04:28:09 +08:00
cache_key = storage . staticfiles_storage . cache_key ( name )
cache_validator = BaseCache ( { } )
cache_validator . validate_key ( cache_key )
2012-08-14 23:24:31 +08:00
self . assertEqual ( cache_key , ' staticfiles:821ea71ef36f95b3922a77f7364670e7 ' )
2012-03-13 04:28:09 +08:00
2013-02-24 05:39:37 +08:00
def test_css_import_case_insensitive ( self ) :
relpath = self . cached_file_path ( " cached/styles_insensitive.css " )
self . assertEqual ( relpath , " cached/styles_insensitive.2f0151cca872.css " )
with storage . staticfiles_storage . open ( relpath ) as relfile :
content = relfile . read ( )
self . assertNotIn ( b " cached/other.css " , content )
self . assertIn ( b " other.d41d8cd98f00.css " , content )
2013-04-28 22:45:05 +08:00
@override_settings (
STATICFILES_DIRS = ( os . path . join ( TEST_ROOT , ' project ' , ' faulty ' ) , ) ,
STATICFILES_FINDERS = ( ' django.contrib.staticfiles.finders.FileSystemFinder ' , ) ,
)
def test_post_processing_failure ( self ) :
"""
Test that post_processing indicates the origin of the error when it
fails . Regression test for #18986.
"""
finders . _finders . clear ( )
err = six . StringIO ( )
2013-10-19 20:31:38 +08:00
with self . assertRaises ( Exception ) :
2013-04-28 22:45:05 +08:00
call_command ( ' collectstatic ' , interactive = False , verbosity = 0 , stderr = err )
self . assertEqual ( " Post-processing ' faulty.css ' failed! \n \n " , err . getvalue ( ) )
2012-03-13 04:28:09 +08:00
2012-05-16 19:21:46 +08:00
# we set DEBUG to False here since the template tag wouldn't work otherwise
@override_settings ( * * dict ( TEST_SETTINGS ,
2013-02-26 20:19:18 +08:00
STATICFILES_STORAGE = ' staticfiles_tests.storage.SimpleCachedStaticFilesStorage ' ,
2012-05-16 19:21:46 +08:00
DEBUG = False ,
) )
class TestCollectionSimpleCachedStorage ( BaseCollectionTestCase ,
BaseStaticFilesTestCase , TestCase ) :
"""
Tests for the Cache busting storage
"""
def cached_file_path ( self , path ) :
fullpath = self . render_template ( self . static_template_snippet ( path ) )
return fullpath . replace ( settings . STATIC_URL , ' ' )
def test_template_tag_return ( self ) :
"""
Test the CachedStaticFilesStorage backend .
"""
self . assertStaticRaises ( ValueError ,
" does/not/exist.png " ,
" /static/does/not/exist.png " )
self . assertStaticRenders ( " test/file.txt " ,
" /static/test/file.deploy12345.txt " )
self . assertStaticRenders ( " cached/styles.css " ,
" /static/cached/styles.deploy12345.css " )
self . assertStaticRenders ( " path/ " ,
" /static/path/ " )
self . assertStaticRenders ( " path/?query " ,
" /static/path/?query " )
def test_template_tag_simple_content ( self ) :
relpath = self . cached_file_path ( " cached/styles.css " )
self . assertEqual ( relpath , " cached/styles.deploy12345.css " )
with storage . staticfiles_storage . open ( relpath ) as relfile :
content = relfile . read ( )
2012-08-14 23:24:31 +08:00
self . assertNotIn ( b " cached/other.css " , content )
self . assertIn ( b " other.deploy12345.css " , content )
2012-05-16 19:21:46 +08:00
2010-10-20 09:33:24 +08:00
if sys . platform != ' win32 ' :
2011-08-11 22:07:39 +08:00
class TestCollectionLinks ( CollectionTestCase , TestDefaults ) :
2010-10-20 09:33:24 +08:00
"""
Test ` ` - - link ` ` option for ` ` collectstatic ` ` management command .
Note that by inheriting ` ` TestDefaults ` ` we repeat all
the standard file resolving tests here , to make sure using
` ` - - link ` ` does not change the file - selection semantics .
"""
def run_collectstatic ( self ) :
2011-08-11 22:07:39 +08:00
super ( TestCollectionLinks , self ) . run_collectstatic ( link = True )
2010-10-20 09:33:24 +08:00
def test_links_created ( self ) :
"""
With ` ` - - link ` ` , symbolic links are created .
"""
2010-12-04 15:28:12 +08:00
self . assertTrue ( os . path . islink ( os . path . join ( settings . STATIC_ROOT , ' test.txt ' ) ) )
2010-10-20 09:33:24 +08:00
class TestServeStatic ( StaticFilesTestCase ) :
"""
Test static asset serving view .
"""
2013-02-26 20:19:18 +08:00
urls = ' staticfiles_tests.urls.default '
2010-10-21 11:16:41 +08:00
2010-10-20 09:33:24 +08:00
def _response ( self , filepath ) :
return self . client . get (
2010-11-17 23:36:26 +08:00
posixpath . join ( settings . STATIC_URL , filepath ) )
2010-10-20 09:33:24 +08:00
def assertFileContains ( self , filepath , text ) :
self . assertContains ( self . _response ( filepath ) , text )
def assertFileNotFound ( self , filepath ) :
2011-03-03 23:04:39 +08:00
self . assertEqual ( self . _response ( filepath ) . status_code , 404 )
2010-10-20 09:33:24 +08:00
2010-10-21 11:16:41 +08:00
class TestServeDisabled ( TestServeStatic ) :
"""
2011-02-02 04:39:40 +08:00
Test serving static files disabled when DEBUG is False .
2010-10-21 11:16:41 +08:00
"""
def setUp ( self ) :
super ( TestServeDisabled , self ) . setUp ( )
settings . DEBUG = False
def test_disabled_serving ( self ) :
2013-07-31 15:11:49 +08:00
self . assertFileNotFound ( ' test.txt ' )
2010-10-21 11:16:41 +08:00
2010-10-20 09:33:24 +08:00
class TestServeStaticWithDefaultURL ( TestServeStatic , TestDefaults ) :
"""
2011-02-02 04:39:40 +08:00
Test static asset serving view with manually configured URLconf .
2010-10-20 09:33:24 +08:00
"""
2010-10-21 11:16:41 +08:00
pass
2010-10-20 09:33:24 +08:00
2011-08-11 22:07:39 +08:00
2010-10-20 09:33:24 +08:00
class TestServeStaticWithURLHelper ( TestServeStatic , TestDefaults ) :
"""
Test static asset serving view with staticfiles_urlpatterns helper .
"""
2013-02-26 20:19:18 +08:00
urls = ' staticfiles_tests.urls.helper '
2010-10-20 09:33:24 +08:00
class TestServeAdminMedia ( TestServeStatic ) :
"""
Test serving media from django . contrib . admin .
"""
def _response ( self , filepath ) :
return self . client . get (
2011-06-30 17:06:19 +08:00
posixpath . join ( settings . STATIC_URL , ' admin/ ' , filepath ) )
2010-10-20 09:33:24 +08:00
def test_serve_admin_media ( self ) :
self . assertFileContains ( ' css/base.css ' , ' body ' )
class FinderTestCase ( object ) :
"""
2011-05-27 18:55:07 +08:00
Base finder test mixin .
On Windows , sometimes the case of the path we ask the finders for and the
path ( s ) they find can differ . Compare them using os . path . normcase ( ) to
avoid false negatives .
2010-10-20 09:33:24 +08:00
"""
def test_find_first ( self ) :
src , dst = self . find_first
2011-05-27 18:55:07 +08:00
found = self . finder . find ( src )
self . assertEqual ( os . path . normcase ( found ) , os . path . normcase ( dst ) )
2010-10-20 09:33:24 +08:00
def test_find_all ( self ) :
src , dst = self . find_all
2011-05-27 18:55:07 +08:00
found = self . finder . find ( src , all = True )
found = [ os . path . normcase ( f ) for f in found ]
dst = [ os . path . normcase ( d ) for d in dst ]
self . assertEqual ( found , dst )
2010-10-20 09:33:24 +08:00
class TestFileSystemFinder ( StaticFilesTestCase , FinderTestCase ) :
"""
Test FileSystemFinder .
"""
def setUp ( self ) :
super ( TestFileSystemFinder , self ) . setUp ( )
self . finder = finders . FileSystemFinder ( )
2010-12-31 22:22:32 +08:00
test_file_path = os . path . join ( TEST_ROOT , ' project ' , ' documents ' , ' test ' , ' file.txt ' )
self . find_first = ( os . path . join ( ' test ' , ' file.txt ' ) , test_file_path )
self . find_all = ( os . path . join ( ' test ' , ' file.txt ' ) , [ test_file_path ] )
2010-10-20 09:33:24 +08:00
class TestAppDirectoriesFinder ( StaticFilesTestCase , FinderTestCase ) :
"""
Test AppDirectoriesFinder .
"""
def setUp ( self ) :
super ( TestAppDirectoriesFinder , self ) . setUp ( )
self . finder = finders . AppDirectoriesFinder ( )
2010-12-31 22:22:32 +08:00
test_file_path = os . path . join ( TEST_ROOT , ' apps ' , ' test ' , ' static ' , ' test ' , ' file1.txt ' )
self . find_first = ( os . path . join ( ' test ' , ' file1.txt ' ) , test_file_path )
self . find_all = ( os . path . join ( ' test ' , ' file1.txt ' ) , [ test_file_path ] )
2010-10-20 09:33:24 +08:00
class TestDefaultStorageFinder ( StaticFilesTestCase , FinderTestCase ) :
"""
Test DefaultStorageFinder .
"""
def setUp ( self ) :
super ( TestDefaultStorageFinder , self ) . setUp ( )
self . finder = finders . DefaultStorageFinder (
storage = storage . StaticFilesStorage ( location = settings . MEDIA_ROOT ) )
test_file_path = os . path . join ( settings . MEDIA_ROOT , ' media-file.txt ' )
2010-12-31 22:22:32 +08:00
self . find_first = ( ' media-file.txt ' , test_file_path )
self . find_all = ( ' media-file.txt ' , [ test_file_path ] )
2010-10-20 09:33:24 +08:00
class TestMiscFinder ( TestCase ) :
"""
A few misc finder tests .
"""
def test_get_finder ( self ) :
2011-11-03 18:51:02 +08:00
self . assertIsInstance ( finders . get_finder (
2010-12-31 22:22:32 +08:00
' django.contrib.staticfiles.finders.FileSystemFinder ' ) ,
2011-11-03 18:51:02 +08:00
finders . FileSystemFinder )
2011-02-01 22:57:10 +08:00
def test_get_finder_bad_classname ( self ) :
2011-08-11 22:07:39 +08:00
self . assertRaises ( ImproperlyConfigured , finders . get_finder ,
' django.contrib.staticfiles.finders.FooBarFinder ' )
2011-02-01 22:57:10 +08:00
def test_get_finder_bad_module ( self ) :
2010-10-20 09:33:24 +08:00
self . assertRaises ( ImproperlyConfigured ,
2010-12-31 22:22:32 +08:00
finders . get_finder , ' foo.bar.FooBarFinder ' )
2011-02-01 22:57:10 +08:00
2011-09-21 23:58:32 +08:00
@override_settings ( STATICFILES_DIRS = ' a string ' )
2011-02-01 22:57:10 +08:00
def test_non_tuple_raises_exception ( self ) :
2011-08-11 22:07:39 +08:00
"""
We can ' t determine if STATICFILES_DIRS is set correctly just by
looking at the type , but we can determine if it ' s definitely wrong.
"""
2011-09-21 23:58:32 +08:00
self . assertRaises ( ImproperlyConfigured , finders . FileSystemFinder )
@override_settings ( MEDIA_ROOT = ' ' )
def test_location_empty ( self ) :
self . assertRaises ( ImproperlyConfigured , finders . DefaultStorageFinder )
2011-08-11 22:07:39 +08:00
class TestTemplateTag ( StaticFilesTestCase ) :
2011-06-30 17:06:19 +08:00
2011-08-11 22:07:39 +08:00
def test_template_tag ( self ) :
2011-11-03 18:51:02 +08:00
self . assertStaticRenders ( " does/not/exist.png " ,
" /static/does/not/exist.png " )
self . assertStaticRenders ( " testfile.txt " , " /static/testfile.txt " )
2013-02-24 07:01:45 +08:00
class TestAppStaticStorage ( TestCase ) :
def setUp ( self ) :
# Creates a python module foo_module in a directory with non ascii
# characters
self . search_path = ' search_path_ \xc3 \xbc '
os . mkdir ( self . search_path )
module_path = os . path . join ( self . search_path , ' foo_module ' )
os . mkdir ( module_path )
2013-09-04 01:37:27 +08:00
self . init_file = open ( os . path . join ( module_path , ' __init__.py ' ) , ' w ' )
2013-02-24 07:01:45 +08:00
sys . path . append ( os . path . abspath ( self . search_path ) )
def tearDown ( self ) :
2013-09-04 01:37:27 +08:00
self . init_file . close ( )
2013-02-24 07:01:45 +08:00
sys . path . remove ( os . path . abspath ( self . search_path ) )
shutil . rmtree ( self . search_path )
def test_app_with_non_ascii_characters_in_path ( self ) :
"""
Regression test for #18404 - Tests AppStaticStorage with a module that
has non ascii characters in path and a non utf8 file system encoding
"""
# set file system encoding to a non unicode encoding
old_enc_func = sys . getfilesystemencoding
sys . getfilesystemencoding = lambda : ' ISO-8859-1 '
try :
st = storage . AppStaticStorage ( ' foo_module ' )
st . path ( ' bar ' )
finally :
sys . getfilesystemencoding = old_enc_func