test_http.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. import os
  2. from datetime import date
  3. from django.contrib.sitemaps import Sitemap
  4. from django.contrib.sites.models import Site
  5. from django.core.exceptions import ImproperlyConfigured
  6. from django.test import ignore_warnings, modify_settings, override_settings
  7. from django.utils import translation
  8. from django.utils.deprecation import RemovedInDjango50Warning
  9. from django.utils.formats import localize
  10. from .base import SitemapTestsBase
  11. from .models import TestModel
  12. class HTTPSitemapTests(SitemapTestsBase):
  13. use_sitemap_err_msg = (
  14. 'To use sitemaps, either enable the sites framework or pass a '
  15. 'Site/RequestSite object in your view.'
  16. )
  17. def test_simple_sitemap_index(self):
  18. "A simple sitemap index can be rendered"
  19. response = self.client.get('/simple/index.xml')
  20. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  21. <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  22. <sitemap><loc>%s/simple/sitemap-simple.xml</loc><lastmod>%s</lastmod></sitemap>
  23. </sitemapindex>
  24. """ % (self.base_url, date.today())
  25. self.assertXMLEqual(response.content.decode(), expected_content)
  26. def test_sitemap_not_callable(self):
  27. """A sitemap may not be callable."""
  28. response = self.client.get('/simple-not-callable/index.xml')
  29. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  30. <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  31. <sitemap><loc>%s/simple/sitemap-simple.xml</loc><lastmod>%s</lastmod></sitemap>
  32. </sitemapindex>
  33. """ % (self.base_url, date.today())
  34. self.assertXMLEqual(response.content.decode(), expected_content)
  35. def test_paged_sitemap(self):
  36. """A sitemap may have multiple pages."""
  37. response = self.client.get('/simple-paged/index.xml')
  38. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  39. <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  40. <sitemap><loc>{0}/simple/sitemap-simple.xml</loc><lastmod>{1}</lastmod></sitemap><sitemap><loc>{0}/simple/sitemap-simple.xml?p=2</loc><lastmod>{1}</lastmod></sitemap>
  41. </sitemapindex>
  42. """.format(self.base_url, date.today())
  43. self.assertXMLEqual(response.content.decode(), expected_content)
  44. @override_settings(TEMPLATES=[{
  45. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  46. 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')],
  47. }])
  48. def test_simple_sitemap_custom_lastmod_index(self):
  49. "A simple sitemap index can be rendered with a custom template"
  50. response = self.client.get('/simple/custom-lastmod-index.xml')
  51. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  52. <!-- This is a customised template -->
  53. <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  54. <sitemap><loc>%s/simple/sitemap-simple.xml</loc><lastmod>%s</lastmod></sitemap>
  55. </sitemapindex>
  56. """ % (self.base_url, date.today())
  57. self.assertXMLEqual(response.content.decode(), expected_content)
  58. def test_simple_sitemap_section(self):
  59. "A simple sitemap section can be rendered"
  60. response = self.client.get('/simple/sitemap-simple.xml')
  61. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  62. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  63. <url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
  64. </urlset>
  65. """ % (self.base_url, date.today())
  66. self.assertXMLEqual(response.content.decode(), expected_content)
  67. def test_no_section(self):
  68. response = self.client.get('/simple/sitemap-simple2.xml')
  69. self.assertEqual(str(response.context['exception']), "No sitemap available for section: 'simple2'")
  70. self.assertEqual(response.status_code, 404)
  71. def test_empty_page(self):
  72. response = self.client.get('/simple/sitemap-simple.xml?p=0')
  73. self.assertEqual(str(response.context['exception']), 'Page 0 empty')
  74. self.assertEqual(response.status_code, 404)
  75. def test_page_not_int(self):
  76. response = self.client.get('/simple/sitemap-simple.xml?p=test')
  77. self.assertEqual(str(response.context['exception']), "No page 'test'")
  78. self.assertEqual(response.status_code, 404)
  79. def test_simple_sitemap(self):
  80. "A simple sitemap can be rendered"
  81. response = self.client.get('/simple/sitemap.xml')
  82. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  83. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  84. <url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
  85. </urlset>
  86. """ % (self.base_url, date.today())
  87. self.assertXMLEqual(response.content.decode(), expected_content)
  88. @override_settings(TEMPLATES=[{
  89. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  90. 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')],
  91. }])
  92. def test_simple_custom_sitemap(self):
  93. "A simple sitemap can be rendered with a custom template"
  94. response = self.client.get('/simple/custom-sitemap.xml')
  95. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  96. <!-- This is a customised template -->
  97. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  98. <url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
  99. </urlset>
  100. """ % (self.base_url, date.today())
  101. self.assertXMLEqual(response.content.decode(), expected_content)
  102. def test_sitemap_last_modified(self):
  103. "Last-Modified header is set correctly"
  104. response = self.client.get('/lastmod/sitemap.xml')
  105. self.assertEqual(response.headers['Last-Modified'], 'Wed, 13 Mar 2013 10:00:00 GMT')
  106. def test_sitemap_last_modified_date(self):
  107. """
  108. The Last-Modified header should be support dates (without time).
  109. """
  110. response = self.client.get('/lastmod/date-sitemap.xml')
  111. self.assertEqual(response.headers['Last-Modified'], 'Wed, 13 Mar 2013 00:00:00 GMT')
  112. def test_sitemap_last_modified_tz(self):
  113. """
  114. The Last-Modified header should be converted from timezone aware dates
  115. to GMT.
  116. """
  117. response = self.client.get('/lastmod/tz-sitemap.xml')
  118. self.assertEqual(response.headers['Last-Modified'], 'Wed, 13 Mar 2013 15:00:00 GMT')
  119. def test_sitemap_last_modified_missing(self):
  120. "Last-Modified header is missing when sitemap has no lastmod"
  121. response = self.client.get('/generic/sitemap.xml')
  122. self.assertFalse(response.has_header('Last-Modified'))
  123. def test_sitemap_last_modified_mixed(self):
  124. "Last-Modified header is omitted when lastmod not on all items"
  125. response = self.client.get('/lastmod-mixed/sitemap.xml')
  126. self.assertFalse(response.has_header('Last-Modified'))
  127. def test_sitemaps_lastmod_mixed_ascending_last_modified_missing(self):
  128. """
  129. The Last-Modified header is omitted when lastmod isn't found in all
  130. sitemaps. Test sitemaps are sorted by lastmod in ascending order.
  131. """
  132. response = self.client.get('/lastmod-sitemaps/mixed-ascending.xml')
  133. self.assertFalse(response.has_header('Last-Modified'))
  134. def test_sitemaps_lastmod_mixed_descending_last_modified_missing(self):
  135. """
  136. The Last-Modified header is omitted when lastmod isn't found in all
  137. sitemaps. Test sitemaps are sorted by lastmod in descending order.
  138. """
  139. response = self.client.get('/lastmod-sitemaps/mixed-descending.xml')
  140. self.assertFalse(response.has_header('Last-Modified'))
  141. def test_sitemaps_lastmod_ascending(self):
  142. """
  143. The Last-Modified header is set to the most recent sitemap lastmod.
  144. Test sitemaps are sorted by lastmod in ascending order.
  145. """
  146. response = self.client.get('/lastmod-sitemaps/ascending.xml')
  147. self.assertEqual(response.headers['Last-Modified'], 'Sat, 20 Apr 2013 05:00:00 GMT')
  148. def test_sitemaps_lastmod_descending(self):
  149. """
  150. The Last-Modified header is set to the most recent sitemap lastmod.
  151. Test sitemaps are sorted by lastmod in descending order.
  152. """
  153. response = self.client.get('/lastmod-sitemaps/descending.xml')
  154. self.assertEqual(response.headers['Last-Modified'], 'Sat, 20 Apr 2013 05:00:00 GMT')
  155. def test_sitemap_get_latest_lastmod_none(self):
  156. """
  157. sitemapindex.lastmod is ommitted when Sitemap.lastmod is
  158. callable and Sitemap.get_latest_lastmod is not implemented
  159. """
  160. response = self.client.get('/lastmod/get-latest-lastmod-none-sitemap.xml')
  161. self.assertNotContains(response, '<lastmod>')
  162. def test_sitemap_get_latest_lastmod(self):
  163. """
  164. sitemapindex.lastmod is included when Sitemap.lastmod is
  165. attribute and Sitemap.get_latest_lastmod is implemented
  166. """
  167. response = self.client.get('/lastmod/get-latest-lastmod-sitemap.xml')
  168. self.assertContains(response, '<lastmod>2013-03-13T10:00:00</lastmod>')
  169. def test_sitemap_latest_lastmod_timezone(self):
  170. """
  171. lastmod datestamp shows timezones if Sitemap.get_latest_lastmod
  172. returns an aware datetime.
  173. """
  174. response = self.client.get('/lastmod/latest-lastmod-timezone-sitemap.xml')
  175. self.assertContains(response, '<lastmod>2013-03-13T10:00:00-05:00</lastmod>')
  176. def test_localized_priority(self):
  177. """The priority value should not be localized."""
  178. with translation.override('fr'):
  179. self.assertEqual('0,3', localize(0.3))
  180. # Priorities aren't rendered in localized format.
  181. response = self.client.get('/simple/sitemap.xml')
  182. self.assertContains(response, '<priority>0.5</priority>')
  183. self.assertContains(response, '<lastmod>%s</lastmod>' % date.today())
  184. @modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
  185. def test_requestsite_sitemap(self):
  186. # Hitting the flatpages sitemap without the sites framework installed
  187. # doesn't raise an exception.
  188. response = self.client.get('/simple/sitemap.xml')
  189. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  190. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  191. <url><loc>http://testserver/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
  192. </urlset>
  193. """ % date.today()
  194. self.assertXMLEqual(response.content.decode(), expected_content)
  195. @ignore_warnings(category=RemovedInDjango50Warning)
  196. def test_sitemap_get_urls_no_site_1(self):
  197. """
  198. Check we get ImproperlyConfigured if we don't pass a site object to
  199. Sitemap.get_urls and no Site objects exist
  200. """
  201. Site.objects.all().delete()
  202. with self.assertRaisesMessage(ImproperlyConfigured, self.use_sitemap_err_msg):
  203. Sitemap().get_urls()
  204. @modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
  205. @ignore_warnings(category=RemovedInDjango50Warning)
  206. def test_sitemap_get_urls_no_site_2(self):
  207. """
  208. Check we get ImproperlyConfigured when we don't pass a site object to
  209. Sitemap.get_urls if Site objects exists, but the sites framework is not
  210. actually installed.
  211. """
  212. with self.assertRaisesMessage(ImproperlyConfigured, self.use_sitemap_err_msg):
  213. Sitemap().get_urls()
  214. @ignore_warnings(category=RemovedInDjango50Warning)
  215. def test_sitemap_item(self):
  216. """
  217. Check to make sure that the raw item is included with each
  218. Sitemap.get_url() url result.
  219. """
  220. test_sitemap = Sitemap()
  221. test_sitemap.items = TestModel.objects.order_by('pk').all
  222. def is_testmodel(url):
  223. return isinstance(url['item'], TestModel)
  224. item_in_url_info = all(map(is_testmodel, test_sitemap.get_urls()))
  225. self.assertTrue(item_in_url_info)
  226. def test_cached_sitemap_index(self):
  227. """
  228. A cached sitemap index can be rendered (#2713).
  229. """
  230. response = self.client.get('/cached/index.xml')
  231. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  232. <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  233. <sitemap><loc>%s/cached/sitemap-simple.xml</loc><lastmod>%s</lastmod></sitemap>
  234. </sitemapindex>
  235. """ % (self.base_url, date.today())
  236. self.assertXMLEqual(response.content.decode(), expected_content)
  237. def test_x_robots_sitemap(self):
  238. response = self.client.get('/simple/index.xml')
  239. self.assertEqual(response.headers['X-Robots-Tag'], 'noindex, noodp, noarchive')
  240. response = self.client.get('/simple/sitemap.xml')
  241. self.assertEqual(response.headers['X-Robots-Tag'], 'noindex, noodp, noarchive')
  242. def test_empty_sitemap(self):
  243. response = self.client.get('/empty/sitemap.xml')
  244. self.assertEqual(response.status_code, 200)
  245. @override_settings(LANGUAGES=(('en', 'English'), ('pt', 'Portuguese')))
  246. def test_simple_i18n_sitemap_index(self):
  247. """
  248. A simple i18n sitemap index can be rendered, without logging variable
  249. lookup errors.
  250. """
  251. with self.assertNoLogs('django.template', 'DEBUG'):
  252. response = self.client.get('/simple/i18n.xml')
  253. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  254. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  255. <url><loc>{0}/en/i18n/testmodel/{1}/</loc><changefreq>never</changefreq><priority>0.5</priority></url><url><loc>{0}/pt/i18n/testmodel/{1}/</loc><changefreq>never</changefreq><priority>0.5</priority></url>
  256. </urlset>
  257. """.format(self.base_url, self.i18n_model.pk)
  258. self.assertXMLEqual(response.content.decode(), expected_content)
  259. @override_settings(LANGUAGES=(('en', 'English'), ('pt', 'Portuguese')))
  260. def test_alternate_i18n_sitemap_index(self):
  261. """
  262. A i18n sitemap with alternate/hreflang links can be rendered.
  263. """
  264. response = self.client.get('/alternates/i18n.xml')
  265. url, pk = self.base_url, self.i18n_model.pk
  266. expected_urls = f"""
  267. <url><loc>{url}/en/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
  268. <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
  269. <xhtml:link rel="alternate" hreflang="pt" href="{url}/pt/i18n/testmodel/{pk}/"/>
  270. </url>
  271. <url><loc>{url}/pt/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
  272. <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
  273. <xhtml:link rel="alternate" hreflang="pt" href="{url}/pt/i18n/testmodel/{pk}/"/>
  274. </url>
  275. """.replace('\n', '')
  276. expected_content = f"""<?xml version="1.0" encoding="UTF-8"?>
  277. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  278. {expected_urls}
  279. </urlset>
  280. """
  281. self.assertXMLEqual(response.content.decode(), expected_content)
  282. @override_settings(LANGUAGES=(('en', 'English'), ('pt', 'Portuguese'), ('es', 'Spanish')))
  283. def test_alternate_i18n_sitemap_limited(self):
  284. """
  285. A i18n sitemap index with limited languages can be rendered.
  286. """
  287. response = self.client.get('/limited/i18n.xml')
  288. url, pk = self.base_url, self.i18n_model.pk
  289. expected_urls = f"""
  290. <url><loc>{url}/en/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
  291. <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
  292. <xhtml:link rel="alternate" hreflang="es" href="{url}/es/i18n/testmodel/{pk}/"/>
  293. </url>
  294. <url><loc>{url}/es/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
  295. <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
  296. <xhtml:link rel="alternate" hreflang="es" href="{url}/es/i18n/testmodel/{pk}/"/>
  297. </url>
  298. """.replace('\n', '')
  299. expected_content = f"""<?xml version="1.0" encoding="UTF-8"?>
  300. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  301. {expected_urls}
  302. </urlset>
  303. """
  304. self.assertXMLEqual(response.content.decode(), expected_content)
  305. @override_settings(LANGUAGES=(('en', 'English'), ('pt', 'Portuguese')))
  306. def test_alternate_i18n_sitemap_xdefault(self):
  307. """
  308. A i18n sitemap index with x-default can be rendered.
  309. """
  310. response = self.client.get('/x-default/i18n.xml')
  311. url, pk = self.base_url, self.i18n_model.pk
  312. expected_urls = f"""
  313. <url><loc>{url}/en/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
  314. <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
  315. <xhtml:link rel="alternate" hreflang="pt" href="{url}/pt/i18n/testmodel/{pk}/"/>
  316. <xhtml:link rel="alternate" hreflang="x-default" href="{url}/i18n/testmodel/{pk}/"/>
  317. </url>
  318. <url><loc>{url}/pt/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
  319. <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
  320. <xhtml:link rel="alternate" hreflang="pt" href="{url}/pt/i18n/testmodel/{pk}/"/>
  321. <xhtml:link rel="alternate" hreflang="x-default" href="{url}/i18n/testmodel/{pk}/"/>
  322. </url>
  323. """.replace('\n', '')
  324. expected_content = f"""<?xml version="1.0" encoding="UTF-8"?>
  325. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  326. {expected_urls}
  327. </urlset>
  328. """
  329. self.assertXMLEqual(response.content.decode(), expected_content)
  330. def test_sitemap_without_entries(self):
  331. response = self.client.get('/sitemap-without-entries/sitemap.xml')
  332. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  333. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  334. </urlset>"""
  335. self.assertXMLEqual(response.content.decode(), expected_content)
  336. def test_callable_sitemod_partial(self):
  337. """
  338. Not all items have `lastmod`. Therefore the `Last-Modified` header
  339. is not set by the detail or index sitemap view.
  340. """
  341. index_response = self.client.get('/callable-lastmod-partial/index.xml')
  342. sitemap_response = self.client.get('/callable-lastmod-partial/sitemap.xml')
  343. self.assertNotIn('Last-Modified', index_response)
  344. self.assertNotIn('Last-Modified', sitemap_response)
  345. expected_content_index = """<?xml version="1.0" encoding="UTF-8"?>
  346. <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  347. <sitemap><loc>http://example.com/simple/sitemap-callable-lastmod.xml</loc></sitemap>
  348. </sitemapindex>
  349. """
  350. expected_content_sitemap = """<?xml version="1.0" encoding="UTF-8"?>
  351. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  352. <url><loc>http://example.com/location/</loc><lastmod>2013-03-13</lastmod></url><url><loc>http://example.com/location/</loc></url>
  353. </urlset>
  354. """
  355. self.assertXMLEqual(index_response.content.decode(), expected_content_index)
  356. self.assertXMLEqual(sitemap_response.content.decode(), expected_content_sitemap)
  357. def test_callable_sitemod_full(self):
  358. """
  359. All items in the sitemap have `lastmod`. The `Last-Modified` header
  360. is set for the detail and index sitemap view.
  361. """
  362. index_response = self.client.get('/callable-lastmod-full/index.xml')
  363. sitemap_response = self.client.get('/callable-lastmod-full/sitemap.xml')
  364. self.assertEqual(index_response.headers['Last-Modified'], 'Thu, 13 Mar 2014 10:00:00 GMT')
  365. self.assertEqual(sitemap_response.headers['Last-Modified'], 'Thu, 13 Mar 2014 10:00:00 GMT')
  366. expected_content_index = """<?xml version="1.0" encoding="UTF-8"?>
  367. <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  368. <sitemap><loc>http://example.com/simple/sitemap-callable-lastmod.xml</loc><lastmod>2014-03-13T10:00:00</lastmod></sitemap>
  369. </sitemapindex>
  370. """
  371. expected_content_sitemap = """<?xml version="1.0" encoding="UTF-8"?>
  372. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  373. <url><loc>http://example.com/location/</loc><lastmod>2013-03-13</lastmod></url><url><loc>http://example.com/location/</loc><lastmod>2014-03-13</lastmod></url>
  374. </urlset>
  375. """
  376. self.assertXMLEqual(index_response.content.decode(), expected_content_index)
  377. self.assertXMLEqual(sitemap_response.content.decode(), expected_content_sitemap)
  378. # RemovedInDjango50Warning
  379. class DeprecatedTests(SitemapTestsBase):
  380. @override_settings(TEMPLATES=[{
  381. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  382. 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')],
  383. }])
  384. def test_simple_sitemap_custom_index_warning(self):
  385. msg = 'Calling `__str__` on SitemapIndexItem is deprecated, use the `location` attribute instead.'
  386. with self.assertRaisesMessage(RemovedInDjango50Warning, msg):
  387. self.client.get('/simple/custom-index.xml')
  388. @ignore_warnings(category=RemovedInDjango50Warning)
  389. @override_settings(TEMPLATES=[{
  390. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  391. 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')],
  392. }])
  393. def test_simple_sitemap_custom_index(self):
  394. "A simple sitemap index can be rendered with a custom template"
  395. response = self.client.get('/simple/custom-index.xml')
  396. expected_content = """<?xml version="1.0" encoding="UTF-8"?>
  397. <!-- This is a customised template -->
  398. <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  399. <sitemap><loc>%s/simple/sitemap-simple.xml</loc></sitemap>
  400. </sitemapindex>
  401. """ % (self.base_url)
  402. self.assertXMLEqual(response.content.decode(), expected_content)