123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625 |
- import os
- from datetime import date
- from django.contrib.sitemaps import Sitemap
- from django.contrib.sites.models import Site
- from django.core.exceptions import ImproperlyConfigured
- from django.test import ignore_warnings, modify_settings, override_settings
- from django.utils import translation
- from django.utils.deprecation import RemovedInDjango50Warning
- from django.utils.formats import localize
- from .base import SitemapTestsBase
- from .models import I18nTestModel, TestModel
- class HTTPSitemapTests(SitemapTestsBase):
- use_sitemap_err_msg = (
- "To use sitemaps, either enable the sites framework or pass a "
- "Site/RequestSite object in your view."
- )
- def test_simple_sitemap_index(self):
- "A simple sitemap index can be rendered"
- response = self.client.get("/simple/index.xml")
- expected_content = """<?xml version="1.0" encoding="UTF-8"?>
- <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- <sitemap><loc>%s/simple/sitemap-simple.xml</loc><lastmod>%s</lastmod></sitemap>
- </sitemapindex>
- """ % (
- self.base_url,
- date.today(),
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- def test_sitemap_not_callable(self):
- """A sitemap may not be callable."""
- response = self.client.get("/simple-not-callable/index.xml")
- expected_content = """<?xml version="1.0" encoding="UTF-8"?>
- <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- <sitemap><loc>%s/simple/sitemap-simple.xml</loc><lastmod>%s</lastmod></sitemap>
- </sitemapindex>
- """ % (
- self.base_url,
- date.today(),
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- def test_paged_sitemap(self):
- """A sitemap may have multiple pages."""
- response = self.client.get("/simple-paged/index.xml")
- expected_content = """<?xml version="1.0" encoding="UTF-8"?>
- <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- <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>
- </sitemapindex>
- """.format(
- self.base_url, date.today()
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- @override_settings(
- TEMPLATES=[
- {
- "BACKEND": "django.template.backends.django.DjangoTemplates",
- "DIRS": [os.path.join(os.path.dirname(__file__), "templates")],
- }
- ]
- )
- def test_simple_sitemap_custom_lastmod_index(self):
- "A simple sitemap index can be rendered with a custom template"
- response = self.client.get("/simple/custom-lastmod-index.xml")
- expected_content = """<?xml version="1.0" encoding="UTF-8"?>
- <!-- This is a customised template -->
- <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- <sitemap><loc>%s/simple/sitemap-simple.xml</loc><lastmod>%s</lastmod></sitemap>
- </sitemapindex>
- """ % (
- self.base_url,
- date.today(),
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- def test_simple_sitemap_section(self):
- "A simple sitemap section can be rendered"
- response = self.client.get("/simple/sitemap-simple.xml")
- expected_content = (
- '<?xml version="1.0" encoding="UTF-8"?>\n'
- '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- 'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- "<url><loc>%s/location/</loc><lastmod>%s</lastmod>"
- "<changefreq>never</changefreq><priority>0.5</priority></url>\n"
- "</urlset>"
- ) % (
- self.base_url,
- date.today(),
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- def test_no_section(self):
- response = self.client.get("/simple/sitemap-simple2.xml")
- self.assertEqual(
- str(response.context["exception"]),
- "No sitemap available for section: 'simple2'",
- )
- self.assertEqual(response.status_code, 404)
- def test_empty_page(self):
- response = self.client.get("/simple/sitemap-simple.xml?p=0")
- self.assertEqual(str(response.context["exception"]), "Page 0 empty")
- self.assertEqual(response.status_code, 404)
- def test_page_not_int(self):
- response = self.client.get("/simple/sitemap-simple.xml?p=test")
- self.assertEqual(str(response.context["exception"]), "No page 'test'")
- self.assertEqual(response.status_code, 404)
- def test_simple_sitemap(self):
- "A simple sitemap can be rendered"
- response = self.client.get("/simple/sitemap.xml")
- expected_content = (
- '<?xml version="1.0" encoding="UTF-8"?>\n'
- '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- 'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- "<url><loc>%s/location/</loc><lastmod>%s</lastmod>"
- "<changefreq>never</changefreq><priority>0.5</priority></url>\n"
- "</urlset>"
- ) % (
- self.base_url,
- date.today(),
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- @override_settings(
- TEMPLATES=[
- {
- "BACKEND": "django.template.backends.django.DjangoTemplates",
- "DIRS": [os.path.join(os.path.dirname(__file__), "templates")],
- }
- ]
- )
- def test_simple_custom_sitemap(self):
- "A simple sitemap can be rendered with a custom template"
- response = self.client.get("/simple/custom-sitemap.xml")
- expected_content = """<?xml version="1.0" encoding="UTF-8"?>
- <!-- This is a customised template -->
- <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- <url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
- </urlset>
- """ % (
- self.base_url,
- date.today(),
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- def test_sitemap_last_modified(self):
- "Last-Modified header is set correctly"
- response = self.client.get("/lastmod/sitemap.xml")
- self.assertEqual(
- response.headers["Last-Modified"], "Wed, 13 Mar 2013 10:00:00 GMT"
- )
- def test_sitemap_last_modified_date(self):
- """
- The Last-Modified header should be support dates (without time).
- """
- response = self.client.get("/lastmod/date-sitemap.xml")
- self.assertEqual(
- response.headers["Last-Modified"], "Wed, 13 Mar 2013 00:00:00 GMT"
- )
- def test_sitemap_last_modified_tz(self):
- """
- The Last-Modified header should be converted from timezone aware dates
- to GMT.
- """
- response = self.client.get("/lastmod/tz-sitemap.xml")
- self.assertEqual(
- response.headers["Last-Modified"], "Wed, 13 Mar 2013 15:00:00 GMT"
- )
- def test_sitemap_last_modified_missing(self):
- "Last-Modified header is missing when sitemap has no lastmod"
- response = self.client.get("/generic/sitemap.xml")
- self.assertFalse(response.has_header("Last-Modified"))
- def test_sitemap_last_modified_mixed(self):
- "Last-Modified header is omitted when lastmod not on all items"
- response = self.client.get("/lastmod-mixed/sitemap.xml")
- self.assertFalse(response.has_header("Last-Modified"))
- def test_sitemaps_lastmod_mixed_ascending_last_modified_missing(self):
- """
- The Last-Modified header is omitted when lastmod isn't found in all
- sitemaps. Test sitemaps are sorted by lastmod in ascending order.
- """
- response = self.client.get("/lastmod-sitemaps/mixed-ascending.xml")
- self.assertFalse(response.has_header("Last-Modified"))
- def test_sitemaps_lastmod_mixed_descending_last_modified_missing(self):
- """
- The Last-Modified header is omitted when lastmod isn't found in all
- sitemaps. Test sitemaps are sorted by lastmod in descending order.
- """
- response = self.client.get("/lastmod-sitemaps/mixed-descending.xml")
- self.assertFalse(response.has_header("Last-Modified"))
- def test_sitemaps_lastmod_ascending(self):
- """
- The Last-Modified header is set to the most recent sitemap lastmod.
- Test sitemaps are sorted by lastmod in ascending order.
- """
- response = self.client.get("/lastmod-sitemaps/ascending.xml")
- self.assertEqual(
- response.headers["Last-Modified"], "Sat, 20 Apr 2013 05:00:00 GMT"
- )
- def test_sitemaps_lastmod_descending(self):
- """
- The Last-Modified header is set to the most recent sitemap lastmod.
- Test sitemaps are sorted by lastmod in descending order.
- """
- response = self.client.get("/lastmod-sitemaps/descending.xml")
- self.assertEqual(
- response.headers["Last-Modified"], "Sat, 20 Apr 2013 05:00:00 GMT"
- )
- def test_sitemap_get_latest_lastmod_none(self):
- """
- sitemapindex.lastmod is omitted when Sitemap.lastmod is
- callable and Sitemap.get_latest_lastmod is not implemented
- """
- response = self.client.get("/lastmod/get-latest-lastmod-none-sitemap.xml")
- self.assertNotContains(response, "<lastmod>")
- def test_sitemap_get_latest_lastmod(self):
- """
- sitemapindex.lastmod is included when Sitemap.lastmod is
- attribute and Sitemap.get_latest_lastmod is implemented
- """
- response = self.client.get("/lastmod/get-latest-lastmod-sitemap.xml")
- self.assertContains(response, "<lastmod>2013-03-13T10:00:00</lastmod>")
- def test_sitemap_latest_lastmod_timezone(self):
- """
- lastmod datestamp shows timezones if Sitemap.get_latest_lastmod
- returns an aware datetime.
- """
- response = self.client.get("/lastmod/latest-lastmod-timezone-sitemap.xml")
- self.assertContains(response, "<lastmod>2013-03-13T10:00:00-05:00</lastmod>")
- def test_localized_priority(self):
- """The priority value should not be localized."""
- with translation.override("fr"):
- self.assertEqual("0,3", localize(0.3))
- # Priorities aren't rendered in localized format.
- response = self.client.get("/simple/sitemap.xml")
- self.assertContains(response, "<priority>0.5</priority>")
- self.assertContains(response, "<lastmod>%s</lastmod>" % date.today())
- @modify_settings(INSTALLED_APPS={"remove": "django.contrib.sites"})
- def test_requestsite_sitemap(self):
- # Hitting the flatpages sitemap without the sites framework installed
- # doesn't raise an exception.
- response = self.client.get("/simple/sitemap.xml")
- expected_content = (
- '<?xml version="1.0" encoding="UTF-8"?>\n'
- '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- 'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- "<url><loc>http://testserver/location/</loc><lastmod>%s</lastmod>"
- "<changefreq>never</changefreq><priority>0.5</priority></url>\n"
- "</urlset>"
- ) % date.today()
- self.assertXMLEqual(response.content.decode(), expected_content)
- @ignore_warnings(category=RemovedInDjango50Warning)
- def test_sitemap_get_urls_no_site_1(self):
- """
- Check we get ImproperlyConfigured if we don't pass a site object to
- Sitemap.get_urls and no Site objects exist
- """
- Site.objects.all().delete()
- with self.assertRaisesMessage(ImproperlyConfigured, self.use_sitemap_err_msg):
- Sitemap().get_urls()
- @modify_settings(INSTALLED_APPS={"remove": "django.contrib.sites"})
- @ignore_warnings(category=RemovedInDjango50Warning)
- def test_sitemap_get_urls_no_site_2(self):
- """
- Check we get ImproperlyConfigured when we don't pass a site object to
- Sitemap.get_urls if Site objects exists, but the sites framework is not
- actually installed.
- """
- with self.assertRaisesMessage(ImproperlyConfigured, self.use_sitemap_err_msg):
- Sitemap().get_urls()
- @ignore_warnings(category=RemovedInDjango50Warning)
- def test_sitemap_item(self):
- """
- Check to make sure that the raw item is included with each
- Sitemap.get_url() url result.
- """
- test_sitemap = Sitemap()
- test_sitemap.items = TestModel.objects.order_by("pk").all
- def is_testmodel(url):
- return isinstance(url["item"], TestModel)
- item_in_url_info = all(map(is_testmodel, test_sitemap.get_urls()))
- self.assertTrue(item_in_url_info)
- def test_cached_sitemap_index(self):
- """
- A cached sitemap index can be rendered (#2713).
- """
- response = self.client.get("/cached/index.xml")
- expected_content = """<?xml version="1.0" encoding="UTF-8"?>
- <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- <sitemap><loc>%s/cached/sitemap-simple.xml</loc><lastmod>%s</lastmod></sitemap>
- </sitemapindex>
- """ % (
- self.base_url,
- date.today(),
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- def test_x_robots_sitemap(self):
- response = self.client.get("/simple/index.xml")
- self.assertEqual(response.headers["X-Robots-Tag"], "noindex, noodp, noarchive")
- response = self.client.get("/simple/sitemap.xml")
- self.assertEqual(response.headers["X-Robots-Tag"], "noindex, noodp, noarchive")
- def test_empty_sitemap(self):
- response = self.client.get("/empty/sitemap.xml")
- self.assertEqual(response.status_code, 200)
- @override_settings(LANGUAGES=(("en", "English"), ("pt", "Portuguese")))
- def test_simple_i18n_sitemap_index(self):
- """
- A simple i18n sitemap index can be rendered, without logging variable
- lookup errors.
- """
- with self.assertNoLogs("django.template", "DEBUG"):
- response = self.client.get("/simple/i18n.xml")
- expected_content = (
- '<?xml version="1.0" encoding="UTF-8"?>\n'
- '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- 'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- "<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>\n"
- "</urlset>"
- ).format(self.base_url, self.i18n_model.pk)
- self.assertXMLEqual(response.content.decode(), expected_content)
- @override_settings(LANGUAGES=(("en", "English"), ("pt", "Portuguese")))
- def test_alternate_i18n_sitemap_index(self):
- """
- A i18n sitemap with alternate/hreflang links can be rendered.
- """
- response = self.client.get("/alternates/i18n.xml")
- url, pk = self.base_url, self.i18n_model.pk
- expected_urls = f"""
- <url><loc>{url}/en/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
- <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
- <xhtml:link rel="alternate" hreflang="pt" href="{url}/pt/i18n/testmodel/{pk}/"/>
- </url>
- <url><loc>{url}/pt/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
- <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
- <xhtml:link rel="alternate" hreflang="pt" href="{url}/pt/i18n/testmodel/{pk}/"/>
- </url>
- """.replace(
- "\n", ""
- )
- expected_content = (
- f'<?xml version="1.0" encoding="UTF-8"?>\n'
- f'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- f'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- f"{expected_urls}\n"
- f"</urlset>"
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- @override_settings(
- LANGUAGES=(("en", "English"), ("pt", "Portuguese"), ("es", "Spanish"))
- )
- def test_alternate_i18n_sitemap_limited(self):
- """
- A i18n sitemap index with limited languages can be rendered.
- """
- response = self.client.get("/limited/i18n.xml")
- url, pk = self.base_url, self.i18n_model.pk
- expected_urls = f"""
- <url><loc>{url}/en/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
- <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
- <xhtml:link rel="alternate" hreflang="es" href="{url}/es/i18n/testmodel/{pk}/"/>
- </url>
- <url><loc>{url}/es/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
- <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
- <xhtml:link rel="alternate" hreflang="es" href="{url}/es/i18n/testmodel/{pk}/"/>
- </url>
- """.replace(
- "\n", ""
- )
- expected_content = (
- f'<?xml version="1.0" encoding="UTF-8"?>\n'
- f'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- f'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- f"{expected_urls}\n"
- f"</urlset>"
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- @override_settings(LANGUAGES=(("en", "English"), ("pt", "Portuguese")))
- def test_alternate_i18n_sitemap_xdefault(self):
- """
- A i18n sitemap index with x-default can be rendered.
- """
- response = self.client.get("/x-default/i18n.xml")
- url, pk = self.base_url, self.i18n_model.pk
- expected_urls = f"""
- <url><loc>{url}/en/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
- <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
- <xhtml:link rel="alternate" hreflang="pt" href="{url}/pt/i18n/testmodel/{pk}/"/>
- <xhtml:link rel="alternate" hreflang="x-default" href="{url}/i18n/testmodel/{pk}/"/>
- </url>
- <url><loc>{url}/pt/i18n/testmodel/{pk}/</loc><changefreq>never</changefreq><priority>0.5</priority>
- <xhtml:link rel="alternate" hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>
- <xhtml:link rel="alternate" hreflang="pt" href="{url}/pt/i18n/testmodel/{pk}/"/>
- <xhtml:link rel="alternate" hreflang="x-default" href="{url}/i18n/testmodel/{pk}/"/>
- </url>
- """.replace(
- "\n", ""
- )
- expected_content = (
- f'<?xml version="1.0" encoding="UTF-8"?>\n'
- f'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- f'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- f"{expected_urls}\n"
- f"</urlset>"
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- @override_settings(LANGUAGES=(("en", "English"), ("pt", "Portuguese")))
- def test_language_for_item_i18n_sitemap(self):
- """
- A i18n sitemap index in which item can be chosen to be displayed for a
- lang or not.
- """
- only_pt = I18nTestModel.objects.create(name="Only for PT")
- response = self.client.get("/item-by-lang/i18n.xml")
- url, pk, only_pt_pk = self.base_url, self.i18n_model.pk, only_pt.pk
- expected_urls = (
- f"<url><loc>{url}/en/i18n/testmodel/{pk}/</loc>"
- f"<changefreq>never</changefreq><priority>0.5</priority></url>"
- f"<url><loc>{url}/pt/i18n/testmodel/{pk}/</loc>"
- f"<changefreq>never</changefreq><priority>0.5</priority></url>"
- f"<url><loc>{url}/pt/i18n/testmodel/{only_pt_pk}/</loc>"
- f"<changefreq>never</changefreq><priority>0.5</priority></url>"
- )
- expected_content = (
- f'<?xml version="1.0" encoding="UTF-8"?>\n'
- f'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- f'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- f"{expected_urls}\n"
- f"</urlset>"
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- @override_settings(LANGUAGES=(("en", "English"), ("pt", "Portuguese")))
- def test_alternate_language_for_item_i18n_sitemap(self):
- """
- A i18n sitemap index in which item can be chosen to be displayed for a
- lang or not.
- """
- only_pt = I18nTestModel.objects.create(name="Only for PT")
- response = self.client.get("/item-by-lang-alternates/i18n.xml")
- url, pk, only_pt_pk = self.base_url, self.i18n_model.pk, only_pt.pk
- expected_urls = (
- f"<url><loc>{url}/en/i18n/testmodel/{pk}/</loc>"
- f"<changefreq>never</changefreq><priority>0.5</priority>"
- f'<xhtml:link rel="alternate" '
- f'hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>'
- f'<xhtml:link rel="alternate" '
- f'hreflang="pt" href="{url}/pt/i18n/testmodel/{pk}/"/>'
- f'<xhtml:link rel="alternate" '
- f'hreflang="x-default" href="{url}/i18n/testmodel/{pk}/"/></url>'
- f"<url><loc>{url}/pt/i18n/testmodel/{pk}/</loc>"
- f"<changefreq>never</changefreq><priority>0.5</priority>"
- f'<xhtml:link rel="alternate" '
- f'hreflang="en" href="{url}/en/i18n/testmodel/{pk}/"/>'
- f'<xhtml:link rel="alternate" '
- f'hreflang="pt" href="{url}/pt/i18n/testmodel/{pk}/"/>'
- f'<xhtml:link rel="alternate" '
- f'hreflang="x-default" href="{url}/i18n/testmodel/{pk}/"/></url>'
- f"<url><loc>{url}/pt/i18n/testmodel/{only_pt_pk}/</loc>"
- f"<changefreq>never</changefreq><priority>0.5</priority>"
- f'<xhtml:link rel="alternate" '
- f'hreflang="pt" href="{url}/pt/i18n/testmodel/{only_pt_pk}/"/></url>'
- )
- expected_content = (
- f'<?xml version="1.0" encoding="UTF-8"?>\n'
- f'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- f'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- f"{expected_urls}\n"
- f"</urlset>"
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- def test_sitemap_without_entries(self):
- response = self.client.get("/sitemap-without-entries/sitemap.xml")
- expected_content = (
- '<?xml version="1.0" encoding="UTF-8"?>\n'
- '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- 'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n\n'
- "</urlset>"
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
- def test_callable_sitemod_partial(self):
- """
- Not all items have `lastmod`. Therefore the `Last-Modified` header
- is not set by the detail or index sitemap view.
- """
- index_response = self.client.get("/callable-lastmod-partial/index.xml")
- sitemap_response = self.client.get("/callable-lastmod-partial/sitemap.xml")
- self.assertNotIn("Last-Modified", index_response)
- self.assertNotIn("Last-Modified", sitemap_response)
- expected_content_index = """<?xml version="1.0" encoding="UTF-8"?>
- <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- <sitemap><loc>http://example.com/simple/sitemap-callable-lastmod.xml</loc></sitemap>
- </sitemapindex>
- """
- expected_content_sitemap = (
- '<?xml version="1.0" encoding="UTF-8"?>\n'
- '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- 'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- "<url><loc>http://example.com/location/</loc>"
- "<lastmod>2013-03-13</lastmod></url><url>"
- "<loc>http://example.com/location/</loc></url>\n"
- "</urlset>"
- )
- self.assertXMLEqual(index_response.content.decode(), expected_content_index)
- self.assertXMLEqual(sitemap_response.content.decode(), expected_content_sitemap)
- def test_callable_sitemod_full(self):
- """
- All items in the sitemap have `lastmod`. The `Last-Modified` header
- is set for the detail and index sitemap view.
- """
- index_response = self.client.get("/callable-lastmod-full/index.xml")
- sitemap_response = self.client.get("/callable-lastmod-full/sitemap.xml")
- self.assertEqual(
- index_response.headers["Last-Modified"], "Thu, 13 Mar 2014 10:00:00 GMT"
- )
- self.assertEqual(
- sitemap_response.headers["Last-Modified"], "Thu, 13 Mar 2014 10:00:00 GMT"
- )
- expected_content_index = """<?xml version="1.0" encoding="UTF-8"?>
- <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- <sitemap><loc>http://example.com/simple/sitemap-callable-lastmod.xml</loc><lastmod>2014-03-13T10:00:00</lastmod></sitemap>
- </sitemapindex>
- """
- expected_content_sitemap = (
- '<?xml version="1.0" encoding="UTF-8"?>\n'
- '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
- 'xmlns:xhtml="http://www.w3.org/1999/xhtml">\n'
- "<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>\n"
- "</urlset>"
- )
- self.assertXMLEqual(index_response.content.decode(), expected_content_index)
- self.assertXMLEqual(sitemap_response.content.decode(), expected_content_sitemap)
- def test_callable_sitemod_no_items(self):
- index_response = self.client.get("/callable-lastmod-no-items/index.xml")
- self.assertNotIn("Last-Modified", index_response)
- expected_content_index = """<?xml version="1.0" encoding="UTF-8"?>
- <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- <sitemap><loc>http://example.com/simple/sitemap-callable-lastmod.xml</loc></sitemap>
- </sitemapindex>
- """
- self.assertXMLEqual(index_response.content.decode(), expected_content_index)
- # RemovedInDjango50Warning
- class DeprecatedTests(SitemapTestsBase):
- @override_settings(
- TEMPLATES=[
- {
- "BACKEND": "django.template.backends.django.DjangoTemplates",
- "DIRS": [os.path.join(os.path.dirname(__file__), "templates")],
- }
- ]
- )
- def test_simple_sitemap_custom_index_warning(self):
- msg = (
- "Calling `__str__` on SitemapIndexItem is deprecated, use the `location` "
- "attribute instead."
- )
- with self.assertRaisesMessage(RemovedInDjango50Warning, msg):
- self.client.get("/simple/custom-index.xml")
- @ignore_warnings(category=RemovedInDjango50Warning)
- @override_settings(
- TEMPLATES=[
- {
- "BACKEND": "django.template.backends.django.DjangoTemplates",
- "DIRS": [os.path.join(os.path.dirname(__file__), "templates")],
- }
- ]
- )
- def test_simple_sitemap_custom_index(self):
- "A simple sitemap index can be rendered with a custom template"
- response = self.client.get("/simple/custom-index.xml")
- expected_content = """<?xml version="1.0" encoding="UTF-8"?>
- <!-- This is a customised template -->
- <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- <sitemap><loc>%s/simple/sitemap-simple.xml</loc></sitemap>
- </sitemapindex>
- """ % (
- self.base_url
- )
- self.assertXMLEqual(response.content.decode(), expected_content)
|