Skip to content

Commit

Permalink
fix typings & linting
Browse files Browse the repository at this point in the history
  • Loading branch information
fmigneault committed Jul 30, 2020
1 parent e5c46d9 commit 8a49be4
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 85 deletions.
2 changes: 1 addition & 1 deletion magpie/api/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
URL_REGEX = colander.URL_REGEX


def verify_param( # noqa: E126
def verify_param( # noqa: E126 # pylint: disable=R0913,too-many-arguments
# --- verification values ---
param, # type: Any
param_compare=None, # type: Optional[Union[Any, List[Any]]]
Expand Down
2 changes: 1 addition & 1 deletion magpie/api/login/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,4 +292,4 @@ def get_providers(request): # noqa: F811
"""
return ax.valid_http(http_success=HTTPOk, detail=s.Providers_GET_OkResponseSchema.description,
content={"providers": {"internal": sorted(MAGPIE_INTERNAL_PROVIDERS.values()),
"external": sorted(MAGPIE_EXTERNAL_PROVIDERS.values()), }})
"external": sorted(MAGPIE_EXTERNAL_PROVIDERS.values()), }})
7 changes: 5 additions & 2 deletions magpie/api/management/resource/resource_formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,11 @@ def format_resource_tree(children, db_session, resources_perms_dict=None, _inter
perms = _internal_svc_res_perm_dict[service_id][resource.resource_type] # 'resource_type' is str here

fmt_res_tree[child_id] = format_resource(resource, perms)
fmt_res_tree[child_id]["children"] = format_resource_tree(new_children, db_session,
resources_perms_dict, _internal_svc_res_perm_dict)
fmt_res_tree[child_id]["children"] = format_resource_tree(
new_children, db_session,
resources_perms_dict,
_internal_svc_res_perm_dict
)

return fmt_res_tree

Expand Down
6 changes: 3 additions & 3 deletions magpie/api/management/resource/resource_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
# pylint: disable=W0611,unused-import
from pyramid.httpexceptions import HTTPException
from sqlalchemy.orm.session import Session
from magpie.typedefs import List, Str, Optional, Tuple, Type, ServiceOrResourceType # noqa: F401
from magpie.typedefs import List, Str, Optional, Tuple, Type, ServiceOrResourceType, Union # noqa: F401
from magpie.services import ServiceInterface # noqa: F401


Expand Down Expand Up @@ -121,7 +121,7 @@ def get_resource_permissions(resource, db_session):
msg_on_fail=s.UserResourcePermissions_GET_BadRequestResourceResponseSchema.description)
# directly access the service resource
if resource.root_service_id is None:
service = resource
service = resource # type: models.Service # noqa
return SERVICE_TYPE_DICT[service.type].permissions

# otherwise obtain root level service to infer sub-resource permissions
Expand All @@ -137,7 +137,7 @@ def get_resource_permissions(resource, db_session):


def get_resource_root_service(resource, db_session):
# type: (models.Resource, Session) -> Optional[models.Resource]
# type: (Union[models.Service, models.Resource], Session) -> Optional[models.Service]
"""
Recursively rewinds back through the top of the resource tree up to the top-level service-resource.
Expand Down
1 change: 0 additions & 1 deletion magpie/api/management/service/service_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import TYPE_CHECKING

import colander
from pyramid.httpexceptions import HTTPBadRequest, HTTPConflict, HTTPCreated, HTTPForbidden, HTTPInternalServerError
from ziggurat_foundations.models.services.group import GroupService
from ziggurat_foundations.models.services.resource import ResourceService
Expand Down
22 changes: 12 additions & 10 deletions magpie/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
if TYPE_CHECKING:
# pylint: disable=W0611,unused-import
from magpie.typedefs import ( # noqa: F401
Any, AnyCookiesType, CookiesOrSessionType, Dict, List, JSON, Optional, Str, Tuple, Union
Any, AnyCookiesType, CookiesOrSessionType, Dict, Iterable, List, JSON, Optional, Str, Tuple, Union
)
ConfigItem = Dict[Str, Str]
ConfigList = List[ConfigItem]
Expand Down Expand Up @@ -276,25 +276,27 @@ def _register_services(where, # type: Optional[Str]
return success, statuses


def sync_services_phoenix(services_object_dict, services_as_dicts=False):
# type: (Dict[Str, Union[models.Service, JSON]], bool) -> bool
def sync_services_phoenix(services, services_as_dicts=False):
# type: (Union[Iterable[models.Service], JSON], bool) -> bool
"""
Syncs Magpie services by pushing updates to Phoenix.
Services must be one of types specified in :py:data:`magpie.register.SERVICES_PHOENIX_ALLOWED`.
:param services_object_dict:
dictionary of ``{svc-name: models.Service}`` objects containing each service's information
:param services_as_dicts:
alternatively specify :paramref:`services_object_dict` as dict of ``{svc-name: {service-info}}``
where ``{service-info}`` is defined as::
:param services:
An iterable of :class:`models.Service` by default, or a dictionary of ``{svc-name: {<service-info>}}`` JSON
objects containing each service's information if :paramref:`services_ad_dicts` is ``True``.
where ``<service-info>`` is defined as::
{"public_url": <url>, "service_name": <name>, "service_type": <type>}
:param services_as_dicts: indicate if services must be parsed as JSON definitions.
"""
services_dict = {}
for svc in services_object_dict:
for svc in services:
if services_as_dicts:
svc_dict = services_object_dict[svc]
svc_dict = services[svc]
services_dict[svc] = {"url": svc_dict["public_url"], "title": svc_dict["service_name"],
"type": svc_dict["service_type"], "c4i": False, "public": True}
else:
Expand Down
1 change: 0 additions & 1 deletion magpie/typedefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
AnyCookiesType = Union[CookiesType, RequestsCookieJar]
AnyResponseType = Union[WebobResponse, PyramidResponse, TestResponse]
CookiesOrSessionType = Union[RequestsCookieJar, Session]
OptionalHeaderCookiesType = Tuple[Optional[AnyHeadersType], Optional[AnyCookiesType]]

AnyKey = Union[Str, int]
AnyValue = Union[Str, Number, bool, None]
Expand Down
91 changes: 47 additions & 44 deletions tests/interfaces.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import unittest
import warnings
from abc import ABCMeta, abstactmethod
from abc import ABCMeta, abstractmethod
from copy import deepcopy
from distutils.version import LooseVersion
from typing import TYPE_CHECKING
Expand Down Expand Up @@ -29,45 +29,40 @@ class Base_Magpie_TestCase(six.with_metaclass(ABCMeta, unittest.TestCase)):
"""
Base definition for all other Test Suite interfaces.
The implementers must provide :meth:`initClass` which prepares the various test parameters, session cookies and
The implementers must provide :meth:`setUpClass` which prepares the various test parameters, session cookies and
the local application or remote Magpie URL configuration to evaluate test cases on.
The implementers Test Suites must also set :attr:`__test__` to ``True`` so that tests are picked up as executable.
.. note::
Attribute attr:`__test__` is employed to avoid duplicate runs of this base class or other derived classes that
must not be considered as the *final implementer* Test Suite.
.. warning::
Do not use :meth:`setUpClass` with :py:exception:`NotImplementedError` in this class or any derived *incomplete*
class as this method still gets called by some test runners although marked with ``__test__ = False``.
The tests would be interpreted as failing in this situation (due to raised error) instead of only indicating an
abstract class definition. You are free to use it if the method is non-raising, but remember that the code will
be executed during initialization of the Test Suite even if seemingly disabled for testing.
"""
# pylint: disable=C0103,invalid-name
version = None # type: Optional[Str]
require = None # type: Optional[Str]
# parameters for setup operations, admin-level access to the app
grp = None # type: Optional[Str]
usr = None # type: Optional[Str]
pwd = None # type: Optional[Str]
require = None # type: Optional[Str]
cookies = None # type: Optional[CookiesType]
headers = None # type: Optional[HeadersType]
json_headers = None # type: Optional[HeadersType]
# parameters for testing, extracted automatically within utils.TestSetup methods
test_service_type = None # type: Optional[Str]
test_service_name = None # type: Optional[Str]
test_user = None # type: Optional[Str]
test_group = None # type: Optional[Str]
test_user_name = None # type: Optional[Str]
test_group_name = None # type: Optional[Str]

__test__ = False # won't run this as a test suite, only its derived classes that overrides to True

@classmethod
@abstactmethod
def initClass(cls):
@abstractmethod
def setUpClass(cls):
raise NotImplementedError

@classmethod
def tearDownClass(cls): # noqa: N802
def tearDownClass(cls):
pyramid.testing.tearDown()


Expand All @@ -77,16 +72,12 @@ class Interface_MagpieAPI_NoAuth(six.with_metaclass(ABCMeta, Base_Magpie_TestCas
"""
Interface class for unittests of Magpie API. Test any operation that do not require user AuthN/AuthZ.
Derived classes must implement :meth:`initClass` accordingly to generate the Magpie test application.
Derived classes must implement :meth:`setUpClass` accordingly to generate the Magpie test application.
"""

@classmethod
def initClass(cls):
raise NotImplementedError

@classmethod
def setUpClass(cls):
cls.initClass()
raise NotImplementedError

@runner.MAGPIE_TEST_LOGIN
def test_GetSession_Anonymous(self):
Expand Down Expand Up @@ -130,18 +121,30 @@ def test_NotAcceptableRequest(self):
utils.check_response_basic_info(resp, expected_code=406)

@runner.MAGPIE_TEST_USERS
@runner.MAGPIE_TEST_LOGGED
def test_RegisterDiscoverableGroup_Unauthorized(self):
"""Not logged-in user cannot update membership to group although group is discoverable."""
raise NotImplementedError # TODO
utils.warn_version(self, "User registration views not yet available.", "2.0.0", skip=True)
resp = utils.test_request(self, "GET", "/register/groups", headers=self.json_headers, expect_errors=True)
body = utils.check_response_basic_info(resp, 401)
utils.check_val_not_in("group_names", body)

@runner.MAGPIE_TEST_USERS
def test_UnregisterDiscoverableGroup_Unauthorized(self):
"""Not logged-in user cannot remove membership to group although group is discoverable."""
raise NotImplementedError # TODO
utils.warn_version(self, "User registration views not yet available.", "2.0.0", skip=True)
path = "/register/groups/random-group"
resp = utils.test_request(self, "DELETE", path, headers=self.json_headers, expect_errors=True)
utils.check_response_basic_info(resp, 401)

def test_ViewDiscoverableGroup_Unauthorized(self):
"""Not logged-in user cannot view group although group is discoverable."""
raise NotImplementedError # TODO
utils.warn_version(self, "User registration views not yet available.", "2.0.0", skip=True)
utils.TestSetup

path = "/register/groups/random-group"
resp = utils.test_request(self, "DELETE", path, headers=self.json_headers, expect_errors=True)
utils.check_response_basic_info(resp, 401)

def test_ListDiscoverableGroup_Unauthorized(self):
"""Not logged-in user cannot list group names although groups are discoverable."""
Expand All @@ -154,11 +157,11 @@ class Interface_MagpieAPI_UsersAuth(six.with_metaclass(ABCMeta, Base_Magpie_Test
"""
Interface class for unittests of Magpie API. Test any operation that require at least logged user AuthN/AuthZ.
Derived classes must implement :meth:`initClass` accordingly to generate the Magpie test application.
Derived classes must implement :meth:`setUpClass` accordingly to generate the Magpie test application.
"""

@classmethod
def initClass(cls):
def setUpClass(cls):
raise NotImplementedError

@classmethod
Expand Down Expand Up @@ -352,11 +355,11 @@ class Interface_MagpieAPI_AdminAuth(six.with_metaclass(ABCMeta, Base_Magpie_Test
Interface class for unittests of Magpie API. Test any operation that require at least 'administrator' group
AuthN/AuthZ.
Derived classes must implement :meth:`initClass` accordingly to generate the Magpie test application.
Derived classes must implement :meth:`setUpClass` accordingly to generate the Magpie test application.
"""

@classmethod
def initClass(cls):
def setUpClass(cls):
raise NotImplementedError

def tearDown(self):
Expand Down Expand Up @@ -404,7 +407,6 @@ def setup_test_values(cls):

cls.test_group_name = "magpie-unittest-dummy-group"
cls.test_user_name = "magpie-unittest-toto"
cls.test_user_group = get_constant("MAGPIE_USERS_GROUP")

def setUp(self):
self.check_requirements()
Expand Down Expand Up @@ -536,15 +538,15 @@ def test_GetCurrentUserResourcesPermissions_Queries(self):
body = utils.TestSetup.create_TestService(self, override_service_type=ServiceAPI.service_type)
test_svc_res_id = body["service"]["resource_id"]
test_res_type = Route.resource_type_name
body = utils.TestSetup.create_TestServiceResource(self, data_override={"resource_type": test_res_type})
body = utils.TestSetup.create_TestServiceResource(self, override_data={"resource_type": test_res_type})
test_parent_res_id = body["resource"]["resource_id"]
child_resource_name = self.test_resource_name + "-child"
data_override = {
override_data = {
"resource_name": child_resource_name,
"resource_type": test_res_type,
"parent_id": test_parent_res_id
}
body = utils.TestSetup.create_TestServiceResource(self, data_override)
body = utils.TestSetup.create_TestServiceResource(self, override_data)
test_child_res_id = body["resource"]["resource_id"]
anonym_usr = get_constant("MAGPIE_ANONYMOUS_USER")
anonym_grp = get_constant("MAGPIE_ANONYMOUS_GROUP")
Expand Down Expand Up @@ -617,7 +619,7 @@ def test_PostUserResourcesPermissions_Created(self):
utils.TestSetup.delete_TestServiceResource(self, override_resource_name=resource_name)

data = {"resource_name": resource_name}
body = utils.TestSetup.create_TestServiceResource(self, data_override=data)
body = utils.TestSetup.create_TestServiceResource(self, override_data=data)
test_res_id = body["resource"]["resource_id"]

# test permission creation
Expand All @@ -641,7 +643,7 @@ def test_PostUserResourcesPermissions_Conflict(self):
utils.TestSetup.delete_TestServiceResource(self, override_resource_name=resource_name)

data = {"resource_name": resource_name}
body = utils.TestSetup.create_TestServiceResource(self, data_override=data)
body = utils.TestSetup.create_TestServiceResource(self, override_data=data)
test_res_id = body["resource"]["resource_id"]

path = "/users/{usr}/resources/{res}/permissions".format(res=test_res_id, usr=self.usr)
Expand Down Expand Up @@ -978,7 +980,7 @@ def test_PostUsers_InvalidParameters(self):
"user_name": self.test_user_name,
"email": "{}@mail.com".format(self.test_user_name),
"password": self.test_user_name,
"group_name": self.test_user_group,
"group_name": self.test_group_name,
}
for code, variant in [
(400, {"user_name": ""}),
Expand Down Expand Up @@ -1214,7 +1216,8 @@ def test_PostUserGroup_conflict(self):

@runner.MAGPIE_TEST_USERS
def test_GetUserGroups(self):
utils.TestSetup.create_TestUser(self) # automatically adds user to "MAGPIE_USERS_GROUP"
users_group = get_constant("MAGPIE_USERS_GROUP")
utils.TestSetup.create_TestUser(self, override_group_name=users_group)
utils.TestSetup.create_TestGroup(self)
utils.TestSetup.assign_TestUserGroup(self)

Expand All @@ -1224,7 +1227,7 @@ def test_GetUserGroups(self):
body = utils.check_response_basic_info(resp, 200, expected_method="GET")
utils.check_val_is_in("group_names", body)
utils.check_val_type(body["group_names"], list)
expected_groups = {self.test_group_name, self.test_user_group}
expected_groups = {self.test_group_name, users_group}
if LooseVersion(self.version) >= LooseVersion("1.4.0"):
expected_groups.add(get_constant("MAGPIE_ANONYMOUS_GROUP"))
utils.check_all_equal(body["group_names"], expected_groups, any_order=True)
Expand Down Expand Up @@ -1767,12 +1770,12 @@ def test_PostServiceResources_ChildrenResource_ParentID(self):

# create the child resource under the direct resource and validate response info
child_resource_name = self.test_resource_name + "-children"
data_override = {
override_data = {
"resource_name": child_resource_name,
"resource_type": self.test_resource_type,
"parent_id": test_resource_id
}
body = utils.TestSetup.create_TestServiceResource(self, data_override)
body = utils.TestSetup.create_TestServiceResource(self, override_data)
if LooseVersion(self.version) >= LooseVersion("0.6.3"):
utils.check_val_is_in("resource", body)
utils.check_val_type(body["resource"], dict)
Expand Down Expand Up @@ -1950,11 +1953,11 @@ class Interface_MagpieUI_NoAuth(six.with_metaclass(ABCMeta, Base_Magpie_TestCase
"""
Interface class for unittests of Magpie UI. Test any operation that do not require user AuthN/AuthZ.
Derived classes must implement :meth:`initClass` accordingly to generate the Magpie test application.
Derived classes must implement :meth:`setUpClass` accordingly to generate the Magpie test application.
"""

@classmethod
def initClass(cls):
def setUpClass(cls):
raise NotImplementedError

@runner.MAGPIE_TEST_STATUS
Expand Down Expand Up @@ -2028,7 +2031,7 @@ class Interface_MagpieUI_UsersAuth(six.with_metaclass(ABCMeta, Base_Magpie_TestC
"""
Interface class for unittests of Magpie UI. Test any operation that require at least logged user AuthN/AuthZ.
Derived classes must implement :meth:`initClass` accordingly to generate the Magpie test application.
Derived classes must implement :meth:`setUpClass` accordingly to generate the Magpie test application.
"""

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -2087,11 +2090,11 @@ class Interface_MagpieUI_AdminAuth(six.with_metaclass(ABCMeta, Base_Magpie_TestC
Interface class for unittests of Magpie UI. Test any operation that require at least 'administrator' group
AuthN/AuthZ.
Derived classes must implement :meth:`initClass` accordingly to generate the Magpie test application.
Derived classes must implement :meth:`setUpClass` accordingly to generate the Magpie test application.
"""

@classmethod
def initClass(cls):
def setUpClass(cls):
raise NotImplementedError

@classmethod
Expand Down
Loading

0 comments on commit 8a49be4

Please sign in to comment.