diff --git a/CHANGELOG.md b/CHANGELOG.md index 46a4379e..f9bea6fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- #[25](https://github.com/braincube-io/python-connector/issues/25): support `{braincube-name}` as a placeholder in `braincube_base_url` configuration. + ## [2.4.1 - 2021-04-22](https://github.com/braincube-io/python-connector/compare/2.4.0...2.4.1) ### Fixed diff --git a/braincube_connector/bases/base_entity.py b/braincube_connector/bases/base_entity.py index 4149c47e..d7239892 100644 --- a/braincube_connector/bases/base_entity.py +++ b/braincube_connector/bases/base_entity.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from braincube_connector import client, parameters +from braincube_connector import client, parameters, constants from braincube_connector.bases import base NAME = "name" @@ -12,7 +12,15 @@ class BaseEntity(base.Base): """Basics components of an entity requested by the connector.""" - def __init__(self, bcid: str, name: str, metadata: Dict[str, Any], path: str = ""): + def __init__( + self, + bcid: str, + name: str, + metadata: Dict[str, Any], + path: str = constants.EMPTY_STRING, + braincube_name: str = constants.EMPTY_STRING, + parent_entity: Optional["BaseEntity"] = None, + ): """Initialize BaseEntity. Args: @@ -20,8 +28,11 @@ def __init__(self, bcid: str, name: str, metadata: Dict[str, Any], path: str = " name: Usual name of the object. metadata: Raw metadata associated to the object. path: Path of the entity on the server. + braincube_name: name of the braincube linked to this entity, + useful if you use a placeholder in your config. + parent_entity: parent of this entity, used to retrieve the braincube name if needed. """ - self.initialize(bcid, name, metadata, path) + self.initialize(bcid, name, metadata, path, braincube_name, parent_entity) def __repr__(self) -> str: """Produce the a detailed description of the BaseEntity object. @@ -33,12 +44,13 @@ def __repr__(self) -> str: return "<{self_str} at {addr}>".format(self_str=description, addr=hex(id(self))) @classmethod - def create_from_json(cls, json_data: Dict[str, str], entity_path: str, **kwargs) -> Any: + def create_from_json(cls, json_data: Dict[str, str], entity_path: str, caller, **kwargs) -> Any: """Create an entity from a raw json. Args: json_data: Json dictionary obtained from a request to the webservice. entity_path: Path of the entity on the webservice. + caller: class used to call this method, useful to indicate which is the parent entity. **kwargs: Additional keyword argument to pass to an object initialization. Returns: @@ -51,36 +63,59 @@ def create_from_json(cls, json_data: Dict[str, str], entity_path: str, **kwargs) json_data[cls.get_parameter_key(NAME)], json_data, entity_path, + parent_entity=caller, **kwargs, ) return entity @classmethod - def create_singleton_from_path(cls, request_path: str, entity_path: str, **kwargs) -> Any: + def create_singleton_from_path( + cls, + request_path: str, + entity_path: str, + caller, + braincube_name: str = constants.EMPTY_STRING, + **kwargs, + ) -> Any: """Create an entity from a request path. Args: request_path: Webservice path to request. entity_path: Path of the entity on the webservice. + caller: class used to call this method, useful to indicate which is the parent entity. + braincube_name: name of the braincube linked to this entity, + useful if you use a placeholder in your config. **kwargs: Additional keyword argument to pass to an object initialization. Returns: The created entity. """ - json_data = client.request_ws(request_path.format(webservice="braincube")) - return cls.create_from_json(json_data, entity_path, **kwargs) + json_data = client.request_ws( + request_path.format(webservice="braincube"), braincube_name=braincube_name + ) + return cls.create_from_json(json_data, entity_path, caller, **kwargs) @classmethod def create_collection_from_path( - cls, request_path: str, entity_path: str, page: int = -1, page_size: int = -1, **kwargs, + cls, + request_path: str, + entity_path: str, + caller, + page: int = -1, + page_size: int = -1, + braincube_name: str = constants.EMPTY_STRING, + **kwargs, ) -> List[Any]: """Create many memory_base from a request path. Args: request_path: Webservice path to request. entity_path: Path of the entity on the webservice. + caller: class used to call this method, useful to indicate which is the parent entity. page: Index of page to return, all pages are return if page=-1 page_size: Number of memory_base per page. + braincube_name: name of the braincube linked to this entity, + useful if you use a placeholder in your config. **kwargs: Additional keyword argument to pass to an object initialization. Returns: @@ -95,10 +130,12 @@ def create_collection_from_path( json_data = client.request_ws( "{path}?offset={offset}&size={size}".format( path=request_path.format(webservice="braincube"), offset=offset, size=page_size, - ) + ), + braincube_name=braincube_name, ) new_entities = [ - cls.create_from_json(elmt, entity_path, **kwargs) for elmt in json_data["items"] + cls.create_from_json(elmt, entity_path, caller, **kwargs) + for elmt in json_data["items"] ] entity_list += new_entities if not new_entities or page > -1: @@ -123,7 +160,15 @@ def get_bcid(self) -> str: """ return self._bcid - def initialize(self, bcid: str, name: str, metadata: Dict[str, Any], path: str = ""): + def initialize( + self, + bcid: str, + name: str, + metadata: Dict[str, Any], + path: str = constants.EMPTY_STRING, + braincube_name: str = constants.EMPTY_STRING, + parent_entity: Optional["BaseEntity"] = None, + ): """Initialize BaseEntity. Args: @@ -131,6 +176,9 @@ def initialize(self, bcid: str, name: str, metadata: Dict[str, Any], path: str = name: Usual name of the object. metadata: Raw metadata associated to the object. path: Path of the entity on the server. + braincube_name: name of the braincube linked to this entity, + useful if you use a placeholder in your config. + parent_entity: parent of this entity, used to retrieve the braincube name if needed. """ self._bcid = bcid self._name = name @@ -138,6 +186,8 @@ def initialize(self, bcid: str, name: str, metadata: Dict[str, Any], path: str = if "{bcid}" in path: path = path.replace("{bcid}", str(self._bcid)) self._path = path + self._braincube_name = braincube_name + self._parent_entity = parent_entity @classmethod def get_parameter_key(cls, key) -> str: diff --git a/braincube_connector/bases/resource_getter.py b/braincube_connector/bases/resource_getter.py index 32ce8f72..1a3b70f1 100644 --- a/braincube_connector/bases/resource_getter.py +++ b/braincube_connector/bases/resource_getter.py @@ -2,7 +2,7 @@ from typing import Any, Tuple, Union -from braincube_connector import tools +from braincube_connector import tools, constants class ResourceGetter(object): @@ -10,7 +10,23 @@ class ResourceGetter(object): def __init__(self): """Initialize ResourceGetter.""" - self._path = "" + self._path = constants.EMPTY_STRING + self._braincube_name = constants.EMPTY_STRING + self._parent_entity = None + + def get_braincube_name(self): + """Get an object's braincube name. + + Returns: + A braincube name. + """ + if self._braincube_name: + return self._braincube_name + + if self._parent_entity: + return self._parent_entity.get_braincube_name() + + return constants.EMPTY_STRING def get_braincube_path(self) -> str: """Get an object's parent braincube path. @@ -21,7 +37,11 @@ def get_braincube_path(self) -> str: return (self._path.split("{webservice}"))[0] def _get_resource( - self, resource_class: Any, bcid: Union[str, int], singleton_path: str = "", **kwargs, + self, + resource_class: Any, + bcid: Union[str, int], + singleton_path: str = constants.EMPTY_STRING, + **kwargs, ): """Get a resource from its bcId. @@ -40,10 +60,14 @@ def _get_resource( resource_class.entity_path.replace("{bcid}", str(bcid)), resource_class.request_one_path if not singleton_path else singleton_path, ), + self, + braincube_name=self.get_braincube_name(), **kwargs, ) - def _get_resource_list(self, resource_class: Any, collection_path: str = "", **kwargs): + def _get_resource_list( + self, resource_class: Any, collection_path: str = constants.EMPTY_STRING, **kwargs, + ): """Get a list a of resources from a list of ids. Args: @@ -61,6 +85,8 @@ def _get_resource_list(self, resource_class: Any, collection_path: str = "", **k resource_class.request_many_path if not collection_path else collection_path, request_list=True, ), + self, + braincube_name=self.get_braincube_name(), **kwargs, ) diff --git a/braincube_connector/braincube.py b/braincube_connector/braincube.py index 15836d2a..0374ca23 100644 --- a/braincube_connector/braincube.py +++ b/braincube_connector/braincube.py @@ -19,7 +19,13 @@ def __init__(self, product_id: str, name: str, metadata: Dict[str, Any]): metadata: Raw metadata associated to the Braincube. """ self._product_id = product_id - super().__init__(name, name, metadata, "braincube/{bc_name}".format(bc_name=name)) + + entity_path = "braincube/{bc_name}".format(bc_name=name) + if client.get_instance().has_placeholder_in_braincube_url(): + entity_path = "" + + super().__init__(name, name, metadata, entity_path) + self._braincube_name = name def get_memory_base(self, mb_bcid: Union[str, int]) -> memory_base.MemoryBase: """Get a MemoryBase object from its id. diff --git a/braincube_connector/client.py b/braincube_connector/client.py index 9ecc7ba3..cd1c5ee8 100644 --- a/braincube_connector/client.py +++ b/braincube_connector/client.py @@ -28,11 +28,11 @@ def __init__( if instances.get_instance(INSTANCE_KEY) is not None: raise Exception("A client has already been inialized.") else: - config_dict = tools.check_config(config_dict=config_dict, config_file=config_file) - self._sso_url = tools.get_sso_base_url(config_dict) - self._braincube_base_url = tools.get_braincube_base_url(config_dict) - self._verify = config_dict.get(constants.VERIFY_CERT, True) # noqa: WPS425 - self._authentication = self._build_authentication(config_dict) + self._config_dict = tools.check_config(config_dict=config_dict, config_file=config_file) + self._sso_url = tools.get_sso_base_url(self._config_dict) + self._braincube_base_url = tools.get_braincube_base_url(self._config_dict) + self._verify = self._config_dict.get(constants.VERIFY_CERT, True) # noqa: WPS425 + self._authentication = self._build_authentication(self._config_dict) available_braincube_infos = self._request_braincubes() self._braincube_infos = available_braincube_infos self._timeout = timeout @@ -54,6 +54,7 @@ def request_ws( rtype: str = "GET", api: bool = True, response_as_json: bool = True, + braincube_name: str = "", ) -> Dict[str, Any]: """Make a request at a given path on the client's domain. @@ -64,6 +65,8 @@ def request_ws( rtype: Request type (GET, POST). api: Requests the API server on the domain. response_as_json: parse a json output to a python dictionary. + braincube_name: name of the Braincube you want to use to do this request. + Usefull when you have {braincube-name} in your base URL Returns: The request's json output or the full response. @@ -72,7 +75,7 @@ def request_ws( if api: base_url = self._braincube_base_url - url = tools.build_url(base_url, path) + url = tools.build_url(base_url, path, braincube_name) if not headers: headers = self._headers @@ -92,6 +95,16 @@ def get_braincube_infos(self) -> Dict[str, Any]: """ return self._braincube_infos + def has_placeholder_in_braincube_url(self): + """Indicates whether or not braincube_base_url contains a placeholder. + + The placeholder format is given by constants.BRAINCUBE_NAME_PLACEHOLDER. + + Returns: + Returns a boolean indicating whether or not braincube_base_url contains a placeholder + """ + return constants.BRAINCUBE_NAME_PLACEHOLDER in self._braincube_base_url + def _request_braincubes(self) -> Dict[str, Any]: """Request the accessible braincube to the sso server. @@ -168,6 +181,7 @@ def request_ws( rtype: str = "GET", api: bool = True, response_as_json: bool = True, + braincube_name: str = "", ) -> Dict[str, Any]: """Make a request at a given path on the client's domain. @@ -178,9 +192,11 @@ def request_ws( rtype: Request type (GET, POST). api: Requests the API server on the domain. response_as_json: parse a json output to a python dictionary. + braincube_name: name of the braincube on which is made the request, + useful if you use a placeholder in your config Returns: The request's json output or the full response. """ cli = get_instance() - return cli.request_ws(path, headers, body_data, rtype, api, response_as_json) + return cli.request_ws(path, headers, body_data, rtype, api, response_as_json, braincube_name) diff --git a/braincube_connector/constants.py b/braincube_connector/constants.py index da7d8071..af3bb4b4 100644 --- a/braincube_connector/constants.py +++ b/braincube_connector/constants.py @@ -23,3 +23,5 @@ OAUTH2_KEY = "oauth2_token" SSO_TOKEN_KEY = "IPLSSOTOKEN" # noqa: S105 VERIFY_CERT = "verify" +BRAINCUBE_NAME_PLACEHOLDER = "{braincube-name}" +EMPTY_STRING = "" diff --git a/braincube_connector/memory_base/memory_base.py b/braincube_connector/memory_base/memory_base.py index 8c5ab333..289bad62 100644 --- a/braincube_connector/memory_base/memory_base.py +++ b/braincube_connector/memory_base/memory_base.py @@ -172,27 +172,3 @@ def get_order_variable_long_id(self) -> str: if order_id: return order_id raise KeyError("The memory base contains neither a reference nor a order key.") - - def _get_resource(self, resource_class: Any, bcid: Union[str, int]): # type: ignore - """Get a resource from its bcId. - - Args: - resource_class: Class of the resource to get. - bcid: Event bcid. - - Returns: - A resource description. - """ - return super()._get_resource(resource_class, bcid, memory_base=self) - - def _get_resource_list(self, resource_class: Any, **kwargs): # type: ignore - """Get a list a of resources from a list of ids. - - Args: - resource_class: Class of the resources to get. - **kwargs: Optional page and page_size or parent (memory_base). - - Returns: - A list of resources. - """ - return super()._get_resource_list(resource_class, memory_base=self, **kwargs) diff --git a/braincube_connector/memory_base/nested_resources/mb_child.py b/braincube_connector/memory_base/nested_resources/mb_child.py index df5f915f..977ba19b 100644 --- a/braincube_connector/memory_base/nested_resources/mb_child.py +++ b/braincube_connector/memory_base/nested_resources/mb_child.py @@ -6,7 +6,7 @@ class MbChild(base_entity.BaseEntity): """MbChild object provides an interface between a child and its memory bases.""" - def __init__(self, bcid, name, metadata, path, memory_base): + def __init__(self, bcid, name, metadata, path, **kwargs): """Initialize a memory bases child. Args: @@ -14,11 +14,11 @@ def __init__(self, bcid, name, metadata, path, memory_base): name: Usual name of the entity description. metadata: Raw metadata associated to the entity description. path: Path of the entity description on the server. - memory_base: Instance of the parent memory base. + **kwargs: Optional braincube_name or parent_entity. """ - self.initialize(bcid, name, metadata, path, memory_base) + self.initialize(bcid, name, metadata, path, **kwargs) - def initialize(self, bcid, name, metadata, path, memory_base): + def initialize(self, bcid, name, metadata, path, **kwargs): """Initialize a memory bases child. Args: @@ -26,10 +26,10 @@ def initialize(self, bcid, name, metadata, path, memory_base): name: Usual name of the entity description. metadata: Raw metadata associated to the entity description. path: Path of the entity description on the server. - memory_base: Instance of the parent memory base. + **kwargs: Optional braincube_name or parent_entity. """ - super().initialize(bcid, name, metadata, path) - self._memory_base = memory_base + super().initialize(bcid, name, metadata, path, **kwargs) + self._memory_base = self._parent_entity def get_memory_base(self) -> "MemoryBase": # type: ignore # noqa """Get the entity's parent memory bases. diff --git a/braincube_connector/tools.py b/braincube_connector/tools.py index e391be3a..24ba39f3 100644 --- a/braincube_connector/tools.py +++ b/braincube_connector/tools.py @@ -10,8 +10,6 @@ from braincube_connector import constants -EMPTY_STRING = "" - def read_config(path: str) -> Dict[str, str]: """Reads the configuration file. @@ -92,22 +90,36 @@ def join_path(path_elmts: List[str]) -> str: return "/".join(clean_elmts) -def build_url(base_url: str = EMPTY_STRING, path: str = EMPTY_STRING) -> str: +def build_url( + base_url: str = constants.EMPTY_STRING, + path: str = constants.EMPTY_STRING, + braincube_name: str = constants.EMPTY_STRING, +) -> str: """Appends a path to the given base_url to generate a valid url. Args: base_url: Base URL to complete with given path. path: Path to a specific resource. + braincube_name: name of the braincube to use to replace the placeholder. Returns: A complete url. """ parts = urlsplit(base_url) full_path = join_path([parts.path, path]) - return urlunsplit( - (parts.scheme, parts.netloc, strip_path(full_path), EMPTY_STRING, EMPTY_STRING) + + url_with_placeholder = urlunsplit( + ( + parts.scheme, + parts.netloc, + strip_path(full_path), + constants.EMPTY_STRING, + constants.EMPTY_STRING, + ) ) + return url_with_placeholder.replace(constants.BRAINCUBE_NAME_PLACEHOLDER, braincube_name) + def check_config( config_dict: Optional[Dict[str, str]] = None, config_file: Optional[str] = None diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 00000000..a3a9964f --- /dev/null +++ b/mypy.ini @@ -0,0 +1,2 @@ +[mypy-pandas.*] +ignore_missing_imports = True diff --git a/tests/mock.py b/tests/mock.py index c30186cc..2ae05eb7 100644 --- a/tests/mock.py +++ b/tests/mock.py @@ -65,7 +65,7 @@ def mock_request_entity(mocker, monkeypatch): @pytest.fixture -def bc_obj(): +def bc_obj(mock_client): """Create a mock of the Braincube object.""" obj = braincube.Braincube(product_id="id123", name="bcname", metadata={"meta": 1},) return obj @@ -82,7 +82,9 @@ def mb_obj(): @pytest.fixture def mbchild_obj(): - child = mb_child.MbChild("id1", "child", {"metadata": []}, "path/mb/10/child/id1", "MB_obj") + child = mb_child.MbChild( + "id1", "child", {"metadata": []}, "path/mb/10/child/id1", parent_entity="MB_obj" + ) return child @@ -91,7 +93,7 @@ def create_mock_var(): def create_mock(bcid="1", name="", metadata={"type": "NUMERIC"}, mb=None): name = name if name else "var{0}".format(bcid) var = variable.VariableDescription( - bcid=bcid, name=name, metadata=metadata, path="path", memory_base=mb + bcid=bcid, name=name, metadata=metadata, path="path", parent_entity=mb ) return var @@ -103,7 +105,7 @@ def create_mock_datagroup(): def create_mock(bcid="1", name="", variables=[], mb=None): name = name if name else "datagroup{0}".format(bcid) metadata = {"variables": [{"bcId": var} for var in variables]} - dgroup = datagroup.DataGroup(bcid, name, metadata, "path", mb) + dgroup = datagroup.DataGroup(bcid, name, metadata, "path", parent_entity=mb) return dgroup return create_mock @@ -118,7 +120,7 @@ def create_mock(bcid="1", name="", variables=[], mb=None): {"variable": {"bcId": var_id}, "minimum": 0, "maximum": 1} for var_id in variables ] } - return event.Event(bcid, name, metadata, "path", mb) + return event.Event(bcid, name, metadata, "path", parent_entity=mb) return create_mock @@ -165,7 +167,7 @@ def create_mock( datagroups = {"dataGroups": [{"bcId": did} for did in datagroups]} metadata.update(datagroups) name = name if name else "job{0}".format(bcid) - job_obj = job.JobDescription(bcid, name, metadata, path, mb) + job_obj = job.JobDescription(bcid, name, metadata, path, parent_entity=mb) return job_obj return create_mock diff --git a/tests/test_bases/test_base_entity.py b/tests/test_bases/test_base_entity.py index 241e1199..b0069bfd 100644 --- a/tests/test_bases/test_base_entity.py +++ b/tests/test_bases/test_base_entity.py @@ -7,7 +7,6 @@ from braincube_connector import parameters from braincube_connector.bases import base_entity -from braincube_connector.bases.base_entity import BaseEntity from tests.mock import entity_obj, mock_client, base_obj import pytest @@ -33,7 +32,7 @@ def test_get_metadata(entity_obj): def test_create_from_json(): json_dict = {"bcId": "1", "name": "abcd"} - obj = base_entity.BaseEntity.create_from_json(json_dict, "path/{bcid}") + obj = base_entity.BaseEntity.create_from_json(json_dict, "path/{bcid}", None) assert obj._name == "abcd" assert obj._bcid == "1" assert obj._path == "path/1" @@ -45,7 +44,7 @@ def test_create_singleton_from_path(mock_client): json_data = {"name": "abcd", "bcId": "1"} responses.add(responses.GET, "https://api.a.b/braincube/path", json=json_data, status=200) entity = base_entity.BaseEntity.create_singleton_from_path( - "{webservice}/path", "{webservice}/path/{bcid}" + "{webservice}/path", "{webservice}/path/{bcid}", None ) assert entity._name == "abcd" assert entity._bcid == "1" @@ -66,7 +65,7 @@ def test_create_collection_from_path( """Test create_collection_from_path for different pagination settings""" items = [{"name": "name{}".format(i), "bcId": str(i)} for i in range(4)] - def mock_request_ws(path): + def mock_request_ws(path, **kwargs): path, param = path.split("?") params = {key: int(val) for key, val in [pp.split("=") for pp in param.split("&")]} assert path == "braincube/path/all/summary" @@ -75,11 +74,12 @@ def mock_request_ws(path): rpatch = mocker.patch("braincube_connector.client.request_ws", side_effect=mock_request_ws) parameters.set_parameter({"page_size": page_size}) entities = base_entity.BaseEntity.create_collection_from_path( - "{webservice}/path/all/summary", "{webservice}/path/{bcid}", page=page + "{webservice}/path/all/summary", "{webservice}/path/{bcid}", None, page=page ) calls = [ - mocker.call("braincube/path/all/summary{param}".format(param=pp)) for pp in call_params + mocker.call("braincube/path/all/summary{param}".format(param=pp), braincube_name="") + for pp in call_params ] rpatch.assert_has_calls(calls) assert len(entities) == length @@ -95,7 +95,7 @@ def test_get_name(mocker): "braincube_connector.instances.instances", {"parameter_set": {}} ) # Uses a temporary instance for the test. json_dict = {"bcId": "1", "name": "abcd", "tag": "dcba"} - obj = base_entity.BaseEntity.create_from_json(json_dict, "path/{bcid}") + obj = base_entity.BaseEntity.create_from_json(json_dict, "path/{bcid}", None) assert obj.get_name() == "abcd" parameters.set_parameter({"BaseEntity_name_key": "tag"}) assert obj.get_name() == "dcba" @@ -104,5 +104,5 @@ def test_get_name(mocker): def test_get_uuid(mocker): uuid = "myuuid" json_dict = {"bcId": "1", "name": "abcd", "uuid": "{0}_{1}".format("base64", uuid)} - obj = base_entity.BaseEntity.create_from_json(json_dict, "path/{bcid}") + obj = base_entity.BaseEntity.create_from_json(json_dict, "path/{bcid}", None) assert obj.get_uuid() == uuid diff --git a/tests/test_bases/test_resource_getter.py b/tests/test_bases/test_resource_getter.py index 6d0e6da1..b966adaa 100644 --- a/tests/test_bases/test_resource_getter.py +++ b/tests/test_bases/test_resource_getter.py @@ -44,14 +44,17 @@ def test_generate_path(request_list, expected_req_path): def test_get_resource(mock_entity_class, resource_parent, bcid): resource_parent._get_resource(mock_entity_class, bcid=bcid) mock_entity_class.create_singleton_from_path.assert_called_once_with( - "parent_path/entity/1/extended", "parent_path/entity/1" + "parent_path/entity/1/extended", "parent_path/entity/1", resource_parent, braincube_name="" ) def test_get_resource_list(mock_entity_class, resource_parent): resource_parent._get_resource_list(mock_entity_class) mock_entity_class.create_collection_from_path.assert_called_once_with( - "parent_path/entity/all/extended", "parent_path/entity/{bcid}" + "parent_path/entity/all/extended", + "parent_path/entity/{bcid}", + resource_parent, + braincube_name="", ) diff --git a/tests/test_braincube.py b/tests/test_braincube.py index 2367730f..556ba80a 100644 --- a/tests/test_braincube.py +++ b/tests/test_braincube.py @@ -50,7 +50,8 @@ def test_get_memory_base_list(mocker, monkeypatch, bc_obj, mock_request_entity): parameters.set_parameter({"page_size": 2}) mb_list = bc_obj.get_memory_base_list(page=10) mock_request_entity.assert_called_with( - "braincube/bcname/braincube/mb/all/summary?offset=20&size=2" + "braincube/bcname/braincube/mb/all/summary?offset=20&size=2", + braincube_name=bc_obj.get_braincube_name(), ) diff --git a/tests/test_memory_base/test_memory_base.py b/tests/test_memory_base/test_memory_base.py index 8941d779..3abdaabc 100644 --- a/tests/test_memory_base/test_memory_base.py +++ b/tests/test_memory_base/test_memory_base.py @@ -40,11 +40,11 @@ def test_get_variable_list(mocker, monkeypatch, mb_obj, mock_request_entity): assert var_list[0]._name == "name0" request_path = "braincube/bcname/braincube/mb/1/variables/summary?offset=0&size=2" - mock_request_entity.assert_called_with(request_path) + mock_request_entity.assert_called_with(request_path, braincube_name="") mock_request_entity.reset_mock() parameters.set_parameter({"page_size": 4}) var_list = mb_obj.get_variable_list(page=0, page_size=2) - mock_request_entity.assert_called_with(request_path) + mock_request_entity.assert_called_with(request_path, braincube_name="") @responses.activate @@ -61,11 +61,11 @@ def test_get_job_list(mocker, monkeypatch, mb_obj, mock_request_entity): job_list = mb_obj.get_job_list(page=0) assert job_list[0]._name == "name0" request_path = "braincube/bcname/braincube/mb/1/jobs/all/summary?offset=0&size=2" - mock_request_entity.assert_called_with(request_path) + mock_request_entity.assert_called_with(request_path, braincube_name="") mock_request_entity.reset_mock() parameters.set_parameter({"page_size": 4}) job_list = mb_obj.get_job_list(page=0, page_size=2) - mock_request_entity.assert_called_with(request_path) + mock_request_entity.assert_called_with(request_path, braincube_name="") @responses.activate @@ -82,11 +82,11 @@ def test_get_datagroup_list(mocker, monkeypatch, mb_obj, mock_request_entity): group_list = mb_obj.get_datagroup_list(page=0) assert group_list[0]._name == "name0" request_path = "braincube/bcname/braincube/mb/1/dataGroups/summary?offset=0&size=2" - mock_request_entity.assert_called_with(request_path) + mock_request_entity.assert_called_with(request_path, braincube_name="") mock_request_entity.reset_mock() parameters.set_parameter({"page_size": 4}) group_list = mb_obj.get_datagroup_list(page=0, page_size=2) - mock_request_entity.assert_called_with(request_path) + mock_request_entity.assert_called_with(request_path, braincube_name="") @responses.activate @@ -103,11 +103,11 @@ def test_get_events_list(mocker, monkeypatch, mb_obj, mock_request_entity): event_list = mb_obj.get_event_list(page=0) assert event_list[0]._name == "name0" request_path = "braincube/bcname/braincube/mb/1/events/all/extended?offset=0&size=2" - mock_request_entity.assert_called_with(request_path) + mock_request_entity.assert_called_with(request_path, braincube_name="") mock_request_entity.reset_mock() parameters.set_parameter({"page_size": 4}) event_list = mb_obj.get_event_list(page=0, page_size=2) - mock_request_entity.assert_called_with(request_path) + mock_request_entity.assert_called_with(request_path, braincube_name="") @responses.activate @@ -124,11 +124,11 @@ def test_get_rule_list(mocker, monkeypatch, mb_obj, mock_request_entity): rule_list = mb_obj.get_rule_list(page=0) assert rule_list[0]._name == "name0" request_path = "braincube/bcname/braincube/mb/1/rules/all/selector?offset=0&size=2" - mock_request_entity.assert_called_with(request_path) + mock_request_entity.assert_called_with(request_path, braincube_name="") mock_request_entity.reset_mock() parameters.set_parameter({"page_size": 4}) rule_list = mb_obj.get_rule_list(page=0, page_size=2) - mock_request_entity.assert_called_with(request_path) + mock_request_entity.assert_called_with(request_path, braincube_name="") @pytest.mark.parametrize( diff --git a/tests/test_memory_base/test_nested_resources/test_mb_child.py b/tests/test_memory_base/test_nested_resources/test_mb_child.py index 5b470bf6..01aa57e4 100644 --- a/tests/test_memory_base/test_nested_resources/test_mb_child.py +++ b/tests/test_memory_base/test_nested_resources/test_mb_child.py @@ -7,7 +7,9 @@ def test_initialize(): - child = mb_child.MbChild("id1", "child", {"metadata": []}, "path/mb/11/child/id1", "MB_obj") + child = mb_child.MbChild( + "id1", "child", {"metadata": []}, "path/mb/11/child/id1", parent_entity="MB_obj" + ) assert child._name == "child" assert child._memory_base == "MB_obj" diff --git a/tests/test_tools.py b/tests/test_tools.py index 081335bb..c16ce442 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -148,21 +148,54 @@ def test_get_braincube_base_url(config, output): @pytest.mark.parametrize( - "base_url, path, full_url", + "base_url, path, braincube_name, full_url", [ - ("http://a.domain/prefix/v1.0", "with/a/path", "http://a.domain/prefix/v1.0/with/a/path"), - ("toto", "with/a/path", "toto/with/a/path"), + ( + "http://a.domain/prefix/v1.0", + "with/a/path", + "", + "http://a.domain/prefix/v1.0/with/a/path", + ), + ("toto", "with/a/path", "", "toto/with/a/path"), ( "http://a.domain/prefix/v1.0", "with/a/path?size=50&page=2", + "", "http://a.domain/prefix/v1.0/with/a/path?size=50&page=2", ), - ("http://a.domain/prefix/v1.0", "/with/a/path", "http://a.domain/prefix/v1.0/with/a/path"), - ("http://a.domain/prefix/v1.0/", "with/a/path", "http://a.domain/prefix/v1.0/with/a/path"), - ("http://a.domain/prefix/v1.0/", "/with/a/path", "http://a.domain/prefix/v1.0/with/a/path"), - ("http://a.domain/prefix/v1.0", "", "http://a.domain/prefix/v1.0"), - ("", "with/a/path", "with/a/path"), + ( + "http://a.domain/prefix/v1.0", + "/with/a/path", + "", + "http://a.domain/prefix/v1.0/with/a/path", + ), + ( + "http://a.domain/prefix/v1.0/", + "with/a/path", + "", + "http://a.domain/prefix/v1.0/with/a/path", + ), + ( + "http://a.domain/prefix/v1.0/", + "/with/a/path", + "", + "http://a.domain/prefix/v1.0/with/a/path", + ), + ("http://a.domain/prefix/v1.0", "", "", "http://a.domain/prefix/v1.0"), + ("", "with/a/path", "", "with/a/path"), + ( + "http://{braincube-name}.domain/prefix/v1.0/", + "/with/a/path", + "demo", + "http://demo.domain/prefix/v1.0/with/a/path", + ), + ( + "http://a.domain/prefix/v1.0/", + "/{braincube-name}/with/a/path", + "demo", + "http://a.domain/prefix/v1.0/demo/with/a/path", + ), ], ) -def test_build_url(base_url, path, full_url): - assert tools.build_url(base_url, path) == full_url +def test_build_url(base_url, path, braincube_name, full_url): + assert tools.build_url(base_url, path, braincube_name) == full_url diff --git a/tests_integration/mocks.py b/tests_integration/mocks.py index 86a52431..d7ea009c 100644 --- a/tests_integration/mocks.py +++ b/tests_integration/mocks.py @@ -85,6 +85,19 @@ "status": 200, "json": {"referenceDateVariable": {"bcId": 101, "id": 101}, "name": "mb1", "bcId": 1,}, }, + # Expected call for test_memorybase_with_custom_domains_and_placeholder + { + "method": "GET", + "url": "http://demo.plop.com/prefix/v1.0/braincube/mb/1/extended", + "status": 200, + "json": {"referenceDateVariable": {"bcId": 101, "id": 101}, "name": "mb1", "bcId": 1,}, + }, + { + "method": "GET", + "url": "http://demo.plop.com/prefix/v1.0/braincube/mb/1/variables/summary?offset=0&size=150", + "status": 200, + "json": {"items": [],}, + }, ] for bcid in ["101", "102", "103"]: diff --git a/tests_integration/test_integration.py b/tests_integration/test_integration.py index e6f27a15..6c8bd866 100644 --- a/tests_integration/test_integration.py +++ b/tests_integration/test_integration.py @@ -81,6 +81,25 @@ def test_memorybase_with_custom_domains(patch_endpoints, custom_patch_endpoints) assert mb._bcid == 1 +@responses.activate +def test_memorybase_with_custom_domains_and_placeholder(patch_endpoints, custom_patch_endpoints): + custom_config = { + "sso_base_url": "http://another.plop.com", + "braincube_base_url": "http://{braincube-name}.plop.com/prefix/v1.0/", + "api_key": "abcd", + } + + with pytest.raises(ConnectionError): + test_braincube(patch_endpoints, custom_config) + + bc = test_braincube(custom_patch_endpoints, custom_config) + custom_patch_endpoints() + mb = bc.get_memory_base(1) + assert mb._name == "mb1" + assert mb._bcid == 1 + mb.get_variable_list() + + @responses.activate def test_get_data(patch_endpoints): mb = test_memorybase(patch_endpoints)