async def test_move_file(self, provider_one, provider_two, file_stream, upload_response): # aliased for clarity src_provider, dst_provider = provider_one, provider_two src_provider.download = utils.MockCoroutine(return_value=file_stream) src_provider.intra_move = utils.MockCoroutine( return_value=(upload_response, True)) dst_provider._send_to_storage_provider = utils.MockCoroutine() src_path = WaterButlerPath('/foo', _ids=('Test', '56ab34')) dest_path = WaterButlerPath('/', _ids=('Test', )) metadata, created = await src_provider.move(dst_provider, src_path, dest_path, handle_naming=False) assert metadata is not None assert created is True src_provider.download.assert_called_once_with(WaterButlerPath('/foo')) dst_provider._send_to_storage_provider.assert_called_once_with( file_stream, WaterButlerPath('/'), rename=None, conflict='replace') src_provider.intra_move.assert_called_once_with( dst_provider, WaterButlerPath('/foo'), WaterButlerPath('/'))
def callback(monkeypatch): mock_request = test_utils.MockCoroutine( return_value=mock.Mock(status=200, read=test_utils.MockCoroutine( return_value=b'meowmeowmeow'))) monkeypatch.setattr(copy.utils, 'send_signed_request', mock_request) return mock_request
async def test_copy_but_intra_copy(self, provider_one, auth, credentials, settings_region_one): """OSFStorageProvider.copy checks to see if intra_copy can be called as an optimization. This is copied over from the `BaseProvider.copy()` implementation, and is unlikely to be called in a real-world situation. All calls to `OSFStorageProvider.copy()` have probably passed through a `can_intra_copy` check already. Nevertheless, let's test it to make sure it behaves as expected.""" # aliased for clarity src_provider = provider_one settings_region_one['nid'] = 'fake-nid' dst_provider = OSFStorageProvider(auth, credentials, settings_region_one) src_provider.can_intra_copy = mock.Mock(return_value=True) src_provider.intra_copy = utils.MockCoroutine() src_provider.download = utils.MockCoroutine() src_path = WaterButlerPath('/foo', _ids=('Test', '56ab34')) dest_path = WaterButlerPath('/', _ids=('Test', )) await src_provider.copy(dst_provider, src_path, dest_path, handle_naming=False) src_provider.can_intra_copy.assert_called_once_with( dst_provider, src_path) src_provider.intra_copy.assert_called_once_with( dst_provider, src_path, dest_path) src_provider.download.assert_not_called()
async def test_copy_cross_provider(self, monkeypatch, provider_one, provider_two): # aliased for clarity src_provider, dst_provider = provider_one, provider_two src_provider.download = utils.MockCoroutine() dst_provider.NAME = 'not-osfstorage' core_copy = utils.MockCoroutine() monkeypatch.setattr('waterbutler.core.provider.BaseProvider.copy', core_copy) src_path = WaterButlerPath('/foo', _ids=('Test', '56ab34')) dest_path = WaterButlerPath('/', _ids=('Test', )) await src_provider.copy(dst_provider, src_path, dest_path, handle_naming=False) core_copy.assert_called_once_with(dst_provider, src_path, dest_path, rename=None, conflict='replace', handle_naming=False) src_provider.download.assert_not_called()
async def test_move_folder(self, provider_one, provider_two): # aliased for clarity src_provider, dst_provider = provider_one, provider_two src_provider._folder_file_op = utils.MockCoroutine( return_value=(upload_response, True)) src_provider.delete = utils.MockCoroutine() src_path = WaterButlerPath('/foo/', _ids=('Test', '56ab34'), folder=True) dest_path = WaterButlerPath('/', _ids=('Test', ), folder=True) metadata, created = await src_provider.move(dst_provider, src_path, dest_path, handle_naming=False) assert metadata is not None assert created is True src_provider._folder_file_op.assert_called_once_with( src_provider.move, dst_provider, WaterButlerPath('/foo/'), WaterButlerPath('/'), rename=None, conflict='replace') src_provider.delete.assert_called_once_with(WaterButlerPath('/foo/'))
async def test_intra_move_folder(self, provider_and_mock, provider_and_mock2, folder_children_metadata, mock_time): src_provider, src_mock = provider_and_mock assert src_provider.can_duplicate_names() src_mock.intra_move = src_provider.intra_move dest_provider, dest_mock = provider_and_mock2 dest_mock.nid = 'abcde' dest_mock._children_metadata = utils.MockCoroutine( return_value=folder_children_metadata) dest_mock.validate_v1_path = utils.MockCoroutine( return_value=WaterButlerPath('/folder1/', _ids=('rootId', 'folder1'))) src_path = WaterButlerPath('/folder1/', _ids=['RootId', 'folder1'], folder=True) dest_path = WaterButlerPath('/folder1/', _ids=['RootId', 'folder1'], folder=True) data = json.dumps({ 'user': src_provider.auth['id'], 'source': src_path.identifier, 'destination': { 'name': dest_path.name, 'node': dest_provider.nid, 'parent': dest_path.parent.identifier } }) url, _, params = src_provider.build_signed_url( 'POST', 'https://waterbutler.io/hooks/move/', data=data) body = { 'path': '/folder1/', 'id': 'folder1', 'kind': 'folder', 'name': 'folder1' } aiohttpretty.register_json_uri('POST', url, params=params, status=201, body=body) folder_meta, created = await src_mock.intra_move( dest_mock, src_path, dest_path) assert created == False assert isinstance(folder_meta, OsfStorageFolderMetadata) assert len(folder_meta.children) == 4 dest_mock._children_metadata.assert_called_once_with( WaterButlerPath('/folder1/')) assert dest_mock.validate_v1_path.call_count == 1 src_mock._children_metadata.assert_not_called() src_mock.validate_v1_path.assert_not_called()
async def test_copy_pipes_download_to_upload(self, provider1): src_path = await provider1.validate_path('/source/path') dest_path = await provider1.validate_path('/destination/path') provider1.upload = utils.MockCoroutine(return_value='Upload return') provider1.download = utils.MockCoroutine(return_value='Download return') ret = await provider1.copy(provider1, src_path, dest_path) assert ret == 'Upload return' provider1.download.assert_called_once_with(src_path) provider1.upload.assert_called_once_with('Download return', dest_path)
async def test_intra_move_uses_intra_copy(self, provider1, monkeypatch): icopy_mock = utils.MockCoroutine() delete_mock = utils.MockCoroutine() icopy_mock.return_value = ({}, False) monkeypatch.setattr(provider1, 'intra_copy', icopy_mock) monkeypatch.setattr(provider1, 'delete', delete_mock) metadata, created = await provider1.intra_move(provider1, None, None) assert metadata == {} assert created is False assert delete_mock.called is True icopy_mock.assert_called_once_with(provider1, None, None) is True
async def test_delete_folder_contents(self, provider, file_path, folder_path, folder_children_metadata, mock_time): provider.validate_path = utils.MockCoroutine(return_value=file_path) provider.delete = utils.MockCoroutine() children_url, params = build_signed_url_without_auth(provider, 'GET', folder_path.identifier, 'children') aiohttpretty.register_json_uri('GET', children_url, params=params, status=200, body=folder_children_metadata) await provider._delete_folder_contents(folder_path) provider.delete.assert_called_with(file_path) assert provider.delete.call_count == 4
async def test_upload_fails(self, monkeypatch, provider_and_mock, file_stream, upload_response, mock_time): self.patch_tasks(monkeypatch) provider, inner_provider = provider_and_mock path = WaterButlerPath('/{}'.format(upload_response['data']['name']), _ids=('Test', upload_response['data']['id'])) url = 'https://waterbutler.io/{}/children/'.format( path.parent.identifier) aiohttpretty.register_json_uri('POST', url, status=201, body=upload_response) inner_provider.metadata = utils.MockCoroutine( return_value=utils.MockFileMetadata()) inner_provider.upload.side_effect = Exception() with pytest.raises(Exception): await provider.upload(file_stream, path) assert not os.path.isfile(FILE_PATH_PENDING + '/patched_path') inner_provider.upload.assert_called_once_with( file_stream, WaterButlerPath('/patched_path'), check_created=False, fetch_metadata=False)
async def test_intra_copy_file_overwrite(self, provider_and_mock, provider_and_mock2, mock_time): src_provider, src_mock = provider_and_mock src_mock.intra_copy = src_provider.intra_copy dest_provider, dest_mock = provider_and_mock2 dest_mock.nid = 'abcde' dest_mock.validate_v1_path = utils.MockCoroutine( return_value=WaterButlerPath('/file', _ids=('rootId', 'fileId')) ) src_path = WaterButlerPath('/folder1/', _ids=['RootId', 'folder1'], folder=True) dest_path = WaterButlerPath('/folder1/',_ids=['RootId', 'folder1'], folder=True) data=json.dumps({ 'user': src_provider.auth['id'], 'source': src_path.identifier, 'destination': { 'name': dest_path.name, 'node': dest_provider.nid, 'parent': dest_path.parent.identifier } }) url, _, params = src_provider.build_signed_url('POST', 'https://waterbutler.io/hooks/copy/', data=data) body = {'path': '/file', 'id': 'fileId', 'kind': 'file', 'name': 'file'} aiohttpretty.register_json_uri('POST', url, params=params, status=201, body=body) file_meta, created = await src_mock.intra_copy(dest_mock, src_path, dest_path) assert not created assert isinstance(file_meta, OsfStorageFileMetadata) assert file_meta.name == 'file'
def test_rename(self): metadata = utils.MockFileMetadata() self.source_provider.move = utils.MockCoroutine( return_value=(metadata, False) ) payload = self.payload() payload['rename'] = 'MyCoolFileGuys' resp = yield self.http_client.fetch( self.get_url('/ops/move'), method='POST', body=json.dumps(payload) ) assert resp.code == 200 assert json.loads(resp.body.decode()) == metadata.serialized() assert self.source_provider.move.called self.source_provider.move.assert_called_once_with( self.destination_provider, WaterButlerPath(payload['source']['path']), WaterButlerPath(payload['destination']['path']), rename='MyCoolFileGuys', conflict='replace' )
def test_no_delete_on_copy_error(self, provider1): src_path = yield from provider1.validate_path('/source/path') dest_path = yield from provider1.validate_path('/destination/path') provider1.delete = utils.MockCoroutine() provider1.copy = utils.MockCoroutine(side_effect=Exception('WHAT')) with pytest.raises(Exception) as e: yield from provider1.move(provider1, src_path, dest_path) assert e.value.args == ('WHAT', ) assert provider1.delete.called is False provider1.copy.assert_called_once_with(provider1, src_path, dest_path, handle_naming=False)
def test_calls_copy_and_delete(self, provider1): src_path = yield from provider1.validate_path('/source/path') dest_path = yield from provider1.validate_path('/destination/path') provider1.delete = utils.MockCoroutine() provider1.copy = utils.MockCoroutine(return_value=('Copy return', 'Value')) ret = yield from provider1.move(provider1, src_path, dest_path) assert ret == ('Copy return', 'Value') provider1.delete.assert_called_once_with(src_path) provider1.copy.assert_called_once_with(provider1, src_path, dest_path, handle_naming=False)
async def test_upload_keep(self, provider, file_stream, file_metadata, file_metadata_object): path = WaterButlerPath('/phile', prepend=provider.folder) renamed_path = WaterButlerPath('/phile (1)', prepend=provider.folder) path._parts[-1]._id = 'fake_id' provider.handle_name_conflict = utils.MockCoroutine( return_value=(renamed_path, True)) url = provider._webdav_url_ + renamed_path.full_path aiohttpretty.register_uri('PROPFIND', url, body=file_metadata, auto_length=True, status=207) aiohttpretty.register_uri('PUT', provider._webdav_url_ + '/my_folder/phile (1)', body=b'squares', auto_length=True, status=201) metadata, created = await provider.upload(file_stream, path, 'keep') assert created is True assert metadata.name == file_metadata_object.name assert metadata.size == file_metadata_object.size assert aiohttpretty.has_call(method='PUT', uri=url)
async def test_upload_new(self, monkeypatch, provider_and_mock, file_stream, upload_response, mock_time): self.patch_tasks(monkeypatch) path = WaterButlerPath('/newfile', _ids=('rootId', None)) url = 'https://waterbutler.io/{}/children/'.format( path.parent.identifier) aiohttpretty.register_json_uri('POST', url, status=201, body=upload_response) provider, inner_provider = provider_and_mock inner_provider.metadata = utils.MockCoroutine( return_value=utils.MockFileMetadata()) res, created = await provider.upload(file_stream, path) assert created is True assert res.name == 'newfile' assert res.extra['version'] == 8 assert res.provider == 'osfstorage' assert res.extra['downloads'] == 10 assert res.extra['checkout'] is None assert path.identifier_path == res.path inner_provider.delete.assert_called_once_with( WaterButlerPath('/uniquepath')) inner_provider.metadata.assert_called_once_with( WaterButlerPath('/' + file_stream.writers['sha256'].hexdigest)) inner_provider.upload.assert_called_once_with( file_stream, WaterButlerPath('/uniquepath'), check_created=False, fetch_metadata=False)
async def test_action_type(self, method, action, auth_type, headers, query_args, expected): handler = OsfAuthHandler() request = mock.Mock() request.method = method request.headers = headers if headers is not None else {} request.query_arguments = query_args if query_args is not None else {} request.cookies = {} kwargs = {} if action is not None: kwargs['action'] = action if auth_type is not None: kwargs['auth_type'] = auth_type handler.build_payload = mock.Mock() handler.make_request = utils.MockCoroutine( return_value={'auth': {}, 'callback_url': 'dummy'} ) await handler.get('test', 'test', request, **kwargs) handler.build_payload.asssert_called_once() args, _ = handler.build_payload.call_args assert args[0]['action'] == expected
def test_no_replace_or_existing(self, provider1): path = yield from provider1.validate_path('/test/path') provider1.exists = utils.MockCoroutine(return_value=False) handled, exists = yield from provider1.handle_name_conflict(path) assert handled is path assert exists is False
def test_download_not_found(self): self.mock_provider.download = utils.MockCoroutine( side_effect=exceptions.NotFoundError('/freddie.png')) with pytest.raises(httpclient.HTTPError) as exc: yield self.http_client.fetch( self.get_url('/file?provider=queenhub&path=/freddie.png'), ) assert exc.value.code == 404
async def test_calls_folder_op_on_dir_and_delete(self, provider1): src_path = await provider1.validate_path('/source/path/') dest_path = await provider1.validate_path('/destination/path/') provider1.delete = utils.MockCoroutine() provider1._folder_file_op = utils.MockCoroutine(return_value=('Someratheruniquevalue', 'AndThen')) data = await provider1.move(provider1, src_path, dest_path) assert data == ('Someratheruniquevalue', 'AndThen') provider1.delete.assert_called_once_with(src_path) provider1._folder_file_op.assert_called_once_with( provider1.move, provider1, src_path, dest_path.child('path', folder=True), )
async def test_handles_naming_false(self, provider1): src_path = await provider1.validate_path('/source/path') dest_path = await provider1.validate_path('/destination/path') provider1.handle_naming = utils.MockCoroutine() await provider1.move(provider1, src_path, dest_path, handle_naming=False) assert provider1.handle_naming.called is False
async def test_rename_explicit(self, provider1): dest_path = await provider1.validate_path('/test/') src_path = await provider1.validate_path('/test/name1') provider1.exists = utils.MockCoroutine(return_value=False) handled = await provider1.handle_naming(src_path, dest_path, rename='name2') assert handled.name == 'name2' assert handled.is_file is True
def test_rename_via_path(self, provider1): src_path = yield from provider1.validate_path('/test/name1') dest_path = yield from provider1.validate_path('/test/name2') provider1.exists = utils.MockCoroutine(return_value=False) handled = yield from provider1.handle_naming(src_path, dest_path) assert handled.name == 'name2' assert handled.is_file is True
async def test_replace_not_existing(self, provider1): path = await provider1.validate_path('/test/path') provider1.exists = utils.MockCoroutine(return_value=False) handled, exists = await provider1.handle_name_conflict(path, conflict='replace') assert handled is path assert str(handled) == '/test/path' assert exists is False
def test_download_accept_url_invalid(self): self.mock_provider.download = utils.MockCoroutine() with pytest.raises(httpclient.HTTPError) as exc: yield self.http_client.fetch( self.get_url('/file?provider=queenhub&path=/freddie.png&accept_url=teapot'), ) assert exc.value.code == 400 assert self.mock_provider.download.called is False
def test_replace(self, provider1): path = yield from provider1.validate_path('/test/path') provider1.exists = utils.MockCoroutine(return_value=True) handled, exists = yield from provider1.handle_name_conflict( path, conflict='replace') assert handled is path assert exists is True assert str(handled) == '/test/path'
def test_intra_makes_callback(self): self.source_provider.copy = utils.MockCoroutine( return_value=(utils.MockFileMetadata(), False)) yield self.http_client.fetch(self.get_url('/ops/copy'), method='POST', body=json.dumps(self.payload())) self.mock_send_hook.assert_called_once_with('copy', utils.MockFileMetadata())
async def test_renames_twice(self, provider1): path = await provider1.validate_path('/test/path') provider1.exists = utils.MockCoroutine(side_effect=(True, True, False)) handled, exists = await provider1.handle_name_conflict(path, conflict='keep') assert handled is path assert exists is False assert str(handled) == '/test/path (2)' assert handled.name == 'path (2)'
def test_no_problem(self, provider1): src_path = yield from provider1.validate_path('/test/path/') dest_path = yield from provider1.validate_path('/test/path/') provider1.exists = utils.MockCoroutine(return_value=False) handled = yield from provider1.handle_naming(src_path, dest_path) assert handled == src_path.child('path', folder=True) assert handled.is_dir is True assert len(handled.parts) == 4 # Includes root assert handled.name == 'path'
def test_no_problem_file(self, provider1): src_path = yield from provider1.validate_path('/test/path') dest_path = yield from provider1.validate_path('/test/path') provider1.exists = utils.MockCoroutine(return_value=False) handled = yield from provider1.handle_naming(src_path, dest_path) assert handled == dest_path # == not is assert handled.is_file is True assert len(handled.parts) == 3 # Includes root assert handled.name == 'path'