tests.py 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375
  1. import os
  2. import unittest
  3. import warnings
  4. from io import StringIO
  5. from unittest import mock
  6. from django.conf import settings
  7. from django.contrib.staticfiles.finders import get_finder, get_finders
  8. from django.contrib.staticfiles.storage import staticfiles_storage
  9. from django.core.exceptions import ImproperlyConfigured
  10. from django.core.files.storage import default_storage
  11. from django.db import connection, connections, models, router
  12. from django.forms import EmailField, IntegerField
  13. from django.http import HttpResponse
  14. from django.template.loader import render_to_string
  15. from django.test import (
  16. SimpleTestCase, TestCase, TransactionTestCase, skipIfDBFeature,
  17. skipUnlessDBFeature,
  18. )
  19. from django.test.html import HTMLParseError, parse_html
  20. from django.test.utils import (
  21. CaptureQueriesContext, TestContextDecorator, isolate_apps,
  22. override_settings, setup_test_environment,
  23. )
  24. from django.urls import NoReverseMatch, path, reverse, reverse_lazy
  25. from .models import Car, Person, PossessedCar
  26. from .views import empty_response
  27. class SkippingTestCase(SimpleTestCase):
  28. def _assert_skipping(self, func, expected_exc, msg=None):
  29. try:
  30. if msg is not None:
  31. with self.assertRaisesMessage(expected_exc, msg):
  32. func()
  33. else:
  34. with self.assertRaises(expected_exc):
  35. func()
  36. except unittest.SkipTest:
  37. self.fail('%s should not result in a skipped test.' % func.__name__)
  38. def test_skip_unless_db_feature(self):
  39. """
  40. Testing the django.test.skipUnlessDBFeature decorator.
  41. """
  42. # Total hack, but it works, just want an attribute that's always true.
  43. @skipUnlessDBFeature("__class__")
  44. def test_func():
  45. raise ValueError
  46. @skipUnlessDBFeature("notprovided")
  47. def test_func2():
  48. raise ValueError
  49. @skipUnlessDBFeature("__class__", "__class__")
  50. def test_func3():
  51. raise ValueError
  52. @skipUnlessDBFeature("__class__", "notprovided")
  53. def test_func4():
  54. raise ValueError
  55. self._assert_skipping(test_func, ValueError)
  56. self._assert_skipping(test_func2, unittest.SkipTest)
  57. self._assert_skipping(test_func3, ValueError)
  58. self._assert_skipping(test_func4, unittest.SkipTest)
  59. class SkipTestCase(SimpleTestCase):
  60. @skipUnlessDBFeature('missing')
  61. def test_foo(self):
  62. pass
  63. self._assert_skipping(
  64. SkipTestCase('test_foo').test_foo,
  65. ValueError,
  66. "skipUnlessDBFeature cannot be used on test_foo (test_utils.tests."
  67. "SkippingTestCase.test_skip_unless_db_feature.<locals>.SkipTestCase) "
  68. "as SkippingTestCase.test_skip_unless_db_feature.<locals>.SkipTestCase "
  69. "doesn't allow queries against the 'default' database."
  70. )
  71. def test_skip_if_db_feature(self):
  72. """
  73. Testing the django.test.skipIfDBFeature decorator.
  74. """
  75. @skipIfDBFeature("__class__")
  76. def test_func():
  77. raise ValueError
  78. @skipIfDBFeature("notprovided")
  79. def test_func2():
  80. raise ValueError
  81. @skipIfDBFeature("__class__", "__class__")
  82. def test_func3():
  83. raise ValueError
  84. @skipIfDBFeature("__class__", "notprovided")
  85. def test_func4():
  86. raise ValueError
  87. @skipIfDBFeature("notprovided", "notprovided")
  88. def test_func5():
  89. raise ValueError
  90. self._assert_skipping(test_func, unittest.SkipTest)
  91. self._assert_skipping(test_func2, ValueError)
  92. self._assert_skipping(test_func3, unittest.SkipTest)
  93. self._assert_skipping(test_func4, unittest.SkipTest)
  94. self._assert_skipping(test_func5, ValueError)
  95. class SkipTestCase(SimpleTestCase):
  96. @skipIfDBFeature('missing')
  97. def test_foo(self):
  98. pass
  99. self._assert_skipping(
  100. SkipTestCase('test_foo').test_foo,
  101. ValueError,
  102. "skipIfDBFeature cannot be used on test_foo (test_utils.tests."
  103. "SkippingTestCase.test_skip_if_db_feature.<locals>.SkipTestCase) "
  104. "as SkippingTestCase.test_skip_if_db_feature.<locals>.SkipTestCase "
  105. "doesn't allow queries against the 'default' database."
  106. )
  107. class SkippingClassTestCase(TestCase):
  108. def test_skip_class_unless_db_feature(self):
  109. @skipUnlessDBFeature("__class__")
  110. class NotSkippedTests(TestCase):
  111. def test_dummy(self):
  112. return
  113. @skipUnlessDBFeature("missing")
  114. @skipIfDBFeature("__class__")
  115. class SkippedTests(TestCase):
  116. def test_will_be_skipped(self):
  117. self.fail("We should never arrive here.")
  118. @skipIfDBFeature("__dict__")
  119. class SkippedTestsSubclass(SkippedTests):
  120. pass
  121. test_suite = unittest.TestSuite()
  122. test_suite.addTest(NotSkippedTests('test_dummy'))
  123. try:
  124. test_suite.addTest(SkippedTests('test_will_be_skipped'))
  125. test_suite.addTest(SkippedTestsSubclass('test_will_be_skipped'))
  126. except unittest.SkipTest:
  127. self.fail('SkipTest should not be raised here.')
  128. result = unittest.TextTestRunner(stream=StringIO()).run(test_suite)
  129. self.assertEqual(result.testsRun, 3)
  130. self.assertEqual(len(result.skipped), 2)
  131. self.assertEqual(result.skipped[0][1], 'Database has feature(s) __class__')
  132. self.assertEqual(result.skipped[1][1], 'Database has feature(s) __class__')
  133. def test_missing_default_databases(self):
  134. @skipIfDBFeature('missing')
  135. class MissingDatabases(SimpleTestCase):
  136. def test_assertion_error(self):
  137. pass
  138. suite = unittest.TestSuite()
  139. try:
  140. suite.addTest(MissingDatabases('test_assertion_error'))
  141. except unittest.SkipTest:
  142. self.fail("SkipTest should not be raised at this stage")
  143. runner = unittest.TextTestRunner(stream=StringIO())
  144. msg = (
  145. "skipIfDBFeature cannot be used on <class 'test_utils.tests."
  146. "SkippingClassTestCase.test_missing_default_databases.<locals>."
  147. "MissingDatabases'> as it doesn't allow queries against the "
  148. "'default' database."
  149. )
  150. with self.assertRaisesMessage(ValueError, msg):
  151. runner.run(suite)
  152. @override_settings(ROOT_URLCONF='test_utils.urls')
  153. class AssertNumQueriesTests(TestCase):
  154. def test_assert_num_queries(self):
  155. def test_func():
  156. raise ValueError
  157. with self.assertRaises(ValueError):
  158. self.assertNumQueries(2, test_func)
  159. def test_assert_num_queries_with_client(self):
  160. person = Person.objects.create(name='test')
  161. self.assertNumQueries(
  162. 1,
  163. self.client.get,
  164. "/test_utils/get_person/%s/" % person.pk
  165. )
  166. self.assertNumQueries(
  167. 1,
  168. self.client.get,
  169. "/test_utils/get_person/%s/" % person.pk
  170. )
  171. def test_func():
  172. self.client.get("/test_utils/get_person/%s/" % person.pk)
  173. self.client.get("/test_utils/get_person/%s/" % person.pk)
  174. self.assertNumQueries(2, test_func)
  175. @unittest.skipUnless(
  176. connection.vendor != 'sqlite' or not connection.is_in_memory_db(),
  177. 'For SQLite in-memory tests, closing the connection destroys the database.'
  178. )
  179. class AssertNumQueriesUponConnectionTests(TransactionTestCase):
  180. available_apps = []
  181. def test_ignores_connection_configuration_queries(self):
  182. real_ensure_connection = connection.ensure_connection
  183. connection.close()
  184. def make_configuration_query():
  185. is_opening_connection = connection.connection is None
  186. real_ensure_connection()
  187. if is_opening_connection:
  188. # Avoid infinite recursion. Creating a cursor calls
  189. # ensure_connection() which is currently mocked by this method.
  190. connection.cursor().execute('SELECT 1' + connection.features.bare_select_suffix)
  191. ensure_connection = 'django.db.backends.base.base.BaseDatabaseWrapper.ensure_connection'
  192. with mock.patch(ensure_connection, side_effect=make_configuration_query):
  193. with self.assertNumQueries(1):
  194. list(Car.objects.all())
  195. class AssertQuerysetEqualTests(TestCase):
  196. @classmethod
  197. def setUpTestData(cls):
  198. cls.p1 = Person.objects.create(name='p1')
  199. cls.p2 = Person.objects.create(name='p2')
  200. def test_ordered(self):
  201. self.assertQuerysetEqual(
  202. Person.objects.all().order_by('name'),
  203. [repr(self.p1), repr(self.p2)]
  204. )
  205. def test_unordered(self):
  206. self.assertQuerysetEqual(
  207. Person.objects.all().order_by('name'),
  208. [repr(self.p2), repr(self.p1)],
  209. ordered=False
  210. )
  211. def test_transform(self):
  212. self.assertQuerysetEqual(
  213. Person.objects.all().order_by('name'),
  214. [self.p1.pk, self.p2.pk],
  215. transform=lambda x: x.pk
  216. )
  217. def test_undefined_order(self):
  218. # Using an unordered queryset with more than one ordered value
  219. # is an error.
  220. msg = 'Trying to compare non-ordered queryset against more than one ordered values'
  221. with self.assertRaisesMessage(ValueError, msg):
  222. self.assertQuerysetEqual(
  223. Person.objects.all(),
  224. [repr(self.p1), repr(self.p2)]
  225. )
  226. # No error for one value.
  227. self.assertQuerysetEqual(
  228. Person.objects.filter(name='p1'),
  229. [repr(self.p1)]
  230. )
  231. def test_repeated_values(self):
  232. """
  233. assertQuerysetEqual checks the number of appearance of each item
  234. when used with option ordered=False.
  235. """
  236. batmobile = Car.objects.create(name='Batmobile')
  237. k2000 = Car.objects.create(name='K 2000')
  238. PossessedCar.objects.bulk_create([
  239. PossessedCar(car=batmobile, belongs_to=self.p1),
  240. PossessedCar(car=batmobile, belongs_to=self.p1),
  241. PossessedCar(car=k2000, belongs_to=self.p1),
  242. PossessedCar(car=k2000, belongs_to=self.p1),
  243. PossessedCar(car=k2000, belongs_to=self.p1),
  244. PossessedCar(car=k2000, belongs_to=self.p1),
  245. ])
  246. with self.assertRaises(AssertionError):
  247. self.assertQuerysetEqual(
  248. self.p1.cars.all(),
  249. [repr(batmobile), repr(k2000)],
  250. ordered=False
  251. )
  252. self.assertQuerysetEqual(
  253. self.p1.cars.all(),
  254. [repr(batmobile)] * 2 + [repr(k2000)] * 4,
  255. ordered=False
  256. )
  257. @override_settings(ROOT_URLCONF='test_utils.urls')
  258. class CaptureQueriesContextManagerTests(TestCase):
  259. @classmethod
  260. def setUpTestData(cls):
  261. cls.person_pk = str(Person.objects.create(name='test').pk)
  262. def test_simple(self):
  263. with CaptureQueriesContext(connection) as captured_queries:
  264. Person.objects.get(pk=self.person_pk)
  265. self.assertEqual(len(captured_queries), 1)
  266. self.assertIn(self.person_pk, captured_queries[0]['sql'])
  267. with CaptureQueriesContext(connection) as captured_queries:
  268. pass
  269. self.assertEqual(0, len(captured_queries))
  270. def test_within(self):
  271. with CaptureQueriesContext(connection) as captured_queries:
  272. Person.objects.get(pk=self.person_pk)
  273. self.assertEqual(len(captured_queries), 1)
  274. self.assertIn(self.person_pk, captured_queries[0]['sql'])
  275. def test_nested(self):
  276. with CaptureQueriesContext(connection) as captured_queries:
  277. Person.objects.count()
  278. with CaptureQueriesContext(connection) as nested_captured_queries:
  279. Person.objects.count()
  280. self.assertEqual(1, len(nested_captured_queries))
  281. self.assertEqual(2, len(captured_queries))
  282. def test_failure(self):
  283. with self.assertRaises(TypeError):
  284. with CaptureQueriesContext(connection):
  285. raise TypeError
  286. def test_with_client(self):
  287. with CaptureQueriesContext(connection) as captured_queries:
  288. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  289. self.assertEqual(len(captured_queries), 1)
  290. self.assertIn(self.person_pk, captured_queries[0]['sql'])
  291. with CaptureQueriesContext(connection) as captured_queries:
  292. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  293. self.assertEqual(len(captured_queries), 1)
  294. self.assertIn(self.person_pk, captured_queries[0]['sql'])
  295. with CaptureQueriesContext(connection) as captured_queries:
  296. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  297. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  298. self.assertEqual(len(captured_queries), 2)
  299. self.assertIn(self.person_pk, captured_queries[0]['sql'])
  300. self.assertIn(self.person_pk, captured_queries[1]['sql'])
  301. @override_settings(ROOT_URLCONF='test_utils.urls')
  302. class AssertNumQueriesContextManagerTests(TestCase):
  303. def test_simple(self):
  304. with self.assertNumQueries(0):
  305. pass
  306. with self.assertNumQueries(1):
  307. Person.objects.count()
  308. with self.assertNumQueries(2):
  309. Person.objects.count()
  310. Person.objects.count()
  311. def test_failure(self):
  312. with self.assertRaises(AssertionError) as exc_info:
  313. with self.assertNumQueries(2):
  314. Person.objects.count()
  315. exc_lines = str(exc_info.exception).split('\n')
  316. self.assertEqual(exc_lines[0], '1 != 2 : 1 queries executed, 2 expected')
  317. self.assertEqual(exc_lines[1], 'Captured queries were:')
  318. self.assertTrue(exc_lines[2].startswith('1.')) # queries are numbered
  319. with self.assertRaises(TypeError):
  320. with self.assertNumQueries(4000):
  321. raise TypeError
  322. def test_with_client(self):
  323. person = Person.objects.create(name="test")
  324. with self.assertNumQueries(1):
  325. self.client.get("/test_utils/get_person/%s/" % person.pk)
  326. with self.assertNumQueries(1):
  327. self.client.get("/test_utils/get_person/%s/" % person.pk)
  328. with self.assertNumQueries(2):
  329. self.client.get("/test_utils/get_person/%s/" % person.pk)
  330. self.client.get("/test_utils/get_person/%s/" % person.pk)
  331. @override_settings(ROOT_URLCONF='test_utils.urls')
  332. class AssertTemplateUsedContextManagerTests(SimpleTestCase):
  333. def test_usage(self):
  334. with self.assertTemplateUsed('template_used/base.html'):
  335. render_to_string('template_used/base.html')
  336. with self.assertTemplateUsed(template_name='template_used/base.html'):
  337. render_to_string('template_used/base.html')
  338. with self.assertTemplateUsed('template_used/base.html'):
  339. render_to_string('template_used/include.html')
  340. with self.assertTemplateUsed('template_used/base.html'):
  341. render_to_string('template_used/extends.html')
  342. with self.assertTemplateUsed('template_used/base.html'):
  343. render_to_string('template_used/base.html')
  344. render_to_string('template_used/base.html')
  345. def test_nested_usage(self):
  346. with self.assertTemplateUsed('template_used/base.html'):
  347. with self.assertTemplateUsed('template_used/include.html'):
  348. render_to_string('template_used/include.html')
  349. with self.assertTemplateUsed('template_used/extends.html'):
  350. with self.assertTemplateUsed('template_used/base.html'):
  351. render_to_string('template_used/extends.html')
  352. with self.assertTemplateUsed('template_used/base.html'):
  353. with self.assertTemplateUsed('template_used/alternative.html'):
  354. render_to_string('template_used/alternative.html')
  355. render_to_string('template_used/base.html')
  356. with self.assertTemplateUsed('template_used/base.html'):
  357. render_to_string('template_used/extends.html')
  358. with self.assertTemplateNotUsed('template_used/base.html'):
  359. render_to_string('template_used/alternative.html')
  360. render_to_string('template_used/base.html')
  361. def test_not_used(self):
  362. with self.assertTemplateNotUsed('template_used/base.html'):
  363. pass
  364. with self.assertTemplateNotUsed('template_used/alternative.html'):
  365. pass
  366. def test_error_message(self):
  367. msg = 'template_used/base.html was not rendered. No template was rendered.'
  368. with self.assertRaisesMessage(AssertionError, msg):
  369. with self.assertTemplateUsed('template_used/base.html'):
  370. pass
  371. with self.assertRaisesMessage(AssertionError, msg):
  372. with self.assertTemplateUsed(template_name='template_used/base.html'):
  373. pass
  374. msg2 = (
  375. 'template_used/base.html was not rendered. Following templates '
  376. 'were rendered: template_used/alternative.html'
  377. )
  378. with self.assertRaisesMessage(AssertionError, msg2):
  379. with self.assertTemplateUsed('template_used/base.html'):
  380. render_to_string('template_used/alternative.html')
  381. with self.assertRaisesMessage(AssertionError, 'No templates used to render the response'):
  382. response = self.client.get('/test_utils/no_template_used/')
  383. self.assertTemplateUsed(response, 'template_used/base.html')
  384. def test_failure(self):
  385. msg = 'response and/or template_name argument must be provided'
  386. with self.assertRaisesMessage(TypeError, msg):
  387. with self.assertTemplateUsed():
  388. pass
  389. msg = 'No templates used to render the response'
  390. with self.assertRaisesMessage(AssertionError, msg):
  391. with self.assertTemplateUsed(''):
  392. pass
  393. with self.assertRaisesMessage(AssertionError, msg):
  394. with self.assertTemplateUsed(''):
  395. render_to_string('template_used/base.html')
  396. with self.assertRaisesMessage(AssertionError, msg):
  397. with self.assertTemplateUsed(template_name=''):
  398. pass
  399. msg = (
  400. 'template_used/base.html was not rendered. Following '
  401. 'templates were rendered: template_used/alternative.html'
  402. )
  403. with self.assertRaisesMessage(AssertionError, msg):
  404. with self.assertTemplateUsed('template_used/base.html'):
  405. render_to_string('template_used/alternative.html')
  406. def test_assert_used_on_http_response(self):
  407. response = HttpResponse()
  408. error_msg = (
  409. 'assertTemplateUsed() and assertTemplateNotUsed() are only '
  410. 'usable on responses fetched using the Django test Client.'
  411. )
  412. with self.assertRaisesMessage(ValueError, error_msg):
  413. self.assertTemplateUsed(response, 'template.html')
  414. with self.assertRaisesMessage(ValueError, error_msg):
  415. self.assertTemplateNotUsed(response, 'template.html')
  416. class HTMLEqualTests(SimpleTestCase):
  417. def test_html_parser(self):
  418. element = parse_html('<div><p>Hello</p></div>')
  419. self.assertEqual(len(element.children), 1)
  420. self.assertEqual(element.children[0].name, 'p')
  421. self.assertEqual(element.children[0].children[0], 'Hello')
  422. parse_html('<p>')
  423. parse_html('<p attr>')
  424. dom = parse_html('<p>foo')
  425. self.assertEqual(len(dom.children), 1)
  426. self.assertEqual(dom.name, 'p')
  427. self.assertEqual(dom[0], 'foo')
  428. def test_parse_html_in_script(self):
  429. parse_html('<script>var a = "<p" + ">";</script>')
  430. parse_html('''
  431. <script>
  432. var js_sha_link='<p>***</p>';
  433. </script>
  434. ''')
  435. # script content will be parsed to text
  436. dom = parse_html('''
  437. <script><p>foo</p> '</scr'+'ipt>' <span>bar</span></script>
  438. ''')
  439. self.assertEqual(len(dom.children), 1)
  440. self.assertEqual(dom.children[0], "<p>foo</p> '</scr'+'ipt>' <span>bar</span>")
  441. def test_self_closing_tags(self):
  442. self_closing_tags = (
  443. 'br', 'hr', 'input', 'img', 'meta', 'spacer', 'link', 'frame',
  444. 'base', 'col',
  445. )
  446. for tag in self_closing_tags:
  447. dom = parse_html('<p>Hello <%s> world</p>' % tag)
  448. self.assertEqual(len(dom.children), 3)
  449. self.assertEqual(dom[0], 'Hello')
  450. self.assertEqual(dom[1].name, tag)
  451. self.assertEqual(dom[2], 'world')
  452. dom = parse_html('<p>Hello <%s /> world</p>' % tag)
  453. self.assertEqual(len(dom.children), 3)
  454. self.assertEqual(dom[0], 'Hello')
  455. self.assertEqual(dom[1].name, tag)
  456. self.assertEqual(dom[2], 'world')
  457. def test_simple_equal_html(self):
  458. self.assertHTMLEqual('', '')
  459. self.assertHTMLEqual('<p></p>', '<p></p>')
  460. self.assertHTMLEqual('<p></p>', ' <p> </p> ')
  461. self.assertHTMLEqual(
  462. '<div><p>Hello</p></div>',
  463. '<div><p>Hello</p></div>')
  464. self.assertHTMLEqual(
  465. '<div><p>Hello</p></div>',
  466. '<div> <p>Hello</p> </div>')
  467. self.assertHTMLEqual(
  468. '<div>\n<p>Hello</p></div>',
  469. '<div><p>Hello</p></div>\n')
  470. self.assertHTMLEqual(
  471. '<div><p>Hello\nWorld !</p></div>',
  472. '<div><p>Hello World\n!</p></div>')
  473. self.assertHTMLEqual(
  474. '<div><p>Hello\nWorld !</p></div>',
  475. '<div><p>Hello World\n!</p></div>')
  476. self.assertHTMLEqual(
  477. '<p>Hello World !</p>',
  478. '<p>Hello World\n\n!</p>')
  479. self.assertHTMLEqual('<p> </p>', '<p></p>')
  480. self.assertHTMLEqual('<p/>', '<p></p>')
  481. self.assertHTMLEqual('<p />', '<p></p>')
  482. self.assertHTMLEqual('<input checked>', '<input checked="checked">')
  483. self.assertHTMLEqual('<p>Hello', '<p> Hello')
  484. self.assertHTMLEqual('<p>Hello</p>World', '<p>Hello</p> World')
  485. def test_ignore_comments(self):
  486. self.assertHTMLEqual(
  487. '<div>Hello<!-- this is a comment --> World!</div>',
  488. '<div>Hello World!</div>')
  489. def test_unequal_html(self):
  490. self.assertHTMLNotEqual('<p>Hello</p>', '<p>Hello!</p>')
  491. self.assertHTMLNotEqual('<p>foo&#20;bar</p>', '<p>foo&nbsp;bar</p>')
  492. self.assertHTMLNotEqual('<p>foo bar</p>', '<p>foo &nbsp;bar</p>')
  493. self.assertHTMLNotEqual('<p>foo nbsp</p>', '<p>foo &nbsp;</p>')
  494. self.assertHTMLNotEqual('<p>foo #20</p>', '<p>foo &#20;</p>')
  495. self.assertHTMLNotEqual(
  496. '<p><span>Hello</span><span>World</span></p>',
  497. '<p><span>Hello</span>World</p>')
  498. self.assertHTMLNotEqual(
  499. '<p><span>Hello</span>World</p>',
  500. '<p><span>Hello</span><span>World</span></p>')
  501. def test_attributes(self):
  502. self.assertHTMLEqual(
  503. '<input type="text" id="id_name" />',
  504. '<input id="id_name" type="text" />')
  505. self.assertHTMLEqual(
  506. '''<input type='text' id="id_name" />''',
  507. '<input id="id_name" type="text" />')
  508. self.assertHTMLNotEqual(
  509. '<input type="text" id="id_name" />',
  510. '<input type="password" id="id_name" />')
  511. def test_normalize_refs(self):
  512. pairs = [
  513. ('&#39;', '&#x27;'),
  514. ('&#39;', "'"),
  515. ('&#x27;', '&#39;'),
  516. ('&#x27;', "'"),
  517. ("'", '&#39;'),
  518. ("'", '&#x27;'),
  519. ('&amp;', '&#38;'),
  520. ('&amp;', '&#x26;'),
  521. ('&amp;', '&'),
  522. ('&#38;', '&amp;'),
  523. ('&#38;', '&#x26;'),
  524. ('&#38;', '&'),
  525. ('&#x26;', '&amp;'),
  526. ('&#x26;', '&#38;'),
  527. ('&#x26;', '&'),
  528. ('&', '&amp;'),
  529. ('&', '&#38;'),
  530. ('&', '&#x26;'),
  531. ]
  532. for pair in pairs:
  533. with self.subTest(repr(pair)):
  534. self.assertHTMLEqual(*pair)
  535. def test_complex_examples(self):
  536. self.assertHTMLEqual(
  537. """<tr><th><label for="id_first_name">First name:</label></th>
  538. <td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>
  539. <tr><th><label for="id_last_name">Last name:</label></th>
  540. <td><input type="text" id="id_last_name" name="last_name" value="Lennon" /></td></tr>
  541. <tr><th><label for="id_birthday">Birthday:</label></th>
  542. <td><input type="text" value="1940-10-9" name="birthday" id="id_birthday" /></td></tr>""",
  543. """
  544. <tr><th>
  545. <label for="id_first_name">First name:</label></th><td>
  546. <input type="text" name="first_name" value="John" id="id_first_name" />
  547. </td></tr>
  548. <tr><th>
  549. <label for="id_last_name">Last name:</label></th><td>
  550. <input type="text" name="last_name" value="Lennon" id="id_last_name" />
  551. </td></tr>
  552. <tr><th>
  553. <label for="id_birthday">Birthday:</label></th><td>
  554. <input type="text" name="birthday" value="1940-10-9" id="id_birthday" />
  555. </td></tr>
  556. """)
  557. self.assertHTMLEqual(
  558. """<!DOCTYPE html>
  559. <html>
  560. <head>
  561. <link rel="stylesheet">
  562. <title>Document</title>
  563. <meta attribute="value">
  564. </head>
  565. <body>
  566. <p>
  567. This is a valid paragraph
  568. <div> this is a div AFTER the p</div>
  569. </body>
  570. </html>""", """
  571. <html>
  572. <head>
  573. <link rel="stylesheet">
  574. <title>Document</title>
  575. <meta attribute="value">
  576. </head>
  577. <body>
  578. <p> This is a valid paragraph
  579. <!-- browsers would close the p tag here -->
  580. <div> this is a div AFTER the p</div>
  581. </p> <!-- this is invalid HTML parsing, but it should make no
  582. difference in most cases -->
  583. </body>
  584. </html>""")
  585. def test_html_contain(self):
  586. # equal html contains each other
  587. dom1 = parse_html('<p>foo')
  588. dom2 = parse_html('<p>foo</p>')
  589. self.assertIn(dom1, dom2)
  590. self.assertIn(dom2, dom1)
  591. dom2 = parse_html('<div><p>foo</p></div>')
  592. self.assertIn(dom1, dom2)
  593. self.assertNotIn(dom2, dom1)
  594. self.assertNotIn('<p>foo</p>', dom2)
  595. self.assertIn('foo', dom2)
  596. # when a root element is used ...
  597. dom1 = parse_html('<p>foo</p><p>bar</p>')
  598. dom2 = parse_html('<p>foo</p><p>bar</p>')
  599. self.assertIn(dom1, dom2)
  600. dom1 = parse_html('<p>foo</p>')
  601. self.assertIn(dom1, dom2)
  602. dom1 = parse_html('<p>bar</p>')
  603. self.assertIn(dom1, dom2)
  604. dom1 = parse_html('<div><p>foo</p><p>bar</p></div>')
  605. self.assertIn(dom2, dom1)
  606. def test_count(self):
  607. # equal html contains each other one time
  608. dom1 = parse_html('<p>foo')
  609. dom2 = parse_html('<p>foo</p>')
  610. self.assertEqual(dom1.count(dom2), 1)
  611. self.assertEqual(dom2.count(dom1), 1)
  612. dom2 = parse_html('<p>foo</p><p>bar</p>')
  613. self.assertEqual(dom2.count(dom1), 1)
  614. dom2 = parse_html('<p>foo foo</p><p>foo</p>')
  615. self.assertEqual(dom2.count('foo'), 3)
  616. dom2 = parse_html('<p class="bar">foo</p>')
  617. self.assertEqual(dom2.count('bar'), 0)
  618. self.assertEqual(dom2.count('class'), 0)
  619. self.assertEqual(dom2.count('p'), 0)
  620. self.assertEqual(dom2.count('o'), 2)
  621. dom2 = parse_html('<p>foo</p><p>foo</p>')
  622. self.assertEqual(dom2.count(dom1), 2)
  623. dom2 = parse_html('<div><p>foo<input type=""></p><p>foo</p></div>')
  624. self.assertEqual(dom2.count(dom1), 1)
  625. dom2 = parse_html('<div><div><p>foo</p></div></div>')
  626. self.assertEqual(dom2.count(dom1), 1)
  627. dom2 = parse_html('<p>foo<p>foo</p></p>')
  628. self.assertEqual(dom2.count(dom1), 1)
  629. dom2 = parse_html('<p>foo<p>bar</p></p>')
  630. self.assertEqual(dom2.count(dom1), 0)
  631. # html with a root element contains the same html with no root element
  632. dom1 = parse_html('<p>foo</p><p>bar</p>')
  633. dom2 = parse_html('<div><p>foo</p><p>bar</p></div>')
  634. self.assertEqual(dom2.count(dom1), 1)
  635. def test_parsing_errors(self):
  636. with self.assertRaises(AssertionError):
  637. self.assertHTMLEqual('<p>', '')
  638. with self.assertRaises(AssertionError):
  639. self.assertHTMLEqual('', '<p>')
  640. error_msg = (
  641. "First argument is not valid HTML:\n"
  642. "('Unexpected end tag `div` (Line 1, Column 6)', (1, 6))"
  643. )
  644. with self.assertRaisesMessage(AssertionError, error_msg):
  645. self.assertHTMLEqual('< div></ div>', '<div></div>')
  646. with self.assertRaises(HTMLParseError):
  647. parse_html('</p>')
  648. def test_contains_html(self):
  649. response = HttpResponse('''<body>
  650. This is a form: <form method="get">
  651. <input type="text" name="Hello" />
  652. </form></body>''')
  653. self.assertNotContains(response, "<input name='Hello' type='text'>")
  654. self.assertContains(response, '<form method="get">')
  655. self.assertContains(response, "<input name='Hello' type='text'>", html=True)
  656. self.assertNotContains(response, '<form method="get">', html=True)
  657. invalid_response = HttpResponse('''<body <bad>>''')
  658. with self.assertRaises(AssertionError):
  659. self.assertContains(invalid_response, '<p></p>')
  660. with self.assertRaises(AssertionError):
  661. self.assertContains(response, '<p "whats" that>')
  662. def test_unicode_handling(self):
  663. response = HttpResponse('<p class="help">Some help text for the title (with unicode ŠĐĆŽćžšđ)</p>')
  664. self.assertContains(
  665. response,
  666. '<p class="help">Some help text for the title (with unicode ŠĐĆŽćžšđ)</p>',
  667. html=True
  668. )
  669. class JSONEqualTests(SimpleTestCase):
  670. def test_simple_equal(self):
  671. json1 = '{"attr1": "foo", "attr2":"baz"}'
  672. json2 = '{"attr1": "foo", "attr2":"baz"}'
  673. self.assertJSONEqual(json1, json2)
  674. def test_simple_equal_unordered(self):
  675. json1 = '{"attr1": "foo", "attr2":"baz"}'
  676. json2 = '{"attr2":"baz", "attr1": "foo"}'
  677. self.assertJSONEqual(json1, json2)
  678. def test_simple_equal_raise(self):
  679. json1 = '{"attr1": "foo", "attr2":"baz"}'
  680. json2 = '{"attr2":"baz"}'
  681. with self.assertRaises(AssertionError):
  682. self.assertJSONEqual(json1, json2)
  683. def test_equal_parsing_errors(self):
  684. invalid_json = '{"attr1": "foo, "attr2":"baz"}'
  685. valid_json = '{"attr1": "foo", "attr2":"baz"}'
  686. with self.assertRaises(AssertionError):
  687. self.assertJSONEqual(invalid_json, valid_json)
  688. with self.assertRaises(AssertionError):
  689. self.assertJSONEqual(valid_json, invalid_json)
  690. def test_simple_not_equal(self):
  691. json1 = '{"attr1": "foo", "attr2":"baz"}'
  692. json2 = '{"attr2":"baz"}'
  693. self.assertJSONNotEqual(json1, json2)
  694. def test_simple_not_equal_raise(self):
  695. json1 = '{"attr1": "foo", "attr2":"baz"}'
  696. json2 = '{"attr1": "foo", "attr2":"baz"}'
  697. with self.assertRaises(AssertionError):
  698. self.assertJSONNotEqual(json1, json2)
  699. def test_not_equal_parsing_errors(self):
  700. invalid_json = '{"attr1": "foo, "attr2":"baz"}'
  701. valid_json = '{"attr1": "foo", "attr2":"baz"}'
  702. with self.assertRaises(AssertionError):
  703. self.assertJSONNotEqual(invalid_json, valid_json)
  704. with self.assertRaises(AssertionError):
  705. self.assertJSONNotEqual(valid_json, invalid_json)
  706. class XMLEqualTests(SimpleTestCase):
  707. def test_simple_equal(self):
  708. xml1 = "<elem attr1='a' attr2='b' />"
  709. xml2 = "<elem attr1='a' attr2='b' />"
  710. self.assertXMLEqual(xml1, xml2)
  711. def test_simple_equal_unordered(self):
  712. xml1 = "<elem attr1='a' attr2='b' />"
  713. xml2 = "<elem attr2='b' attr1='a' />"
  714. self.assertXMLEqual(xml1, xml2)
  715. def test_simple_equal_raise(self):
  716. xml1 = "<elem attr1='a' />"
  717. xml2 = "<elem attr2='b' attr1='a' />"
  718. with self.assertRaises(AssertionError):
  719. self.assertXMLEqual(xml1, xml2)
  720. def test_simple_equal_raises_message(self):
  721. xml1 = "<elem attr1='a' />"
  722. xml2 = "<elem attr2='b' attr1='a' />"
  723. msg = '''{xml1} != {xml2}
  724. - <elem attr1='a' />
  725. + <elem attr2='b' attr1='a' />
  726. ? ++++++++++
  727. '''.format(xml1=repr(xml1), xml2=repr(xml2))
  728. with self.assertRaisesMessage(AssertionError, msg):
  729. self.assertXMLEqual(xml1, xml2)
  730. def test_simple_not_equal(self):
  731. xml1 = "<elem attr1='a' attr2='c' />"
  732. xml2 = "<elem attr1='a' attr2='b' />"
  733. self.assertXMLNotEqual(xml1, xml2)
  734. def test_simple_not_equal_raise(self):
  735. xml1 = "<elem attr1='a' attr2='b' />"
  736. xml2 = "<elem attr2='b' attr1='a' />"
  737. with self.assertRaises(AssertionError):
  738. self.assertXMLNotEqual(xml1, xml2)
  739. def test_parsing_errors(self):
  740. xml_unvalid = "<elem attr1='a attr2='b' />"
  741. xml2 = "<elem attr2='b' attr1='a' />"
  742. with self.assertRaises(AssertionError):
  743. self.assertXMLNotEqual(xml_unvalid, xml2)
  744. def test_comment_root(self):
  745. xml1 = "<?xml version='1.0'?><!-- comment1 --><elem attr1='a' attr2='b' />"
  746. xml2 = "<?xml version='1.0'?><!-- comment2 --><elem attr2='b' attr1='a' />"
  747. self.assertXMLEqual(xml1, xml2)
  748. def test_simple_equal_with_leading_or_trailing_whitespace(self):
  749. xml1 = "<elem>foo</elem> \t\n"
  750. xml2 = " \t\n<elem>foo</elem>"
  751. self.assertXMLEqual(xml1, xml2)
  752. def test_simple_not_equal_with_whitespace_in_the_middle(self):
  753. xml1 = "<elem>foo</elem><elem>bar</elem>"
  754. xml2 = "<elem>foo</elem> <elem>bar</elem>"
  755. self.assertXMLNotEqual(xml1, xml2)
  756. class SkippingExtraTests(TestCase):
  757. fixtures = ['should_not_be_loaded.json']
  758. # HACK: This depends on internals of our TestCase subclasses
  759. def __call__(self, result=None):
  760. # Detect fixture loading by counting SQL queries, should be zero
  761. with self.assertNumQueries(0):
  762. super().__call__(result)
  763. @unittest.skip("Fixture loading should not be performed for skipped tests.")
  764. def test_fixtures_are_skipped(self):
  765. pass
  766. class AssertRaisesMsgTest(SimpleTestCase):
  767. def test_assert_raises_message(self):
  768. msg = "'Expected message' not found in 'Unexpected message'"
  769. # context manager form of assertRaisesMessage()
  770. with self.assertRaisesMessage(AssertionError, msg):
  771. with self.assertRaisesMessage(ValueError, "Expected message"):
  772. raise ValueError("Unexpected message")
  773. # callable form
  774. def func():
  775. raise ValueError("Unexpected message")
  776. with self.assertRaisesMessage(AssertionError, msg):
  777. self.assertRaisesMessage(ValueError, "Expected message", func)
  778. def test_special_re_chars(self):
  779. """assertRaisesMessage shouldn't interpret RE special chars."""
  780. def func1():
  781. raise ValueError("[.*x+]y?")
  782. with self.assertRaisesMessage(ValueError, "[.*x+]y?"):
  783. func1()
  784. class AssertWarnsMessageTests(SimpleTestCase):
  785. def test_context_manager(self):
  786. with self.assertWarnsMessage(UserWarning, 'Expected message'):
  787. warnings.warn('Expected message', UserWarning)
  788. def test_context_manager_failure(self):
  789. msg = "Expected message' not found in 'Unexpected message'"
  790. with self.assertRaisesMessage(AssertionError, msg):
  791. with self.assertWarnsMessage(UserWarning, 'Expected message'):
  792. warnings.warn('Unexpected message', UserWarning)
  793. def test_callable(self):
  794. def func():
  795. warnings.warn('Expected message', UserWarning)
  796. self.assertWarnsMessage(UserWarning, 'Expected message', func)
  797. def test_special_re_chars(self):
  798. def func1():
  799. warnings.warn('[.*x+]y?', UserWarning)
  800. with self.assertWarnsMessage(UserWarning, '[.*x+]y?'):
  801. func1()
  802. class AssertFieldOutputTests(SimpleTestCase):
  803. def test_assert_field_output(self):
  804. error_invalid = ['Enter a valid email address.']
  805. self.assertFieldOutput(EmailField, {'a@a.com': 'a@a.com'}, {'aaa': error_invalid})
  806. with self.assertRaises(AssertionError):
  807. self.assertFieldOutput(EmailField, {'a@a.com': 'a@a.com'}, {'aaa': error_invalid + ['Another error']})
  808. with self.assertRaises(AssertionError):
  809. self.assertFieldOutput(EmailField, {'a@a.com': 'Wrong output'}, {'aaa': error_invalid})
  810. with self.assertRaises(AssertionError):
  811. self.assertFieldOutput(
  812. EmailField, {'a@a.com': 'a@a.com'}, {'aaa': ['Come on, gimme some well formatted data, dude.']}
  813. )
  814. def test_custom_required_message(self):
  815. class MyCustomField(IntegerField):
  816. default_error_messages = {
  817. 'required': 'This is really required.',
  818. }
  819. self.assertFieldOutput(MyCustomField, {}, {}, empty_value=None)
  820. @override_settings(ROOT_URLCONF='test_utils.urls')
  821. class AssertURLEqualTests(SimpleTestCase):
  822. def test_equal(self):
  823. valid_tests = (
  824. ('http://example.com/?', 'http://example.com/'),
  825. ('http://example.com/?x=1&', 'http://example.com/?x=1'),
  826. ('http://example.com/?x=1&y=2', 'http://example.com/?y=2&x=1'),
  827. ('http://example.com/?x=1&y=2', 'http://example.com/?y=2&x=1'),
  828. ('http://example.com/?x=1&y=2&a=1&a=2', 'http://example.com/?a=1&a=2&y=2&x=1'),
  829. ('/path/to/?x=1&y=2&z=3', '/path/to/?z=3&y=2&x=1'),
  830. ('?x=1&y=2&z=3', '?z=3&y=2&x=1'),
  831. ('/test_utils/no_template_used/', reverse_lazy('no_template_used')),
  832. )
  833. for url1, url2 in valid_tests:
  834. with self.subTest(url=url1):
  835. self.assertURLEqual(url1, url2)
  836. def test_not_equal(self):
  837. invalid_tests = (
  838. # Protocol must be the same.
  839. ('http://example.com/', 'https://example.com/'),
  840. ('http://example.com/?x=1&x=2', 'https://example.com/?x=2&x=1'),
  841. ('http://example.com/?x=1&y=bar&x=2', 'https://example.com/?y=bar&x=2&x=1'),
  842. # Parameters of the same name must be in the same order.
  843. ('/path/to?a=1&a=2', '/path/to/?a=2&a=1')
  844. )
  845. for url1, url2 in invalid_tests:
  846. with self.subTest(url=url1), self.assertRaises(AssertionError):
  847. self.assertURLEqual(url1, url2)
  848. def test_message(self):
  849. msg = (
  850. "Expected 'http://example.com/?x=1&x=2' to equal "
  851. "'https://example.com/?x=2&x=1'"
  852. )
  853. with self.assertRaisesMessage(AssertionError, msg):
  854. self.assertURLEqual('http://example.com/?x=1&x=2', 'https://example.com/?x=2&x=1')
  855. def test_msg_prefix(self):
  856. msg = (
  857. "Prefix: Expected 'http://example.com/?x=1&x=2' to equal "
  858. "'https://example.com/?x=2&x=1'"
  859. )
  860. with self.assertRaisesMessage(AssertionError, msg):
  861. self.assertURLEqual(
  862. 'http://example.com/?x=1&x=2', 'https://example.com/?x=2&x=1',
  863. msg_prefix='Prefix: ',
  864. )
  865. class FirstUrls:
  866. urlpatterns = [path('first/', empty_response, name='first')]
  867. class SecondUrls:
  868. urlpatterns = [path('second/', empty_response, name='second')]
  869. class SetupTestEnvironmentTests(SimpleTestCase):
  870. def test_setup_test_environment_calling_more_than_once(self):
  871. with self.assertRaisesMessage(RuntimeError, "setup_test_environment() was already called"):
  872. setup_test_environment()
  873. def test_allowed_hosts(self):
  874. for type_ in (list, tuple):
  875. with self.subTest(type_=type_):
  876. allowed_hosts = type_('*')
  877. with mock.patch('django.test.utils._TestState') as x:
  878. del x.saved_data
  879. with self.settings(ALLOWED_HOSTS=allowed_hosts):
  880. setup_test_environment()
  881. self.assertEqual(settings.ALLOWED_HOSTS, ['*', 'testserver'])
  882. class OverrideSettingsTests(SimpleTestCase):
  883. # #21518 -- If neither override_settings nor a setting_changed receiver
  884. # clears the URL cache between tests, then one of test_first or
  885. # test_second will fail.
  886. @override_settings(ROOT_URLCONF=FirstUrls)
  887. def test_urlconf_first(self):
  888. reverse('first')
  889. @override_settings(ROOT_URLCONF=SecondUrls)
  890. def test_urlconf_second(self):
  891. reverse('second')
  892. def test_urlconf_cache(self):
  893. with self.assertRaises(NoReverseMatch):
  894. reverse('first')
  895. with self.assertRaises(NoReverseMatch):
  896. reverse('second')
  897. with override_settings(ROOT_URLCONF=FirstUrls):
  898. self.client.get(reverse('first'))
  899. with self.assertRaises(NoReverseMatch):
  900. reverse('second')
  901. with override_settings(ROOT_URLCONF=SecondUrls):
  902. with self.assertRaises(NoReverseMatch):
  903. reverse('first')
  904. self.client.get(reverse('second'))
  905. self.client.get(reverse('first'))
  906. with self.assertRaises(NoReverseMatch):
  907. reverse('second')
  908. with self.assertRaises(NoReverseMatch):
  909. reverse('first')
  910. with self.assertRaises(NoReverseMatch):
  911. reverse('second')
  912. def test_override_media_root(self):
  913. """
  914. Overriding the MEDIA_ROOT setting should be reflected in the
  915. base_location attribute of django.core.files.storage.default_storage.
  916. """
  917. self.assertEqual(default_storage.base_location, '')
  918. with self.settings(MEDIA_ROOT='test_value'):
  919. self.assertEqual(default_storage.base_location, 'test_value')
  920. def test_override_media_url(self):
  921. """
  922. Overriding the MEDIA_URL setting should be reflected in the
  923. base_url attribute of django.core.files.storage.default_storage.
  924. """
  925. self.assertEqual(default_storage.base_location, '')
  926. with self.settings(MEDIA_URL='/test_value/'):
  927. self.assertEqual(default_storage.base_url, '/test_value/')
  928. def test_override_file_upload_permissions(self):
  929. """
  930. Overriding the FILE_UPLOAD_PERMISSIONS setting should be reflected in
  931. the file_permissions_mode attribute of
  932. django.core.files.storage.default_storage.
  933. """
  934. self.assertEqual(default_storage.file_permissions_mode, 0o644)
  935. with self.settings(FILE_UPLOAD_PERMISSIONS=0o777):
  936. self.assertEqual(default_storage.file_permissions_mode, 0o777)
  937. def test_override_file_upload_directory_permissions(self):
  938. """
  939. Overriding the FILE_UPLOAD_DIRECTORY_PERMISSIONS setting should be
  940. reflected in the directory_permissions_mode attribute of
  941. django.core.files.storage.default_storage.
  942. """
  943. self.assertIsNone(default_storage.directory_permissions_mode)
  944. with self.settings(FILE_UPLOAD_DIRECTORY_PERMISSIONS=0o777):
  945. self.assertEqual(default_storage.directory_permissions_mode, 0o777)
  946. def test_override_database_routers(self):
  947. """
  948. Overriding DATABASE_ROUTERS should update the master router.
  949. """
  950. test_routers = [object()]
  951. with self.settings(DATABASE_ROUTERS=test_routers):
  952. self.assertEqual(router.routers, test_routers)
  953. def test_override_static_url(self):
  954. """
  955. Overriding the STATIC_URL setting should be reflected in the
  956. base_url attribute of
  957. django.contrib.staticfiles.storage.staticfiles_storage.
  958. """
  959. with self.settings(STATIC_URL='/test/'):
  960. self.assertEqual(staticfiles_storage.base_url, '/test/')
  961. def test_override_static_root(self):
  962. """
  963. Overriding the STATIC_ROOT setting should be reflected in the
  964. location attribute of
  965. django.contrib.staticfiles.storage.staticfiles_storage.
  966. """
  967. with self.settings(STATIC_ROOT='/tmp/test'):
  968. self.assertEqual(staticfiles_storage.location, os.path.abspath('/tmp/test'))
  969. def test_override_staticfiles_storage(self):
  970. """
  971. Overriding the STATICFILES_STORAGE setting should be reflected in
  972. the value of django.contrib.staticfiles.storage.staticfiles_storage.
  973. """
  974. new_class = 'ManifestStaticFilesStorage'
  975. new_storage = 'django.contrib.staticfiles.storage.' + new_class
  976. with self.settings(STATICFILES_STORAGE=new_storage):
  977. self.assertEqual(staticfiles_storage.__class__.__name__, new_class)
  978. def test_override_staticfiles_finders(self):
  979. """
  980. Overriding the STATICFILES_FINDERS setting should be reflected in
  981. the return value of django.contrib.staticfiles.finders.get_finders.
  982. """
  983. current = get_finders()
  984. self.assertGreater(len(list(current)), 1)
  985. finders = ['django.contrib.staticfiles.finders.FileSystemFinder']
  986. with self.settings(STATICFILES_FINDERS=finders):
  987. self.assertEqual(len(list(get_finders())), len(finders))
  988. def test_override_staticfiles_dirs(self):
  989. """
  990. Overriding the STATICFILES_DIRS setting should be reflected in
  991. the locations attribute of the
  992. django.contrib.staticfiles.finders.FileSystemFinder instance.
  993. """
  994. finder = get_finder('django.contrib.staticfiles.finders.FileSystemFinder')
  995. test_path = '/tmp/test'
  996. expected_location = ('', test_path)
  997. self.assertNotIn(expected_location, finder.locations)
  998. with self.settings(STATICFILES_DIRS=[test_path]):
  999. finder = get_finder('django.contrib.staticfiles.finders.FileSystemFinder')
  1000. self.assertIn(expected_location, finder.locations)
  1001. class TestBadSetUpTestData(TestCase):
  1002. """
  1003. An exception in setUpTestData() shouldn't leak a transaction which would
  1004. cascade across the rest of the test suite.
  1005. """
  1006. class MyException(Exception):
  1007. pass
  1008. @classmethod
  1009. def setUpClass(cls):
  1010. try:
  1011. super().setUpClass()
  1012. except cls.MyException:
  1013. cls._in_atomic_block = connection.in_atomic_block
  1014. @classmethod
  1015. def tearDownClass(Cls):
  1016. # override to avoid a second cls._rollback_atomics() which would fail.
  1017. # Normal setUpClass() methods won't have exception handling so this
  1018. # method wouldn't typically be run.
  1019. pass
  1020. @classmethod
  1021. def setUpTestData(cls):
  1022. # Simulate a broken setUpTestData() method.
  1023. raise cls.MyException()
  1024. def test_failure_in_setUpTestData_should_rollback_transaction(self):
  1025. # setUpTestData() should call _rollback_atomics() so that the
  1026. # transaction doesn't leak.
  1027. self.assertFalse(self._in_atomic_block)
  1028. class DisallowedDatabaseQueriesTests(SimpleTestCase):
  1029. def test_disallowed_database_connections(self):
  1030. expected_message = (
  1031. "Database connections to 'default' are not allowed in SimpleTestCase "
  1032. "subclasses. Either subclass TestCase or TransactionTestCase to "
  1033. "ensure proper test isolation or add 'default' to "
  1034. "test_utils.tests.DisallowedDatabaseQueriesTests.databases to "
  1035. "silence this failure."
  1036. )
  1037. with self.assertRaisesMessage(AssertionError, expected_message):
  1038. connection.connect()
  1039. with self.assertRaisesMessage(AssertionError, expected_message):
  1040. connection.temporary_connection()
  1041. def test_disallowed_database_queries(self):
  1042. expected_message = (
  1043. "Database queries to 'default' are not allowed in SimpleTestCase "
  1044. "subclasses. Either subclass TestCase or TransactionTestCase to "
  1045. "ensure proper test isolation or add 'default' to "
  1046. "test_utils.tests.DisallowedDatabaseQueriesTests.databases to "
  1047. "silence this failure."
  1048. )
  1049. with self.assertRaisesMessage(AssertionError, expected_message):
  1050. Car.objects.first()
  1051. def test_disallowed_database_chunked_cursor_queries(self):
  1052. expected_message = (
  1053. "Database queries to 'default' are not allowed in SimpleTestCase "
  1054. "subclasses. Either subclass TestCase or TransactionTestCase to "
  1055. "ensure proper test isolation or add 'default' to "
  1056. "test_utils.tests.DisallowedDatabaseQueriesTests.databases to "
  1057. "silence this failure."
  1058. )
  1059. with self.assertRaisesMessage(AssertionError, expected_message):
  1060. next(Car.objects.iterator())
  1061. class AllowedDatabaseQueriesTests(SimpleTestCase):
  1062. databases = {'default'}
  1063. def test_allowed_database_queries(self):
  1064. Car.objects.first()
  1065. def test_allowed_database_chunked_cursor_queries(self):
  1066. next(Car.objects.iterator(), None)
  1067. class DatabaseAliasTests(SimpleTestCase):
  1068. def setUp(self):
  1069. self.addCleanup(setattr, self.__class__, 'databases', self.databases)
  1070. def test_no_close_match(self):
  1071. self.__class__.databases = {'void'}
  1072. message = (
  1073. "test_utils.tests.DatabaseAliasTests.databases refers to 'void' which is not defined "
  1074. "in settings.DATABASES."
  1075. )
  1076. with self.assertRaisesMessage(ImproperlyConfigured, message):
  1077. self._validate_databases()
  1078. def test_close_match(self):
  1079. self.__class__.databases = {'defualt'}
  1080. message = (
  1081. "test_utils.tests.DatabaseAliasTests.databases refers to 'defualt' which is not defined "
  1082. "in settings.DATABASES. Did you mean 'default'?"
  1083. )
  1084. with self.assertRaisesMessage(ImproperlyConfigured, message):
  1085. self._validate_databases()
  1086. def test_match(self):
  1087. self.__class__.databases = {'default', 'other'}
  1088. self.assertEqual(self._validate_databases(), frozenset({'default', 'other'}))
  1089. def test_all(self):
  1090. self.__class__.databases = '__all__'
  1091. self.assertEqual(self._validate_databases(), frozenset(connections))
  1092. @isolate_apps('test_utils', attr_name='class_apps')
  1093. class IsolatedAppsTests(SimpleTestCase):
  1094. def test_installed_apps(self):
  1095. self.assertEqual([app_config.label for app_config in self.class_apps.get_app_configs()], ['test_utils'])
  1096. def test_class_decoration(self):
  1097. class ClassDecoration(models.Model):
  1098. pass
  1099. self.assertEqual(ClassDecoration._meta.apps, self.class_apps)
  1100. @isolate_apps('test_utils', kwarg_name='method_apps')
  1101. def test_method_decoration(self, method_apps):
  1102. class MethodDecoration(models.Model):
  1103. pass
  1104. self.assertEqual(MethodDecoration._meta.apps, method_apps)
  1105. def test_context_manager(self):
  1106. with isolate_apps('test_utils') as context_apps:
  1107. class ContextManager(models.Model):
  1108. pass
  1109. self.assertEqual(ContextManager._meta.apps, context_apps)
  1110. @isolate_apps('test_utils', kwarg_name='method_apps')
  1111. def test_nested(self, method_apps):
  1112. class MethodDecoration(models.Model):
  1113. pass
  1114. with isolate_apps('test_utils') as context_apps:
  1115. class ContextManager(models.Model):
  1116. pass
  1117. with isolate_apps('test_utils') as nested_context_apps:
  1118. class NestedContextManager(models.Model):
  1119. pass
  1120. self.assertEqual(MethodDecoration._meta.apps, method_apps)
  1121. self.assertEqual(ContextManager._meta.apps, context_apps)
  1122. self.assertEqual(NestedContextManager._meta.apps, nested_context_apps)
  1123. class DoNothingDecorator(TestContextDecorator):
  1124. def enable(self):
  1125. pass
  1126. def disable(self):
  1127. pass
  1128. class TestContextDecoratorTests(SimpleTestCase):
  1129. @mock.patch.object(DoNothingDecorator, 'disable')
  1130. def test_exception_in_setup(self, mock_disable):
  1131. """An exception is setUp() is reraised after disable() is called."""
  1132. class ExceptionInSetUp(unittest.TestCase):
  1133. def setUp(self):
  1134. raise NotImplementedError('reraised')
  1135. decorator = DoNothingDecorator()
  1136. decorated_test_class = decorator.__call__(ExceptionInSetUp)()
  1137. self.assertFalse(mock_disable.called)
  1138. with self.assertRaisesMessage(NotImplementedError, 'reraised'):
  1139. decorated_test_class.setUp()
  1140. self.assertTrue(mock_disable.called)