2
0

tests.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. import tempfile
  2. import shutil
  3. import os
  4. import sys
  5. import posixpath
  6. from django.test import TestCase
  7. from django.conf import settings
  8. from django.core.exceptions import ImproperlyConfigured
  9. from django.core.management import call_command
  10. from django.db.models.loading import load_app
  11. from django.template import Template, Context
  12. from django.contrib.staticfiles import finders, storage
  13. TEST_ROOT = os.path.dirname(__file__)
  14. class StaticFilesTestCase(TestCase):
  15. """
  16. Test case with a couple utility assertions.
  17. """
  18. def setUp(self):
  19. self.old_staticfiles_url = settings.STATICFILES_URL
  20. self.old_staticfiles_root = settings.STATICFILES_ROOT
  21. self.old_staticfiles_dirs = settings.STATICFILES_DIRS
  22. self.old_staticfiles_finders = settings.STATICFILES_FINDERS
  23. self.old_installed_apps = settings.INSTALLED_APPS
  24. self.old_media_root = settings.MEDIA_ROOT
  25. self.old_media_url = settings.MEDIA_URL
  26. self.old_admin_media_prefix = settings.ADMIN_MEDIA_PREFIX
  27. # We have to load these apps to test staticfiles.
  28. load_app('regressiontests.staticfiles_tests.apps.test')
  29. load_app('regressiontests.staticfiles_tests.apps.no_label')
  30. site_media = os.path.join(TEST_ROOT, 'project', 'site_media')
  31. settings.MEDIA_ROOT = os.path.join(site_media, 'media')
  32. settings.MEDIA_URL = '/media/'
  33. settings.STATICFILES_ROOT = os.path.join(site_media, 'static')
  34. settings.STATICFILES_URL = '/static/'
  35. settings.ADMIN_MEDIA_PREFIX = '/static/admin/'
  36. settings.STATICFILES_DIRS = (
  37. os.path.join(TEST_ROOT, 'project', 'documents'),
  38. )
  39. settings.STATICFILES_FINDERS = (
  40. 'django.contrib.staticfiles.finders.FileSystemFinder',
  41. 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
  42. 'django.contrib.staticfiles.finders.DefaultStorageFinder',
  43. )
  44. def tearDown(self):
  45. settings.MEDIA_ROOT = self.old_media_root
  46. settings.MEDIA_URL = self.old_media_url
  47. settings.ADMIN_MEDIA_PREFIX = self.old_admin_media_prefix
  48. settings.STATICFILES_ROOT = self.old_staticfiles_root
  49. settings.STATICFILES_URL = self.old_staticfiles_url
  50. settings.STATICFILES_DIRS = self.old_staticfiles_dirs
  51. settings.STATICFILES_FINDERS = self.old_staticfiles_finders
  52. settings.INSTALLED_APPS = self.old_installed_apps
  53. def assertFileContains(self, filepath, text):
  54. self.failUnless(text in self._get_file(filepath),
  55. "'%s' not in '%s'" % (text, filepath))
  56. def assertFileNotFound(self, filepath):
  57. self.assertRaises(IOError, self._get_file, filepath)
  58. class BuildStaticTestCase(StaticFilesTestCase):
  59. """
  60. Tests shared by all file-resolving features (collectstatic,
  61. findstatic, and static serve view).
  62. This relies on the asserts defined in UtilityAssertsTestCase, but
  63. is separated because some test cases need those asserts without
  64. all these tests.
  65. """
  66. def setUp(self):
  67. super(BuildStaticTestCase, self).setUp()
  68. self.old_staticfiles_storage = settings.STATICFILES_STORAGE
  69. self.old_root = settings.STATICFILES_ROOT
  70. settings.STATICFILES_ROOT = tempfile.mkdtemp()
  71. self.run_collectstatic()
  72. def tearDown(self):
  73. shutil.rmtree(settings.STATICFILES_ROOT)
  74. settings.STATICFILES_ROOT = self.old_root
  75. super(BuildStaticTestCase, self).tearDown()
  76. def run_collectstatic(self, **kwargs):
  77. call_command('collectstatic', interactive=False, verbosity='0',
  78. ignore_patterns=['*.ignoreme'], **kwargs)
  79. def _get_file(self, filepath):
  80. assert filepath, 'filepath is empty.'
  81. filepath = os.path.join(settings.STATICFILES_ROOT, filepath)
  82. return open(filepath).read()
  83. class TestDefaults(object):
  84. """
  85. A few standard test cases.
  86. """
  87. def test_staticfiles_dirs(self):
  88. """
  89. Can find a file in a STATICFILES_DIRS directory.
  90. """
  91. self.assertFileContains('test.txt', 'Can we find')
  92. def test_staticfiles_dirs_subdir(self):
  93. """
  94. Can find a file in a subdirectory of a STATICFILES_DIRS
  95. directory.
  96. """
  97. self.assertFileContains('subdir/test.txt', 'Can we find')
  98. def test_staticfiles_dirs_priority(self):
  99. """
  100. File in STATICFILES_DIRS has priority over file in app.
  101. """
  102. self.assertFileContains('test/file.txt', 'STATICFILES_DIRS')
  103. def test_app_files(self):
  104. """
  105. Can find a file in an app media/ directory.
  106. """
  107. self.assertFileContains('test/file1.txt', 'file1 in the app dir')
  108. class TestBuildStatic(BuildStaticTestCase, TestDefaults):
  109. """
  110. Test ``collectstatic`` management command.
  111. """
  112. def test_ignore(self):
  113. """
  114. Test that -i patterns are ignored.
  115. """
  116. self.assertFileNotFound('test/test.ignoreme')
  117. def test_common_ignore_patterns(self):
  118. """
  119. Common ignore patterns (*~, .*, CVS) are ignored.
  120. """
  121. self.assertFileNotFound('test/.hidden')
  122. self.assertFileNotFound('test/backup~')
  123. self.assertFileNotFound('test/CVS')
  124. class TestBuildStaticExcludeNoDefaultIgnore(BuildStaticTestCase, TestDefaults):
  125. """
  126. Test ``--exclude-dirs`` and ``--no-default-ignore`` options for
  127. ``collectstatic`` management command.
  128. """
  129. def run_collectstatic(self):
  130. super(TestBuildStaticExcludeNoDefaultIgnore, self).run_collectstatic(
  131. use_default_ignore_patterns=False)
  132. def test_no_common_ignore_patterns(self):
  133. """
  134. With --no-default-ignore, common ignore patterns (*~, .*, CVS)
  135. are not ignored.
  136. """
  137. self.assertFileContains('test/.hidden', 'should be ignored')
  138. self.assertFileContains('test/backup~', 'should be ignored')
  139. self.assertFileContains('test/CVS', 'should be ignored')
  140. class TestBuildStaticDryRun(BuildStaticTestCase):
  141. """
  142. Test ``--dry-run`` option for ``collectstatic`` management command.
  143. """
  144. def run_collectstatic(self):
  145. super(TestBuildStaticDryRun, self).run_collectstatic(dry_run=True)
  146. def test_no_files_created(self):
  147. """
  148. With --dry-run, no files created in destination dir.
  149. """
  150. self.assertEquals(os.listdir(settings.STATICFILES_ROOT), [])
  151. if sys.platform != 'win32':
  152. class TestBuildStaticLinks(BuildStaticTestCase, TestDefaults):
  153. """
  154. Test ``--link`` option for ``collectstatic`` management command.
  155. Note that by inheriting ``TestDefaults`` we repeat all
  156. the standard file resolving tests here, to make sure using
  157. ``--link`` does not change the file-selection semantics.
  158. """
  159. def run_collectstatic(self):
  160. super(TestBuildStaticLinks, self).run_collectstatic(link=True)
  161. def test_links_created(self):
  162. """
  163. With ``--link``, symbolic links are created.
  164. """
  165. self.failUnless(os.path.islink(os.path.join(settings.STATICFILES_ROOT, 'test.txt')))
  166. class TestServeStatic(StaticFilesTestCase):
  167. """
  168. Test static asset serving view.
  169. """
  170. def _response(self, filepath):
  171. return self.client.get(
  172. posixpath.join(settings.STATICFILES_URL, filepath))
  173. def assertFileContains(self, filepath, text):
  174. self.assertContains(self._response(filepath), text)
  175. def assertFileNotFound(self, filepath):
  176. self.assertEquals(self._response(filepath).status_code, 404)
  177. class TestServeStaticWithDefaultURL(TestServeStatic, TestDefaults):
  178. """
  179. Test static asset serving view with staticfiles_urlpatterns helper.
  180. """
  181. urls = "regressiontests.staticfiles_tests.urls.default"
  182. class TestServeStaticWithURLHelper(TestServeStatic, TestDefaults):
  183. """
  184. Test static asset serving view with staticfiles_urlpatterns helper.
  185. """
  186. urls = "regressiontests.staticfiles_tests.urls.helper"
  187. class TestServeAdminMedia(TestServeStatic):
  188. """
  189. Test serving media from django.contrib.admin.
  190. """
  191. def _response(self, filepath):
  192. return self.client.get(
  193. posixpath.join(settings.ADMIN_MEDIA_PREFIX, filepath))
  194. def test_serve_admin_media(self):
  195. self.assertFileContains('css/base.css', 'body')
  196. class FinderTestCase(object):
  197. """
  198. Base finder test mixin
  199. """
  200. def test_find_first(self):
  201. src, dst = self.find_first
  202. self.assertEquals(self.finder.find(src), dst)
  203. def test_find_all(self):
  204. src, dst = self.find_all
  205. self.assertEquals(self.finder.find(src, all=True), dst)
  206. class TestFileSystemFinder(StaticFilesTestCase, FinderTestCase):
  207. """
  208. Test FileSystemFinder.
  209. """
  210. def setUp(self):
  211. super(TestFileSystemFinder, self).setUp()
  212. self.finder = finders.FileSystemFinder()
  213. test_file_path = os.path.join(TEST_ROOT, 'project/documents/test/file.txt')
  214. self.find_first = ("test/file.txt", test_file_path)
  215. self.find_all = ("test/file.txt", [test_file_path])
  216. class TestAppDirectoriesFinder(StaticFilesTestCase, FinderTestCase):
  217. """
  218. Test AppDirectoriesFinder.
  219. """
  220. def setUp(self):
  221. super(TestAppDirectoriesFinder, self).setUp()
  222. self.finder = finders.AppDirectoriesFinder()
  223. test_file_path = os.path.join(TEST_ROOT, 'apps/test/static/test/file1.txt')
  224. self.find_first = ("test/file1.txt", test_file_path)
  225. self.find_all = ("test/file1.txt", [test_file_path])
  226. class TestDefaultStorageFinder(StaticFilesTestCase, FinderTestCase):
  227. """
  228. Test DefaultStorageFinder.
  229. """
  230. def setUp(self):
  231. super(TestDefaultStorageFinder, self).setUp()
  232. self.finder = finders.DefaultStorageFinder(
  233. storage=storage.StaticFilesStorage(location=settings.MEDIA_ROOT))
  234. test_file_path = os.path.join(settings.MEDIA_ROOT, 'media-file.txt')
  235. self.find_first = ("media-file.txt", test_file_path)
  236. self.find_all = ("media-file.txt", [test_file_path])
  237. class TestMiscFinder(TestCase):
  238. """
  239. A few misc finder tests.
  240. """
  241. def test_get_finder(self):
  242. self.assertTrue(isinstance(finders.get_finder(
  243. "django.contrib.staticfiles.finders.FileSystemFinder"),
  244. finders.FileSystemFinder))
  245. self.assertRaises(ImproperlyConfigured,
  246. finders.get_finder, "django.contrib.staticfiles.finders.FooBarFinder")
  247. self.assertRaises(ImproperlyConfigured,
  248. finders.get_finder, "foo.bar.FooBarFinder")
  249. class TemplateTagTest(TestCase):
  250. def test_get_staticfiles_prefix(self):
  251. """
  252. Test the get_staticfiles_prefix helper return the STATICFILES_URL setting.
  253. """
  254. self.assertEquals(Template(
  255. "{% load staticfiles %}"
  256. "{% get_staticfiles_prefix %}"
  257. ).render(Context()), settings.STATICFILES_URL)
  258. def test_get_staticfiles_prefix_with_as(self):
  259. """
  260. Test the get_staticfiles_prefix helper return the STATICFILES_URL setting.
  261. """
  262. self.assertEquals(Template(
  263. "{% load staticfiles %}"
  264. "{% get_staticfiles_prefix as staticfiles_prefix %}"
  265. "{{ staticfiles_prefix }}"
  266. ).render(Context()), settings.STATICFILES_URL)