test_urls.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. import pytest
  2. import unittest
  3. from ast import literal_eval
  4. from django.urls import reverse
  5. from django.test import Client
  6. from django.test.utils import override_settings
  7. from django.utils import timezone
  8. from wagtail.core.models import Site, Page
  9. from wagtail.images.tests.utils import Image, get_test_image_file
  10. from coderedcms.models import LayoutSettings
  11. from coderedcms.tests.testapp.models import EventPage, EventIndexPage, EventOccurrence
  12. @pytest.mark.django_db
  13. class TestSiteURLs(unittest.TestCase):
  14. def setUp(self):
  15. self.client = Client()
  16. @override_settings(DEBUG=False)
  17. def test_404(self):
  18. response = self.client.get("/testing/404/page/", follow=True)
  19. self.assertEqual(response.status_code, 404)
  20. def test_sitemap(self):
  21. response = self.client.get("/sitemap.xml")
  22. self.assertEqual(response.status_code, 200)
  23. self.assertEqual(response['content-type'], 'application/xml')
  24. def test_robots(self):
  25. response = self.client.get("/robots.txt")
  26. self.assertEqual(response.status_code, 200)
  27. self.assertEqual(response['content-type'], 'text/plain')
  28. def test_search(self):
  29. response = self.client.get(reverse(
  30. 'codered_search'),
  31. {'s': 'Test Search Query'},
  32. follow=True
  33. )
  34. self.assertEqual(response.status_code, 200)
  35. self.assertNotEqual(response.context['results'], None)
  36. response = self.client.get(reverse(
  37. 'codered_search'),
  38. {
  39. 's': 'keyword',
  40. 't': 't',
  41. },
  42. follow=False
  43. )
  44. self.assertEqual(response.status_code, 200)
  45. self.assertEqual(response.context['results'], None)
  46. @pytest.mark.django_db
  47. class TestEventURLs(unittest.TestCase):
  48. def setUp(self):
  49. self.client = Client()
  50. self.root_page = Page.get_root_nodes()[0]
  51. def test_generate_single_event(self):
  52. event_page = EventPage(
  53. path='/single-event/',
  54. depth=1,
  55. title='Single Event',
  56. slug='single-event'
  57. )
  58. self.root_page.add_child(instance=event_page)
  59. occurrence = EventOccurrence(
  60. event=event_page,
  61. start='2019-01-01T10:00:00+0000',
  62. end='2019-01-01T11:00:00+0000'
  63. )
  64. occurrence.save()
  65. response = self.client.post(
  66. "/ical/generate/single/",
  67. {
  68. 'event_pk': event_page.pk,
  69. 'datetime_start': EventOccurrence.objects.get(
  70. event=event_page
  71. ).start.strftime("%Y-%m-%d %H:%M:%S%z").replace(' ', 'T'),
  72. 'datetime_end': EventOccurrence.objects.get(
  73. event=event_page
  74. ).end.strftime("%Y-%m-%d %H:%M:%S%z").replace(' ', 'T'),
  75. },
  76. follow=True
  77. )
  78. self.assertEqual(response.status_code, 200)
  79. self.assertEqual(response['Filename'], "{0}.ics".format(event_page.slug))
  80. self.assertEqual(
  81. response['Content-Disposition'],
  82. 'attachment; filename={0}.ics'.format(event_page.slug)
  83. )
  84. self.assertEqual(response['content-type'], 'text/calendar')
  85. # Get datetimes from response and compare them to datetimes on page
  86. # startswith() is used because older versions of Python
  87. # use different datetime formatting, specifically for timezones
  88. split_content = str(response._container[0]).split('VALUE=DATE-TIME:')
  89. start = split_content[1].split('\\')[0]
  90. end = split_content[2].split('\\')[0]
  91. self.assertTrue(
  92. start.startswith(
  93. EventOccurrence.objects.get(event=event_page).start.strftime("%Y%m%dT%H%M%S")
  94. )
  95. )
  96. self.assertTrue(
  97. end.startswith(
  98. EventOccurrence.objects.get(event=event_page).end.strftime("%Y%m%dT%H%M%S")
  99. )
  100. )
  101. def test_generate_recurring_event(self):
  102. event_page = EventPage(
  103. path='/recurring-event/',
  104. depth=1,
  105. title='Recurring Event',
  106. slug='recurring-event'
  107. )
  108. self.root_page.add_child(instance=event_page)
  109. occurrence = EventOccurrence(
  110. event=event_page,
  111. start='2019-01-01T10:00:00+0000',
  112. end='2019-01-01T11:00:00+0000'
  113. )
  114. occurrence.save()
  115. response = self.client.post(
  116. "/ical/generate/recurring/",
  117. {'event_pk': event_page.pk},
  118. follow=True
  119. )
  120. self.assertEqual(response.status_code, 200)
  121. self.assertEqual(response['Filename'], "{0}.ics".format(event_page.slug))
  122. self.assertEqual(
  123. response['Content-Disposition'],
  124. 'attachment; filename={0}.ics'.format(event_page.slug)
  125. )
  126. self.assertEqual(response['content-type'], 'text/calendar')
  127. # Get datetimes from response and compare them to datetimes on page
  128. # startswith() is used because older versions of Python
  129. # use different datetime formatting, specifically for timezones
  130. split_content = str(response._container[0]).split('VALUE=DATE-TIME:')
  131. start = split_content[1].split('\\')[0]
  132. end = split_content[2].split('\\')[0]
  133. self.assertTrue(
  134. start.startswith(
  135. EventOccurrence.objects.get(event=event_page).start.strftime("%Y%m%dT%H%M%S")
  136. )
  137. )
  138. self.assertTrue(
  139. end.startswith(
  140. EventOccurrence.objects.get(event=event_page).end.strftime("%Y%m%dT%H%M%S")
  141. )
  142. )
  143. def test_generate_calendar(self):
  144. calendar_page = EventIndexPage(
  145. path='/event-index-page/',
  146. depth=1,
  147. title='Event Index Page',
  148. slug='event-index-page'
  149. )
  150. self.root_page.add_child(instance=calendar_page)
  151. event_page = EventPage(
  152. path='/eventpage/1/',
  153. depth=2,
  154. title='Event Page 1',
  155. slug='eventpage1'
  156. )
  157. calendar_page.add_child(instance=event_page)
  158. occurrence = EventOccurrence(
  159. event=event_page,
  160. start='2019-01-01T10:00:00+0000',
  161. end='2019-01-01T11:00:00+0000'
  162. )
  163. occurrence.save()
  164. response = self.client.post(
  165. "/ical/generate/calendar/",
  166. {'page_id': calendar_page.pk},
  167. follow=True
  168. )
  169. self.assertEqual(response.status_code, 200)
  170. self.assertEqual(response['Filename'], 'calendar.ics')
  171. self.assertEqual(response['Content-Disposition'], 'attachment; filename=calendar.ics')
  172. self.assertEqual(response['content-type'], 'text/calendar')
  173. # Get datetimes from response and compare them to datetimes on page
  174. # startswith() is used because older versions of Python
  175. # use different datetime formatting, specifically for timezones
  176. split_content = str(response._container[0]).split('VALUE=DATE-TIME:')
  177. start = split_content[1].split('\\')[0]
  178. end = split_content[2].split('\\')[0]
  179. self.assertTrue(
  180. start.startswith(
  181. EventOccurrence.objects.get(event=event_page).start.strftime("%Y%m%dT%H%M%S")
  182. )
  183. )
  184. self.assertTrue(
  185. end.startswith(
  186. EventOccurrence.objects.get(event=event_page).end.strftime("%Y%m%dT%H%M%S")
  187. )
  188. )
  189. def test_ajax_calendar(self):
  190. calendar_page = EventIndexPage(
  191. path='/event-index-page/',
  192. depth=1,
  193. title='Event Index Page',
  194. slug='event-index-page'
  195. )
  196. self.root_page.add_child(instance=calendar_page)
  197. event_page = EventPage(
  198. path='/eventpage/1/',
  199. depth=2,
  200. title='Event Page 1',
  201. slug='eventpage1'
  202. )
  203. calendar_page.add_child(instance=event_page)
  204. occurrence_one = EventOccurrence(
  205. event=event_page,
  206. start='2019-01-01T10:00:00+0000',
  207. end='2019-01-01T11:00:00+0000'
  208. )
  209. occurrence_one.save()
  210. response = self.client.post(
  211. "/ajax/calendar/events/?pid=" + str(calendar_page.pk),
  212. follow=True,
  213. **{'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
  214. )
  215. self.assertEqual(response.status_code, 200)
  216. # Get datetimes from response and compare them to datetimes on page
  217. start = literal_eval(response._container[0].decode()[1:-1])['start']
  218. end = literal_eval(response._container[0].decode()[1:-1])['end']
  219. event_local_start = timezone.localtime(
  220. EventOccurrence.objects.get(event=event_page).start
  221. )
  222. event_local_end = timezone.localtime(
  223. EventOccurrence.objects.get(event=event_page).end
  224. )
  225. self.assertEqual(
  226. start,
  227. event_local_start.strftime("%Y-%m-%dT%H:%M:%S%z")
  228. )
  229. self.assertEqual(
  230. end,
  231. event_local_end.strftime("%Y-%m-%dT%H:%M:%S%z")
  232. )
  233. @pytest.mark.django_db
  234. class TestFavicon(unittest.TestCase):
  235. def test_404(self):
  236. client = Client()
  237. # Get the default site
  238. site = Site.objects.filter(is_default_site=True)[0]
  239. # Ensure the favicon is blank
  240. layout = LayoutSettings.for_site(site)
  241. layout.favicon = None
  242. layout.save()
  243. # Expect a 404
  244. response = client.get("/favicon.ico")
  245. self.assertEqual(response.status_code, 404)
  246. def test_301(self):
  247. client = Client()
  248. # Get the default site
  249. site = Site.objects.filter(is_default_site=True)[0]
  250. # Set a dummy favicon
  251. layout = LayoutSettings.for_site(site)
  252. img = Image.objects.create(
  253. title="Test image",
  254. file=get_test_image_file(),
  255. )
  256. layout.favicon = img
  257. layout.save()
  258. # Expect a 301 redirect
  259. response = client.get("/favicon.ico")
  260. self.assertEqual(response.status_code, 301)