Skip to content

Commit fc481ae

Browse files
authored
Convert integration tests to use pytest instead of unittest (#313)
* convert integration test to use pytest instead of unittest
1 parent 9204111 commit fc481ae

File tree

2 files changed

+115
-144
lines changed

2 files changed

+115
-144
lines changed

test/integration/test_dropbox.py

Lines changed: 113 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
from __future__ import absolute_import, division, print_function, unicode_literals
44

55
import datetime
6-
import functools
76
import os
87
import random
98
import re
10-
import six
119
import string
1210
import sys
13-
import unittest
11+
import pytest
1412

1513
try:
1614
from io import BytesIO
@@ -41,49 +39,40 @@
4139
)
4240

4341
def _value_from_env_or_die(env_name='DROPBOX_TOKEN'):
44-
oauth2_token = os.environ.get(env_name)
45-
if oauth2_token is None:
42+
value = os.environ.get(env_name)
43+
if value is None:
4644
print('Set {} environment variable to a valid token.'.format(env_name),
4745
file=sys.stderr)
4846
sys.exit(1)
49-
return oauth2_token
50-
51-
def dbx_from_env(f):
52-
@functools.wraps(f)
53-
def wrapped(self, *args, **kwargs):
54-
oauth2_token = _value_from_env_or_die()
55-
args += (Dropbox(oauth2_token),)
56-
return f(self, *args, **kwargs)
57-
return wrapped
58-
59-
def refresh_dbx_from_env(f):
60-
@functools.wraps(f)
61-
def wrapped(self, *args, **kwargs):
62-
refresh_token = _value_from_env_or_die("DROPBOX_REFRESH_TOKEN")
63-
app_key = _value_from_env_or_die("DROPBOX_APP_KEY")
64-
app_secret = _value_from_env_or_die("DROPBOX_APP_SECRET")
65-
args += (Dropbox(oauth2_refresh_token=refresh_token,
66-
app_key=app_key, app_secret=app_secret),)
67-
return f(self, *args, **kwargs)
68-
return wrapped
69-
70-
def dbx_team_from_env(f):
71-
@functools.wraps(f)
72-
def wrapped(self, *args, **kwargs):
73-
team_oauth2_token = _value_from_env_or_die('DROPBOX_TEAM_TOKEN')
74-
args += (DropboxTeam(team_oauth2_token),)
75-
return f(self, *args, **kwargs)
76-
return wrapped
77-
78-
79-
def dbx_app_auth_from_env(f):
80-
@functools.wraps(f)
81-
def wrapped(self, *args, **kwargs):
82-
app_key = _value_from_env_or_die("DROPBOX_APP_KEY")
83-
app_secret = _value_from_env_or_die("DROPBOX_APP_SECRET")
84-
args += (Dropbox(oauth2_access_token="foo", app_key=app_key, app_secret=app_secret),)
85-
return f(self, *args, **kwargs)
86-
return wrapped
47+
return value
48+
49+
50+
@pytest.fixture()
51+
def dbx_from_env():
52+
oauth2_token = _value_from_env_or_die()
53+
return Dropbox(oauth2_token)
54+
55+
56+
@pytest.fixture()
57+
def refresh_dbx_from_env():
58+
refresh_token = _value_from_env_or_die("DROPBOX_REFRESH_TOKEN")
59+
app_key = _value_from_env_or_die("DROPBOX_APP_KEY")
60+
app_secret = _value_from_env_or_die("DROPBOX_APP_SECRET")
61+
return Dropbox(oauth2_refresh_token=refresh_token,
62+
app_key=app_key, app_secret=app_secret)
63+
64+
65+
@pytest.fixture()
66+
def dbx_team_from_env():
67+
team_oauth2_token = _value_from_env_or_die('DROPBOX_TEAM_TOKEN')
68+
return DropboxTeam(team_oauth2_token)
69+
70+
71+
@pytest.fixture()
72+
def dbx_app_auth_from_env():
73+
app_key = _value_from_env_or_die("DROPBOX_APP_KEY")
74+
app_secret = _value_from_env_or_die("DROPBOX_APP_SECRET")
75+
return Dropbox(oauth2_access_token="foo", app_key=app_key, app_secret=app_secret)
8776

8877

8978
MALFORMED_TOKEN = 'asdf'
@@ -92,188 +81,170 @@ def wrapped(self, *args, **kwargs):
9281
# Need bytes type for Python3
9382
DUMMY_PAYLOAD = string.ascii_letters.encode('ascii')
9483

