33from __future__ import absolute_import , division , print_function , unicode_literals
44
55import datetime
6- import functools
76import os
87import random
98import re
10- import six
119import string
1210import sys
13- import unittest
11+ import pytest
1412
1513try :
1614 from io import BytesIO
4139)
4240
4341def _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
8978MALFORMED_TOKEN = 'asdf'
@@ -92,188 +81,170 @@ def wrapped(self, *args, **kwargs):
9281# Need bytes type for Python3
9382DUMMY_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__ )
0 commit comments