Skip to content

Commit ee2bf36

Browse files
Merge pull request #5 from sendgrid/generic-unit-tests
Unit tests no longer requires mocked server
2 parents d9b0ea0 + b059acc commit ee2bf36

File tree

6 files changed

+152
-120
lines changed

6 files changed

+152
-120
lines changed

CONTRIBUTING.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,6 @@ pyenv local 3.5.0 3.4.3 3.3.6 3.2.6 2.7.8 2.6.9
138138
pyenv rehash
139139
````
140140
141-
Please [email](mailto:dx@sendgrid.com) us for details on how we mocked up the SendGrid API server, otherwise when you commit to your branch the Travis tests will execute remotely against our Mock Server.
142-
143141
### Execute: ###
144142
145143
```

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,6 @@ We were inspired by the work done on [birdy](https://github.com/inueni/birdy) an
129129

130130
python-http-client is guided and supported by the SendGrid [Developer Experience Team](mailto:dx@sendgrid.com).
131131

132-
python-http-client is maintained and funded by SendGrid, inc. The names and logos for python-http-client are trademarks of SendGrid, inc.
132+
python-http-client is maintained and funded by SendGrid, Inc. The names and logos for python-http-client are trademarks of SendGrid, Inc.
133133

134134

python_http_client/client.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ class Client(object):
2323
:param version: The version number of the API.
2424
Subclass _build_versioned_url for custom behavior.
2525
Or just pass the version as part of the URL
26-
(e.g. client._("/v3"))
26+
(e.g. client._('/v3'))
2727
:type integer:
2828
"""
2929
def __init__(self,
30-
host=None,
30+
host,
3131
request_headers=None,
3232
version=None):
3333
self.host = host
@@ -60,25 +60,25 @@ def _add_to_url_path(self, name):
6060

6161
"""Subclass this function for your own needs.
6262
Or just pass the version as part of the URL
63-
(e.g. client._("/v3"))
63+
(e.g. client._('/v3'))
6464
"""
6565
def _build_versioned_url(self, url):
66-
return self.host + "/v" + str(self._version) + url
66+
return '{0}/v{1}{2}'.format(self.host, str(self._version), url)
6767

6868
"""Build the final URL to be passed to urllib
6969
7070
:param query_params: A dictionary of all the query parameters
7171
:type query_params: dictionary
7272
"""
7373
def _build_url(self, query_params):
74-
url = ""
74+
url = ''
7575
count = 0
7676
while count < len(self._url_path):
77-
url += "/" + str(self._url_path[count])
77+
url += '/{0}'.format(self._url_path[count])
7878
count += 1
7979
if query_params:
8080
url_values = urlencode(sorted(query_params.items()))
81-
url = url + '?' + url_values
81+
url = '{0}?{1}'.format(url, url_values)
8282
if self._version:
8383
url = self._build_versioned_url(url)
8484
else:
@@ -101,7 +101,16 @@ def _set_response(self, response):
101101
:type request_headers: dictionary
102102
"""
103103
def _set_headers(self, request_headers):
104-
self.request_headers.update(request_headers)
104+
if self.request_headers:
105+
self.request_headers.update(request_headers)
106+
else:
107+
self.request_headers = request_headers
108+
109+
"""Make the API call and return the response. This is separated into it's
110+
own functin, so we can mock it easily for testing.
111+
"""
112+
def _make_request(self, opener, request):
113+
return opener.open(request)
105114

106115
"""Add variable values to the url. (e.g. /your/api/{variable_value}/call)
107116
Another example: if you have a Python reserved word, such as global,
@@ -122,7 +131,7 @@ def _(self, name):
122131
:type name: string or integer if name == version
123132
"""
124133
def __getattr__(self, name):
125-
if name == "version":
134+
if name == 'version':
126135
def get_version(*args, **kwargs):
127136
self._version = args[0]
128137
return self
@@ -141,10 +150,11 @@ def http_request(*args, **kwargs):
141150
if 'query_params' in kwargs else None
142151
opener = urllib.build_opener()
143152
request = urllib.Request(self._build_url(params), data=data)
144-
for key, value in self.request_headers.items():
145-
request.add_header(key, value)
153+
if self.request_headers:
154+
for key, value in self.request_headers.items():
155+
request.add_header(key, value)
146156
request.get_method = lambda: method
147-
self._response = opener.open(request)
157+
self._response = self._make_request(opener, request)
148158
self._set_response(self._response)
149159
self._reset()
150160
return self

python_http_client/config.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,27 @@ class Config(object):
55
"""Allow variables assigned in .env available using
66
os.environ.get('VAR_NAME')
77
8-
:param base_path: The path to your .env config file
8+
:param base_path: The path to your .env config file without a
9+
a trailing slash
910
:type base_path: string
1011
"""
1112
def __init__(self, base_path=None):
1213
if base_path:
1314
base_path = base_path
1415
else:
16+
# By default, choose the parent directory
1517
base_path = os.path.join(os.path.dirname(__file__), os.pardir)
16-
if os.path.exists(base_path + '/.env'):
17-
file = open(base_path + '/.env')
18+
# Setup the environment variables found in .env
19+
if os.path.exists('{0}/.env'.format(base_path)):
20+
file = open('{0}/.env'.format(base_path))
1821
for line in file:
1922
var = line.strip().split('=')
2023
if len(var) == 2:
2124
os.environ[var[0]] = var[1]
2225
file.close()
26+
27+
self._local_path_to_env = '{0}/.env'.format(base_path)
28+
29+
@property
30+
def local_path_to_env(self):
31+
return self._local_path_to_env

tests/profile.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,27 +120,27 @@ def run_tested_code(client, num_loops):
120120

121121
data = {'sample': 'data'}
122122
headers = {'X-Mock': 200}
123-
api_key_id = "test_url_param"
123+
api_key_id = 'test_url_param'
124124
client.api_keys._(api_key_id).put(request_body=data,
125125
request_headers=headers)
126126

127127
data = {'sample': 'data'}
128128
headers = {'X-Mock': 200}
129-
api_key_id = "test_url_param"
129+
api_key_id = 'test_url_param'
130130
client.api_keys._(api_key_id).patch(request_body=data,
131131
request_headers=headers)
132132

133133
headers = {'X-Mock': 204}
134-
api_key_id = "test_url_param"
134+
api_key_id = 'test_url_param'
135135
client.api_keys._(api_key_id).delete(request_headers=headers)
136136

137137
num_loops -= 1
138138

139139

140140
@timefunc
141141
def dynamic_version():
142-
path = os.path.abspath(os.path.dirname(__file__)) + "/.."
143-
Config(path)
142+
local_path = '{}/..'.format(os.path.abspath(os.path.dirname(__file__)))
143+
Config(local_path)
144144
api_key = os.environ.get('SENDGRID_API_KEY')
145145
request_headers = {
146146
'X-Mock': 200,
@@ -155,8 +155,8 @@ def dynamic_version():
155155

156156
@timefunc
157157
def static_version():
158-
path = os.path.abspath(os.path.dirname(__file__)) + "/.."
159-
Config(path)
158+
local_path = '{}/..'.format(os.path.abspath(os.path.dirname(__file__)))
159+
Config(local_path)
160160
api_key = os.environ.get('SENDGRID_API_KEY')
161161
request_headers = {
162162
'X-Mock': 200,
@@ -169,5 +169,4 @@ def static_version():
169169
run_tested_code(client, 10)
170170

171171
dynamic_result = dynamic_version()
172-
173172
static_result = static_version()

0 commit comments

Comments
 (0)