test_sitemaps.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from __future__ import unicode_literals
  2. from io import BytesIO
  3. from unittest import skipUnless
  4. from xml.dom import minidom
  5. import os
  6. import zipfile
  7. from django.conf import settings
  8. from django.contrib.gis.geos import HAS_GEOS
  9. from django.contrib.gis.tests.utils import HAS_SPATIAL_DB
  10. from django.contrib.sites.models import Site
  11. from django.test import TestCase, modify_settings
  12. from django.test.utils import IgnoreDeprecationWarningsMixin
  13. from django.utils._os import upath
  14. if HAS_GEOS:
  15. from .models import City, Country
  16. @modify_settings(INSTALLED_APPS={'append': 'django.contrib.sites'})
  17. @skipUnless(HAS_GEOS and HAS_SPATIAL_DB, "Geos and spatial db are required.")
  18. class GeoSitemapTest(IgnoreDeprecationWarningsMixin, TestCase):
  19. urls = 'django.contrib.gis.tests.geoapp.urls'
  20. def setUp(self):
  21. super(GeoSitemapTest, self).setUp()
  22. Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
  23. def assertChildNodes(self, elem, expected):
  24. "Taken from syndication/tests.py."
  25. actual = set(n.nodeName for n in elem.childNodes)
  26. expected = set(expected)
  27. self.assertEqual(actual, expected)
  28. def test_geositemap_index(self):
  29. "Tests geographic sitemap index."
  30. # Getting the geo index.
  31. from django.contrib import sitemaps
  32. template_dirs = settings.TEMPLATE_DIRS + (
  33. os.path.join(os.path.dirname(upath(sitemaps.__file__)), 'templates'),)
  34. with self.settings(TEMPLATE_DIRS=template_dirs):
  35. doc = minidom.parseString(self.client.get('/sitemap.xml').content)
  36. index = doc.firstChild
  37. self.assertEqual(index.getAttribute('xmlns'), 'http://www.sitemaps.org/schemas/sitemap/0.9')
  38. self.assertEqual(3, len(index.getElementsByTagName('sitemap')))
  39. def test_geositemap_kml(self):
  40. "Tests KML/KMZ geographic sitemaps."
  41. for kml_type in ('kml', 'kmz'):
  42. doc = minidom.parseString(self.client.get('/sitemaps/%s.xml' % kml_type).content)
  43. # Ensuring the right sitemaps namespaces are present.
  44. urlset = doc.firstChild
  45. self.assertEqual(urlset.getAttribute('xmlns'), 'http://www.sitemaps.org/schemas/sitemap/0.9')
  46. self.assertEqual(urlset.getAttribute('xmlns:geo'), 'http://www.google.com/geo/schemas/sitemap/1.0')
  47. urls = urlset.getElementsByTagName('url')
  48. self.assertEqual(2, len(urls)) # Should only be 2 sitemaps.
  49. for url in urls:
  50. self.assertChildNodes(url, ['loc', 'geo:geo'])
  51. # Making sure the 'geo:format' element was properly set.
  52. geo_elem = url.getElementsByTagName('geo:geo')[0]
  53. geo_format = geo_elem.getElementsByTagName('geo:format')[0]
  54. self.assertEqual(kml_type, geo_format.childNodes[0].data)
  55. # Getting the relative URL since we don't have a real site.
  56. kml_url = url.getElementsByTagName('loc')[0].childNodes[0].data.split('http://example.com')[1]
  57. if kml_type == 'kml':
  58. kml_doc = minidom.parseString(self.client.get(kml_url).content)
  59. elif kml_type == 'kmz':
  60. # Have to decompress KMZ before parsing.
  61. buf = BytesIO(self.client.get(kml_url).content)
  62. zf = zipfile.ZipFile(buf)
  63. self.assertEqual(1, len(zf.filelist))
  64. self.assertEqual('doc.kml', zf.filelist[0].filename)
  65. kml_doc = minidom.parseString(zf.read('doc.kml'))
  66. # Ensuring the correct number of placemarks are in the KML doc.
  67. if 'city' in kml_url:
  68. model = City
  69. elif 'country' in kml_url:
  70. model = Country
  71. self.assertEqual(model.objects.count(), len(kml_doc.getElementsByTagName('Placemark')))
  72. def test_geositemap_georss(self):
  73. "Tests GeoRSS geographic sitemaps."
  74. from .feeds import feed_dict
  75. doc = minidom.parseString(self.client.get('/sitemaps/georss.xml').content)
  76. # Ensuring the right sitemaps namespaces are present.
  77. urlset = doc.firstChild
  78. self.assertEqual(urlset.getAttribute('xmlns'), 'http://www.sitemaps.org/schemas/sitemap/0.9')
  79. self.assertEqual(urlset.getAttribute('xmlns:geo'), 'http://www.google.com/geo/schemas/sitemap/1.0')
  80. # Making sure the correct number of feed URLs were included.
  81. urls = urlset.getElementsByTagName('url')
  82. self.assertEqual(len(feed_dict), len(urls))
  83. for url in urls:
  84. self.assertChildNodes(url, ['loc', 'geo:geo'])
  85. # Making sure the 'geo:format' element was properly set to 'georss'.
  86. geo_elem = url.getElementsByTagName('geo:geo')[0]
  87. geo_format = geo_elem.getElementsByTagName('geo:format')[0]
  88. self.assertEqual('georss', geo_format.childNodes[0].data)