95-
class TestDropbox(unittest.TestCase):
84+
85+
@pytest.mark.usefixtures("dbx_from_env", "refresh_dbx_from_env", "dbx_app_auth_from_env")
86+
class TestDropbox:
9687

9788
def test_default_oauth2_urls(self):
9889
flow_obj = DropboxOAuth2Flow('dummy_app_key', 'dummy_app_secret',
9990
'http://localhost/dummy', 'dummy_session', 'dbx-auth-csrf-token')
10091

101-
six.assertRegex(
102-
self,
103-
flow_obj._get_authorize_url('http://localhost/redirect', 'state', 'legacy'),
92+
assert re.match(
10493
r'^https://{}/oauth2/authorize\?'.format(re.escape(session.WEB_HOST)),
94+
flow_obj._get_authorize_url('http://localhost/redirect', 'state', 'legacy'),
10595
)
10696

107-
self.assertEqual(
108-
flow_obj.build_url('/oauth2/authorize'),
109-
'https://{}/oauth2/authorize'.format(session.API_HOST),
110-
)
97+
assert flow_obj.build_url(
98+
'/oauth2/authorize'
99+
) == 'https://{}/oauth2/authorize'.format(session.API_HOST)
111100

112-
self.assertEqual(
113-
flow_obj.build_url('/oauth2/authorize', host=session.WEB_HOST),
114-
'https://{}/oauth2/authorize'.format(session.WEB_HOST),
115-
)
101+
assert flow_obj.build_url(
102+
'/oauth2/authorize', host=session.WEB_HOST
103+
) == 'https://{}/oauth2/authorize'.format(session.WEB_HOST)
116104

117105
def test_bad_auth(self):
118106
# Test malformed token
119107
malformed_token_dbx = Dropbox(MALFORMED_TOKEN)
120-
with self.assertRaises(BadInputError) as cm:
108+
with pytest.raises(BadInputError) as cm:
121109
malformed_token_dbx.files_list_folder('')
122-
self.assertIn('token is malformed', cm.exception.message)
110+
assert 'token is malformed' in cm.value.message
123111

124112
# Test reasonable-looking invalid token
125113
invalid_token_dbx = Dropbox(INVALID_TOKEN)
126-
with self.assertRaises(AuthError) as cm:
114+
with pytest.raises(AuthError) as cm:
127115
invalid_token_dbx.files_list_folder('')
128-
self.assertTrue(cm.exception.error.is_invalid_access_token())
116+
assert cm.value.error.is_invalid_access_token()
129117

130-
@refresh_dbx_from_env
131-
def test_refresh(self, dbx):
132-
dbx.users_get_current_account()
118+
def test_refresh(self, refresh_dbx_from_env):
119+
refresh_dbx_from_env.users_get_current_account()
133120

134-
@dbx_app_auth_from_env
135-
def test_app_auth(self, dbx_app_auth):
136-
dbx_app_auth.check_app(query="hello world")
121+
def test_app_auth(self, dbx_app_auth_from_env):
122+
dbx_app_auth_from_env.check_app(query="hello world")
137123

138-
@refresh_dbx_from_env
139-
def test_downscope(self, dbx):
140-
dbx.users_get_current_account()
141-
dbx.refresh_access_token(scope=['files.metadata.read'])
142-
with self.assertRaises(AuthError):
124+
def test_downscope(self, refresh_dbx_from_env):
125+
refresh_dbx_from_env.users_get_current_account()
126+
refresh_dbx_from_env.refresh_access_token(scope=['files.metadata.read'])
127+
with pytest.raises(AuthError):
143128
# Should fail because downscoped to not include needed scope
144-
dbx.users_get_current_account()
129+
refresh_dbx_from_env.users_get_current_account()
145130

146-
@dbx_from_env
147-
def test_rpc(self, dbx):
148-
dbx.files_list_folder('')
131+
def test_rpc(self, dbx_from_env):
132+
dbx_from_env.files_list_folder('')
149133

150134
# Test API error
151135
random_folder_path = '/' + \
152136
''.join(random.sample(string.ascii_letters, 15))
153-
with self.assertRaises(ApiError) as cm:
154-
dbx.files_list_folder(random_folder_path)
155-
self.assertIsInstance(cm.exception.error, ListFolderError)
137+
with pytest.raises(ApiError) as cm:
138+
dbx_from_env.files_list_folder(random_folder_path)
139+
assert isinstance(cm.value.error, ListFolderError)
156140

157-
@dbx_from_env
158-
def test_upload_download(self, dbx):
141+
def test_upload_download(self, dbx_from_env):
159142
# Upload file
160143
timestamp = str(datetime.datetime.utcnow())
161144
random_filename = ''.join(random.sample(string.ascii_letters, 15))
162145
random_path = '/Test/%s/%s' % (timestamp, random_filename)
163146
test_contents = DUMMY_PAYLOAD
164-
dbx.files_upload(test_contents, random_path)
147+
dbx_from_env.files_upload(test_contents, random_path)
165148

166149
# Download file
167-
_, resp = dbx.files_download(random_path)
168-
self.assertEqual(DUMMY_PAYLOAD, resp.content)
150+
_, resp = dbx_from_env.files_download(random_path)
151+
assert DUMMY_PAYLOAD == resp.content
169152

170153
# Cleanup folder
171-
dbx.files_delete('/Test/%s' % timestamp)
154+
dbx_from_env.files_delete('/Test/%s' % timestamp)
172155

173-
@dbx_from_env
174-
def test_bad_upload_types(self, dbx):
175-
with self.assertRaises(TypeError):
176-
dbx.files_upload(BytesIO(b'test'), '/Test')
156+
def test_bad_upload_types(self, dbx_from_env):
157+
with pytest.raises(TypeError):
158+
dbx_from_env.files_upload(BytesIO(b'test'), '/Test')
177159

178-
@dbx_from_env
179-
def test_clone_when_user_linked(self, dbx):
180-
new_dbx = dbx.clone()
181-
self.assertIsNot(dbx, new_dbx)
182-
self.assertIsInstance(new_dbx, dbx.__class__)
160+
def test_clone_when_user_linked(self, dbx_from_env):
161+
new_dbx = dbx_from_env.clone()
162+
assert dbx_from_env is not new_dbx
163+
assert isinstance(new_dbx, dbx_from_env.__class__)
183164

184-
@dbx_from_env
185-
def test_with_path_root_constructor(self, dbx):
165+
def test_with_path_root_constructor(self, dbx_from_env):
186166
# Verify valid mode types
187167
for path_root in (
188168
PathRoot.home,
189169
PathRoot.root("123"),
190170
PathRoot.namespace_id("123"),
191171
):
192-
dbx_new = dbx.with_path_root(path_root)
193-
self.assertIsNot(dbx_new, dbx)
172+
dbx_new = dbx_from_env.with_path_root(path_root)
173+
assert dbx_new is not dbx_from_env
194174

195175
expected = stone_serializers.json_encode(PathRoot_validator, path_root)
196-
self.assertEqual(dbx_new._headers.get(PATH_ROOT_HEADER), expected)
176+
assert dbx_new._headers.get(PATH_ROOT_HEADER) == expected
197177

198178
# verify invalid mode raises ValueError
199-
with self.assertRaises(ValueError):
200-
dbx.with_path_root(None)
179+
with pytest.raises(ValueError):
180+
dbx_from_env.with_path_root(None)
201181

202-
@dbx_from_env
203-
def test_path_root(self, dbx):
204-
root_info = dbx.users_get_current_account().root_info
182+
def test_path_root(self, dbx_from_env):
183+
root_info = dbx_from_env.users_get_current_account().root_info
205184
root_ns = root_info.root_namespace_id
206185
home_ns = root_info.home_namespace_id
207186

208187
# verify home mode
209-
dbxpr = dbx.with_path_root(PathRoot.home)
188+
dbxpr = dbx_from_env.with_path_root(PathRoot.home)
210189
dbxpr.files_list_folder('')
211190

212191
# verify root mode
213-
dbxpr = dbx.with_path_root(PathRoot.root(root_ns))
192+
dbxpr = dbx_from_env.with_path_root(PathRoot.root(root_ns))
214193
dbxpr.files_list_folder('')
215194

216195
# verify namespace_id mode
217-
dbxpr = dbx.with_path_root(PathRoot.namespace_id(home_ns))
196+
dbxpr = dbx_from_env.with_path_root(PathRoot.namespace_id(home_ns))
218197
dbxpr.files_list_folder('')
219198

220-
@dbx_from_env
221-
def test_path_root_err(self, dbx):
199+
def test_path_root_err(self, dbx_from_env):
222200
# verify invalid namespace return is_no_permission error
223-
dbxpr = dbx.with_path_root(PathRoot.namespace_id("1234567890"))
224-
with self.assertRaises(PathRootError) as cm:
201+
dbxpr = dbx_from_env.with_path_root(PathRoot.namespace_id("1234567890"))
202+
with pytest.raises(PathRootError) as cm:
225203
dbxpr.files_list_folder('')
226-
self.assertTrue(cm.exception.error.is_no_permission())
204+
assert cm.value.error.is_no_permission()
227205

228-
dbxpr = dbx.with_path_root(PathRoot.root("1234567890"))
229-
with self.assertRaises(PathRootError) as cm:
206+
dbxpr = dbx_from_env.with_path_root(PathRoot.root("1234567890"))
207+
with pytest.raises(PathRootError) as cm:
230208
dbxpr.files_list_folder('')
231-
self.assertTrue(cm.exception.error.is_invalid_root())
209+
assert cm.value.error.is_invalid_root()
232210

233-
@dbx_from_env
234-
def test_versioned_route(self, dbx):
211+
def test_versioned_route(self, dbx_from_env):
235212
# Upload a test file
236213
path = '/test.txt'
237-
dbx.files_upload(DUMMY_PAYLOAD, path)
214+
dbx_from_env.files_upload(DUMMY_PAYLOAD, path)
238215

239216
# Delete the file with v2 route
240-
resp = dbx.files_delete_v2(path)
217+
resp = dbx_from_env.files_delete_v2(path)
241218
# Verify response type is of v2 route
242-
self.assertIsInstance(resp, DeleteResult)
219+
assert isinstance(resp, DeleteResult)
243220

244-
class TestDropboxTeam(unittest.TestCase):
245-
@dbx_team_from_env
246-
def test_team(self, dbxt):
247-
dbxt.team_groups_list()
248-
r = dbxt.team_members_list()
221+
@pytest.mark.usefixtures("dbx_team_from_env")
222+
class TestDropboxTeam:
223+
def test_team(self, dbx_team_from_env):
224+
dbx_team_from_env.team_groups_list()
225+
r = dbx_team_from_env.team_members_list()
249226
if r.members:
250227
# Only test assuming a member if there is a member
251228
team_member_id = r.members[0].profile.team_member_id
252-
dbxt.as_user(team_member_id).files_list_folder('')
229+
dbx_team_from_env.as_user(team_member_id).files_list_folder('')
253230

254-
@dbx_team_from_env
255-
def test_as_user(self, dbxt):
256-
dbx_as_user = dbxt.as_user('1')
231+
def test_as_user(self, dbx_team_from_env):
232+
dbx_as_user = dbx_team_from_env.as_user('1')
257233
path_root = PathRoot.root("123")
258234

259235
dbx_new = dbx_as_user.with_path_root(path_root)
260236

261-
self.assertIsInstance(dbx_new, Dropbox)
262-
self.assertEqual(dbx_new._headers.get(SELECT_USER_HEADER), '1')
237+
assert isinstance(dbx_new, Dropbox)
238+
assert dbx_new._headers.get(SELECT_USER_HEADER) == '1'
263239

264240
expected = stone_serializers.json_encode(PathRoot_validator, path_root)
265-
self.assertEqual(dbx_new._headers.get(PATH_ROOT_HEADER), expected)
266-
267-
@dbx_team_from_env
268-
def test_as_admin(self, dbxt):
269-
dbx_as_admin = dbxt.as_admin('1')
270-
self.assertIsInstance(dbx_as_admin, Dropbox)
241+
assert dbx_new._headers.get(PATH_ROOT_HEADER) == expected
271242

272-
@dbx_team_from_env
273-
def test_clone_when_team_linked(self, dbxt):
274-
new_dbxt = dbxt.clone()
275-
self.assertIsNot(dbxt, new_dbxt)
276-
self.assertIsInstance(new_dbxt, dbxt.__class__)
243+
def test_as_admin(self, dbx_team_from_env):
244+
dbx_as_admin = dbx_team_from_env.as_admin('1')
245+
assert isinstance(dbx_as_admin, Dropbox)
277246

278-
if __name__ == '__main__':
279-
unittest.main()
247+
def test_clone_when_team_linked(self, dbx_team_from_env):
248+
new_dbxt = dbx_team_from_env.clone()
249+
assert dbx_team_from_env is not new_dbxt
250+
assert isinstance(new_dbxt, dbx_team_from_env.__class__)

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ per-file-ignores =
1717
[testenv:test_integration]
1818

1919
commands =
20-
pytest test/integration/test_dropbox.py
20+
pytest test/integration/
2121

2222
passenv =
2323
DROPBOX_REFRESH_TOKEN
@@ -75,7 +75,7 @@ deps =
7575
[testenv:test_unit]
7676

7777
commands =
78-
pytest test/unit/test_dropbox_unit.py
78+
pytest test/unit/
7979

8080
deps =
8181
-rtest/requirements.txt

0 commit comments

Comments
 (0)