2012-06-02 19:24:18 +00:00
|
|
|
import os
|
2010-08-27 15:16:04 +00:00
|
|
|
from datetime import date
|
2013-07-01 12:22:27 +00:00
|
|
|
from unittest import skipUnless
|
2012-06-02 19:24:18 +00:00
|
|
|
|
2010-08-27 15:16:04 +00:00
|
|
|
from django.conf import settings
|
2017-02-25 12:54:17 +00:00
|
|
|
from django.contrib.sitemaps import Sitemap
|
Fixed #14386, #8960, #10235, #10909, #10608, #13845, #14377 - standardize Site/RequestSite usage in various places.
Many thanks to gabrielhurley for putting most of this together. Also to
bmihelac, arthurk, qingfeng, hvendelbo, petr.pulc@s-cape.cz, Hraban for
reports and some initial patches.
The patch also contains some whitespace/PEP8 fixes.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@13980 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-04 14:20:47 +00:00
|
|
|
from django.contrib.sites.models import Site
|
2010-10-11 14:34:42 +00:00
|
|
|
from django.core.exceptions import ImproperlyConfigured
|
2015-08-17 17:45:07 +00:00
|
|
|
from django.test import modify_settings, override_settings
|
2010-08-27 15:16:04 +00:00
|
|
|
from django.utils.formats import localize
|
2010-10-09 14:36:18 +00:00
|
|
|
from django.utils.translation import activate, deactivate
|
2010-08-27 15:16:04 +00:00
|
|
|
|
2015-02-10 13:11:25 +00:00
|
|
|
from .base import SitemapTestsBase
|
|
|
|
from .models import TestModel
|
2010-08-27 15:16:04 +00:00
|
|
|
|
2012-06-02 19:24:18 +00:00
|
|
|
|
2012-01-29 19:24:32 +00:00
|
|
|
class HTTPSitemapTests(SitemapTestsBase):
|
2017-05-28 19:37:21 +00:00
|
|
|
use_sitemap_err_msg = (
|
|
|
|
'To use sitemaps, either enable the sites framework or pass a '
|
|
|
|
'Site/RequestSite object in your view.'
|
|
|
|
)
|
2010-12-12 22:56:29 +00:00
|
|
|
|
|
|
|
def test_simple_sitemap_index(self):
|
|
|
|
"A simple sitemap index can be rendered"
|
2014-12-21 20:19:05 +00:00
|
|
|
response = self.client.get('/simple/index.xml')
|
2012-08-14 18:12:38 +00:00
|
|
|
expected_content = """<?xml version="1.0" encoding="UTF-8"?>
|
2010-12-12 22:56:29 +00:00
|
|
|
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
2011-02-05 03:49:03 +00:00
|
|
|
<sitemap><loc>%s/simple/sitemap-simple.xml</loc></sitemap>
|
2010-12-12 22:56:29 +00:00
|
|
|
</sitemapindex>
|
2012-08-14 18:12:38 +00:00
|
|
|
""" % self.base_url
|
2017-02-07 17:05:47 +00:00
|
|
|
self.assertXMLEqual(response.content.decode(), expected_content)
|
2010-12-12 22:56:29 +00:00
|
|
|
|
2017-03-17 19:25:50 +00:00
|
|
|
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></sitemap>
|
|
|
|
</sitemapindex>
|
|
|
|
""" % self.base_url
|
|
|
|
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></sitemap><sitemap><loc>{0}/simple/sitemap-simple.xml?p=2</loc></sitemap>
|
|
|
|
</sitemapindex>
|
|
|
|
""".format(self.base_url)
|
|
|
|
self.assertXMLEqual(response.content.decode(), expected_content)
|
|
|
|
|
2014-12-17 21:51:42 +00:00
|
|
|
@override_settings(TEMPLATES=[{
|
|
|
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
2017-01-20 13:01:02 +00:00
|
|
|
'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')],
|
2014-12-17 21:51:42 +00:00
|
|
|
}])
|
2010-12-12 22:56:29 +00:00
|
|
|
def test_simple_sitemap_custom_index(self):
|
|
|
|
"A simple sitemap index can be rendered with a custom template"
|
2014-12-21 20:19:05 +00:00
|
|
|
response = self.client.get('/simple/custom-index.xml')
|
2012-08-14 18:12:38 +00:00
|
|
|
expected_content = """<?xml version="1.0" encoding="UTF-8"?>
|
2010-12-12 22:56:29 +00:00
|
|
|
<!-- This is a customised template -->
|
|
|
|
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
2011-02-05 03:49:03 +00:00
|
|
|
<sitemap><loc>%s/simple/sitemap-simple.xml</loc></sitemap>
|
2010-12-12 22:56:29 +00:00
|
|
|
</sitemapindex>
|
2012-08-14 18:12:38 +00:00
|
|
|
""" % self.base_url
|
2017-02-07 17:05:47 +00:00
|
|
|
self.assertXMLEqual(response.content.decode(), expected_content)
|
2012-08-14 18:12:38 +00:00
|
|
|
|
2012-01-29 19:24:32 +00:00
|
|
|
def test_simple_sitemap_section(self):
|
|
|
|
"A simple sitemap section can be rendered"
|
|
|
|
response = self.client.get('/simple/sitemap-simple.xml')
|
2012-08-14 18:12:38 +00:00
|
|
|
expected_content = """<?xml version="1.0" encoding="UTF-8"?>
|
2012-01-29 19:24:32 +00:00
|
|
|
<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>
|
2012-08-14 18:12:38 +00:00
|
|
|
""" % (self.base_url, date.today())
|
2017-02-07 17:05:47 +00:00
|
|
|
self.assertXMLEqual(response.content.decode(), expected_content)
|
2012-01-29 19:24:32 +00:00
|
|
|
|
2017-03-17 19:25:50 +00:00
|
|
|
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)
|
|
|
|
|
2010-08-27 15:16:04 +00:00
|
|
|
def test_simple_sitemap(self):
|
|
|
|
"A simple sitemap can be rendered"
|
2010-08-30 15:09:12 +00:00
|
|
|
response = self.client.get('/simple/sitemap.xml')
|
2012-08-14 18:12:38 +00:00
|
|
|
expected_content = """<?xml version="1.0" encoding="UTF-8"?>
|
2010-08-27 15:16:04 +00:00
|
|
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
2011-02-05 03:49:03 +00:00
|
|
|
<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
2010-12-12 22:56:29 +00:00
|
|
|
</urlset>
|
2012-08-14 18:12:38 +00:00
|
|
|
""" % (self.base_url, date.today())
|
2017-02-07 17:05:47 +00:00
|
|
|
self.assertXMLEqual(response.content.decode(), expected_content)
|
2010-12-12 22:56:29 +00:00
|
|
|
|
2014-12-17 21:51:42 +00:00
|
|
|
@override_settings(TEMPLATES=[{
|
|
|
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
2017-01-20 13:01:02 +00:00
|
|
|
'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')],
|
2014-12-17 21:51:42 +00:00
|
|
|
}])
|
2010-12-12 22:56:29 +00:00
|
|
|
def test_simple_custom_sitemap(self):
|
|
|
|
"A simple sitemap can be rendered with a custom template"
|
|
|
|
response = self.client.get('/simple/custom-sitemap.xml')
|
2012-08-14 18:12:38 +00:00
|
|
|
expected_content = """<?xml version="1.0" encoding="UTF-8"?>
|
2010-12-12 22:56:29 +00:00
|
|
|
<!-- This is a customised template -->
|
|
|
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
2011-02-05 03:49:03 +00:00
|
|
|
<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
2010-08-27 15:16:04 +00:00
|
|
|
</urlset>
|
2012-08-14 18:12:38 +00:00
|
|
|
""" % (self.base_url, date.today())
|
2017-02-07 17:05:47 +00:00
|
|
|
self.assertXMLEqual(response.content.decode(), expected_content)
|
2010-08-27 15:16:04 +00:00
|
|
|
|
2013-07-23 14:25:21 +00:00
|
|
|
def test_sitemap_last_modified(self):
|
2016-10-27 07:53:39 +00:00
|
|
|
"Last-Modified header is set correctly"
|
2013-07-23 14:25:21 +00:00
|
|
|
response = self.client.get('/lastmod/sitemap.xml')
|
|
|
|
self.assertEqual(response['Last-Modified'], 'Wed, 13 Mar 2013 10:00:00 GMT')
|
|
|
|
|
2014-09-09 17:34:40 +00:00
|
|
|
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['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['Last-Modified'], 'Wed, 13 Mar 2013 15:00:00 GMT')
|
|
|
|
|
2013-07-23 14:25:21 +00:00
|
|
|
def test_sitemap_last_modified_missing(self):
|
2016-10-27 07:53:39 +00:00
|
|
|
"Last-Modified header is missing when sitemap has no lastmod"
|
2013-07-23 14:25:21 +00:00
|
|
|
response = self.client.get('/generic/sitemap.xml')
|
|
|
|
self.assertFalse(response.has_header('Last-Modified'))
|
|
|
|
|
|
|
|
def test_sitemap_last_modified_mixed(self):
|
2016-10-27 07:53:39 +00:00
|
|
|
"Last-Modified header is omitted when lastmod not on all items"
|
2013-07-23 14:25:21 +00:00
|
|
|
response = self.client.get('/lastmod-mixed/sitemap.xml')
|
|
|
|
self.assertFalse(response.has_header('Last-Modified'))
|
|
|
|
|
2015-12-26 18:01:25 +00:00
|
|
|
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['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['Last-Modified'], 'Sat, 20 Apr 2013 05:00:00 GMT')
|
|
|
|
|
2010-12-05 02:07:46 +00:00
|
|
|
@skipUnless(settings.USE_I18N, "Internationalization is not enabled")
|
2012-06-02 19:24:18 +00:00
|
|
|
@override_settings(USE_L10N=True)
|
2010-08-27 15:16:04 +00:00
|
|
|
def test_localized_priority(self):
|
|
|
|
"The priority value should not be localized (Refs #14164)"
|
|
|
|
activate('fr')
|
2012-06-07 16:08:47 +00:00
|
|
|
self.assertEqual('0,3', localize(0.3))
|
2010-08-27 15:16:04 +00:00
|
|
|
|
2016-10-27 07:53:39 +00:00
|
|
|
# Priorities haven't been rendered in localized format.
|
2010-08-30 15:09:12 +00:00
|
|
|
response = self.client.get('/simple/sitemap.xml')
|
2010-08-27 15:16:04 +00:00
|
|
|
self.assertContains(response, '<priority>0.5</priority>')
|
2011-10-13 19:23:45 +00:00
|
|
|
self.assertContains(response, '<lastmod>%s</lastmod>' % date.today())
|
2010-10-09 14:36:18 +00:00
|
|
|
deactivate()
|
2010-08-30 15:09:12 +00:00
|
|
|
|
2013-12-23 09:37:34 +00:00
|
|
|
@modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
|
Fixed #14386, #8960, #10235, #10909, #10608, #13845, #14377 - standardize Site/RequestSite usage in various places.
Many thanks to gabrielhurley for putting most of this together. Also to
bmihelac, arthurk, qingfeng, hvendelbo, petr.pulc@s-cape.cz, Hraban for
reports and some initial patches.
The patch also contains some whitespace/PEP8 fixes.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@13980 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-04 14:20:47 +00:00
|
|
|
def test_requestsite_sitemap(self):
|
2016-10-27 07:53:39 +00:00
|
|
|
# Hitting the flatpages sitemap without the sites framework installed
|
|
|
|
# doesn't raise an exception.
|
2013-12-23 09:37:34 +00:00
|
|
|
response = self.client.get('/simple/sitemap.xml')
|
|
|
|
expected_content = """<?xml version="1.0" encoding="UTF-8"?>
|
Fixed #14386, #8960, #10235, #10909, #10608, #13845, #14377 - standardize Site/RequestSite usage in various places.
Many thanks to gabrielhurley for putting most of this together. Also to
bmihelac, arthurk, qingfeng, hvendelbo, petr.pulc@s-cape.cz, Hraban for
reports and some initial patches.
The patch also contains some whitespace/PEP8 fixes.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@13980 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-04 14:20:47 +00:00
|
|
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
|
|
<url><loc>http://testserver/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
|
|
|
</urlset>
|
2012-08-14 18:12:38 +00:00
|
|
|
""" % date.today()
|
2017-02-07 17:05:47 +00:00
|
|
|
self.assertXMLEqual(response.content.decode(), expected_content)
|
2010-10-11 14:34:42 +00:00
|
|
|
|
|
|
|
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()
|
2017-05-28 19:37:21 +00:00
|
|
|
with self.assertRaisesMessage(ImproperlyConfigured, self.use_sitemap_err_msg):
|
2016-01-17 11:26:39 +00:00
|
|
|
Sitemap().get_urls()
|
2010-10-11 14:34:42 +00:00
|
|
|
|
2013-12-23 09:37:34 +00:00
|
|
|
@modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
|
2010-10-11 14:34:42 +00:00
|
|
|
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.
|
|
|
|
"""
|
2017-05-28 19:37:21 +00:00
|
|
|
with self.assertRaisesMessage(ImproperlyConfigured, self.use_sitemap_err_msg):
|
2016-01-17 11:26:39 +00:00
|
|
|
Sitemap().get_urls()
|
2011-06-28 10:16:34 +00:00
|
|
|
|
|
|
|
def test_sitemap_item(self):
|
|
|
|
"""
|
|
|
|
Check to make sure that the raw item is included with each
|
|
|
|
Sitemap.get_url() url result.
|
|
|
|
"""
|
2017-02-25 12:54:17 +00:00
|
|
|
test_sitemap = Sitemap()
|
|
|
|
test_sitemap.items = TestModel.objects.order_by('pk').all
|
2013-10-22 10:21:07 +00:00
|
|
|
|
2013-03-23 01:57:48 +00:00
|
|
|
def is_testmodel(url):
|
|
|
|
return isinstance(url['item'], TestModel)
|
|
|
|
item_in_url_info = all(map(is_testmodel, test_sitemap.get_urls()))
|
2011-06-28 10:16:34 +00:00
|
|
|
self.assertTrue(item_in_url_info)
|
2012-01-29 09:30:28 +00:00
|
|
|
|
|
|
|
def test_cached_sitemap_index(self):
|
|
|
|
"""
|
2016-10-27 07:53:39 +00:00
|
|
|
A cached sitemap index can be rendered (#2713).
|
2012-01-29 09:30:28 +00:00
|
|
|
"""
|
|
|
|
response = self.client.get('/cached/index.xml')
|
2012-08-14 18:12:38 +00:00
|
|
|
expected_content = """<?xml version="1.0" encoding="UTF-8"?>
|
2012-01-29 09:30:28 +00:00
|
|
|
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
|
|
<sitemap><loc>%s/cached/sitemap-simple.xml</loc></sitemap>
|
|
|
|
</sitemapindex>
|
2012-08-14 18:12:38 +00:00
|
|
|
""" % self.base_url
|
2017-02-07 17:05:47 +00:00
|
|
|
self.assertXMLEqual(response.content.decode(), expected_content)
|
2013-05-04 10:08:15 +00:00
|
|
|
|
|
|
|
def test_x_robots_sitemap(self):
|
2014-12-21 20:19:05 +00:00
|
|
|
response = self.client.get('/simple/index.xml')
|
2013-05-04 10:08:15 +00:00
|
|
|
self.assertEqual(response['X-Robots-Tag'], 'noindex, noodp, noarchive')
|
|
|
|
|
|
|
|
response = self.client.get('/simple/sitemap.xml')
|
|
|
|
self.assertEqual(response['X-Robots-Tag'], 'noindex, noodp, noarchive')
|
2013-09-17 14:21:11 +00:00
|
|
|
|
|
|
|
def test_empty_sitemap(self):
|
|
|
|
response = self.client.get('/empty/sitemap.xml')
|
|
|
|
self.assertEqual(response.status_code, 200)
|
2014-06-06 18:47:15 +00:00
|
|
|
|
|
|
|
@override_settings(LANGUAGES=(('en', 'English'), ('pt', 'Portuguese')))
|
|
|
|
def test_simple_i18nsitemap_index(self):
|
|
|
|
"A simple i18n sitemap index can be rendered"
|
|
|
|
response = self.client.get('/simple/i18n.xml')
|
|
|
|
expected_content = """<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
2014-06-20 21:53:18 +00:00
|
|
|
<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>
|
2014-06-06 18:47:15 +00:00
|
|
|
</urlset>
|
2014-06-20 21:53:18 +00:00
|
|
|
""".format(self.base_url, self.i18n_model.pk)
|
2017-02-07 17:05:47 +00:00
|
|
|
self.assertXMLEqual(response.content.decode(), expected_content)
|
2016-01-24 19:35:46 +00:00
|
|
|
|
|
|
|
def test_sitemap_without_entries(self):
|
|
|
|
response = self.client.get('/sitemap-without-entries/sitemap.xml')
|
|
|
|
expected_content = """<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
|
|
|
|
|
|
</urlset>"""
|
2017-02-07 17:05:47 +00:00
|
|
|
self.assertXMLEqual(response.content.decode(), expected_content)
|