diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py index 8d779ca2bd..5721c8861d 100644 --- a/django/contrib/sitemaps/__init__.py +++ b/django/contrib/sitemaps/__init__.py @@ -21,6 +21,15 @@ def ping_google(sitemap_url=None, ping_url=PING_URL): for this site -- e.g., '/sitemap.xml'. If sitemap_url is not provided, this function will attempt to deduce it by using urls.reverse(). """ + sitemap_full_url = _get_sitemap_full_url(sitemap_url) + params = urlencode({'sitemap': sitemap_full_url}) + urlopen('%s?%s' % (ping_url, params)) + + +def _get_sitemap_full_url(sitemap_url): + if not django_apps.is_installed('django.contrib.sites'): + raise ImproperlyConfigured("ping_google requires django.contrib.sites, which isn't installed.") + if sitemap_url is None: try: # First, try to get the "index" sitemap URL. @@ -35,13 +44,9 @@ def ping_google(sitemap_url=None, ping_url=PING_URL): if sitemap_url is None: raise SitemapNotFound("You didn't provide a sitemap_url, and the sitemap URL couldn't be auto-detected.") - if not django_apps.is_installed('django.contrib.sites'): - raise ImproperlyConfigured("ping_google requires django.contrib.sites, which isn't installed.") Site = django_apps.get_model('sites.Site') current_site = Site.objects.get_current() - url = "http://%s%s" % (current_site.domain, sitemap_url) - params = urlencode({'sitemap': url}) - urlopen("%s?%s" % (ping_url, params)) + return 'http://%s%s' % (current_site.domain, sitemap_url) class Sitemap(object): diff --git a/tests/sitemaps_tests/test_management.py b/tests/sitemaps_tests/test_management.py new file mode 100644 index 0000000000..459a1d1b3c --- /dev/null +++ b/tests/sitemaps_tests/test_management.py @@ -0,0 +1,16 @@ +from django.core.management import call_command +from django.test import mock + +from .base import SitemapTestsBase + + +@mock.patch('django.contrib.sitemaps.management.commands.ping_google.ping_google') +class PingGoogleTests(SitemapTestsBase): + + def test_default(self, ping_google_func): + call_command('ping_google') + ping_google_func.assert_called_with(sitemap_url=None) + + def test_arg(self, ping_google_func): + call_command('ping_google', 'foo.xml') + ping_google_func.assert_called_with(sitemap_url='foo.xml') diff --git a/tests/sitemaps_tests/test_utils.py b/tests/sitemaps_tests/test_utils.py new file mode 100644 index 0000000000..ba1eadd5d1 --- /dev/null +++ b/tests/sitemaps_tests/test_utils.py @@ -0,0 +1,40 @@ +from django.contrib.sitemaps import ( + SitemapNotFound, _get_sitemap_full_url, ping_google, +) +from django.core.exceptions import ImproperlyConfigured +from django.test import mock, modify_settings, override_settings +from django.utils.six.moves.urllib.parse import urlencode + +from .base import SitemapTestsBase + + +class PingGoogleTests(SitemapTestsBase): + + @mock.patch('django.contrib.sitemaps.urlopen') + def test_something(self, urlopen): + ping_google() + params = urlencode({'sitemap': 'http://example.com/sitemap-without-entries/sitemap.xml'}) + full_url = 'https://www.google.com/webmasters/tools/ping?%s' % params + urlopen.assert_called_with(full_url) + + def test_get_sitemap_full_url_global(self): + self.assertEqual(_get_sitemap_full_url(None), 'http://example.com/sitemap-without-entries/sitemap.xml') + + @override_settings(ROOT_URLCONF='sitemaps_tests.urls.index_only') + def test_get_sitemap_full_url_index(self): + self.assertEqual(_get_sitemap_full_url(None), 'http://example.com/simple/index.xml') + + @override_settings(ROOT_URLCONF='sitemaps_tests.urls.empty') + def test_get_sitemap_full_url_not_detected(self): + msg = "You didn't provide a sitemap_url, and the sitemap URL couldn't be auto-detected." + with self.assertRaisesMessage(SitemapNotFound, msg): + _get_sitemap_full_url(None) + + def test_get_sitemap_full_url_exact_url(self): + self.assertEqual(_get_sitemap_full_url('/foo.xml'), 'http://example.com/foo.xml') + + @modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'}) + def test_get_sitemap_full_url_no_sites(self): + msg = "ping_google requires django.contrib.sites, which isn't installed." + with self.assertRaisesMessage(ImproperlyConfigured, msg): + _get_sitemap_full_url(None) diff --git a/tests/sitemaps_tests/urls/empty.py b/tests/sitemaps_tests/urls/empty.py new file mode 100644 index 0000000000..637600f58a --- /dev/null +++ b/tests/sitemaps_tests/urls/empty.py @@ -0,0 +1 @@ +urlpatterns = [] diff --git a/tests/sitemaps_tests/urls/index_only.py b/tests/sitemaps_tests/urls/index_only.py new file mode 100644 index 0000000000..7b9a093d87 --- /dev/null +++ b/tests/sitemaps_tests/urls/index_only.py @@ -0,0 +1,9 @@ +from django.conf.urls import url +from django.contrib.sitemaps import views + +from .http import simple_sitemaps + +urlpatterns = [ + url(r'^simple/index\.xml$', views.index, {'sitemaps': simple_sitemaps}, + name='django.contrib.sitemaps.views.index'), +]