def test_search_by_my_ip_nonascii(self): rec1 = Feature((D('11.03'), D('10.04')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={'name': "Bob's House Of Monkeys", 'category': "monkey dealership"}) rec2 = Feature((D('11.03'), D('10.05')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={'name': "Monkey Food 'R' Us", 'category': "pet food store"}) mockhttp = mock.Mock() mockhttp.request.return_value = ({'status': '200', 'content-type': 'application/json', }, json.dumps({'type': "FeatureColllection", 'features': [rec1.to_dict(), rec2.to_dict()]})) self.client.places.http = mockhttp ipaddr = '192.0.32.10' self.failUnlessRaises(AssertionError, self.client.places.search_by_my_ip, ipaddr) # Someone accidentally passed an ip addr to search_by_my_ip(). res = self.client.places.search_by_my_ip(query='monk❥y', category='animal') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[-1][0], 'request') urlused = mockhttp.method_calls[-1][1][0] urlused = urllib.unquote(urlused).decode('utf-8') self.assertEqual(urlused, u'http://api.simplegeo.com:80/%s/places/ip.json?q=monk❥y&category=animal' % (API_VERSION,)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET') res = self.client.places.search_by_my_ip(query='monk❥y', category='anim❥l') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[-1][0], 'request') urlused = mockhttp.method_calls[-1][1][0] urlused = urllib.unquote(urlused).decode('utf-8') self.assertEqual(urlused, u'http://api.simplegeo.com:80/%s/places/ip.json?q=monk❥y&category=anim❥l' % (API_VERSION,)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET')
def test_search_by_address_nonascii(self): rec1 = Feature((D('11.03'), D('10.04')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={'name': "Bob's House Of Monkeys", 'category': "monkey dealership"}) rec2 = Feature((D('11.03'), D('10.05')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={'name': "Monkey Food 'R' Us", 'category': "pet food store"}) mockhttp = mock.Mock() mockhttp.request.return_value = ({'status': '200', 'content-type': 'application/json', }, json.dumps({'type': "FeatureColllection", 'features': [rec1.to_dict(), rec2.to_dict()]})) self.client.places.http = mockhttp lat = D('11.03') lon = D('10.04') self.failUnlessRaises(AssertionError, self.client.places.search_by_address, lat, lon) # Someone accidentally passed a lat,lon to search_by_address(). addr = u'41 Decatur St, San Francisc❦, CA' res = self.client.places.search_by_address(addr, query='monkeys', category='animal') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[-1][0], 'request') urlused = mockhttp.method_calls[-1][1][0] cod = urllib.quote_plus(addr.encode('utf-8')) self.assertEqual(urlused, 'http://api.simplegeo.com:80/%s/places/address.json?q=monkeys&category=animal&address=%s' % (API_VERSION, cod,)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET') res = self.client.places.search_by_address(addr, query=u'monke❦s', category=u'ani❦al') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[-1][0], 'request') urlused = mockhttp.method_calls[-1][1][0] quargs = {'q': u'monke❦s', 'category': u'ani❦al', 'address': addr} equargs = dict( (k, v.encode('utf-8')) for k, v in quargs.iteritems() ) s2quargs = urllib.urlencode(equargs) self.assertEqual(urlused, 'http://api.simplegeo.com:80/%s/places/address.json?%s' % (API_VERSION, s2quargs)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET')
def test_geojson_is_correct(self): f = Feature(coordinates=[-90, D('171.0')], properties={'record_id': 'my_id'}, strict_lon_validation=True) stringy = f.to_json() self.failUnlessEqual( stringy, '{"geometry": {"type": "Point", "coordinates": [171.0, -90]}, "type": "Feature", "id": null, "properties": {"record_id": "my_id", "private": false}}' )
def test_get_feature(self): handle = 'SG_abcdefghijklmnopqrstuv' resultfeature = Feature((D('11.03'), D('10.03')), simplegeohandle=handle) mockhttp = mock.Mock() mockhttp.request.return_value = ({'status': '200', 'content-type': 'application/json', }, resultfeature.to_json()) self.client.places.http = mockhttp res = self.client.places.get_feature(handle) self.assertEqual(mockhttp.method_calls[0][0], 'request') self.assertEqual(mockhttp.method_calls[0][1][0], 'http://api.simplegeo.com:80/%s/features/%s.json' % (API_VERSION, handle)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET') self.failUnless(isinstance(res, Feature), res) self.assertEqual(res.to_json(), resultfeature.to_json())
def test_no_terms_search_by_ip(self): rec1 = Feature((D('11.03'), D('10.04')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={'name': "Bob's House Of Monkeys", 'category': "monkey dealership"}) rec2 = Feature((D('11.03'), D('10.05')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={'name': "Monkey Food 'R' Us", 'category': "pet food store"}) mockhttp = mock.Mock() mockhttp.request.return_value = ({'status': '200', 'content-type': 'application/json', }, json.dumps({'type': "FeatureColllection", 'features': [rec1.to_dict(), rec2.to_dict()]})) self.client.places.http = mockhttp ipaddr = '192.0.32.10' res = self.client.places.search_by_ip(ipaddr) self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[0][0], 'request') self.assertEqual(mockhttp.method_calls[0][1][0], 'http://api.simplegeo.com:80/%s/places/%s.json' % (API_VERSION, ipaddr)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET')
def search(self, lat, lon, radius=None, query=None, category=None): """Search for places near a lat/lon, within a radius (in kilometers).""" precondition(is_valid_lat(lat), lat) precondition(is_valid_lon(lon), lon) precondition(radius is None or is_numeric(radius), radius) precondition(query is None or isinstance(query, basestring), query) precondition(category is None or isinstance(category, basestring), category) if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = {} if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category endpoint = self._endpoint('search', lat=lat, lon=lon) result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def search_by_ip(self, ipaddr, radius=None, query=None, category=None): """ Search for places near an IP address, within a radius (in kilometers). The server uses guesses the latitude and longitude from the ipaddr and then does the same thing as search(), using that guessed latitude and longitude. """ precondition(is_valid_ip(ipaddr), ipaddr) precondition(radius is None or is_numeric(radius), radius) precondition(query is None or isinstance(query, basestring), query) precondition(category is None or isinstance(category, basestring), category) if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = {} if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category endpoint = self._endpoint('search_by_ip', ipaddr=ipaddr) result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def search_by_my_ip(self, radius=None, query=None, category=None): """ Search for places near your IP address, within a radius (in kilometers). The server gets the IP address from the HTTP connection (this may be the IP address of your device or of a firewall, NAT, or HTTP proxy device between you and the server), and then does the same thing as search_by_ip(), using that IP address. """ precondition(radius is None or is_numeric(radius), radius) precondition(query is None or isinstance(query, basestring), query) precondition(category is None or isinstance(category, basestring), category) if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = {} if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category endpoint = self._endpoint('search_by_my_ip') result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def search_by_my_ip(self, radius=None, query=None, category=None): """ Search for places near your IP address, within a radius (in kilometers). The server gets the IP address from the HTTP connection (this may be the IP address of your device or of a firewall, NAT, or HTTP proxy device between you and the server), and then does the same thing as search_by_ip(), using that IP address. """ precondition(radius is None or is_numeric(radius), radius) precondition(query is None or isinstance(query, basestring), query) precondition(category is None or isinstance(category, basestring), category) if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = { } if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category endpoint = self._endpoint('search_by_my_ip') result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def search_by_ip(self, ipaddr, radius=None, query=None, category=None): """ Search for places near an IP address, within a radius (in kilometers). The server uses guesses the latitude and longitude from the ipaddr and then does the same thing as search(), using that guessed latitude and longitude. """ precondition(is_valid_ip(ipaddr), ipaddr) precondition(radius is None or is_numeric(radius), radius) precondition(query is None or isinstance(query, basestring), query) precondition(category is None or isinstance(category, basestring), category) if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = { } if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category endpoint = self._endpoint('search_by_ip', ipaddr=ipaddr) result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def search(self, lat, lon, radius=None, query=None, category=None): """Search for places near a lat/lon, within a radius (in kilometers).""" precondition(is_valid_lat(lat), lat) precondition(is_valid_lon(lon), lon) precondition(radius is None or is_numeric(radius), radius) precondition(query is None or isinstance(query, basestring), query) precondition(category is None or isinstance(category, basestring), category) if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = { } if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category endpoint = self._endpoint('search', lat=lat, lon=lon) result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def search(self, lat, lon, radius=None, query=None, category=None, num=None): """Search for places near a lat/lon, within a radius (in kilometers).""" _assert_valid_lat(lat) _assert_valid_lon(lon) if (radius and not is_numeric(radius)): raise ValueError("Radius must be numeric.") if (query and not isinstance(query, basestring)): raise ValueError("Query must be a string.") if (category and not isinstance(category, basestring)): raise ValueError("Category must be a string.") if (num and not is_numeric(num)): raise ValueError("Num parameter must be numeric.") if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = { } if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category if num: kwargs['num'] = num endpoint = self._endpoint('search', lat=lat, lon=lon) result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def test_update_feature(self): handle = 'SG_abcdefghijklmnopqrstuv' rec = Feature((D('11.03'), D('10.04')), simplegeohandle=handle) mockhttp = mock.Mock() mockhttp.request.return_value = ({ 'status': '200', 'content-type': 'application/json', }, { 'token': "this is your polling token" }) self.client.places.http = mockhttp res = self.client.places.update_feature(rec) self.failUnless(isinstance(res, dict), res) self.failUnless(res.has_key('token'), res) self.assertEqual(mockhttp.method_calls[0][0], 'request') self.assertEqual( mockhttp.method_calls[0][1][0], 'http://api.simplegeo.com:80/%s/features/%s.json' % (API_VERSION, handle)) self.assertEqual(mockhttp.method_calls[0][1][1], 'POST') bodyjson = mockhttp.method_calls[0][2]['body'] self.failUnless(isinstance(bodyjson, basestring), (repr(bodyjson), type(bodyjson))) # If it decoded as valid json then check for some expected fields bodyobj = json.loads(bodyjson) self.failUnless( bodyobj.get('geometry').has_key('coordinates'), bodyobj) self.failUnless(bodyobj.get('geometry').has_key('type'), bodyobj) self.failUnlessEqual(bodyobj.get('geometry')['type'], 'Point')
def _record(self): self.record_id += 1 self.record_lat = (self.record_lat + 10) % 90 self.record_lon = (self.record_lon + 10) % 180 return Feature(layer=TESTING_LAYER, id=str(self.record_id), coordinates=(self.record_lat, self.record_lon))
def test_record_constructor_useful_validation_error_message(self): try: Feature(coordinates=[181, D('10.0')], properties={'record_id': 'my_id'}) except TypeError, e: self.failUnless(str(e).startswith('The first argument'), str(e)) self.failUnless('is required to be a 2-element sequence' in str(e), str(e))
def test_add_feature_simplegeohandle(self): handle = 'SG_abcdefghijklmnopqrstuv' feature = Feature(simplegeohandle=handle, coordinates=(D('37.8016'), D('-122.4783'))) # You can't add-feature on a feature that already has a simplegeo handle. Don't do that. self.failUnlessRaises(ValueError, self.client.places.add_feature, feature)
def test_add_feature_simplegeohandle_and_record_id(self): handle = 'SG_abcdefghijklmnopqrstuv' record_id = 'this is my record #1. my first record. and it is mine' feature = Feature(simplegeohandle=handle, properties={'record_id': record_id}, coordinates=(D('37.8016'), D('-122.4783'))) # You can't add-feature on a feature that already has a simplegeo handle. Don't do that. self.failUnlessRaises(ValueError, self.client.places.add_feature, feature)
def test_no_terms_search_by_address(self): rec1 = Feature((D('11.03'), D('10.04')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={'name': "Bob's House Of Monkeys", 'category': "monkey dealership"}) rec2 = Feature((D('11.03'), D('10.05')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={'name': "Monkey Food 'R' Us", 'category': "pet food store"}) mockhttp = mock.Mock() mockhttp.request.return_value = ({'status': '200', 'content-type': 'application/json', }, json.dumps({'type': "FeatureColllection", 'features': [rec1.to_dict(), rec2.to_dict()]})) self.client.places.http = mockhttp lat = D('11.03') lon = D('10.04') self.failUnlessRaises(AssertionError, self.client.places.search_by_address, lat, lon) # Someone accidentally passed a lat,lon search_by_address(). addr = '41 Decatur St, San Francisco, CA' res = self.client.places.search_by_address(addr) self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[0][0], 'request') self.assertEqual(mockhttp.method_calls[0][1][0], 'http://api.simplegeo.com:80/%s/places/address.json?address=%s' % (API_VERSION, urllib.quote_plus(addr))) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET')
def get_feature(self, simplegeohandle, zoom=None): """Return the GeoJSON representation of a feature. Zoom needs to be between 1-20, or None for the full polygon.""" if not is_simplegeohandle(simplegeohandle): raise TypeError("simplegeohandle is required to match the regex %s, but it was %s :: %r" % (SIMPLEGEOHANDLE_RSTR, type(simplegeohandle), simplegeohandle)) kwargs = {} if zoom: precondition(zoom >= 1 and zoom <= 20, zoom) kwargs['zoom'] = zoom endpoint = self._endpoint('feature', simplegeohandle=simplegeohandle) return Feature.from_json(self._request(endpoint, 'GET', data=kwargs)[1])
def test_search(self): rec1 = Feature((D('11.03'), D('10.04')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={'name': "Bob's House Of Monkeys", 'category': "monkey dealership"}) rec2 = Feature((D('11.03'), D('10.05')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={'name': "Monkey Food 'R' Us", 'category': "pet food store"}) mockhttp = mock.Mock() mockhttp.request.return_value = ({'status': '200', 'content-type': 'application/json', }, json.dumps({'type': "FeatureColllection", 'features': [rec1.to_dict(), rec2.to_dict()]})) self.client.places.http = mockhttp self.failUnlessRaises(AssertionError, self.client.places.search, -91, 100) self.failUnlessRaises(AssertionError, self.client.places.search, -81, 361) lat = D('11.03') lon = D('10.04') res = self.client.places.search(lat, lon, query='monkeys', category='animal') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[0][0], 'request') self.assertEqual(mockhttp.method_calls[0][1][0], 'http://api.simplegeo.com:80/%s/places/%s,%s.json?q=monkeys&category=animal' % (API_VERSION, lat, lon)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET')
def test_add_feature_norecord_id_nonascii(self): mockhttp = mock.Mock() handle = 'SG_abcdefghijklmnopqrstuv' newloc = 'http://api.simplegeo.com:80/%s/places/%s.json' % ( API_VERSION, handle) properties = {'name': u"B❦b's H❤use of M❥nkeys"} resultfeature = Feature((D('11.03'), D('10.03')), simplegeohandle=handle, properties=properties) methods_called = [] def mockrequest2(*args, **kwargs): methods_called.append(('request', args, kwargs)) return ({ 'status': '200', 'content-type': 'application/json', }, resultfeature.to_json()) def mockrequest(*args, **kwargs): self.assertEqual( args[0], 'http://api.simplegeo.com:80/%s/places' % (API_VERSION, )) self.assertEqual(args[1], 'POST') bodyobj = json.loads(kwargs['body']) self.failUnlessEqual(bodyobj['id'], None) methods_called.append(('request', args, kwargs)) mockhttp.request = mockrequest2 return ({ 'status': '202', 'content-type': 'application/json', 'location': newloc }, json.dumps({'id': handle})) mockhttp.request = mockrequest self.client.places.http = mockhttp feature = Feature(coordinates=(D('37.8016'), D('-122.4783'))) res = self.client.places.add_feature(feature) self.failUnlessEqual(res, handle)
def test_add_feature_record_id(self): mockhttp = mock.Mock() handle = 'SG_abcdefghijklmnopqrstuv' record_id = 'this is my record #1. my first record. and it is mine' newloc = 'http://api.simplegeo.com:80/%s/features/%s.json' % ( API_VERSION, handle) resultfeature = Feature((D('11.03'), D('10.03')), simplegeohandle=handle) methods_called = [] def mockrequest2(*args, **kwargs): methods_called.append(('request', args, kwargs)) return ({ 'status': '200', 'content-type': 'application/json', }, resultfeature.to_json()) def mockrequest(*args, **kwargs): self.failUnlessEqual( args[0], 'http://api.simplegeo.com:80/%s/places' % (API_VERSION, )) self.failUnlessEqual(args[1], 'POST') bodyobj = json.loads(kwargs['body']) self.failUnlessEqual(bodyobj['properties'].get('record_id'), record_id) methods_called.append(('request', args, kwargs)) mockhttp.request = mockrequest2 return ({ 'status': '202', 'content-type': 'application/json', 'location': newloc }, json.dumps({'id': handle})) mockhttp.request = mockrequest self.client.places.http = mockhttp feature = Feature(properties={'record_id': record_id}, coordinates=(D('37.8016'), D('-122.4783'))) res = self.client.places.add_feature(feature) self.failUnlessEqual(res, handle)
def test_get_feature(self): handle = 'SG_abcdefghijklmnopqrstuv' resultfeature = Feature((D('11.03'), D('10.03')), simplegeohandle=handle) mockhttp = mock.Mock() mockhttp.request.return_value = ({ 'status': '200', 'content-type': 'application/json', }, resultfeature.to_json()) self.client.places.http = mockhttp res = self.client.places.get_feature(handle) self.assertEqual(mockhttp.method_calls[0][0], 'request') self.assertEqual( mockhttp.method_calls[0][1][0], 'http://api.simplegeo.com:80/%s/features/%s.json' % (API_VERSION, handle)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET') self.failUnless(isinstance(res, Feature), res) self.assertEqual(res.to_json(), resultfeature.to_json())
def test_search_by_my_ip_nonascii(self): rec1 = Feature((D('11.03'), D('10.04')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={ 'name': "Bob's House Of Monkeys", 'category': "monkey dealership" }) rec2 = Feature((D('11.03'), D('10.05')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={ 'name': "Monkey Food 'R' Us", 'category': "pet food store" }) mockhttp = mock.Mock() mockhttp.request.return_value = ({ 'status': '200', 'content-type': 'application/json', }, json.dumps({ 'type': "FeatureColllection", 'features': [rec1.to_dict(), rec2.to_dict()] })) self.client.places.http = mockhttp ipaddr = '192.0.32.10' self.failUnlessRaises( AssertionError, self.client.places.search_by_my_ip, ipaddr ) # Someone accidentally passed an ip addr to search_by_my_ip(). res = self.client.places.search_by_my_ip(query='monk❥y', category='animal') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[-1][0], 'request') urlused = mockhttp.method_calls[-1][1][0] urlused = urllib.unquote(urlused).decode('utf-8') self.assertEqual( urlused, u'http://api.simplegeo.com:80/%s/places/ip.json?q=monk❥y&category=animal' % (API_VERSION, )) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET') res = self.client.places.search_by_my_ip(query='monk❥y', category='anim❥l') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[-1][0], 'request') urlused = mockhttp.method_calls[-1][1][0] urlused = urllib.unquote(urlused).decode('utf-8') self.assertEqual( urlused, u'http://api.simplegeo.com:80/%s/places/ip.json?q=monk❥y&category=anim❥l' % (API_VERSION, )) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET')
def get_feature(self, simplegeohandle, zoom=None): """Return the GeoJSON representation of a feature. Zoom needs to be between 1-20, or None for the full polygon.""" if not is_simplegeohandle(simplegeohandle): raise TypeError( "simplegeohandle is required to match the regex %s, but it was %s :: %r" % (SIMPLEGEOHANDLE_RSTR, type(simplegeohandle), simplegeohandle) ) kwargs = {} if zoom: if zoom < 1 or zoom > 20: raise AssertionError("Zoom must be in the range 1..20") kwargs["zoom"] = zoom endpoint = self._endpoint("feature", simplegeohandle=simplegeohandle) return Feature.from_json(self._request(endpoint, "GET", data=kwargs)[1])
def get_feature(self, simplegeohandle, zoom=None): """Return the GeoJSON representation of a feature. Zoom needs to be between 1-20, or None for the full polygon.""" if not is_simplegeohandle(simplegeohandle): raise TypeError( "simplegeohandle is required to match the regex %s, but it was %s :: %r" % (SIMPLEGEOHANDLE_RSTR, type(simplegeohandle), simplegeohandle)) kwargs = {} if zoom: precondition(zoom >= 1 and zoom <= 20, zoom) kwargs['zoom'] = zoom endpoint = self._endpoint('feature', simplegeohandle=simplegeohandle) return Feature.from_json( self._request(endpoint, 'GET', data=kwargs)[1])
def test_record_constructor(self): self.failUnlessRaises(TypeError, Feature, D('11.0'), D('10.0'), properties={'record_id': 'my_id'}) # lat exceeds bound self.failUnlessRaises(TypeError, Feature, (D('91.0'), D('10.1')), properties={'record_id': 'my_id'}) # lon exceeds bound self.failUnlessRaises(TypeError, Feature, (D('10.1'), D('180.1')), properties={'record_id': 'my_id'}, strict_lon_validation=True) record = Feature(coordinates=(D('11.0'), D('10.0')), properties={'record_id': 'my_id'}) self.failUnlessEqual(record.properties.get('record_id'), 'my_id') self.failUnlessEqual(record.id, None) self.failUnlessEqual(record.geomtype, 'Point') self.failUnlessEqual(record.coordinates[0], D('11.0')) self.failUnlessEqual(record.coordinates[1], D('10.0')) record = Feature(coordinates=(D('11.0'), D('10.0')), simplegeohandle='SG_abcdefghijklmnopqrstuv') self.failUnlessEqual(record.properties.get('record_id'), None) self.failUnlessEqual(record.id, 'SG_abcdefghijklmnopqrstuv') record = Feature(coordinates=(D('11.0'), D('10.0')), properties={'record_id': 'my_id'}, simplegeohandle='SG_abcdefghijklmnopqrstuv') self.failUnlessEqual(record.properties.get('record_id'), 'my_id') self.failUnlessEqual(record.id, 'SG_abcdefghijklmnopqrstuv') record = Feature(coordinates=(D('11.0'), D('10.0'))) self.failUnlessEqual(record.properties.get('record_id'), None) self.failUnlessEqual(record.id, None) record = Feature((D('11.0'), D('10.0')), properties={'record_id': 'my_id'}) self.failUnlessEqual(record.properties.get('record_id'), 'my_id') record = Feature((11.0, 10.0), properties={'record_id': 'my_id'}) self.failUnlessEqual(record.geomtype, 'Point') self.failUnlessEqual(record.coordinates[0], 11.0) self.failUnlessEqual(record.coordinates[1], 10.0) self.failUnlessEqual(record.properties.get('record_id'), 'my_id') record = Feature([[(11.0, 179.9), (12, -179.9)]], geomtype='Polygon') self.failUnlessEqual(record.geomtype, 'Polygon') self.failUnlessEqual(len(record.coordinates[0]), 2) self.failUnlessEqual(record.coordinates[0][0], (11.0, 179.9)) jsondict = record.to_dict() self.failUnlessEqual(jsondict['geometry']['coordinates'][0][0], (179.9, 11.))
def search_by_address(self, address, radius=None, query=None, category=None, num=None): """ Search for places near the given address, within a radius (in kilometers). The server figures out the latitude and longitude from the street address and then does the same thing as search(), using that deduced latitude and longitude. """ if not isinstance(address, basestring) or not address.strip(): raise ValueError("Address must be a non-empty string.") if (radius and not is_numeric(radius)): raise ValueError("Radius must be numeric.") if (query and not isinstance(query, basestring)): raise ValueError("Query must be a string.") if (category and not isinstance(category, basestring)): raise ValueError("Category must be a string.") if (num and not is_numeric(num)): raise ValueError("Num parameter must be numeric.") if isinstance(address, unicode): address = address.encode('utf-8') if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = { 'address': address } if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category if num: kwargs['num'] = num endpoint = self._endpoint('search_by_address') result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def test_search_nonascii(self): rec1 = Feature((D('11.03'), D('10.04')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={ 'name': u"B❤b's House Of Monkeys", 'category': u"m❤nkey dealership" }) rec2 = Feature((D('11.03'), D('10.05')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={ 'name': u"M❤nkey Food 'R' Us", 'category': "pet food store" }) mockhttp = mock.Mock() mockhttp.request.return_value = ({ 'status': '200', 'content-type': 'application/json', }, json.dumps({ 'type': "FeatureColllection", 'features': [rec1.to_dict(), rec2.to_dict()] })) self.client.places.http = mockhttp self.failUnlessRaises(AssertionError, self.client.places.search, -91, 100) self.failUnlessRaises(AssertionError, self.client.places.search, -81, 361) lat = D('11.03') lon = D('10.04') res = self.client.places.search(lat, lon, query=u'm❤nkey', category='animal') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[0][0], 'request') urlused = mockhttp.method_calls[0][1][0] urlused = urllib.unquote(urlused).decode('utf-8') self.assertEqual( urlused, u'http://api.simplegeo.com:80/%s/places/%s,%s.json?q=m❤nkey&category=animal' % (API_VERSION, lat, lon)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET')
def test_record_to_dict_sets_id_correctly(self): handle = 'SG_abcdefghijklmnopqrstuv' record_id = 'this is my record #1. my first record. and it is mine' rec = Feature(coordinates=(D('11.03'), D('10.03')), simplegeohandle=handle, properties={'record_id': record_id}) dic = rec.to_dict() self.failUnlessEqual(dic.get('id'), handle) self.failUnlessEqual(dic.get('properties', {}).get('record_id'), record_id) rec = Feature(coordinates=(D('11.03'), D('10.03')), simplegeohandle=handle, properties={'record_id': None}) dic = rec.to_dict() self.failUnlessEqual(dic.get('id'), handle) self.failUnlessEqual(dic.get('properties', {}).get('record_id'), None) rec = Feature(coordinates=(D('11.03'), D('10.03')), simplegeohandle=handle, properties={'record_id': None}) dic = rec.to_dict() self.failUnlessEqual(dic.get('id'), handle) self.failUnlessEqual(dic.get('properties', {}).get('record_id'), None) rec = Feature(coordinates=(D('11.03'), D('10.03')), simplegeohandle=None, properties={'record_id': None}) dic = rec.to_dict() self.failUnlessEqual(dic.get('id'), None) self.failUnlessEqual(dic.get('properties', {}).get('record_id'), None)
def search_by_ip(self, ipaddr, radius=None, query=None, category=None, num=None): """ Search for places near an IP address, within a radius (in kilometers). The server uses guesses the latitude and longitude from the ipaddr and then does the same thing as search(), using that guessed latitude and longitude. """ if not is_valid_ip(ipaddr): raise ValueError("Address %s is not a valid IP" % ipaddr) if (radius and not is_numeric(radius)): raise ValueError("Radius must be numeric.") if (query and not isinstance(query, basestring)): raise ValueError("Query must be a string.") if (category and not isinstance(category, basestring)): raise ValueError("Category must be a string.") if (num and not is_numeric(num)): raise ValueError("Num parameter must be numeric.") if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = { } if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category if num: kwargs['num'] = num endpoint = self._endpoint('search_by_ip', ipaddr=ipaddr) result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def search_by_address(self, address, radius=None, query=None, category=None): """ Search for places near the given address, within a radius (in kilometers). The server figures out the latitude and longitude from the street address and then does the same thing as search(), using that deduced latitude and longitude. """ precondition(isinstance(address, basestring), address) precondition(address != '', address) precondition(radius is None or is_numeric(radius), radius) precondition(query is None or isinstance(query, basestring), query) precondition(category is None or isinstance(category, basestring), category) if isinstance(address, unicode): address = address.encode('utf-8') if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = {'address': address} if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category endpoint = self._endpoint('search_by_address') result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def test_search_by_ip(self): rec1 = Feature((D('11.03'), D('10.04')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={ 'name': "Bob's House Of Monkeys", 'category': "monkey dealership" }) rec2 = Feature((D('11.03'), D('10.05')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={ 'name': "Monkey Food 'R' Us", 'category': "pet food store" }) mockhttp = mock.Mock() mockhttp.request.return_value = ({ 'status': '200', 'content-type': 'application/json', }, json.dumps({ 'type': "FeatureColllection", 'features': [rec1.to_dict(), rec2.to_dict()] })) self.client.places.http = mockhttp self.failUnlessRaises(AssertionError, self.client.places.search_by_ip, 'this is not an IP address at all, silly') self.failUnlessRaises( AssertionError, self.client.places.search_by_ip, -81, 181) # Someone accidentally passed lat, lon to search_by_ip(). ipaddr = '192.0.32.10' res = self.client.places.search_by_ip(ipaddr, query='monkeys', category='animal') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[0][0], 'request') self.assertEqual( mockhttp.method_calls[0][1][0], 'http://api.simplegeo.com:80/%s/places/%s.json?q=monkeys&category=animal' % (API_VERSION, ipaddr)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET')
def test_record_from_dict_lon_validation(self): record_dict = { 'geometry': { 'type': 'Point', 'coordinates': [D('181.0'), D('11.0')] }, 'type': 'Feature', 'properties': { 'record_id': 'my_id', 'key': 'value', 'type': 'object' } } self.failUnlessRaises(TypeError, Feature.from_dict, record_dict, True) record = Feature.from_dict(record_dict, strict_lon_validation=False) self.assertEquals(record.coordinates[0], D('11.0')) self.assertEquals(record.coordinates[1], D('181.0')) self.assertEquals(record.properties.get('record_id'), 'my_id') self.assertEquals(record.properties['key'], 'value') self.assertEquals(record.properties['type'], 'object')
def test_record_from_dict_lon_validation(self): record_dict = { 'geometry' : { 'type' : 'Point', 'coordinates' : [D('181.0'), D('11.0')] }, 'type' : 'Feature', 'properties' : { 'record_id' : 'my_id', 'key' : 'value' , 'type' : 'object' } } self.failUnlessRaises(TypeError, Feature.from_dict, record_dict, True) record = Feature.from_dict(record_dict, strict_lon_validation=False) self.assertEquals(record.coordinates[0], D('11.0')) self.assertEquals(record.coordinates[1], D('181.0')) self.assertEquals(record.properties.get('record_id'), 'my_id') self.assertEquals(record.properties['key'], 'value') self.assertEquals(record.properties['type'], 'object')
def search_by_my_ip(self, radius=None, query=None, category=None, num=None): """ Search for places near your IP address, within a radius (in kilometers). The server gets the IP address from the HTTP connection (this may be the IP address of your device or of a firewall, NAT, or HTTP proxy device between you and the server), and then does the same thing as search_by_ip(), using that IP address. """ if (radius and not is_numeric(radius)): raise ValueError("Radius must be numeric.") if (query and not isinstance(query, basestring)): raise ValueError("Query must be a string.") if (category and not isinstance(category, basestring)): raise ValueError("Category must be a string.") if (num and not is_numeric(num)): raise ValueError("Num parameter must be numeric.") if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = { } if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category if num: kwargs['num'] = num endpoint = self._endpoint('search_by_my_ip') result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
def test_no_terms_search_by_address(self): rec1 = Feature((D('11.03'), D('10.04')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={ 'name': "Bob's House Of Monkeys", 'category': "monkey dealership" }) rec2 = Feature((D('11.03'), D('10.05')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={ 'name': "Monkey Food 'R' Us", 'category': "pet food store" }) mockhttp = mock.Mock() mockhttp.request.return_value = ({ 'status': '200', 'content-type': 'application/json', }, json.dumps({ 'type': "FeatureColllection", 'features': [rec1.to_dict(), rec2.to_dict()] })) self.client.places.http = mockhttp lat = D('11.03') lon = D('10.04') self.failUnlessRaises( AssertionError, self.client.places.search_by_address, lat, lon) # Someone accidentally passed a lat,lon search_by_address(). addr = '41 Decatur St, San Francisco, CA' res = self.client.places.search_by_address(addr) self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[0][0], 'request') self.assertEqual( mockhttp.method_calls[0][1][0], 'http://api.simplegeo.com:80/%s/places/address.json?address=%s' % (API_VERSION, urllib.quote_plus(addr))) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET')
def search_by_address(self, address, radius=None, query=None, category=None): """ Search for places near the given address, within a radius (in kilometers). The server figures out the latitude and longitude from the street address and then does the same thing as search(), using that deduced latitude and longitude. """ precondition(isinstance(address, basestring), address) precondition(address != '', address) precondition(radius is None or is_numeric(radius), radius) precondition(query is None or isinstance(query, basestring), query) precondition(category is None or isinstance(category, basestring), category) if isinstance(address, unicode): address = address.encode('utf-8') if isinstance(query, unicode): query = query.encode('utf-8') if isinstance(category, unicode): category = category.encode('utf-8') kwargs = { 'address': address } if radius: kwargs['radius'] = radius if query: kwargs['q'] = query if category: kwargs['category'] = category endpoint = self._endpoint('search_by_address') result = self._request(endpoint, 'GET', data=kwargs)[1] fc = json_decode(result) return [Feature.from_dict(f) for f in fc['features']]
(0.2, 100.2)]]]) def test_record_constructor_useful_validation_error_message(self): try: Feature(coordinates=[181, D('10.0')], properties={'record_id': 'my_id'}) except TypeError, e: self.failUnless(str(e).startswith('The first argument'), str(e)) self.failUnless('is required to be a 2-element sequence' in str(e), str(e)) else: self.fail('Should have raised exception.') try: Feature(coordinates=[-90, D('181.0')], properties={'record_id': 'my_id'}, strict_lon_validation=True) except TypeError, e: self.failUnless('181' in str(e), str(e)) else: self.fail('Should have raised exception.') try: Feature(coordinates=[-90, D('361.0')], properties={'record_id': 'my_id'}) except TypeError, e: self.failUnless('361' in str(e), str(e)) else: self.fail('Should have raised exception.') try:
def test_geojson_is_correct(self): f = Feature(coordinates=[-90, D('171.0')], properties={'record_id': 'my_id'}, strict_lon_validation=True) stringy = f.to_json() self.failUnlessEqual(stringy, '{"geometry": {"type": "Point", "coordinates": [171.0, -90]}, "type": "Feature", "id": null, "properties": {"record_id": "my_id", "private": false}}')
def test_record_from_dict(self): record_dict = { 'geometry' : { 'type' : 'Point', 'coordinates' : [D('10.0'), D('11.0')] }, 'type' : 'Feature', 'properties' : { 'record_id' : 'my_id', 'key' : 'value' , 'type' : 'object' } } record = Feature.from_dict(record_dict) self.assertEquals(record.coordinates[0], D('11.0')) self.assertEquals(record.coordinates[1], D('10.0')) self.assertEquals(record.properties.get('record_id'), 'my_id') self.assertEquals(record.properties['key'], 'value') self.assertEquals(record.properties['type'], 'object') self.assertEquals(record.to_json(), '{"geometry": {"type": "Point", "coordinates": [10.0, 11.0]}, "type": "Feature", "id": null, "properties": {"record_id": "my_id", "type": "object", "private": false, "key": "value"}}') record_dict = { 'geometry' : { 'type' : 'Point', 'coordinates' : [D('10.0'), D('11.0')] }, 'id' : 'SG_abcdefghijklmnopqrstuv', 'type' : 'Feature', 'properties' : { 'key' : 'value' , 'type' : 'object' } } record = Feature.from_dict(record_dict) self.assertEquals(record.properties.get('record_id'), None) self.assertEquals(record.id, 'SG_abcdefghijklmnopqrstuv') record_dict = { 'geometry' : { 'type' : 'Point', 'coordinates' : [D('10.0'), D('11.0')] }, 'id' : 'SG_abcdefghijklmnopqrstuv', 'type' : 'Feature', 'properties' : { 'record_id' : 'my_id', 'key' : 'value' , 'type' : 'object' } } record = Feature.from_dict(record_dict) self.assertEquals(record.properties.get('record_id'), 'my_id') self.assertEquals(record.id, 'SG_abcdefghijklmnopqrstuv') record_dict = { 'geometry' : { 'type' : 'Point', 'coordinates' : [10.0, 11.0] }, 'type' : 'Feature', 'properties' : { 'record_id' : 'my_id', 'key' : 'value' , 'type' : 'object' } } record = Feature.from_dict(record_dict) self.assertEquals(record.coordinates[0], 11.0) self.assertEquals(record.coordinates[1], 10.0)
def test_search_by_address_nonascii(self): rec1 = Feature((D('11.03'), D('10.04')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={ 'name': "Bob's House Of Monkeys", 'category': "monkey dealership" }) rec2 = Feature((D('11.03'), D('10.05')), simplegeohandle='SG_abcdefghijkmlnopqrstuv', properties={ 'name': "Monkey Food 'R' Us", 'category': "pet food store" }) mockhttp = mock.Mock() mockhttp.request.return_value = ({ 'status': '200', 'content-type': 'application/json', }, json.dumps({ 'type': "FeatureColllection", 'features': [rec1.to_dict(), rec2.to_dict()] })) self.client.places.http = mockhttp lat = D('11.03') lon = D('10.04') self.failUnlessRaises( AssertionError, self.client.places.search_by_address, lat, lon ) # Someone accidentally passed a lat,lon to search_by_address(). addr = u'41 Decatur St, San Francisc❦, CA' res = self.client.places.search_by_address(addr, query='monkeys', category='animal') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[-1][0], 'request') urlused = mockhttp.method_calls[-1][1][0] cod = urllib.quote_plus(addr.encode('utf-8')) self.assertEqual( urlused, 'http://api.simplegeo.com:80/%s/places/address.json?q=monkeys&category=animal&address=%s' % ( API_VERSION, cod, )) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET') res = self.client.places.search_by_address(addr, query=u'monke❦s', category=u'ani❦al') self.failUnless(isinstance(res, (list, tuple)), (repr(res), type(res))) self.failUnlessEqual(len(res), 2) self.failUnless(all(isinstance(f, Feature) for f in res)) self.assertEqual(mockhttp.method_calls[-1][0], 'request') urlused = mockhttp.method_calls[-1][1][0] quargs = {'q': u'monke❦s', 'category': u'ani❦al', 'address': addr} equargs = dict((k, v.encode('utf-8')) for k, v in quargs.iteritems()) s2quargs = urllib.urlencode(equargs) self.assertEqual( urlused, 'http://api.simplegeo.com:80/%s/places/address.json?%s' % (API_VERSION, s2quargs)) self.assertEqual(mockhttp.method_calls[0][1][1], 'GET')
def test_record_from_dict(self): record_dict = { 'geometry': { 'type': 'Point', 'coordinates': [D('10.0'), D('11.0')] }, 'type': 'Feature', 'properties': { 'record_id': 'my_id', 'key': 'value', 'type': 'object' } } record = Feature.from_dict(record_dict) self.assertEquals(record.coordinates[0], D('11.0')) self.assertEquals(record.coordinates[1], D('10.0')) self.assertEquals(record.properties.get('record_id'), 'my_id') self.assertEquals(record.properties['key'], 'value') self.assertEquals(record.properties['type'], 'object') self.assertEquals( record.to_json(), '{"geometry": {"type": "Point", "coordinates": [10.0, 11.0]}, "type": "Feature", "id": null, "properties": {"record_id": "my_id", "type": "object", "private": false, "key": "value"}}' ) record_dict = { 'geometry': { 'type': 'Point', 'coordinates': [D('10.0'), D('11.0')] }, 'id': 'SG_abcdefghijklmnopqrstuv', 'type': 'Feature', 'properties': { 'key': 'value', 'type': 'object' } } record = Feature.from_dict(record_dict) self.assertEquals(record.properties.get('record_id'), None) self.assertEquals(record.id, 'SG_abcdefghijklmnopqrstuv') record_dict = { 'geometry': { 'type': 'Point', 'coordinates': [D('10.0'), D('11.0')] }, 'id': 'SG_abcdefghijklmnopqrstuv', 'type': 'Feature', 'properties': { 'record_id': 'my_id', 'key': 'value', 'type': 'object' } } record = Feature.from_dict(record_dict) self.assertEquals(record.properties.get('record_id'), 'my_id') self.assertEquals(record.id, 'SG_abcdefghijklmnopqrstuv') record_dict = { 'geometry': { 'type': 'Point', 'coordinates': [10.0, 11.0] }, 'type': 'Feature', 'properties': { 'record_id': 'my_id', 'key': 'value', 'type': 'object' } } record = Feature.from_dict(record_dict) self.assertEquals(record.coordinates[0], 11.0) self.assertEquals(record.coordinates[1], 10.0)
def test_record_to_dict_sets_id_correctly(self): handle = 'SG_abcdefghijklmnopqrstuv' record_id = 'this is my record #1. my first record. and it is mine' rec = Feature(coordinates=(D('11.03'), D('10.03')), simplegeohandle=handle, properties={'record_id': record_id}) dic = rec.to_dict() self.failUnlessEqual(dic.get('id'), handle) self.failUnlessEqual( dic.get('properties', {}).get('record_id'), record_id) rec = Feature(coordinates=(D('11.03'), D('10.03')), simplegeohandle=handle, properties={'record_id': None}) dic = rec.to_dict() self.failUnlessEqual(dic.get('id'), handle) self.failUnlessEqual(dic.get('properties', {}).get('record_id'), None) rec = Feature(coordinates=(D('11.03'), D('10.03')), simplegeohandle=handle, properties={'record_id': None}) dic = rec.to_dict() self.failUnlessEqual(dic.get('id'), handle) self.failUnlessEqual(dic.get('properties', {}).get('record_id'), None) rec = Feature(coordinates=(D('11.03'), D('10.03')), simplegeohandle=None, properties={'record_id': None}) dic = rec.to_dict() self.failUnlessEqual(dic.get('id'), None) self.failUnlessEqual(dic.get('properties', {}).get('record_id'), None)