tests.py 53 KB

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