mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
There was an existing library dataset permission API and one proposed for HDAs in #6461. This tries to reconcile the two approaches and move toward managers. - Proper treatment of "master_api_key" throughout the manager layers related to this. - Use PUT instead of POST, since that is more appropriate for updates I believe. - Use a similar URL pattern for library datasets, history contents, and dataset APIs. - Generalize the dataset API to allow HDA or LDDA inputs (the proposal for the new API in #6461 added an HDA-only option to the dataset API - this isn't how that API layer is meant to be used I believe). - Add an HDA only endpoint in the history contents API for this functionality to mirror the library dataset API. - Use consistent and backward compatible payload parsing for these endpoints. - Use consistent serialization for the result of these changes. - Generalize the HDA variant of this to allow different actions - such as make public and make private that were available in the library dataset variant. - Test cases for the new API endpoints, the roles API, tests for permissions during collection creation and running tools with both dataset and collection inputs.
140 lines
4.6 KiB
Python
140 lines
4.6 KiB
Python
from contextlib import contextmanager
|
|
|
|
from six.moves.urllib.parse import urlencode
|
|
|
|
from .api_asserts import (
|
|
assert_error_code_is,
|
|
assert_has_keys,
|
|
assert_not_has_keys,
|
|
assert_status_code_is,
|
|
)
|
|
from .api_util import (
|
|
ADMIN_TEST_USER,
|
|
get_master_api_key,
|
|
get_user_api_key,
|
|
OTHER_USER,
|
|
TEST_USER,
|
|
)
|
|
from .interactor import TestCaseGalaxyInteractor as BaseInteractor
|
|
from .testcase import FunctionalTestCase
|
|
|
|
|
|
class UsesApiTestCaseMixin:
|
|
|
|
def _api_url(self, path, params=None, use_key=None, use_admin_key=None):
|
|
if not params:
|
|
params = {}
|
|
url = "%s/api/%s" % (self.url, path)
|
|
if use_key:
|
|
params["key"] = self.galaxy_interactor.api_key
|
|
if use_admin_key:
|
|
params["key"] = self.galaxy_interactor.master_api_key
|
|
query = urlencode(params)
|
|
if query:
|
|
url = "%s?%s" % (url, query)
|
|
return url
|
|
|
|
def _setup_interactor(self):
|
|
self.user_api_key = get_user_api_key()
|
|
self.master_api_key = get_master_api_key()
|
|
self.galaxy_interactor = ApiTestInteractor(self)
|
|
|
|
def _setup_user(self, email, password=None):
|
|
self.galaxy_interactor.ensure_user_with_email(email, password=password)
|
|
users = self._get("users", admin=True).json()
|
|
user = [user for user in users if user["email"] == email][0]
|
|
return user
|
|
|
|
def _setup_user_get_key(self, email):
|
|
self.galaxy_interactor.ensure_user_with_email(email)
|
|
users = self._get("users", admin=True).json()
|
|
user = [user for user in users if user["email"] == email][0]
|
|
return self._post("users/%s/api_key" % user["id"], admin=True).json()
|
|
|
|
@contextmanager
|
|
def _different_user(self, email=OTHER_USER):
|
|
""" Use in test cases to switch get/post operations to act as new user,
|
|
|
|
with self._different_user( "other_user@bx.psu.edu" ):
|
|
self._get( "histories" ) # Gets other_user@bx.psu.edu histories.
|
|
"""
|
|
original_api_key = self.user_api_key
|
|
original_interactor_key = self.galaxy_interactor.api_key
|
|
new_key = self._setup_user_get_key(email)
|
|
try:
|
|
self.user_api_key = new_key
|
|
self.galaxy_interactor.api_key = new_key
|
|
yield
|
|
finally:
|
|
self.user_api_key = original_api_key
|
|
self.galaxy_interactor.api_key = original_interactor_key
|
|
|
|
def _get(self, *args, **kwds):
|
|
return self.galaxy_interactor.get(*args, **kwds)
|
|
|
|
def _post(self, *args, **kwds):
|
|
return self.galaxy_interactor.post(*args, **kwds)
|
|
|
|
def _delete(self, *args, **kwds):
|
|
return self.galaxy_interactor.delete(*args, **kwds)
|
|
|
|
def _put(self, *args, **kwds):
|
|
return self.galaxy_interactor.put(*args, **kwds)
|
|
|
|
def _patch(self, *args, **kwds):
|
|
return self.galaxy_interactor.patch(*args, **kwds)
|
|
|
|
def _assert_status_code_is(self, response, expected_status_code):
|
|
assert_status_code_is(response, expected_status_code)
|
|
|
|
def _assert_has_keys(self, response, *keys):
|
|
assert_has_keys(response, *keys)
|
|
|
|
def _assert_not_has_keys(self, response, *keys):
|
|
assert_not_has_keys(response, *keys)
|
|
|
|
def _assert_error_code_is(self, response, error_code):
|
|
assert_error_code_is(response, error_code)
|
|
|
|
def _random_key(self): # Used for invalid request testing...
|
|
return "1234567890123456"
|
|
|
|
_assert_has_key = _assert_has_keys
|
|
|
|
|
|
class ApiTestCase(FunctionalTestCase, UsesApiTestCaseMixin):
|
|
|
|
def setUp(self):
|
|
super(ApiTestCase, self).setUp()
|
|
self._setup_interactor()
|
|
|
|
|
|
class ApiTestInteractor(BaseInteractor):
|
|
""" Specialized variant of the API interactor (originally developed for
|
|
tool functional tests) for testing the API generally.
|
|
"""
|
|
|
|
def __init__(self, test_case):
|
|
admin = getattr(test_case, "require_admin_user", False)
|
|
test_user = TEST_USER if not admin else ADMIN_TEST_USER
|
|
super(ApiTestInteractor, self).__init__(test_case, test_user=test_user)
|
|
|
|
# This variant the lower level get and post methods are meant to be used
|
|
# directly to test API - instead of relying on higher-level constructs for
|
|
# specific pieces of the API (the way it is done with the variant for tool)
|
|
# testing.
|
|
def get(self, *args, **kwds):
|
|
return self._get(*args, **kwds)
|
|
|
|
def post(self, *args, **kwds):
|
|
return self._post(*args, **kwds)
|
|
|
|
def delete(self, *args, **kwds):
|
|
return self._delete(*args, **kwds)
|
|
|
|
def patch(self, *args, **kwds):
|
|
return self._patch(*args, **kwds)
|
|
|
|
def put(self, *args, **kwds):
|
|
return self._put(*args, **kwds)
|