def test_long_poll_for_events_and_errors(self): client = BoxClient('my_token') longpoll_response = { 'type': 'realtime_server', 'url': 'http://2.realtime.services.box.net/subscribe?channel=12345678&stream_type=all', 'ttl': '10', 'max_retries': '10', 'retry_timeout': 610 } (flexmock(client) .should_receive('_get_long_poll_data') .and_return(longpoll_response) .times(2)) expected_get_params = { 'channel': ['12345678'], 'stream_type': 'changes', 'stream_position': 'some_stream_position', } (flexmock(requests) .should_receive('get') .with_args('http://2.realtime.services.box.net/subscribe', params=expected_get_params) .and_return(mocked_response({'message': 'foo'})) .and_return(mocked_response('some error', status_code=400)) .times(2)) with self.assertRaises(BoxClientException) as expect_exception: client.long_poll_for_events('some_stream_position', stream_type=EventFilter.CHANGES) self.assertEqual(400, expect_exception.exception.status_code) self.assertEqual('some error', expect_exception.exception.message)
def test_change_task(self): client = BoxClient("my_token") due_at = datetime.now() expected_data = {"action": "review", "due_at": str(due_at), "message": "changed" } response = {"type": "task", "id": 123, "action": "review", "message": "changed", "due_at": str(due_at) } (flexmock(requests) .should_receive('request') .with_args("put", "https://api.box.com/2.0/tasks/123", params=None, data=json.dumps(expected_data), headers=client.default_headers) .and_return(mocked_response(response))) changed = client.change_task(123, due_at, message="changed") self.assertEquals(changed, response)
def test_long_poll_for_events_ok(self): client = BoxClient('my_token') longpoll_response = { 'type': 'realtime_server', 'url': 'http://2.realtime.services.box.net/subscribe?channel=12345678&stream_type=all', 'ttl': '10', 'max_retries': '10', 'retry_timeout': 610 } (flexmock(client) .should_receive('_get_long_poll_data') .and_return(longpoll_response) .once()) expected_get_params = { 'channel': ['12345678'], 'stream_type': 'changes', 'stream_position': 'some_stream_position', } (flexmock(requests) .should_receive('get') .with_args('http://2.realtime.services.box.net/subscribe', params=expected_get_params) .and_return(mocked_response({'message': 'new_message'})) .once()) position = client.long_poll_for_events('some_stream_position', stream_type=EventFilter.CHANGES) self.assertEqual('some_stream_position', position)
def test_upload_file_with_timestamps(self): client = BoxClient("my_token") response = mocked_response({"entries": [{"id": "1"}]}) (flexmock(client).should_receive("_check_for_errors").once()) ( flexmock(requests) .should_receive("post") .with_args( "https://upload.box.com/api/2.0/files/content", { "parent_id": "666", "content_modified_at": "2007-05-04T03:02:01+00:00", "content_created_at": "2006-05-04T03:02:01+00:00", }, headers=client.default_headers, files={"hello.jpg": ("hello.jpg", FileObjMatcher("hello world"))}, ) .and_return(response) .once() ) result = client.upload_file( "hello.jpg", StringIO("hello world"), parent=666, content_created_at=datetime(2006, 5, 4, 3, 2, 1, 0, tzinfo=UTC()), content_modified_at=datetime(2007, 5, 4, 3, 2, 1, 0, tzinfo=UTC()), ) self.assertEqual({"id": "1"}, result)
def test_overwrite_file(self): client = BoxClient("my_token") (flexmock(client).should_receive("_check_for_errors").once()) expected_headers = {"If-Match": "some_tag"} expected_headers.update(client.default_headers) expected_response = mocked_response({"entries": [{"id": "1"}]}) ( flexmock(requests) .should_receive("post") .with_args( "https://upload.box.com/api/2.0/files/666/content", {"content_modified_at": "2006-05-04T03:02:01+00:00"}, headers=expected_headers, files={"file": FileObjMatcher("hello world")}, ) .and_return(expected_response) .once() ) result = client.overwrite_file( 666, StringIO("hello world"), etag="some_tag", content_modified_at=datetime(2006, 5, 4, 3, 2, 1, 0, tzinfo=UTC()), ) self.assertEqual({"id": "1"}, result)
def test_get_client_with_retry(self): client = BoxClient("my_token") ( flexmock(requests) .should_receive("request") .with_args( "get", "https://api.box.com/2.0/files/123/thumbnail.png", params={}, data=None, headers=client.default_headers, stream=True, ) .and_return( mocked_response( status_code=202, headers={"Location": "http://box.com/url_to_thumbnail", "Retry-After": "1"} ), mocked_response(StringIO("Thumbnail contents")), ) .one_by_one() ) thumbnail = client.get_thumbnail(123, max_wait=1) self.assertEqual("Thumbnail contents", thumbnail.read())
def test_update_assignment(self): client = BoxClient("my_token") response = {"type": "task_assignment", "id": 123, "message": "All good !!!", "resolution_state": "completed", "assigned_to": {"type": "user", "id": 123, "login": "******"}, "item": {"type": "task", "id": 123} } expected_data = {"resolution_state": "completed", "message": "All good !!!"} (flexmock(requests) .should_receive('request') .with_args("put", "https://api.box.com/2.0/task_assignments/123", params=None, data=json.dumps(expected_data), headers=client.default_headers) .and_return(mocked_response(response))) changed = client.update_assignment(123, "completed", "All good !!!") self.assertEquals(changed, response)
def test_add_task(self): client = BoxClient("my_token") due_at = datetime.now() expected_data = { "item": {"type": "file", "id": 123}, "action": "review", "due_at": str(due_at), "message": "test", } response = {"type": "task", "id": 123, "action": "review", "message": "test", "due_at": str(due_at)} ( flexmock(requests) .should_receive("request") .with_args( "post", "https://api.box.com/2.0/tasks", params=None, data=json.dumps(expected_data), headers=client.default_headers, ) .and_return(mocked_response(response)) ) task = client.add_task(123, due_at, message="test") self.assertEquals(task, response)
def test_long_poll_for_events_and_errors(self): client = BoxClient("my_token") longpoll_response = { "type": "realtime_server", "url": "http://2.realtime.services.box.net/subscribe?channel=12345678&stream_type=all", "ttl": "10", "max_retries": "10", "retry_timeout": 610, } (flexmock(client).should_receive("_get_long_poll_data").and_return(longpoll_response).times(2)) expected_get_params = { "channel": ["12345678"], "stream_type": "changes", "stream_position": "some_stream_position", } ( flexmock(requests) .should_receive("get") .with_args("http://2.realtime.services.box.net/subscribe", params=expected_get_params) .and_return(mocked_response({"message": "foo"})) .and_return(mocked_response("some error", status_code=400)) .times(2) ) with self.assertRaises(BoxClientException) as expect_exception: client.long_poll_for_events("some_stream_position", stream_type=EventFilter.CHANGES) self.assertEqual(400, expect_exception.exception.status_code) self.assertEqual("some error", expect_exception.exception.message)
def test_long_poll_for_events_multiple_tries(self): client = BoxClient("my_token") longpoll_response = { "type": "realtime_server", "url": "http://2.realtime.services.box.net/subscribe?channel=12345678&stream_type=all", "ttl": "10", "max_retries": "10", "retry_timeout": 610, } (flexmock(client).should_receive("_get_long_poll_data").and_return(longpoll_response).times(5)) (flexmock(client).should_receive("get_events").times(0)) expected_get_params = { "channel": ["12345678"], "stream_type": "changes", "stream_position": "some_stream_position", } ( flexmock(requests) .should_receive("get") .with_args("http://2.realtime.services.box.net/subscribe", params=expected_get_params) .and_return(mocked_response({"message": "foo"})) .and_return(mocked_response({"message": "foo"})) .and_return(mocked_response({"message": "foo"})) .and_return(mocked_response({"message": "foo"})) .and_return(mocked_response({"message": "new_message"})) .times(5) ) position = client.long_poll_for_events("some_stream_position", stream_type=EventFilter.CHANGES) self.assertEqual("some_stream_position", position)
def test_get_long_poll_data(self): client = BoxClient("my_token") expected_response = { "type": "realtime_server", "url": "http://2.realtime.services.box.net/subscribe?channel=e9de49a73f0c93a872d7&stream_type=all", "ttl": "10", "max_retries": "10", "retry_timeout": 610, } response = mocked_response({"chunk_size": 1, "entries": [expected_response]}) ( flexmock(requests) .should_receive("request") .with_args( "options", "https://api.box.com/2.0/events", headers=client.default_headers, data=None, params=None ) .and_return(response) .once() ) actual_response = client._get_long_poll_data() self.assertDictEqual(expected_response, actual_response)
def test_add_comment_to_comment(self): client = BoxClient("my_token") response = {"type": "comment", "id": 123, "item": {"id": 123, "type": "comment"}, "message": "test" } expected_data={"item": {"type": "comment", "id": 123}, "message": "test" } (flexmock(requests) .should_receive('request') .with_args("post", "https://api.box.com/2.0/comments", params=None, data=json.dumps(expected_data), headers=client.default_headers) .and_return(mocked_response(response))) comment = client.add_comment(123, "comment", "test") self.assertEquals(comment, response)
def test_add_assignment(self): client = BoxClient("my_token") response = {"type": "task_assignment", "id": 123, "assigned_to": {"type": "user", "id": 123, "login": "******"}, "item": {"type": "task", "id": 123} } expected_data = {"task": {"id": 123, "type": "task"}, "assign_to": {"id": 123, "login": "******"} } (flexmock(requests) .should_receive('request') .with_args("post", "https://api.box.com/2.0/task_assignments", params=None, data=json.dumps(expected_data), headers=client.default_headers) .and_return(mocked_response(response))) assignment = client.assign_task(123, user_id=123, login="******") self.assertEquals(assignment, response)
def test_get_thumbnail_with_params(self): client = BoxClient("my_token") # Not available ( flexmock(requests) .should_receive("request") .with_args( "get", "https://api.box.com/2.0/files/123/thumbnail.png", params={}, data=None, headers=client.default_headers, stream=True, ) .and_return(mocked_response(status_code=302)) .once() ) thumbnail = client.get_thumbnail(123) self.assertIsNone(thumbnail) # Already available ( flexmock(requests) .should_receive("request") .with_args( "get", "https://api.box.com/2.0/files/123/thumbnail.png", params={}, data=None, headers=client.default_headers, stream=True, ) .and_return(mocked_response(StringIO("Thumbnail contents"))) .once() ) thumbnail = client.get_thumbnail(123) self.assertEqual("Thumbnail contents", thumbnail.read()) # With size requirements ( flexmock(requests) .should_receive("request") .with_args( "get", "https://api.box.com/2.0/files/123/thumbnail.png", params={"min_height": 1, "max_height": 2, "min_width": 3, "max_width": 4}, data=None, headers=client.default_headers, stream=True, ) .and_return(mocked_response(StringIO("Thumbnail contents"))) .once() ) thumbnail = client.get_thumbnail(123, min_height=1, max_height=2, min_width=3, max_width=4) self.assertEqual("Thumbnail contents", thumbnail.read())
def get_folders(self, **kwargs): folder_id = kwargs.get('folder_id') if folder_id is None: return [{ 'id': '0', 'path': '/', 'addon': 'box', 'kind': 'folder', 'name': '/ (Full Box)', 'urls': { # 'folders': node.api_url_for('box_folder_list', folderId=0), 'folders': api_v2_url('nodes/{}/addons/box/folders/'.format( self.owner._id), params={'id': '0'}) } }] try: Provider(self.external_account).refresh_oauth_key() client = BoxClient(self.external_account.oauth_key) except BoxClientException: raise HTTPError(http.FORBIDDEN) try: metadata = client.get_folder(folder_id) except BoxClientException: raise HTTPError(http.NOT_FOUND) except MaxRetryError: raise HTTPError(http.BAD_REQUEST) # Raise error if folder was deleted if metadata.get('is_deleted'): raise HTTPError(http.NOT_FOUND) folder_path = '/'.join( [x['name'] for x in metadata['path_collection']['entries']] + [metadata['name']]) return [{ 'addon': 'box', 'kind': 'folder', 'id': item['id'], 'name': item['name'], 'path': os.path.join(folder_path, item['name']).replace('All Files', ''), 'urls': { 'folders': api_v2_url('nodes/{}/addons/box/folders/'.format( self.owner._id), params={'id': item['id']}) } } for item in metadata['item_collection']['entries'] if item['type'] == 'folder']
def box_oauth_finish(auth, **kwargs): """View called when the Oauth flow is completed. Adds a new BoxUserSettings record to the user and saves the user's access token and account info. """ user = auth.user node = Node.load(session.data.pop('box_auth_nid', None)) # Handle request cancellations from Box's API if request.args.get('error'): flash('Box authorization request cancelled.') if node: return redirect(node.web_url_for('node_setting')) return redirect(web_url_for('user_addons')) result = finish_auth() # If result is a redirect response, follow the redirect if isinstance(result, BaseResponse): return result client = BoxClient(CredentialsV2( result['access_token'], result['refresh_token'], settings.BOX_KEY, settings.BOX_SECRET, )) about = client.get_user_info() oauth_settings = BoxOAuthSettings.load(about['id']) if not oauth_settings: oauth_settings = BoxOAuthSettings(user_id=about['id'], username=about['name']) oauth_settings.save() oauth_settings.refresh_token = result['refresh_token'] oauth_settings.access_token = result['access_token'] oauth_settings.expires_at = datetime.utcfromtimestamp(time.time() + 3600) # Make sure user has box enabled user.add_addon('box') user.save() user_settings = user.get_addon('box') user_settings.oauth_settings = oauth_settings user_settings.save() flash('Successfully authorized Box', 'success') if node: # Automatically use newly-created auth if node.has_addon('box'): node_addon = node.get_addon('box') node_addon.set_user_auth(user_settings) node_addon.save() return redirect(node.web_url_for('node_setting')) return redirect(web_url_for('user_addons'))
def get_folders(self, **kwargs): folder_id = kwargs.get('folder_id') if folder_id is None: return [{ 'id': '0', 'path': '/', 'addon': 'box', 'kind': 'folder', 'name': '/ (Full Box)', 'urls': { # 'folders': node.api_url_for('box_folder_list', folderId=0), 'folders': api_v2_url('nodes/{}/addons/box/folders/'.format(self.owner._id), params={'id': '0'} ) } }] try: Provider(self.external_account).refresh_oauth_key() client = BoxClient(self.external_account.oauth_key) except BoxClientException: raise HTTPError(http.FORBIDDEN) try: metadata = client.get_folder(folder_id) except BoxClientException: raise HTTPError(http.NOT_FOUND) except MaxRetryError: raise HTTPError(http.BAD_REQUEST) # Raise error if folder was deleted if metadata.get('is_deleted'): raise HTTPError(http.NOT_FOUND) folder_path = '/'.join( [ x['name'] for x in metadata['path_collection']['entries'] ] + [metadata['name']] ) return [ { 'addon': 'box', 'kind': 'folder', 'id': item['id'], 'name': item['name'], 'path': os.path.join(folder_path, item['name']).replace('All Files', ''), 'urls': { 'folders': api_v2_url('nodes/{}/addons/box/folders/'.format(self.owner._id), params={'id': item['id']} ) } } for item in metadata['item_collection']['entries'] if item['type'] == 'folder' ]
def test_get_folder_iterator_zero_content(self): # setup a regular client without expecting the usual calls client = BoxClient('my_token') (flexmock(client) .should_receive('get_folder_content') .with_args(666, limit=1000) .and_return({'entries': None}) .once()) self.assertListEqual(list(client.get_folder_iterator(666)), [])
def test_get_folder_iterator(self): # setup a regular client without expecting the usual calls client = BoxClient('my_token') (flexmock(client) .should_receive('get_folder_content') .with_args(666, limit=1000) .and_return({'entries': range(10), 'total_count': 10}) .once()) self.assertSequenceEqual(list(client.get_folder_iterator(666)), range(10))
def test_get(self): client = BoxClient('my_token') expected_response = self.make_response() flexmock(requests) \ .should_receive('get') \ .with_args('https://api.box.com/2.0/foo', params={'arg': 'value'}, headers=client._headers, crap=1) \ .and_return(expected_response) \ .once() actual_response = client._get('foo', {'arg': 'value'}, crap=1) self.assertEqual(expected_response, actual_response)
def test_delete_assignment(self): client = BoxClient("my_token") (flexmock(requests) .should_receive('request') .with_args("delete", "https://api.box.com/2.0/task_assignments/123", params=None, data=None, headers=client.default_headers) .and_return(mocked_response(status_code=204))) self.assertIsNone(client.delete_assignment(123))
def test_automatic_refresh(self): credentials = CredentialsV2("access_token", "refresh_token", "client_id", "client_secret") client = BoxClient(credentials) requests_mock = flexmock(requests) # The first attempt, which is denied ( requests_mock.should_receive("request") .with_args( "get", "https://api.box.com/2.0/users/me", params=None, data=None, headers=client.default_headers ) .and_return(mocked_response(status_code=401)) .once() ) # The call to refresh the token ( requests_mock.should_receive("post") .with_args( "https://www.box.com/api/oauth2/token", { "client_id": "client_id", "client_secret": "client_secret", "refresh_token": "refresh_token", "grant_type": "refresh_token", }, ) .and_return(mocked_response({"access_token": "new_access_token", "refresh_token": "new_refresh_token"})) .once() ) # The second attempt with the new access token ( requests_mock.should_receive("request") .with_args( "get", "https://api.box.com/2.0/users/me", params=None, data=None, headers={"Authorization": "Bearer new_access_token"}, ) .and_return(mocked_response({"name": "bla"})) .once() ) result = client.get_user_info() self.assertDictEqual(result, {"name": "bla"}) self.assertEqual(credentials._access_token, "new_access_token") self.assertEqual(credentials._refresh_token, "new_refresh_token")
def test_get_folder_iterator_boundary_2(self): # setup a regular client without expecting the usual calls client = BoxClient("my_token") ( flexmock(client) .should_receive("get_folder_content") .with_args(666, limit=1000) .and_return({"entries": range(1000), "total_count": 1000}) .once() ) (flexmock(client).should_receive("get_folder_content").with_args(666, limit=1000, offset=1000).never()) self.assertSequenceEqual(list(client.get_folder_iterator(666)), range(1000))
def test_get_thumbnail_with_params(self): client = BoxClient("my_token") # Not available (flexmock(requests) .should_receive('request') .with_args("get", 'https://api.box.com/2.0/files/123/thumbnail.png', params={}, data=None, headers=client.default_headers, stream=True) .and_return(mocked_response(status_code=302)) .once()) thumbnail = client.get_thumbnail(123) self.assertIsNone(thumbnail) # Already available (flexmock(requests) .should_receive('request') .with_args("get", 'https://api.box.com/2.0/files/123/thumbnail.png', params={}, data=None, headers=client.default_headers, stream=True) .and_return(mocked_response(StringIO("Thumbnail contents"))) .once()) thumbnail = client.get_thumbnail(123) self.assertEqual('Thumbnail contents', thumbnail.read()) # With size requirements (flexmock(requests) .should_receive('request') .with_args("get", 'https://api.box.com/2.0/files/123/thumbnail.png', params={"min_height": 1, "max_height": 2, "min_width": 3, "max_width": 4}, data=None, headers=client.default_headers, stream=True) .and_return(mocked_response(StringIO("Thumbnail contents"))) .once()) thumbnail = client.get_thumbnail(123, min_height=1, max_height=2, min_width=3, max_width=4) self.assertEqual('Thumbnail contents', thumbnail.read())
def test_delete_no_headers(self): client = BoxClient('my_token') expected_headers = dict(client._headers) expected_response = self.make_response() flexmock(requests) \ .should_receive('delete') \ .with_args('https://api.box.com/2.0/foo', headers=expected_headers, crap=1) \ .and_return(expected_response) \ .once() actual_response = client._delete('foo', crap=1) self.assertEqual(expected_response, actual_response)
def test_get_task_information(self): client = BoxClient("my_token") response = {"type": "task", "id": 123} ( flexmock(requests) .should_receive("request") .with_args( "get", "https://api.box.com/2.0/tasks/123", params=None, data=None, headers=client.default_headers ) .and_return(mocked_response(response)) ) task = client.get_task_information(123) self.assertEquals(task, response)
def test_file_get_tasks(self): client = BoxClient("my_token") response = { "total_count": 0, "entries": [] } (flexmock(requests) .should_receive('request') .with_args("get", 'https://api.box.com/2.0/files/123/tasks', params=None, data=None, headers=client.default_headers) .and_return(mocked_response(response))) tasks = client.get_file_tasks(123) self.assertEquals(tasks, response)
def get_client_from_user_settings(settings_obj): """Same as get client, except its argument is a BoxUserSettingsObject.""" if settings_obj.has_auth: # fetching the access token will guarantee a refresh settings_obj.fetch_access_token() return BoxClient(settings_obj.get_credentialsv2()) raise AddonError('Box credentials for this user have expired.')
def make_client(self, method, path, params=None, data=None, headers=None, endpoint="api", result=None, **kwargs): """ Makes a new test client """ client = BoxClient('my_token') (flexmock(client) .should_receive('_check_for_errors') .once()) if headers: headers = dict(headers) headers.update(client.default_headers) else: headers = client.default_headers if isinstance(data, dict): data = json.dumps(data) (flexmock(requests) .should_receive('request') .with_args(method, 'https://%s.box.com/2.0/%s' % (endpoint, path), params=params, data=data, headers=headers, **kwargs) .and_return(mocked_response(result)) .once()) return client
def test_post_dict(self): client = BoxClient('my_token') expected_data = {'arg': 'value'} expected_response = self.make_response() flexmock(requests) \ .should_receive('post') \ .with_args('https://api.box.com/2.0/foo', CallableMatcher(lambda x: json.loads(x) == expected_data), headers=client._headers, crap=1) \ .and_return(expected_response) \ .once() actual_response = client._post('foo', expected_data, crap=1) self.assertEqual(expected_response, actual_response)
def test_get_folder_iterator(self): # setup a regular client without expecting the usual calls client = BoxClient('my_token') flexmock(client) \ .should_receive('get_folder_content') \ .with_args(666, count=1000) \ .and_return({'entries': range(10)}) \ .once() flexmock(client) \ .should_receive('get_folder_content') \ .with_args(666, count=1000, offset=1000) \ .and_return({'entries': None}) \ .once() self.assertListEqual(list(client.get_folder_iterator(666)), list(range(10)))
def test_put_data(self): client = BoxClient('my_token') expected_data = 'mooooo' expected_response = self.make_response() flexmock(requests) \ .should_receive('put') \ .with_args('https://api.box.com/2.0/foo', expected_data, headers=client._headers, crap=1) \ .and_return(expected_response) \ .once() actual_response = client._put('foo', expected_data, crap=1) self.assertEqual(expected_response, actual_response)
def test_automatic_refresh(self): credentials = CredentialsV2("access_token", "refresh_token", "client_id", "client_secret") client = BoxClient(credentials) requests_mock = flexmock(requests) # The first attempt, which is denied (requests_mock .should_receive('request') .with_args("get", 'https://api.box.com/2.0/users/me', params=None, data=None, headers=client.default_headers) .and_return(mocked_response(status_code=401)) .once()) # The call to refresh the token (requests_mock .should_receive('post') .with_args('https://www.box.com/api/oauth2/token', { 'client_id': 'client_id', 'client_secret': 'client_secret', 'refresh_token': 'refresh_token', 'grant_type': 'refresh_token', }) .and_return(mocked_response({"access_token": "new_access_token", "refresh_token": "new_refresh_token"}))\ .once()) # The second attempt with the new access token (requests_mock .should_receive('request') .with_args("get", 'https://api.box.com/2.0/users/me', params=None, data=None, headers={"Authorization": "Bearer new_access_token"}) .and_return(mocked_response({'name': 'bla'})) .once()) result = client.get_user_info() self.assertDictEqual(result, {'name': 'bla'}) self.assertEqual(credentials._access_token, "new_access_token") self.assertEqual(credentials._refresh_token, "new_refresh_token")
def test_get_thumbnail(self): client = BoxClient("my_token") # Delayed without wait allowed (flexmock(requests) .should_receive('request') .with_args("get", 'https://api.box.com/2.0/files/123/thumbnail.png', params={}, data=None, headers=client.default_headers, stream=True) .and_return(mocked_response(status_code=202, headers={"Location": "http://box.com", "Retry-After": "5"})) .once()) thumbnail = client.get_thumbnail(123) self.assertIsNone(thumbnail)
def test_automatic_refresh(self): credentials = CredentialsV2("access_token", "refresh_token", "client_id", "client_secret") client = BoxClient(credentials) requests_mock = flexmock(requests) # The first attempt, which is denied requests_mock \ .should_receive('request') \ .with_args("get", 'https://api.box.com/2.0/users/me', params=None, data=None, headers=client.default_headers) \ .and_return(mocked_response(status_code=401)) \ .once() # The call to refresh the token requests_mock \ .should_receive('post')\ .with_args('https://www.box.com/api/oauth2/token', { 'client_id': 'client_id', 'client_secret': 'client_secret', 'refresh_token': 'refresh_token', 'grant_type': 'refresh_token', })\ .and_return(mocked_response({"access_token": "new_access_token", "refresh_token": "new_refresh_token"}))\ .once() # The second attempt with the new access token requests_mock \ .should_receive('request') \ .with_args("get", 'https://api.box.com/2.0/users/me', params=None, data=None, headers={"Authorization": "Bearer new_access_token"}) \ .and_return(mocked_response({'name': 'bla'})) \ .once() result = client.get_user_info() self.assertDictEqual(result, {'name': 'bla'}) self.assertEqual(credentials._access_token, "new_access_token") self.assertEqual(credentials._refresh_token, "new_refresh_token")
def test_get_assignment_information(self): client = BoxClient("my_token") response = {"type": "task_assignment", "id": 123 } (flexmock(requests) .should_receive('request') .with_args("get", "https://api.box.com/2.0/task_assignments/123", params=None, data=None, headers=client.default_headers) .and_return(mocked_response(response))) assignment = client.get_assignment(123) self.assertEquals(assignment, response)
def test_upload_file_with_parent_as_dict(self): client = BoxClient('my_token') (flexmock(client) .should_receive('_check_for_errors') .once()) response = mocked_response({'entries': [{'id': '1'}]}) (flexmock(requests) .should_receive('post') .with_args('https://upload.box.com/api/2.0/files/content', {'parent_id': '666'}, headers=client.default_headers, files={'hello.jpg': ('hello.jpg', FileObjMatcher('hello world'))}) .and_return(response) .once()) result = client.upload_file('hello.jpg', StringIO('hello world'), parent={'id': 666}) self.assertEqual({'id': '1'}, result)
def _update_folder_data(self): if self.folder_id is None: return None if not self._folder_data: try: Box(self.external_account).refresh_oauth_key() client = BoxClient(self.external_account.oauth_key) self._folder_data = client.get_folder(self.folder_id) except BoxClientException: return self.folder_name = self._folder_data['name'] self.folder_path = '/'.join( [x['name'] for x in self._folder_data['path_collection']['entries']] + [self._folder_data['name']] ) self.save()
def handle_callback(self, response): """View called when the Oauth flow is completed. Adds a new BoxUserSettings record to the user and saves the user's access token and account info. """ client = BoxClient(CredentialsV2( response['access_token'], response['refresh_token'], settings.BOX_KEY, settings.BOX_SECRET, )) about = client.get_user_info() return { 'provider_id': about['id'], 'display_name': about['name'], 'profile_url': 'https://app.box.com/profile/{0}'.format(about['id']) }
def test_get_client_with_retry(self): client = BoxClient("my_token") (flexmock(requests) .should_receive('request') .with_args("get", 'https://api.box.com/2.0/files/123/thumbnail.png', params={}, data=None, headers=client.default_headers, stream=True) .and_return(mocked_response(status_code=202, headers={"Location": "http://box.com/url_to_thumbnail", "Retry-After": "1"}), mocked_response(StringIO("Thumbnail contents"))) .one_by_one()) thumbnail = client.get_thumbnail(123, max_wait=1) self.assertEqual('Thumbnail contents', thumbnail.read())
def test_change_comment(self): client = BoxClient("my_token") response = {"type": "comment", "id": 123, "message": "new_message" } (flexmock(requests) .should_receive('request') .with_args("put", "https://api.box.com/2.0/comments/123", params=None, data=json.dumps({"message": "new_message"}), headers=client.default_headers) .and_return(mocked_response(response))) modified = client.change_comment(123, "new_message") self.assertEquals(modified, response)
def _folder_data(self, folder_id): # Split out from set_folder for ease of testing, due to # outgoing requests. Should only be called by set_folder try: Provider(self.external_account).refresh_oauth_key(force=True) except InvalidGrantError: raise exceptions.InvalidAuthError() try: client = BoxClient(self.external_account.oauth_key) folder_data = client.get_folder(self.folder_id) except BoxClientException: raise exceptions.InvalidFolderError() folder_name = folder_data['name'].replace('All Files', '') or '/ (Full Box)' folder_path = '/'.join( [x['name'] for x in folder_data['path_collection']['entries'] if x['name']] + [folder_data['name']] ).replace('All Files', '') or '/' return folder_name, folder_path
def test_init_with_string(self): (flexmock(CredentialsV2) .should_receive('__init__') .with_args('my_token') .once()) (flexmock(CredentialsV2) .should_receive('headers') .and_return({'Authorization': 'peanuts'})) client = BoxClient('my_token') self.assertDictEqual(client.default_headers, {'Authorization': 'peanuts'})
def test_get_path_of_file(self): metadata = { "name": "hello.jpg", "path_collection": { "total_count": 2, "entries": [ { "type": "folder", "id": "0", "name": "All Files" }, { "type": "folder", "id": "11446498", "sequence_id": "1", "etag": "1", "name": "Pictures" } ] } } self.assertEqual('/Pictures/hello.jpg', BoxClient.get_path_of_file(metadata)) metadata = { "name": "hello.jpg", "path_collection": { "total_count": 2, "entries": [ { "type": "folder", "id": "0", "name": "All Files" }, ] } } self.assertEqual('/hello.jpg', BoxClient.get_path_of_file(metadata))
def test_overwrite_file(self): client = BoxClient('my_token') (flexmock(client) .should_receive('_check_for_errors') .once()) expected_headers = { 'If-Match': 'some_tag' } expected_headers.update(client.default_headers) expected_response = mocked_response({'entries': [{'id': '1'}]}) (flexmock(requests) .should_receive('post') .with_args('https://upload.box.com/api/2.0/files/666/content', {'content_modified_at': '2006-05-04T03:02:01+00:00'}, headers=expected_headers, files={'file': FileObjMatcher('hello world')}) .and_return(expected_response) .once()) result = client.overwrite_file(666, StringIO('hello world'), etag='some_tag', content_modified_at=datetime(2006, 5, 4, 3, 2, 1, 0, tzinfo=UTC()),) self.assertEqual({'id': '1'}, result)
def test_get_long_poll_data(self): client = BoxClient('my_token') expected_response = { 'type': 'realtime_server', 'url': 'http://2.realtime.services.box.net/subscribe?channel=e9de49a73f0c93a872d7&stream_type=all', 'ttl': '10', 'max_retries': '10', 'retry_timeout': 610 } response = mocked_response({ 'chunk_size': 1, 'entries': [expected_response], }) (flexmock(requests) .should_receive('request') .with_args('options', 'https://api.box.com/2.0/events', headers=client.default_headers, data=None, params=None) .and_return(response) .once()) actual_response = client._get_long_poll_data() self.assertDictEqual(expected_response, actual_response)
def test_upload_file_with_timestamps(self): client = BoxClient('my_token') response = mocked_response({'entries': [{'id': '1'}]}) (flexmock(client) .should_receive('_check_for_errors') .once()) (flexmock(requests) .should_receive('post') .with_args('https://upload.box.com/api/2.0/files/content', { 'parent_id': '666', 'content_modified_at': '2007-05-04T03:02:01+00:00', 'content_created_at': '2006-05-04T03:02:01+00:00' }, headers=client.default_headers, files={'hello.jpg': ('hello.jpg', FileObjMatcher('hello world'))}) .and_return(response) .once()) result = client.upload_file('hello.jpg', StringIO('hello world'), parent=666, content_created_at=datetime(2006, 5, 4, 3, 2, 1, 0, tzinfo=UTC()), content_modified_at=datetime(2007, 5, 4, 3, 2, 1, 0, tzinfo=UTC())) self.assertEqual({'id': '1'}, result)
from box import BoxClient from StringIO import StringIO code = 'h1J9HeATdM4DHKVHZDjZOH3J9ALfCuza' #response= {u'access_token': u'XnpOFtKpn2JUmAOPwKtUyzunZ0mOQAJt', u'restricted_to': [], u'expires_in': 4072, u'refresh_token': u'7PNqFf1Bmv6uM0zkoTxnFh3UOqYs2qIoLvGe04hlhDv76fDqI4n4JqRo0V8R53NY', u'token_type': u'bearer'} #response= {u'access_token': u'VVeRMPOXltFoSWAckvADXTwQyrZsc906', u'restricted_to': [], u'token_type': u'bearer', u'expires_in': 4040, u'refresh_token': u'y5KyiuQstgWdEZsYifALo13EH5x7j5HGxBVlXOnIy6kfeKHSLsMTyA1MC4a5zfdP'} response = { u'access_token': u'rDMonxdCPfhJMAGU7qIA1QPEZf0tlnS8', u'restricted_to': [], u'token_type': u'bearer', u'expires_in': 3722, u'refresh_token': u'pCGF1OO4zsEGoAjXeAftqMLin250LeXqwpcL0caTcvGcmVy3TJq3Twxqo5SrSxf6' } client = BoxClient(response['access_token']) metadata = client.upload_file('fuckyou.txt', StringIO('hello world')) print metadata '''{u'shared_link': None, u'sha1': u'2aae6c35c94fcfb415dbe95f408b9ce91ee846ed', u'modified_by': {u'login': u'*****@*****.**', u'type': u'user', u'id': u'216264056', u'name': u'Siddhanth Gupta'}, u'name': u'fuckyou.txt', u'parent': {u'sequence_id': None, u'etag': None, u'type': u'folder', u'id': u'0', u'name': u'All Files'}, u'purged_at': None, u'trashed_at': None, u'created_at': u'2014-06-28T13:56:35-07:00', u'modified_at': u'2014-06-28T13:56:35-07:00', u'item_status': u'active', u'created_by': {u'login': u'*****@*****.**', u'type': u'user', u'id': u'216264056', u'name': u'Siddhanth Gupta'}, u'content_modified_at': u'2014-06-28T13:56:35-07:00', u'sequence_id': u'0', u'etag': u'0', u'owned_by': {u'login': u'*****@*****.**', u'type': u'user', u'id': u'216264056', u'name': u'Siddhanth Gupta'}, u'path_collection': {u'total_count': 1, u'entries': [{u'sequence_id': None, u'etag': None, u'type': u'folder', u'id': u'0', u'name': u'All Files'}]}, u'size': 11, u'type': u'file', u'id': u'18532645558', u'content_created_at': u'2014-06-28T13:56:35-07:00', u'description': u''} '''
def test_handle_error(self): client = BoxClient('my_token') self.assertIsNone(client._check_for_errors(mocked_response())) with self.assertRaises(ItemAlreadyExists) as expected_exception: client._check_for_errors(mocked_response('something terrible', status_code=CONFLICT)) self.assertEqual(CONFLICT, expected_exception.exception.status_code) self.assertEqual('something terrible', expected_exception.exception.message) with self.assertRaises(ItemDoesNotExist) as expected_exception: client._check_for_errors(mocked_response('something terrible', status_code=NOT_FOUND)) self.assertEqual(NOT_FOUND, expected_exception.exception.status_code) self.assertEqual('something terrible', expected_exception.exception.message) with self.assertRaises(PreconditionFailed) as expected_exception: client._check_for_errors(mocked_response('something terrible', status_code=PRECONDITION_FAILED)) self.assertEqual(PRECONDITION_FAILED, expected_exception.exception.status_code) self.assertEqual('something terrible', expected_exception.exception.message) with self.assertRaises(BoxAccountUnauthorized) as expected_exception: client._check_for_errors(mocked_response('something terrible', status_code=UNAUTHORIZED)) self.assertEqual(UNAUTHORIZED, expected_exception.exception.status_code) self.assertEqual('something terrible', expected_exception.exception.message) # unknown code with self.assertRaises(BoxClientException) as expected_exception: client._check_for_errors(mocked_response('something terrible', status_code=599)) self.assertEqual(599, expected_exception.exception.status_code) self.assertEqual('something terrible', expected_exception.exception.message)