tests.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. # -*- coding: utf-8 -*-
  2. import json
  3. from django.contrib.auth import get_user_model
  4. from django.contrib.auth.models import Group, Permission
  5. from django.core import mail
  6. from django.test import TestCase, override_settings
  7. from django.urls import reverse, reverse_lazy
  8. from django.utils.translation import ugettext_lazy as _
  9. from taggit.models import Tag
  10. from wagtail.admin.menu import MenuItem
  11. from wagtail.admin.site_summary import PagesSummaryItem
  12. from wagtail.admin.utils import send_mail, user_has_any_page_permission
  13. from wagtail.core.models import Page, Site
  14. from wagtail.tests.utils import WagtailTestUtils
  15. class TestHome(TestCase, WagtailTestUtils):
  16. def setUp(self):
  17. # Login
  18. self.login()
  19. def test_simple(self):
  20. response = self.client.get(reverse('wagtailadmin_home'))
  21. self.assertEqual(response.status_code, 200)
  22. self.assertContains(response, "Welcome to the Test Site Wagtail CMS")
  23. def test_admin_menu(self):
  24. response = self.client.get(reverse('wagtailadmin_home'))
  25. self.assertEqual(response.status_code, 200)
  26. # check that media attached to menu items is correctly pulled in
  27. self.assertContains(
  28. response,
  29. '<script type="text/javascript" src="/static/testapp/js/kittens.js"></script>'
  30. )
  31. # check that custom menu items (including classname / attrs parameters) are pulled in
  32. self.assertContains(
  33. response,
  34. '<a href="http://www.tomroyal.com/teaandkittens/" class="icon icon-kitten" data-fluffy="yes">Kittens!</a>'
  35. )
  36. # Check that the explorer menu item is here, with the right start page.
  37. self.assertContains(
  38. response,
  39. 'data-explorer-start-page="1"'
  40. )
  41. # check that is_shown is respected on menu items
  42. response = self.client.get(reverse('wagtailadmin_home') + '?hide-kittens=true')
  43. self.assertNotContains(
  44. response,
  45. '<a href="http://www.tomroyal.com/teaandkittens/" class="icon icon-kitten" data-fluffy="yes">Kittens!</a>'
  46. )
  47. def test_never_cache_header(self):
  48. # This tests that wagtailadmins global cache settings have been applied correctly
  49. response = self.client.get(reverse('wagtailadmin_home'))
  50. self.assertIn('private', response['Cache-Control'])
  51. self.assertIn('no-cache', response['Cache-Control'])
  52. self.assertIn('no-store', response['Cache-Control'])
  53. self.assertIn('max-age=0', response['Cache-Control'])
  54. def test_nonascii_email(self):
  55. # Test that non-ASCII email addresses don't break the admin; previously these would
  56. # cause a failure when generating Gravatar URLs
  57. get_user_model().objects.create_superuser(username='snowman', email='☃@thenorthpole.com', password='password')
  58. # Login
  59. self.assertTrue(self.client.login(username='snowman', password='password'))
  60. response = self.client.get(reverse('wagtailadmin_home'))
  61. self.assertEqual(response.status_code, 200)
  62. class TestPagesSummary(TestCase, WagtailTestUtils):
  63. def setUp(self):
  64. self.login()
  65. def get_request(self):
  66. """
  67. Get a Django WSGI request that has been passed through middleware etc.
  68. """
  69. return self.client.get('/admin/').wsgi_request
  70. def test_page_summary_single_site(self):
  71. request = self.get_request()
  72. root_page = request.site.root_page
  73. link = '<a href="{}">'.format(reverse('wagtailadmin_explore', args=[root_page.pk]))
  74. page_summary = PagesSummaryItem(request)
  75. self.assertIn(link, page_summary.render())
  76. def test_page_summary_multiple_sites(self):
  77. Site.objects.create(
  78. hostname='example.com',
  79. root_page=Page.objects.get(pk=1))
  80. request = self.get_request()
  81. link = '<a href="{}">'.format(reverse('wagtailadmin_explore_root'))
  82. page_summary = PagesSummaryItem(request)
  83. self.assertIn(link, page_summary.render())
  84. def test_page_summary_zero_sites(self):
  85. Site.objects.all().delete()
  86. request = self.get_request()
  87. link = '<a href="{}">'.format(reverse('wagtailadmin_explore_root'))
  88. page_summary = PagesSummaryItem(request)
  89. self.assertIn(link, page_summary.render())
  90. class TestEditorHooks(TestCase, WagtailTestUtils):
  91. def setUp(self):
  92. self.homepage = Page.objects.get(id=2)
  93. self.login()
  94. def test_editor_css_hooks_on_add(self):
  95. response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.homepage.id)))
  96. self.assertEqual(response.status_code, 200)
  97. self.assertContains(response, '<link rel="stylesheet" href="/path/to/my/custom.css">')
  98. def test_editor_js_hooks_on_add(self):
  99. response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.homepage.id)))
  100. self.assertEqual(response.status_code, 200)
  101. self.assertContains(response, '<script src="/path/to/my/custom.js"></script>')
  102. def test_editor_css_hooks_on_edit(self):
  103. response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.homepage.id, )))
  104. self.assertEqual(response.status_code, 200)
  105. self.assertContains(response, '<link rel="stylesheet" href="/path/to/my/custom.css">')
  106. def test_editor_js_hooks_on_edit(self):
  107. response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.homepage.id, )))
  108. self.assertEqual(response.status_code, 200)
  109. self.assertContains(response, '<script src="/path/to/my/custom.js"></script>')
  110. class TestSendMail(TestCase):
  111. def test_send_email(self):
  112. send_mail("Test subject", "Test content", ["nobody@email.com"], "test@email.com")
  113. # Check that the email was sent
  114. self.assertEqual(len(mail.outbox), 1)
  115. self.assertEqual(mail.outbox[0].subject, "Test subject")
  116. self.assertEqual(mail.outbox[0].body, "Test content")
  117. self.assertEqual(mail.outbox[0].to, ["nobody@email.com"])
  118. self.assertEqual(mail.outbox[0].from_email, "test@email.com")
  119. @override_settings(WAGTAILADMIN_NOTIFICATION_FROM_EMAIL='anothertest@email.com')
  120. def test_send_fallback_to_wagtailadmin_notification_from_email_setting(self):
  121. send_mail("Test subject", "Test content", ["nobody@email.com"])
  122. # Check that the email was sent
  123. self.assertEqual(len(mail.outbox), 1)
  124. self.assertEqual(mail.outbox[0].subject, "Test subject")
  125. self.assertEqual(mail.outbox[0].body, "Test content")
  126. self.assertEqual(mail.outbox[0].to, ["nobody@email.com"])
  127. self.assertEqual(mail.outbox[0].from_email, "anothertest@email.com")
  128. @override_settings(DEFAULT_FROM_EMAIL='yetanothertest@email.com')
  129. def test_send_fallback_to_default_from_email_setting(self):
  130. send_mail("Test subject", "Test content", ["nobody@email.com"])
  131. # Check that the email was sent
  132. self.assertEqual(len(mail.outbox), 1)
  133. self.assertEqual(mail.outbox[0].subject, "Test subject")
  134. self.assertEqual(mail.outbox[0].body, "Test content")
  135. self.assertEqual(mail.outbox[0].to, ["nobody@email.com"])
  136. self.assertEqual(mail.outbox[0].from_email, "yetanothertest@email.com")
  137. def test_send_default_from_email(self):
  138. send_mail("Test subject", "Test content", ["nobody@email.com"])
  139. # Check that the email was sent
  140. self.assertEqual(len(mail.outbox), 1)
  141. self.assertEqual(mail.outbox[0].subject, "Test subject")
  142. self.assertEqual(mail.outbox[0].body, "Test content")
  143. self.assertEqual(mail.outbox[0].to, ["nobody@email.com"])
  144. self.assertEqual(mail.outbox[0].from_email, "webmaster@localhost")
  145. class TestTagsAutocomplete(TestCase, WagtailTestUtils):
  146. def setUp(self):
  147. self.login()
  148. Tag.objects.create(name="Test", slug="test")
  149. def test_tags_autocomplete(self):
  150. response = self.client.get(reverse('wagtailadmin_tag_autocomplete'), {
  151. 'term': 'test'
  152. })
  153. self.assertEqual(response.status_code, 200)
  154. self.assertEqual(response['Content-Type'], 'application/json')
  155. data = json.loads(response.content.decode('utf-8'))
  156. self.assertEqual(data, ['Test'])
  157. def test_tags_autocomplete_partial_match(self):
  158. response = self.client.get(reverse('wagtailadmin_tag_autocomplete'), {
  159. 'term': 'te'
  160. })
  161. self.assertEqual(response.status_code, 200)
  162. self.assertEqual(response['Content-Type'], 'application/json')
  163. data = json.loads(response.content.decode('utf-8'))
  164. self.assertEqual(data, ['Test'])
  165. def test_tags_autocomplete_different_term(self):
  166. response = self.client.get(reverse('wagtailadmin_tag_autocomplete'), {
  167. 'term': 'hello'
  168. })
  169. self.assertEqual(response.status_code, 200)
  170. self.assertEqual(response['Content-Type'], 'application/json')
  171. data = json.loads(response.content.decode('utf-8'))
  172. self.assertEqual(data, [])
  173. def test_tags_autocomplete_no_term(self):
  174. response = self.client.get(reverse('wagtailadmin_tag_autocomplete'))
  175. self.assertEqual(response.status_code, 200)
  176. self.assertEqual(response['Content-Type'], 'application/json')
  177. data = json.loads(response.content.decode('utf-8'))
  178. self.assertEqual(data, [])
  179. class TestMenuItem(TestCase, WagtailTestUtils):
  180. def setUp(self):
  181. self.login()
  182. response = self.client.get(reverse('wagtailadmin_home'))
  183. self.request = response.wsgi_request
  184. def test_menuitem_reverse_lazy_url_pass(self):
  185. menuitem = MenuItem(_('Test'), reverse_lazy('wagtailadmin_home'))
  186. self.assertEqual(menuitem.is_active(self.request), True)
  187. class TestUserPassesTestPermissionDecorator(TestCase):
  188. """
  189. Test for custom user_passes_test permission decorators.
  190. testapp_bob_only_zone is a view configured to only grant access to users with a first_name of Bob
  191. """
  192. def test_user_passes_test(self):
  193. # create and log in as a user called Bob
  194. get_user_model().objects.create_superuser(first_name='Bob', last_name='Mortimer', username='test', email='test@email.com', password='password')
  195. self.assertTrue(self.client.login(username='test', password='password'))
  196. response = self.client.get(reverse('testapp_bob_only_zone'))
  197. self.assertEqual(response.status_code, 200)
  198. def test_user_fails_test(self):
  199. # create and log in as a user not called Bob
  200. get_user_model().objects.create_superuser(first_name='Vic', last_name='Reeves', username='test', email='test@email.com', password='password')
  201. self.assertTrue(self.client.login(username='test', password='password'))
  202. response = self.client.get(reverse('testapp_bob_only_zone'))
  203. self.assertRedirects(response, reverse('wagtailadmin_home'))
  204. def test_user_fails_test_ajax(self):
  205. # create and log in as a user not called Bob
  206. get_user_model().objects.create_superuser(first_name='Vic', last_name='Reeves', username='test', email='test@email.com', password='password')
  207. self.assertTrue(self.client.login(username='test', password='password'))
  208. response = self.client.get(reverse('testapp_bob_only_zone'), HTTP_X_REQUESTED_WITH='XMLHttpRequest')
  209. self.assertEqual(response.status_code, 403)
  210. class TestUserHasAnyPagePermission(TestCase):
  211. def test_superuser(self):
  212. user = get_user_model().objects.create_superuser(
  213. username='superuser', email='admin@example.com', password='p')
  214. self.assertTrue(user_has_any_page_permission(user))
  215. def test_inactive_superuser(self):
  216. user = get_user_model().objects.create_superuser(
  217. username='superuser', email='admin@example.com', password='p')
  218. user.is_active = False
  219. self.assertFalse(user_has_any_page_permission(user))
  220. def test_editor(self):
  221. user = get_user_model().objects.create_user(
  222. username='editor', email='ed@example.com', password='p')
  223. editors = Group.objects.get(name='Editors')
  224. user.groups.add(editors)
  225. self.assertTrue(user_has_any_page_permission(user))
  226. def test_moderator(self):
  227. user = get_user_model().objects.create_user(
  228. username='moderator', email='mod@example.com', password='p')
  229. editors = Group.objects.get(name='Moderators')
  230. user.groups.add(editors)
  231. self.assertTrue(user_has_any_page_permission(user))
  232. def test_no_permissions(self):
  233. user = get_user_model().objects.create_user(
  234. username='pleb', email='pleb@example.com', password='p')
  235. user.user_permissions.add(
  236. Permission.objects.get(content_type__app_label='wagtailadmin', codename='access_admin')
  237. )
  238. self.assertFalse(user_has_any_page_permission(user))
  239. class Test404(TestCase, WagtailTestUtils):
  240. def test_admin_404_template_used(self):
  241. self.login()
  242. response = self.client.get('/admin/sdfgdsfgdsfgsdf')
  243. self.assertEqual(response.status_code, 404)
  244. self.assertTemplateUsed(response, 'wagtailadmin/404.html')
  245. def test_not_logged_in_redirect(self):
  246. response = self.client.get('/admin/sdfgdsfgdsfgsdf')
  247. # Check that the user was redirected to the login page and that next was set correctly
  248. self.assertRedirects(response, reverse('wagtailadmin_login') + '?next=/admin/sdfgdsfgdsfgsdf')