From cd4c707253599b1b7dc3ab2dfe330ce91e7afa2c Mon Sep 17 00:00:00 2001 From: gpongelli Date: Tue, 28 Mar 2023 15:46:44 +0200 Subject: [PATCH 1/3] feat: use a keyword argument to retrieve all workitem attributes --- rtcclient/base.py | 15 ++++++++++----- rtcclient/client.py | 11 +++++++---- rtcclient/workitem.py | 4 ++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/rtcclient/base.py b/rtcclient/base.py index ea6453d..a5936ba 100644 --- a/rtcclient/base.py +++ b/rtcclient/base.py @@ -17,12 +17,17 @@ class RTCBase(object): OSLC_CR_XML = "application/x-oslc-cm-change-request+xml" OSLC_CR_JSON = "application/x-oslc-cm-change-request+json" - def __init__(self, url): + def __init__(self, url, **kwargs): self.url = self.validate_url(url) + self.__skip_full_attributes = kwargs.get('skip_full_attributes', True) def __repr__(self): return "<%s %s>" % (self.__class__.__name__, str(self)) + @property + def skip_full_attributes(self): + return self.__skip_full_attributes + @abc.abstractmethod def __str__(self): pass @@ -244,8 +249,8 @@ class FieldBase(RTCBase): __metaclass__ = abc.ABCMeta log = logging.getLogger("base.FieldBase") - def __init__(self, url, rtc_obj, raw_data=None): - RTCBase.__init__(self, url) + def __init__(self, url, rtc_obj, raw_data=None, **kwargs): + RTCBase.__init__(self, url, **kwargs) self.field_alias = dict() self.rtc_obj = rtc_obj self.raw_data = raw_data @@ -306,8 +311,8 @@ def __process_items(self, item): attr = key.split(":")[-1].replace("-", "_") attr_list = attr.split(".") - # ignore long attributes - if len(attr_list) > 1: + # user want to ignore long attributes + if self.skip_full_attributes and len(attr_list) > 1: # attr = "_".join([attr_list[-2], # attr_list[-1]]) return None diff --git a/rtcclient/client.py b/rtcclient/client.py index 5d2be51..efc4408 100644 --- a/rtcclient/client.py +++ b/rtcclient/client.py @@ -59,7 +59,8 @@ def __init__(self, searchpath=None, ends_with_jazz=True, verify: Union[bool, str] = False, - old_rtc_authentication=False): + old_rtc_authentication=False, + **kwargs): """Initialization See params above @@ -70,7 +71,7 @@ def __init__(self, self.proxies = proxies self.verify = verify self.old_rtc_authentication = old_rtc_authentication - RTCBase.__init__(self, url) + RTCBase.__init__(self, url, **kwargs) if not isinstance(ends_with_jazz, bool): raise exception.BadValue("ends_with_jazz is not boolean") @@ -980,13 +981,14 @@ def listFieldsFromWorkitem(self, copied_from, keep=False): return self.templater.listFieldsFromWorkitem(copied_from, keep=keep) - def getWorkitem(self, workitem_id, returned_properties=None): + def getWorkitem(self, workitem_id, returned_properties=None, skip_full_attributes=True): """Get :class:`rtcclient.workitem.Workitem` object by its id/number :param workitem_id: the workitem id/number (integer or equivalent string) :param returned_properties: the returned properties that you want. Refer to :class:`rtcclient.client.RTCClient` for more explanations + :param skip_full_attributes: flag to retrieve all attributes. :return: the :class:`rtcclient.workitem.Workitem` object :rtype: rtcclient.workitem.Workitem """ @@ -1019,7 +1021,8 @@ def getWorkitem(self, workitem_id, returned_properties=None): return Workitem(workitem_url, self, workitem_id=workitem_id, - raw_data=workitem_raw) + raw_data=workitem_raw, + skip_full_attributes=skip_full_attributes) except ValueError: excp_msg = "Please input a valid workitem id" diff --git a/rtcclient/workitem.py b/rtcclient/workitem.py index 7507774..e3684ec 100644 --- a/rtcclient/workitem.py +++ b/rtcclient/workitem.py @@ -27,9 +27,9 @@ class Workitem(FieldBase): OSLC_CR_RDF = "application/rdf+xml" - def __init__(self, url, rtc_obj, workitem_id=None, raw_data=None): + def __init__(self, url, rtc_obj, workitem_id=None, raw_data=None, **kwargs): self.identifier = workitem_id - FieldBase.__init__(self, url, rtc_obj, raw_data) + FieldBase.__init__(self, url, rtc_obj, raw_data, **kwargs) if self.identifier is None: self.identifier = self.url.split("/")[-1] From adc665013bd744cb4a8e90fb2f99a812898c9f0e Mon Sep 17 00:00:00 2001 From: gpongelli Date: Tue, 28 Mar 2023 17:16:03 +0200 Subject: [PATCH 2/3] test for full_attributes --- rtcclient/client.py | 5 +++- tests/test_client.py | 67 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/rtcclient/client.py b/rtcclient/client.py index efc4408..ac7cb58 100644 --- a/rtcclient/client.py +++ b/rtcclient/client.py @@ -981,7 +981,10 @@ def listFieldsFromWorkitem(self, copied_from, keep=False): return self.templater.listFieldsFromWorkitem(copied_from, keep=keep) - def getWorkitem(self, workitem_id, returned_properties=None, skip_full_attributes=True): + def getWorkitem(self, + workitem_id, + returned_properties=None, + skip_full_attributes=True): """Get :class:`rtcclient.workitem.Workitem` object by its id/number :param workitem_id: the workitem id/number diff --git a/tests/test_client.py b/tests/test_client.py index 49e7fd5..6d93c8c 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1626,6 +1626,73 @@ def test_get_workitem(self, mocker, myrtcclient): raw_data=utils_test.workitem1) assert workitem1 == workitem11 + @pytest.mark.parametrize('item,expected', [ + ('com.ibm.workitem.attribute.custom.completeperc', "0"), + ("com.ibm.team.workitem.linktype.parentworkitem.parent", + "input title here for 161"), + ("com.ibm.team.workitem.linktype.attachment.attachment", + "input title here for 161"), + ("com.ibm.team.workitem.linktype.resolvesworkitem.resolves", + "input title here for 161"), + ('com.ibm.team.workitem.linktype.relatedworkitem.related', + "input title here for 161"), + ('com.ibm.team.workitem.linktype.resolvesworkitem.resolves', + "input title here for 161"), + ("com.ibm.team.enterprise.promotion.linktype.promotionBuildResult.promotionBuildResult", + "input title here for 161"), + ("com.ibm.team.enterprise.deployment.linktype.deploymentDefinition.packageDefinition", + "input title here for 161"), + ("com.ibm.team.enterprise.deployment.linktype.deploymentBuildResult.packageBuildResult", + "input title here for 161"), + ("com.ibm.team.enterprise.promotion.linktype.resultWorkItem.promoted", + "input title here for 161"), + ("com.ibm.team.workitem.linktype.schedulePredecessor.predecessor", + "input title here for 161"), + ("com.ibm.team.build.linktype.includedPackages.com.ibm.team.build.common.link.includedInPackages", + "input title here for 161"), + ("com.ibm.team.enterprise.promotion.linktype.gapChangeSets.gapChangeSets", + "input title here for 161"), + ("com.ibm.team.workitem.linktype.resolvesworkitem.resolvedBy", + "input title here for 161"), + ("com.ibm.team.workitem.linktype.duplicateworkitem.duplicates", + "input title here for 161"), + ("com.ibm.team.workitem.linktype.parentworkitem.children", + "input title here for 161"), + ("com.ibm.team.enterprise.promotion.linktype.promotedBuildMaps.promotedBuildMaps", + "input title here for 161"), + ("com.ibm.team.workitem.linktype.schedulePredecessor.successor", + "input title here for 161"), + ("com.ibm.team.filesystem.workitems.change_set.com.ibm.team.scm.ChangeSet", + "input title here for 161"), + ("com.ibm.team.workitem.linktype.blocksworkitem.dependsOn", + "input title here for 161"), + ("com.ibm.team.enterprise.promotion.linktype.resultWorkItem.result", + "input title here for 161"), + ("com.ibm.team.workitem.linktype.relatedartifact.relatedArtifact", + "input title here for 161"), + ("com.ibm.workitem.attribute.custom.odc.deftype", None), + ("com.ibm.workitem.attribute.custom.odc.history", None), + ("com.ibm.workitem.attribute.custom.odc.qualifier", None), + ("com.ibm.workitem.attribute.custom.odc.trigger", None), + ("com.ibm.workitem.attribute.custome.isvalid", None) + ]) + def test_get_workitem_full_attributes(self, mocker, myrtcclient, item, + expected): + mocked_get = mocker.patch("requests.get") + mock_resp = mocker.MagicMock(spec=requests.Response) + mock_resp.status_code = 200 + mock_resp.content = utils_test.workitem1_raw + mocked_get.return_value = mock_resp + + # Workitem1 + workitem1 = Workitem("http://test.url:9443/jazz/oslc/workitems/161", + myrtcclient, + workitem_id=161, + raw_data=utils_test.workitem1, + skip_full_attributes=False) + assert workitem1.identifier == "161" + assert workitem1[item] == expected + @pytest.fixture def mock_get_workitems(self, mocker): mocked_get = mocker.patch("requests.get") From 4a872df9464f62e4bd8d65f1dc3eb4fa63e34867 Mon Sep 17 00:00:00 2001 From: Gabriele Pongelli Date: Wed, 29 Mar 2023 06:14:27 +0000 Subject: [PATCH 3/3] skip_full_attributes as init arg --- rtcclient/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtcclient/base.py b/rtcclient/base.py index a5936ba..2c79e5f 100644 --- a/rtcclient/base.py +++ b/rtcclient/base.py @@ -17,9 +17,9 @@ class RTCBase(object): OSLC_CR_XML = "application/x-oslc-cm-change-request+xml" OSLC_CR_JSON = "application/x-oslc-cm-change-request+json" - def __init__(self, url, **kwargs): + def __init__(self, url, skip_full_attributes=True, **kwargs): self.url = self.validate_url(url) - self.__skip_full_attributes = kwargs.get('skip_full_attributes', True) + self.__skip_full_attributes = skip_full_attributes def __repr__(self): return "<%s %s>" % (self.__class__.__name__, str(self))