| 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) |