tests.py 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397
  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. 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link',
  444. 'meta', 'param', 'source', 'track', 'wbr',
  445. # Deprecated tags
  446. 'frame', 'spacer',
  447. ]
  448. for tag in self_closing_tags:
  449. with self.subTest(tag):
  450. dom = parse_html('<p>Hello <%s> world</p>' % tag)
  451. self.assertEqual(len(dom.children), 3)
  452. self.assertEqual(dom[0], 'Hello')
  453. self.assertEqual(dom[1].name, tag)
  454. self.assertEqual(dom[2], 'world')
  455. dom = parse_html('<p>Hello <%s /> world</p>' % tag)
  456. self.assertEqual(len(dom.children), 3)
  457. self.assertEqual(dom[0], 'Hello')
  458. self.assertEqual(dom[1].name, tag)
  459. self.assertEqual(dom[2], 'world')
  460. def test_simple_equal_html(self):
  461. self.assertHTMLEqual('', '')
  462. self.assertHTMLEqual('<p></p>', '<p></p>')
  463. self.assertHTMLEqual('<p></p>', ' <p> </p> ')
  464. self.assertHTMLEqual(
  465. '<div><p>Hello</p></div>',
  466. '<div><p>Hello</p></div>')
  467. self.assertHTMLEqual(
  468. '<div><p>Hello</p></div>',
  469. '<div> <p>Hello</p> </div>')
  470. self.assertHTMLEqual(
  471. '<div>\n<p>Hello</p></div>',
  472. '<div><p>Hello</p></div>\n')
  473. self.assertHTMLEqual(
  474. '<div><p>Hello\nWorld !</p></div>',
  475. '<div><p>Hello World\n!</p></div>')
  476. self.assertHTMLEqual(
  477. '<div><p>Hello\nWorld !</p></div>',
  478. '<div><p>Hello World\n!</p></div>')
  479. self.assertHTMLEqual(
  480. '<p>Hello World !</p>',
  481. '<p>Hello World\n\n!</p>')
  482. self.assertHTMLEqual('<p> </p>', '<p></p>')
  483. self.assertHTMLEqual('<p/>', '<p></p>')
  484. self.assertHTMLEqual('<p />', '<p></p>')
  485. self.assertHTMLEqual('<input checked>', '<input checked="checked">')
  486. self.assertHTMLEqual('<p>Hello', '<p> Hello')
  487. self.assertHTMLEqual('<p>Hello</p>World', '<p>Hello</p> World')
  488. def test_ignore_comments(self):
  489. self.assertHTMLEqual(
  490. '<div>Hello<!-- this is a comment --> World!</div>',
  491. '<div>Hello World!</div>')
  492. def test_unequal_html(self):
  493. self.assertHTMLNotEqual('<p>Hello</p>', '<p>Hello!</p>')
  494. self.assertHTMLNotEqual('<p>foo&#20;bar</p>', '<p>foo&nbsp;bar</p>')
  495. self.assertHTMLNotEqual('<p>foo bar</p>', '<p>foo &nbsp;bar</p>')
  496. self.assertHTMLNotEqual('<p>foo nbsp</p>', '<p>foo &nbsp;</p>')
  497. self.assertHTMLNotEqual('<p>foo #20</p>', '<p>foo &#20;</p>')
  498. self.assertHTMLNotEqual(
  499. '<p><span>Hello</span><span>World</span></p>',
  500. '<p><span>Hello</span>World</p>')
  501. self.assertHTMLNotEqual(
  502. '<p><span>Hello</span>World</p>',
  503. '<p><span>Hello</span><span>World</span></p>')
  504. def test_attributes(self):
  505. self.assertHTMLEqual(
  506. '<input type="text" id="id_name" />',
  507. '<input id="id_name" type="text" />')
  508. self.assertHTMLEqual(
  509. '''<input type='text' id="id_name" />''',
  510. '<input id="id_name" type="text" />')
  511. self.assertHTMLNotEqual(
  512. '<input type="text" id="id_name" />',
  513. '<input type="password" id="id_name" />')
  514. def test_class_attribute(self):
  515. pairs = [
  516. ('<p class="foo bar"></p>', '<p class="bar foo"></p>'),
  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\tbar"></p>', '<p class="bar foo"></p>'),
  520. ('<p class="\tfoo\tbar\t"></p>', '<p class="bar foo"></p>'),
  521. ('<p class="\t\t\tfoo\t\t\tbar\t\t\t"></p>', '<p class="bar foo"></p>'),
  522. ('<p class="\t \nfoo \t\nbar\n\t "></p>', '<p class="bar foo"></p>'),
  523. ]
  524. for html1, html2 in pairs:
  525. with self.subTest(html1):
  526. self.assertHTMLEqual(html1, html2)
  527. def test_normalize_refs(self):
  528. pairs = [
  529. ('&#39;', '&#x27;'),
  530. ('&#39;', "'"),
  531. ('&#x27;', '&#39;'),
  532. ('&#x27;', "'"),
  533. ("'", '&#39;'),
  534. ("'", '&#x27;'),
  535. ('&amp;', '&#38;'),
  536. ('&amp;', '&#x26;'),
  537. ('&amp;', '&'),
  538. ('&#38;', '&amp;'),
  539. ('&#38;', '&#x26;'),
  540. ('&#38;', '&'),
  541. ('&#x26;', '&amp;'),
  542. ('&#x26;', '&#38;'),
  543. ('&#x26;', '&'),
  544. ('&', '&amp;'),
  545. ('&', '&#38;'),
  546. ('&', '&#x26;'),
  547. ]
  548. for pair in pairs:
  549. with self.subTest(repr(pair)):
  550. self.assertHTMLEqual(*pair)
  551. def test_complex_examples(self):
  552. self.assertHTMLEqual(
  553. """<tr><th><label for="id_first_name">First name:</label></th>
  554. <td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>
  555. <tr><th><label for="id_last_name">Last name:</label></th>
  556. <td><input type="text" id="id_last_name" name="last_name" value="Lennon" /></td></tr>
  557. <tr><th><label for="id_birthday">Birthday:</label></th>
  558. <td><input type="text" value="1940-10-9" name="birthday" id="id_birthday" /></td></tr>""",
  559. """
  560. <tr><th>
  561. <label for="id_first_name">First name:</label></th><td>
  562. <input type="text" name="first_name" value="John" id="id_first_name" />
  563. </td></tr>
  564. <tr><th>
  565. <label for="id_last_name">Last name:</label></th><td>
  566. <input type="text" name="last_name" value="Lennon" id="id_last_name" />
  567. </td></tr>
  568. <tr><th>
  569. <label for="id_birthday">Birthday:</label></th><td>
  570. <input type="text" name="birthday" value="1940-10-9" id="id_birthday" />
  571. </td></tr>
  572. """)
  573. self.assertHTMLEqual(
  574. """<!DOCTYPE html>
  575. <html>
  576. <head>
  577. <link rel="stylesheet">
  578. <title>Document</title>
  579. <meta attribute="value">
  580. </head>
  581. <body>
  582. <p>
  583. This is a valid paragraph
  584. <div> this is a div AFTER the p</div>
  585. </body>
  586. </html>""", """
  587. <html>
  588. <head>
  589. <link rel="stylesheet">
  590. <title>Document</title>
  591. <meta attribute="value">
  592. </head>
  593. <body>
  594. <p> This is a valid paragraph
  595. <!-- browsers would close the p tag here -->
  596. <div> this is a div AFTER the p</div>
  597. </p> <!-- this is invalid HTML parsing, but it should make no
  598. difference in most cases -->
  599. </body>
  600. </html>""")
  601. def test_html_contain(self):
  602. # equal html contains each other
  603. dom1 = parse_html('<p>foo')
  604. dom2 = parse_html('<p>foo</p>')
  605. self.assertIn(dom1, dom2)
  606. self.assertIn(dom2, dom1)
  607. dom2 = parse_html('<div><p>foo</p></div>')
  608. self.assertIn(dom1, dom2)
  609. self.assertNotIn(dom2, dom1)
  610. self.assertNotIn('<p>foo</p>', dom2)
  611. self.assertIn('foo', dom2)
  612. # when a root element is used ...
  613. dom1 = parse_html('<p>foo</p><p>bar</p>')
  614. dom2 = parse_html('<p>foo</p><p>bar</p>')
  615. self.assertIn(dom1, dom2)
  616. dom1 = parse_html('<p>foo</p>')
  617. self.assertIn(dom1, dom2)
  618. dom1 = parse_html('<p>bar</p>')
  619. self.assertIn(dom1, dom2)
  620. dom1 = parse_html('<div><p>foo</p><p>bar</p></div>')
  621. self.assertIn(dom2, dom1)
  622. def test_count(self):
  623. # equal html contains each other one time
  624. dom1 = parse_html('<p>foo')
  625. dom2 = parse_html('<p>foo</p>')
  626. self.assertEqual(dom1.count(dom2), 1)
  627. self.assertEqual(dom2.count(dom1), 1)
  628. dom2 = parse_html('<p>foo</p><p>bar</p>')
  629. self.assertEqual(dom2.count(dom1), 1)
  630. dom2 = parse_html('<p>foo foo</p><p>foo</p>')
  631. self.assertEqual(dom2.count('foo'), 3)
  632. dom2 = parse_html('<p class="bar">foo</p>')
  633. self.assertEqual(dom2.count('bar'), 0)
  634. self.assertEqual(dom2.count('class'), 0)
  635. self.assertEqual(dom2.count('p'), 0)
  636. self.assertEqual(dom2.count('o'), 2)
  637. dom2 = parse_html('<p>foo</p><p>foo</p>')
  638. self.assertEqual(dom2.count(dom1), 2)
  639. dom2 = parse_html('<div><p>foo<input type=""></p><p>foo</p></div>')
  640. self.assertEqual(dom2.count(dom1), 1)
  641. dom2 = parse_html('<div><div><p>foo</p></div></div>')
  642. self.assertEqual(dom2.count(dom1), 1)
  643. dom2 = parse_html('<p>foo<p>foo</p></p>')
  644. self.assertEqual(dom2.count(dom1), 1)
  645. dom2 = parse_html('<p>foo<p>bar</p></p>')
  646. self.assertEqual(dom2.count(dom1), 0)
  647. # html with a root element contains the same html with no root element
  648. dom1 = parse_html('<p>foo</p><p>bar</p>')
  649. dom2 = parse_html('<div><p>foo</p><p>bar</p></div>')
  650. self.assertEqual(dom2.count(dom1), 1)
  651. def test_parsing_errors(self):
  652. with self.assertRaises(AssertionError):
  653. self.assertHTMLEqual('<p>', '')
  654. with self.assertRaises(AssertionError):
  655. self.assertHTMLEqual('', '<p>')
  656. error_msg = (
  657. "First argument is not valid HTML:\n"
  658. "('Unexpected end tag `div` (Line 1, Column 6)', (1, 6))"
  659. )
  660. with self.assertRaisesMessage(AssertionError, error_msg):
  661. self.assertHTMLEqual('< div></ div>', '<div></div>')
  662. with self.assertRaises(HTMLParseError):
  663. parse_html('</p>')
  664. def test_contains_html(self):
  665. response = HttpResponse('''<body>
  666. This is a form: <form method="get">
  667. <input type="text" name="Hello" />
  668. </form></body>''')
  669. self.assertNotContains(response, "<input name='Hello' type='text'>")
  670. self.assertContains(response, '<form method="get">')
  671. self.assertContains(response, "<input name='Hello' type='text'>", html=True)
  672. self.assertNotContains(response, '<form method="get">', html=True)
  673. invalid_response = HttpResponse('''<body <bad>>''')
  674. with self.assertRaises(AssertionError):
  675. self.assertContains(invalid_response, '<p></p>')
  676. with self.assertRaises(AssertionError):
  677. self.assertContains(response, '<p "whats" that>')
  678. def test_unicode_handling(self):
  679. response = HttpResponse('<p class="help">Some help text for the title (with unicode ŠĐĆŽćžšđ)</p>')
  680. self.assertContains(
  681. response,
  682. '<p class="help">Some help text for the title (with unicode ŠĐĆŽćžšđ)</p>',
  683. html=True
  684. )
  685. class JSONEqualTests(SimpleTestCase):
  686. def test_simple_equal(self):
  687. json1 = '{"attr1": "foo", "attr2":"baz"}'
  688. json2 = '{"attr1": "foo", "attr2":"baz"}'
  689. self.assertJSONEqual(json1, json2)
  690. def test_simple_equal_unordered(self):
  691. json1 = '{"attr1": "foo", "attr2":"baz"}'
  692. json2 = '{"attr2":"baz", "attr1": "foo"}'
  693. self.assertJSONEqual(json1, json2)
  694. def test_simple_equal_raise(self):
  695. json1 = '{"attr1": "foo", "attr2":"baz"}'
  696. json2 = '{"attr2":"baz"}'
  697. with self.assertRaises(AssertionError):
  698. self.assertJSONEqual(json1, json2)
  699. def test_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.assertJSONEqual(invalid_json, valid_json)
  704. with self.assertRaises(AssertionError):
  705. self.assertJSONEqual(valid_json, invalid_json)
  706. def test_simple_not_equal(self):
  707. json1 = '{"attr1": "foo", "attr2":"baz"}'
  708. json2 = '{"attr2":"baz"}'
  709. self.assertJSONNotEqual(json1, json2)
  710. def test_simple_not_equal_raise(self):
  711. json1 = '{"attr1": "foo", "attr2":"baz"}'
  712. json2 = '{"attr1": "foo", "attr2":"baz"}'
  713. with self.assertRaises(AssertionError):
  714. self.assertJSONNotEqual(json1, json2)
  715. def test_not_equal_parsing_errors(self):
  716. invalid_json = '{"attr1": "foo, "attr2":"baz"}'
  717. valid_json = '{"attr1": "foo", "attr2":"baz"}'
  718. with self.assertRaises(AssertionError):
  719. self.assertJSONNotEqual(invalid_json, valid_json)
  720. with self.assertRaises(AssertionError):
  721. self.assertJSONNotEqual(valid_json, invalid_json)
  722. class XMLEqualTests(SimpleTestCase):
  723. def test_simple_equal(self):
  724. xml1 = "<elem attr1='a' attr2='b' />"
  725. xml2 = "<elem attr1='a' attr2='b' />"
  726. self.assertXMLEqual(xml1, xml2)
  727. def test_simple_equal_unordered(self):
  728. xml1 = "<elem attr1='a' attr2='b' />"
  729. xml2 = "<elem attr2='b' attr1='a' />"
  730. self.assertXMLEqual(xml1, xml2)
  731. def test_simple_equal_raise(self):
  732. xml1 = "<elem attr1='a' />"
  733. xml2 = "<elem attr2='b' attr1='a' />"
  734. with self.assertRaises(AssertionError):
  735. self.assertXMLEqual(xml1, xml2)
  736. def test_simple_equal_raises_message(self):
  737. xml1 = "<elem attr1='a' />"
  738. xml2 = "<elem attr2='b' attr1='a' />"
  739. msg = '''{xml1} != {xml2}
  740. - <elem attr1='a' />
  741. + <elem attr2='b' attr1='a' />
  742. ? ++++++++++
  743. '''.format(xml1=repr(xml1), xml2=repr(xml2))
  744. with self.assertRaisesMessage(AssertionError, msg):
  745. self.assertXMLEqual(xml1, xml2)
  746. def test_simple_not_equal(self):
  747. xml1 = "<elem attr1='a' attr2='c' />"
  748. xml2 = "<elem attr1='a' attr2='b' />"
  749. self.assertXMLNotEqual(xml1, xml2)
  750. def test_simple_not_equal_raise(self):
  751. xml1 = "<elem attr1='a' attr2='b' />"
  752. xml2 = "<elem attr2='b' attr1='a' />"
  753. with self.assertRaises(AssertionError):
  754. self.assertXMLNotEqual(xml1, xml2)
  755. def test_parsing_errors(self):
  756. xml_unvalid = "<elem attr1='a attr2='b' />"
  757. xml2 = "<elem attr2='b' attr1='a' />"
  758. with self.assertRaises(AssertionError):
  759. self.assertXMLNotEqual(xml_unvalid, xml2)
  760. def test_comment_root(self):
  761. xml1 = "<?xml version='1.0'?><!-- comment1 --><elem attr1='a' attr2='b' />"
  762. xml2 = "<?xml version='1.0'?><!-- comment2 --><elem attr2='b' attr1='a' />"
  763. self.assertXMLEqual(xml1, xml2)
  764. def test_simple_equal_with_leading_or_trailing_whitespace(self):
  765. xml1 = "<elem>foo</elem> \t\n"
  766. xml2 = " \t\n<elem>foo</elem>"
  767. self.assertXMLEqual(xml1, xml2)
  768. def test_simple_not_equal_with_whitespace_in_the_middle(self):
  769. xml1 = "<elem>foo</elem><elem>bar</elem>"
  770. xml2 = "<elem>foo</elem> <elem>bar</elem>"
  771. self.assertXMLNotEqual(xml1, xml2)
  772. def test_doctype_root(self):
  773. xml1 = '<?xml version="1.0"?><!DOCTYPE root SYSTEM "example1.dtd"><root />'
  774. xml2 = '<?xml version="1.0"?><!DOCTYPE root SYSTEM "example2.dtd"><root />'
  775. self.assertXMLEqual(xml1, xml2)
  776. class SkippingExtraTests(TestCase):
  777. fixtures = ['should_not_be_loaded.json']
  778. # HACK: This depends on internals of our TestCase subclasses
  779. def __call__(self, result=None):
  780. # Detect fixture loading by counting SQL queries, should be zero
  781. with self.assertNumQueries(0):
  782. super().__call__(result)
  783. @unittest.skip("Fixture loading should not be performed for skipped tests.")
  784. def test_fixtures_are_skipped(self):
  785. pass
  786. class AssertRaisesMsgTest(SimpleTestCase):
  787. def test_assert_raises_message(self):
  788. msg = "'Expected message' not found in 'Unexpected message'"
  789. # context manager form of assertRaisesMessage()
  790. with self.assertRaisesMessage(AssertionError, msg):
  791. with self.assertRaisesMessage(ValueError, "Expected message"):
  792. raise ValueError("Unexpected message")
  793. # callable form
  794. def func():
  795. raise ValueError("Unexpected message")
  796. with self.assertRaisesMessage(AssertionError, msg):
  797. self.assertRaisesMessage(ValueError, "Expected message", func)
  798. def test_special_re_chars(self):
  799. """assertRaisesMessage shouldn't interpret RE special chars."""
  800. def func1():
  801. raise ValueError("[.*x+]y?")
  802. with self.assertRaisesMessage(ValueError, "[.*x+]y?"):
  803. func1()
  804. class AssertWarnsMessageTests(SimpleTestCase):
  805. def test_context_manager(self):
  806. with self.assertWarnsMessage(UserWarning, 'Expected message'):
  807. warnings.warn('Expected message', UserWarning)
  808. def test_context_manager_failure(self):
  809. msg = "Expected message' not found in 'Unexpected message'"
  810. with self.assertRaisesMessage(AssertionError, msg):
  811. with self.assertWarnsMessage(UserWarning, 'Expected message'):
  812. warnings.warn('Unexpected message', UserWarning)
  813. def test_callable(self):
  814. def func():
  815. warnings.warn('Expected message', UserWarning)
  816. self.assertWarnsMessage(UserWarning, 'Expected message', func)
  817. def test_special_re_chars(self):
  818. def func1():
  819. warnings.warn('[.*x+]y?', UserWarning)
  820. with self.assertWarnsMessage(UserWarning, '[.*x+]y?'):
  821. func1()
  822. class AssertFieldOutputTests(SimpleTestCase):
  823. def test_assert_field_output(self):
  824. error_invalid = ['Enter a valid email address.']
  825. self.assertFieldOutput(EmailField, {'a@a.com': 'a@a.com'}, {'aaa': error_invalid})
  826. with self.assertRaises(AssertionError):
  827. self.assertFieldOutput(EmailField, {'a@a.com': 'a@a.com'}, {'aaa': error_invalid + ['Another error']})
  828. with self.assertRaises(AssertionError):
  829. self.assertFieldOutput(EmailField, {'a@a.com': 'Wrong output'}, {'aaa': error_invalid})
  830. with self.assertRaises(AssertionError):
  831. self.assertFieldOutput(
  832. EmailField, {'a@a.com': 'a@a.com'}, {'aaa': ['Come on, gimme some well formatted data, dude.']}
  833. )
  834. def test_custom_required_message(self):
  835. class MyCustomField(IntegerField):
  836. default_error_messages = {
  837. 'required': 'This is really required.',
  838. }
  839. self.assertFieldOutput(MyCustomField, {}, {}, empty_value=None)
  840. @override_settings(ROOT_URLCONF='test_utils.urls')
  841. class AssertURLEqualTests(SimpleTestCase):
  842. def test_equal(self):
  843. valid_tests = (
  844. ('http://example.com/?', 'http://example.com/'),
  845. ('http://example.com/?x=1&', 'http://example.com/?x=1'),
  846. ('http://example.com/?x=1&y=2', 'http://example.com/?y=2&x=1'),
  847. ('http://example.com/?x=1&y=2', 'http://example.com/?y=2&x=1'),
  848. ('http://example.com/?x=1&y=2&a=1&a=2', 'http://example.com/?a=1&a=2&y=2&x=1'),
  849. ('/path/to/?x=1&y=2&z=3', '/path/to/?z=3&y=2&x=1'),
  850. ('?x=1&y=2&z=3', '?z=3&y=2&x=1'),
  851. ('/test_utils/no_template_used/', reverse_lazy('no_template_used')),
  852. )
  853. for url1, url2 in valid_tests:
  854. with self.subTest(url=url1):
  855. self.assertURLEqual(url1, url2)
  856. def test_not_equal(self):
  857. invalid_tests = (
  858. # Protocol must be the same.
  859. ('http://example.com/', 'https://example.com/'),
  860. ('http://example.com/?x=1&x=2', 'https://example.com/?x=2&x=1'),
  861. ('http://example.com/?x=1&y=bar&x=2', 'https://example.com/?y=bar&x=2&x=1'),
  862. # Parameters of the same name must be in the same order.
  863. ('/path/to?a=1&a=2', '/path/to/?a=2&a=1')
  864. )
  865. for url1, url2 in invalid_tests:
  866. with self.subTest(url=url1), self.assertRaises(AssertionError):
  867. self.assertURLEqual(url1, url2)
  868. def test_message(self):
  869. msg = (
  870. "Expected 'http://example.com/?x=1&x=2' to equal "
  871. "'https://example.com/?x=2&x=1'"
  872. )
  873. with self.assertRaisesMessage(AssertionError, msg):
  874. self.assertURLEqual('http://example.com/?x=1&x=2', 'https://example.com/?x=2&x=1')
  875. def test_msg_prefix(self):
  876. msg = (
  877. "Prefix: Expected 'http://example.com/?x=1&x=2' to equal "
  878. "'https://example.com/?x=2&x=1'"
  879. )
  880. with self.assertRaisesMessage(AssertionError, msg):
  881. self.assertURLEqual(
  882. 'http://example.com/?x=1&x=2', 'https://example.com/?x=2&x=1',
  883. msg_prefix='Prefix: ',
  884. )
  885. class FirstUrls:
  886. urlpatterns = [path('first/', empty_response, name='first')]
  887. class SecondUrls:
  888. urlpatterns = [path('second/', empty_response, name='second')]
  889. class SetupTestEnvironmentTests(SimpleTestCase):
  890. def test_setup_test_environment_calling_more_than_once(self):
  891. with self.assertRaisesMessage(RuntimeError, "setup_test_environment() was already called"):
  892. setup_test_environment()
  893. def test_allowed_hosts(self):
  894. for type_ in (list, tuple):
  895. with self.subTest(type_=type_):
  896. allowed_hosts = type_('*')
  897. with mock.patch('django.test.utils._TestState') as x:
  898. del x.saved_data
  899. with self.settings(ALLOWED_HOSTS=allowed_hosts):
  900. setup_test_environment()
  901. self.assertEqual(settings.ALLOWED_HOSTS, ['*', 'testserver'])
  902. class OverrideSettingsTests(SimpleTestCase):
  903. # #21518 -- If neither override_settings nor a setting_changed receiver
  904. # clears the URL cache between tests, then one of test_first or
  905. # test_second will fail.
  906. @override_settings(ROOT_URLCONF=FirstUrls)
  907. def test_urlconf_first(self):
  908. reverse('first')
  909. @override_settings(ROOT_URLCONF=SecondUrls)
  910. def test_urlconf_second(self):
  911. reverse('second')
  912. def test_urlconf_cache(self):
  913. with self.assertRaises(NoReverseMatch):
  914. reverse('first')
  915. with self.assertRaises(NoReverseMatch):
  916. reverse('second')
  917. with override_settings(ROOT_URLCONF=FirstUrls):
  918. self.client.get(reverse('first'))
  919. with self.assertRaises(NoReverseMatch):
  920. reverse('second')
  921. with override_settings(ROOT_URLCONF=SecondUrls):
  922. with self.assertRaises(NoReverseMatch):
  923. reverse('first')
  924. self.client.get(reverse('second'))
  925. self.client.get(reverse('first'))
  926. with self.assertRaises(NoReverseMatch):
  927. reverse('second')
  928. with self.assertRaises(NoReverseMatch):
  929. reverse('first')
  930. with self.assertRaises(NoReverseMatch):
  931. reverse('second')
  932. def test_override_media_root(self):
  933. """
  934. Overriding the MEDIA_ROOT setting should be reflected in the
  935. base_location attribute of django.core.files.storage.default_storage.
  936. """
  937. self.assertEqual(default_storage.base_location, '')
  938. with self.settings(MEDIA_ROOT='test_value'):
  939. self.assertEqual(default_storage.base_location, 'test_value')
  940. def test_override_media_url(self):
  941. """
  942. Overriding the MEDIA_URL setting should be reflected in the
  943. base_url attribute of django.core.files.storage.default_storage.
  944. """
  945. self.assertEqual(default_storage.base_location, '')
  946. with self.settings(MEDIA_URL='/test_value/'):
  947. self.assertEqual(default_storage.base_url, '/test_value/')
  948. def test_override_file_upload_permissions(self):
  949. """
  950. Overriding the FILE_UPLOAD_PERMISSIONS setting should be reflected in
  951. the file_permissions_mode attribute of
  952. django.core.files.storage.default_storage.
  953. """
  954. self.assertEqual(default_storage.file_permissions_mode, 0o644)
  955. with self.settings(FILE_UPLOAD_PERMISSIONS=0o777):
  956. self.assertEqual(default_storage.file_permissions_mode, 0o777)
  957. def test_override_file_upload_directory_permissions(self):
  958. """
  959. Overriding the FILE_UPLOAD_DIRECTORY_PERMISSIONS setting should be
  960. reflected in the directory_permissions_mode attribute of
  961. django.core.files.storage.default_storage.
  962. """
  963. self.assertIsNone(default_storage.directory_permissions_mode)
  964. with self.settings(FILE_UPLOAD_DIRECTORY_PERMISSIONS=0o777):
  965. self.assertEqual(default_storage.directory_permissions_mode, 0o777)
  966. def test_override_database_routers(self):
  967. """
  968. Overriding DATABASE_ROUTERS should update the master router.
  969. """
  970. test_routers = [object()]
  971. with self.settings(DATABASE_ROUTERS=test_routers):
  972. self.assertEqual(router.routers, test_routers)
  973. def test_override_static_url(self):
  974. """
  975. Overriding the STATIC_URL setting should be reflected in the
  976. base_url attribute of
  977. django.contrib.staticfiles.storage.staticfiles_storage.
  978. """
  979. with self.settings(STATIC_URL='/test/'):
  980. self.assertEqual(staticfiles_storage.base_url, '/test/')
  981. def test_override_static_root(self):
  982. """
  983. Overriding the STATIC_ROOT setting should be reflected in the
  984. location attribute of
  985. django.contrib.staticfiles.storage.staticfiles_storage.
  986. """
  987. with self.settings(STATIC_ROOT='/tmp/test'):
  988. self.assertEqual(staticfiles_storage.location, os.path.abspath('/tmp/test'))
  989. def test_override_staticfiles_storage(self):
  990. """
  991. Overriding the STATICFILES_STORAGE setting should be reflected in
  992. the value of django.contrib.staticfiles.storage.staticfiles_storage.
  993. """
  994. new_class = 'ManifestStaticFilesStorage'
  995. new_storage = 'django.contrib.staticfiles.storage.' + new_class
  996. with self.settings(STATICFILES_STORAGE=new_storage):
  997. self.assertEqual(staticfiles_storage.__class__.__name__, new_class)
  998. def test_override_staticfiles_finders(self):
  999. """
  1000. Overriding the STATICFILES_FINDERS setting should be reflected in
  1001. the return value of django.contrib.staticfiles.finders.get_finders.
  1002. """
  1003. current = get_finders()
  1004. self.assertGreater(len(list(current)), 1)
  1005. finders = ['django.contrib.staticfiles.finders.FileSystemFinder']
  1006. with self.settings(STATICFILES_FINDERS=finders):
  1007. self.assertEqual(len(list(get_finders())), len(finders))
  1008. def test_override_staticfiles_dirs(self):
  1009. """
  1010. Overriding the STATICFILES_DIRS setting should be reflected in
  1011. the locations attribute of the
  1012. django.contrib.staticfiles.finders.FileSystemFinder instance.
  1013. """
  1014. finder = get_finder('django.contrib.staticfiles.finders.FileSystemFinder')
  1015. test_path = '/tmp/test'
  1016. expected_location = ('', test_path)
  1017. self.assertNotIn(expected_location, finder.locations)
  1018. with self.settings(STATICFILES_DIRS=[test_path]):
  1019. finder = get_finder('django.contrib.staticfiles.finders.FileSystemFinder')
  1020. self.assertIn(expected_location, finder.locations)
  1021. class TestBadSetUpTestData(TestCase):
  1022. """
  1023. An exception in setUpTestData() shouldn't leak a transaction which would
  1024. cascade across the rest of the test suite.
  1025. """
  1026. class MyException(Exception):
  1027. pass
  1028. @classmethod
  1029. def setUpClass(cls):
  1030. try:
  1031. super().setUpClass()
  1032. except cls.MyException:
  1033. cls._in_atomic_block = connection.in_atomic_block
  1034. @classmethod
  1035. def tearDownClass(Cls):
  1036. # override to avoid a second cls._rollback_atomics() which would fail.
  1037. # Normal setUpClass() methods won't have exception handling so this
  1038. # method wouldn't typically be run.
  1039. pass
  1040. @classmethod
  1041. def setUpTestData(cls):
  1042. # Simulate a broken setUpTestData() method.
  1043. raise cls.MyException()
  1044. def test_failure_in_setUpTestData_should_rollback_transaction(self):
  1045. # setUpTestData() should call _rollback_atomics() so that the
  1046. # transaction doesn't leak.
  1047. self.assertFalse(self._in_atomic_block)
  1048. class DisallowedDatabaseQueriesTests(SimpleTestCase):
  1049. def test_disallowed_database_connections(self):
  1050. expected_message = (
  1051. "Database connections to 'default' are not allowed in SimpleTestCase "
  1052. "subclasses. Either subclass TestCase or TransactionTestCase to "
  1053. "ensure proper test isolation or add 'default' to "
  1054. "test_utils.tests.DisallowedDatabaseQueriesTests.databases to "
  1055. "silence this failure."
  1056. )
  1057. with self.assertRaisesMessage(AssertionError, expected_message):
  1058. connection.connect()
  1059. with self.assertRaisesMessage(AssertionError, expected_message):
  1060. connection.temporary_connection()
  1061. def test_disallowed_database_queries(self):
  1062. expected_message = (
  1063. "Database queries to 'default' are not allowed in SimpleTestCase "
  1064. "subclasses. Either subclass TestCase or TransactionTestCase to "
  1065. "ensure proper test isolation or add 'default' to "
  1066. "test_utils.tests.DisallowedDatabaseQueriesTests.databases to "
  1067. "silence this failure."
  1068. )
  1069. with self.assertRaisesMessage(AssertionError, expected_message):
  1070. Car.objects.first()
  1071. def test_disallowed_database_chunked_cursor_queries(self):
  1072. expected_message = (
  1073. "Database queries to 'default' are not allowed in SimpleTestCase "
  1074. "subclasses. Either subclass TestCase or TransactionTestCase to "
  1075. "ensure proper test isolation or add 'default' to "
  1076. "test_utils.tests.DisallowedDatabaseQueriesTests.databases to "
  1077. "silence this failure."
  1078. )
  1079. with self.assertRaisesMessage(AssertionError, expected_message):
  1080. next(Car.objects.iterator())
  1081. class AllowedDatabaseQueriesTests(SimpleTestCase):
  1082. databases = {'default'}
  1083. def test_allowed_database_queries(self):
  1084. Car.objects.first()
  1085. def test_allowed_database_chunked_cursor_queries(self):
  1086. next(Car.objects.iterator(), None)
  1087. class DatabaseAliasTests(SimpleTestCase):
  1088. def setUp(self):
  1089. self.addCleanup(setattr, self.__class__, 'databases', self.databases)
  1090. def test_no_close_match(self):
  1091. self.__class__.databases = {'void'}
  1092. message = (
  1093. "test_utils.tests.DatabaseAliasTests.databases refers to 'void' which is not defined "
  1094. "in settings.DATABASES."
  1095. )
  1096. with self.assertRaisesMessage(ImproperlyConfigured, message):
  1097. self._validate_databases()
  1098. def test_close_match(self):
  1099. self.__class__.databases = {'defualt'}
  1100. message = (
  1101. "test_utils.tests.DatabaseAliasTests.databases refers to 'defualt' which is not defined "
  1102. "in settings.DATABASES. Did you mean 'default'?"
  1103. )
  1104. with self.assertRaisesMessage(ImproperlyConfigured, message):
  1105. self._validate_databases()
  1106. def test_match(self):
  1107. self.__class__.databases = {'default', 'other'}
  1108. self.assertEqual(self._validate_databases(), frozenset({'default', 'other'}))
  1109. def test_all(self):
  1110. self.__class__.databases = '__all__'
  1111. self.assertEqual(self._validate_databases(), frozenset(connections))
  1112. @isolate_apps('test_utils', attr_name='class_apps')
  1113. class IsolatedAppsTests(SimpleTestCase):
  1114. def test_installed_apps(self):
  1115. self.assertEqual([app_config.label for app_config in self.class_apps.get_app_configs()], ['test_utils'])
  1116. def test_class_decoration(self):
  1117. class ClassDecoration(models.Model):
  1118. pass
  1119. self.assertEqual(ClassDecoration._meta.apps, self.class_apps)
  1120. @isolate_apps('test_utils', kwarg_name='method_apps')
  1121. def test_method_decoration(self, method_apps):
  1122. class MethodDecoration(models.Model):
  1123. pass
  1124. self.assertEqual(MethodDecoration._meta.apps, method_apps)
  1125. def test_context_manager(self):
  1126. with isolate_apps('test_utils') as context_apps:
  1127. class ContextManager(models.Model):
  1128. pass
  1129. self.assertEqual(ContextManager._meta.apps, context_apps)
  1130. @isolate_apps('test_utils', kwarg_name='method_apps')
  1131. def test_nested(self, method_apps):
  1132. class MethodDecoration(models.Model):
  1133. pass
  1134. with isolate_apps('test_utils') as context_apps:
  1135. class ContextManager(models.Model):
  1136. pass
  1137. with isolate_apps('test_utils') as nested_context_apps:
  1138. class NestedContextManager(models.Model):
  1139. pass
  1140. self.assertEqual(MethodDecoration._meta.apps, method_apps)
  1141. self.assertEqual(ContextManager._meta.apps, context_apps)
  1142. self.assertEqual(NestedContextManager._meta.apps, nested_context_apps)
  1143. class DoNothingDecorator(TestContextDecorator):
  1144. def enable(self):
  1145. pass
  1146. def disable(self):
  1147. pass
  1148. class TestContextDecoratorTests(SimpleTestCase):
  1149. @mock.patch.object(DoNothingDecorator, 'disable')
  1150. def test_exception_in_setup(self, mock_disable):
  1151. """An exception is setUp() is reraised after disable() is called."""
  1152. class ExceptionInSetUp(unittest.TestCase):
  1153. def setUp(self):
  1154. raise NotImplementedError('reraised')
  1155. decorator = DoNothingDecorator()
  1156. decorated_test_class = decorator.__call__(ExceptionInSetUp)()
  1157. self.assertFalse(mock_disable.called)
  1158. with self.assertRaisesMessage(NotImplementedError, 'reraised'):
  1159. decorated_test_class.setUp()
  1160. self.assertTrue(mock_disable.called)