2
0

test_templates.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. from django.template import Context, RequestContext, Template, engines
  2. from django.test import TestCase
  3. from wagtail.core.models import Page, Site
  4. from wagtail.tests.testapp.models import TestSetting
  5. from wagtail.tests.utils import WagtailTestUtils
  6. class TemplateTestCase(TestCase, WagtailTestUtils):
  7. def setUp(self):
  8. root = Page.objects.first()
  9. other_home = Page(title='Other Root')
  10. root.add_child(instance=other_home)
  11. self.default_site = Site.objects.get(is_default_site=True)
  12. self.other_site = Site.objects.create(hostname='other', root_page=other_home)
  13. self.test_setting = TestSetting.objects.create(
  14. title='Site title',
  15. email='initial@example.com',
  16. site=self.default_site)
  17. self.other_setting = TestSetting.objects.create(
  18. title='Other title',
  19. email='other@example.com',
  20. site=self.other_site)
  21. def get_request(self, site=None):
  22. if site is None:
  23. site = self.default_site
  24. request = self.client.get('/test/', HTTP_HOST=site.hostname)
  25. request.site = site
  26. return request
  27. def render(self, request, string, context=None, site=None):
  28. template = Template(string)
  29. context = RequestContext(request, context)
  30. return template.render(context)
  31. class TestContextProcessor(TemplateTestCase):
  32. def test_accessing_setting(self):
  33. """ Check that the context processor works """
  34. request = self.get_request()
  35. self.assertEqual(
  36. self.render(request, '{{ settings.tests.TestSetting.title }}'),
  37. self.test_setting.title)
  38. def test_multisite(self):
  39. """ Check that the correct setting for the current site is returned """
  40. request = self.get_request(site=self.default_site)
  41. self.assertEqual(
  42. self.render(request, '{{ settings.tests.TestSetting.title }}'),
  43. self.test_setting.title)
  44. request = self.get_request(site=self.other_site)
  45. self.assertEqual(
  46. self.render(request, '{{ settings.tests.TestSetting.title }}'),
  47. self.other_setting.title)
  48. def test_model_case_insensitive(self):
  49. """ Model names should be case insensitive """
  50. request = self.get_request()
  51. self.assertEqual(
  52. self.render(request, '{{ settings.tests.testsetting.title }}'),
  53. self.test_setting.title)
  54. self.assertEqual(
  55. self.render(request, '{{ settings.tests.TESTSETTING.title }}'),
  56. self.test_setting.title)
  57. self.assertEqual(
  58. self.render(request, '{{ settings.tests.TestSetting.title }}'),
  59. self.test_setting.title)
  60. self.assertEqual(
  61. self.render(request, '{{ settings.tests.tEstsEttIng.title }}'),
  62. self.test_setting.title)
  63. def test_models_cached(self):
  64. """ Accessing a setting should only hit the DB once per render """
  65. request = self.get_request()
  66. get_title = '{{ settings.tests.testsetting.title }}'
  67. for i in range(1, 4):
  68. with self.assertNumQueries(1):
  69. self.assertEqual(
  70. self.render(request, get_title * i),
  71. self.test_setting.title * i)
  72. class TestTemplateTag(TemplateTestCase):
  73. def test_no_context_processor(self):
  74. """
  75. Assert that not running the context processor means settings are not in
  76. the context, as expected.
  77. """
  78. template = Template('{{ settings.tests.TestSetting.title }}')
  79. context = Context()
  80. self.assertEqual(template.render(context), '')
  81. def test_get_settings_request_context(self):
  82. """ Check that the {% get_settings %} tag works """
  83. request = self.get_request(site=self.other_site)
  84. context = Context({'request': request})
  85. # This should use the site in the request
  86. template = Template('{% load wagtailsettings_tags %}'
  87. '{% get_settings %}'
  88. '{{ settings.tests.testsetting.title}}')
  89. self.assertEqual(template.render(context), self.other_setting.title)
  90. def test_get_settings_request_context_use_default(self):
  91. """
  92. Check that the {% get_settings use_default_site=True %} option
  93. overrides a request in the context.
  94. """
  95. request = self.get_request(site=self.other_site)
  96. context = Context({'request': request})
  97. # This should use the default site, ignoring the site in the request
  98. template = Template('{% load wagtailsettings_tags %}'
  99. '{% get_settings use_default_site=True %}'
  100. '{{ settings.tests.testsetting.title}}')
  101. self.assertEqual(template.render(context), self.test_setting.title)
  102. def test_get_settings_use_default(self):
  103. """
  104. Check that the {% get_settings use_default_site=True %} option works
  105. """
  106. context = Context()
  107. # This should use the default site
  108. template = Template('{% load wagtailsettings_tags %}'
  109. '{% get_settings use_default_site=True %}'
  110. '{{ settings.tests.testsetting.title}}')
  111. self.assertEqual(template.render(context), self.test_setting.title)
  112. def test_get_settings_no_request_no_default(self):
  113. """
  114. Check that the {% get_settings %} throws an error if it can not find a
  115. site to work with
  116. """
  117. context = Context()
  118. # Without a request in the context, and without use_default_site, this
  119. # should bail with an error
  120. template = Template('{% load wagtailsettings_tags %}'
  121. '{% get_settings %}'
  122. '{{ settings.tests.testsetting.title}}')
  123. with self.assertRaises(RuntimeError):
  124. template.render(context)
  125. class TestSettingsJinja(TemplateTestCase):
  126. def setUp(self):
  127. super().setUp()
  128. self.engine = engines['jinja2']
  129. def render(self, string, context=None, request_context=True):
  130. if context is None:
  131. context = {}
  132. # Add a request to the template, to simulate a RequestContext
  133. if request_context:
  134. if 'site' in context:
  135. site = context['site']
  136. else:
  137. site = Site.objects.get(is_default_site=True)
  138. request = self.client.get('/test/', HTTP_HOST=site.hostname)
  139. request.site = site
  140. context['request'] = request
  141. template = self.engine.from_string(string)
  142. return template.render(context)
  143. def test_accessing_setting(self):
  144. """ Check that the context processor works """
  145. self.assertEqual(
  146. self.render('{{ settings("tests.TestSetting").title }}'),
  147. self.test_setting.title)
  148. def test_multisite(self):
  149. """ Check that the correct setting for the current site is returned """
  150. context = {'site': self.default_site}
  151. self.assertEqual(
  152. self.render('{{ settings("tests.TestSetting").title }}', context),
  153. self.test_setting.title)
  154. context = {'site': self.other_site}
  155. self.assertEqual(
  156. self.render('{{ settings("tests.TestSetting").title }}', context),
  157. self.other_setting.title)
  158. def test_model_case_insensitive(self):
  159. """ Model names should be case insensitive """
  160. self.assertEqual(
  161. self.render('{{ settings("tests.testsetting").title }}'),
  162. self.test_setting.title)
  163. self.assertEqual(
  164. self.render('{{ settings("tests.TESTSETTING").title }}'),
  165. self.test_setting.title)
  166. self.assertEqual(
  167. self.render('{{ settings("tests.TestSetting").title }}'),
  168. self.test_setting.title)
  169. self.assertEqual(
  170. self.render('{{ settings("tests.tEstsEttIng").title }}'),
  171. self.test_setting.title)
  172. def test_models_cached(self):
  173. """ Accessing a setting should only hit the DB once per render """
  174. get_title = '{{ settings("tests.testsetting").title }}'
  175. # Cant use the default 'self.render()' as it does DB queries to get
  176. # site, dummy request
  177. site = Site.objects.get(is_default_site=True)
  178. request = self.client.get('/test/', HTTP_HOST=site.hostname)
  179. request.site = site
  180. for i in range(1, 4):
  181. with self.assertNumQueries(1):
  182. context = {'request': request}
  183. template = self.engine.from_string(get_title * i)
  184. self.assertEqual(
  185. template.render(context),
  186. self.test_setting.title * i)
  187. def test_settings_use_default_site_override(self):
  188. """
  189. Check that {{ settings(use_default_site=True) }} overrides a site in
  190. the context.
  191. """
  192. request = self.get_request(site=self.other_site)
  193. context = {'request': request}
  194. # This should use the default site, ignoring the site in the request
  195. template = '{{ settings("tests.testsetting", use_default_site=True).title }}'
  196. self.assertEqual(
  197. self.render(template, context),
  198. self.test_setting.title)
  199. def test_settings_use_default_site(self):
  200. """
  201. Check that the {{ settings(use_default_site=True) }} option works with
  202. no site in the context
  203. """
  204. context = {}
  205. # This should use the default site
  206. template = '{{ settings("tests.testsetting", use_default_site=True).title}}'
  207. self.assertEqual(
  208. self.render(template, context, request_context=False),
  209. self.test_setting.title)
  210. def test_settings_no_request_no_use_default(self):
  211. """
  212. Check that {{ settings }} throws an error if it can not find a
  213. site to work with
  214. """
  215. context = {}
  216. # Without a request in the context, and without use_default_site, this
  217. # should bail with an error
  218. template = '{{ settings("tests.testsetting").title}}'
  219. with self.assertRaises(RuntimeError):
  220. self.render(template, context, request_context=False)