| | 1 | import os |
| | 2 | from datetime import date |
| | 3 | from django.conf import settings |
| | 4 | from django.contrib.auth.models import User |
| | 5 | from django.contrib.sitemaps import Sitemap, GenericSitemap |
| | 6 | from django.contrib.sites.models import Site |
| | 7 | from django.core.exceptions import ImproperlyConfigured |
| | 8 | from django.test import TestCase |
| | 9 | from django.utils.unittest import skipUnless |
| | 10 | from django.utils.formats import localize |
| | 11 | from django.utils.translation import activate, deactivate |
| | 12 | |
| | 13 | |
| | 14 | class HTTPSSitemapTests(TestCase): |
| | 15 | urls = 'django.contrib.sitemaps.tests.urls_https' |
| | 16 | |
| | 17 | def setUp(self): |
| | 18 | if Site._meta.installed: |
| | 19 | self.base_url = 'https://example.com' |
| | 20 | else: |
| | 21 | self.base_url = 'https://testserver' |
| | 22 | self.old_USE_L10N = settings.USE_L10N |
| | 23 | self.old_Site_meta_installed = Site._meta.installed |
| | 24 | self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS |
| | 25 | self.old_Site_meta_installed = Site._meta.installed |
| | 26 | settings.TEMPLATE_DIRS = ( |
| | 27 | os.path.join(os.path.dirname(__file__), 'templates'), |
| | 28 | ) |
| | 29 | # Create a user that will double as sitemap content |
| | 30 | User.objects.create_user('testuser', 'test@example.com', 's3krit') |
| | 31 | |
| | 32 | def tearDown(self): |
| | 33 | settings.USE_L10N = self.old_USE_L10N |
| | 34 | Site._meta.installed = self.old_Site_meta_installed |
| | 35 | settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS |
| | 36 | Site._meta.installed = self.old_Site_meta_installed |
| | 37 | |
| | 38 | def test_simple_sitemap_index(self): |
| | 39 | "A simple sitemap index can be rendered" |
| | 40 | # Retrieve the sitemap. |
| | 41 | response = self.client.get('/simple/index.xml') |
| | 42 | # Check for all the important bits: |
| | 43 | self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?> |
| | 44 | <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> |
| | 45 | <sitemap><loc>%s/simple/sitemap-simple.xml</loc></sitemap> |
| | 46 | </sitemapindex> |
| | 47 | """ % self.base_url) |
| | 48 | |
| | 49 | def test_simple_sitemap_custom_index(self): |
| | 50 | "A simple sitemap index can be rendered with a custom template" |
| | 51 | # Retrieve the sitemap. |
| | 52 | response = self.client.get('/simple/custom-index.xml') |
| | 53 | # Check for all the important bits: |
| | 54 | self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?> |
| | 55 | <!-- This is a customised template --> |
| | 56 | <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> |
| | 57 | <sitemap><loc>%s/simple/sitemap-simple.xml</loc></sitemap> |
| | 58 | </sitemapindex> |
| | 59 | """ % self.base_url) |
| | 60 | |
| | 61 | def test_simple_sitemap(self): |
| | 62 | "A simple sitemap can be rendered" |
| | 63 | # Retrieve the sitemap. |
| | 64 | response = self.client.get('/simple/sitemap.xml') |
| | 65 | # Check for all the important bits: |
| | 66 | self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?> |
| | 67 | <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> |
| | 68 | <url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url> |
| | 69 | </urlset> |
| | 70 | """ % (self.base_url, date.today().strftime('%Y-%m-%d'))) |
| | 71 | |
| | 72 | def test_simple_custom_sitemap(self): |
| | 73 | "A simple sitemap can be rendered with a custom template" |
| | 74 | # Retrieve the sitemap. |
| | 75 | response = self.client.get('/simple/custom-sitemap.xml') |
| | 76 | # Check for all the important bits: |
| | 77 | self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?> |
| | 78 | <!-- This is a customised template --> |
| | 79 | <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> |
| | 80 | <url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url> |
| | 81 | </urlset> |
| | 82 | """ % (self.base_url, date.today().strftime('%Y-%m-%d'))) |
| | 83 | |
| | 84 | @skipUnless(settings.USE_I18N, "Internationalization is not enabled") |
| | 85 | def test_localized_priority(self): |
| | 86 | "The priority value should not be localized (Refs #14164)" |
| | 87 | # Localization should be active |
| | 88 | settings.USE_L10N = True |
| | 89 | activate('fr') |
| | 90 | self.assertEqual(u'0,3', localize(0.3)) |
| | 91 | |
| | 92 | # Retrieve the sitemap. Check that priorities |
| | 93 | # haven't been rendered in localized format |
| | 94 | response = self.client.get('/simple/sitemap.xml') |
| | 95 | self.assertContains(response, '<priority>0.5</priority>') |
| | 96 | self.assertContains(response, '<lastmod>%s</lastmod>' % date.today().strftime('%Y-%m-%d')) |
| | 97 | deactivate() |
| | 98 | |
| | 99 | def test_generic_sitemap(self): |
| | 100 | "A minimal generic sitemap can be rendered" |
| | 101 | # Retrieve the sitemap. |
| | 102 | response = self.client.get('/generic/sitemap.xml') |
| | 103 | |
| | 104 | expected = '' |
| | 105 | for username in User.objects.values_list("username", flat=True): |
| | 106 | expected += "<url><loc>%s/users/%s/</loc></url>" % (self.base_url, username) |
| | 107 | # Check for all the important bits: |
| | 108 | self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?> |
| | 109 | <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> |
| | 110 | %s |
| | 111 | </urlset> |
| | 112 | """ % expected) |
| | 113 | |
| | 114 | @skipUnless("django.contrib.flatpages" in settings.INSTALLED_APPS, "django.contrib.flatpages app not installed.") |
| | 115 | def test_flatpage_sitemap(self): |
| | 116 | "Basic FlatPage sitemap test" |
| | 117 | |
| | 118 | # Import FlatPage inside the test so that when django.contrib.flatpages |
| | 119 | # is not installed we don't get problems trying to delete Site |
| | 120 | # objects (FlatPage has an M2M to Site, Site.delete() tries to |
| | 121 | # delete related objects, but the M2M table doesn't exist. |
| | 122 | from django.contrib.flatpages.models import FlatPage |
| | 123 | |
| | 124 | public = FlatPage.objects.create( |
| | 125 | url=u'/public/', |
| | 126 | title=u'Public Page', |
| | 127 | enable_comments=True, |
| | 128 | registration_required=False, |
| | 129 | ) |
| | 130 | public.sites.add(settings.SITE_ID) |
| | 131 | private = FlatPage.objects.create( |
| | 132 | url=u'/private/', |
| | 133 | title=u'Private Page', |
| | 134 | enable_comments=True, |
| | 135 | registration_required=True |
| | 136 | ) |
| | 137 | private.sites.add(settings.SITE_ID) |
| | 138 | response = self.client.get('/flatpages/sitemap.xml') |
| | 139 | # Public flatpage should be in the sitemap |
| | 140 | self.assertContains(response, '<loc>%s%s</loc>' % (self.base_url, public.url)) |
| | 141 | # Private flatpage should not be in the sitemap |
| | 142 | self.assertNotContains(response, '<loc>%s%s</loc>' % (self.base_url, private.url)) |
| | 143 | |
| | 144 | def test_requestsite_sitemap(self): |
| | 145 | # Make sure hitting the flatpages sitemap without the sites framework |
| | 146 | # installed doesn't raise an exception |
| | 147 | Site._meta.installed = False |
| | 148 | # Retrieve the sitemap. |
| | 149 | response = self.client.get('/simple/sitemap.xml') |
| | 150 | # Check for all the important bits: |
| | 151 | self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?> |
| | 152 | <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> |
| | 153 | <url><loc>https://testserver/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url> |
| | 154 | </urlset> |
| | 155 | """ % date.today().strftime('%Y-%m-%d')) |
| | 156 | |
| | 157 | @skipUnless("django.contrib.sites" in settings.INSTALLED_APPS, "django.contrib.sites app not installed.") |
| | 158 | def test_sitemap_get_urls_no_site_1(self): |
| | 159 | """ |
| | 160 | Check we get ImproperlyConfigured if we don't pass a site object to |
| | 161 | Sitemap.get_urls and no Site objects exist |
| | 162 | """ |
| | 163 | Site.objects.all().delete() |
| | 164 | self.assertRaises(ImproperlyConfigured, Sitemap().get_urls) |
| | 165 | |
| | 166 | def test_sitemap_get_urls_no_site_2(self): |
| | 167 | """ |
| | 168 | Check we get ImproperlyConfigured when we don't pass a site object to |
| | 169 | Sitemap.get_urls if Site objects exists, but the sites framework is not |
| | 170 | actually installed. |
| | 171 | """ |
| | 172 | Site._meta.installed = False |
| | 173 | self.assertRaises(ImproperlyConfigured, Sitemap().get_urls) |
| | 174 | |
| | 175 | def test_sitemap_item(self): |
| | 176 | """ |
| | 177 | Check to make sure that the raw item is included with each |
| | 178 | Sitemap.get_url() url result. |
| | 179 | """ |
| | 180 | user_sitemap = GenericSitemap({'queryset': User.objects.all()}) |
| | 181 | def is_user(url): |
| | 182 | return isinstance(url['item'], User) |
| | 183 | item_in_url_info = all(map(is_user, user_sitemap.get_urls())) |
| | 184 | self.assertTrue(item_in_url_info) |