Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Replace wbv0 ...url_for with wbv1 [OSF-8696] #7788

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 22 additions & 11 deletions addons/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from website import settings
from addons.base import logger, serializer
from website.oauth.signals import oauth_complete
from website.util import waterbutler_url_for
from website.util import waterbutler_api_url_for

lookup = TemplateLookup(
directories=[
Expand Down Expand Up @@ -559,26 +559,37 @@ def archive_folder_name(self):
return name

def _get_fileobj_child_metadata(self, filenode, user, cookie=None, version=None):
kwargs = dict(
provider=self.config.short_name,
path=filenode.get('path', ''),
node=self.owner,

kwargs = {}
if version:
kwargs['version'] = version
if cookie:
kwargs['cookie'] = cookie
elif user:
kwargs['cookie'] = user.get_or_create_cookie()

metadata_url = waterbutler_api_url_for(
self.owner._id,
self.config.short_name,
path=filenode.get('path', '/'),
user=user,
view_only=True,
_internal=True,
**kwargs
)
if cookie:
kwargs['cookie'] = cookie
if version:
kwargs['version'] = version
metadata_url = waterbutler_url_for('metadata', _internal=True, **kwargs)

res = requests.get(metadata_url)

if res.status_code != 200:
raise HTTPError(res.status_code, data={'error': res.json()})

# TODO: better throttling?
time.sleep(1.0 / 5.0)
return res.json().get('data', [])

data = res.json().get('data', None)
if data:
return [child['attributes'] for child in data]
return []

def _get_file_tree(self, filenode=None, user=None, cookie=None, version=None):
"""
Expand Down
28 changes: 0 additions & 28 deletions api/base/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import urllib
import urlparse

import furl
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from rest_framework.exceptions import NotFound
Expand Down Expand Up @@ -126,33 +125,6 @@ def get_object_or_error(model_cls, query_or_pk, request, display_name=None):
return obj


def waterbutler_url_for(request_type, provider, path, node_id, token, obj_args=None, **query):
"""Reverse URL lookup for WaterButler routes
:param str request_type: data or metadata
:param str provider: The name of the requested provider
:param str path: The path of the requested file or folder
:param str node_id: The id of the node being accessed
:param str token: The cookie to be used or None
:param dict **query: Addition query parameters to be appended
"""
url = furl.furl(website_settings.WATERBUTLER_URL)
url.path.segments.append(request_type)

url.args.update({
'path': path,
'nid': node_id,
'provider': provider,
})

if token is not None:
url.args['cookie'] = token

if 'view_only' in obj_args:
url.args['view_only'] = obj_args['view_only']

url.args.update(query)
return url.url

def default_node_list_queryset():
return Node.objects.filter(is_deleted=False)

Expand Down
89 changes: 69 additions & 20 deletions osf_tests/test_archiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

from website import mails
from website import settings
from website.util import waterbutler_url_for
from website.util import waterbutler_api_url_for
from website.util.sanitize import strip_html
from osf.models import MetaSchema
from addons.base.models import BaseStorageAddon
Expand Down Expand Up @@ -147,6 +147,42 @@ def select_files_from_tree(file_tree):
],
}

WB_FILE_TREE = {
'attributes': {
'path': '/',
'name': '',
'kind': 'folder',
'children': [
{
'attributes': {
'path': '/1234567',
'name': 'Afile.file',
'kind': 'file',
'size': '128',
}
},
{
'attributes': {
'path': '/qwerty',
'name': 'A Folder',
'kind': 'folder',
'children': [
{
'attributes': {
'path': '/qwerty/asdfgh',
'name': 'coolphoto.png',
'kind': 'file',
'size': '256',
}
}
],
}
}
],
}
}


class MockAddon(object):

complete = True
Expand Down Expand Up @@ -360,28 +396,36 @@ def setUp(self):
self.archive_job = self.dst.archive_job

class TestStorageAddonBase(ArchiverTestCase):

RESP_MAP = {
'/': dict(data=FILE_TREE['children']),
'/1234567': dict(data=FILE_TREE['children'][0]),
'/qwerty': dict(data=FILE_TREE['children'][1]['children']),
'/qwerty/asdfgh': dict(data=FILE_TREE['children'][1]['children'][0]),
}

tree_root = WB_FILE_TREE['attributes']['children']
tree_child = tree_root[0]
tree_grandchild = tree_root[1]['attributes']['children']
tree_great_grandchild = tree_grandchild[0]

URLS = ['/', '/1234567', '/qwerty', '/qwerty/asdfgh']

def get_resp(self, url):
if '/qwerty/asdfgh' in url:
return dict(data=self.tree_great_grandchild)
if '/qwerty' in url:
return dict(data=self.tree_grandchild)
if '/1234567' in url:
return dict(data=self.tree_child)
return dict(data=self.tree_root)

@httpretty.activate
def _test__get_file_tree(self, addon_short_name):
requests_made = []
# requests_to_make = []
def callback(request, uri, headers):
path = request.querystring['path'][0]
requests_made.append(path)
return (200, headers, json.dumps(self.RESP_MAP[path]))

for path in self.RESP_MAP.keys():
url = waterbutler_url_for(
'metadata',
provider=addon_short_name,
requests_made.append(uri)
return (200, headers, json.dumps(self.get_resp(uri)))

for path in self.URLS:
url = waterbutler_api_url_for(
self.src._id,
addon_short_name,
meta=True,
path=path,
node=self.src,
user=self.user,
view_only=True,
_internal=True,
Expand All @@ -398,12 +442,17 @@ def callback(request, uri, headers):
}
file_tree = addon._get_file_tree(root, self.user)
assert_equal(FILE_TREE, file_tree)
assert_equal(requests_made, ['/', '/qwerty']) # no requests made for files
assert_equal(len(requests_made), 2)

# Makes a request for folders ('/qwerty') but not files ('/1234567', '/qwerty/asdfgh')
assert_true(any('/qwerty' in url for url in requests_made))
assert_false(any('/1234567' in url for url in requests_made))
assert_false(any('/qwerty/asdfgh' in url for url in requests_made))

def _test_addon(self, addon_short_name):
self._test__get_file_tree(addon_short_name)

@pytest.mark.skip('Unskip when figshare addon is implemented')
# @pytest.mark.skip('Unskip when figshare addon is implemented')
def test_addons(self):
# Test that each addon in settings.ADDONS_ARCHIVABLE other than wiki/forward implements the StorageAddonBase interface
for addon in [a for a in settings.ADDONS_ARCHIVABLE if a not in ['wiki', 'forward']]:
Expand Down
43 changes: 25 additions & 18 deletions tests/mock_addons.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from website import settings
from addons.base import serializer, logger
from osf.models import OSFUser, AbstractNode
from website.util import waterbutler_url_for
from website.util import waterbutler_api_url_for

from website.oauth.signals import oauth_complete

Expand Down Expand Up @@ -552,30 +552,37 @@ def archive_folder_name(self):
return name

def _get_fileobj_child_metadata(self, filenode, user, cookie=None, version=None):
kwargs = dict(
provider=self.config.short_name,
path=filenode.get('path', ''),
node=self.owner,
user=user,
view_only=True,
)
if cookie:
kwargs['cookie'] = cookie

kwargs = {}
if version:
kwargs['version'] = version
metadata_url = waterbutler_url_for(
'metadata',
_internal=True,
if cookie:
kwargs['cookie'] = cookie
elif user:
kwargs['cookie'] = user.get_or_create_cookie()

metadata_url = waterbutler_api_url_for(
self.owner._id,
self.config.short_name,
path=filenode.get('path', '/'),
user=user,
view_only=True,
_internal=True,
**kwargs
)

res = requests.get(metadata_url)

if res.status_code != 200:
raise HTTPError(res.status_code, data={
'error': res.json(),
})
raise HTTPError(res.status_code, data={'error': res.json()})

# TODO: better throttling?
sleep(1.0 / 5.0)
return res.json().get('data', [])
time.sleep(1.0 / 5.0)

data = res.json().get('data', None)
if data:
return [child['attributes'] for child in data]
return []

def _get_file_tree(self, filenode=None, user=None, cookie=None, version=None):
"""
Expand Down
21 changes: 10 additions & 11 deletions tests/test_conferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,40 +176,39 @@ def test_provision_spam(self):
assert_in('emailed', self.node.system_tags)
assert_in('spam', self.node.system_tags)

@mock.patch('website.util.waterbutler_url_for')
@mock.patch('website.util.waterbutler_api_url_for')
@mock.patch('website.conferences.utils.requests.put')
def test_upload(self, mock_put, mock_get_url):
mock_get_url.return_value = 'http://queen.com/'
self.attachment.filename = 'hammer-to-fall'
file_name = 'hammer-to-fall'
self.attachment.filename = file_name
self.attachment.content_type = 'application/json'
utils.upload_attachment(self.user, self.node, self.attachment)
mock_get_url.assert_called_with(
'upload',
self.node._id,
'osfstorage',
'/' + self.attachment.filename,
self.node,
_internal=True,
user=self.user,
cookie=self.user.get_or_create_cookie(),
name='/' + file_name
)
mock_put.assert_called_with(
mock_get_url.return_value,
data=self.content,
)

@mock.patch('website.util.waterbutler_url_for')
@mock.patch('website.util.waterbutler_api_url_for')
@mock.patch('website.conferences.utils.requests.put')
def test_upload_no_file_name(self, mock_put, mock_get_url):
mock_get_url.return_value = 'http://queen.com/'
self.attachment.filename = ''
self.attachment.content_type = 'application/json'
utils.upload_attachment(self.user, self.node, self.attachment)
mock_get_url.assert_called_with(
'upload',
self.node._id,
'osfstorage',
'/' + settings.MISSING_FILE_NAME,
self.node,
_internal=True,
user=self.user,
cookie=self.user.get_or_create_cookie(),
name='/' + settings.MISSING_FILE_NAME,
)
mock_put.assert_called_with(
mock_get_url.return_value,
Expand Down
Loading