1. import zipfile
    
  2. from io import BytesIO
    
  3. from xml.dom import minidom
    
  4. 
    
  5. from django.conf import settings
    
  6. from django.contrib.sites.models import Site
    
  7. from django.test import TestCase, modify_settings, override_settings
    
  8. 
    
  9. from .models import City, Country
    
  10. 
    
  11. 
    
  12. @modify_settings(
    
  13.     INSTALLED_APPS={"append": ["django.contrib.sites", "django.contrib.sitemaps"]}
    
  14. )
    
  15. @override_settings(ROOT_URLCONF="gis_tests.geoapp.urls")
    
  16. class GeoSitemapTest(TestCase):
    
  17.     @classmethod
    
  18.     def setUpTestData(cls):
    
  19.         Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
    
  20. 
    
  21.     def assertChildNodes(self, elem, expected):
    
  22.         "Taken from syndication/tests.py."
    
  23.         actual = {n.nodeName for n in elem.childNodes}
    
  24.         expected = set(expected)
    
  25.         self.assertEqual(actual, expected)
    
  26. 
    
  27.     def test_geositemap_kml(self):
    
  28.         "Tests KML/KMZ geographic sitemaps."
    
  29.         for kml_type in ("kml", "kmz"):
    
  30.             doc = minidom.parseString(
    
  31.                 self.client.get("/sitemaps/%s.xml" % kml_type).content
    
  32.             )
    
  33. 
    
  34.             # Ensuring the right sitemaps namespace is present.
    
  35.             urlset = doc.firstChild
    
  36.             self.assertEqual(
    
  37.                 urlset.getAttribute("xmlns"),
    
  38.                 "http://www.sitemaps.org/schemas/sitemap/0.9",
    
  39.             )
    
  40. 
    
  41.             urls = urlset.getElementsByTagName("url")
    
  42.             self.assertEqual(2, len(urls))  # Should only be 2 sitemaps.
    
  43.             for url in urls:
    
  44.                 self.assertChildNodes(url, ["loc"])
    
  45. 
    
  46.                 # Getting the relative URL since we don't have a real site.
    
  47.                 kml_url = (
    
  48.                     url.getElementsByTagName("loc")[0]
    
  49.                     .childNodes[0]
    
  50.                     .data.split("http://example.com")[1]
    
  51.                 )
    
  52. 
    
  53.                 if kml_type == "kml":
    
  54.                     kml_doc = minidom.parseString(self.client.get(kml_url).content)
    
  55.                 elif kml_type == "kmz":
    
  56.                     # Have to decompress KMZ before parsing.
    
  57.                     buf = BytesIO(self.client.get(kml_url).content)
    
  58.                     with zipfile.ZipFile(buf) as zf:
    
  59.                         self.assertEqual(1, len(zf.filelist))
    
  60.                         self.assertEqual("doc.kml", zf.filelist[0].filename)
    
  61.                         kml_doc = minidom.parseString(zf.read("doc.kml"))
    
  62. 
    
  63.                 # Ensuring the correct number of placemarks are in the KML doc.
    
  64.                 if "city" in kml_url:
    
  65.                     model = City
    
  66.                 elif "country" in kml_url:
    
  67.                     model = Country
    
  68.                 self.assertEqual(
    
  69.                     model.objects.count(),
    
  70.                     len(kml_doc.getElementsByTagName("Placemark")),
    
  71.                 )