Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ before_install:

install:
- pip install -r requirements.txt
- pip install httpretty pylint coveralls
- pip install requests_mock pylint coveralls
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install unittest2 ipaddr; fi
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install ipaddr; fi

Expand Down
2 changes: 1 addition & 1 deletion geoip2/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def isp(self, ip_address):
ip_address)

def _get(self, database_type, ip_address):
if not database_type in self.metadata().database_type:
if database_type not in self.metadata().database_type:
caller = inspect.stack()[2][3]
raise TypeError("The %s method cannot be used with the "
"%s database" %
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
install_requires=requirements,
extras_require={
':python_version=="2.6" or python_version=="2.7"': ['ipaddr']},
tests_require=['httpretty>=0.6.1'],
tests_require=['requests_mock'],
test_suite="tests",
license=geoip2.__license__,
classifiers=(
Expand Down
232 changes: 121 additions & 111 deletions tests/webservice_test.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import httpretty
import httpretty.core
import sys
sys.path.append('..')

import geoip2
import json
import requests
import requests_mock
from geoip2.errors import AddressNotFoundError, AuthenticationError, \
GeoIP2Error, HTTPError, InvalidRequestError, OutOfQueriesError
from geoip2.webservice import Client
Expand All @@ -28,7 +25,6 @@
unittest.TestCase.assertRegex = unittest.TestCase.assertRegexpMatches


@httpretty.activate
class TestClient(unittest.TestCase):

def setUp(self):
Expand All @@ -54,12 +50,13 @@ def _content_type(self, endpoint):
return ('application/vnd.maxmind.com-' +
endpoint + '+json; charset=UTF-8; version=1.0')

def test_country_ok(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/1.2.3.4',
body=json.dumps(self.country),
status=200,
content_type=self._content_type('country'))
@requests_mock.mock()
def test_country_ok(self, mock):
mock.get(self.base_uri + 'country/1.2.3.4',
json=self.country,
status_code=200,
headers={'Content-Type':
self._content_type('country')})
country = self.client.country('1.2.3.4')
self.assertEqual(type(country), geoip2.models.Country,
'return value of client.country')
Expand All @@ -82,24 +79,25 @@ def test_country_ok(self):
'queries_remaining is 11')
self.assertEqual(country.raw, self.country, 'raw response is correct')

def test_me(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/me',
body=json.dumps(self.country),
status=200,
content_type=self._content_type('country'))
@requests_mock.mock()
def test_me(self, mock):
mock.get(self.base_uri + 'country/me',
json=self.country,
status_code=200,
headers={'Content-Type':
self._content_type('country')})
implicit_me = self.client.country()
self.assertEqual(type(implicit_me), geoip2.models.Country,
'country() returns Country object')
explicit_me = self.client.country()
self.assertEqual(type(explicit_me), geoip2.models.Country,
'country(\'me\') returns Country object')

def test_200_error(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/1.1.1.1',
status=200,
content_type=self._content_type('country'))
@requests_mock.mock()
def test_200_error(self, mock):
mock.get(self.base_uri + 'country/1.1.1.1',
status_code=200,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(GeoIP2Error,
'could not decode the response as JSON'):
self.client.country('1.1.1.1')
Expand All @@ -110,126 +108,138 @@ def test_bad_ip_address(self):
"or IPv6 address"):
self.client.country('1.2.3')

def test_no_body_error(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.7',
body='',
status=400,
content_type=self._content_type('country'))
@requests_mock.mock()
def test_no_body_error(self, mock):
mock.get(self.base_uri + 'country/' + '1.2.3.7',
text='',
status_code=400,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(HTTPError,
'Received a 400 error for .* with no body'):
self.client.country('1.2.3.7')

def test_weird_body_error(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.8',
body='{"wierd": 42}',
status=400,
content_type=self._content_type('country'))
@requests_mock.mock()
def test_weird_body_error(self, mock):
mock.get(self.base_uri + 'country/' + '1.2.3.8',
text='{"wierd": 42}',
status_code=400,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(HTTPError,
'Response contains JSON but it does not '
'specify code or error keys'):
self.client.country('1.2.3.8')

def test_bad_body_error(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.9',
body='bad body',
status=400,
content_type=self._content_type('country'))
@requests_mock.mock()
def test_bad_body_error(self, mock):
mock.get(self.base_uri + 'country/' + '1.2.3.9',
text='bad body',
status_code=400,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(HTTPError,
'it did not include the expected JSON body'
):
self.client.country('1.2.3.9')

def test_500_error(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.10',
status=500)
@requests_mock.mock()
def test_500_error(self, mock):
mock.get(self.base_uri + 'country/' + '1.2.3.10',
status_code=500)
with self.assertRaisesRegex(HTTPError,
'Received a server error \(500\) for'):
self.client.country('1.2.3.10')

def test_300_error(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.11',
status=300,
content_type=self._content_type('country'))
@requests_mock.mock()
def test_300_error(self, mock):
mock.get(self.base_uri + 'country/' + '1.2.3.11',
status_code=300,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(HTTPError,
'Received a very surprising HTTP status '
'\(300\) for'):

self.client.country('1.2.3.11')

def test_address_not_found_error(self):
@requests_mock.mock()
def test_address_not_found_error(self, mock):
body = {'error': 'Not in DB', 'code': 'IP_ADDRESS_NOT_FOUND'}
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.13',
body=json.dumps(body),
status=404,
content_type=self._content_type('country'))
mock.get(self.base_uri + 'country/' + '1.2.3.13',
json=body,
status_code=404,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(AddressNotFoundError,
'Not in DB'):
self.client.country('1.2.3.13')

def test_private_address_error(self):
@requests_mock.mock()
def test_private_address_error(self, mock):
body = {'error': 'Private', 'code': 'IP_ADDRESS_RESERVED'}
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.14',
body=json.dumps(body),
status=401,
content_type=self._content_type('country'))
mock.get(self.base_uri + 'country/' + '1.2.3.14',
json=body,
status_code=401,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(AddressNotFoundError, 'Private'):
self.client.country('1.2.3.14')

def test_auth_invalid(self):
@requests_mock.mock()
def test_auth_invalid(self, mock):
body = {'error': 'Invalid auth', 'code': 'AUTHORIZATION_INVALID'}
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.15',
body=json.dumps(body),
status=400,
content_type=self._content_type('country'))
mock.get(self.base_uri + 'country/' + '1.2.3.15',
json=body,
status_code=400,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(AuthenticationError, 'Invalid auth'):
self.client.country('1.2.3.15')

def test_license_required(self):
@requests_mock.mock()
def test_license_required(self, mock):
body = {'error': 'License required', 'code': 'LICENSE_KEY_REQUIRED'}
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.16',
body=json.dumps(body),
status=401,
content_type=self._content_type('country'))
mock.get(self.base_uri + 'country/' + '1.2.3.16',
json=body,
status_code=401,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(AuthenticationError, 'License required'):
self.client.country('1.2.3.16')

def test_user_id_required(self):
@requests_mock.mock()
def test_user_id_required(self, mock):
body = {'error': 'User ID required', 'code': 'USER_ID_REQUIRED'}
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.17',
body=json.dumps(body),
status=401,
content_type=self._content_type('country'))
mock.get(self.base_uri + 'country/' + '1.2.3.17',
json=body,
status_code=401,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(AuthenticationError, 'User ID required'):
self.client.country('1.2.3.17')

def test_out_of_queries_error(self):
@requests_mock.mock()
def test_out_of_queries_error(self, mock):
body = {'error': 'Out of Queries', 'code': 'OUT_OF_QUERIES'}
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.18',
body=json.dumps(body),
status=402,
content_type=self._content_type('country'))
mock.get(self.base_uri + 'country/' + '1.2.3.18',
json=body,
status_code=402,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(OutOfQueriesError, 'Out of Queries',):
self.client.country('1.2.3.18')

def test_request(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'country/' + '1.2.3.4',
body=json.dumps(self.country),
status=200,
content_type=self._content_type('country'))
country = self.client.country('1.2.3.4')
request = httpretty.core.httpretty.latest_requests[-1]
@requests_mock.mock()
def test_unknown_error(self, mock):
msg = 'Unknown error type'
ip = '1.2.3.19'
body = {'error': msg, 'code': 'UNKNOWN_TYPE'}
mock.get(self.base_uri + 'country/' + ip,
json=body,
status_code=400,
headers={'Content-Type': self._content_type('country')})
with self.assertRaisesRegex(InvalidRequestError, msg,):
self.client.country(ip)

@requests_mock.mock()
def test_request(self, mock):
mock.get(self.base_uri + 'country/' + '1.2.3.4',
json=self.country,
status_code=200,
headers={'Content-Type': self._content_type('country')})
self.client.country('1.2.3.4')
request = mock.request_history[-1]

self.assertEqual(request.path,
'/geoip/v2.1/country/1.2.3.4',
Expand All @@ -243,32 +253,32 @@ def test_request(self):
self.assertEqual(request.headers['Authorization'],
'Basic NDI6YWJjZGVmMTIzNDU2', 'correct auth')

def test_city_ok(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'city/' + '1.2.3.4',
body=json.dumps(self.country),
status=200,
content_type=self._content_type('city'))
@requests_mock.mock()
def test_city_ok(self, mock):
mock.get(self.base_uri + 'city/' + '1.2.3.4',
json=self.country,
status_code=200,
headers={'Content-Type': self._content_type('city')})
city = self.client.city('1.2.3.4')
self.assertEqual(type(city), geoip2.models.City,
'return value of client.city')

def test_insights_ok(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'insights/1.2.3.4',
body=json.dumps(self.country),
status=200,
content_type=self._content_type('country'))
@requests_mock.mock()
def test_insights_ok(self, mock):
mock.get(self.base_uri + 'insights/1.2.3.4',
json=self.country,
status_code=200,
headers={'Content-Type': self._content_type('country')})
insights = self.client.insights('1.2.3.4')
self.assertEqual(type(insights), geoip2.models.Insights,
'return value of client.insights')

def test_insights_ok(self):
httpretty.register_uri(httpretty.GET,
self.base_uri + 'insights/1.2.3.4',
body=json.dumps(self.country),
status=200,
content_type=self._content_type('country'))
@requests_mock.mock()
def test_insights_ok(self, mock):
mock.get(self.base_uri + 'insights/1.2.3.4',
json=self.country,
status_code=200,
headers={'Content-Type': self._content_type('country')})
insights = self.client.insights('1.2.3.4')
self.assertEqual(type(insights), geoip2.models.Insights,
'return value of client.insights')
Expand Down