app/django/contrib/gis/tests/test_geoip.py
author Sverre Rabbelier <srabbelier@gmail.com>
Mon, 13 Apr 2009 15:31:39 +0000
changeset 2177 e2c193e1f631
parent 323 ff1a9aa48cfd
permissions -rw-r--r--
Do not rely on dicts.merge to change target Also make dicts.merge actually not touch target. This is much cleaner than modifying in place, especially since we assign the result of the dicts.merge call to target most of the time anyway. Patch by: Sverre Rabbelier

import os, unittest
from django.db import settings
from django.contrib.gis.geos import GEOSGeometry
from django.contrib.gis.utils import GeoIP, GeoIPException

# Note: Requires use of both the GeoIP country and city datasets.
# The GEOIP_DATA path should be the only setting set (the directory
# should contain links or the actual database files 'GeoIP.dat' and 
# 'GeoLiteCity.dat'.
class GeoIPTest(unittest.TestCase):
    
    def test01_init(self):
        "Testing GeoIP initialization."
        g1 = GeoIP() # Everything inferred from GeoIP path
        path = settings.GEOIP_PATH
        g2 = GeoIP(path, 0) # Passing in data path explicitly.
        g3 = GeoIP.open(path, 0) # MaxMind Python API syntax.

        for g in (g1, g2, g3):
            self.assertEqual(True, bool(g._country))
            self.assertEqual(True, bool(g._city))
        
        # Only passing in the location of one database.
        city = os.path.join(path, 'GeoLiteCity.dat')
        cntry = os.path.join(path, 'GeoIP.dat')
        g4 = GeoIP(city, country='')
        self.assertEqual(None, g4._country)
        g5 = GeoIP(cntry, city='')
        self.assertEqual(None, g5._city)

        # Improper parameters.
        bad_params = (23, 'foo', 15.23)
        for bad in bad_params:
            self.assertRaises(GeoIPException, GeoIP, cache=bad)
            if isinstance(bad, basestring):
                e = GeoIPException
            else:
                e = TypeError
            self.assertRaises(e, GeoIP, bad, 0)

    def test02_bad_query(self):
        "Testing GeoIP query parameter checking."
        cntry_g = GeoIP(city='<foo>')
        # No city database available, these calls should fail.
        self.assertRaises(GeoIPException, cntry_g.city, 'google.com')
        self.assertRaises(GeoIPException, cntry_g.coords, 'yahoo.com')

        # Non-string query should raise TypeError
        self.assertRaises(TypeError, cntry_g.country_code, 17)
        self.assertRaises(TypeError, cntry_g.country_name, GeoIP)

    def test03_country(self):
        "Testing GeoIP country querying methods."
        g = GeoIP(city='<foo>')
        
        fqdn = 'www.google.com'
        addr = '12.215.42.19'
        
        for query in (fqdn, addr):
            for func in (g.country_code, g.country_code_by_addr, g.country_code_by_name):
                self.assertEqual('US', func(query))
            for func in (g.country_name, g.country_name_by_addr, g.country_name_by_name):
                self.assertEqual('United States', func(query))
            self.assertEqual({'country_code' : 'US', 'country_name' : 'United States'},
                             g.country(query))

    def test04_city(self):
        "Testing GeoIP city querying methods."
        g = GeoIP(country='<foo>')
        
        addr = '130.80.29.3'
        fqdn = 'chron.com'
        for query in (fqdn, addr):
            # Country queries should still work.
            for func in (g.country_code, g.country_code_by_addr, g.country_code_by_name):
                self.assertEqual('US', func(query))
            for func in (g.country_name, g.country_name_by_addr, g.country_name_by_name):
                self.assertEqual('United States', func(query))
            self.assertEqual({'country_code' : 'US', 'country_name' : 'United States'},
                             g.country(query))
            
            # City information dictionary.
            d = g.city(query)
            self.assertEqual('USA', d['country_code3'])
            self.assertEqual('Houston', d['city'])
            self.assertEqual('TX', d['region'])
            self.assertEqual('77002', d['postal_code'])
            self.assertEqual(713, d['area_code'])
            geom = g.geos(query)
            self.failIf(not isinstance(geom, GEOSGeometry))
            lon, lat = (-95.366996765, 29.752300262)
            lat_lon = g.lat_lon(query)
            lat_lon = (lat_lon[1], lat_lon[0])
            for tup in (geom.tuple, g.coords(query), g.lon_lat(query), lat_lon):
                self.assertAlmostEqual(lon, tup[0], 9)
                self.assertAlmostEqual(lat, tup[1], 9)

def suite():
    s = unittest.TestSuite()
    s.addTest(unittest.makeSuite(GeoIPTest))
    return s

def run(verbosity=2):
    unittest.TextTestRunner(verbosity=verbosity).run(suite())