tests.py 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153
  1. import os
  2. import unittest
  3. import warnings
  4. from io import StringIO
  5. from unittest import mock
  6. from django.conf import STATICFILES_STORAGE_ALIAS, 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 (
  12. IntegrityError,
  13. connection,
  14. connections,
  15. models,
  16. router,
  17. transaction,
  18. )
  19. from django.forms import (
  20. CharField,
  21. EmailField,
  22. Form,
  23. IntegerField,
  24. ValidationError,
  25. formset_factory,
  26. )
  27. from django.http import HttpResponse
  28. from django.template.loader import render_to_string
  29. from django.test import (
  30. SimpleTestCase,
  31. TestCase,
  32. TransactionTestCase,
  33. skipIfDBFeature,
  34. skipUnlessDBFeature,
  35. )
  36. from django.test.html import HTMLParseError, parse_html
  37. from django.test.testcases import DatabaseOperationForbidden
  38. from django.test.utils import (
  39. CaptureQueriesContext,
  40. TestContextDecorator,
  41. ignore_warnings,
  42. isolate_apps,
  43. override_settings,
  44. setup_test_environment,
  45. )
  46. from django.urls import NoReverseMatch, path, reverse, reverse_lazy
  47. from django.utils.deprecation import RemovedInDjango51Warning
  48. from django.utils.html import VOID_ELEMENTS
  49. from django.utils.version import PY311
  50. from .models import Car, Person, PossessedCar
  51. from .views import empty_response
  52. class SkippingTestCase(SimpleTestCase):
  53. def _assert_skipping(self, func, expected_exc, msg=None):
  54. try:
  55. if msg is not None:
  56. with self.assertRaisesMessage(expected_exc, msg):
  57. func()
  58. else:
  59. with self.assertRaises(expected_exc):
  60. func()
  61. except unittest.SkipTest:
  62. self.fail("%s should not result in a skipped test." % func.__name__)
  63. def test_skip_unless_db_feature(self):
  64. """
  65. Testing the django.test.skipUnlessDBFeature decorator.
  66. """
  67. # Total hack, but it works, just want an attribute that's always true.
  68. @skipUnlessDBFeature("__class__")
  69. def test_func():
  70. raise ValueError
  71. @skipUnlessDBFeature("notprovided")
  72. def test_func2():
  73. raise ValueError
  74. @skipUnlessDBFeature("__class__", "__class__")
  75. def test_func3():
  76. raise ValueError
  77. @skipUnlessDBFeature("__class__", "notprovided")
  78. def test_func4():
  79. raise ValueError
  80. self._assert_skipping(test_func, ValueError)
  81. self._assert_skipping(test_func2, unittest.SkipTest)
  82. self._assert_skipping(test_func3, ValueError)
  83. self._assert_skipping(test_func4, unittest.SkipTest)
  84. class SkipTestCase(SimpleTestCase):
  85. @skipUnlessDBFeature("missing")
  86. def test_foo(self):
  87. pass
  88. self._assert_skipping(
  89. SkipTestCase("test_foo").test_foo,
  90. ValueError,
  91. "skipUnlessDBFeature cannot be used on test_foo (test_utils.tests."
  92. "SkippingTestCase.test_skip_unless_db_feature.<locals>.SkipTestCase%s) "
  93. "as SkippingTestCase.test_skip_unless_db_feature.<locals>.SkipTestCase "
  94. "doesn't allow queries against the 'default' database."
  95. # Python 3.11 uses fully qualified test name in the output.
  96. % (".test_foo" if PY311 else ""),
  97. )
  98. def test_skip_if_db_feature(self):
  99. """
  100. Testing the django.test.skipIfDBFeature decorator.
  101. """
  102. @skipIfDBFeature("__class__")
  103. def test_func():
  104. raise ValueError
  105. @skipIfDBFeature("notprovided")
  106. def test_func2():
  107. raise ValueError
  108. @skipIfDBFeature("__class__", "__class__")
  109. def test_func3():
  110. raise ValueError
  111. @skipIfDBFeature("__class__", "notprovided")
  112. def test_func4():
  113. raise ValueError
  114. @skipIfDBFeature("notprovided", "notprovided")
  115. def test_func5():
  116. raise ValueError
  117. self._assert_skipping(test_func, unittest.SkipTest)
  118. self._assert_skipping(test_func2, ValueError)
  119. self._assert_skipping(test_func3, unittest.SkipTest)
  120. self._assert_skipping(test_func4, unittest.SkipTest)
  121. self._assert_skipping(test_func5, ValueError)
  122. class SkipTestCase(SimpleTestCase):
  123. @skipIfDBFeature("missing")
  124. def test_foo(self):
  125. pass
  126. self._assert_skipping(
  127. SkipTestCase("test_foo").test_foo,
  128. ValueError,
  129. "skipIfDBFeature cannot be used on test_foo (test_utils.tests."
  130. "SkippingTestCase.test_skip_if_db_feature.<locals>.SkipTestCase%s) "
  131. "as SkippingTestCase.test_skip_if_db_feature.<locals>.SkipTestCase "
  132. "doesn't allow queries against the 'default' database."
  133. # Python 3.11 uses fully qualified test name in the output.
  134. % (".test_foo" if PY311 else ""),
  135. )
  136. class SkippingClassTestCase(TestCase):
  137. def test_skip_class_unless_db_feature(self):
  138. @skipUnlessDBFeature("__class__")
  139. class NotSkippedTests(TestCase):
  140. def test_dummy(self):
  141. return
  142. @skipUnlessDBFeature("missing")
  143. @skipIfDBFeature("__class__")
  144. class SkippedTests(TestCase):
  145. def test_will_be_skipped(self):
  146. self.fail("We should never arrive here.")
  147. @skipIfDBFeature("__dict__")
  148. class SkippedTestsSubclass(SkippedTests):
  149. pass
  150. test_suite = unittest.TestSuite()
  151. test_suite.addTest(NotSkippedTests("test_dummy"))
  152. try:
  153. test_suite.addTest(SkippedTests("test_will_be_skipped"))
  154. test_suite.addTest(SkippedTestsSubclass("test_will_be_skipped"))
  155. except unittest.SkipTest:
  156. self.fail("SkipTest should not be raised here.")
  157. result = unittest.TextTestRunner(stream=StringIO()).run(test_suite)
  158. self.assertEqual(result.testsRun, 3)
  159. self.assertEqual(len(result.skipped), 2)
  160. self.assertEqual(result.skipped[0][1], "Database has feature(s) __class__")
  161. self.assertEqual(result.skipped[1][1], "Database has feature(s) __class__")
  162. def test_missing_default_databases(self):
  163. @skipIfDBFeature("missing")
  164. class MissingDatabases(SimpleTestCase):
  165. def test_assertion_error(self):
  166. pass
  167. suite = unittest.TestSuite()
  168. try:
  169. suite.addTest(MissingDatabases("test_assertion_error"))
  170. except unittest.SkipTest:
  171. self.fail("SkipTest should not be raised at this stage")
  172. runner = unittest.TextTestRunner(stream=StringIO())
  173. msg = (
  174. "skipIfDBFeature cannot be used on <class 'test_utils.tests."
  175. "SkippingClassTestCase.test_missing_default_databases.<locals>."
  176. "MissingDatabases'> as it doesn't allow queries against the "
  177. "'default' database."
  178. )
  179. with self.assertRaisesMessage(ValueError, msg):
  180. runner.run(suite)
  181. @override_settings(ROOT_URLCONF="test_utils.urls")
  182. class AssertNumQueriesTests(TestCase):
  183. def test_assert_num_queries(self):
  184. def test_func():
  185. raise ValueError
  186. with self.assertRaises(ValueError):
  187. self.assertNumQueries(2, test_func)
  188. def test_assert_num_queries_with_client(self):
  189. person = Person.objects.create(name="test")
  190. self.assertNumQueries(
  191. 1, self.client.get, "/test_utils/get_person/%s/" % person.pk
  192. )
  193. self.assertNumQueries(
  194. 1, self.client.get, "/test_utils/get_person/%s/" % person.pk
  195. )
  196. def test_func():
  197. self.client.get("/test_utils/get_person/%s/" % person.pk)
  198. self.client.get("/test_utils/get_person/%s/" % person.pk)
  199. self.assertNumQueries(2, test_func)
  200. class AssertNumQueriesUponConnectionTests(TransactionTestCase):
  201. available_apps = []
  202. def test_ignores_connection_configuration_queries(self):
  203. real_ensure_connection = connection.ensure_connection
  204. connection.close()
  205. def make_configuration_query():
  206. is_opening_connection = connection.connection is None
  207. real_ensure_connection()
  208. if is_opening_connection:
  209. # Avoid infinite recursion. Creating a cursor calls
  210. # ensure_connection() which is currently mocked by this method.
  211. with connection.cursor() as cursor:
  212. cursor.execute("SELECT 1" + connection.features.bare_select_suffix)
  213. ensure_connection = (
  214. "django.db.backends.base.base.BaseDatabaseWrapper.ensure_connection"
  215. )
  216. with mock.patch(ensure_connection, side_effect=make_configuration_query):
  217. with self.assertNumQueries(1):
  218. list(Car.objects.all())
  219. class AssertQuerySetEqualTests(TestCase):
  220. @classmethod
  221. def setUpTestData(cls):
  222. cls.p1 = Person.objects.create(name="p1")
  223. cls.p2 = Person.objects.create(name="p2")
  224. def test_rename_assertquerysetequal_deprecation_warning(self):
  225. msg = "assertQuerysetEqual() is deprecated in favor of assertQuerySetEqual()."
  226. with self.assertRaisesMessage(RemovedInDjango51Warning, msg):
  227. self.assertQuerysetEqual()
  228. @ignore_warnings(category=RemovedInDjango51Warning)
  229. def test_deprecated_assertquerysetequal(self):
  230. self.assertQuerysetEqual(Person.objects.filter(name="p3"), [])
  231. def test_empty(self):
  232. self.assertQuerySetEqual(Person.objects.filter(name="p3"), [])
  233. def test_ordered(self):
  234. self.assertQuerySetEqual(
  235. Person.objects.order_by("name"),
  236. [self.p1, self.p2],
  237. )
  238. def test_unordered(self):
  239. self.assertQuerySetEqual(
  240. Person.objects.order_by("name"), [self.p2, self.p1], ordered=False
  241. )
  242. def test_queryset(self):
  243. self.assertQuerySetEqual(
  244. Person.objects.order_by("name"),
  245. Person.objects.order_by("name"),
  246. )
  247. def test_flat_values_list(self):
  248. self.assertQuerySetEqual(
  249. Person.objects.order_by("name").values_list("name", flat=True),
  250. ["p1", "p2"],
  251. )
  252. def test_transform(self):
  253. self.assertQuerySetEqual(
  254. Person.objects.order_by("name"),
  255. [self.p1.pk, self.p2.pk],
  256. transform=lambda x: x.pk,
  257. )
  258. def test_repr_transform(self):
  259. self.assertQuerySetEqual(
  260. Person.objects.order_by("name"),
  261. [repr(self.p1), repr(self.p2)],
  262. transform=repr,
  263. )
  264. def test_undefined_order(self):
  265. # Using an unordered queryset with more than one ordered value
  266. # is an error.
  267. msg = (
  268. "Trying to compare non-ordered queryset against more than one "
  269. "ordered value."
  270. )
  271. with self.assertRaisesMessage(ValueError, msg):
  272. self.assertQuerySetEqual(
  273. Person.objects.all(),
  274. [self.p1, self.p2],
  275. )
  276. # No error for one value.
  277. self.assertQuerySetEqual(Person.objects.filter(name="p1"), [self.p1])
  278. def test_repeated_values(self):
  279. """
  280. assertQuerySetEqual checks the number of appearance of each item
  281. when used with option ordered=False.
  282. """
  283. batmobile = Car.objects.create(name="Batmobile")
  284. k2000 = Car.objects.create(name="K 2000")
  285. PossessedCar.objects.bulk_create(
  286. [
  287. PossessedCar(car=batmobile, belongs_to=self.p1),
  288. PossessedCar(car=batmobile, belongs_to=self.p1),
  289. PossessedCar(car=k2000, belongs_to=self.p1),
  290. PossessedCar(car=k2000, belongs_to=self.p1),
  291. PossessedCar(car=k2000, belongs_to=self.p1),
  292. PossessedCar(car=k2000, belongs_to=self.p1),
  293. ]
  294. )
  295. with self.assertRaises(AssertionError):
  296. self.assertQuerySetEqual(
  297. self.p1.cars.all(), [batmobile, k2000], ordered=False
  298. )
  299. self.assertQuerySetEqual(
  300. self.p1.cars.all(), [batmobile] * 2 + [k2000] * 4, ordered=False
  301. )
  302. def test_maxdiff(self):
  303. names = ["Joe Smith %s" % i for i in range(20)]
  304. Person.objects.bulk_create([Person(name=name) for name in names])
  305. names.append("Extra Person")
  306. with self.assertRaises(AssertionError) as ctx:
  307. self.assertQuerySetEqual(
  308. Person.objects.filter(name__startswith="Joe"),
  309. names,
  310. ordered=False,
  311. transform=lambda p: p.name,
  312. )
  313. self.assertIn("Set self.maxDiff to None to see it.", str(ctx.exception))
  314. original = self.maxDiff
  315. self.maxDiff = None
  316. try:
  317. with self.assertRaises(AssertionError) as ctx:
  318. self.assertQuerySetEqual(
  319. Person.objects.filter(name__startswith="Joe"),
  320. names,
  321. ordered=False,
  322. transform=lambda p: p.name,
  323. )
  324. finally:
  325. self.maxDiff = original
  326. exception_msg = str(ctx.exception)
  327. self.assertNotIn("Set self.maxDiff to None to see it.", exception_msg)
  328. for name in names:
  329. self.assertIn(name, exception_msg)
  330. @override_settings(ROOT_URLCONF="test_utils.urls")
  331. class CaptureQueriesContextManagerTests(TestCase):
  332. @classmethod
  333. def setUpTestData(cls):
  334. cls.person_pk = str(Person.objects.create(name="test").pk)
  335. def test_simple(self):
  336. with CaptureQueriesContext(connection) as captured_queries:
  337. Person.objects.get(pk=self.person_pk)
  338. self.assertEqual(len(captured_queries), 1)
  339. self.assertIn(self.person_pk, captured_queries[0]["sql"])
  340. with CaptureQueriesContext(connection) as captured_queries:
  341. pass
  342. self.assertEqual(0, len(captured_queries))
  343. def test_within(self):
  344. with CaptureQueriesContext(connection) as captured_queries:
  345. Person.objects.get(pk=self.person_pk)
  346. self.assertEqual(len(captured_queries), 1)
  347. self.assertIn(self.person_pk, captured_queries[0]["sql"])
  348. def test_nested(self):
  349. with CaptureQueriesContext(connection) as captured_queries:
  350. Person.objects.count()
  351. with CaptureQueriesContext(connection) as nested_captured_queries:
  352. Person.objects.count()
  353. self.assertEqual(1, len(nested_captured_queries))
  354. self.assertEqual(2, len(captured_queries))
  355. def test_failure(self):
  356. with self.assertRaises(TypeError):
  357. with CaptureQueriesContext(connection):
  358. raise TypeError
  359. def test_with_client(self):
  360. with CaptureQueriesContext(connection) as captured_queries:
  361. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  362. self.assertEqual(len(captured_queries), 1)
  363. self.assertIn(self.person_pk, captured_queries[0]["sql"])
  364. with CaptureQueriesContext(connection) as captured_queries:
  365. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  366. self.assertEqual(len(captured_queries), 1)
  367. self.assertIn(self.person_pk, captured_queries[0]["sql"])
  368. with CaptureQueriesContext(connection) as captured_queries:
  369. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  370. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  371. self.assertEqual(len(captured_queries), 2)
  372. self.assertIn(self.person_pk, captured_queries[0]["sql"])
  373. self.assertIn(self.person_pk, captured_queries[1]["sql"])
  374. @override_settings(ROOT_URLCONF="test_utils.urls")
  375. class AssertNumQueriesContextManagerTests(TestCase):
  376. def test_simple(self):
  377. with self.assertNumQueries(0):
  378. pass
  379. with self.assertNumQueries(1):
  380. Person.objects.count()
  381. with self.assertNumQueries(2):
  382. Person.objects.count()
  383. Person.objects.count()
  384. def test_failure(self):
  385. msg = "1 != 2 : 1 queries executed, 2 expected\nCaptured queries were:\n1."
  386. with self.assertRaisesMessage(AssertionError, msg):
  387. with self.assertNumQueries(2):
  388. Person.objects.count()
  389. with self.assertRaises(TypeError):
  390. with self.assertNumQueries(4000):
  391. raise TypeError
  392. def test_with_client(self):
  393. person = Person.objects.create(name="test")
  394. with self.assertNumQueries(1):
  395. self.client.get("/test_utils/get_person/%s/" % person.pk)
  396. with self.assertNumQueries(1):
  397. self.client.get("/test_utils/get_person/%s/" % person.pk)
  398. with self.assertNumQueries(2):
  399. self.client.get("/test_utils/get_person/%s/" % person.pk)
  400. self.client.get("/test_utils/get_person/%s/" % person.pk)
  401. @override_settings(ROOT_URLCONF="test_utils.urls")
  402. class AssertTemplateUsedContextManagerTests(SimpleTestCase):
  403. def test_usage(self):
  404. with self.assertTemplateUsed("template_used/base.html"):
  405. render_to_string("template_used/base.html")
  406. with self.assertTemplateUsed(template_name="template_used/base.html"):
  407. render_to_string("template_used/base.html")
  408. with self.assertTemplateUsed("template_used/base.html"):
  409. render_to_string("template_used/include.html")
  410. with self.assertTemplateUsed("template_used/base.html"):
  411. render_to_string("template_used/extends.html")
  412. with self.assertTemplateUsed("template_used/base.html"):
  413. render_to_string("template_used/base.html")
  414. render_to_string("template_used/base.html")
  415. def test_nested_usage(self):
  416. with self.assertTemplateUsed("template_used/base.html"):
  417. with self.assertTemplateUsed("template_used/include.html"):
  418. render_to_string("template_used/include.html")
  419. with self.assertTemplateUsed("template_used/extends.html"):
  420. with self.assertTemplateUsed("template_used/base.html"):
  421. render_to_string("template_used/extends.html")
  422. with self.assertTemplateUsed("template_used/base.html"):
  423. with self.assertTemplateUsed("template_used/alternative.html"):
  424. render_to_string("template_used/alternative.html")
  425. render_to_string("template_used/base.html")
  426. with self.assertTemplateUsed("template_used/base.html"):
  427. render_to_string("template_used/extends.html")
  428. with self.assertTemplateNotUsed("template_used/base.html"):
  429. render_to_string("template_used/alternative.html")
  430. render_to_string("template_used/base.html")
  431. def test_not_used(self):
  432. with self.assertTemplateNotUsed("template_used/base.html"):
  433. pass
  434. with self.assertTemplateNotUsed("template_used/alternative.html"):
  435. pass
  436. def test_error_message(self):
  437. msg = "No templates used to render the response"
  438. with self.assertRaisesMessage(AssertionError, msg):
  439. with self.assertTemplateUsed("template_used/base.html"):
  440. pass
  441. with self.assertRaisesMessage(AssertionError, msg):
  442. with self.assertTemplateUsed(template_name="template_used/base.html"):
  443. pass
  444. msg2 = (
  445. "Template 'template_used/base.html' was not a template used to render "
  446. "the response. Actual template(s) used: template_used/alternative.html"
  447. )
  448. with self.assertRaisesMessage(AssertionError, msg2):
  449. with self.assertTemplateUsed("template_used/base.html"):
  450. render_to_string("template_used/alternative.html")
  451. with self.assertRaisesMessage(
  452. AssertionError, "No templates used to render the response"
  453. ):
  454. response = self.client.get("/test_utils/no_template_used/")
  455. self.assertTemplateUsed(response, "template_used/base.html")
  456. def test_msg_prefix(self):
  457. msg_prefix = "Prefix"
  458. msg = f"{msg_prefix}: No templates used to render the response"
  459. with self.assertRaisesMessage(AssertionError, msg):
  460. with self.assertTemplateUsed(
  461. "template_used/base.html", msg_prefix=msg_prefix
  462. ):
  463. pass
  464. with self.assertRaisesMessage(AssertionError, msg):
  465. with self.assertTemplateUsed(
  466. template_name="template_used/base.html",
  467. msg_prefix=msg_prefix,
  468. ):
  469. pass
  470. msg = (
  471. f"{msg_prefix}: Template 'template_used/base.html' was not a "
  472. f"template used to render the response. Actual template(s) used: "
  473. f"template_used/alternative.html"
  474. )
  475. with self.assertRaisesMessage(AssertionError, msg):
  476. with self.assertTemplateUsed(
  477. "template_used/base.html", msg_prefix=msg_prefix
  478. ):
  479. render_to_string("template_used/alternative.html")
  480. def test_count(self):
  481. with self.assertTemplateUsed("template_used/base.html", count=2):
  482. render_to_string("template_used/base.html")
  483. render_to_string("template_used/base.html")
  484. msg = (
  485. "Template 'template_used/base.html' was expected to be rendered "
  486. "3 time(s) but was actually rendered 2 time(s)."
  487. )
  488. with self.assertRaisesMessage(AssertionError, msg):
  489. with self.assertTemplateUsed("template_used/base.html", count=3):
  490. render_to_string("template_used/base.html")
  491. render_to_string("template_used/base.html")
  492. def test_failure(self):
  493. msg = "response and/or template_name argument must be provided"
  494. with self.assertRaisesMessage(TypeError, msg):
  495. with self.assertTemplateUsed():
  496. pass
  497. msg = "No templates used to render the response"
  498. with self.assertRaisesMessage(AssertionError, msg):
  499. with self.assertTemplateUsed(""):
  500. pass
  501. with self.assertRaisesMessage(AssertionError, msg):
  502. with self.assertTemplateUsed(""):
  503. render_to_string("template_used/base.html")
  504. with self.assertRaisesMessage(AssertionError, msg):
  505. with self.assertTemplateUsed(template_name=""):
  506. pass
  507. msg = (
  508. "Template 'template_used/base.html' was not a template used to "
  509. "render the response. Actual template(s) used: "
  510. "template_used/alternative.html"
  511. )
  512. with self.assertRaisesMessage(AssertionError, msg):
  513. with self.assertTemplateUsed("template_used/base.html"):
  514. render_to_string("template_used/alternative.html")
  515. def test_assert_used_on_http_response(self):
  516. response = HttpResponse()
  517. msg = "%s() is only usable on responses fetched using the Django test Client."
  518. with self.assertRaisesMessage(ValueError, msg % "assertTemplateUsed"):
  519. self.assertTemplateUsed(response, "template.html")
  520. with self.assertRaisesMessage(ValueError, msg % "assertTemplateNotUsed"):
  521. self.assertTemplateNotUsed(response, "template.html")
  522. class HTMLEqualTests(SimpleTestCase):
  523. def test_html_parser(self):
  524. element = parse_html("<div><p>Hello</p></div>")
  525. self.assertEqual(len(element.children), 1)
  526. self.assertEqual(element.children[0].name, "p")
  527. self.assertEqual(element.children[0].children[0], "Hello")
  528. parse_html("<p>")
  529. parse_html("<p attr>")
  530. dom = parse_html("<p>foo")
  531. self.assertEqual(len(dom.children), 1)
  532. self.assertEqual(dom.name, "p")
  533. self.assertEqual(dom[0], "foo")
  534. def test_parse_html_in_script(self):
  535. parse_html('<script>var a = "<p" + ">";</script>')
  536. parse_html(
  537. """
  538. <script>
  539. var js_sha_link='<p>***</p>';
  540. </script>
  541. """
  542. )
  543. # script content will be parsed to text
  544. dom = parse_html(
  545. """
  546. <script><p>foo</p> '</scr'+'ipt>' <span>bar</span></script>
  547. """
  548. )
  549. self.assertEqual(len(dom.children), 1)
  550. self.assertEqual(dom.children[0], "<p>foo</p> '</scr'+'ipt>' <span>bar</span>")
  551. def test_void_elements(self):
  552. for tag in VOID_ELEMENTS:
  553. with self.subTest(tag):
  554. dom = parse_html("<p>Hello <%s> world</p>" % tag)
  555. self.assertEqual(len(dom.children), 3)
  556. self.assertEqual(dom[0], "Hello")
  557. self.assertEqual(dom[1].name, tag)
  558. self.assertEqual(dom[2], "world")
  559. dom = parse_html("<p>Hello <%s /> world</p>" % tag)
  560. self.assertEqual(len(dom.children), 3)
  561. self.assertEqual(dom[0], "Hello")
  562. self.assertEqual(dom[1].name, tag)
  563. self.assertEqual(dom[2], "world")
  564. def test_simple_equal_html(self):
  565. self.assertHTMLEqual("", "")
  566. self.assertHTMLEqual("<p></p>", "<p></p>")
  567. self.assertHTMLEqual("<p></p>", " <p> </p> ")
  568. self.assertHTMLEqual("<div><p>Hello</p></div>", "<div><p>Hello</p></div>")
  569. self.assertHTMLEqual("<div><p>Hello</p></div>", "<div> <p>Hello</p> </div>")
  570. self.assertHTMLEqual("<div>\n<p>Hello</p></div>", "<div><p>Hello</p></div>\n")
  571. self.assertHTMLEqual(
  572. "<div><p>Hello\nWorld !</p></div>", "<div><p>Hello World\n!</p></div>"
  573. )
  574. self.assertHTMLEqual(
  575. "<div><p>Hello\nWorld !</p></div>", "<div><p>Hello World\n!</p></div>"
  576. )
  577. self.assertHTMLEqual("<p>Hello World !</p>", "<p>Hello World\n\n!</p>")
  578. self.assertHTMLEqual("<p> </p>", "<p></p>")
  579. self.assertHTMLEqual("<p/>", "<p></p>")
  580. self.assertHTMLEqual("<p />", "<p></p>")
  581. self.assertHTMLEqual("<input checked>", '<input checked="checked">')
  582. self.assertHTMLEqual("<p>Hello", "<p> Hello")
  583. self.assertHTMLEqual("<p>Hello</p>World", "<p>Hello</p> World")
  584. def test_ignore_comments(self):
  585. self.assertHTMLEqual(
  586. "<div>Hello<!-- this is a comment --> World!</div>",
  587. "<div>Hello World!</div>",
  588. )
  589. def test_unequal_html(self):
  590. self.assertHTMLNotEqual("<p>Hello</p>", "<p>Hello!</p>")
  591. self.assertHTMLNotEqual("<p>foo&#20;bar</p>", "<p>foo&nbsp;bar</p>")
  592. self.assertHTMLNotEqual("<p>foo bar</p>", "<p>foo &nbsp;bar</p>")
  593. self.assertHTMLNotEqual("<p>foo nbsp</p>", "<p>foo &nbsp;</p>")
  594. self.assertHTMLNotEqual("<p>foo #20</p>", "<p>foo &#20;</p>")
  595. self.assertHTMLNotEqual(
  596. "<p><span>Hello</span><span>World</span></p>",
  597. "<p><span>Hello</span>World</p>",
  598. )
  599. self.assertHTMLNotEqual(
  600. "<p><span>Hello</span>World</p>",
  601. "<p><span>Hello</span><span>World</span></p>",
  602. )
  603. def test_attributes(self):
  604. self.assertHTMLEqual(
  605. '<input type="text" id="id_name" />', '<input id="id_name" type="text" />'
  606. )
  607. self.assertHTMLEqual(
  608. """<input type='text' id="id_name" />""",
  609. '<input id="id_name" type="text" />',
  610. )
  611. self.assertHTMLNotEqual(
  612. '<input type="text" id="id_name" />',
  613. '<input type="password" id="id_name" />',
  614. )
  615. def test_class_attribute(self):
  616. pairs = [
  617. ('<p class="foo bar"></p>', '<p class="bar foo"></p>'),
  618. ('<p class=" foo bar "></p>', '<p class="bar foo"></p>'),
  619. ('<p class=" foo bar "></p>', '<p class="bar foo"></p>'),
  620. ('<p class="foo\tbar"></p>', '<p class="bar foo"></p>'),
  621. ('<p class="\tfoo\tbar\t"></p>', '<p class="bar foo"></p>'),
  622. ('<p class="\t\t\tfoo\t\t\tbar\t\t\t"></p>', '<p class="bar foo"></p>'),
  623. ('<p class="\t \nfoo \t\nbar\n\t "></p>', '<p class="bar foo"></p>'),
  624. ]
  625. for html1, html2 in pairs:
  626. with self.subTest(html1):
  627. self.assertHTMLEqual(html1, html2)
  628. def test_boolean_attribute(self):
  629. html1 = "<input checked>"
  630. html2 = '<input checked="">'
  631. html3 = '<input checked="checked">'
  632. self.assertHTMLEqual(html1, html2)
  633. self.assertHTMLEqual(html1, html3)
  634. self.assertHTMLEqual(html2, html3)
  635. self.assertHTMLNotEqual(html1, '<input checked="invalid">')
  636. self.assertEqual(str(parse_html(html1)), "<input checked>")
  637. self.assertEqual(str(parse_html(html2)), "<input checked>")
  638. self.assertEqual(str(parse_html(html3)), "<input checked>")
  639. def test_non_boolean_attibutes(self):
  640. html1 = "<input value>"
  641. html2 = '<input value="">'
  642. html3 = '<input value="value">'
  643. self.assertHTMLEqual(html1, html2)
  644. self.assertHTMLNotEqual(html1, html3)
  645. self.assertEqual(str(parse_html(html1)), '<input value="">')
  646. self.assertEqual(str(parse_html(html2)), '<input value="">')
  647. def test_normalize_refs(self):
  648. pairs = [
  649. ("&#39;", "&#x27;"),
  650. ("&#39;", "'"),
  651. ("&#x27;", "&#39;"),
  652. ("&#x27;", "'"),
  653. ("'", "&#39;"),
  654. ("'", "&#x27;"),
  655. ("&amp;", "&#38;"),
  656. ("&amp;", "&#x26;"),
  657. ("&amp;", "&"),
  658. ("&#38;", "&amp;"),
  659. ("&#38;", "&#x26;"),
  660. ("&#38;", "&"),
  661. ("&#x26;", "&amp;"),
  662. ("&#x26;", "&#38;"),
  663. ("&#x26;", "&"),
  664. ("&", "&amp;"),
  665. ("&", "&#38;"),
  666. ("&", "&#x26;"),
  667. ]
  668. for pair in pairs:
  669. with self.subTest(repr(pair)):
  670. self.assertHTMLEqual(*pair)
  671. def test_complex_examples(self):
  672. self.assertHTMLEqual(
  673. """<tr><th><label for="id_first_name">First name:</label></th>
  674. <td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>
  675. <tr><th><label for="id_last_name">Last name:</label></th>
  676. <td><input type="text" id="id_last_name" name="last_name" value="Lennon" /></td></tr>
  677. <tr><th><label for="id_birthday">Birthday:</label></th>
  678. <td><input type="text" value="1940-10-9" name="birthday" id="id_birthday" /></td></tr>""", # NOQA
  679. """
  680. <tr><th>
  681. <label for="id_first_name">First name:</label></th><td>
  682. <input type="text" name="first_name" value="John" id="id_first_name" />
  683. </td></tr>
  684. <tr><th>
  685. <label for="id_last_name">Last name:</label></th><td>
  686. <input type="text" name="last_name" value="Lennon" id="id_last_name" />
  687. </td></tr>
  688. <tr><th>
  689. <label for="id_birthday">Birthday:</label></th><td>
  690. <input type="text" name="birthday" value="1940-10-9" id="id_birthday" />
  691. </td></tr>
  692. """,
  693. )
  694. self.assertHTMLEqual(
  695. """<!DOCTYPE html>
  696. <html>
  697. <head>
  698. <link rel="stylesheet">
  699. <title>Document</title>
  700. <meta attribute="value">
  701. </head>
  702. <body>
  703. <p>
  704. This is a valid paragraph
  705. <div> this is a div AFTER the p</div>
  706. </body>
  707. </html>""",
  708. """
  709. <html>
  710. <head>
  711. <link rel="stylesheet">
  712. <title>Document</title>
  713. <meta attribute="value">
  714. </head>
  715. <body>
  716. <p> This is a valid paragraph
  717. <!-- browsers would close the p tag here -->
  718. <div> this is a div AFTER the p</div>
  719. </p> <!-- this is invalid HTML parsing, but it should make no
  720. difference in most cases -->
  721. </body>
  722. </html>""",
  723. )
  724. def test_html_contain(self):
  725. # equal html contains each other
  726. dom1 = parse_html("<p>foo")
  727. dom2 = parse_html("<p>foo</p>")
  728. self.assertIn(dom1, dom2)
  729. self.assertIn(dom2, dom1)
  730. dom2 = parse_html("<div><p>foo</p></div>")
  731. self.assertIn(dom1, dom2)
  732. self.assertNotIn(dom2, dom1)
  733. self.assertNotIn("<p>foo</p>", dom2)
  734. self.assertIn("foo", dom2)
  735. # when a root element is used ...
  736. dom1 = parse_html("<p>foo</p><p>bar</p>")
  737. dom2 = parse_html("<p>foo</p><p>bar</p>")
  738. self.assertIn(dom1, dom2)
  739. dom1 = parse_html("<p>foo</p>")
  740. self.assertIn(dom1, dom2)
  741. dom1 = parse_html("<p>bar</p>")
  742. self.assertIn(dom1, dom2)
  743. dom1 = parse_html("<div><p>foo</p><p>bar</p></div>")
  744. self.assertIn(dom2, dom1)
  745. def test_count(self):
  746. # equal html contains each other one time
  747. dom1 = parse_html("<p>foo")
  748. dom2 = parse_html("<p>foo</p>")
  749. self.assertEqual(dom1.count(dom2), 1)
  750. self.assertEqual(dom2.count(dom1), 1)
  751. dom2 = parse_html("<p>foo</p><p>bar</p>")
  752. self.assertEqual(dom2.count(dom1), 1)
  753. dom2 = parse_html("<p>foo foo</p><p>foo</p>")
  754. self.assertEqual(dom2.count("foo"), 3)
  755. dom2 = parse_html('<p class="bar">foo</p>')
  756. self.assertEqual(dom2.count("bar"), 0)
  757. self.assertEqual(dom2.count("class"), 0)
  758. self.assertEqual(dom2.count("p"), 0)
  759. self.assertEqual(dom2.count("o"), 2)
  760. dom2 = parse_html("<p>foo</p><p>foo</p>")
  761. self.assertEqual(dom2.count(dom1), 2)
  762. dom2 = parse_html('<div><p>foo<input type=""></p><p>foo</p></div>')
  763. self.assertEqual(dom2.count(dom1), 1)
  764. dom2 = parse_html("<div><div><p>foo</p></div></div>")
  765. self.assertEqual(dom2.count(dom1), 1)
  766. dom2 = parse_html("<p>foo<p>foo</p></p>")
  767. self.assertEqual(dom2.count(dom1), 1)
  768. dom2 = parse_html("<p>foo<p>bar</p></p>")
  769. self.assertEqual(dom2.count(dom1), 0)
  770. # HTML with a root element contains the same HTML with no root element.
  771. dom1 = parse_html("<p>foo</p><p>bar</p>")
  772. dom2 = parse_html("<div><p>foo</p><p>bar</p></div>")
  773. self.assertEqual(dom2.count(dom1), 1)
  774. # Target of search is a sequence of child elements and appears more
  775. # than once.
  776. dom2 = parse_html("<div><p>foo</p><p>bar</p><p>foo</p><p>bar</p></div>")
  777. self.assertEqual(dom2.count(dom1), 2)
  778. # Searched HTML has additional children.
  779. dom1 = parse_html("<a/><b/>")
  780. dom2 = parse_html("<a/><b/><c/>")
  781. self.assertEqual(dom2.count(dom1), 1)
  782. # No match found in children.
  783. dom1 = parse_html("<b/><a/>")
  784. self.assertEqual(dom2.count(dom1), 0)
  785. # Target of search found among children and grandchildren.
  786. dom1 = parse_html("<b/><b/>")
  787. dom2 = parse_html("<a><b/><b/></a><b/><b/>")
  788. self.assertEqual(dom2.count(dom1), 2)
  789. def test_root_element_escaped_html(self):
  790. html = "&lt;br&gt;"
  791. parsed = parse_html(html)
  792. self.assertEqual(str(parsed), html)
  793. def test_parsing_errors(self):
  794. with self.assertRaises(AssertionError):
  795. self.assertHTMLEqual("<p>", "")
  796. with self.assertRaises(AssertionError):
  797. self.assertHTMLEqual("", "<p>")
  798. error_msg = (
  799. "First argument is not valid HTML:\n"
  800. "('Unexpected end tag `div` (Line 1, Column 6)', (1, 6))"
  801. )
  802. with self.assertRaisesMessage(AssertionError, error_msg):
  803. self.assertHTMLEqual("< div></ div>", "<div></div>")
  804. with self.assertRaises(HTMLParseError):
  805. parse_html("</p>")
  806. def test_escaped_html_errors(self):
  807. msg = "<p>\n<foo>\n</p> != <p>\n&lt;foo&gt;\n</p>\n"
  808. with self.assertRaisesMessage(AssertionError, msg):
  809. self.assertHTMLEqual("<p><foo></p>", "<p>&lt;foo&gt;</p>")
  810. with self.assertRaisesMessage(AssertionError, msg):
  811. self.assertHTMLEqual("<p><foo></p>", "<p>&#60;foo&#62;</p>")
  812. def test_contains_html(self):
  813. response = HttpResponse(
  814. """<body>
  815. This is a form: <form method="get">
  816. <input type="text" name="Hello" />
  817. </form></body>"""
  818. )
  819. self.assertNotContains(response, "<input name='Hello' type='text'>")
  820. self.assertContains(response, '<form method="get">')
  821. self.assertContains(response, "<input name='Hello' type='text'>", html=True)
  822. self.assertNotContains(response, '<form method="get">', html=True)
  823. invalid_response = HttpResponse("""<body <bad>>""")
  824. with self.assertRaises(AssertionError):
  825. self.assertContains(invalid_response, "<p></p>")
  826. with self.assertRaises(AssertionError):
  827. self.assertContains(response, '<p "whats" that>')
  828. def test_unicode_handling(self):
  829. response = HttpResponse(
  830. '<p class="help">Some help text for the title (with Unicode ŠĐĆŽćžšđ)</p>'
  831. )
  832. self.assertContains(
  833. response,
  834. '<p class="help">Some help text for the title (with Unicode ŠĐĆŽćžšđ)</p>',
  835. html=True,
  836. )
  837. class JSONEqualTests(SimpleTestCase):
  838. def test_simple_equal(self):
  839. json1 = '{"attr1": "foo", "attr2":"baz"}'
  840. json2 = '{"attr1": "foo", "attr2":"baz"}'
  841. self.assertJSONEqual(json1, json2)
  842. def test_simple_equal_unordered(self):
  843. json1 = '{"attr1": "foo", "attr2":"baz"}'
  844. json2 = '{"attr2":"baz", "attr1": "foo"}'
  845. self.assertJSONEqual(json1, json2)
  846. def test_simple_equal_raise(self):
  847. json1 = '{"attr1": "foo", "attr2":"baz"}'
  848. json2 = '{"attr2":"baz"}'
  849. with self.assertRaises(AssertionError):
  850. self.assertJSONEqual(json1, json2)
  851. def test_equal_parsing_errors(self):
  852. invalid_json = '{"attr1": "foo, "attr2":"baz"}'
  853. valid_json = '{"attr1": "foo", "attr2":"baz"}'
  854. with self.assertRaises(AssertionError):
  855. self.assertJSONEqual(invalid_json, valid_json)
  856. with self.assertRaises(AssertionError):
  857. self.assertJSONEqual(valid_json, invalid_json)
  858. def test_simple_not_equal(self):
  859. json1 = '{"attr1": "foo", "attr2":"baz"}'
  860. json2 = '{"attr2":"baz"}'
  861. self.assertJSONNotEqual(json1, json2)
  862. def test_simple_not_equal_raise(self):
  863. json1 = '{"attr1": "foo", "attr2":"baz"}'
  864. json2 = '{"attr1": "foo", "attr2":"baz"}'
  865. with self.assertRaises(AssertionError):
  866. self.assertJSONNotEqual(json1, json2)
  867. def test_not_equal_parsing_errors(self):
  868. invalid_json = '{"attr1": "foo, "attr2":"baz"}'
  869. valid_json = '{"attr1": "foo", "attr2":"baz"}'
  870. with self.assertRaises(AssertionError):
  871. self.assertJSONNotEqual(invalid_json, valid_json)
  872. with self.assertRaises(AssertionError):
  873. self.assertJSONNotEqual(valid_json, invalid_json)
  874. class XMLEqualTests(SimpleTestCase):
  875. def test_simple_equal(self):
  876. xml1 = "<elem attr1='a' attr2='b' />"
  877. xml2 = "<elem attr1='a' attr2='b' />"
  878. self.assertXMLEqual(xml1, xml2)
  879. def test_simple_equal_unordered(self):
  880. xml1 = "<elem attr1='a' attr2='b' />"
  881. xml2 = "<elem attr2='b' attr1='a' />"
  882. self.assertXMLEqual(xml1, xml2)
  883. def test_simple_equal_raise(self):
  884. xml1 = "<elem attr1='a' />"
  885. xml2 = "<elem attr2='b' attr1='a' />"
  886. with self.assertRaises(AssertionError):
  887. self.assertXMLEqual(xml1, xml2)
  888. def test_simple_equal_raises_message(self):
  889. xml1 = "<elem attr1='a' />"
  890. xml2 = "<elem attr2='b' attr1='a' />"
  891. msg = """{xml1} != {xml2}
  892. - <elem attr1='a' />
  893. + <elem attr2='b' attr1='a' />
  894. ? ++++++++++
  895. """.format(
  896. xml1=repr(xml1), xml2=repr(xml2)
  897. )
  898. with self.assertRaisesMessage(AssertionError, msg):
  899. self.assertXMLEqual(xml1, xml2)
  900. def test_simple_not_equal(self):
  901. xml1 = "<elem attr1='a' attr2='c' />"
  902. xml2 = "<elem attr1='a' attr2='b' />"
  903. self.assertXMLNotEqual(xml1, xml2)
  904. def test_simple_not_equal_raise(self):
  905. xml1 = "<elem attr1='a' attr2='b' />"
  906. xml2 = "<elem attr2='b' attr1='a' />"
  907. with self.assertRaises(AssertionError):
  908. self.assertXMLNotEqual(xml1, xml2)
  909. def test_parsing_errors(self):
  910. xml_unvalid = "<elem attr1='a attr2='b' />"
  911. xml2 = "<elem attr2='b' attr1='a' />"
  912. with self.assertRaises(AssertionError):
  913. self.assertXMLNotEqual(xml_unvalid, xml2)
  914. def test_comment_root(self):
  915. xml1 = "<?xml version='1.0'?><!-- comment1 --><elem attr1='a' attr2='b' />"
  916. xml2 = "<?xml version='1.0'?><!-- comment2 --><elem attr2='b' attr1='a' />"
  917. self.assertXMLEqual(xml1, xml2)
  918. def test_simple_equal_with_leading_or_trailing_whitespace(self):
  919. xml1 = "<elem>foo</elem> \t\n"
  920. xml2 = " \t\n<elem>foo</elem>"
  921. self.assertXMLEqual(xml1, xml2)
  922. def test_simple_not_equal_with_whitespace_in_the_middle(self):
  923. xml1 = "<elem>foo</elem><elem>bar</elem>"
  924. xml2 = "<elem>foo</elem> <elem>bar</elem>"
  925. self.assertXMLNotEqual(xml1, xml2)
  926. def test_doctype_root(self):
  927. xml1 = '<?xml version="1.0"?><!DOCTYPE root SYSTEM "example1.dtd"><root />'
  928. xml2 = '<?xml version="1.0"?><!DOCTYPE root SYSTEM "example2.dtd"><root />'
  929. self.assertXMLEqual(xml1, xml2)
  930. def test_processing_instruction(self):
  931. xml1 = (
  932. '<?xml version="1.0"?>'
  933. '<?xml-model href="http://www.example1.com"?><root />'
  934. )
  935. xml2 = (
  936. '<?xml version="1.0"?>'
  937. '<?xml-model href="http://www.example2.com"?><root />'
  938. )
  939. self.assertXMLEqual(xml1, xml2)
  940. self.assertXMLEqual(
  941. '<?xml-stylesheet href="style1.xslt" type="text/xsl"?><root />',
  942. '<?xml-stylesheet href="style2.xslt" type="text/xsl"?><root />',
  943. )
  944. class SkippingExtraTests(TestCase):
  945. fixtures = ["should_not_be_loaded.json"]
  946. # HACK: This depends on internals of our TestCase subclasses
  947. def __call__(self, result=None):
  948. # Detect fixture loading by counting SQL queries, should be zero
  949. with self.assertNumQueries(0):
  950. super().__call__(result)
  951. @unittest.skip("Fixture loading should not be performed for skipped tests.")
  952. def test_fixtures_are_skipped(self):
  953. pass
  954. class AssertRaisesMsgTest(SimpleTestCase):
  955. def test_assert_raises_message(self):
  956. msg = "'Expected message' not found in 'Unexpected message'"
  957. # context manager form of assertRaisesMessage()
  958. with self.assertRaisesMessage(AssertionError, msg):
  959. with self.assertRaisesMessage(ValueError, "Expected message"):
  960. raise ValueError("Unexpected message")
  961. # callable form
  962. def func():
  963. raise ValueError("Unexpected message")
  964. with self.assertRaisesMessage(AssertionError, msg):
  965. self.assertRaisesMessage(ValueError, "Expected message", func)
  966. def test_special_re_chars(self):
  967. """assertRaisesMessage shouldn't interpret RE special chars."""
  968. def func1():
  969. raise ValueError("[.*x+]y?")
  970. with self.assertRaisesMessage(ValueError, "[.*x+]y?"):
  971. func1()
  972. class AssertWarnsMessageTests(SimpleTestCase):
  973. def test_context_manager(self):
  974. with self.assertWarnsMessage(UserWarning, "Expected message"):
  975. warnings.warn("Expected message", UserWarning)
  976. def test_context_manager_failure(self):
  977. msg = "Expected message' not found in 'Unexpected message'"
  978. with self.assertRaisesMessage(AssertionError, msg):
  979. with self.assertWarnsMessage(UserWarning, "Expected message"):
  980. warnings.warn("Unexpected message", UserWarning)
  981. def test_callable(self):
  982. def func():
  983. warnings.warn("Expected message", UserWarning)
  984. self.assertWarnsMessage(UserWarning, "Expected message", func)
  985. def test_special_re_chars(self):
  986. def func1():
  987. warnings.warn("[.*x+]y?", UserWarning)
  988. with self.assertWarnsMessage(UserWarning, "[.*x+]y?"):
  989. func1()
  990. class AssertFieldOutputTests(SimpleTestCase):
  991. def test_assert_field_output(self):
  992. error_invalid = ["Enter a valid email address."]
  993. self.assertFieldOutput(
  994. EmailField, {"a@a.com": "a@a.com"}, {"aaa": error_invalid}
  995. )
  996. with self.assertRaises(AssertionError):
  997. self.assertFieldOutput(
  998. EmailField,
  999. {"a@a.com": "a@a.com"},
  1000. {"aaa": error_invalid + ["Another error"]},
  1001. )
  1002. with self.assertRaises(AssertionError):
  1003. self.assertFieldOutput(
  1004. EmailField, {"a@a.com": "Wrong output"}, {"aaa": error_invalid}
  1005. )
  1006. with self.assertRaises(AssertionError):
  1007. self.assertFieldOutput(
  1008. EmailField,
  1009. {"a@a.com": "a@a.com"},
  1010. {"aaa": ["Come on, gimme some well formatted data, dude."]},
  1011. )
  1012. def test_custom_required_message(self):
  1013. class MyCustomField(IntegerField):
  1014. default_error_messages = {
  1015. "required": "This is really required.",
  1016. }
  1017. self.assertFieldOutput(MyCustomField, {}, {}, empty_value=None)
  1018. @override_settings(ROOT_URLCONF="test_utils.urls")
  1019. class AssertURLEqualTests(SimpleTestCase):
  1020. def test_equal(self):
  1021. valid_tests = (
  1022. ("http://example.com/?", "http://example.com/"),
  1023. ("http://example.com/?x=1&", "http://example.com/?x=1"),
  1024. ("http://example.com/?x=1&y=2", "http://example.com/?y=2&x=1"),
  1025. ("http://example.com/?x=1&y=2", "http://example.com/?y=2&x=1"),
  1026. (
  1027. "http://example.com/?x=1&y=2&a=1&a=2",
  1028. "http://example.com/?a=1&a=2&y=2&x=1",
  1029. ),
  1030. ("/path/to/?x=1&y=2&z=3", "/path/to/?z=3&y=2&x=1"),
  1031. ("?x=1&y=2&z=3", "?z=3&y=2&x=1"),
  1032. ("/test_utils/no_template_used/", reverse_lazy("no_template_used")),
  1033. )
  1034. for url1, url2 in valid_tests:
  1035. with self.subTest(url=url1):
  1036. self.assertURLEqual(url1, url2)
  1037. def test_not_equal(self):
  1038. invalid_tests = (
  1039. # Protocol must be the same.
  1040. ("http://example.com/", "https://example.com/"),
  1041. ("http://example.com/?x=1&x=2", "https://example.com/?x=2&x=1"),
  1042. ("http://example.com/?x=1&y=bar&x=2", "https://example.com/?y=bar&x=2&x=1"),
  1043. # Parameters of the same name must be in the same order.
  1044. ("/path/to?a=1&a=2", "/path/to/?a=2&a=1"),
  1045. )
  1046. for url1, url2 in invalid_tests:
  1047. with self.subTest(url=url1), self.assertRaises(AssertionError):
  1048. self.assertURLEqual(url1, url2)
  1049. def test_message(self):
  1050. msg = (
  1051. "Expected 'http://example.com/?x=1&x=2' to equal "
  1052. "'https://example.com/?x=2&x=1'"
  1053. )
  1054. with self.assertRaisesMessage(AssertionError, msg):
  1055. self.assertURLEqual(
  1056. "http://example.com/?x=1&x=2", "https://example.com/?x=2&x=1"
  1057. )
  1058. def test_msg_prefix(self):
  1059. msg = (
  1060. "Prefix: Expected 'http://example.com/?x=1&x=2' to equal "
  1061. "'https://example.com/?x=2&x=1'"
  1062. )
  1063. with self.assertRaisesMessage(AssertionError, msg):
  1064. self.assertURLEqual(
  1065. "http://example.com/?x=1&x=2",
  1066. "https://example.com/?x=2&x=1",
  1067. msg_prefix="Prefix: ",
  1068. )
  1069. class TestForm(Form):
  1070. field = CharField()
  1071. def clean_field(self):
  1072. value = self.cleaned_data.get("field", "")
  1073. if value == "invalid":
  1074. raise ValidationError("invalid value")
  1075. return value
  1076. def clean(self):
  1077. if self.cleaned_data.get("field") == "invalid_non_field":
  1078. raise ValidationError("non-field error")
  1079. return self.cleaned_data
  1080. @classmethod
  1081. def _get_cleaned_form(cls, field_value):
  1082. form = cls({"field": field_value})
  1083. form.full_clean()
  1084. return form
  1085. @classmethod
  1086. def valid(cls):
  1087. return cls._get_cleaned_form("valid")
  1088. @classmethod
  1089. def invalid(cls, nonfield=False):
  1090. return cls._get_cleaned_form("invalid_non_field" if nonfield else "invalid")
  1091. class TestFormset(formset_factory(TestForm)):
  1092. @classmethod
  1093. def _get_cleaned_formset(cls, field_value):
  1094. formset = cls(
  1095. {
  1096. "form-TOTAL_FORMS": "1",
  1097. "form-INITIAL_FORMS": "0",
  1098. "form-0-field": field_value,
  1099. }
  1100. )
  1101. formset.full_clean()
  1102. return formset
  1103. @classmethod
  1104. def valid(cls):
  1105. return cls._get_cleaned_formset("valid")
  1106. @classmethod
  1107. def invalid(cls, nonfield=False, nonform=False):
  1108. if nonform:
  1109. formset = cls({}, error_messages={"missing_management_form": "error"})
  1110. formset.full_clean()
  1111. return formset
  1112. return cls._get_cleaned_formset("invalid_non_field" if nonfield else "invalid")
  1113. class AssertFormErrorTests(SimpleTestCase):
  1114. def test_single_error(self):
  1115. self.assertFormError(TestForm.invalid(), "field", "invalid value")
  1116. def test_error_list(self):
  1117. self.assertFormError(TestForm.invalid(), "field", ["invalid value"])
  1118. def test_empty_errors_valid_form(self):
  1119. self.assertFormError(TestForm.valid(), "field", [])
  1120. def test_empty_errors_valid_form_non_field_errors(self):
  1121. self.assertFormError(TestForm.valid(), None, [])
  1122. def test_field_not_in_form(self):
  1123. msg = (
  1124. "The form <TestForm bound=True, valid=False, fields=(field)> does not "
  1125. "contain the field 'other_field'."
  1126. )
  1127. with self.assertRaisesMessage(AssertionError, msg):
  1128. self.assertFormError(TestForm.invalid(), "other_field", "invalid value")
  1129. msg_prefix = "Custom prefix"
  1130. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1131. self.assertFormError(
  1132. TestForm.invalid(),
  1133. "other_field",
  1134. "invalid value",
  1135. msg_prefix=msg_prefix,
  1136. )
  1137. def test_field_with_no_errors(self):
  1138. msg = (
  1139. "The errors of field 'field' on form <TestForm bound=True, valid=True, "
  1140. "fields=(field)> don't match."
  1141. )
  1142. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1143. self.assertFormError(TestForm.valid(), "field", "invalid value")
  1144. self.assertIn("[] != ['invalid value']", str(ctx.exception))
  1145. msg_prefix = "Custom prefix"
  1146. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1147. self.assertFormError(
  1148. TestForm.valid(), "field", "invalid value", msg_prefix=msg_prefix
  1149. )
  1150. def test_field_with_different_error(self):
  1151. msg = (
  1152. "The errors of field 'field' on form <TestForm bound=True, valid=False, "
  1153. "fields=(field)> don't match."
  1154. )
  1155. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1156. self.assertFormError(TestForm.invalid(), "field", "other error")
  1157. self.assertIn("['invalid value'] != ['other error']", str(ctx.exception))
  1158. msg_prefix = "Custom prefix"
  1159. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1160. self.assertFormError(
  1161. TestForm.invalid(), "field", "other error", msg_prefix=msg_prefix
  1162. )
  1163. def test_unbound_form(self):
  1164. msg = (
  1165. "The form <TestForm bound=False, valid=Unknown, fields=(field)> is not "
  1166. "bound, it will never have any errors."
  1167. )
  1168. with self.assertRaisesMessage(AssertionError, msg):
  1169. self.assertFormError(TestForm(), "field", [])
  1170. msg_prefix = "Custom prefix"
  1171. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1172. self.assertFormError(TestForm(), "field", [], msg_prefix=msg_prefix)
  1173. def test_empty_errors_invalid_form(self):
  1174. msg = (
  1175. "The errors of field 'field' on form <TestForm bound=True, valid=False, "
  1176. "fields=(field)> don't match."
  1177. )
  1178. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1179. self.assertFormError(TestForm.invalid(), "field", [])
  1180. self.assertIn("['invalid value'] != []", str(ctx.exception))
  1181. def test_non_field_errors(self):
  1182. self.assertFormError(TestForm.invalid(nonfield=True), None, "non-field error")
  1183. def test_different_non_field_errors(self):
  1184. msg = (
  1185. "The non-field errors of form <TestForm bound=True, valid=False, "
  1186. "fields=(field)> don't match."
  1187. )
  1188. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1189. self.assertFormError(
  1190. TestForm.invalid(nonfield=True), None, "other non-field error"
  1191. )
  1192. self.assertIn(
  1193. "['non-field error'] != ['other non-field error']", str(ctx.exception)
  1194. )
  1195. msg_prefix = "Custom prefix"
  1196. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1197. self.assertFormError(
  1198. TestForm.invalid(nonfield=True),
  1199. None,
  1200. "other non-field error",
  1201. msg_prefix=msg_prefix,
  1202. )
  1203. class AssertFormSetErrorTests(SimpleTestCase):
  1204. def test_single_error(self):
  1205. self.assertFormSetError(TestFormset.invalid(), 0, "field", "invalid value")
  1206. def test_error_list(self):
  1207. self.assertFormSetError(TestFormset.invalid(), 0, "field", ["invalid value"])
  1208. def test_empty_errors_valid_formset(self):
  1209. self.assertFormSetError(TestFormset.valid(), 0, "field", [])
  1210. def test_multiple_forms(self):
  1211. formset = TestFormset(
  1212. {
  1213. "form-TOTAL_FORMS": "2",
  1214. "form-INITIAL_FORMS": "0",
  1215. "form-0-field": "valid",
  1216. "form-1-field": "invalid",
  1217. }
  1218. )
  1219. formset.full_clean()
  1220. self.assertFormSetError(formset, 0, "field", [])
  1221. self.assertFormSetError(formset, 1, "field", ["invalid value"])
  1222. def test_field_not_in_form(self):
  1223. msg = (
  1224. "The form 0 of formset <TestFormset: bound=True valid=False total_forms=1> "
  1225. "does not contain the field 'other_field'."
  1226. )
  1227. with self.assertRaisesMessage(AssertionError, msg):
  1228. self.assertFormSetError(
  1229. TestFormset.invalid(), 0, "other_field", "invalid value"
  1230. )
  1231. msg_prefix = "Custom prefix"
  1232. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1233. self.assertFormSetError(
  1234. TestFormset.invalid(),
  1235. 0,
  1236. "other_field",
  1237. "invalid value",
  1238. msg_prefix=msg_prefix,
  1239. )
  1240. def test_field_with_no_errors(self):
  1241. msg = (
  1242. "The errors of field 'field' on form 0 of formset <TestFormset: bound=True "
  1243. "valid=True total_forms=1> don't match."
  1244. )
  1245. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1246. self.assertFormSetError(TestFormset.valid(), 0, "field", "invalid value")
  1247. self.assertIn("[] != ['invalid value']", str(ctx.exception))
  1248. msg_prefix = "Custom prefix"
  1249. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1250. self.assertFormSetError(
  1251. TestFormset.valid(), 0, "field", "invalid value", msg_prefix=msg_prefix
  1252. )
  1253. def test_field_with_different_error(self):
  1254. msg = (
  1255. "The errors of field 'field' on form 0 of formset <TestFormset: bound=True "
  1256. "valid=False total_forms=1> don't match."
  1257. )
  1258. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1259. self.assertFormSetError(TestFormset.invalid(), 0, "field", "other error")
  1260. self.assertIn("['invalid value'] != ['other error']", str(ctx.exception))
  1261. msg_prefix = "Custom prefix"
  1262. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1263. self.assertFormSetError(
  1264. TestFormset.invalid(), 0, "field", "other error", msg_prefix=msg_prefix
  1265. )
  1266. def test_unbound_formset(self):
  1267. msg = (
  1268. "The formset <TestFormset: bound=False valid=Unknown total_forms=1> is not "
  1269. "bound, it will never have any errors."
  1270. )
  1271. with self.assertRaisesMessage(AssertionError, msg):
  1272. self.assertFormSetError(TestFormset(), 0, "field", [])
  1273. def test_empty_errors_invalid_formset(self):
  1274. msg = (
  1275. "The errors of field 'field' on form 0 of formset <TestFormset: bound=True "
  1276. "valid=False total_forms=1> don't match."
  1277. )
  1278. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1279. self.assertFormSetError(TestFormset.invalid(), 0, "field", [])
  1280. self.assertIn("['invalid value'] != []", str(ctx.exception))
  1281. def test_non_field_errors(self):
  1282. self.assertFormSetError(
  1283. TestFormset.invalid(nonfield=True), 0, None, "non-field error"
  1284. )
  1285. def test_different_non_field_errors(self):
  1286. msg = (
  1287. "The non-field errors of form 0 of formset <TestFormset: bound=True "
  1288. "valid=False total_forms=1> don't match."
  1289. )
  1290. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1291. self.assertFormSetError(
  1292. TestFormset.invalid(nonfield=True), 0, None, "other non-field error"
  1293. )
  1294. self.assertIn(
  1295. "['non-field error'] != ['other non-field error']", str(ctx.exception)
  1296. )
  1297. msg_prefix = "Custom prefix"
  1298. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1299. self.assertFormSetError(
  1300. TestFormset.invalid(nonfield=True),
  1301. 0,
  1302. None,
  1303. "other non-field error",
  1304. msg_prefix=msg_prefix,
  1305. )
  1306. def test_no_non_field_errors(self):
  1307. msg = (
  1308. "The non-field errors of form 0 of formset <TestFormset: bound=True "
  1309. "valid=False total_forms=1> don't match."
  1310. )
  1311. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1312. self.assertFormSetError(TestFormset.invalid(), 0, None, "non-field error")
  1313. self.assertIn("[] != ['non-field error']", str(ctx.exception))
  1314. msg_prefix = "Custom prefix"
  1315. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1316. self.assertFormSetError(
  1317. TestFormset.invalid(), 0, None, "non-field error", msg_prefix=msg_prefix
  1318. )
  1319. def test_non_form_errors(self):
  1320. self.assertFormSetError(TestFormset.invalid(nonform=True), None, None, "error")
  1321. def test_different_non_form_errors(self):
  1322. msg = (
  1323. "The non-form errors of formset <TestFormset: bound=True valid=False "
  1324. "total_forms=0> don't match."
  1325. )
  1326. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1327. self.assertFormSetError(
  1328. TestFormset.invalid(nonform=True), None, None, "other error"
  1329. )
  1330. self.assertIn("['error'] != ['other error']", str(ctx.exception))
  1331. msg_prefix = "Custom prefix"
  1332. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1333. self.assertFormSetError(
  1334. TestFormset.invalid(nonform=True),
  1335. None,
  1336. None,
  1337. "other error",
  1338. msg_prefix=msg_prefix,
  1339. )
  1340. def test_no_non_form_errors(self):
  1341. msg = (
  1342. "The non-form errors of formset <TestFormset: bound=True valid=False "
  1343. "total_forms=1> don't match."
  1344. )
  1345. with self.assertRaisesMessage(AssertionError, msg) as ctx:
  1346. self.assertFormSetError(TestFormset.invalid(), None, None, "error")
  1347. self.assertIn("[] != ['error']", str(ctx.exception))
  1348. msg_prefix = "Custom prefix"
  1349. with self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {msg}"):
  1350. self.assertFormSetError(
  1351. TestFormset.invalid(),
  1352. None,
  1353. None,
  1354. "error",
  1355. msg_prefix=msg_prefix,
  1356. )
  1357. def test_non_form_errors_with_field(self):
  1358. msg = "You must use field=None with form_index=None."
  1359. with self.assertRaisesMessage(ValueError, msg):
  1360. self.assertFormSetError(
  1361. TestFormset.invalid(nonform=True), None, "field", "error"
  1362. )
  1363. def test_form_index_too_big(self):
  1364. msg = (
  1365. "The formset <TestFormset: bound=True valid=False total_forms=1> only has "
  1366. "1 form."
  1367. )
  1368. with self.assertRaisesMessage(AssertionError, msg):
  1369. self.assertFormSetError(TestFormset.invalid(), 2, "field", "error")
  1370. def test_form_index_too_big_plural(self):
  1371. formset = TestFormset(
  1372. {
  1373. "form-TOTAL_FORMS": "2",
  1374. "form-INITIAL_FORMS": "0",
  1375. "form-0-field": "valid",
  1376. "form-1-field": "valid",
  1377. }
  1378. )
  1379. formset.full_clean()
  1380. msg = (
  1381. "The formset <TestFormset: bound=True valid=True total_forms=2> only has 2 "
  1382. "forms."
  1383. )
  1384. with self.assertRaisesMessage(AssertionError, msg):
  1385. self.assertFormSetError(formset, 2, "field", "error")
  1386. class FirstUrls:
  1387. urlpatterns = [path("first/", empty_response, name="first")]
  1388. class SecondUrls:
  1389. urlpatterns = [path("second/", empty_response, name="second")]
  1390. class SetupTestEnvironmentTests(SimpleTestCase):
  1391. def test_setup_test_environment_calling_more_than_once(self):
  1392. with self.assertRaisesMessage(
  1393. RuntimeError, "setup_test_environment() was already called"
  1394. ):
  1395. setup_test_environment()
  1396. def test_allowed_hosts(self):
  1397. for type_ in (list, tuple):
  1398. with self.subTest(type_=type_):
  1399. allowed_hosts = type_("*")
  1400. with mock.patch("django.test.utils._TestState") as x:
  1401. del x.saved_data
  1402. with self.settings(ALLOWED_HOSTS=allowed_hosts):
  1403. setup_test_environment()
  1404. self.assertEqual(settings.ALLOWED_HOSTS, ["*", "testserver"])
  1405. class OverrideSettingsTests(SimpleTestCase):
  1406. # #21518 -- If neither override_settings nor a setting_changed receiver
  1407. # clears the URL cache between tests, then one of test_first or
  1408. # test_second will fail.
  1409. @override_settings(ROOT_URLCONF=FirstUrls)
  1410. def test_urlconf_first(self):
  1411. reverse("first")
  1412. @override_settings(ROOT_URLCONF=SecondUrls)
  1413. def test_urlconf_second(self):
  1414. reverse("second")
  1415. def test_urlconf_cache(self):
  1416. with self.assertRaises(NoReverseMatch):
  1417. reverse("first")
  1418. with self.assertRaises(NoReverseMatch):
  1419. reverse("second")
  1420. with override_settings(ROOT_URLCONF=FirstUrls):
  1421. self.client.get(reverse("first"))
  1422. with self.assertRaises(NoReverseMatch):
  1423. reverse("second")
  1424. with override_settings(ROOT_URLCONF=SecondUrls):
  1425. with self.assertRaises(NoReverseMatch):
  1426. reverse("first")
  1427. self.client.get(reverse("second"))
  1428. self.client.get(reverse("first"))
  1429. with self.assertRaises(NoReverseMatch):
  1430. reverse("second")
  1431. with self.assertRaises(NoReverseMatch):
  1432. reverse("first")
  1433. with self.assertRaises(NoReverseMatch):
  1434. reverse("second")
  1435. def test_override_media_root(self):
  1436. """
  1437. Overriding the MEDIA_ROOT setting should be reflected in the
  1438. base_location attribute of django.core.files.storage.default_storage.
  1439. """
  1440. self.assertEqual(default_storage.base_location, "")
  1441. with self.settings(MEDIA_ROOT="test_value"):
  1442. self.assertEqual(default_storage.base_location, "test_value")
  1443. def test_override_media_url(self):
  1444. """
  1445. Overriding the MEDIA_URL setting should be reflected in the
  1446. base_url attribute of django.core.files.storage.default_storage.
  1447. """
  1448. self.assertEqual(default_storage.base_location, "")
  1449. with self.settings(MEDIA_URL="/test_value/"):
  1450. self.assertEqual(default_storage.base_url, "/test_value/")
  1451. def test_override_file_upload_permissions(self):
  1452. """
  1453. Overriding the FILE_UPLOAD_PERMISSIONS setting should be reflected in
  1454. the file_permissions_mode attribute of
  1455. django.core.files.storage.default_storage.
  1456. """
  1457. self.assertEqual(default_storage.file_permissions_mode, 0o644)
  1458. with self.settings(FILE_UPLOAD_PERMISSIONS=0o777):
  1459. self.assertEqual(default_storage.file_permissions_mode, 0o777)
  1460. def test_override_file_upload_directory_permissions(self):
  1461. """
  1462. Overriding the FILE_UPLOAD_DIRECTORY_PERMISSIONS setting should be
  1463. reflected in the directory_permissions_mode attribute of
  1464. django.core.files.storage.default_storage.
  1465. """
  1466. self.assertIsNone(default_storage.directory_permissions_mode)
  1467. with self.settings(FILE_UPLOAD_DIRECTORY_PERMISSIONS=0o777):
  1468. self.assertEqual(default_storage.directory_permissions_mode, 0o777)
  1469. def test_override_database_routers(self):
  1470. """
  1471. Overriding DATABASE_ROUTERS should update the base router.
  1472. """
  1473. test_routers = [object()]
  1474. with self.settings(DATABASE_ROUTERS=test_routers):
  1475. self.assertEqual(router.routers, test_routers)
  1476. def test_override_static_url(self):
  1477. """
  1478. Overriding the STATIC_URL setting should be reflected in the
  1479. base_url attribute of
  1480. django.contrib.staticfiles.storage.staticfiles_storage.
  1481. """
  1482. with self.settings(STATIC_URL="/test/"):
  1483. self.assertEqual(staticfiles_storage.base_url, "/test/")
  1484. def test_override_static_root(self):
  1485. """
  1486. Overriding the STATIC_ROOT setting should be reflected in the
  1487. location attribute of
  1488. django.contrib.staticfiles.storage.staticfiles_storage.
  1489. """
  1490. with self.settings(STATIC_ROOT="/tmp/test"):
  1491. self.assertEqual(staticfiles_storage.location, os.path.abspath("/tmp/test"))
  1492. def test_override_staticfiles_storage(self):
  1493. """
  1494. Overriding the STORAGES setting should be reflected in
  1495. the value of django.contrib.staticfiles.storage.staticfiles_storage.
  1496. """
  1497. new_class = "ManifestStaticFilesStorage"
  1498. new_storage = "django.contrib.staticfiles.storage." + new_class
  1499. with self.settings(
  1500. STORAGES={STATICFILES_STORAGE_ALIAS: {"BACKEND": new_storage}}
  1501. ):
  1502. self.assertEqual(staticfiles_storage.__class__.__name__, new_class)
  1503. def test_override_staticfiles_finders(self):
  1504. """
  1505. Overriding the STATICFILES_FINDERS setting should be reflected in
  1506. the return value of django.contrib.staticfiles.finders.get_finders.
  1507. """
  1508. current = get_finders()
  1509. self.assertGreater(len(list(current)), 1)
  1510. finders = ["django.contrib.staticfiles.finders.FileSystemFinder"]
  1511. with self.settings(STATICFILES_FINDERS=finders):
  1512. self.assertEqual(len(list(get_finders())), len(finders))
  1513. def test_override_staticfiles_dirs(self):
  1514. """
  1515. Overriding the STATICFILES_DIRS setting should be reflected in
  1516. the locations attribute of the
  1517. django.contrib.staticfiles.finders.FileSystemFinder instance.
  1518. """
  1519. finder = get_finder("django.contrib.staticfiles.finders.FileSystemFinder")
  1520. test_path = "/tmp/test"
  1521. expected_location = ("", test_path)
  1522. self.assertNotIn(expected_location, finder.locations)
  1523. with self.settings(STATICFILES_DIRS=[test_path]):
  1524. finder = get_finder("django.contrib.staticfiles.finders.FileSystemFinder")
  1525. self.assertIn(expected_location, finder.locations)
  1526. @skipUnlessDBFeature("supports_transactions")
  1527. class TestBadSetUpTestData(TestCase):
  1528. """
  1529. An exception in setUpTestData() shouldn't leak a transaction which would
  1530. cascade across the rest of the test suite.
  1531. """
  1532. class MyException(Exception):
  1533. pass
  1534. @classmethod
  1535. def setUpClass(cls):
  1536. try:
  1537. super().setUpClass()
  1538. except cls.MyException:
  1539. cls._in_atomic_block = connection.in_atomic_block
  1540. @classmethod
  1541. def tearDownClass(Cls):
  1542. # override to avoid a second cls._rollback_atomics() which would fail.
  1543. # Normal setUpClass() methods won't have exception handling so this
  1544. # method wouldn't typically be run.
  1545. pass
  1546. @classmethod
  1547. def setUpTestData(cls):
  1548. # Simulate a broken setUpTestData() method.
  1549. raise cls.MyException()
  1550. def test_failure_in_setUpTestData_should_rollback_transaction(self):
  1551. # setUpTestData() should call _rollback_atomics() so that the
  1552. # transaction doesn't leak.
  1553. self.assertFalse(self._in_atomic_block)
  1554. @skipUnlessDBFeature("supports_transactions")
  1555. class CaptureOnCommitCallbacksTests(TestCase):
  1556. databases = {"default", "other"}
  1557. callback_called = False
  1558. def enqueue_callback(self, using="default"):
  1559. def hook():
  1560. self.callback_called = True
  1561. transaction.on_commit(hook, using=using)
  1562. def test_no_arguments(self):
  1563. with self.captureOnCommitCallbacks() as callbacks:
  1564. self.enqueue_callback()
  1565. self.assertEqual(len(callbacks), 1)
  1566. self.assertIs(self.callback_called, False)
  1567. callbacks[0]()
  1568. self.assertIs(self.callback_called, True)
  1569. def test_using(self):
  1570. with self.captureOnCommitCallbacks(using="other") as callbacks:
  1571. self.enqueue_callback(using="other")
  1572. self.assertEqual(len(callbacks), 1)
  1573. self.assertIs(self.callback_called, False)
  1574. callbacks[0]()
  1575. self.assertIs(self.callback_called, True)
  1576. def test_different_using(self):
  1577. with self.captureOnCommitCallbacks(using="default") as callbacks:
  1578. self.enqueue_callback(using="other")
  1579. self.assertEqual(callbacks, [])
  1580. def test_execute(self):
  1581. with self.captureOnCommitCallbacks(execute=True) as callbacks:
  1582. self.enqueue_callback()
  1583. self.assertEqual(len(callbacks), 1)
  1584. self.assertIs(self.callback_called, True)
  1585. def test_pre_callback(self):
  1586. def pre_hook():
  1587. pass
  1588. transaction.on_commit(pre_hook, using="default")
  1589. with self.captureOnCommitCallbacks() as callbacks:
  1590. self.enqueue_callback()
  1591. self.assertEqual(len(callbacks), 1)
  1592. self.assertNotEqual(callbacks[0], pre_hook)
  1593. def test_with_rolled_back_savepoint(self):
  1594. with self.captureOnCommitCallbacks() as callbacks:
  1595. try:
  1596. with transaction.atomic():
  1597. self.enqueue_callback()
  1598. raise IntegrityError
  1599. except IntegrityError:
  1600. # Inner transaction.atomic() has been rolled back.
  1601. pass
  1602. self.assertEqual(callbacks, [])
  1603. def test_execute_recursive(self):
  1604. with self.captureOnCommitCallbacks(execute=True) as callbacks:
  1605. transaction.on_commit(self.enqueue_callback)
  1606. self.assertEqual(len(callbacks), 2)
  1607. self.assertIs(self.callback_called, True)
  1608. def test_execute_tree(self):
  1609. """
  1610. A visualisation of the callback tree tested. Each node is expected to
  1611. be visited only once:
  1612. └─branch_1
  1613. ├─branch_2
  1614. │ ├─leaf_1
  1615. │ └─leaf_2
  1616. └─leaf_3
  1617. """
  1618. branch_1_call_counter = 0
  1619. branch_2_call_counter = 0
  1620. leaf_1_call_counter = 0
  1621. leaf_2_call_counter = 0
  1622. leaf_3_call_counter = 0
  1623. def leaf_1():
  1624. nonlocal leaf_1_call_counter
  1625. leaf_1_call_counter += 1
  1626. def leaf_2():
  1627. nonlocal leaf_2_call_counter
  1628. leaf_2_call_counter += 1
  1629. def leaf_3():
  1630. nonlocal leaf_3_call_counter
  1631. leaf_3_call_counter += 1
  1632. def branch_1():
  1633. nonlocal branch_1_call_counter
  1634. branch_1_call_counter += 1
  1635. transaction.on_commit(branch_2)
  1636. transaction.on_commit(leaf_3)
  1637. def branch_2():
  1638. nonlocal branch_2_call_counter
  1639. branch_2_call_counter += 1
  1640. transaction.on_commit(leaf_1)
  1641. transaction.on_commit(leaf_2)
  1642. with self.captureOnCommitCallbacks(execute=True) as callbacks:
  1643. transaction.on_commit(branch_1)
  1644. self.assertEqual(branch_1_call_counter, 1)
  1645. self.assertEqual(branch_2_call_counter, 1)
  1646. self.assertEqual(leaf_1_call_counter, 1)
  1647. self.assertEqual(leaf_2_call_counter, 1)
  1648. self.assertEqual(leaf_3_call_counter, 1)
  1649. self.assertEqual(callbacks, [branch_1, branch_2, leaf_3, leaf_1, leaf_2])
  1650. def test_execute_robust(self):
  1651. class MyException(Exception):
  1652. pass
  1653. def hook():
  1654. self.callback_called = True
  1655. raise MyException("robust callback")
  1656. with self.assertLogs("django.test", "ERROR") as cm:
  1657. with self.captureOnCommitCallbacks(execute=True) as callbacks:
  1658. transaction.on_commit(hook, robust=True)
  1659. self.assertEqual(len(callbacks), 1)
  1660. self.assertIs(self.callback_called, True)
  1661. log_record = cm.records[0]
  1662. self.assertEqual(
  1663. log_record.getMessage(),
  1664. "Error calling CaptureOnCommitCallbacksTests.test_execute_robust.<locals>."
  1665. "hook in on_commit() (robust callback).",
  1666. )
  1667. self.assertIsNotNone(log_record.exc_info)
  1668. raised_exception = log_record.exc_info[1]
  1669. self.assertIsInstance(raised_exception, MyException)
  1670. self.assertEqual(str(raised_exception), "robust callback")
  1671. class DisallowedDatabaseQueriesTests(SimpleTestCase):
  1672. def test_disallowed_database_connections(self):
  1673. expected_message = (
  1674. "Database connections to 'default' are not allowed in SimpleTestCase "
  1675. "subclasses. Either subclass TestCase or TransactionTestCase to "
  1676. "ensure proper test isolation or add 'default' to "
  1677. "test_utils.tests.DisallowedDatabaseQueriesTests.databases to "
  1678. "silence this failure."
  1679. )
  1680. with self.assertRaisesMessage(DatabaseOperationForbidden, expected_message):
  1681. connection.connect()
  1682. with self.assertRaisesMessage(DatabaseOperationForbidden, expected_message):
  1683. connection.temporary_connection()
  1684. def test_disallowed_database_queries(self):
  1685. expected_message = (
  1686. "Database queries to 'default' are not allowed in SimpleTestCase "
  1687. "subclasses. Either subclass TestCase or TransactionTestCase to "
  1688. "ensure proper test isolation or add 'default' to "
  1689. "test_utils.tests.DisallowedDatabaseQueriesTests.databases to "
  1690. "silence this failure."
  1691. )
  1692. with self.assertRaisesMessage(DatabaseOperationForbidden, expected_message):
  1693. Car.objects.first()
  1694. def test_disallowed_database_chunked_cursor_queries(self):
  1695. expected_message = (
  1696. "Database queries to 'default' are not allowed in SimpleTestCase "
  1697. "subclasses. Either subclass TestCase or TransactionTestCase to "
  1698. "ensure proper test isolation or add 'default' to "
  1699. "test_utils.tests.DisallowedDatabaseQueriesTests.databases to "
  1700. "silence this failure."
  1701. )
  1702. with self.assertRaisesMessage(DatabaseOperationForbidden, expected_message):
  1703. next(Car.objects.iterator())
  1704. class AllowedDatabaseQueriesTests(SimpleTestCase):
  1705. databases = {"default"}
  1706. def test_allowed_database_queries(self):
  1707. Car.objects.first()
  1708. def test_allowed_database_chunked_cursor_queries(self):
  1709. next(Car.objects.iterator(), None)
  1710. class DatabaseAliasTests(SimpleTestCase):
  1711. def setUp(self):
  1712. self.addCleanup(setattr, self.__class__, "databases", self.databases)
  1713. def test_no_close_match(self):
  1714. self.__class__.databases = {"void"}
  1715. message = (
  1716. "test_utils.tests.DatabaseAliasTests.databases refers to 'void' which is "
  1717. "not defined in settings.DATABASES."
  1718. )
  1719. with self.assertRaisesMessage(ImproperlyConfigured, message):
  1720. self._validate_databases()
  1721. def test_close_match(self):
  1722. self.__class__.databases = {"defualt"}
  1723. message = (
  1724. "test_utils.tests.DatabaseAliasTests.databases refers to 'defualt' which "
  1725. "is not defined in settings.DATABASES. Did you mean 'default'?"
  1726. )
  1727. with self.assertRaisesMessage(ImproperlyConfigured, message):
  1728. self._validate_databases()
  1729. def test_match(self):
  1730. self.__class__.databases = {"default", "other"}
  1731. self.assertEqual(self._validate_databases(), frozenset({"default", "other"}))
  1732. def test_all(self):
  1733. self.__class__.databases = "__all__"
  1734. self.assertEqual(self._validate_databases(), frozenset(connections))
  1735. @isolate_apps("test_utils", attr_name="class_apps")
  1736. class IsolatedAppsTests(SimpleTestCase):
  1737. def test_installed_apps(self):
  1738. self.assertEqual(
  1739. [app_config.label for app_config in self.class_apps.get_app_configs()],
  1740. ["test_utils"],
  1741. )
  1742. def test_class_decoration(self):
  1743. class ClassDecoration(models.Model):
  1744. pass
  1745. self.assertEqual(ClassDecoration._meta.apps, self.class_apps)
  1746. @isolate_apps("test_utils", kwarg_name="method_apps")
  1747. def test_method_decoration(self, method_apps):
  1748. class MethodDecoration(models.Model):
  1749. pass
  1750. self.assertEqual(MethodDecoration._meta.apps, method_apps)
  1751. def test_context_manager(self):
  1752. with isolate_apps("test_utils") as context_apps:
  1753. class ContextManager(models.Model):
  1754. pass
  1755. self.assertEqual(ContextManager._meta.apps, context_apps)
  1756. @isolate_apps("test_utils", kwarg_name="method_apps")
  1757. def test_nested(self, method_apps):
  1758. class MethodDecoration(models.Model):
  1759. pass
  1760. with isolate_apps("test_utils") as context_apps:
  1761. class ContextManager(models.Model):
  1762. pass
  1763. with isolate_apps("test_utils") as nested_context_apps:
  1764. class NestedContextManager(models.Model):
  1765. pass
  1766. self.assertEqual(MethodDecoration._meta.apps, method_apps)
  1767. self.assertEqual(ContextManager._meta.apps, context_apps)
  1768. self.assertEqual(NestedContextManager._meta.apps, nested_context_apps)
  1769. class DoNothingDecorator(TestContextDecorator):
  1770. def enable(self):
  1771. pass
  1772. def disable(self):
  1773. pass
  1774. class TestContextDecoratorTests(SimpleTestCase):
  1775. @mock.patch.object(DoNothingDecorator, "disable")
  1776. def test_exception_in_setup(self, mock_disable):
  1777. """An exception is setUp() is reraised after disable() is called."""
  1778. class ExceptionInSetUp(unittest.TestCase):
  1779. def setUp(self):
  1780. raise NotImplementedError("reraised")
  1781. decorator = DoNothingDecorator()
  1782. decorated_test_class = decorator.__call__(ExceptionInSetUp)()
  1783. self.assertFalse(mock_disable.called)
  1784. with self.assertRaisesMessage(NotImplementedError, "reraised"):
  1785. decorated_test_class.setUp()
  1786. decorated_test_class.doCleanups()
  1787. self.assertTrue(mock_disable.called)
  1788. def test_cleanups_run_after_tearDown(self):
  1789. calls = []
  1790. class SaveCallsDecorator(TestContextDecorator):
  1791. def enable(self):
  1792. calls.append("enable")
  1793. def disable(self):
  1794. calls.append("disable")
  1795. class AddCleanupInSetUp(unittest.TestCase):
  1796. def setUp(self):
  1797. calls.append("setUp")
  1798. self.addCleanup(lambda: calls.append("cleanup"))
  1799. decorator = SaveCallsDecorator()
  1800. decorated_test_class = decorator.__call__(AddCleanupInSetUp)()
  1801. decorated_test_class.setUp()
  1802. decorated_test_class.tearDown()
  1803. decorated_test_class.doCleanups()
  1804. self.assertEqual(calls, ["enable", "setUp", "cleanup", "disable"])