From c611b418f0114f85e2b41a2d2264e94e7c710a72 Mon Sep 17 00:00:00 2001 From: francescadecicco Date: Tue, 1 Jul 2025 11:39:08 +0200 Subject: [PATCH 1/9] fix(Global Search/Tagging): regenerated services with latest API definition Signed-off-by: francescadecicco --- ibm_platform_services/global_tagging_v1.py | 177 +++++++++++++----- test/unit/test_global_tagging_v1.py | 203 ++++++++------------- 2 files changed, 213 insertions(+), 167 deletions(-) diff --git a/ibm_platform_services/global_tagging_v1.py b/ibm_platform_services/global_tagging_v1.py index aaf367ef..74f4a591 100644 --- a/ibm_platform_services/global_tagging_v1.py +++ b/ibm_platform_services/global_tagging_v1.py @@ -1,6 +1,6 @@ # coding: utf-8 -# (C) Copyright IBM Corp. 2024. +# (C) Copyright IBM Corp. 2025. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# IBM OpenAPI SDK Code Generator Version: 3.87.0-91c7c775-20240320-213027 +# IBM OpenAPI SDK Code Generator Version: 3.105.0-3c13b041-20250605-193116 """ Manage your tags with the Tagging API in IBM Cloud. You can attach, detach, delete, or @@ -23,10 +23,10 @@ `label`. The tagging API supports three types of tag: `user` `service`, and `access` tags. `service` tags cannot be attached to IMS resources. `service` tags must be in the form `service_prefix:tag_label` where `service_prefix` identifies the Service owning the tag. -`access` tags cannot be attached to IMS and Cloud Foundry resources. They must be in the -form `key:value`. You can replace all resource's tags using the `replace` query parameter -in the attach operation. You can update the `value` of a resource's tag in the format -`key:value`, using the `update` query parameter in the attach operation. +`access` tags cannot be attached to IMS resources. They must be in the form `key:value`. +You can replace all resource's tags using the `replace` query parameter in the attach +operation. You can update the `value` of a resource's tag in the format `key:value`, using +the `update` query parameter in the attach operation. API Version: 1.2.0 """ @@ -63,7 +63,9 @@ def new_instance( parameters and external configuration. """ authenticator = get_authenticator_from_environment(service_name) - service = cls(authenticator) + service = cls( + authenticator + ) service.configure_service(service_name) return service @@ -453,10 +455,11 @@ def delete_tag( def attach_tag( self, - resources: List['Resource'], *, tag_name: Optional[str] = None, tag_names: Optional[List[str]] = None, + resources: Optional[List['Resource']] = None, + query: Optional['QueryString'] = None, x_request_id: Optional[str] = None, x_correlation_id: Optional[str] = None, account_id: Optional[str] = None, @@ -472,10 +475,11 @@ def attach_tag( than 1000 tags per each 'user' and 'service' type, and no more than 250 'access' tags (which is the account limit). - :param List[Resource] resources: List of resources on which the tag or tags - are attached. :param str tag_name: (optional) The name of the tag to attach. :param List[str] tag_names: (optional) An array of tag names to attach. + :param List[Resource] resources: (optional) List of resources on which the + tagging operation operates on. + :param QueryString query: (optional) A valid Global Search string. :param str x_request_id: (optional) An alphanumeric string that is used to trace the request. The value may include ASCII alphanumerics and any of following segment separators: space ( ), comma (,), hyphen, (-), and @@ -516,9 +520,10 @@ def attach_tag( :rtype: DetailedResponse with `dict` result representing a `TagResults` object """ - if resources is None: - raise ValueError('resources must be provided') - resources = [convert_model(x) for x in resources] + if resources is not None: + resources = [convert_model(x) for x in resources] + if query is not None: + query = convert_model(query) headers = { 'x-request-id': x_request_id, 'x-correlation-id': x_correlation_id, @@ -538,9 +543,10 @@ def attach_tag( } data = { - 'resources': resources, 'tag_name': tag_name, 'tag_names': tag_names, + 'resources': resources, + 'query': query, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -565,10 +571,11 @@ def attach_tag( def detach_tag( self, - resources: List['Resource'], *, tag_name: Optional[str] = None, tag_names: Optional[List[str]] = None, + resources: Optional[List['Resource']] = None, + query: Optional['QueryString'] = None, x_request_id: Optional[str] = None, x_correlation_id: Optional[str] = None, account_id: Optional[str] = None, @@ -580,10 +587,11 @@ def detach_tag( Detaches one or more tags from one or more resources. - :param List[Resource] resources: List of resources on which the tag or tags - are detached. :param str tag_name: (optional) The name of the tag to detach. :param List[str] tag_names: (optional) An array of tag names to detach. + :param List[Resource] resources: (optional) List of resources on which the + tagging operation operates on. + :param QueryString query: (optional) A valid Global Search string. :param str x_request_id: (optional) An alphanumeric string that is used to trace the request. The value may include ASCII alphanumerics and any of following segment separators: space ( ), comma (,), hyphen, (-), and @@ -612,9 +620,10 @@ def detach_tag( :rtype: DetailedResponse with `dict` result representing a `TagResults` object """ - if resources is None: - raise ValueError('resources must be provided') - resources = [convert_model(x) for x in resources] + if resources is not None: + resources = [convert_model(x) for x in resources] + if query is not None: + query = convert_model(query) headers = { 'x-request-id': x_request_id, 'x-correlation-id': x_correlation_id, @@ -632,9 +641,10 @@ def detach_tag( } data = { - 'resources': resources, 'tag_name': tag_name, 'tag_names': tag_names, + 'resources': resources, + 'query': query, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -672,7 +682,6 @@ class TagType(str, Enum): USER = 'user' SERVICE = 'service' ACCESS = 'access' - class Providers(str, Enum): """ Select a provider. Supported values are `ghost` and `ims`. To list both Global @@ -683,7 +692,6 @@ class Providers(str, Enum): GHOST = 'ghost' IMS = 'ims' - class OrderByName(str, Enum): """ Order the output by tag name. @@ -718,7 +726,6 @@ class Providers(str, Enum): GHOST = 'ghost' IMS = 'ims' - class TagType(str, Enum): """ The type of the tag. Supported values are `user`, `service` and `access`. @@ -744,7 +751,6 @@ class Providers(str, Enum): GHOST = 'ghost' IMS = 'ims' - class TagType(str, Enum): """ The type of the tag. Supported values are `user`, `service` and `access`. @@ -1001,6 +1007,8 @@ class DeleteTagResultsItem: :param str provider: (optional) The provider of the tag. :param bool is_error: (optional) It is `true` if the operation exits with an error (for example, the tag does not exist). + + This type supports additional properties of type object. """ # The set of defined properties for the class @@ -1011,7 +1019,7 @@ def __init__( *, provider: Optional[str] = None, is_error: Optional[bool] = None, - **kwargs, + **kwargs: Optional[object], ) -> None: """ Initialize a DeleteTagResultsItem object. @@ -1019,12 +1027,17 @@ def __init__( :param str provider: (optional) The provider of the tag. :param bool is_error: (optional) It is `true` if the operation exits with an error (for example, the tag does not exist). - :param **kwargs: (optional) Any additional properties. + :param object **kwargs: (optional) Additional properties of type object """ self.provider = provider self.is_error = is_error - for _key, _value in kwargs.items(): - setattr(self, _key, _value) + for k, v in kwargs.items(): + if k not in DeleteTagResultsItem._properties: + if not isinstance(v, object): + raise ValueError('Value for additional property {} must be of type object'.format(k)) + setattr(self, k, v) + else: + raise ValueError('Property {} cannot be specified as an additional property'.format(k)) @classmethod def from_dict(cls, _dict: Dict) -> 'DeleteTagResultsItem': @@ -1034,7 +1047,11 @@ def from_dict(cls, _dict: Dict) -> 'DeleteTagResultsItem': args['provider'] = provider if (is_error := _dict.get('is_error')) is not None: args['is_error'] = is_error - args.update({k: v for (k, v) in _dict.items() if k not in cls._properties}) + for k, v in _dict.items(): + if k not in cls._properties: + if not isinstance(v, object): + raise ValueError('Value for additional property {} must be of type object'.format(k)) + args[k] = v return cls(**args) @classmethod @@ -1049,8 +1066,8 @@ def to_dict(self) -> Dict: _dict['provider'] = self.provider if hasattr(self, 'is_error') and self.is_error is not None: _dict['is_error'] = self.is_error - for _key in [k for k in vars(self).keys() if k not in DeleteTagResultsItem._properties]: - _dict[_key] = getattr(self, _key) + for k in [_k for _k in vars(self).keys() if _k not in DeleteTagResultsItem._properties]: + _dict[k] = getattr(self, k) return _dict def _to_dict(self): @@ -1058,21 +1075,23 @@ def _to_dict(self): return self.to_dict() def get_properties(self) -> Dict: - """Return a dictionary of arbitrary properties from this instance of DeleteTagResultsItem""" + """Return the additional properties from this instance of DeleteTagResultsItem in the form of a dict.""" _dict = {} - - for _key in [k for k in vars(self).keys() if k not in DeleteTagResultsItem._properties]: - _dict[_key] = getattr(self, _key) + for k in [_k for _k in vars(self).keys() if _k not in DeleteTagResultsItem._properties]: + _dict[k] = getattr(self, k) return _dict def set_properties(self, _dict: dict): - """Set a dictionary of arbitrary properties to this instance of DeleteTagResultsItem""" - for _key in [k for k in vars(self).keys() if k not in DeleteTagResultsItem._properties]: - delattr(self, _key) - - for _key, _value in _dict.items(): - if _key not in DeleteTagResultsItem._properties: - setattr(self, _key, _value) + """Set a dictionary of additional properties in this instance of DeleteTagResultsItem""" + for k in [_k for _k in vars(self).keys() if _k not in DeleteTagResultsItem._properties]: + delattr(self, k) + for k, v in _dict.items(): + if k not in DeleteTagResultsItem._properties: + if not isinstance(v, object): + raise ValueError('Value for additional property {} must be of type object'.format(k)) + setattr(self, k, v) + else: + raise ValueError('Property {} cannot be specified as an additional property'.format(k)) def __str__(self) -> str: """Return a `str` version of this DeleteTagResultsItem object.""" @@ -1097,6 +1116,7 @@ class ProviderEnum(str, Enum): IMS = 'ims' + class DeleteTagsResult: """ Results of deleting unattatched tags. @@ -1248,12 +1268,76 @@ def __ne__(self, other: 'DeleteTagsResultItem') -> bool: return not self == other +class QueryString: + """ + A valid Global Search string. + + :param str query_string: The Lucene-formatted query string. + """ + + def __init__( + self, + query_string: str, + ) -> None: + """ + Initialize a QueryString object. + + :param str query_string: The Lucene-formatted query string. + """ + self.query_string = query_string + + @classmethod + def from_dict(cls, _dict: Dict) -> 'QueryString': + """Initialize a QueryString object from a json dictionary.""" + args = {} + if (query_string := _dict.get('query_string')) is not None: + args['query_string'] = query_string + else: + raise ValueError('Required property \'query_string\' not present in QueryString JSON') + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a QueryString object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'query_string') and self.query_string is not None: + _dict['query_string'] = self.query_string + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this QueryString object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'QueryString') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'QueryString') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + class Resource: """ A resource that might have tags that are attached. :param str resource_id: The CRN or IMS ID of the resource. - :param str resource_type: (optional) The IMS resource type of the resource. + :param str resource_type: (optional) The IMS resource type of the resource. It + can be one of SoftLayer_Virtual_DedicatedHost, SoftLayer_Hardware, + SoftLayer_Hardware_Server, SoftLayer_Network_Application_Delivery_Controller, + SoftLayer_Network_Vlan, SoftLayer_Network_Vlan_Firewall, + SoftLayer_Network_Component_Firewall, SoftLayer_Network_Firewall_Module_Context, + SoftLayer_Virtual_Guest. """ def __init__( @@ -1267,6 +1351,11 @@ def __init__( :param str resource_id: The CRN or IMS ID of the resource. :param str resource_type: (optional) The IMS resource type of the resource. + It can be one of SoftLayer_Virtual_DedicatedHost, SoftLayer_Hardware, + SoftLayer_Hardware_Server, + SoftLayer_Network_Application_Delivery_Controller, SoftLayer_Network_Vlan, + SoftLayer_Network_Vlan_Firewall, SoftLayer_Network_Component_Firewall, + SoftLayer_Network_Firewall_Module_Context, SoftLayer_Virtual_Guest. """ self.resource_id = resource_id self.resource_type = resource_type diff --git a/test/unit/test_global_tagging_v1.py b/test/unit/test_global_tagging_v1.py index 2e6af5e8..750724be 100644 --- a/test/unit/test_global_tagging_v1.py +++ b/test/unit/test_global_tagging_v1.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# (C) Copyright IBM Corp. 2024. +# (C) Copyright IBM Corp. 2025. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -29,7 +29,9 @@ from ibm_platform_services.global_tagging_v1 import * -_service = GlobalTaggingV1(authenticator=NoAuthAuthenticator()) +_service = GlobalTaggingV1( + authenticator=NoAuthAuthenticator() +) _base_url = 'https://tags.global-search-tagging.cloud.ibm.com' _service.set_service_url(_base_url) @@ -42,15 +44,8 @@ def preprocess_url(operation_path: str): The returned request URL is used to register the mock response so it needs to match the request URL that is formed by the requests library. """ - # First, unquote the path since it might have some quoted/escaped characters in it - # due to how the generator inserts the operation paths into the unit test code. - operation_path = urllib.parse.unquote(operation_path) - # Next, quote the path using urllib so that we approximate what will - # happen during request processing. - operation_path = urllib.parse.quote(operation_path, safe='/') - - # Finally, form the request URL from the base URL and operation path. + # Form the request URL from the base URL and operation path. request_url = _base_url + operation_path # If the request url does NOT end with a /, then just return it as-is. @@ -594,10 +589,15 @@ def test_attach_tag_all_params(self): resource_model['resource_id'] = 'testString' resource_model['resource_type'] = 'testString' + # Construct a dict representation of a QueryString model + query_string_model = {} + query_string_model['query_string'] = 'testString' + # Set up parameter values - resources = [resource_model] tag_name = 'testString' tag_names = ['testString'] + resources = [resource_model] + query = query_string_model x_request_id = 'testString' x_correlation_id = 'testString' account_id = 'testString' @@ -607,9 +607,10 @@ def test_attach_tag_all_params(self): # Invoke method response = _service.attach_tag( - resources, tag_name=tag_name, tag_names=tag_names, + resources=resources, + query=query, x_request_id=x_request_id, x_correlation_id=x_correlation_id, account_id=account_id, @@ -631,9 +632,10 @@ def test_attach_tag_all_params(self): assert 'update={}'.format('true' if update else 'false') in query_string # Validate body params req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['resources'] == [resource_model] assert req_body['tag_name'] == 'testString' assert req_body['tag_names'] == ['testString'] + assert req_body['resources'] == [resource_model] + assert req_body['query'] == query_string_model def test_attach_tag_all_params_with_retries(self): # Enable retries and run test_attach_tag_all_params. @@ -665,16 +667,22 @@ def test_attach_tag_required_params(self): resource_model['resource_id'] = 'testString' resource_model['resource_type'] = 'testString' + # Construct a dict representation of a QueryString model + query_string_model = {} + query_string_model['query_string'] = 'testString' + # Set up parameter values - resources = [resource_model] tag_name = 'testString' tag_names = ['testString'] + resources = [resource_model] + query = query_string_model # Invoke method response = _service.attach_tag( - resources, tag_name=tag_name, tag_names=tag_names, + resources=resources, + query=query, headers={}, ) @@ -683,9 +691,10 @@ def test_attach_tag_required_params(self): assert response.status_code == 200 # Validate body params req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['resources'] == [resource_model] assert req_body['tag_name'] == 'testString' assert req_body['tag_names'] == ['testString'] + assert req_body['resources'] == [resource_model] + assert req_body['query'] == query_string_model def test_attach_tag_required_params_with_retries(self): # Enable retries and run test_attach_tag_required_params. @@ -696,50 +705,6 @@ def test_attach_tag_required_params_with_retries(self): _service.disable_retries() self.test_attach_tag_required_params() - @responses.activate - def test_attach_tag_value_error(self): - """ - test_attach_tag_value_error() - """ - # Set up mock - url = preprocess_url('/v3/tags/attach') - mock_response = '{"results": [{"resource_id": "resource_id", "is_error": true}]}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Construct a dict representation of a Resource model - resource_model = {} - resource_model['resource_id'] = 'testString' - resource_model['resource_type'] = 'testString' - - # Set up parameter values - resources = [resource_model] - tag_name = 'testString' - tag_names = ['testString'] - - # Pass in all but one required param and check for a ValueError - req_param_dict = { - "resources": resources, - } - for param in req_param_dict.keys(): - req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} - with pytest.raises(ValueError): - _service.attach_tag(**req_copy) - - def test_attach_tag_value_error_with_retries(self): - # Enable retries and run test_attach_tag_value_error. - _service.enable_retries() - self.test_attach_tag_value_error() - - # Disable retries and run test_attach_tag_value_error. - _service.disable_retries() - self.test_attach_tag_value_error() - class TestDetachTag: """ @@ -767,10 +732,15 @@ def test_detach_tag_all_params(self): resource_model['resource_id'] = 'testString' resource_model['resource_type'] = 'testString' + # Construct a dict representation of a QueryString model + query_string_model = {} + query_string_model['query_string'] = 'testString' + # Set up parameter values - resources = [resource_model] tag_name = 'testString' tag_names = ['testString'] + resources = [resource_model] + query = query_string_model x_request_id = 'testString' x_correlation_id = 'testString' account_id = 'testString' @@ -778,9 +748,10 @@ def test_detach_tag_all_params(self): # Invoke method response = _service.detach_tag( - resources, tag_name=tag_name, tag_names=tag_names, + resources=resources, + query=query, x_request_id=x_request_id, x_correlation_id=x_correlation_id, account_id=account_id, @@ -798,9 +769,10 @@ def test_detach_tag_all_params(self): assert 'tag_type={}'.format(tag_type) in query_string # Validate body params req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['resources'] == [resource_model] assert req_body['tag_name'] == 'testString' assert req_body['tag_names'] == ['testString'] + assert req_body['resources'] == [resource_model] + assert req_body['query'] == query_string_model def test_detach_tag_all_params_with_retries(self): # Enable retries and run test_detach_tag_all_params. @@ -832,16 +804,22 @@ def test_detach_tag_required_params(self): resource_model['resource_id'] = 'testString' resource_model['resource_type'] = 'testString' + # Construct a dict representation of a QueryString model + query_string_model = {} + query_string_model['query_string'] = 'testString' + # Set up parameter values - resources = [resource_model] tag_name = 'testString' tag_names = ['testString'] + resources = [resource_model] + query = query_string_model # Invoke method response = _service.detach_tag( - resources, tag_name=tag_name, tag_names=tag_names, + resources=resources, + query=query, headers={}, ) @@ -850,9 +828,10 @@ def test_detach_tag_required_params(self): assert response.status_code == 200 # Validate body params req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['resources'] == [resource_model] assert req_body['tag_name'] == 'testString' assert req_body['tag_names'] == ['testString'] + assert req_body['resources'] == [resource_model] + assert req_body['query'] == query_string_model def test_detach_tag_required_params_with_retries(self): # Enable retries and run test_detach_tag_required_params. @@ -863,50 +842,6 @@ def test_detach_tag_required_params_with_retries(self): _service.disable_retries() self.test_detach_tag_required_params() - @responses.activate - def test_detach_tag_value_error(self): - """ - test_detach_tag_value_error() - """ - # Set up mock - url = preprocess_url('/v3/tags/detach') - mock_response = '{"results": [{"resource_id": "resource_id", "is_error": true}]}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Construct a dict representation of a Resource model - resource_model = {} - resource_model['resource_id'] = 'testString' - resource_model['resource_type'] = 'testString' - - # Set up parameter values - resources = [resource_model] - tag_name = 'testString' - tag_names = ['testString'] - - # Pass in all but one required param and check for a ValueError - req_param_dict = { - "resources": resources, - } - for param in req_param_dict.keys(): - req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} - with pytest.raises(ValueError): - _service.detach_tag(**req_copy) - - def test_detach_tag_value_error_with_retries(self): - # Enable retries and run test_detach_tag_value_error. - _service.enable_retries() - self.test_detach_tag_value_error() - - # Disable retries and run test_detach_tag_value_error. - _service.disable_retries() - self.test_detach_tag_value_error() - # endregion ############################################################################## @@ -972,18 +907,12 @@ def test_create_tag_results_results_item_serialization(self): create_tag_results_results_item_model_json['is_error'] = True # Construct a model instance of CreateTagResultsResultsItem by calling from_dict on the json representation - create_tag_results_results_item_model = CreateTagResultsResultsItem.from_dict( - create_tag_results_results_item_model_json - ) + create_tag_results_results_item_model = CreateTagResultsResultsItem.from_dict(create_tag_results_results_item_model_json) assert create_tag_results_results_item_model != False # Construct a model instance of CreateTagResultsResultsItem by calling from_dict on the json representation - create_tag_results_results_item_model_dict = CreateTagResultsResultsItem.from_dict( - create_tag_results_results_item_model_json - ).__dict__ - create_tag_results_results_item_model2 = CreateTagResultsResultsItem( - **create_tag_results_results_item_model_dict - ) + create_tag_results_results_item_model_dict = CreateTagResultsResultsItem.from_dict(create_tag_results_results_item_model_json).__dict__ + create_tag_results_results_item_model2 = CreateTagResultsResultsItem(**create_tag_results_results_item_model_dict) # Verify the model instances are equivalent assert create_tag_results_results_item_model == create_tag_results_results_item_model2 @@ -1069,7 +998,7 @@ def test_delete_tag_results_item_serialization(self): expected_dict = {'foo': 'testString'} delete_tag_results_item_model.set_properties(expected_dict) actual_dict = delete_tag_results_item_model.get_properties() - assert actual_dict == expected_dict + assert actual_dict.keys() == expected_dict.keys() class TestModel_DeleteTagsResult: @@ -1141,6 +1070,36 @@ def test_delete_tags_result_item_serialization(self): assert delete_tags_result_item_model_json2 == delete_tags_result_item_model_json +class TestModel_QueryString: + """ + Test Class for QueryString + """ + + def test_query_string_serialization(self): + """ + Test serialization/deserialization for QueryString + """ + + # Construct a json representation of a QueryString model + query_string_model_json = {} + query_string_model_json['query_string'] = 'testString' + + # Construct a model instance of QueryString by calling from_dict on the json representation + query_string_model = QueryString.from_dict(query_string_model_json) + assert query_string_model != False + + # Construct a model instance of QueryString by calling from_dict on the json representation + query_string_model_dict = QueryString.from_dict(query_string_model_json).__dict__ + query_string_model2 = QueryString(**query_string_model_dict) + + # Verify the model instances are equivalent + assert query_string_model == query_string_model2 + + # Convert model instance back to dict and verify no loss of data + query_string_model_json2 = query_string_model.to_dict() + assert query_string_model_json2 == query_string_model_json + + class TestModel_Resource: """ Test Class for Resource @@ -1253,9 +1212,7 @@ def test_tag_results_serialization(self): # Construct dict forms of any model objects needed in order to build this model. tag_results_item_model = {} # TagResultsItem - tag_results_item_model['resource_id'] = ( - 'crn:v1:staging:public:resource-controller::a/5c2ac0d93c69e82c6c9c7c78dc4beda3::resource-group:1c061f4485b34360a8f8ee049880dc13' - ) + tag_results_item_model['resource_id'] = 'crn:v1:staging:public:resource-controller::a/5c2ac0d93c69e82c6c9c7c78dc4beda3::resource-group:1c061f4485b34360a8f8ee049880dc13' tag_results_item_model['is_error'] = False # Construct a json representation of a TagResults model From b79d16ee7c415f8a671a86ee24623b1c8a868268 Mon Sep 17 00:00:00 2001 From: francescadecicco Date: Tue, 1 Jul 2025 15:02:29 +0200 Subject: [PATCH 2/9] fix(Global Search/Tagging): regenerated services with latest API definition Signed-off-by: francescadecicco --- ibm_platform_services/global_tagging_v1.py | 15 +- test/integration/test_global_tagging_v1.py | 1555 ++++++++++++++++---- 2 files changed, 1239 insertions(+), 331 deletions(-) diff --git a/ibm_platform_services/global_tagging_v1.py b/ibm_platform_services/global_tagging_v1.py index 74f4a591..dd18ed6e 100644 --- a/ibm_platform_services/global_tagging_v1.py +++ b/ibm_platform_services/global_tagging_v1.py @@ -63,9 +63,7 @@ def new_instance( parameters and external configuration. """ authenticator = get_authenticator_from_environment(service_name) - service = cls( - authenticator - ) + service = cls(authenticator) service.configure_service(service_name) return service @@ -682,6 +680,7 @@ class TagType(str, Enum): USER = 'user' SERVICE = 'service' ACCESS = 'access' + class Providers(str, Enum): """ Select a provider. Supported values are `ghost` and `ims`. To list both Global @@ -692,6 +691,7 @@ class Providers(str, Enum): GHOST = 'ghost' IMS = 'ims' + class OrderByName(str, Enum): """ Order the output by tag name. @@ -726,6 +726,7 @@ class Providers(str, Enum): GHOST = 'ghost' IMS = 'ims' + class TagType(str, Enum): """ The type of the tag. Supported values are `user`, `service` and `access`. @@ -751,6 +752,7 @@ class Providers(str, Enum): GHOST = 'ghost' IMS = 'ims' + class TagType(str, Enum): """ The type of the tag. Supported values are `user`, `service` and `access`. @@ -1049,9 +1051,9 @@ def from_dict(cls, _dict: Dict) -> 'DeleteTagResultsItem': args['is_error'] = is_error for k, v in _dict.items(): if k not in cls._properties: - if not isinstance(v, object): - raise ValueError('Value for additional property {} must be of type object'.format(k)) - args[k] = v + if not isinstance(v, object): + raise ValueError('Value for additional property {} must be of type object'.format(k)) + args[k] = v return cls(**args) @classmethod @@ -1116,7 +1118,6 @@ class ProviderEnum(str, Enum): IMS = 'ims' - class DeleteTagsResult: """ Results of deleting unattatched tags. diff --git a/test/integration/test_global_tagging_v1.py b/test/integration/test_global_tagging_v1.py index f2bb8af8..2f34f5d7 100644 --- a/test/integration/test_global_tagging_v1.py +++ b/test/integration/test_global_tagging_v1.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# (C) Copyright IBM Corp. 2020. +# (C) Copyright IBM Corp. 2025. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,360 +12,1267 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + """ -Integration Tests for GlobalTaggingV1 +Unit Tests for GlobalTaggingV1 """ +from ibm_cloud_sdk_core.authenticators.no_auth_authenticator import NoAuthAuthenticator +import inspect +import json import os import pytest -from ibm_cloud_sdk_core import * +import re +import requests +import responses +import urllib from ibm_platform_services.global_tagging_v1 import * -from random import randint - -# Config file name -config_file = 'global_tagging.env' - - -class TestGlobalTaggingV1: - """ - Integration Test Class for GlobalTaggingV1 - """ - - needscredentials = pytest.mark.skipif( - not os.path.exists(config_file), reason="External configuration not available, skipping..." - ) - - @classmethod - def setup_class(cls): - print('\nStarting setup...') - if os.path.exists(config_file): - os.environ['IBM_CREDENTIALS_FILE'] = config_file - - cls.global_tagging_service = GlobalTaggingV1.new_instance() - assert cls.global_tagging_service is not None - - cls.config = read_external_sources(GlobalTaggingV1.DEFAULT_SERVICE_NAME) - assert cls.config is not None - - cls.resource_crn = cls.config.get("RESOURCE_CRN") - assert cls.resource_crn is not None - - assert cls.config["URL"] == cls.global_tagging_service.service_url - - cls.sdk_label = 'python-sdk' - cls.user_tag_1 = cls.sdk_label + '-user-test1' - cls.user_tag_2 = cls.sdk_label + '-user-test2' - cls.access_tag_1 = 'env:' + cls.sdk_label + '-public' - cls.access_tag_2 = 'region:' + cls.sdk_label + '-us-south' - - print('Service URL: ', cls.global_tagging_service.service_url) - print('Resource CRN: ', cls.resource_crn) - - cls.clean_tags(cls) - - print('Setup complete.') - - @classmethod - def teardown_class(cls): - print('\nStarting teardown...') - cls.clean_tags(cls) - print('\nTeardown complete.') - - def clean_tags(self): - print('\nStarted cleaning tags...') - # Detach all user and access tags that contain our label. - tag_names = self.get_tag_names_for_resource(self, self.resource_crn, 'user') - for tag_name in tag_names: - if self.sdk_label in tag_name: - print('Detaching user tag {0} from resource {1}'.format(tag_name, self.resource_crn)) - self.detach_tag(self, self.resource_crn, tag_name, 'user') - tag_names = self.get_tag_names_for_resource(self, self.resource_crn, 'user') - print('Resource now has these user tags: {0}'.format(tag_names)) - - tag_names = self.get_tag_names_for_resource(self, self.resource_crn, 'access') - for tag_name in tag_names: - if self.sdk_label in tag_name: - print('Detaching access tag {0} from resource {1}'.format(tag_name, self.resource_crn)) - self.detach_tag(self, self.resource_crn, tag_name, 'access') - tag_names = self.get_tag_names_for_resource(self, self.resource_crn, 'access') - print('Resource now has these access tags: {0}'.format(tag_names)) - - # Delete all user and access tags that contain our label. - tag_names = self.list_tags_with_label(self, 'user', self.sdk_label) - print('Found {0} user tag(s) that contain our label.'.format(len(tag_names))) - for tag_name in tag_names: - print('Deleting user tag: {0}'.format(tag_name)) - self.delete_tag(self, tag_name, 'user') - - tag_names = self.list_tags_with_label(self, 'access', self.sdk_label) - print('Found {0} access tag(s) that contain our label.'.format(len(tag_names))) - for tag_name in tag_names: - print('Deleting access tag: {0}'.format(tag_name)) - self.delete_tag(self, tag_name, 'access') - - print('\nFinished cleaning tags...') - - def delete_tag(self, tag_name, tag_type): - response = self.global_tagging_service.delete_tag(tag_name=tag_name, tag_type=tag_type) - assert response.get_status_code() == 200 - assert response.get_result() is not None - delete_tag_results = DeleteTagResults.from_dict(response.get_result()) - assert delete_tag_results is not None - for elem in delete_tag_results.results: - assert elem.is_error is False - - def detach_tag(self, resource_id, tag_name, tag_type): - resource_model = {'resource_id': resource_id} - response = self.global_tagging_service.detach_tag( - resources=[resource_model], tag_names=[tag_name], tag_type=tag_type + + +_service = GlobalTaggingV1(authenticator=NoAuthAuthenticator()) + +_base_url = 'https://tags.global-search-tagging.cloud.ibm.com' +_service.set_service_url(_base_url) + + +def preprocess_url(operation_path: str): + """ + Returns the request url associated with the specified operation path. + This will be base_url concatenated with a quoted version of operation_path. + The returned request URL is used to register the mock response so it needs + to match the request URL that is formed by the requests library. + """ + + # Form the request URL from the base URL and operation path. + request_url = _base_url + operation_path + + # If the request url does NOT end with a /, then just return it as-is. + # Otherwise, return a regular expression that matches one or more trailing /. + if not request_url.endswith('/'): + return request_url + return re.compile(request_url.rstrip('/') + '/+') + + +############################################################################## +# Start of Service: Tags +############################################################################## +# region + + +class TestNewInstance: + """ + Test Class for new_instance + """ + + def test_new_instance(self): + """ + new_instance() + """ + os.environ['TEST_SERVICE_AUTH_TYPE'] = 'noAuth' + + service = GlobalTaggingV1.new_instance( + service_name='TEST_SERVICE', ) - assert response.get_status_code() == 200 - assert response.get_result() is not None - tag_results = TagResults.from_dict(response.get_result()) - assert tag_results is not None - for elem in tag_results.results: - assert elem.is_error is False - - def get_tag_names_for_resource(self, resource_id, tag_type): - tag_names = [] - response = self.global_tagging_service.list_tags(attached_to=resource_id, tag_type=tag_type) - tag_list = TagList.from_dict(response.get_result()) - if tag_list.items is not None: - for item in tag_list.items: - tag_names.append(item.name) - return tag_names - - def list_tags_with_label(self, tag_type, label): - tag_names = [] + + assert service is not None + assert isinstance(service, GlobalTaggingV1) + + def test_new_instance_without_authenticator(self): + """ + new_instance_without_authenticator() + """ + with pytest.raises(ValueError, match='authenticator must be provided'): + service = GlobalTaggingV1.new_instance( + service_name='TEST_SERVICE_NOT_FOUND', + ) + + +class TestListTags: + """ + Test Class for list_tags + """ + + @responses.activate + def test_list_tags_all_params(self): + """ + list_tags() + """ + # Set up mock + url = preprocess_url('/v3/tags') + mock_response = '{"total_count": 0, "offset": 0, "limit": 1, "items": [{"name": "name"}]}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + x_request_id = 'testString' + x_correlation_id = 'testString' + account_id = 'testString' + tag_type = 'user' + full_data = False + providers = ['ghost'] + attached_to = 'testString' offset = 0 - more_results = True - while more_results: - list_tags_response = self.global_tagging_service.list_tags(offset=offset, limit=500, tag_type=tag_type) - assert list_tags_response.get_status_code() == 200 - assert list_tags_response.get_result() is not None - - tag_list = TagList.from_dict(list_tags_response.get_result()) - assert tag_list is not None - if len(tag_list.items) > 0: - for tag in tag_list.items: - if self.sdk_label in tag.name: - tag_names.append(tag.name) - offset += len(tag_list.items) - else: - more_results = False - return tag_names - - @needscredentials - def test_create_tag(self): - create_tag_response = self.global_tagging_service.create_tag( - tag_names=[self.access_tag_1, self.access_tag_2], tag_type='access' + limit = 100 + timeout = 0 + order_by_name = 'asc' + attached_only = False + + # Invoke method + response = _service.list_tags( + x_request_id=x_request_id, + x_correlation_id=x_correlation_id, + account_id=account_id, + tag_type=tag_type, + full_data=full_data, + providers=providers, + attached_to=attached_to, + offset=offset, + limit=limit, + timeout=timeout, + order_by_name=order_by_name, + attached_only=attached_only, + headers={}, ) - assert create_tag_response.get_status_code() == 200 - assert create_tag_response.get_result() is not None - create_tag_results = CreateTagResults.from_dict(create_tag_response.get_result()) - assert create_tag_results is not None - print('\ncreate_tag() result: ', json.dumps(create_tag_results.to_dict(), indent=2)) - assert create_tag_results.results is not None - for result in create_tag_results.results: - assert result.is_error is False - - @needscredentials - def test_attach_tag_user(self): - # Construct a dict representation of a Resource model - resource_model = { - 'resource_id': self.resource_crn, - } + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate query params + query_string = responses.calls[0].request.url.split('?', 1)[1] + query_string = urllib.parse.unquote_plus(query_string) + assert 'account_id={}'.format(account_id) in query_string + assert 'tag_type={}'.format(tag_type) in query_string + assert 'full_data={}'.format('true' if full_data else 'false') in query_string + assert 'providers={}'.format(','.join(providers)) in query_string + assert 'attached_to={}'.format(attached_to) in query_string + assert 'offset={}'.format(offset) in query_string + assert 'limit={}'.format(limit) in query_string + assert 'timeout={}'.format(timeout) in query_string + assert 'order_by_name={}'.format(order_by_name) in query_string + assert 'attached_only={}'.format('true' if attached_only else 'false') in query_string + + def test_list_tags_all_params_with_retries(self): + # Enable retries and run test_list_tags_all_params. + _service.enable_retries() + self.test_list_tags_all_params() + + # Disable retries and run test_list_tags_all_params. + _service.disable_retries() + self.test_list_tags_all_params() + + @responses.activate + def test_list_tags_required_params(self): + """ + test_list_tags_required_params() + """ + # Set up mock + url = preprocess_url('/v3/tags') + mock_response = '{"total_count": 0, "offset": 0, "limit": 1, "items": [{"name": "name"}]}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Invoke method + response = _service.list_tags() - attach_tag_response = self.global_tagging_service.attach_tag( - resources=[resource_model], tag_names=[self.user_tag_1, self.user_tag_2], tag_type='user' + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_list_tags_required_params_with_retries(self): + # Enable retries and run test_list_tags_required_params. + _service.enable_retries() + self.test_list_tags_required_params() + + # Disable retries and run test_list_tags_required_params. + _service.disable_retries() + self.test_list_tags_required_params() + + +class TestCreateTag: + """ + Test Class for create_tag + """ + + @responses.activate + def test_create_tag_all_params(self): + """ + create_tag() + """ + # Set up mock + url = preprocess_url('/v3/tags') + mock_response = '{"results": [{"tag_name": "tag_name", "is_error": true}]}' + responses.add( + responses.POST, + url, + body=mock_response, + content_type='application/json', + status=200, ) - assert attach_tag_response.get_status_code() == 200 - assert attach_tag_response.get_result() is not None - tag_results = TagResults.from_dict(attach_tag_response.get_result()) - assert tag_results is not None - print('\nattach_tag(user) result: ', json.dumps(tag_results.to_dict(), indent=2)) + # Set up parameter values + tag_names = ['testString'] + x_request_id = 'testString' + x_correlation_id = 'testString' + account_id = 'testString' + tag_type = 'access' + + # Invoke method + response = _service.create_tag( + tag_names, + x_request_id=x_request_id, + x_correlation_id=x_correlation_id, + account_id=account_id, + tag_type=tag_type, + headers={}, + ) - for elem in tag_results.results: - assert elem.is_error is False + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate query params + query_string = responses.calls[0].request.url.split('?', 1)[1] + query_string = urllib.parse.unquote_plus(query_string) + assert 'account_id={}'.format(account_id) in query_string + assert 'tag_type={}'.format(tag_type) in query_string + # Validate body params + req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) + assert req_body['tag_names'] == ['testString'] + + def test_create_tag_all_params_with_retries(self): + # Enable retries and run test_create_tag_all_params. + _service.enable_retries() + self.test_create_tag_all_params() + + # Disable retries and run test_create_tag_all_params. + _service.disable_retries() + self.test_create_tag_all_params() + + @responses.activate + def test_create_tag_required_params(self): + """ + test_create_tag_required_params() + """ + # Set up mock + url = preprocess_url('/v3/tags') + mock_response = '{"results": [{"tag_name": "tag_name", "is_error": true}]}' + responses.add( + responses.POST, + url, + body=mock_response, + content_type='application/json', + status=200, + ) - # Make sure the tags are in fact attached to the resource. - tag_names = self.get_tag_names_for_resource(resource_id=self.resource_crn, tag_type='user') - assert self.user_tag_1 in tag_names - assert self.user_tag_2 in tag_names + # Set up parameter values + tag_names = ['testString'] - @needscredentials - def test_attach_tag_access(self): - # Construct a dict representation of a Resource model - resource_model = { - 'resource_id': self.resource_crn, + # Invoke method + response = _service.create_tag( + tag_names, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate body params + req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) + assert req_body['tag_names'] == ['testString'] + + def test_create_tag_required_params_with_retries(self): + # Enable retries and run test_create_tag_required_params. + _service.enable_retries() + self.test_create_tag_required_params() + + # Disable retries and run test_create_tag_required_params. + _service.disable_retries() + self.test_create_tag_required_params() + + @responses.activate + def test_create_tag_value_error(self): + """ + test_create_tag_value_error() + """ + # Set up mock + url = preprocess_url('/v3/tags') + mock_response = '{"results": [{"tag_name": "tag_name", "is_error": true}]}' + responses.add( + responses.POST, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + tag_names = ['testString'] + + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "tag_names": tag_names, } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.create_tag(**req_copy) - attach_tag_response = self.global_tagging_service.attach_tag( - resources=[resource_model], tag_names=[self.access_tag_1, self.access_tag_2], tag_type='access' + def test_create_tag_value_error_with_retries(self): + # Enable retries and run test_create_tag_value_error. + _service.enable_retries() + self.test_create_tag_value_error() + + # Disable retries and run test_create_tag_value_error. + _service.disable_retries() + self.test_create_tag_value_error() + + +class TestDeleteTagAll: + """ + Test Class for delete_tag_all + """ + + @responses.activate + def test_delete_tag_all_all_params(self): + """ + delete_tag_all() + """ + # Set up mock + url = preprocess_url('/v3/tags') + mock_response = '{"total_count": 11, "errors": true, "items": [{"tag_name": "tag_name", "is_error": true}]}' + responses.add( + responses.DELETE, + url, + body=mock_response, + content_type='application/json', + status=200, ) - assert attach_tag_response.get_status_code() == 200 - assert attach_tag_response.get_result() is not None - tag_results = TagResults.from_dict(attach_tag_response.get_result()) - assert tag_results is not None - print('\nattach_tag(access) result: ', json.dumps(tag_results.to_dict(), indent=2)) + # Set up parameter values + x_request_id = 'testString' + x_correlation_id = 'testString' + providers = 'ghost' + account_id = 'testString' + tag_type = 'user' + + # Invoke method + response = _service.delete_tag_all( + x_request_id=x_request_id, + x_correlation_id=x_correlation_id, + providers=providers, + account_id=account_id, + tag_type=tag_type, + headers={}, + ) - for elem in tag_results.results: - assert elem.is_error is False + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate query params + query_string = responses.calls[0].request.url.split('?', 1)[1] + query_string = urllib.parse.unquote_plus(query_string) + assert 'providers={}'.format(providers) in query_string + assert 'account_id={}'.format(account_id) in query_string + assert 'tag_type={}'.format(tag_type) in query_string + + def test_delete_tag_all_all_params_with_retries(self): + # Enable retries and run test_delete_tag_all_all_params. + _service.enable_retries() + self.test_delete_tag_all_all_params() + + # Disable retries and run test_delete_tag_all_all_params. + _service.disable_retries() + self.test_delete_tag_all_all_params() + + @responses.activate + def test_delete_tag_all_required_params(self): + """ + test_delete_tag_all_required_params() + """ + # Set up mock + url = preprocess_url('/v3/tags') + mock_response = '{"total_count": 11, "errors": true, "items": [{"tag_name": "tag_name", "is_error": true}]}' + responses.add( + responses.DELETE, + url, + body=mock_response, + content_type='application/json', + status=200, + ) - # Make sure the tags are in fact attached to the resource. - tag_names = self.get_tag_names_for_resource(resource_id=self.resource_crn, tag_type='access') - assert self.access_tag_1 in tag_names - assert self.access_tag_2 in tag_names + # Invoke method + response = _service.delete_tag_all() + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_delete_tag_all_required_params_with_retries(self): + # Enable retries and run test_delete_tag_all_required_params. + _service.enable_retries() + self.test_delete_tag_all_required_params() + + # Disable retries and run test_delete_tag_all_required_params. + _service.disable_retries() + self.test_delete_tag_all_required_params() + + +class TestDeleteTag: + """ + Test Class for delete_tag + """ + + @responses.activate + def test_delete_tag_all_params(self): + """ + delete_tag() + """ + # Set up mock + url = preprocess_url('/v3/tags/testString') + mock_response = '{"results": [{"provider": "ghost", "is_error": true}]}' + responses.add( + responses.DELETE, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + tag_name = 'testString' + x_request_id = 'testString' + x_correlation_id = 'testString' + providers = ['ghost'] + account_id = 'testString' + tag_type = 'user' + + # Invoke method + response = _service.delete_tag( + tag_name, + x_request_id=x_request_id, + x_correlation_id=x_correlation_id, + providers=providers, + account_id=account_id, + tag_type=tag_type, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate query params + query_string = responses.calls[0].request.url.split('?', 1)[1] + query_string = urllib.parse.unquote_plus(query_string) + assert 'providers={}'.format(','.join(providers)) in query_string + assert 'account_id={}'.format(account_id) in query_string + assert 'tag_type={}'.format(tag_type) in query_string + + def test_delete_tag_all_params_with_retries(self): + # Enable retries and run test_delete_tag_all_params. + _service.enable_retries() + self.test_delete_tag_all_params() + + # Disable retries and run test_delete_tag_all_params. + _service.disable_retries() + self.test_delete_tag_all_params() + + @responses.activate + def test_delete_tag_required_params(self): + """ + test_delete_tag_required_params() + """ + # Set up mock + url = preprocess_url('/v3/tags/testString') + mock_response = '{"results": [{"provider": "ghost", "is_error": true}]}' + responses.add( + responses.DELETE, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + tag_name = 'testString' + + # Invoke method + response = _service.delete_tag( + tag_name, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_delete_tag_required_params_with_retries(self): + # Enable retries and run test_delete_tag_required_params. + _service.enable_retries() + self.test_delete_tag_required_params() + + # Disable retries and run test_delete_tag_required_params. + _service.disable_retries() + self.test_delete_tag_required_params() + + @responses.activate + def test_delete_tag_value_error(self): + """ + test_delete_tag_value_error() + """ + # Set up mock + url = preprocess_url('/v3/tags/testString') + mock_response = '{"results": [{"provider": "ghost", "is_error": true}]}' + responses.add( + responses.DELETE, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + tag_name = 'testString' + + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "tag_name": tag_name, + } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.delete_tag(**req_copy) + + def test_delete_tag_value_error_with_retries(self): + # Enable retries and run test_delete_tag_value_error. + _service.enable_retries() + self.test_delete_tag_value_error() + + # Disable retries and run test_delete_tag_value_error. + _service.disable_retries() + self.test_delete_tag_value_error() + + +class TestAttachTag: + """ + Test Class for attach_tag + """ + + @responses.activate + def test_attach_tag_all_params(self): + """ + attach_tag() + """ + # Set up mock + url = preprocess_url('/v3/tags/attach') + mock_response = '{"results": [{"resource_id": "resource_id", "is_error": true}]}' + responses.add( + responses.POST, + url, + body=mock_response, + content_type='application/json', + status=200, + ) - @needscredentials - def test_list_tags_user(self): - tags = [] - offset = 0 - more_results = True - while more_results: - list_tags_response = self.global_tagging_service.list_tags(offset=offset, limit=500, tag_type='user') - assert list_tags_response.get_status_code() == 200 - assert list_tags_response.get_result() is not None - - tag_list = TagList.from_dict(list_tags_response.get_result()) - assert tag_list is not None - if len(tag_list.items) > 0: - for item in tag_list.items: - tags.append(item) - offset += len(tag_list.items) - else: - more_results = False - - print('\nRetrieved a total of {0} user tags.'.format(len(tags))) - matches = [] - for tag in tags: - if self.sdk_label in tag.name: - matches.append(tag.name) - print('Found {0} user tags containing our label: {1}'.format(len(matches), matches)) - - @needscredentials - def test_list_tags_access(self): - tags = [] - offset = 0 - more_results = True - while more_results: - list_tags_response = self.global_tagging_service.list_tags(offset=offset, limit=500, tag_type='access') - assert list_tags_response.get_status_code() == 200 - assert list_tags_response.get_result() is not None - - tag_list = TagList.from_dict(list_tags_response.get_result()) - assert tag_list is not None - if len(tag_list.items) > 0: - for item in tag_list.items: - tags.append(item) - offset += len(tag_list.items) - else: - more_results = False - - print('\nRetrieved a total of {0} access tags.'.format(len(tags))) - matches = [] - for tag in tags: - if self.sdk_label in tag.name: - matches.append(tag.name) - print('Found {0} access tags containing our label: {1}'.format(len(matches), matches)) - - @needscredentials - def test_detach_tag_user(self): # Construct a dict representation of a Resource model - resource_model = {'resource_id': self.resource_crn} + resource_model = {} + resource_model['resource_id'] = 'testString' + resource_model['resource_type'] = 'testString' + + # Construct a dict representation of a QueryString model + query_string_model = {} + query_string_model['query_string'] = 'testString' + + # Set up parameter values + tag_name = 'testString' + tag_names = ['testString'] + resources = [resource_model] + query = query_string_model + x_request_id = 'testString' + x_correlation_id = 'testString' + account_id = 'testString' + tag_type = 'user' + replace = False + update = False + + # Invoke method + response = _service.attach_tag( + tag_name=tag_name, + tag_names=tag_names, + resources=resources, + query=query, + x_request_id=x_request_id, + x_correlation_id=x_correlation_id, + account_id=account_id, + tag_type=tag_type, + replace=replace, + update=update, + headers={}, + ) - detach_tag_response = self.global_tagging_service.detach_tag( - resources=[resource_model], tag_names=[self.user_tag_1, self.user_tag_2], tag_type='user' + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate query params + query_string = responses.calls[0].request.url.split('?', 1)[1] + query_string = urllib.parse.unquote_plus(query_string) + assert 'account_id={}'.format(account_id) in query_string + assert 'tag_type={}'.format(tag_type) in query_string + assert 'replace={}'.format('true' if replace else 'false') in query_string + assert 'update={}'.format('true' if update else 'false') in query_string + # Validate body params + req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) + assert req_body['tag_name'] == 'testString' + assert req_body['tag_names'] == ['testString'] + assert req_body['resources'] == [resource_model] + assert req_body['query'] == query_string_model + + def test_attach_tag_all_params_with_retries(self): + # Enable retries and run test_attach_tag_all_params. + _service.enable_retries() + self.test_attach_tag_all_params() + + # Disable retries and run test_attach_tag_all_params. + _service.disable_retries() + self.test_attach_tag_all_params() + + @responses.activate + def test_attach_tag_required_params(self): + """ + test_attach_tag_required_params() + """ + # Set up mock + url = preprocess_url('/v3/tags/attach') + mock_response = '{"results": [{"resource_id": "resource_id", "is_error": true}]}' + responses.add( + responses.POST, + url, + body=mock_response, + content_type='application/json', + status=200, ) - assert detach_tag_response.get_status_code() == 200 - assert detach_tag_response.get_result() is not None - tag_results = TagResults.from_dict(detach_tag_response.get_result()) - assert tag_results is not None - print('\ndetach_tag(user) result: ', json.dumps(tag_results.to_dict(), indent=2)) + # Construct a dict representation of a Resource model + resource_model = {} + resource_model['resource_id'] = 'testString' + resource_model['resource_type'] = 'testString' + + # Construct a dict representation of a QueryString model + query_string_model = {} + query_string_model['query_string'] = 'testString' + + # Set up parameter values + tag_name = 'testString' + tag_names = ['testString'] + resources = [resource_model] + query = query_string_model + + # Invoke method + response = _service.attach_tag( + tag_name=tag_name, + tag_names=tag_names, + resources=resources, + query=query, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate body params + req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) + assert req_body['tag_name'] == 'testString' + assert req_body['tag_names'] == ['testString'] + assert req_body['resources'] == [resource_model] + assert req_body['query'] == query_string_model + + def test_attach_tag_required_params_with_retries(self): + # Enable retries and run test_attach_tag_required_params. + _service.enable_retries() + self.test_attach_tag_required_params() + + # Disable retries and run test_attach_tag_required_params. + _service.disable_retries() + self.test_attach_tag_required_params() - for elem in tag_results.results: - assert elem.is_error is False - # Make sure the tag is in fact attached to the resource - tag_names = self.get_tag_names_for_resource(self.resource_crn, 'user') - assert self.user_tag_1 not in tag_names - assert self.user_tag_2 not in tag_names +class TestDetachTag: + """ + Test Class for detach_tag + """ + + @responses.activate + def test_detach_tag_all_params(self): + """ + detach_tag() + """ + # Set up mock + url = preprocess_url('/v3/tags/detach') + mock_response = '{"results": [{"resource_id": "resource_id", "is_error": true}]}' + responses.add( + responses.POST, + url, + body=mock_response, + content_type='application/json', + status=200, + ) - @needscredentials - def test_detach_tag_access(self): # Construct a dict representation of a Resource model - resource_model = {'resource_id': self.resource_crn} + resource_model = {} + resource_model['resource_id'] = 'testString' + resource_model['resource_type'] = 'testString' + + # Construct a dict representation of a QueryString model + query_string_model = {} + query_string_model['query_string'] = 'testString' + + # Set up parameter values + tag_name = 'testString' + tag_names = ['testString'] + resources = [resource_model] + query = query_string_model + x_request_id = 'testString' + x_correlation_id = 'testString' + account_id = 'testString' + tag_type = 'user' + + # Invoke method + response = _service.detach_tag( + tag_name=tag_name, + tag_names=tag_names, + resources=resources, + query=query, + x_request_id=x_request_id, + x_correlation_id=x_correlation_id, + account_id=account_id, + tag_type=tag_type, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate query params + query_string = responses.calls[0].request.url.split('?', 1)[1] + query_string = urllib.parse.unquote_plus(query_string) + assert 'account_id={}'.format(account_id) in query_string + assert 'tag_type={}'.format(tag_type) in query_string + # Validate body params + req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) + assert req_body['tag_name'] == 'testString' + assert req_body['tag_names'] == ['testString'] + assert req_body['resources'] == [resource_model] + assert req_body['query'] == query_string_model + + def test_detach_tag_all_params_with_retries(self): + # Enable retries and run test_detach_tag_all_params. + _service.enable_retries() + self.test_detach_tag_all_params() + + # Disable retries and run test_detach_tag_all_params. + _service.disable_retries() + self.test_detach_tag_all_params() + + @responses.activate + def test_detach_tag_required_params(self): + """ + test_detach_tag_required_params() + """ + # Set up mock + url = preprocess_url('/v3/tags/detach') + mock_response = '{"results": [{"resource_id": "resource_id", "is_error": true}]}' + responses.add( + responses.POST, + url, + body=mock_response, + content_type='application/json', + status=200, + ) - detach_tag_response = self.global_tagging_service.detach_tag( - resources=[resource_model], tag_names=[self.access_tag_1, self.access_tag_2], tag_type='access' + # Construct a dict representation of a Resource model + resource_model = {} + resource_model['resource_id'] = 'testString' + resource_model['resource_type'] = 'testString' + + # Construct a dict representation of a QueryString model + query_string_model = {} + query_string_model['query_string'] = 'testString' + + # Set up parameter values + tag_name = 'testString' + tag_names = ['testString'] + resources = [resource_model] + query = query_string_model + + # Invoke method + response = _service.detach_tag( + tag_name=tag_name, + tag_names=tag_names, + resources=resources, + query=query, + headers={}, ) - assert detach_tag_response.get_status_code() == 200 - assert detach_tag_response.get_result() is not None - tag_results = TagResults.from_dict(detach_tag_response.get_result()) - assert tag_results is not None - print('\ndetach_tag(access) result: ', json.dumps(tag_results.to_dict(), indent=2)) - - for elem in tag_results.results: - assert elem.is_error is False - - # Make sure the tag is in fact attached to the resource - tag_names = self.get_tag_names_for_resource(self.resource_crn, 'access') - assert self.access_tag_1 not in tag_names - assert self.access_tag_2 not in tag_names - - @needscredentials - def test_delete_tag_user(self): - delete_tag_response = self.global_tagging_service.delete_tag(tag_name=self.user_tag_1, tag_type='user') - - assert delete_tag_response.get_status_code() == 200 - assert delete_tag_response.get_result() is not None - delete_tag_results = DeleteTagResults.from_dict(delete_tag_response.get_result()) - assert delete_tag_results is not None - print('\ndelete_tag(user) result: ', json.dumps(delete_tag_results.to_dict(), indent=2)) - - for item in delete_tag_results.results: - assert item.is_error is False - - @needscredentials - def test_delete_tag_access(self): - delete_tag_response = self.global_tagging_service.delete_tag(tag_name=self.access_tag_1, tag_type='access') - - assert delete_tag_response.get_status_code() == 200 - assert delete_tag_response.get_result() is not None - delete_tag_results = DeleteTagResults.from_dict(delete_tag_response.get_result()) - assert delete_tag_results is not None - print('\ndelete_tag(access) result: ', json.dumps(delete_tag_results.to_dict(), indent=2)) - - for item in delete_tag_results.results: - assert item.is_error is False - - @needscredentials - def test_delete_tag_all_user(self): - delete_tag_all_response = self.global_tagging_service.delete_tag_all(tag_type='user') - - assert delete_tag_all_response.get_status_code() == 200 - assert delete_tag_all_response.get_result() is not None - delete_tags_result = DeleteTagsResult.from_dict(delete_tag_all_response.get_result()) - assert delete_tags_result is not None - print('\ndelete_tag_all(user) result: ', json.dumps(delete_tags_result.to_dict(), indent=2)) - - for item in delete_tags_result.items: - assert item.is_error is False - - @needscredentials - def test_delete_tag_all_access(self): - delete_tag_all_response = self.global_tagging_service.delete_tag_all(tag_type='access') - - assert delete_tag_all_response.get_status_code() == 200 - assert delete_tag_all_response.get_result() is not None - delete_tags_result = DeleteTagsResult.from_dict(delete_tag_all_response.get_result()) - assert delete_tags_result is not None - print('\ndelete_tag_all(access) result: ', json.dumps(delete_tags_result.to_dict(), indent=2)) - - for item in delete_tags_result.items: - assert item.is_error is False + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate body params + req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) + assert req_body['tag_name'] == 'testString' + assert req_body['tag_names'] == ['testString'] + assert req_body['resources'] == [resource_model] + assert req_body['query'] == query_string_model + + def test_detach_tag_required_params_with_retries(self): + # Enable retries and run test_detach_tag_required_params. + _service.enable_retries() + self.test_detach_tag_required_params() + + # Disable retries and run test_detach_tag_required_params. + _service.disable_retries() + self.test_detach_tag_required_params() + + +# endregion +############################################################################## +# End of Service: Tags +############################################################################## + + +############################################################################## +# Start of Model Tests +############################################################################## +# region + + +class TestModel_CreateTagResults: + """ + Test Class for CreateTagResults + """ + + def test_create_tag_results_serialization(self): + """ + Test serialization/deserialization for CreateTagResults + """ + + # Construct dict forms of any model objects needed in order to build this model. + + create_tag_results_results_item_model = {} # CreateTagResultsResultsItem + create_tag_results_results_item_model['tag_name'] = 'testString' + create_tag_results_results_item_model['is_error'] = True + + # Construct a json representation of a CreateTagResults model + create_tag_results_model_json = {} + create_tag_results_model_json['results'] = [create_tag_results_results_item_model] + + # Construct a model instance of CreateTagResults by calling from_dict on the json representation + create_tag_results_model = CreateTagResults.from_dict(create_tag_results_model_json) + assert create_tag_results_model != False + + # Construct a model instance of CreateTagResults by calling from_dict on the json representation + create_tag_results_model_dict = CreateTagResults.from_dict(create_tag_results_model_json).__dict__ + create_tag_results_model2 = CreateTagResults(**create_tag_results_model_dict) + + # Verify the model instances are equivalent + assert create_tag_results_model == create_tag_results_model2 + + # Convert model instance back to dict and verify no loss of data + create_tag_results_model_json2 = create_tag_results_model.to_dict() + assert create_tag_results_model_json2 == create_tag_results_model_json + + +class TestModel_CreateTagResultsResultsItem: + """ + Test Class for CreateTagResultsResultsItem + """ + + def test_create_tag_results_results_item_serialization(self): + """ + Test serialization/deserialization for CreateTagResultsResultsItem + """ + + # Construct a json representation of a CreateTagResultsResultsItem model + create_tag_results_results_item_model_json = {} + create_tag_results_results_item_model_json['tag_name'] = 'testString' + create_tag_results_results_item_model_json['is_error'] = True + + # Construct a model instance of CreateTagResultsResultsItem by calling from_dict on the json representation + create_tag_results_results_item_model = CreateTagResultsResultsItem.from_dict( + create_tag_results_results_item_model_json + ) + assert create_tag_results_results_item_model != False + + # Construct a model instance of CreateTagResultsResultsItem by calling from_dict on the json representation + create_tag_results_results_item_model_dict = CreateTagResultsResultsItem.from_dict( + create_tag_results_results_item_model_json + ).__dict__ + create_tag_results_results_item_model2 = CreateTagResultsResultsItem( + **create_tag_results_results_item_model_dict + ) + + # Verify the model instances are equivalent + assert create_tag_results_results_item_model == create_tag_results_results_item_model2 + + # Convert model instance back to dict and verify no loss of data + create_tag_results_results_item_model_json2 = create_tag_results_results_item_model.to_dict() + assert create_tag_results_results_item_model_json2 == create_tag_results_results_item_model_json + + +class TestModel_DeleteTagResults: + """ + Test Class for DeleteTagResults + """ + + def test_delete_tag_results_serialization(self): + """ + Test serialization/deserialization for DeleteTagResults + """ + + # Construct dict forms of any model objects needed in order to build this model. + + delete_tag_results_item_model = {} # DeleteTagResultsItem + delete_tag_results_item_model['provider'] = 'ghost' + delete_tag_results_item_model['is_error'] = True + delete_tag_results_item_model['foo'] = 'testString' + + # Construct a json representation of a DeleteTagResults model + delete_tag_results_model_json = {} + delete_tag_results_model_json['results'] = [delete_tag_results_item_model] + + # Construct a model instance of DeleteTagResults by calling from_dict on the json representation + delete_tag_results_model = DeleteTagResults.from_dict(delete_tag_results_model_json) + assert delete_tag_results_model != False + + # Construct a model instance of DeleteTagResults by calling from_dict on the json representation + delete_tag_results_model_dict = DeleteTagResults.from_dict(delete_tag_results_model_json).__dict__ + delete_tag_results_model2 = DeleteTagResults(**delete_tag_results_model_dict) + + # Verify the model instances are equivalent + assert delete_tag_results_model == delete_tag_results_model2 + + # Convert model instance back to dict and verify no loss of data + delete_tag_results_model_json2 = delete_tag_results_model.to_dict() + assert delete_tag_results_model_json2 == delete_tag_results_model_json + + +class TestModel_DeleteTagResultsItem: + """ + Test Class for DeleteTagResultsItem + """ + + def test_delete_tag_results_item_serialization(self): + """ + Test serialization/deserialization for DeleteTagResultsItem + """ + + # Construct a json representation of a DeleteTagResultsItem model + delete_tag_results_item_model_json = {} + delete_tag_results_item_model_json['provider'] = 'ghost' + delete_tag_results_item_model_json['is_error'] = True + delete_tag_results_item_model_json['foo'] = 'testString' + + # Construct a model instance of DeleteTagResultsItem by calling from_dict on the json representation + delete_tag_results_item_model = DeleteTagResultsItem.from_dict(delete_tag_results_item_model_json) + assert delete_tag_results_item_model != False + + # Construct a model instance of DeleteTagResultsItem by calling from_dict on the json representation + delete_tag_results_item_model_dict = DeleteTagResultsItem.from_dict(delete_tag_results_item_model_json).__dict__ + delete_tag_results_item_model2 = DeleteTagResultsItem(**delete_tag_results_item_model_dict) + + # Verify the model instances are equivalent + assert delete_tag_results_item_model == delete_tag_results_item_model2 + + # Convert model instance back to dict and verify no loss of data + delete_tag_results_item_model_json2 = delete_tag_results_item_model.to_dict() + assert delete_tag_results_item_model_json2 == delete_tag_results_item_model_json + + # Test get_properties and set_properties methods. + delete_tag_results_item_model.set_properties({}) + actual_dict = delete_tag_results_item_model.get_properties() + assert actual_dict == {} + + expected_dict = {'foo': 'testString'} + delete_tag_results_item_model.set_properties(expected_dict) + actual_dict = delete_tag_results_item_model.get_properties() + assert actual_dict.keys() == expected_dict.keys() + + +class TestModel_DeleteTagsResult: + """ + Test Class for DeleteTagsResult + """ + + def test_delete_tags_result_serialization(self): + """ + Test serialization/deserialization for DeleteTagsResult + """ + + # Construct dict forms of any model objects needed in order to build this model. + + delete_tags_result_item_model = {} # DeleteTagsResultItem + delete_tags_result_item_model['tag_name'] = 'testString' + delete_tags_result_item_model['is_error'] = True + + # Construct a json representation of a DeleteTagsResult model + delete_tags_result_model_json = {} + delete_tags_result_model_json['total_count'] = 38 + delete_tags_result_model_json['errors'] = True + delete_tags_result_model_json['items'] = [delete_tags_result_item_model] + + # Construct a model instance of DeleteTagsResult by calling from_dict on the json representation + delete_tags_result_model = DeleteTagsResult.from_dict(delete_tags_result_model_json) + assert delete_tags_result_model != False + + # Construct a model instance of DeleteTagsResult by calling from_dict on the json representation + delete_tags_result_model_dict = DeleteTagsResult.from_dict(delete_tags_result_model_json).__dict__ + delete_tags_result_model2 = DeleteTagsResult(**delete_tags_result_model_dict) + + # Verify the model instances are equivalent + assert delete_tags_result_model == delete_tags_result_model2 + + # Convert model instance back to dict and verify no loss of data + delete_tags_result_model_json2 = delete_tags_result_model.to_dict() + assert delete_tags_result_model_json2 == delete_tags_result_model_json + + +class TestModel_DeleteTagsResultItem: + """ + Test Class for DeleteTagsResultItem + """ + + def test_delete_tags_result_item_serialization(self): + """ + Test serialization/deserialization for DeleteTagsResultItem + """ + + # Construct a json representation of a DeleteTagsResultItem model + delete_tags_result_item_model_json = {} + delete_tags_result_item_model_json['tag_name'] = 'testString' + delete_tags_result_item_model_json['is_error'] = True + + # Construct a model instance of DeleteTagsResultItem by calling from_dict on the json representation + delete_tags_result_item_model = DeleteTagsResultItem.from_dict(delete_tags_result_item_model_json) + assert delete_tags_result_item_model != False + + # Construct a model instance of DeleteTagsResultItem by calling from_dict on the json representation + delete_tags_result_item_model_dict = DeleteTagsResultItem.from_dict(delete_tags_result_item_model_json).__dict__ + delete_tags_result_item_model2 = DeleteTagsResultItem(**delete_tags_result_item_model_dict) + + # Verify the model instances are equivalent + assert delete_tags_result_item_model == delete_tags_result_item_model2 + + # Convert model instance back to dict and verify no loss of data + delete_tags_result_item_model_json2 = delete_tags_result_item_model.to_dict() + assert delete_tags_result_item_model_json2 == delete_tags_result_item_model_json + + +class TestModel_QueryString: + """ + Test Class for QueryString + """ + + def test_query_string_serialization(self): + """ + Test serialization/deserialization for QueryString + """ + + # Construct a json representation of a QueryString model + query_string_model_json = {} + query_string_model_json['query_string'] = 'testString' + + # Construct a model instance of QueryString by calling from_dict on the json representation + query_string_model = QueryString.from_dict(query_string_model_json) + assert query_string_model != False + + # Construct a model instance of QueryString by calling from_dict on the json representation + query_string_model_dict = QueryString.from_dict(query_string_model_json).__dict__ + query_string_model2 = QueryString(**query_string_model_dict) + + # Verify the model instances are equivalent + assert query_string_model == query_string_model2 + + # Convert model instance back to dict and verify no loss of data + query_string_model_json2 = query_string_model.to_dict() + assert query_string_model_json2 == query_string_model_json + + +class TestModel_Resource: + """ + Test Class for Resource + """ + + def test_resource_serialization(self): + """ + Test serialization/deserialization for Resource + """ + + # Construct a json representation of a Resource model + resource_model_json = {} + resource_model_json['resource_id'] = 'testString' + resource_model_json['resource_type'] = 'testString' + + # Construct a model instance of Resource by calling from_dict on the json representation + resource_model = Resource.from_dict(resource_model_json) + assert resource_model != False + + # Construct a model instance of Resource by calling from_dict on the json representation + resource_model_dict = Resource.from_dict(resource_model_json).__dict__ + resource_model2 = Resource(**resource_model_dict) + + # Verify the model instances are equivalent + assert resource_model == resource_model2 + + # Convert model instance back to dict and verify no loss of data + resource_model_json2 = resource_model.to_dict() + assert resource_model_json2 == resource_model_json + + +class TestModel_Tag: + """ + Test Class for Tag + """ + + def test_tag_serialization(self): + """ + Test serialization/deserialization for Tag + """ + + # Construct a json representation of a Tag model + tag_model_json = {} + tag_model_json['name'] = 'testString' + + # Construct a model instance of Tag by calling from_dict on the json representation + tag_model = Tag.from_dict(tag_model_json) + assert tag_model != False + + # Construct a model instance of Tag by calling from_dict on the json representation + tag_model_dict = Tag.from_dict(tag_model_json).__dict__ + tag_model2 = Tag(**tag_model_dict) + + # Verify the model instances are equivalent + assert tag_model == tag_model2 + + # Convert model instance back to dict and verify no loss of data + tag_model_json2 = tag_model.to_dict() + assert tag_model_json2 == tag_model_json + + +class TestModel_TagList: + """ + Test Class for TagList + """ + + def test_tag_list_serialization(self): + """ + Test serialization/deserialization for TagList + """ + + # Construct dict forms of any model objects needed in order to build this model. + + tag_model = {} # Tag + tag_model['name'] = 'testString' + + # Construct a json representation of a TagList model + tag_list_model_json = {} + tag_list_model_json['total_count'] = 0 + tag_list_model_json['offset'] = 0 + tag_list_model_json['limit'] = 1 + tag_list_model_json['items'] = [tag_model] + + # Construct a model instance of TagList by calling from_dict on the json representation + tag_list_model = TagList.from_dict(tag_list_model_json) + assert tag_list_model != False + + # Construct a model instance of TagList by calling from_dict on the json representation + tag_list_model_dict = TagList.from_dict(tag_list_model_json).__dict__ + tag_list_model2 = TagList(**tag_list_model_dict) + + # Verify the model instances are equivalent + assert tag_list_model == tag_list_model2 + + # Convert model instance back to dict and verify no loss of data + tag_list_model_json2 = tag_list_model.to_dict() + assert tag_list_model_json2 == tag_list_model_json + + +class TestModel_TagResults: + """ + Test Class for TagResults + """ + + def test_tag_results_serialization(self): + """ + Test serialization/deserialization for TagResults + """ + + # Construct dict forms of any model objects needed in order to build this model. + + tag_results_item_model = {} # TagResultsItem + tag_results_item_model['resource_id'] = ( + 'crn:v1:staging:public:resource-controller::a/5c2ac0d93c69e82c6c9c7c78dc4beda3::resource-group:1c061f4485b34360a8f8ee049880dc13' + ) + tag_results_item_model['is_error'] = False + + # Construct a json representation of a TagResults model + tag_results_model_json = {} + tag_results_model_json['results'] = [tag_results_item_model] + + # Construct a model instance of TagResults by calling from_dict on the json representation + tag_results_model = TagResults.from_dict(tag_results_model_json) + assert tag_results_model != False + + # Construct a model instance of TagResults by calling from_dict on the json representation + tag_results_model_dict = TagResults.from_dict(tag_results_model_json).__dict__ + tag_results_model2 = TagResults(**tag_results_model_dict) + + # Verify the model instances are equivalent + assert tag_results_model == tag_results_model2 + + # Convert model instance back to dict and verify no loss of data + tag_results_model_json2 = tag_results_model.to_dict() + assert tag_results_model_json2 == tag_results_model_json + + +class TestModel_TagResultsItem: + """ + Test Class for TagResultsItem + """ + + def test_tag_results_item_serialization(self): + """ + Test serialization/deserialization for TagResultsItem + """ + + # Construct a json representation of a TagResultsItem model + tag_results_item_model_json = {} + tag_results_item_model_json['resource_id'] = 'testString' + tag_results_item_model_json['is_error'] = True + + # Construct a model instance of TagResultsItem by calling from_dict on the json representation + tag_results_item_model = TagResultsItem.from_dict(tag_results_item_model_json) + assert tag_results_item_model != False + + # Construct a model instance of TagResultsItem by calling from_dict on the json representation + tag_results_item_model_dict = TagResultsItem.from_dict(tag_results_item_model_json).__dict__ + tag_results_item_model2 = TagResultsItem(**tag_results_item_model_dict) + + # Verify the model instances are equivalent + assert tag_results_item_model == tag_results_item_model2 + + # Convert model instance back to dict and verify no loss of data + tag_results_item_model_json2 = tag_results_item_model.to_dict() + assert tag_results_item_model_json2 == tag_results_item_model_json + + +# endregion +############################################################################## +# End of Model Tests +############################################################################## From ca810c74af2a04e259b46902a1816a61eb5626dc Mon Sep 17 00:00:00 2001 From: francescadecicco Date: Tue, 1 Jul 2025 15:14:25 +0200 Subject: [PATCH 3/9] fix(Global Search/Tagging): regenerated services with latest API definition Signed-off-by: francescadecicco --- test/integration/test_global_tagging_v1.py | 1555 ++++---------------- test/unit/test_global_tagging_v1.py | 20 +- 2 files changed, 337 insertions(+), 1238 deletions(-) diff --git a/test/integration/test_global_tagging_v1.py b/test/integration/test_global_tagging_v1.py index 2f34f5d7..f2bb8af8 100644 --- a/test/integration/test_global_tagging_v1.py +++ b/test/integration/test_global_tagging_v1.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# (C) Copyright IBM Corp. 2025. +# (C) Copyright IBM Corp. 2020. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,1267 +12,360 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - """ -Unit Tests for GlobalTaggingV1 +Integration Tests for GlobalTaggingV1 """ -from ibm_cloud_sdk_core.authenticators.no_auth_authenticator import NoAuthAuthenticator -import inspect -import json import os import pytest -import re -import requests -import responses -import urllib +from ibm_cloud_sdk_core import * from ibm_platform_services.global_tagging_v1 import * - - -_service = GlobalTaggingV1(authenticator=NoAuthAuthenticator()) - -_base_url = 'https://tags.global-search-tagging.cloud.ibm.com' -_service.set_service_url(_base_url) - - -def preprocess_url(operation_path: str): - """ - Returns the request url associated with the specified operation path. - This will be base_url concatenated with a quoted version of operation_path. - The returned request URL is used to register the mock response so it needs - to match the request URL that is formed by the requests library. - """ - - # Form the request URL from the base URL and operation path. - request_url = _base_url + operation_path - - # If the request url does NOT end with a /, then just return it as-is. - # Otherwise, return a regular expression that matches one or more trailing /. - if not request_url.endswith('/'): - return request_url - return re.compile(request_url.rstrip('/') + '/+') - - -############################################################################## -# Start of Service: Tags -############################################################################## -# region - - -class TestNewInstance: - """ - Test Class for new_instance - """ - - def test_new_instance(self): - """ - new_instance() - """ - os.environ['TEST_SERVICE_AUTH_TYPE'] = 'noAuth' - - service = GlobalTaggingV1.new_instance( - service_name='TEST_SERVICE', +from random import randint + +# Config file name +config_file = 'global_tagging.env' + + +class TestGlobalTaggingV1: + """ + Integration Test Class for GlobalTaggingV1 + """ + + needscredentials = pytest.mark.skipif( + not os.path.exists(config_file), reason="External configuration not available, skipping..." + ) + + @classmethod + def setup_class(cls): + print('\nStarting setup...') + if os.path.exists(config_file): + os.environ['IBM_CREDENTIALS_FILE'] = config_file + + cls.global_tagging_service = GlobalTaggingV1.new_instance() + assert cls.global_tagging_service is not None + + cls.config = read_external_sources(GlobalTaggingV1.DEFAULT_SERVICE_NAME) + assert cls.config is not None + + cls.resource_crn = cls.config.get("RESOURCE_CRN") + assert cls.resource_crn is not None + + assert cls.config["URL"] == cls.global_tagging_service.service_url + + cls.sdk_label = 'python-sdk' + cls.user_tag_1 = cls.sdk_label + '-user-test1' + cls.user_tag_2 = cls.sdk_label + '-user-test2' + cls.access_tag_1 = 'env:' + cls.sdk_label + '-public' + cls.access_tag_2 = 'region:' + cls.sdk_label + '-us-south' + + print('Service URL: ', cls.global_tagging_service.service_url) + print('Resource CRN: ', cls.resource_crn) + + cls.clean_tags(cls) + + print('Setup complete.') + + @classmethod + def teardown_class(cls): + print('\nStarting teardown...') + cls.clean_tags(cls) + print('\nTeardown complete.') + + def clean_tags(self): + print('\nStarted cleaning tags...') + # Detach all user and access tags that contain our label. + tag_names = self.get_tag_names_for_resource(self, self.resource_crn, 'user') + for tag_name in tag_names: + if self.sdk_label in tag_name: + print('Detaching user tag {0} from resource {1}'.format(tag_name, self.resource_crn)) + self.detach_tag(self, self.resource_crn, tag_name, 'user') + tag_names = self.get_tag_names_for_resource(self, self.resource_crn, 'user') + print('Resource now has these user tags: {0}'.format(tag_names)) + + tag_names = self.get_tag_names_for_resource(self, self.resource_crn, 'access') + for tag_name in tag_names: + if self.sdk_label in tag_name: + print('Detaching access tag {0} from resource {1}'.format(tag_name, self.resource_crn)) + self.detach_tag(self, self.resource_crn, tag_name, 'access') + tag_names = self.get_tag_names_for_resource(self, self.resource_crn, 'access') + print('Resource now has these access tags: {0}'.format(tag_names)) + + # Delete all user and access tags that contain our label. + tag_names = self.list_tags_with_label(self, 'user', self.sdk_label) + print('Found {0} user tag(s) that contain our label.'.format(len(tag_names))) + for tag_name in tag_names: + print('Deleting user tag: {0}'.format(tag_name)) + self.delete_tag(self, tag_name, 'user') + + tag_names = self.list_tags_with_label(self, 'access', self.sdk_label) + print('Found {0} access tag(s) that contain our label.'.format(len(tag_names))) + for tag_name in tag_names: + print('Deleting access tag: {0}'.format(tag_name)) + self.delete_tag(self, tag_name, 'access') + + print('\nFinished cleaning tags...') + + def delete_tag(self, tag_name, tag_type): + response = self.global_tagging_service.delete_tag(tag_name=tag_name, tag_type=tag_type) + assert response.get_status_code() == 200 + assert response.get_result() is not None + delete_tag_results = DeleteTagResults.from_dict(response.get_result()) + assert delete_tag_results is not None + for elem in delete_tag_results.results: + assert elem.is_error is False + + def detach_tag(self, resource_id, tag_name, tag_type): + resource_model = {'resource_id': resource_id} + response = self.global_tagging_service.detach_tag( + resources=[resource_model], tag_names=[tag_name], tag_type=tag_type ) - - assert service is not None - assert isinstance(service, GlobalTaggingV1) - - def test_new_instance_without_authenticator(self): - """ - new_instance_without_authenticator() - """ - with pytest.raises(ValueError, match='authenticator must be provided'): - service = GlobalTaggingV1.new_instance( - service_name='TEST_SERVICE_NOT_FOUND', - ) - - -class TestListTags: - """ - Test Class for list_tags - """ - - @responses.activate - def test_list_tags_all_params(self): - """ - list_tags() - """ - # Set up mock - url = preprocess_url('/v3/tags') - mock_response = '{"total_count": 0, "offset": 0, "limit": 1, "items": [{"name": "name"}]}' - responses.add( - responses.GET, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - x_request_id = 'testString' - x_correlation_id = 'testString' - account_id = 'testString' - tag_type = 'user' - full_data = False - providers = ['ghost'] - attached_to = 'testString' + assert response.get_status_code() == 200 + assert response.get_result() is not None + tag_results = TagResults.from_dict(response.get_result()) + assert tag_results is not None + for elem in tag_results.results: + assert elem.is_error is False + + def get_tag_names_for_resource(self, resource_id, tag_type): + tag_names = [] + response = self.global_tagging_service.list_tags(attached_to=resource_id, tag_type=tag_type) + tag_list = TagList.from_dict(response.get_result()) + if tag_list.items is not None: + for item in tag_list.items: + tag_names.append(item.name) + return tag_names + + def list_tags_with_label(self, tag_type, label): + tag_names = [] offset = 0 - limit = 100 - timeout = 0 - order_by_name = 'asc' - attached_only = False - - # Invoke method - response = _service.list_tags( - x_request_id=x_request_id, - x_correlation_id=x_correlation_id, - account_id=account_id, - tag_type=tag_type, - full_data=full_data, - providers=providers, - attached_to=attached_to, - offset=offset, - limit=limit, - timeout=timeout, - order_by_name=order_by_name, - attached_only=attached_only, - headers={}, + more_results = True + while more_results: + list_tags_response = self.global_tagging_service.list_tags(offset=offset, limit=500, tag_type=tag_type) + assert list_tags_response.get_status_code() == 200 + assert list_tags_response.get_result() is not None + + tag_list = TagList.from_dict(list_tags_response.get_result()) + assert tag_list is not None + if len(tag_list.items) > 0: + for tag in tag_list.items: + if self.sdk_label in tag.name: + tag_names.append(tag.name) + offset += len(tag_list.items) + else: + more_results = False + return tag_names + + @needscredentials + def test_create_tag(self): + create_tag_response = self.global_tagging_service.create_tag( + tag_names=[self.access_tag_1, self.access_tag_2], tag_type='access' ) - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - # Validate query params - query_string = responses.calls[0].request.url.split('?', 1)[1] - query_string = urllib.parse.unquote_plus(query_string) - assert 'account_id={}'.format(account_id) in query_string - assert 'tag_type={}'.format(tag_type) in query_string - assert 'full_data={}'.format('true' if full_data else 'false') in query_string - assert 'providers={}'.format(','.join(providers)) in query_string - assert 'attached_to={}'.format(attached_to) in query_string - assert 'offset={}'.format(offset) in query_string - assert 'limit={}'.format(limit) in query_string - assert 'timeout={}'.format(timeout) in query_string - assert 'order_by_name={}'.format(order_by_name) in query_string - assert 'attached_only={}'.format('true' if attached_only else 'false') in query_string - - def test_list_tags_all_params_with_retries(self): - # Enable retries and run test_list_tags_all_params. - _service.enable_retries() - self.test_list_tags_all_params() - - # Disable retries and run test_list_tags_all_params. - _service.disable_retries() - self.test_list_tags_all_params() - - @responses.activate - def test_list_tags_required_params(self): - """ - test_list_tags_required_params() - """ - # Set up mock - url = preprocess_url('/v3/tags') - mock_response = '{"total_count": 0, "offset": 0, "limit": 1, "items": [{"name": "name"}]}' - responses.add( - responses.GET, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Invoke method - response = _service.list_tags() - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - - def test_list_tags_required_params_with_retries(self): - # Enable retries and run test_list_tags_required_params. - _service.enable_retries() - self.test_list_tags_required_params() - - # Disable retries and run test_list_tags_required_params. - _service.disable_retries() - self.test_list_tags_required_params() - - -class TestCreateTag: - """ - Test Class for create_tag - """ - - @responses.activate - def test_create_tag_all_params(self): - """ - create_tag() - """ - # Set up mock - url = preprocess_url('/v3/tags') - mock_response = '{"results": [{"tag_name": "tag_name", "is_error": true}]}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - tag_names = ['testString'] - x_request_id = 'testString' - x_correlation_id = 'testString' - account_id = 'testString' - tag_type = 'access' - - # Invoke method - response = _service.create_tag( - tag_names, - x_request_id=x_request_id, - x_correlation_id=x_correlation_id, - account_id=account_id, - tag_type=tag_type, - headers={}, - ) - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - # Validate query params - query_string = responses.calls[0].request.url.split('?', 1)[1] - query_string = urllib.parse.unquote_plus(query_string) - assert 'account_id={}'.format(account_id) in query_string - assert 'tag_type={}'.format(tag_type) in query_string - # Validate body params - req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['tag_names'] == ['testString'] - - def test_create_tag_all_params_with_retries(self): - # Enable retries and run test_create_tag_all_params. - _service.enable_retries() - self.test_create_tag_all_params() - - # Disable retries and run test_create_tag_all_params. - _service.disable_retries() - self.test_create_tag_all_params() - - @responses.activate - def test_create_tag_required_params(self): - """ - test_create_tag_required_params() - """ - # Set up mock - url = preprocess_url('/v3/tags') - mock_response = '{"results": [{"tag_name": "tag_name", "is_error": true}]}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - tag_names = ['testString'] - - # Invoke method - response = _service.create_tag( - tag_names, - headers={}, - ) - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - # Validate body params - req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['tag_names'] == ['testString'] - - def test_create_tag_required_params_with_retries(self): - # Enable retries and run test_create_tag_required_params. - _service.enable_retries() - self.test_create_tag_required_params() - - # Disable retries and run test_create_tag_required_params. - _service.disable_retries() - self.test_create_tag_required_params() - - @responses.activate - def test_create_tag_value_error(self): - """ - test_create_tag_value_error() - """ - # Set up mock - url = preprocess_url('/v3/tags') - mock_response = '{"results": [{"tag_name": "tag_name", "is_error": true}]}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - tag_names = ['testString'] - - # Pass in all but one required param and check for a ValueError - req_param_dict = { - "tag_names": tag_names, + assert create_tag_response.get_status_code() == 200 + assert create_tag_response.get_result() is not None + create_tag_results = CreateTagResults.from_dict(create_tag_response.get_result()) + assert create_tag_results is not None + print('\ncreate_tag() result: ', json.dumps(create_tag_results.to_dict(), indent=2)) + assert create_tag_results.results is not None + for result in create_tag_results.results: + assert result.is_error is False + + @needscredentials + def test_attach_tag_user(self): + # Construct a dict representation of a Resource model + resource_model = { + 'resource_id': self.resource_crn, } - for param in req_param_dict.keys(): - req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} - with pytest.raises(ValueError): - _service.create_tag(**req_copy) - def test_create_tag_value_error_with_retries(self): - # Enable retries and run test_create_tag_value_error. - _service.enable_retries() - self.test_create_tag_value_error() - - # Disable retries and run test_create_tag_value_error. - _service.disable_retries() - self.test_create_tag_value_error() - - -class TestDeleteTagAll: - """ - Test Class for delete_tag_all - """ - - @responses.activate - def test_delete_tag_all_all_params(self): - """ - delete_tag_all() - """ - # Set up mock - url = preprocess_url('/v3/tags') - mock_response = '{"total_count": 11, "errors": true, "items": [{"tag_name": "tag_name", "is_error": true}]}' - responses.add( - responses.DELETE, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - x_request_id = 'testString' - x_correlation_id = 'testString' - providers = 'ghost' - account_id = 'testString' - tag_type = 'user' - - # Invoke method - response = _service.delete_tag_all( - x_request_id=x_request_id, - x_correlation_id=x_correlation_id, - providers=providers, - account_id=account_id, - tag_type=tag_type, - headers={}, + attach_tag_response = self.global_tagging_service.attach_tag( + resources=[resource_model], tag_names=[self.user_tag_1, self.user_tag_2], tag_type='user' ) - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - # Validate query params - query_string = responses.calls[0].request.url.split('?', 1)[1] - query_string = urllib.parse.unquote_plus(query_string) - assert 'providers={}'.format(providers) in query_string - assert 'account_id={}'.format(account_id) in query_string - assert 'tag_type={}'.format(tag_type) in query_string - - def test_delete_tag_all_all_params_with_retries(self): - # Enable retries and run test_delete_tag_all_all_params. - _service.enable_retries() - self.test_delete_tag_all_all_params() - - # Disable retries and run test_delete_tag_all_all_params. - _service.disable_retries() - self.test_delete_tag_all_all_params() - - @responses.activate - def test_delete_tag_all_required_params(self): - """ - test_delete_tag_all_required_params() - """ - # Set up mock - url = preprocess_url('/v3/tags') - mock_response = '{"total_count": 11, "errors": true, "items": [{"tag_name": "tag_name", "is_error": true}]}' - responses.add( - responses.DELETE, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Invoke method - response = _service.delete_tag_all() - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 + assert attach_tag_response.get_status_code() == 200 + assert attach_tag_response.get_result() is not None + tag_results = TagResults.from_dict(attach_tag_response.get_result()) + assert tag_results is not None + print('\nattach_tag(user) result: ', json.dumps(tag_results.to_dict(), indent=2)) - def test_delete_tag_all_required_params_with_retries(self): - # Enable retries and run test_delete_tag_all_required_params. - _service.enable_retries() - self.test_delete_tag_all_required_params() + for elem in tag_results.results: + assert elem.is_error is False - # Disable retries and run test_delete_tag_all_required_params. - _service.disable_retries() - self.test_delete_tag_all_required_params() - - -class TestDeleteTag: - """ - Test Class for delete_tag - """ - - @responses.activate - def test_delete_tag_all_params(self): - """ - delete_tag() - """ - # Set up mock - url = preprocess_url('/v3/tags/testString') - mock_response = '{"results": [{"provider": "ghost", "is_error": true}]}' - responses.add( - responses.DELETE, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - tag_name = 'testString' - x_request_id = 'testString' - x_correlation_id = 'testString' - providers = ['ghost'] - account_id = 'testString' - tag_type = 'user' - - # Invoke method - response = _service.delete_tag( - tag_name, - x_request_id=x_request_id, - x_correlation_id=x_correlation_id, - providers=providers, - account_id=account_id, - tag_type=tag_type, - headers={}, - ) - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - # Validate query params - query_string = responses.calls[0].request.url.split('?', 1)[1] - query_string = urllib.parse.unquote_plus(query_string) - assert 'providers={}'.format(','.join(providers)) in query_string - assert 'account_id={}'.format(account_id) in query_string - assert 'tag_type={}'.format(tag_type) in query_string - - def test_delete_tag_all_params_with_retries(self): - # Enable retries and run test_delete_tag_all_params. - _service.enable_retries() - self.test_delete_tag_all_params() - - # Disable retries and run test_delete_tag_all_params. - _service.disable_retries() - self.test_delete_tag_all_params() - - @responses.activate - def test_delete_tag_required_params(self): - """ - test_delete_tag_required_params() - """ - # Set up mock - url = preprocess_url('/v3/tags/testString') - mock_response = '{"results": [{"provider": "ghost", "is_error": true}]}' - responses.add( - responses.DELETE, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - tag_name = 'testString' - - # Invoke method - response = _service.delete_tag( - tag_name, - headers={}, - ) - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - - def test_delete_tag_required_params_with_retries(self): - # Enable retries and run test_delete_tag_required_params. - _service.enable_retries() - self.test_delete_tag_required_params() - - # Disable retries and run test_delete_tag_required_params. - _service.disable_retries() - self.test_delete_tag_required_params() - - @responses.activate - def test_delete_tag_value_error(self): - """ - test_delete_tag_value_error() - """ - # Set up mock - url = preprocess_url('/v3/tags/testString') - mock_response = '{"results": [{"provider": "ghost", "is_error": true}]}' - responses.add( - responses.DELETE, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - tag_name = 'testString' - - # Pass in all but one required param and check for a ValueError - req_param_dict = { - "tag_name": tag_name, - } - for param in req_param_dict.keys(): - req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} - with pytest.raises(ValueError): - _service.delete_tag(**req_copy) - - def test_delete_tag_value_error_with_retries(self): - # Enable retries and run test_delete_tag_value_error. - _service.enable_retries() - self.test_delete_tag_value_error() - - # Disable retries and run test_delete_tag_value_error. - _service.disable_retries() - self.test_delete_tag_value_error() - - -class TestAttachTag: - """ - Test Class for attach_tag - """ - - @responses.activate - def test_attach_tag_all_params(self): - """ - attach_tag() - """ - # Set up mock - url = preprocess_url('/v3/tags/attach') - mock_response = '{"results": [{"resource_id": "resource_id", "is_error": true}]}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, - ) + # Make sure the tags are in fact attached to the resource. + tag_names = self.get_tag_names_for_resource(resource_id=self.resource_crn, tag_type='user') + assert self.user_tag_1 in tag_names + assert self.user_tag_2 in tag_names + @needscredentials + def test_attach_tag_access(self): # Construct a dict representation of a Resource model - resource_model = {} - resource_model['resource_id'] = 'testString' - resource_model['resource_type'] = 'testString' - - # Construct a dict representation of a QueryString model - query_string_model = {} - query_string_model['query_string'] = 'testString' - - # Set up parameter values - tag_name = 'testString' - tag_names = ['testString'] - resources = [resource_model] - query = query_string_model - x_request_id = 'testString' - x_correlation_id = 'testString' - account_id = 'testString' - tag_type = 'user' - replace = False - update = False - - # Invoke method - response = _service.attach_tag( - tag_name=tag_name, - tag_names=tag_names, - resources=resources, - query=query, - x_request_id=x_request_id, - x_correlation_id=x_correlation_id, - account_id=account_id, - tag_type=tag_type, - replace=replace, - update=update, - headers={}, - ) - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - # Validate query params - query_string = responses.calls[0].request.url.split('?', 1)[1] - query_string = urllib.parse.unquote_plus(query_string) - assert 'account_id={}'.format(account_id) in query_string - assert 'tag_type={}'.format(tag_type) in query_string - assert 'replace={}'.format('true' if replace else 'false') in query_string - assert 'update={}'.format('true' if update else 'false') in query_string - # Validate body params - req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['tag_name'] == 'testString' - assert req_body['tag_names'] == ['testString'] - assert req_body['resources'] == [resource_model] - assert req_body['query'] == query_string_model - - def test_attach_tag_all_params_with_retries(self): - # Enable retries and run test_attach_tag_all_params. - _service.enable_retries() - self.test_attach_tag_all_params() - - # Disable retries and run test_attach_tag_all_params. - _service.disable_retries() - self.test_attach_tag_all_params() - - @responses.activate - def test_attach_tag_required_params(self): - """ - test_attach_tag_required_params() - """ - # Set up mock - url = preprocess_url('/v3/tags/attach') - mock_response = '{"results": [{"resource_id": "resource_id", "is_error": true}]}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, - ) + resource_model = { + 'resource_id': self.resource_crn, + } - # Construct a dict representation of a Resource model - resource_model = {} - resource_model['resource_id'] = 'testString' - resource_model['resource_type'] = 'testString' - - # Construct a dict representation of a QueryString model - query_string_model = {} - query_string_model['query_string'] = 'testString' - - # Set up parameter values - tag_name = 'testString' - tag_names = ['testString'] - resources = [resource_model] - query = query_string_model - - # Invoke method - response = _service.attach_tag( - tag_name=tag_name, - tag_names=tag_names, - resources=resources, - query=query, - headers={}, + attach_tag_response = self.global_tagging_service.attach_tag( + resources=[resource_model], tag_names=[self.access_tag_1, self.access_tag_2], tag_type='access' ) - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - # Validate body params - req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['tag_name'] == 'testString' - assert req_body['tag_names'] == ['testString'] - assert req_body['resources'] == [resource_model] - assert req_body['query'] == query_string_model - - def test_attach_tag_required_params_with_retries(self): - # Enable retries and run test_attach_tag_required_params. - _service.enable_retries() - self.test_attach_tag_required_params() - - # Disable retries and run test_attach_tag_required_params. - _service.disable_retries() - self.test_attach_tag_required_params() - + assert attach_tag_response.get_status_code() == 200 + assert attach_tag_response.get_result() is not None + tag_results = TagResults.from_dict(attach_tag_response.get_result()) + assert tag_results is not None + print('\nattach_tag(access) result: ', json.dumps(tag_results.to_dict(), indent=2)) -class TestDetachTag: - """ - Test Class for detach_tag - """ + for elem in tag_results.results: + assert elem.is_error is False - @responses.activate - def test_detach_tag_all_params(self): - """ - detach_tag() - """ - # Set up mock - url = preprocess_url('/v3/tags/detach') - mock_response = '{"results": [{"resource_id": "resource_id", "is_error": true}]}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, - ) + # Make sure the tags are in fact attached to the resource. + tag_names = self.get_tag_names_for_resource(resource_id=self.resource_crn, tag_type='access') + assert self.access_tag_1 in tag_names + assert self.access_tag_2 in tag_names + @needscredentials + def test_list_tags_user(self): + tags = [] + offset = 0 + more_results = True + while more_results: + list_tags_response = self.global_tagging_service.list_tags(offset=offset, limit=500, tag_type='user') + assert list_tags_response.get_status_code() == 200 + assert list_tags_response.get_result() is not None + + tag_list = TagList.from_dict(list_tags_response.get_result()) + assert tag_list is not None + if len(tag_list.items) > 0: + for item in tag_list.items: + tags.append(item) + offset += len(tag_list.items) + else: + more_results = False + + print('\nRetrieved a total of {0} user tags.'.format(len(tags))) + matches = [] + for tag in tags: + if self.sdk_label in tag.name: + matches.append(tag.name) + print('Found {0} user tags containing our label: {1}'.format(len(matches), matches)) + + @needscredentials + def test_list_tags_access(self): + tags = [] + offset = 0 + more_results = True + while more_results: + list_tags_response = self.global_tagging_service.list_tags(offset=offset, limit=500, tag_type='access') + assert list_tags_response.get_status_code() == 200 + assert list_tags_response.get_result() is not None + + tag_list = TagList.from_dict(list_tags_response.get_result()) + assert tag_list is not None + if len(tag_list.items) > 0: + for item in tag_list.items: + tags.append(item) + offset += len(tag_list.items) + else: + more_results = False + + print('\nRetrieved a total of {0} access tags.'.format(len(tags))) + matches = [] + for tag in tags: + if self.sdk_label in tag.name: + matches.append(tag.name) + print('Found {0} access tags containing our label: {1}'.format(len(matches), matches)) + + @needscredentials + def test_detach_tag_user(self): # Construct a dict representation of a Resource model - resource_model = {} - resource_model['resource_id'] = 'testString' - resource_model['resource_type'] = 'testString' - - # Construct a dict representation of a QueryString model - query_string_model = {} - query_string_model['query_string'] = 'testString' - - # Set up parameter values - tag_name = 'testString' - tag_names = ['testString'] - resources = [resource_model] - query = query_string_model - x_request_id = 'testString' - x_correlation_id = 'testString' - account_id = 'testString' - tag_type = 'user' - - # Invoke method - response = _service.detach_tag( - tag_name=tag_name, - tag_names=tag_names, - resources=resources, - query=query, - x_request_id=x_request_id, - x_correlation_id=x_correlation_id, - account_id=account_id, - tag_type=tag_type, - headers={}, - ) + resource_model = {'resource_id': self.resource_crn} - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - # Validate query params - query_string = responses.calls[0].request.url.split('?', 1)[1] - query_string = urllib.parse.unquote_plus(query_string) - assert 'account_id={}'.format(account_id) in query_string - assert 'tag_type={}'.format(tag_type) in query_string - # Validate body params - req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['tag_name'] == 'testString' - assert req_body['tag_names'] == ['testString'] - assert req_body['resources'] == [resource_model] - assert req_body['query'] == query_string_model - - def test_detach_tag_all_params_with_retries(self): - # Enable retries and run test_detach_tag_all_params. - _service.enable_retries() - self.test_detach_tag_all_params() - - # Disable retries and run test_detach_tag_all_params. - _service.disable_retries() - self.test_detach_tag_all_params() - - @responses.activate - def test_detach_tag_required_params(self): - """ - test_detach_tag_required_params() - """ - # Set up mock - url = preprocess_url('/v3/tags/detach') - mock_response = '{"results": [{"resource_id": "resource_id", "is_error": true}]}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, + detach_tag_response = self.global_tagging_service.detach_tag( + resources=[resource_model], tag_names=[self.user_tag_1, self.user_tag_2], tag_type='user' ) - # Construct a dict representation of a Resource model - resource_model = {} - resource_model['resource_id'] = 'testString' - resource_model['resource_type'] = 'testString' - - # Construct a dict representation of a QueryString model - query_string_model = {} - query_string_model['query_string'] = 'testString' - - # Set up parameter values - tag_name = 'testString' - tag_names = ['testString'] - resources = [resource_model] - query = query_string_model - - # Invoke method - response = _service.detach_tag( - tag_name=tag_name, - tag_names=tag_names, - resources=resources, - query=query, - headers={}, - ) - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - # Validate body params - req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['tag_name'] == 'testString' - assert req_body['tag_names'] == ['testString'] - assert req_body['resources'] == [resource_model] - assert req_body['query'] == query_string_model - - def test_detach_tag_required_params_with_retries(self): - # Enable retries and run test_detach_tag_required_params. - _service.enable_retries() - self.test_detach_tag_required_params() - - # Disable retries and run test_detach_tag_required_params. - _service.disable_retries() - self.test_detach_tag_required_params() - - -# endregion -############################################################################## -# End of Service: Tags -############################################################################## - - -############################################################################## -# Start of Model Tests -############################################################################## -# region - - -class TestModel_CreateTagResults: - """ - Test Class for CreateTagResults - """ - - def test_create_tag_results_serialization(self): - """ - Test serialization/deserialization for CreateTagResults - """ - - # Construct dict forms of any model objects needed in order to build this model. - - create_tag_results_results_item_model = {} # CreateTagResultsResultsItem - create_tag_results_results_item_model['tag_name'] = 'testString' - create_tag_results_results_item_model['is_error'] = True - - # Construct a json representation of a CreateTagResults model - create_tag_results_model_json = {} - create_tag_results_model_json['results'] = [create_tag_results_results_item_model] - - # Construct a model instance of CreateTagResults by calling from_dict on the json representation - create_tag_results_model = CreateTagResults.from_dict(create_tag_results_model_json) - assert create_tag_results_model != False - - # Construct a model instance of CreateTagResults by calling from_dict on the json representation - create_tag_results_model_dict = CreateTagResults.from_dict(create_tag_results_model_json).__dict__ - create_tag_results_model2 = CreateTagResults(**create_tag_results_model_dict) - - # Verify the model instances are equivalent - assert create_tag_results_model == create_tag_results_model2 + assert detach_tag_response.get_status_code() == 200 + assert detach_tag_response.get_result() is not None + tag_results = TagResults.from_dict(detach_tag_response.get_result()) + assert tag_results is not None + print('\ndetach_tag(user) result: ', json.dumps(tag_results.to_dict(), indent=2)) - # Convert model instance back to dict and verify no loss of data - create_tag_results_model_json2 = create_tag_results_model.to_dict() - assert create_tag_results_model_json2 == create_tag_results_model_json + for elem in tag_results.results: + assert elem.is_error is False + # Make sure the tag is in fact attached to the resource + tag_names = self.get_tag_names_for_resource(self.resource_crn, 'user') + assert self.user_tag_1 not in tag_names + assert self.user_tag_2 not in tag_names -class TestModel_CreateTagResultsResultsItem: - """ - Test Class for CreateTagResultsResultsItem - """ - - def test_create_tag_results_results_item_serialization(self): - """ - Test serialization/deserialization for CreateTagResultsResultsItem - """ - - # Construct a json representation of a CreateTagResultsResultsItem model - create_tag_results_results_item_model_json = {} - create_tag_results_results_item_model_json['tag_name'] = 'testString' - create_tag_results_results_item_model_json['is_error'] = True - - # Construct a model instance of CreateTagResultsResultsItem by calling from_dict on the json representation - create_tag_results_results_item_model = CreateTagResultsResultsItem.from_dict( - create_tag_results_results_item_model_json - ) - assert create_tag_results_results_item_model != False - - # Construct a model instance of CreateTagResultsResultsItem by calling from_dict on the json representation - create_tag_results_results_item_model_dict = CreateTagResultsResultsItem.from_dict( - create_tag_results_results_item_model_json - ).__dict__ - create_tag_results_results_item_model2 = CreateTagResultsResultsItem( - **create_tag_results_results_item_model_dict - ) - - # Verify the model instances are equivalent - assert create_tag_results_results_item_model == create_tag_results_results_item_model2 - - # Convert model instance back to dict and verify no loss of data - create_tag_results_results_item_model_json2 = create_tag_results_results_item_model.to_dict() - assert create_tag_results_results_item_model_json2 == create_tag_results_results_item_model_json - - -class TestModel_DeleteTagResults: - """ - Test Class for DeleteTagResults - """ - - def test_delete_tag_results_serialization(self): - """ - Test serialization/deserialization for DeleteTagResults - """ - - # Construct dict forms of any model objects needed in order to build this model. - - delete_tag_results_item_model = {} # DeleteTagResultsItem - delete_tag_results_item_model['provider'] = 'ghost' - delete_tag_results_item_model['is_error'] = True - delete_tag_results_item_model['foo'] = 'testString' - - # Construct a json representation of a DeleteTagResults model - delete_tag_results_model_json = {} - delete_tag_results_model_json['results'] = [delete_tag_results_item_model] - - # Construct a model instance of DeleteTagResults by calling from_dict on the json representation - delete_tag_results_model = DeleteTagResults.from_dict(delete_tag_results_model_json) - assert delete_tag_results_model != False - - # Construct a model instance of DeleteTagResults by calling from_dict on the json representation - delete_tag_results_model_dict = DeleteTagResults.from_dict(delete_tag_results_model_json).__dict__ - delete_tag_results_model2 = DeleteTagResults(**delete_tag_results_model_dict) - - # Verify the model instances are equivalent - assert delete_tag_results_model == delete_tag_results_model2 - - # Convert model instance back to dict and verify no loss of data - delete_tag_results_model_json2 = delete_tag_results_model.to_dict() - assert delete_tag_results_model_json2 == delete_tag_results_model_json - - -class TestModel_DeleteTagResultsItem: - """ - Test Class for DeleteTagResultsItem - """ - - def test_delete_tag_results_item_serialization(self): - """ - Test serialization/deserialization for DeleteTagResultsItem - """ - - # Construct a json representation of a DeleteTagResultsItem model - delete_tag_results_item_model_json = {} - delete_tag_results_item_model_json['provider'] = 'ghost' - delete_tag_results_item_model_json['is_error'] = True - delete_tag_results_item_model_json['foo'] = 'testString' - - # Construct a model instance of DeleteTagResultsItem by calling from_dict on the json representation - delete_tag_results_item_model = DeleteTagResultsItem.from_dict(delete_tag_results_item_model_json) - assert delete_tag_results_item_model != False - - # Construct a model instance of DeleteTagResultsItem by calling from_dict on the json representation - delete_tag_results_item_model_dict = DeleteTagResultsItem.from_dict(delete_tag_results_item_model_json).__dict__ - delete_tag_results_item_model2 = DeleteTagResultsItem(**delete_tag_results_item_model_dict) - - # Verify the model instances are equivalent - assert delete_tag_results_item_model == delete_tag_results_item_model2 - - # Convert model instance back to dict and verify no loss of data - delete_tag_results_item_model_json2 = delete_tag_results_item_model.to_dict() - assert delete_tag_results_item_model_json2 == delete_tag_results_item_model_json - - # Test get_properties and set_properties methods. - delete_tag_results_item_model.set_properties({}) - actual_dict = delete_tag_results_item_model.get_properties() - assert actual_dict == {} - - expected_dict = {'foo': 'testString'} - delete_tag_results_item_model.set_properties(expected_dict) - actual_dict = delete_tag_results_item_model.get_properties() - assert actual_dict.keys() == expected_dict.keys() - - -class TestModel_DeleteTagsResult: - """ - Test Class for DeleteTagsResult - """ - - def test_delete_tags_result_serialization(self): - """ - Test serialization/deserialization for DeleteTagsResult - """ - - # Construct dict forms of any model objects needed in order to build this model. - - delete_tags_result_item_model = {} # DeleteTagsResultItem - delete_tags_result_item_model['tag_name'] = 'testString' - delete_tags_result_item_model['is_error'] = True - - # Construct a json representation of a DeleteTagsResult model - delete_tags_result_model_json = {} - delete_tags_result_model_json['total_count'] = 38 - delete_tags_result_model_json['errors'] = True - delete_tags_result_model_json['items'] = [delete_tags_result_item_model] - - # Construct a model instance of DeleteTagsResult by calling from_dict on the json representation - delete_tags_result_model = DeleteTagsResult.from_dict(delete_tags_result_model_json) - assert delete_tags_result_model != False - - # Construct a model instance of DeleteTagsResult by calling from_dict on the json representation - delete_tags_result_model_dict = DeleteTagsResult.from_dict(delete_tags_result_model_json).__dict__ - delete_tags_result_model2 = DeleteTagsResult(**delete_tags_result_model_dict) - - # Verify the model instances are equivalent - assert delete_tags_result_model == delete_tags_result_model2 - - # Convert model instance back to dict and verify no loss of data - delete_tags_result_model_json2 = delete_tags_result_model.to_dict() - assert delete_tags_result_model_json2 == delete_tags_result_model_json - - -class TestModel_DeleteTagsResultItem: - """ - Test Class for DeleteTagsResultItem - """ - - def test_delete_tags_result_item_serialization(self): - """ - Test serialization/deserialization for DeleteTagsResultItem - """ - - # Construct a json representation of a DeleteTagsResultItem model - delete_tags_result_item_model_json = {} - delete_tags_result_item_model_json['tag_name'] = 'testString' - delete_tags_result_item_model_json['is_error'] = True - - # Construct a model instance of DeleteTagsResultItem by calling from_dict on the json representation - delete_tags_result_item_model = DeleteTagsResultItem.from_dict(delete_tags_result_item_model_json) - assert delete_tags_result_item_model != False - - # Construct a model instance of DeleteTagsResultItem by calling from_dict on the json representation - delete_tags_result_item_model_dict = DeleteTagsResultItem.from_dict(delete_tags_result_item_model_json).__dict__ - delete_tags_result_item_model2 = DeleteTagsResultItem(**delete_tags_result_item_model_dict) - - # Verify the model instances are equivalent - assert delete_tags_result_item_model == delete_tags_result_item_model2 - - # Convert model instance back to dict and verify no loss of data - delete_tags_result_item_model_json2 = delete_tags_result_item_model.to_dict() - assert delete_tags_result_item_model_json2 == delete_tags_result_item_model_json - - -class TestModel_QueryString: - """ - Test Class for QueryString - """ - - def test_query_string_serialization(self): - """ - Test serialization/deserialization for QueryString - """ - - # Construct a json representation of a QueryString model - query_string_model_json = {} - query_string_model_json['query_string'] = 'testString' - - # Construct a model instance of QueryString by calling from_dict on the json representation - query_string_model = QueryString.from_dict(query_string_model_json) - assert query_string_model != False - - # Construct a model instance of QueryString by calling from_dict on the json representation - query_string_model_dict = QueryString.from_dict(query_string_model_json).__dict__ - query_string_model2 = QueryString(**query_string_model_dict) - - # Verify the model instances are equivalent - assert query_string_model == query_string_model2 - - # Convert model instance back to dict and verify no loss of data - query_string_model_json2 = query_string_model.to_dict() - assert query_string_model_json2 == query_string_model_json - - -class TestModel_Resource: - """ - Test Class for Resource - """ - - def test_resource_serialization(self): - """ - Test serialization/deserialization for Resource - """ - - # Construct a json representation of a Resource model - resource_model_json = {} - resource_model_json['resource_id'] = 'testString' - resource_model_json['resource_type'] = 'testString' - - # Construct a model instance of Resource by calling from_dict on the json representation - resource_model = Resource.from_dict(resource_model_json) - assert resource_model != False - - # Construct a model instance of Resource by calling from_dict on the json representation - resource_model_dict = Resource.from_dict(resource_model_json).__dict__ - resource_model2 = Resource(**resource_model_dict) - - # Verify the model instances are equivalent - assert resource_model == resource_model2 - - # Convert model instance back to dict and verify no loss of data - resource_model_json2 = resource_model.to_dict() - assert resource_model_json2 == resource_model_json - - -class TestModel_Tag: - """ - Test Class for Tag - """ - - def test_tag_serialization(self): - """ - Test serialization/deserialization for Tag - """ - - # Construct a json representation of a Tag model - tag_model_json = {} - tag_model_json['name'] = 'testString' - - # Construct a model instance of Tag by calling from_dict on the json representation - tag_model = Tag.from_dict(tag_model_json) - assert tag_model != False - - # Construct a model instance of Tag by calling from_dict on the json representation - tag_model_dict = Tag.from_dict(tag_model_json).__dict__ - tag_model2 = Tag(**tag_model_dict) - - # Verify the model instances are equivalent - assert tag_model == tag_model2 - - # Convert model instance back to dict and verify no loss of data - tag_model_json2 = tag_model.to_dict() - assert tag_model_json2 == tag_model_json - - -class TestModel_TagList: - """ - Test Class for TagList - """ - - def test_tag_list_serialization(self): - """ - Test serialization/deserialization for TagList - """ - - # Construct dict forms of any model objects needed in order to build this model. - - tag_model = {} # Tag - tag_model['name'] = 'testString' - - # Construct a json representation of a TagList model - tag_list_model_json = {} - tag_list_model_json['total_count'] = 0 - tag_list_model_json['offset'] = 0 - tag_list_model_json['limit'] = 1 - tag_list_model_json['items'] = [tag_model] - - # Construct a model instance of TagList by calling from_dict on the json representation - tag_list_model = TagList.from_dict(tag_list_model_json) - assert tag_list_model != False - - # Construct a model instance of TagList by calling from_dict on the json representation - tag_list_model_dict = TagList.from_dict(tag_list_model_json).__dict__ - tag_list_model2 = TagList(**tag_list_model_dict) - - # Verify the model instances are equivalent - assert tag_list_model == tag_list_model2 - - # Convert model instance back to dict and verify no loss of data - tag_list_model_json2 = tag_list_model.to_dict() - assert tag_list_model_json2 == tag_list_model_json - - -class TestModel_TagResults: - """ - Test Class for TagResults - """ - - def test_tag_results_serialization(self): - """ - Test serialization/deserialization for TagResults - """ - - # Construct dict forms of any model objects needed in order to build this model. + @needscredentials + def test_detach_tag_access(self): + # Construct a dict representation of a Resource model + resource_model = {'resource_id': self.resource_crn} - tag_results_item_model = {} # TagResultsItem - tag_results_item_model['resource_id'] = ( - 'crn:v1:staging:public:resource-controller::a/5c2ac0d93c69e82c6c9c7c78dc4beda3::resource-group:1c061f4485b34360a8f8ee049880dc13' + detach_tag_response = self.global_tagging_service.detach_tag( + resources=[resource_model], tag_names=[self.access_tag_1, self.access_tag_2], tag_type='access' ) - tag_results_item_model['is_error'] = False - - # Construct a json representation of a TagResults model - tag_results_model_json = {} - tag_results_model_json['results'] = [tag_results_item_model] - - # Construct a model instance of TagResults by calling from_dict on the json representation - tag_results_model = TagResults.from_dict(tag_results_model_json) - assert tag_results_model != False - - # Construct a model instance of TagResults by calling from_dict on the json representation - tag_results_model_dict = TagResults.from_dict(tag_results_model_json).__dict__ - tag_results_model2 = TagResults(**tag_results_model_dict) - - # Verify the model instances are equivalent - assert tag_results_model == tag_results_model2 - - # Convert model instance back to dict and verify no loss of data - tag_results_model_json2 = tag_results_model.to_dict() - assert tag_results_model_json2 == tag_results_model_json - - -class TestModel_TagResultsItem: - """ - Test Class for TagResultsItem - """ - - def test_tag_results_item_serialization(self): - """ - Test serialization/deserialization for TagResultsItem - """ - - # Construct a json representation of a TagResultsItem model - tag_results_item_model_json = {} - tag_results_item_model_json['resource_id'] = 'testString' - tag_results_item_model_json['is_error'] = True - - # Construct a model instance of TagResultsItem by calling from_dict on the json representation - tag_results_item_model = TagResultsItem.from_dict(tag_results_item_model_json) - assert tag_results_item_model != False - - # Construct a model instance of TagResultsItem by calling from_dict on the json representation - tag_results_item_model_dict = TagResultsItem.from_dict(tag_results_item_model_json).__dict__ - tag_results_item_model2 = TagResultsItem(**tag_results_item_model_dict) - - # Verify the model instances are equivalent - assert tag_results_item_model == tag_results_item_model2 - - # Convert model instance back to dict and verify no loss of data - tag_results_item_model_json2 = tag_results_item_model.to_dict() - assert tag_results_item_model_json2 == tag_results_item_model_json - -# endregion -############################################################################## -# End of Model Tests -############################################################################## + assert detach_tag_response.get_status_code() == 200 + assert detach_tag_response.get_result() is not None + tag_results = TagResults.from_dict(detach_tag_response.get_result()) + assert tag_results is not None + print('\ndetach_tag(access) result: ', json.dumps(tag_results.to_dict(), indent=2)) + + for elem in tag_results.results: + assert elem.is_error is False + + # Make sure the tag is in fact attached to the resource + tag_names = self.get_tag_names_for_resource(self.resource_crn, 'access') + assert self.access_tag_1 not in tag_names + assert self.access_tag_2 not in tag_names + + @needscredentials + def test_delete_tag_user(self): + delete_tag_response = self.global_tagging_service.delete_tag(tag_name=self.user_tag_1, tag_type='user') + + assert delete_tag_response.get_status_code() == 200 + assert delete_tag_response.get_result() is not None + delete_tag_results = DeleteTagResults.from_dict(delete_tag_response.get_result()) + assert delete_tag_results is not None + print('\ndelete_tag(user) result: ', json.dumps(delete_tag_results.to_dict(), indent=2)) + + for item in delete_tag_results.results: + assert item.is_error is False + + @needscredentials + def test_delete_tag_access(self): + delete_tag_response = self.global_tagging_service.delete_tag(tag_name=self.access_tag_1, tag_type='access') + + assert delete_tag_response.get_status_code() == 200 + assert delete_tag_response.get_result() is not None + delete_tag_results = DeleteTagResults.from_dict(delete_tag_response.get_result()) + assert delete_tag_results is not None + print('\ndelete_tag(access) result: ', json.dumps(delete_tag_results.to_dict(), indent=2)) + + for item in delete_tag_results.results: + assert item.is_error is False + + @needscredentials + def test_delete_tag_all_user(self): + delete_tag_all_response = self.global_tagging_service.delete_tag_all(tag_type='user') + + assert delete_tag_all_response.get_status_code() == 200 + assert delete_tag_all_response.get_result() is not None + delete_tags_result = DeleteTagsResult.from_dict(delete_tag_all_response.get_result()) + assert delete_tags_result is not None + print('\ndelete_tag_all(user) result: ', json.dumps(delete_tags_result.to_dict(), indent=2)) + + for item in delete_tags_result.items: + assert item.is_error is False + + @needscredentials + def test_delete_tag_all_access(self): + delete_tag_all_response = self.global_tagging_service.delete_tag_all(tag_type='access') + + assert delete_tag_all_response.get_status_code() == 200 + assert delete_tag_all_response.get_result() is not None + delete_tags_result = DeleteTagsResult.from_dict(delete_tag_all_response.get_result()) + assert delete_tags_result is not None + print('\ndelete_tag_all(access) result: ', json.dumps(delete_tags_result.to_dict(), indent=2)) + + for item in delete_tags_result.items: + assert item.is_error is False diff --git a/test/unit/test_global_tagging_v1.py b/test/unit/test_global_tagging_v1.py index 750724be..2f34f5d7 100644 --- a/test/unit/test_global_tagging_v1.py +++ b/test/unit/test_global_tagging_v1.py @@ -29,9 +29,7 @@ from ibm_platform_services.global_tagging_v1 import * -_service = GlobalTaggingV1( - authenticator=NoAuthAuthenticator() -) +_service = GlobalTaggingV1(authenticator=NoAuthAuthenticator()) _base_url = 'https://tags.global-search-tagging.cloud.ibm.com' _service.set_service_url(_base_url) @@ -907,12 +905,18 @@ def test_create_tag_results_results_item_serialization(self): create_tag_results_results_item_model_json['is_error'] = True # Construct a model instance of CreateTagResultsResultsItem by calling from_dict on the json representation - create_tag_results_results_item_model = CreateTagResultsResultsItem.from_dict(create_tag_results_results_item_model_json) + create_tag_results_results_item_model = CreateTagResultsResultsItem.from_dict( + create_tag_results_results_item_model_json + ) assert create_tag_results_results_item_model != False # Construct a model instance of CreateTagResultsResultsItem by calling from_dict on the json representation - create_tag_results_results_item_model_dict = CreateTagResultsResultsItem.from_dict(create_tag_results_results_item_model_json).__dict__ - create_tag_results_results_item_model2 = CreateTagResultsResultsItem(**create_tag_results_results_item_model_dict) + create_tag_results_results_item_model_dict = CreateTagResultsResultsItem.from_dict( + create_tag_results_results_item_model_json + ).__dict__ + create_tag_results_results_item_model2 = CreateTagResultsResultsItem( + **create_tag_results_results_item_model_dict + ) # Verify the model instances are equivalent assert create_tag_results_results_item_model == create_tag_results_results_item_model2 @@ -1212,7 +1216,9 @@ def test_tag_results_serialization(self): # Construct dict forms of any model objects needed in order to build this model. tag_results_item_model = {} # TagResultsItem - tag_results_item_model['resource_id'] = 'crn:v1:staging:public:resource-controller::a/5c2ac0d93c69e82c6c9c7c78dc4beda3::resource-group:1c061f4485b34360a8f8ee049880dc13' + tag_results_item_model['resource_id'] = ( + 'crn:v1:staging:public:resource-controller::a/5c2ac0d93c69e82c6c9c7c78dc4beda3::resource-group:1c061f4485b34360a8f8ee049880dc13' + ) tag_results_item_model['is_error'] = False # Construct a json representation of a TagResults model From 38d309a0bc9ef234f76601ffa3a33e322239b95e Mon Sep 17 00:00:00 2001 From: francescadecicco Date: Fri, 4 Jul 2025 12:25:15 +0200 Subject: [PATCH 4/9] feat(Global Search/Tagging): regenerated services with latest API definition Signed-off-by: francescadecicco --- examples/test_global_tagging_v1_examples.py | 46 +++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/examples/test_global_tagging_v1_examples.py b/examples/test_global_tagging_v1_examples.py index 8633764a..321001f0 100644 --- a/examples/test_global_tagging_v1_examples.py +++ b/examples/test_global_tagging_v1_examples.py @@ -141,6 +141,29 @@ def test_attach_tag_example(self): except ApiException as e: pytest.fail(str(e)) + @needscredentials + def test_attach_tag_query_example(self): + """ + attach_tag request example + """ + try: + print('\nattach_tag() result:') + # begin-attach_tag + + filter = 'crn: "%s"' (resource_crn) + query_string_model = {'query_string': 'resource_crn} + + tag_results = global_tagging_service.attach_tag( + query=query_string_model, tag_names=['tag_test_3', 'tag_test_4'], tag_type='user' + ).get_result() + + print(json.dumps(tag_results, indent=2)) + + # end-attach_tag + + except ApiException as e: + pytest.fail(str(e)) + @needscredentials def test_detach_tag_example(self): """ @@ -163,6 +186,29 @@ def test_detach_tag_example(self): except ApiException as e: pytest.fail(str(e)) + @needscredentials + def test_detach_tag_query_example(self): + """ + detach_tag request example + """ + try: + print('\nattach_tag() result:') + # begin-attach_tag + + filter = 'crn: "%s"' (resource_crn) + query_string_model = {'query_string': 'resource_crn} + + tag_results = global_tagging_service.detach_tag( + query=query_string_model, tag_names=['tag_test_3', 'tag_test_4'], tag_type='user' + ).get_result() + + print(json.dumps(tag_results, indent=2)) + + # end-attach_tag + + except ApiException as e: + pytest.fail(str(e)) + @needscredentials def test_delete_tag_example(self): """ From f72e0d20e8cc439ef31b53ec4f677401df4e9760 Mon Sep 17 00:00:00 2001 From: francescadecicco Date: Fri, 4 Jul 2025 12:30:51 +0200 Subject: [PATCH 5/9] feat(Global Search/Tagging): regenerated services with latest API definition Signed-off-by: francescadecicco --- examples/test_global_tagging_v1_examples.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/test_global_tagging_v1_examples.py b/examples/test_global_tagging_v1_examples.py index 321001f0..40acf2aa 100644 --- a/examples/test_global_tagging_v1_examples.py +++ b/examples/test_global_tagging_v1_examples.py @@ -151,7 +151,7 @@ def test_attach_tag_query_example(self): # begin-attach_tag filter = 'crn: "%s"' (resource_crn) - query_string_model = {'query_string': 'resource_crn} + query_string_model = {'query_string': filter} tag_results = global_tagging_service.attach_tag( query=query_string_model, tag_names=['tag_test_3', 'tag_test_4'], tag_type='user' @@ -196,7 +196,7 @@ def test_detach_tag_query_example(self): # begin-attach_tag filter = 'crn: "%s"' (resource_crn) - query_string_model = {'query_string': 'resource_crn} + query_string_model = {'query_string': filter} tag_results = global_tagging_service.detach_tag( query=query_string_model, tag_names=['tag_test_3', 'tag_test_4'], tag_type='user' From 5c343969e2c1f3084917614adfef6a2da9a49501 Mon Sep 17 00:00:00 2001 From: francescadecicco Date: Fri, 4 Jul 2025 12:56:46 +0200 Subject: [PATCH 6/9] fix(Global Search/Tagging): regenerated services with latest API definition Signed-off-by: francescadecicco --- examples/test_global_tagging_v1_examples.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/test_global_tagging_v1_examples.py b/examples/test_global_tagging_v1_examples.py index 40acf2aa..6fca3a4f 100644 --- a/examples/test_global_tagging_v1_examples.py +++ b/examples/test_global_tagging_v1_examples.py @@ -68,7 +68,8 @@ def setup_class(cls): # Load the configuration global config - config = read_external_sources(GlobalTaggingV1.DEFAULT_SERVICE_NAME) + config = read_external_sources( + GlobalTaggingV1.DEFAULT_SERVICE_NAME) global resource_crn resource_crn = config.get("RESOURCE_CRN") @@ -238,7 +239,8 @@ def test_delete_tag_all_example(self): print('\ndelete_tag_all() result:') # begin-delete_tag_all - delete_tags_result = global_tagging_service.delete_tag_all(tag_type='user').get_result() + delete_tags_result = global_tagging_service.delete_tag_all( + tag_type='user').get_result() print(json.dumps(delete_tags_result, indent=2)) @@ -251,4 +253,4 @@ def test_delete_tag_all_example(self): # endregion ############################################################################## # End of Examples for Service: GlobalTaggingV1 -############################################################################## +############################################################################## \ No newline at end of file From 839740034b13e20a2d13b204cd76422d0797d64c Mon Sep 17 00:00:00 2001 From: francescadecicco Date: Fri, 4 Jul 2025 16:30:05 +0200 Subject: [PATCH 7/9] feat(Global Search/Tagging): regenerated services with latest API definition Signed-off-by: francescadecicco --- examples/test_global_tagging_v1_examples.py | 29 ++++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/examples/test_global_tagging_v1_examples.py b/examples/test_global_tagging_v1_examples.py index 6fca3a4f..d7b59d9d 100644 --- a/examples/test_global_tagging_v1_examples.py +++ b/examples/test_global_tagging_v1_examples.py @@ -77,8 +77,8 @@ def setup_class(cls): print('Setup complete.') needscredentials = pytest.mark.skipif( - not os.path.exists(config_file), reason="External configuration not available, skipping..." - ) + not os.path.exists(config_file), + reason="External configuration not available, skipping...") @needscredentials def test_create_tag_example(self): @@ -110,8 +110,11 @@ def test_list_tags_example(self): # begin-list_tags tag_list = global_tagging_service.list_tags( - tag_type='user', attached_only=True, full_data=True, providers=['ghost'], order_by_name='asc' - ).get_result() + tag_type='user', + attached_only=True, + full_data=True, + providers=['ghost'], + order_by_name='asc').get_result() print(json.dumps(tag_list, indent=2)) @@ -132,8 +135,8 @@ def test_attach_tag_example(self): resource_model = {'resource_id': resource_crn} tag_results = global_tagging_service.attach_tag( - resources=[resource_model], tag_names=['tag_test_1', 'tag_test_2'], tag_type='user' - ).get_result() + resources=[resource_model], tag_names=[ + 'tag_test_1', 'tag_test_2'], tag_type='user').get_result() print(json.dumps(tag_results, indent=2)) @@ -155,8 +158,8 @@ def test_attach_tag_query_example(self): query_string_model = {'query_string': filter} tag_results = global_tagging_service.attach_tag( - query=query_string_model, tag_names=['tag_test_3', 'tag_test_4'], tag_type='user' - ).get_result() + query=query_string_model, tag_names=[ + 'tag_test_3', 'tag_test_4'], tag_type='user').get_result() print(json.dumps(tag_results, indent=2)) @@ -177,8 +180,8 @@ def test_detach_tag_example(self): resource_model = {'resource_id': resource_crn} tag_results = global_tagging_service.detach_tag( - resources=[resource_model], tag_names=['tag_test_1', 'tag_test_2'], tag_type='user' - ).get_result() + resources=[resource_model], tag_names=[ + 'tag_test_1', 'tag_test_2'], tag_type='user').get_result() print(json.dumps(tag_results, indent=2)) @@ -200,8 +203,8 @@ def test_detach_tag_query_example(self): query_string_model = {'query_string': filter} tag_results = global_tagging_service.detach_tag( - query=query_string_model, tag_names=['tag_test_3', 'tag_test_4'], tag_type='user' - ).get_result() + query=query_string_model, tag_names=[ + 'tag_test_3', 'tag_test_4'], tag_type='user').get_result() print(json.dumps(tag_results, indent=2)) @@ -253,4 +256,4 @@ def test_delete_tag_all_example(self): # endregion ############################################################################## # End of Examples for Service: GlobalTaggingV1 -############################################################################## \ No newline at end of file +############################################################################## From a2997ae2972a6b8df61faab29715229b67071eec Mon Sep 17 00:00:00 2001 From: francescadecicco Date: Tue, 8 Jul 2025 16:32:12 +0200 Subject: [PATCH 8/9] fix(Global Search/Tagging): regenerated services with latest API definition Signed-off-by: francescadecicco --- examples/test_global_tagging_v1_examples.py | 71 +++------------------ 1 file changed, 10 insertions(+), 61 deletions(-) diff --git a/examples/test_global_tagging_v1_examples.py b/examples/test_global_tagging_v1_examples.py index d7b59d9d..bf4d8c17 100644 --- a/examples/test_global_tagging_v1_examples.py +++ b/examples/test_global_tagging_v1_examples.py @@ -68,8 +68,7 @@ def setup_class(cls): # Load the configuration global config - config = read_external_sources( - GlobalTaggingV1.DEFAULT_SERVICE_NAME) + config = read_external_sources(GlobalTaggingV1.DEFAULT_SERVICE_NAME) global resource_crn resource_crn = config.get("RESOURCE_CRN") @@ -77,8 +76,8 @@ def setup_class(cls): print('Setup complete.') needscredentials = pytest.mark.skipif( - not os.path.exists(config_file), - reason="External configuration not available, skipping...") + not os.path.exists(config_file), reason="External configuration not available, skipping..." + ) @needscredentials def test_create_tag_example(self): @@ -110,11 +109,8 @@ def test_list_tags_example(self): # begin-list_tags tag_list = global_tagging_service.list_tags( - tag_type='user', - attached_only=True, - full_data=True, - providers=['ghost'], - order_by_name='asc').get_result() + tag_type='user', attached_only=True, full_data=True, providers=['ghost'], order_by_name='asc' + ).get_result() print(json.dumps(tag_list, indent=2)) @@ -135,31 +131,8 @@ def test_attach_tag_example(self): resource_model = {'resource_id': resource_crn} tag_results = global_tagging_service.attach_tag( - resources=[resource_model], tag_names=[ - 'tag_test_1', 'tag_test_2'], tag_type='user').get_result() - - print(json.dumps(tag_results, indent=2)) - - # end-attach_tag - - except ApiException as e: - pytest.fail(str(e)) - - @needscredentials - def test_attach_tag_query_example(self): - """ - attach_tag request example - """ - try: - print('\nattach_tag() result:') - # begin-attach_tag - - filter = 'crn: "%s"' (resource_crn) - query_string_model = {'query_string': filter} - - tag_results = global_tagging_service.attach_tag( - query=query_string_model, tag_names=[ - 'tag_test_3', 'tag_test_4'], tag_type='user').get_result() + tag_names=['tag_test_1', 'tag_test_2'], tag_type='user' + ).get_result() print(json.dumps(tag_results, indent=2)) @@ -180,8 +153,8 @@ def test_detach_tag_example(self): resource_model = {'resource_id': resource_crn} tag_results = global_tagging_service.detach_tag( - resources=[resource_model], tag_names=[ - 'tag_test_1', 'tag_test_2'], tag_type='user').get_result() + tag_names=['tag_test_1', 'tag_test_2'], tag_type='user' + ).get_result() print(json.dumps(tag_results, indent=2)) @@ -190,29 +163,6 @@ def test_detach_tag_example(self): except ApiException as e: pytest.fail(str(e)) - @needscredentials - def test_detach_tag_query_example(self): - """ - detach_tag request example - """ - try: - print('\nattach_tag() result:') - # begin-attach_tag - - filter = 'crn: "%s"' (resource_crn) - query_string_model = {'query_string': filter} - - tag_results = global_tagging_service.detach_tag( - query=query_string_model, tag_names=[ - 'tag_test_3', 'tag_test_4'], tag_type='user').get_result() - - print(json.dumps(tag_results, indent=2)) - - # end-attach_tag - - except ApiException as e: - pytest.fail(str(e)) - @needscredentials def test_delete_tag_example(self): """ @@ -242,8 +192,7 @@ def test_delete_tag_all_example(self): print('\ndelete_tag_all() result:') # begin-delete_tag_all - delete_tags_result = global_tagging_service.delete_tag_all( - tag_type='user').get_result() + delete_tags_result = global_tagging_service.delete_tag_all(tag_type='user').get_result() print(json.dumps(delete_tags_result, indent=2)) From bf2569325c8a227f4cc8b78fa57d441525a80d4a Mon Sep 17 00:00:00 2001 From: Norbert Biczo Date: Wed, 9 Jul 2025 11:19:04 +0200 Subject: [PATCH 9/9] fix: remove unused variable Signed-off-by: Norbert Biczo --- examples/test_global_tagging_v1_examples.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/test_global_tagging_v1_examples.py b/examples/test_global_tagging_v1_examples.py index bf4d8c17..52499abe 100644 --- a/examples/test_global_tagging_v1_examples.py +++ b/examples/test_global_tagging_v1_examples.py @@ -128,8 +128,6 @@ def test_attach_tag_example(self): print('\nattach_tag() result:') # begin-attach_tag - resource_model = {'resource_id': resource_crn} - tag_results = global_tagging_service.attach_tag( tag_names=['tag_test_1', 'tag_test_2'], tag_type='user' ).get_result() @@ -150,8 +148,6 @@ def test_detach_tag_example(self): print('\ndetach_tag() result:') # begin-detach_tag - resource_model = {'resource_id': resource_crn} - tag_results = global_tagging_service.detach_tag( tag_names=['tag_test_1', 'tag_test_2'], tag_type='user' ).get_result()