From 3abf76997ff87a2f4754c27f43f2435eb653ee9c Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Tue, 29 Oct 2024 16:33:48 -0300 Subject: [PATCH 1/9] =?UTF-8?q?Renomeia=20os=20m=C3=A9todos,=20eliminando?= =?UTF-8?q?=20'=5Fcontribs'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/article_contribs.py | 24 +++++------ tests/sps/validation/test_article_contribs.py | 40 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/packtools/sps/validation/article_contribs.py b/packtools/sps/validation/article_contribs.py index 35cc15605..08f4560f6 100644 --- a/packtools/sps/validation/article_contribs.py +++ b/packtools/sps/validation/article_contribs.py @@ -31,7 +31,7 @@ class ContribValidation: def __init__(self, contrib): self.contrib = contrib - def validate_contribs_role(self, credit_taxonomy_terms_and_urls): + def validate_role(self, credit_taxonomy_terms_and_urls): """ Checks contributor roles according to CRediT taxonomy. @@ -117,7 +117,7 @@ def validate_contribs_role(self, credit_taxonomy_terms_and_urls): author=_contrib_name, ) - def validate_contribs_orcid_format(self, error_level="ERROR"): + def validate_orcid_format(self, error_level="ERROR"): """ Checks whether a contributor's ORCID is valid. @@ -195,7 +195,7 @@ def validate_contribs_orcid_format(self, error_level="ERROR"): error_level=error_level ) - def validate_contribs_orcid_is_registered(self, callable_get_validate=None, error_level="ERROR"): + def validate_orcid_is_registered(self, callable_get_validate=None, error_level="ERROR"): """ Checks whether a contributor's ORCID is registered. @@ -279,7 +279,7 @@ def validate_contribs_orcid_is_registered(self, callable_get_validate=None, erro error_level=error_level ) - def validate_contribs_collab_list(self, content_types, error_level="ERROR"): + def validate_collab_list(self, content_types, error_level="ERROR"): """ Checks if there is identification of authors for a group of collaborators. @@ -351,7 +351,7 @@ def validate_contribs_collab_list(self, content_types, error_level="ERROR"): error_level=error_level ) - def validate_contribs_affiliations(self, error_level="ERROR"): + def validate_affiliations(self, error_level="ERROR"): """ Checks if an author has the corresponding affiliation data. @@ -441,11 +441,11 @@ def __init__(self, contrib, data, content_types): def validate(self): contrib = ContribValidation(self.contrib) - yield from contrib.validate_contribs_role(self.data["credit_taxonomy_terms_and_urls"]) - yield from contrib.validate_contribs_orcid_format() - yield from contrib.validate_contribs_orcid_is_registered(self.data["callable_get_data"]) - yield from contrib.validate_contribs_collab_list(self.content_types) - yield from contrib.validate_contribs_affiliations() + yield from contrib.validate_role(self.data["credit_taxonomy_terms_and_urls"]) + yield from contrib.validate_orcid_format() + yield from contrib.validate_orcid_is_registered(self.data["callable_get_data"]) + yield from contrib.validate_collab_list(self.content_types) + yield from contrib.validate_affiliations() class ArticleContribsValidation: @@ -461,7 +461,7 @@ def content_types(self): for contrib_group in self.xmltree.xpath('.//contrib-group') ] - def validate_contribs_orcid_is_unique(self, error_level="ERROR"): + def validate_orcid_is_unique(self, error_level="ERROR"): """ Checks whether a contributor's ORCID is unique. @@ -552,7 +552,7 @@ def validate_contribs_orcid_is_unique(self, error_level="ERROR"): def validate(self): # A validação da unicidade do ORCID é feita uma única vez por artigo - yield from self.validate_contribs_orcid_is_unique() + yield from self.validate_orcid_is_unique() for contrib in self.contribs.contribs: yield from ContribsValidation(contrib, self.data, self.content_types).validate() diff --git a/tests/sps/validation/test_article_contribs.py b/tests/sps/validation/test_article_contribs.py index 9d6cd21bd..fab3dbffe 100644 --- a/tests/sps/validation/test_article_contribs.py +++ b/tests/sps/validation/test_article_contribs.py @@ -65,7 +65,7 @@ def test_without_role(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_role( + ContribValidation(contrib).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -146,7 +146,7 @@ def test_role_and_content_type_empty(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_role( + ContribValidation(contrib).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -279,7 +279,7 @@ def test_role_without_content_type(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_role( + ContribValidation(contrib).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -376,7 +376,7 @@ def test_role_no_text_with_content_type(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_role( + ContribValidation(contrib).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -473,7 +473,7 @@ def test_wrong_role_and_content_type(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_role( + ContribValidation(contrib).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -567,7 +567,7 @@ def test_success_role(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_role( + ContribValidation(contrib).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -612,7 +612,7 @@ def test_validate_authors_orcid_format_fail(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_orcid_format()) + ContribValidation(contrib).validate_orcid_format()) expected = [ { @@ -683,7 +683,7 @@ def test_validate_authors_orcid_format_without_orcid(self): """ xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] - obtained = list(ContribValidation(contrib).validate_contribs_orcid_format()) + obtained = list(ContribValidation(contrib).validate_orcid_format()) expected = [ { @@ -757,7 +757,7 @@ def test_validate_authors_orcid_format_success(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_orcid_format()) + ContribValidation(contrib).validate_orcid_format()) expected = [ { @@ -831,7 +831,7 @@ def test_validate_authors_orcid_is_unique_ok(self): xmltree = etree.fromstring(xml) obtained = list( - ArticleContribsValidation(xmltree, data={}).validate_contribs_orcid_is_unique() + ArticleContribsValidation(xmltree, data={}).validate_orcid_is_unique() ) expected = [ @@ -897,7 +897,7 @@ def test_validate_authors_orcid_is_unique_not_ok(self): xmltree = etree.fromstring(xml) obtained = list( - ArticleContribsValidation(xmltree, data={}).validate_contribs_orcid_is_unique() + ArticleContribsValidation(xmltree, data={}).validate_orcid_is_unique() ) expected = [ @@ -962,7 +962,7 @@ def test_validate_authors_orcid_is_registered_success(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_orcid_is_registered(callable_get_data) + ContribValidation(contrib).validate_orcid_is_registered(callable_get_data) ) expected = [ @@ -1039,7 +1039,7 @@ def test_validate_authors_orcid_is_registered_fail(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_orcid_is_registered(callable_get_data) + ContribValidation(contrib).validate_orcid_is_registered(callable_get_data) ) expected = [ @@ -1116,7 +1116,7 @@ def test_validate_authors_orcid_is_registered_fail_empty(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_contribs_orcid_is_registered(callable_get_data_empty) + ContribValidation(contrib).validate_orcid_is_registered(callable_get_data_empty) ) expected = [ @@ -1188,7 +1188,7 @@ def test_validate_authors_with_collab_list(self): contrib = list(ArticleContribs(xml_tree).contribs)[0] content_types = ArticleContribsValidation(xmltree=xml_tree, data={}).content_types - obtained = list(ContribValidation(contrib).validate_contribs_collab_list(content_types)) + obtained = list(ContribValidation(contrib).validate_collab_list(content_types)) self.assertEqual([], obtained) @@ -1213,7 +1213,7 @@ def test_validate_authors_without_collab_list(self): contrib = list(ArticleContribs(xml_tree).contribs)[0] content_types = ArticleContribsValidation(xmltree=xml_tree, data={}).content_types - obtained = list(ContribValidation(contrib).validate_contribs_collab_list(content_types)) + obtained = list(ContribValidation(contrib).validate_collab_list(content_types)) expected = [ { @@ -1537,7 +1537,7 @@ def test_validate_unique_orcid_for_authors_with_same_name(self): xmltree = etree.fromstring(xml) obtained = list( - ArticleContribsValidation(xmltree, data={}).validate_contribs_orcid_is_unique() + ArticleContribsValidation(xmltree, data={}).validate_orcid_is_unique() ) expected = [ @@ -1610,7 +1610,7 @@ def test_validate_unique_orcid_for_authors_with_different_names(self): xmltree = etree.fromstring(xml) obtained = list( - ArticleContribsValidation(xmltree, data={}).validate_contribs_orcid_is_unique() + ArticleContribsValidation(xmltree, data={}).validate_orcid_is_unique() ) expected = [ @@ -1695,7 +1695,7 @@ def test_validate_authors_affiliations_success(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] - obtained = list(ContribValidation(contrib).validate_contribs_affiliations()) + obtained = list(ContribValidation(contrib).validate_affiliations()) self.assertListEqual(obtained, []) def test_validate_authors_affiliations_fail(self): @@ -1728,7 +1728,7 @@ def test_validate_authors_affiliations_fail(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] - obtained = list(ContribValidation(contrib).validate_contribs_affiliations()) + obtained = list(ContribValidation(contrib).validate_affiliations()) expected = [ { 'title': 'Author without affiliation', From b15a7861d761f0b9412f43e5bd2cd8cd0b293269 Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Tue, 29 Oct 2024 17:16:38 -0300 Subject: [PATCH 2/9] Troca _contrib_name por self.contrib_name --- packtools/sps/validation/article_contribs.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/packtools/sps/validation/article_contribs.py b/packtools/sps/validation/article_contribs.py index 08f4560f6..d94403848 100644 --- a/packtools/sps/validation/article_contribs.py +++ b/packtools/sps/validation/article_contribs.py @@ -30,6 +30,7 @@ def _response(contrib, is_valid, expected, obtained, author, error_level="ERROR" class ContribValidation: def __init__(self, contrib): self.contrib = contrib + self.contrib_name = self.contrib.get("contrib_full_name") def validate_role(self, credit_taxonomy_terms_and_urls): """ @@ -91,8 +92,6 @@ def validate_role(self, credit_taxonomy_terms_and_urls): for role in credit_taxonomy_terms_and_urls ] - _contrib_name = self.contrib.get("contrib_full_name") - obtained_value = [ f'{role.get("text")}' for role in (self.contrib.get("contrib_role") or []) @@ -106,7 +105,7 @@ def validate_role(self, credit_taxonomy_terms_and_urls): is_valid=is_valid, expected=expected_value, obtained=role, - author=_contrib_name, + author=self.contrib_name, ) else: yield _response( @@ -114,7 +113,7 @@ def validate_role(self, credit_taxonomy_terms_and_urls): is_valid=False, expected=expected_value, obtained=None, - author=_contrib_name, + author=self.contrib_name, ) def validate_orcid_format(self, error_level="ERROR"): @@ -171,7 +170,6 @@ def validate_orcid_format(self, error_level="ERROR"): r"^[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}$" ) - _contrib_name = self.contrib.get("contrib_full_name") _orcid = self.contrib.get("contrib_ids", {}).get("orcid") is_valid = bool(_orcid and re.match(_default_orcid, _orcid)) expected_value = ( @@ -190,7 +188,7 @@ def validate_orcid_format(self, error_level="ERROR"): is_valid=is_valid, expected=expected_value, obtained=_orcid, - advice=f"The author {_contrib_name} has {_orcid} as ORCID and its format is not valid. Provide a valid ORCID.", + advice=f"The author {self.contrib_name} has {_orcid} as ORCID and its format is not valid. Provide a valid ORCID.", data=self.contrib, error_level=error_level ) @@ -257,10 +255,9 @@ def validate_orcid_is_registered(self, callable_get_validate=None, error_level=" callable_get_validate = ( callable_get_validate or _callable_extern_validate_default ) - obtained_contrib_name = self.contrib.get("contrib_full_name") orcid = self.contrib.get("contrib_ids", {}).get("orcid") expected_contrib_name = callable_get_validate(orcid) - is_valid = obtained_contrib_name == expected_contrib_name + is_valid = self.contrib_name == expected_contrib_name yield format_response( title="Author ORCID element is registered", @@ -273,7 +270,7 @@ def validate_orcid_is_registered(self, callable_get_validate=None, error_level=" validation_type="exist", is_valid=is_valid, expected=[orcid, expected_contrib_name], - obtained=[orcid, obtained_contrib_name], + obtained=[orcid, self.contrib_name], advice="ORCID {} is not registered to any authors".format(orcid), data=self.contrib, error_level=error_level @@ -413,7 +410,6 @@ def validate_affiliations(self, error_level="ERROR"): """ affs = self.contrib.get("affs") if not affs: - _contrib_name = self.contrib.get("contrib_full_name") yield format_response( title='Author without affiliation', parent=self.contrib.get("parent"), @@ -426,7 +422,7 @@ def validate_affiliations(self, error_level="ERROR"): is_valid=False, expected='author affiliation data', obtained=None, - advice=f'provide author affiliation data for {_contrib_name}', + advice=f'provide author affiliation data for {self.contrib_name}', data=self.contrib, error_level=error_level ) From f8bce1c5e8a94d43a459933ad8a27a48599a36cf Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Wed, 30 Oct 2024 09:51:09 -0300 Subject: [PATCH 3/9] =?UTF-8?q?Elimina=20redund=C3=A2ncias=20nos=20textos?= =?UTF-8?q?=20e=20deixa=20o=20conte=C3=BAdo=20de=20'advice'=20mais=20curto?= =?UTF-8?q?=20e=20direto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/article_contribs.py | 30 +++--- tests/sps/validation/test_article_contribs.py | 97 +++++++++---------- 2 files changed, 63 insertions(+), 64 deletions(-) diff --git a/packtools/sps/validation/article_contribs.py b/packtools/sps/validation/article_contribs.py index d94403848..57d48f3a0 100644 --- a/packtools/sps/validation/article_contribs.py +++ b/packtools/sps/validation/article_contribs.py @@ -10,7 +10,7 @@ def _callable_extern_validate_default(orcid): def _response(contrib, is_valid, expected, obtained, author, error_level="ERROR"): return format_response( - title="CRediT taxonomy for contribs", + title="CRediT taxonomy", parent=contrib.get("parent"), parent_id=contrib.get("parent_id"), parent_article_type=contrib.get("parent_article_type"), @@ -21,7 +21,7 @@ def _response(contrib, is_valid, expected, obtained, author, error_level="ERROR" is_valid=is_valid, expected=expected, obtained=obtained, - advice=f"The author {author} does not have a valid role. Provide a role from the list: {expected}", + advice=f"Provide the correct CRediT taxonomy: {expected}", data=contrib, error_level=error_level ) @@ -73,7 +73,7 @@ def validate_role(self, credit_taxonomy_terms_and_urls): A list of dictionaries, such as: [ { - 'title': 'CRediT taxonomy for contribs', + 'title': 'CRediT taxonomy', 'xpath': './contrib-group//contrib//role[@content-type="https://credit.niso.org/contributor-roles/*"]', 'validation_type': 'value in list', 'response': 'OK', @@ -155,7 +155,7 @@ def validate_orcid_format(self, error_level="ERROR"): A list of dictionaries, such as: [ { - 'title': 'Author ORCID', + 'title': 'ORCID format', 'xpath': './/contrib-id[@contrib-id-type="orcid"]', 'validation_type': 'format', 'response': 'OK', @@ -173,11 +173,11 @@ def validate_orcid_format(self, error_level="ERROR"): _orcid = self.contrib.get("contrib_ids", {}).get("orcid") is_valid = bool(_orcid and re.match(_default_orcid, _orcid)) expected_value = ( - _orcid if is_valid else "a Open Researcher and Contributor ID valid" + _orcid if is_valid else "valid ORCID" ) yield format_response( - title="Author ORCID", + title="ORCID format", parent=self.contrib.get("parent"), parent_id=self.contrib.get("parent_id"), parent_article_type=self.contrib.get("parent_article_type"), @@ -188,7 +188,7 @@ def validate_orcid_format(self, error_level="ERROR"): is_valid=is_valid, expected=expected_value, obtained=_orcid, - advice=f"The author {self.contrib_name} has {_orcid} as ORCID and its format is not valid. Provide a valid ORCID.", + advice=f"Provide a valid ORCID.", data=self.contrib, error_level=error_level ) @@ -239,7 +239,7 @@ def validate_orcid_is_registered(self, callable_get_validate=None, error_level=" A list of dictionaries, such as: [ { - 'title': 'Author ORCID element is registered', + 'title': 'Registered ORCID', 'xpath': './/contrib-id[@contrib-id-type="orcid"]', 'validation_type': 'exist', 'response': 'OK', @@ -260,18 +260,18 @@ def validate_orcid_is_registered(self, callable_get_validate=None, error_level=" is_valid = self.contrib_name == expected_contrib_name yield format_response( - title="Author ORCID element is registered", + title="Registered ORCID", parent=self.contrib.get("parent"), parent_id=self.contrib.get("parent_id"), parent_article_type=self.contrib.get("parent_article_type"), parent_lang=self.contrib.get("parent_lang"), item="contrib-id", sub_item='@contrib-id-type="orcid"', - validation_type="exist", + validation_type="registered", is_valid=is_valid, expected=[orcid, expected_contrib_name], obtained=[orcid, self.contrib_name], - advice="ORCID {} is not registered to any authors".format(orcid), + advice=f"Provide a valid ORCID for {self.contrib_name}", data=self.contrib, error_level=error_level ) @@ -420,9 +420,9 @@ def validate_affiliations(self, error_level="ERROR"): sub_item='aff', validation_type='exist', is_valid=False, - expected='author affiliation data', + expected='affiliation', obtained=None, - advice=f'provide author affiliation data for {self.contrib_name}', + advice=f'provide affiliation for {self.contrib_name}', data=self.contrib, error_level=error_level ) @@ -496,7 +496,7 @@ def validate_orcid_is_unique(self, error_level="ERROR"): A list of dictionaries, such as: [ { - 'title': 'Author ORCID element is unique', + 'title': 'Unique ORCID', 'xpath': './/contrib-id[@contrib-id-type="orcid"]', 'validation_type': 'uniqueness', 'response': 'OK', @@ -528,7 +528,7 @@ def validate_orcid_is_unique(self, error_level="ERROR"): } yield format_response( - title="Author ORCID element is unique", + title="Unique ORCID", parent="article", parent_id=None, parent_article_type=self.xmltree.get("article-type"), diff --git a/tests/sps/validation/test_article_contribs.py b/tests/sps/validation/test_article_contribs.py index fab3dbffe..fc1d0c574 100644 --- a/tests/sps/validation/test_article_contribs.py +++ b/tests/sps/validation/test_article_contribs.py @@ -72,7 +72,7 @@ def test_without_role(self): expected = [ { - "title": "CRediT taxonomy for contribs", + "title": "CRediT taxonomy", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -87,7 +87,7 @@ def test_without_role(self): ], "got_value": None, "message": """Got None, expected ['Conceptualization', 'Data curation']""", - "advice": """The author Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto does not have a valid role. Provide a role from the list: ['Conceptualization', 'Data curation']""", + "advice": """Provide the correct CRediT taxonomy: ['Conceptualization', 'Data curation']""", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_name": { @@ -153,7 +153,7 @@ def test_role_and_content_type_empty(self): expected = [ { - "title": "CRediT taxonomy for contribs", + "title": "CRediT taxonomy", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -171,7 +171,7 @@ def test_role_and_content_type_empty(self): ], "got_value": 'None', "message": """Got None, expected ['Conceptualization', 'Data curation']""", - "advice": """The author Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto does not have a valid role. Provide a role from the list: ['Conceptualization', 'Data curation']""", + "advice": """Provide the correct CRediT taxonomy: ['Conceptualization', 'Data curation']""", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_name": { @@ -232,7 +232,7 @@ def test_role_without_content_type(self): expected = [ { - "title": "CRediT taxonomy for contribs", + "title": "CRediT taxonomy", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -250,7 +250,7 @@ def test_role_without_content_type(self): "curation", ], "message": """Got Data curation, expected ['Conceptualization', 'Data curation']""", - "advice": """The author Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto does not have a valid role. Provide a role from the list: ['Conceptualization', 'Data curation']""", + "advice": """Provide the correct CRediT taxonomy: ['Conceptualization', 'Data curation']""", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_name": { @@ -324,7 +324,7 @@ def test_role_no_text_with_content_type(self): expected = [ { - "title": "CRediT taxonomy for contribs", + "title": "CRediT taxonomy", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -342,7 +342,7 @@ def test_role_no_text_with_content_type(self): "curation", ], "message": """Got None, expected ['Conceptualization', 'Data curation']""", - "advice": """The author Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto does not have a valid role. Provide a role from the list: ['Conceptualization', 'Data curation']""", + "advice": """Provide the correct CRediT taxonomy: ['Conceptualization', 'Data curation']""", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_name": { @@ -421,7 +421,7 @@ def test_wrong_role_and_content_type(self): expected = [ { - "title": "CRediT taxonomy for contribs", + "title": "CRediT taxonomy", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -439,7 +439,7 @@ def test_wrong_role_and_content_type(self): "curation", ], "message": """Got Data curation, expected ['Conceptualization', 'Data curation']""", - "advice": """The author Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto does not have a valid role. Provide a role from the list: ['Conceptualization', 'Data curation']""", + "advice": """Provide the correct CRediT taxonomy: ['Conceptualization', 'Data curation']""", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_name": { @@ -518,7 +518,7 @@ def test_success_role(self): expected = [ { - "title": "CRediT taxonomy for contribs", + "title": "CRediT taxonomy", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -616,7 +616,7 @@ def test_validate_authors_orcid_format_fail(self): expected = [ { - "title": "Author ORCID", + "title": "ORCID format", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -625,11 +625,10 @@ def test_validate_authors_orcid_format_fail(self): "sub_item": '@contrib-id-type="orcid"', "validation_type": "format", "response": "ERROR", - "expected_value": "a Open Researcher and Contributor ID valid", + "expected_value": "valid ORCID", "got_value": "0990-01-58-4853", - "message": "Got 0990-01-58-4853, expected a Open Researcher and Contributor ID valid", - "advice": "The author Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto has 0990-01-58-4853 as ORCID " - "and its format is not valid. Provide a valid ORCID.", + "message": "Got 0990-01-58-4853, expected valid ORCID", + "advice": "Provide a valid ORCID.", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_ids": {"orcid": "0990-01-58-4853"}, @@ -687,7 +686,7 @@ def test_validate_authors_orcid_format_without_orcid(self): expected = [ { - "title": "Author ORCID", + "title": "ORCID format", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -696,10 +695,10 @@ def test_validate_authors_orcid_format_without_orcid(self): "sub_item": '@contrib-id-type="orcid"', "validation_type": "format", "response": "ERROR", - "expected_value": "a Open Researcher and Contributor ID valid", + "expected_value": "valid ORCID", "got_value": None, - "message": "Got None, expected a Open Researcher and Contributor ID valid", - "advice": "The author Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto has None as ORCID and its format is not valid. Provide a valid ORCID.", + "message": "Got None, expected valid ORCID", + "advice": "Provide a valid ORCID.", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_name": { @@ -761,7 +760,7 @@ def test_validate_authors_orcid_format_success(self): expected = [ { - "title": "Author ORCID", + "title": "ORCID format", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -836,7 +835,7 @@ def test_validate_authors_orcid_is_unique_ok(self): expected = [ { - "title": "Author ORCID element is unique", + "title": "Unique ORCID", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -902,7 +901,7 @@ def test_validate_authors_orcid_is_unique_not_ok(self): expected = [ { - "title": "Author ORCID element is unique", + "title": "Unique ORCID", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -967,14 +966,14 @@ def test_validate_authors_orcid_is_registered_success(self): expected = [ { - "title": "Author ORCID element is registered", + "title": "Registered ORCID", "parent": "article", "parent_id": None, "parent_article_type": "research-article", "parent_lang": "pt", "item": "contrib-id", "sub_item": '@contrib-id-type="orcid"', - "validation_type": "exist", + "validation_type": "registered", "response": "OK", "expected_value": ["0990-0001-0058-4853", 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto'], "got_value": ["0990-0001-0058-4853", 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto'], @@ -1044,20 +1043,20 @@ def test_validate_authors_orcid_is_registered_fail(self): expected = [ { - "title": "Author ORCID element is registered", + "title": "Registered ORCID", "parent": "article", "parent_id": None, "parent_article_type": "research-article", "parent_lang": "pt", "item": "contrib-id", "sub_item": '@contrib-id-type="orcid"', - "validation_type": "exist", + "validation_type": "registered", "response": "ERROR", "expected_value": ["0990-0001-0058-4853", "Prof FRANCISCO VENEGAS MARTÍNEZ Nieto"], "got_value": ["0990-0001-0058-4853", "Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto"], "message": "Got ['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto'], expected " "['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto']", - "advice": "ORCID 0990-0001-0058-4853 is not registered to any authors", + "advice": "Provide a valid ORCID for Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_ids": {"orcid": "0990-0001-0058-4853"}, @@ -1121,20 +1120,20 @@ def test_validate_authors_orcid_is_registered_fail_empty(self): expected = [ { - "title": "Author ORCID element is registered", + "title": "Registered ORCID", "parent": "article", "parent_id": None, "parent_article_type": "research-article", "parent_lang": "pt", "item": "contrib-id", "sub_item": '@contrib-id-type="orcid"', - "validation_type": "exist", + "validation_type": "registered", "response": "ERROR", "expected_value": ["0990-0001-0058-4853", None], "got_value": ["0990-0001-0058-4853", "Prof FRANCISCO VENEGAS MARTÍNEZ Nieto"], "message": "Got ['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto'], expected " "['0990-0001-0058-4853', None]", - "advice": "ORCID 0990-0001-0058-4853 is not registered to any authors", + "advice": "Provide a valid ORCID for Prof FRANCISCO VENEGAS MARTÍNEZ Nieto", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto', "contrib_ids": {"orcid": "0990-0001-0058-4853"}, @@ -1285,7 +1284,7 @@ def test_validate(self): expected = [ { - "title": "Author ORCID element is unique", + "title": "Unique ORCID", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -1307,7 +1306,7 @@ def test_validate(self): "data": None, }, { - "title": "CRediT taxonomy for contribs", + "title": "CRediT taxonomy", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -1322,7 +1321,7 @@ def test_validate(self): ], "got_value": None, "message": """Got None, expected ['Conceptualization', 'Data curation']""", - "advice": """The author Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto does not have a valid role. Provide a role from the list: ['Conceptualization', 'Data curation']""", + "advice": """Provide the correct CRediT taxonomy: ['Conceptualization', 'Data curation']""", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_ids": {"orcid": "0990-0001-0058-4853"}, @@ -1341,7 +1340,7 @@ def test_validate(self): }, }, { - "title": "Author ORCID", + "title": "ORCID format", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -1372,20 +1371,20 @@ def test_validate(self): }, }, { - "title": "Author ORCID element is registered", + "title": "Registered ORCID", "parent": "article", "parent_id": None, "parent_article_type": "research-article", "parent_lang": "pt", "item": "contrib-id", "sub_item": '@contrib-id-type="orcid"', - "validation_type": "exist", + "validation_type": "registered", "response": "ERROR", "expected_value": ["0990-0001-0058-4853", "Prof FRANCISCO VENEGAS MARTÍNEZ Nieto"], "got_value": ["0990-0001-0058-4853", "Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto"], "message": "Got ['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto'], expected " "['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto']", - "advice": 'ORCID 0990-0001-0058-4853 is not registered to any authors', + "advice": 'Provide a valid ORCID for Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_ids": {"orcid": "0990-0001-0058-4853"}, @@ -1413,10 +1412,10 @@ def test_validate(self): 'sub_item': 'aff', 'validation_type': 'exist', 'response': 'ERROR', - 'expected_value': 'author affiliation data', + 'expected_value': 'affiliation', 'got_value': None, - 'message': 'Got None, expected author affiliation data', - 'advice': 'provide author affiliation data for Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', + 'message': 'Got None, expected affiliation', + 'advice': 'provide affiliation for Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', 'data': { 'contrib_name': { 'given-names': 'FRANCISCO', @@ -1435,7 +1434,7 @@ def test_validate(self): } }, { - "title": "CRediT taxonomy for contribs", + "title": "CRediT taxonomy", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -1450,7 +1449,7 @@ def test_validate(self): ], "got_value": None, "message": """Got None, expected ['Conceptualization', 'Data curation']""", - "advice": """The author Vanessa M. Higa does not have a valid role. Provide a role from the list: ['Conceptualization', 'Data curation']""", + "advice": """Provide the correct CRediT taxonomy: ['Conceptualization', 'Data curation']""", "data": { 'contrib_full_name': 'Vanessa M. Higa', "contrib_ids": {"orcid": "0000-3333-1238-6873"}, @@ -1464,7 +1463,7 @@ def test_validate(self): }, }, { - "title": "Author ORCID", + "title": "ORCID format", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -1542,7 +1541,7 @@ def test_validate_unique_orcid_for_authors_with_same_name(self): expected = [ { - "title": "Author ORCID element is unique", + "title": "Unique ORCID", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -1615,7 +1614,7 @@ def test_validate_unique_orcid_for_authors_with_different_names(self): expected = [ { - "title": "Author ORCID element is unique", + "title": "Unique ORCID", "parent": "article", "parent_id": None, "parent_article_type": "research-article", @@ -1740,10 +1739,10 @@ def test_validate_authors_affiliations_fail(self): 'sub_item': 'aff', 'validation_type': 'exist', 'response': 'ERROR', - 'expected_value': 'author affiliation data', + 'expected_value': 'affiliation', 'got_value': None, - 'message': 'Got None, expected author affiliation data', - 'advice': 'provide author affiliation data for FRANCISCO VENEGAS-MARTÍNEZ', + 'message': 'Got None, expected affiliation', + 'advice': 'provide affiliation for FRANCISCO VENEGAS-MARTÍNEZ', 'data': { 'contrib_full_name': 'FRANCISCO VENEGAS-MARTÍNEZ', 'contrib_name': { From 2feee5bfaa6ef902f822ae079d708153ef374565 Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Wed, 30 Oct 2024 10:10:49 -0300 Subject: [PATCH 4/9] =?UTF-8?q?Modifica=20ContribValidation.validate=5Forc?= =?UTF-8?q?id=5Fis=5Fregistered=20para=20considerar=20que=20a=20fun=C3=A7?= =?UTF-8?q?=C3=A3o=20que=20valida=20orcid,=20recebe=20orcid=20e=20um=20dic?= =?UTF-8?q?ion=C3=A1rio=20com=20dados=20de=20contrib=20e=20retorna=20um=20?= =?UTF-8?q?dicion=C3=A1rio=20com=20os=20dados=20retornados=20pela=20'API'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/article_contribs.py | 35 ++++++--- tests/sps/validation/test_article_contribs.py | 77 +++++++++++-------- 2 files changed, 71 insertions(+), 41 deletions(-) diff --git a/packtools/sps/validation/article_contribs.py b/packtools/sps/validation/article_contribs.py index 57d48f3a0..8d98ddeed 100644 --- a/packtools/sps/validation/article_contribs.py +++ b/packtools/sps/validation/article_contribs.py @@ -166,6 +166,10 @@ def validate_orcid_format(self, error_level="ERROR"): },... ] """ + if not self.contrib_name: + # não há contrib_name, logo não há orcid + return + _default_orcid = ( r"^[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}$" ) @@ -188,7 +192,7 @@ def validate_orcid_format(self, error_level="ERROR"): is_valid=is_valid, expected=expected_value, obtained=_orcid, - advice=f"Provide a valid ORCID.", + advice=None if is_valid else f"Provide a valid ORCID for {self.contrib_name}", data=self.contrib, error_level=error_level ) @@ -252,12 +256,21 @@ def validate_orcid_is_registered(self, callable_get_validate=None, error_level=" ... ] """ + if not self.contrib_name: + # não há contrib_name, logo não há orcid + return + + orcid = self.contrib.get("contrib_ids", {}).get("orcid") + if not orcid: + return + callable_get_validate = ( callable_get_validate or _callable_extern_validate_default ) - orcid = self.contrib.get("contrib_ids", {}).get("orcid") - expected_contrib_name = callable_get_validate(orcid) - is_valid = self.contrib_name == expected_contrib_name + if not callable_get_validate: + return + + result = callable_get_validate(orcid, self.contrib) yield format_response( title="Registered ORCID", @@ -268,10 +281,10 @@ def validate_orcid_is_registered(self, callable_get_validate=None, error_level=" item="contrib-id", sub_item='@contrib-id-type="orcid"', validation_type="registered", - is_valid=is_valid, - expected=[orcid, expected_contrib_name], - obtained=[orcid, self.contrib_name], - advice=f"Provide a valid ORCID for {self.contrib_name}", + is_valid=result['is_valid'], + expected=self.contrib_name, + obtained=result["data"], + advice=None if result['is_valid'] else f"Identify the correct ORCID for {self.contrib_name}", data=self.contrib, error_level=error_level ) @@ -391,10 +404,10 @@ def validate_affiliations(self, error_level="ERROR"): 'parent_id': None, 'validation_type': 'exist', 'response': 'ERROR', - 'expected_value': 'author affiliation data', + 'expected_value': 'affiliation', 'got_value': None, - 'message': 'Got None, expected author affiliation data', - 'advice': 'provide author affiliation data for FRANCISCO VENEGAS-MARTÍNEZ', + 'message': 'Got None, expected affiliation', + 'advice': 'provide affiliation for FRANCISCO VENEGAS-MARTÍNEZ', 'data': { 'aff_rids': ['aff1'], 'contrib-type': 'author', diff --git a/tests/sps/validation/test_article_contribs.py b/tests/sps/validation/test_article_contribs.py index fc1d0c574..707081209 100644 --- a/tests/sps/validation/test_article_contribs.py +++ b/tests/sps/validation/test_article_contribs.py @@ -17,19 +17,40 @@ ] -def callable_get_data(orcid): +def callable_get_unmatched_data(orcid, contrib): tests = { - "0990-0001-0058-4853": "Prof FRANCISCO VENEGAS MARTÍNEZ Nieto", - "0000-3333-1238-6873": "Vanessa M. Higa", + "0990-0001-0058-4853": { + "data": "Autor registrado com orcid = 0990-0001-0058-4853", + "is_valid": False, + }, + + "0000-3333-1238-6873": { + "data": "Vanessa M. Higa", + "is_valid": True, + }, } return tests.get(orcid) -def callable_get_data_empty(orcid): - tests = {"0990-0001-0058-4853": None, "0000-3333-1238-6873": None} +def callable_get_matched_data(orcid, contrib): + tests = { + "0990-0001-0058-4853": { + "data": "FRANCISCO VENEGAS MARTÍNEZ Nieto", + "is_valid": True, + }, + + "0000-3333-1238-6873": { + "data": "Vanessa M. Higa", + "is_valid": True, + }, + } return tests.get(orcid) +def callable_get_not_found_data(orcid, contrib): + return {"data": None, "is_valid": False} + + class ArticleContribsValidationTest(TestCase): def test_without_role(self): self.maxDiff = None @@ -628,7 +649,7 @@ def test_validate_authors_orcid_format_fail(self): "expected_value": "valid ORCID", "got_value": "0990-01-58-4853", "message": "Got 0990-01-58-4853, expected valid ORCID", - "advice": "Provide a valid ORCID.", + "advice": "Provide a valid ORCID for Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_ids": {"orcid": "0990-01-58-4853"}, @@ -698,7 +719,7 @@ def test_validate_authors_orcid_format_without_orcid(self): "expected_value": "valid ORCID", "got_value": None, "message": "Got None, expected valid ORCID", - "advice": "Provide a valid ORCID.", + "advice": "Provide a valid ORCID for Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_name": { @@ -961,7 +982,7 @@ def test_validate_authors_orcid_is_registered_success(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_orcid_is_registered(callable_get_data) + ContribValidation(contrib).validate_orcid_is_registered(callable_get_matched_data) ) expected = [ @@ -975,10 +996,9 @@ def test_validate_authors_orcid_is_registered_success(self): "sub_item": '@contrib-id-type="orcid"', "validation_type": "registered", "response": "OK", - "expected_value": ["0990-0001-0058-4853", 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto'], - "got_value": ["0990-0001-0058-4853", 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto'], - "message": "Got ['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto'], expected " - "['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto']", + "expected_value": 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto', + "got_value": 'FRANCISCO VENEGAS MARTÍNEZ Nieto', + "message": "Got FRANCISCO VENEGAS MARTÍNEZ Nieto, expected Prof FRANCISCO VENEGAS MARTÍNEZ Nieto", "advice": None, "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto', @@ -1038,7 +1058,7 @@ def test_validate_authors_orcid_is_registered_fail(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_orcid_is_registered(callable_get_data) + ContribValidation(contrib).validate_orcid_is_registered(callable_get_not_found_data) ) expected = [ @@ -1052,11 +1072,10 @@ def test_validate_authors_orcid_is_registered_fail(self): "sub_item": '@contrib-id-type="orcid"', "validation_type": "registered", "response": "ERROR", - "expected_value": ["0990-0001-0058-4853", "Prof FRANCISCO VENEGAS MARTÍNEZ Nieto"], - "got_value": ["0990-0001-0058-4853", "Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto"], - "message": "Got ['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto'], expected " - "['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto']", - "advice": "Provide a valid ORCID for Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto", + "expected_value": "Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto", + "got_value": None, + "message": "Got None, expected Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto", + "advice": "Identify the correct ORCID for Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_ids": {"orcid": "0990-0001-0058-4853"}, @@ -1115,7 +1134,7 @@ def test_validate_authors_orcid_is_registered_fail_empty(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_orcid_is_registered(callable_get_data_empty) + ContribValidation(contrib).validate_orcid_is_registered(callable_get_not_found_data) ) expected = [ @@ -1129,11 +1148,10 @@ def test_validate_authors_orcid_is_registered_fail_empty(self): "sub_item": '@contrib-id-type="orcid"', "validation_type": "registered", "response": "ERROR", - "expected_value": ["0990-0001-0058-4853", None], - "got_value": ["0990-0001-0058-4853", "Prof FRANCISCO VENEGAS MARTÍNEZ Nieto"], - "message": "Got ['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto'], expected " - "['0990-0001-0058-4853', None]", - "advice": "Provide a valid ORCID for Prof FRANCISCO VENEGAS MARTÍNEZ Nieto", + "expected_value": "Prof FRANCISCO VENEGAS MARTÍNEZ Nieto", + "got_value": None, + "message": "Got None, expected Prof FRANCISCO VENEGAS MARTÍNEZ Nieto", + "advice": "Identify the correct ORCID for Prof FRANCISCO VENEGAS MARTÍNEZ Nieto", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto', "contrib_ids": {"orcid": "0990-0001-0058-4853"}, @@ -1278,7 +1296,7 @@ def test_validate(self): xmltree = etree.fromstring(xml) data = { "credit_taxonomy_terms_and_urls": credit_taxonomy_terms_and_urls, - "callable_get_data": callable_get_data, + "callable_get_data": callable_get_unmatched_data, } obtained = list(ArticleContribsValidation(xmltree=xmltree, data=data).validate()) @@ -1380,11 +1398,10 @@ def test_validate(self): "sub_item": '@contrib-id-type="orcid"', "validation_type": "registered", "response": "ERROR", - "expected_value": ["0990-0001-0058-4853", "Prof FRANCISCO VENEGAS MARTÍNEZ Nieto"], - "got_value": ["0990-0001-0058-4853", "Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto"], - "message": "Got ['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto'], expected " - "['0990-0001-0058-4853', 'Prof FRANCISCO VENEGAS MARTÍNEZ Nieto']", - "advice": 'Provide a valid ORCID for Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', + "expected_value": "Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto", + "got_value": "Autor registrado com orcid = 0990-0001-0058-4853", + "message": "Got Autor registrado com orcid = 0990-0001-0058-4853, expected Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto", + "advice": "Identify the correct ORCID for Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto", "data": { 'contrib_full_name': 'Prof FRANCISCO VENEGAS-MARTÍNEZ Nieto', "contrib_ids": {"orcid": "0990-0001-0058-4853"}, From fdc07976534a651998ad965913a7794dc96d33d7 Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Wed, 30 Oct 2024 19:42:27 -0300 Subject: [PATCH 5/9] =?UTF-8?q?Cria=20as=20fun=C3=A7=C3=B5es=20get=5Fparen?= =?UTF-8?q?ts=20e=20get=5Fparent=5Fdata=20para=20lidar=20com=20os=20n?= =?UTF-8?q?=C3=B3s=20article=20e=20sub-article?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/utils/xml_utils.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packtools/sps/utils/xml_utils.py b/packtools/sps/utils/xml_utils.py index 78526fd9d..479d6cbb1 100644 --- a/packtools/sps/utils/xml_utils.py +++ b/packtools/sps/utils/xml_utils.py @@ -473,3 +473,22 @@ def put_parent_context(data, lang, article_type, parent, parent_id): } ) return data + + +def get_parent_data(node): + return { + "parent": node.tag, + "parent_id": node.get("id"), + "parent_lang": node.get("{http://www.w3.org/XML/1998/namespace}lang"), + "parent_article_type": node.get("article-type"), + "xpath": "sub-article" if node.tag == "sub-article" else "front | body | back" + } + + +def get_parents(xmltree): + main = xmltree.xpath(".")[0] + yield get_parent_data(main) + for node in xmltree.xpath("./sub-article"): + yield get_parent_data(node) + for sub_node in node.xpath("./sub-article"): + yield get_parent_data(sub_node) From c58067f46941cf00517496dac63c579d57ca4693 Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Wed, 30 Oct 2024 19:43:57 -0300 Subject: [PATCH 6/9] =?UTF-8?q?Cria=20CollabListValidation=20para=20fazer?= =?UTF-8?q?=20a=20valida=C3=A7=C3=A3o=20dos=20pares=20de=20contrib-group?= =?UTF-8?q?=20que=20representam=20uma=20lista=20de=20autores=20pessoas=20a?= =?UTF-8?q?ssociadas=20a=20um=20autor=20institucional?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/article_contribs.py | 254 ++++++++++++------ tests/sps/validation/test_article_contribs.py | 72 ++--- 2 files changed, 203 insertions(+), 123 deletions(-) diff --git a/packtools/sps/validation/article_contribs.py b/packtools/sps/validation/article_contribs.py index 8d98ddeed..a5fc12963 100644 --- a/packtools/sps/validation/article_contribs.py +++ b/packtools/sps/validation/article_contribs.py @@ -1,7 +1,8 @@ import re -from packtools.sps.models.article_contribs import ArticleContribs -from packtools.sps.validation.utils import format_response +from packtools.sps.models.article_contribs import ArticleContribs, ContribGroup +from packtools.sps.validation.utils import format_response, build_response +from packtools.sps.utils.xml_utils import get_parent_data, get_parents def _callable_extern_validate_default(orcid): @@ -28,7 +29,8 @@ def _response(contrib, is_valid, expected, obtained, author, error_level="ERROR" class ContribValidation: - def __init__(self, contrib): + def __init__(self, contrib, data): + self.data = data self.contrib = contrib self.contrib_name = self.contrib.get("contrib_full_name") @@ -289,78 +291,6 @@ def validate_orcid_is_registered(self, callable_get_validate=None, error_level=" error_level=error_level ) - def validate_collab_list(self, content_types, error_level="ERROR"): - """ - Checks if there is identification of authors for a group of collaborators. - - XML input - --------- -
- - - - - The MARS Group - - - - - 0000-0001-0002-0003 - - Wright - Rick W. - - - - - -
- - - Returns - ------- - list of dict - A list of dictionaries, such as: - [ - { - 'title': 'Collab list authors identification', - 'parent': None, - 'parent_id': None, - 'item': 'contrib-group', - 'sub_item': '@content-type', - 'validation_type': 'exist', - 'response': 'ERROR', - 'expected_value': 'contrib group with identification of members of The MARS Group', - 'got_value': None, - 'message': 'Got None, expected contrib group with identification of members of The MARS Group', - 'advice': 'provide the identification of members of The MARS Group', - 'data': { - 'aff_rids': None, - 'collab': 'The MARS Group', - 'contrib-type': 'author' - } - }... - ] - """ - collab = self.contrib.get('collab') - if collab and 'collab-list' not in content_types: - yield format_response( - title='Collab list authors identification', - parent=self.contrib.get("parent"), - parent_id=self.contrib.get("parent_id"), - parent_article_type=self.contrib.get("parent_article_type"), - parent_lang=self.contrib.get("parent_lang"), - item='contrib-group', - sub_item='@content-type', - validation_type='exist', - is_valid=False, - expected=f'contrib group with identification of members of {collab}', - obtained=None, - advice=f'provide the identification of members of {collab}', - data=self.contrib, - error_level=error_level - ) - def validate_affiliations(self, error_level="ERROR"): """ Checks if an author has the corresponding affiliation data. @@ -440,21 +370,62 @@ def validate_affiliations(self, error_level="ERROR"): error_level=error_level ) + def validate_name(self, error_level="ERROR"): + item = self.contrib.get("contrib_name") + if not item: + yield build_response( + title='name', + parent=self.contrib, + item='contrib', + sub_item='name', + validation_type='exist', + is_valid=False, + expected='name', + obtained=None, + advice=f'provide name', + data=self.contrib, + error_level=error_level + ) -class ContribsValidation: - def __init__(self, contrib, data, content_types): - self.contrib = contrib - self.data = data - self.content_types = content_types + def validate_collab(self, error_level="ERROR"): + item = self.contrib.get("collab") + if not item: + yield build_response( + title='collab', + parent=self.contrib, + item='contrib', + sub_item='collab', + validation_type='exist', + is_valid=False, + expected='collab', + obtained=None, + advice=f'provide collab', + data=self.contrib, + error_level=error_level + ) - def validate(self): - contrib = ContribValidation(self.contrib) + def validate_name_or_collab(self, error_level="ERROR"): + item = self.contrib.get("collab") or self.contrib.get("name") + if not item: + yield build_response( + title='name or collab', + parent=self.contrib, + item='contrib', + sub_item='name or collab', + validation_type='exist', + is_valid=False, + expected='name or collab', + obtained=None, + advice=f'provide name or collab', + data=self.contrib, + error_level=error_level + ) - yield from contrib.validate_role(self.data["credit_taxonomy_terms_and_urls"]) - yield from contrib.validate_orcid_format() - yield from contrib.validate_orcid_is_registered(self.data["callable_get_data"]) - yield from contrib.validate_collab_list(self.content_types) - yield from contrib.validate_affiliations() + def validate(self): + yield from self.validate_role(self.data["credit_taxonomy_terms_and_urls"]) + yield from self.validate_orcid_format() + yield from self.validate_orcid_is_registered(self.data["callable_get_data"]) + yield from self.validate_affiliations() class ArticleContribsValidation: @@ -562,8 +533,115 @@ def validate_orcid_is_unique(self, error_level="ERROR"): def validate(self): # A validação da unicidade do ORCID é feita uma única vez por artigo yield from self.validate_orcid_is_unique() + for contrib in self.contribs.contribs: - yield from ContribsValidation(contrib, self.data, self.content_types).validate() + yield from ContribValidation(contrib, self.data).validate() + + validator = CollabListValidation(self.xmltree.find("."), self.data) + yield from validator.validate() + for item in self.xmltree.xpath("sub-article"): + validator = CollabListValidation(item, self.data) + yield from validator.validate() + + +class CollabListValidation: + def __init__(self, parent_node, args): + # parent_node (article ou sub-article) + self.args = args + self.parent_node = parent_node + self.parent_data = get_parent_data(parent_node) + + @property + def data(self): + items = [] + for content_type, group in self.contrib_groups.items(): + for item in group.contribs: + items.append(item) + return items + + @property + def contrib_groups(self): + """ + + + The MARS Group + 1 + + + + + 0000-0001-0002-0003 + + Wright + Rick W. + + 1 + + + + + { + None: ContribGroup, + "collab-list": ContribGroup, + } + """ + if not hasattr(self, '_contrib_groups') or not self._contrib_groups: + data = get_parent_data(self.parent_node) + self._contrib_groups = {} + for node in self.parent_node.xpath(data["xpath"]): + for contrib_group in node.xpath(".//contrib-group"): + self._contrib_groups[contrib_group.get("content-type")] = ContribGroup(contrib_group) + return self._contrib_groups + def validate(self): + if self.parent_node.xpath(".//contrib//collab"): + yield from self.validate_contrib_group__collab() + yield from self.validate_contrib_group__name() + + def validate_contrib_group__collab(self): + try: + contrib_group = self.contrib_groups[None] + except KeyError: + yield build_response( + title="contrib-group/contrib/collab", + parent=self.parent_data, + item="contrib-group", + sub_item='', + validation_type="match", + is_valid=False, + expected="contrib-group", + obtained=None, + advice="Add contrib-group which has contrib/name", + data=self.data, + error_level=self.args["content_type_error_level"] + ) + else: + for contrib in contrib_group.contribs: + contrib.update(self.parent_data) + validator = ContribValidation(contrib, self.args) + yield from validator.validate_collab(self.args["contrib_collab_error_level"]) + + def validate_contrib_group__name(self): + try: + contrib_group = self.contrib_groups["collab-list"] + except KeyError: + yield build_response( + title="contrib-group/contrib/name", + parent=self.parent_data, + item="contrib-group", + sub_item='collab-list', + validation_type="match", + is_valid=False, + expected="contrib-group[@content-type='collab-list']", + obtained=None, + advice="Add content-type='collab-list' to contrib-group must have contrib/name", + data=self.data, + error_level=self.args["content_type_error_level"] + ) + else: + for contrib in contrib_group.contribs: + contrib.update(self.parent_data) + validator = ContribValidation(contrib, self.args) + yield from validator.validate_name(self.args["contrib_name_error_level"]) diff --git a/tests/sps/validation/test_article_contribs.py b/tests/sps/validation/test_article_contribs.py index 707081209..4c3571335 100644 --- a/tests/sps/validation/test_article_contribs.py +++ b/tests/sps/validation/test_article_contribs.py @@ -3,7 +3,7 @@ from lxml import etree from packtools.sps.models.article_contribs import ArticleContribs -from packtools.sps.validation.article_contribs import ContribValidation, ArticleContribsValidation +from packtools.sps.validation.article_contribs import ContribValidation, ArticleContribsValidation, CollabListValidation credit_taxonomy_terms_and_urls = [ { @@ -86,7 +86,7 @@ def test_without_role(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_role( + ContribValidation(contrib, data={}).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -167,7 +167,7 @@ def test_role_and_content_type_empty(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_role( + ContribValidation(contrib, data={}).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -300,7 +300,7 @@ def test_role_without_content_type(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_role( + ContribValidation(contrib, data={}).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -397,7 +397,7 @@ def test_role_no_text_with_content_type(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_role( + ContribValidation(contrib, data={}).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -494,7 +494,7 @@ def test_wrong_role_and_content_type(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_role( + ContribValidation(contrib, data={}).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -588,7 +588,7 @@ def test_success_role(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_role( + ContribValidation(contrib, data={}).validate_role( credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, ) ) @@ -633,7 +633,7 @@ def test_validate_authors_orcid_format_fail(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_orcid_format()) + ContribValidation(contrib, data={}).validate_orcid_format()) expected = [ { @@ -703,7 +703,7 @@ def test_validate_authors_orcid_format_without_orcid(self): """ xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] - obtained = list(ContribValidation(contrib).validate_orcid_format()) + obtained = list(ContribValidation(contrib, data={}).validate_orcid_format()) expected = [ { @@ -777,7 +777,7 @@ def test_validate_authors_orcid_format_success(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_orcid_format()) + ContribValidation(contrib, data={}).validate_orcid_format()) expected = [ { @@ -982,7 +982,7 @@ def test_validate_authors_orcid_is_registered_success(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_orcid_is_registered(callable_get_matched_data) + ContribValidation(contrib, data={}).validate_orcid_is_registered(callable_get_matched_data) ) expected = [ @@ -1058,7 +1058,7 @@ def test_validate_authors_orcid_is_registered_fail(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_orcid_is_registered(callable_get_not_found_data) + ContribValidation(contrib, data={}).validate_orcid_is_registered(callable_get_not_found_data) ) expected = [ @@ -1134,7 +1134,7 @@ def test_validate_authors_orcid_is_registered_fail_empty(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib).validate_orcid_is_registered(callable_get_not_found_data) + ContribValidation(contrib, data={}).validate_orcid_is_registered(callable_get_not_found_data) ) expected = [ @@ -1203,10 +1203,13 @@ def test_validate_authors_with_collab_list(self): """ ) - contrib = list(ArticleContribs(xml_tree).contribs)[0] - content_types = ArticleContribsValidation(xmltree=xml_tree, data={}).content_types - obtained = list(ContribValidation(contrib).validate_collab_list(content_types)) - + data = { + "contrib_name_error_level": "ERROR", + "contrib_collab_error_level": "ERROR", + "content_type_error_level": "ERROR", + } + validator = CollabListValidation(parent_node=xml_tree.find("."), args=data) + obtained = list(validator.validate()) self.assertEqual([], obtained) def test_validate_authors_without_collab_list(self): @@ -1227,34 +1230,33 @@ def test_validate_authors_without_collab_list(self): """ ) - - contrib = list(ArticleContribs(xml_tree).contribs)[0] - content_types = ArticleContribsValidation(xmltree=xml_tree, data={}).content_types - obtained = list(ContribValidation(contrib).validate_collab_list(content_types)) + data = { + "contrib_name_error_level": "ERROR", + "contrib_collab_error_level": "ERROR", + "content_type_error_level": "ERROR", + } + validator = CollabListValidation(parent_node=xml_tree.find("."), args=data) + obtained = list(validator.validate()) expected = [ { - 'title': 'Collab list authors identification', + 'title': 'contrib-group/contrib/name', "parent": "article", "parent_id": None, "parent_article_type": "research-article", "parent_lang": "pt", 'item': 'contrib-group', - 'sub_item': '@content-type', - 'validation_type': 'exist', + 'sub_item': 'collab-list', + 'validation_type': 'match', 'response': 'ERROR', - 'expected_value': 'contrib group with identification of members of The MARS Group', + 'expected_value': "contrib-group[@content-type='collab-list']", 'got_value': None, - 'message': 'Got None, expected contrib group with identification of members of The MARS Group', - 'advice': 'provide the identification of members of The MARS Group', - 'data': { + 'message': "Got None, expected contrib-group[@content-type='collab-list']", + 'advice': "Add content-type='collab-list' to contrib-group must have contrib/name", + 'data': [{ 'collab': 'The MARS Group', 'contrib_type': 'author', - "parent": "article", - "parent_id": None, - "parent_article_type": "research-article", - "parent_lang": "pt", - } + }] } ] for i, item in enumerate(expected): @@ -1711,7 +1713,7 @@ def test_validate_authors_affiliations_success(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] - obtained = list(ContribValidation(contrib).validate_affiliations()) + obtained = list(ContribValidation(contrib, data={}).validate_affiliations()) self.assertListEqual(obtained, []) def test_validate_authors_affiliations_fail(self): @@ -1744,7 +1746,7 @@ def test_validate_authors_affiliations_fail(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] - obtained = list(ContribValidation(contrib).validate_affiliations()) + obtained = list(ContribValidation(contrib, data={}).validate_affiliations()) expected = [ { 'title': 'Author without affiliation', From cc59af322b21c41c11a343fb400005abf5f89405 Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Thu, 31 Oct 2024 12:02:20 -0300 Subject: [PATCH 7/9] =?UTF-8?q?Revisa=20os=20par=C3=A2metros=20dos=20m?= =?UTF-8?q?=C3=A9todos=20e=20os=20move=20para=20uma=20vari=C3=A1vel=20glob?= =?UTF-8?q?al=20da=20classe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/article_contribs.py | 55 ++++--- .../article_contribs_rules.json | 6 +- tests/sps/validation/test_article_contribs.py | 141 ++++++++++++------ 3 files changed, 130 insertions(+), 72 deletions(-) diff --git a/packtools/sps/validation/article_contribs.py b/packtools/sps/validation/article_contribs.py index a5fc12963..568371e65 100644 --- a/packtools/sps/validation/article_contribs.py +++ b/packtools/sps/validation/article_contribs.py @@ -34,7 +34,7 @@ def __init__(self, contrib, data): self.contrib = contrib self.contrib_name = self.contrib.get("contrib_full_name") - def validate_role(self, credit_taxonomy_terms_and_urls): + def validate_role(self): """ Checks contributor roles according to CRediT taxonomy. @@ -89,6 +89,8 @@ def validate_role(self, credit_taxonomy_terms_and_urls): },... ] """ + error_level = self.data["credit_taxonomy_terms_and_urls_error_level"] + credit_taxonomy_terms_and_urls = self.data["credit_taxonomy_terms_and_urls"] expected_value = [ f'{role["term"]}' for role in credit_taxonomy_terms_and_urls @@ -108,6 +110,7 @@ def validate_role(self, credit_taxonomy_terms_and_urls): expected=expected_value, obtained=role, author=self.contrib_name, + error_level=error_level ) else: yield _response( @@ -116,9 +119,10 @@ def validate_role(self, credit_taxonomy_terms_and_urls): expected=expected_value, obtained=None, author=self.contrib_name, + error_level=error_level ) - def validate_orcid_format(self, error_level="ERROR"): + def validate_orcid_format(self): """ Checks whether a contributor's ORCID is valid. @@ -168,6 +172,7 @@ def validate_orcid_format(self, error_level="ERROR"): },... ] """ + error_level = self.data["orcid_format_error_level"] if not self.contrib_name: # não há contrib_name, logo não há orcid return @@ -199,7 +204,7 @@ def validate_orcid_format(self, error_level="ERROR"): error_level=error_level ) - def validate_orcid_is_registered(self, callable_get_validate=None, error_level="ERROR"): + def validate_orcid_is_registered(self, is_orcid_registered): """ Checks whether a contributor's ORCID is registered. @@ -258,6 +263,7 @@ def validate_orcid_is_registered(self, callable_get_validate=None, error_level=" ... ] """ + error_level = self.data["orcid_is_registered_error_level"] if not self.contrib_name: # não há contrib_name, logo não há orcid return @@ -266,13 +272,13 @@ def validate_orcid_is_registered(self, callable_get_validate=None, error_level=" if not orcid: return - callable_get_validate = ( - callable_get_validate or _callable_extern_validate_default + is_orcid_registered = ( + is_orcid_registered or _callable_extern_validate_default ) - if not callable_get_validate: + if not is_orcid_registered: return - result = callable_get_validate(orcid, self.contrib) + result = is_orcid_registered(orcid, self.contrib) yield format_response( title="Registered ORCID", @@ -291,7 +297,7 @@ def validate_orcid_is_registered(self, callable_get_validate=None, error_level=" error_level=error_level ) - def validate_affiliations(self, error_level="ERROR"): + def validate_affiliations(self): """ Checks if an author has the corresponding affiliation data. @@ -351,6 +357,7 @@ def validate_affiliations(self, error_level="ERROR"): },... ] """ + error_level = self.data["affiliations_error_level"] affs = self.contrib.get("affs") if not affs: yield format_response( @@ -370,7 +377,8 @@ def validate_affiliations(self, error_level="ERROR"): error_level=error_level ) - def validate_name(self, error_level="ERROR"): + def validate_name(self): + error_level = self.data["name_error_level"] item = self.contrib.get("contrib_name") if not item: yield build_response( @@ -387,7 +395,8 @@ def validate_name(self, error_level="ERROR"): error_level=error_level ) - def validate_collab(self, error_level="ERROR"): + def validate_collab(self): + error_level = self.data["collab_error_level"] item = self.contrib.get("collab") if not item: yield build_response( @@ -404,7 +413,8 @@ def validate_collab(self, error_level="ERROR"): error_level=error_level ) - def validate_name_or_collab(self, error_level="ERROR"): + def validate_name_or_collab(self): + error_level = self.data["name_or_collab_error_level"] item = self.contrib.get("collab") or self.contrib.get("name") if not item: yield build_response( @@ -421,17 +431,19 @@ def validate_name_or_collab(self, error_level="ERROR"): error_level=error_level ) - def validate(self): - yield from self.validate_role(self.data["credit_taxonomy_terms_and_urls"]) + def validate(self, is_orcid_registered): + yield from self.validate_role() yield from self.validate_orcid_format() - yield from self.validate_orcid_is_registered(self.data["callable_get_data"]) + yield from self.validate_orcid_is_registered(is_orcid_registered) yield from self.validate_affiliations() + # yield from self.validate_name_or_collab() class ArticleContribsValidation: - def __init__(self, xmltree, data): + def __init__(self, xmltree, data, is_orcid_registered): self.xmltree = xmltree self.data = data + self.is_orcid_registered = is_orcid_registered self.contribs = ArticleContribs(self.xmltree) @property @@ -441,7 +453,7 @@ def content_types(self): for contrib_group in self.xmltree.xpath('.//contrib-group') ] - def validate_orcid_is_unique(self, error_level="ERROR"): + def validate_orcid_is_unique(self): """ Checks whether a contributor's ORCID is unique. @@ -491,6 +503,7 @@ def validate_orcid_is_unique(self, error_level="ERROR"): } ] """ + error_level = self.data["orcid_is_unique_error_level"] orcid_dict = {} for contrib in self.contribs.contribs: orcid = contrib.get("contrib_ids", {}).get("orcid") @@ -535,7 +548,7 @@ def validate(self): yield from self.validate_orcid_is_unique() for contrib in self.contribs.contribs: - yield from ContribValidation(contrib, self.data).validate() + yield from ContribValidation(contrib, self.data).validate(self.is_orcid_registered) validator = CollabListValidation(self.xmltree.find("."), self.data) yield from validator.validate() @@ -614,13 +627,13 @@ def validate_contrib_group__collab(self): obtained=None, advice="Add contrib-group which has contrib/name", data=self.data, - error_level=self.args["content_type_error_level"] + error_level=self.args["collab_list_error_level"] ) else: for contrib in contrib_group.contribs: contrib.update(self.parent_data) validator = ContribValidation(contrib, self.args) - yield from validator.validate_collab(self.args["contrib_collab_error_level"]) + yield from validator.validate_collab() def validate_contrib_group__name(self): try: @@ -637,11 +650,11 @@ def validate_contrib_group__name(self): obtained=None, advice="Add content-type='collab-list' to contrib-group must have contrib/name", data=self.data, - error_level=self.args["content_type_error_level"] + error_level=self.args["collab_list_error_level"] ) else: for contrib in contrib_group.contribs: contrib.update(self.parent_data) validator = ContribValidation(contrib, self.args) - yield from validator.validate_name(self.args["contrib_name_error_level"]) + yield from validator.validate_name() diff --git a/packtools/sps/validation_rules/article_contribs_rules.json b/packtools/sps/validation_rules/article_contribs_rules.json index db700459a..d3e81a341 100644 --- a/packtools/sps/validation_rules/article_contribs_rules.json +++ b/packtools/sps/validation_rules/article_contribs_rules.json @@ -1,15 +1,17 @@ { "article_contribs_rules": { - "role_error_level": "CRITICAL", + "credit_taxonomy_terms_and_urls_error_level": "CRITICAL", "orcid_format_error_level": "CRITICAL", "orcid_is_registered_error_level": "ERROR", "collab_list_error_level": "CRITICAL", + "name_error_level": "CRITICAL", + "collab_error_level": "CRITICAL", + "name_or_collab_error_level": "CRITICAL", "affiliations_error_level": "CRITICAL", "orcid_is_unique_error_level": "CRITICAL", "contrib_type_list": [ "author" ], - "orcid_api_get": null, "credit_taxonomy_terms_and_urls": [ { "term": "Conceptualization", diff --git a/tests/sps/validation/test_article_contribs.py b/tests/sps/validation/test_article_contribs.py index 4c3571335..abf85bcb4 100644 --- a/tests/sps/validation/test_article_contribs.py +++ b/tests/sps/validation/test_article_contribs.py @@ -82,13 +82,14 @@ def test_without_role(self): """ + data = {} + data["credit_taxonomy_terms_and_urls"] = credit_taxonomy_terms_and_urls + data["credit_taxonomy_terms_and_urls_error_level"] = "ERROR" xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib, data={}).validate_role( - credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, - ) + ContribValidation(contrib, data).validate_role() ) expected = [ @@ -131,7 +132,7 @@ def test_without_role(self): with self.subTest(i): self.assertDictEqual(obtained[i], item) - def test_role_and_content_type_empty(self): + def test_role_and_collab_list_empty(self): self.maxDiff = None xml = """
""" + data = {} + data["credit_taxonomy_terms_and_urls"] = credit_taxonomy_terms_and_urls + data["credit_taxonomy_terms_and_urls_error_level"] = "ERROR" xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] obtained = list( - ContribValidation(contrib, data={}).validate_role( - credit_taxonomy_terms_and_urls=credit_taxonomy_terms_and_urls, - ) + ContribValidation(contrib, data).validate_role() ) expected = [ @@ -218,7 +220,7 @@ def test_role_and_content_type_empty(self): with self.subTest(i): self.assertDictEqual(obtained[i], item) - def test_role_without_content_type(self): + def test_role_without_collab_list(self): self.maxDiff = None xml = """
""" - + data = {} + data["orcid_is_unique_error_level"] = "ERROR" xmltree = etree.fromstring(xml) obtained = list( - ArticleContribsValidation(xmltree, data={}).validate_orcid_is_unique() + ArticleContribsValidation(xmltree, data, callable_get_matched_data).validate_orcid_is_unique() ) expected = [ @@ -914,10 +929,11 @@ def test_validate_authors_orcid_is_unique_not_ok(self):
""" - + data = {} + data["orcid_is_unique_error_level"] = "ERROR" xmltree = etree.fromstring(xml) obtained = list( - ArticleContribsValidation(xmltree, data={}).validate_orcid_is_unique() + ArticleContribsValidation(xmltree, data, callable_get_matched_data).validate_orcid_is_unique() ) expected = [ @@ -981,8 +997,11 @@ def test_validate_authors_orcid_is_registered_success(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] + data = { + "orcid_is_registered_error_level": "ERROR" + } obtained = list( - ContribValidation(contrib, data={}).validate_orcid_is_registered(callable_get_matched_data) + ContribValidation(contrib, data).validate_orcid_is_registered(callable_get_matched_data) ) expected = [ @@ -1057,8 +1076,11 @@ def test_validate_authors_orcid_is_registered_fail(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] + data = { + "orcid_is_registered_error_level": "ERROR" + } obtained = list( - ContribValidation(contrib, data={}).validate_orcid_is_registered(callable_get_not_found_data) + ContribValidation(contrib, data).validate_orcid_is_registered(callable_get_not_found_data) ) expected = [ @@ -1133,8 +1155,11 @@ def test_validate_authors_orcid_is_registered_fail_empty(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] + data = { + "orcid_is_registered_error_level": "ERROR" + } obtained = list( - ContribValidation(contrib, data={}).validate_orcid_is_registered(callable_get_not_found_data) + ContribValidation(contrib, data).validate_orcid_is_registered(callable_get_not_found_data) ) expected = [ @@ -1204,9 +1229,9 @@ def test_validate_authors_with_collab_list(self): ) data = { - "contrib_name_error_level": "ERROR", - "contrib_collab_error_level": "ERROR", - "content_type_error_level": "ERROR", + "name_error_level": "ERROR", + "collab_error_level": "ERROR", + "collab_list_error_level": "ERROR", } validator = CollabListValidation(parent_node=xml_tree.find("."), args=data) obtained = list(validator.validate()) @@ -1231,9 +1256,9 @@ def test_validate_authors_without_collab_list(self): """ ) data = { - "contrib_name_error_level": "ERROR", - "contrib_collab_error_level": "ERROR", - "content_type_error_level": "ERROR", + "name_error_level": "ERROR", + "collab_error_level": "ERROR", + "collab_list_error_level": "ERROR", } validator = CollabListValidation(parent_node=xml_tree.find("."), args=data) obtained = list(validator.validate()) @@ -1297,10 +1322,18 @@ def test_validate(self): xmltree = etree.fromstring(xml) data = { - "credit_taxonomy_terms_and_urls": credit_taxonomy_terms_and_urls, - "callable_get_data": callable_get_unmatched_data, - } - obtained = list(ArticleContribsValidation(xmltree=xmltree, data=data).validate()) + "credit_taxonomy_terms_and_urls": credit_taxonomy_terms_and_urls, + "credit_taxonomy_terms_and_urls_error_level": "ERROR", + "orcid_format_error_level": "ERROR", + "orcid_is_registered_error_level": "ERROR", + "affiliations_error_level": "ERROR", + "name_error_level": "ERROR", + "collab_error_level": "ERROR", + "name_or_collab_error_level": "ERROR", + "orcid_is_unique_error_level": "ERROR", + "collab_list_error_level": "ERROR" + } + obtained = list(ArticleContribsValidation(xmltree=xmltree, data=data, is_orcid_registered=callable_get_unmatched_data).validate()) expected = [ { @@ -1552,10 +1585,12 @@ def test_validate_unique_orcid_for_authors_with_same_name(self): """ - + data = { + "orcid_is_unique_error_level": "ERROR", + } xmltree = etree.fromstring(xml) obtained = list( - ArticleContribsValidation(xmltree, data={}).validate_orcid_is_unique() + ArticleContribsValidation(xmltree, data, callable_get_matched_data).validate_orcid_is_unique() ) expected = [ @@ -1625,10 +1660,12 @@ def test_validate_unique_orcid_for_authors_with_different_names(self): """ - + data = { + "orcid_is_unique_error_level": "ERROR", + } xmltree = etree.fromstring(xml) obtained = list( - ArticleContribsValidation(xmltree, data={}).validate_orcid_is_unique() + ArticleContribsValidation(xmltree, data, callable_get_matched_data).validate_orcid_is_unique() ) expected = [ @@ -1713,7 +1750,10 @@ def test_validate_authors_affiliations_success(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] - obtained = list(ContribValidation(contrib, data={}).validate_affiliations()) + data = { + "affiliations_error_level": "ERROR" + } + obtained = list(ContribValidation(contrib, data).validate_affiliations()) self.assertListEqual(obtained, []) def test_validate_authors_affiliations_fail(self): @@ -1746,7 +1786,10 @@ def test_validate_authors_affiliations_fail(self): xmltree = etree.fromstring(xml) contrib = list(ArticleContribs(xmltree).contribs)[0] - obtained = list(ContribValidation(contrib, data={}).validate_affiliations()) + data = { + "affiliations_error_level": "ERROR" + } + obtained = list(ContribValidation(contrib, data).validate_affiliations()) expected = [ { 'title': 'Author without affiliation', From 2b80b7b2ac31fee2df64fb6d70c8776c06800f1d Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Thu, 31 Oct 2024 12:10:53 -0300 Subject: [PATCH 8/9] =?UTF-8?q?Adiciona=20a=20valida=C3=A7=C3=A3o=20de=20n?= =?UTF-8?q?ame=20ou=20collab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/article_contribs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packtools/sps/validation/article_contribs.py b/packtools/sps/validation/article_contribs.py index 568371e65..ddf22ef39 100644 --- a/packtools/sps/validation/article_contribs.py +++ b/packtools/sps/validation/article_contribs.py @@ -415,7 +415,7 @@ def validate_collab(self): def validate_name_or_collab(self): error_level = self.data["name_or_collab_error_level"] - item = self.contrib.get("collab") or self.contrib.get("name") + item = self.contrib.get("contrib_name") or self.contrib.get("collab") if not item: yield build_response( title='name or collab', @@ -436,7 +436,7 @@ def validate(self, is_orcid_registered): yield from self.validate_orcid_format() yield from self.validate_orcid_is_registered(is_orcid_registered) yield from self.validate_affiliations() - # yield from self.validate_name_or_collab() + yield from self.validate_name_or_collab() class ArticleContribsValidation: From e3ba19e1fca55c1dbf28c9557833ce85cb193988 Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Thu, 31 Oct 2024 15:18:18 -0300 Subject: [PATCH 9/9] =?UTF-8?q?Atualiza=20a=20chamada=20para=20valida?= =?UTF-8?q?=C3=A7=C3=A3o=20de=20contribs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/xml_validations.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packtools/sps/validation/xml_validations.py b/packtools/sps/validation/xml_validations.py index 1507ef3f9..28ce05a11 100644 --- a/packtools/sps/validation/xml_validations.py +++ b/packtools/sps/validation/xml_validations.py @@ -214,17 +214,9 @@ def validate_references(xmltree, params): def validate_article_contribs(xmltree, params): - # FIXME - def f(arg): - ... - + is_orcid_registered = params.get("is_orcid_registered") article_contribs_rules = params["article_contribs_rules"] - - params_ = {} - params_["callable_get_data"] = article_contribs_rules["orcid_api_get"] or f - params_.update(article_contribs_rules) - - validator = ArticleContribsValidation(xmltree, params_) + validator = ArticleContribsValidation(xmltree, article_contribs_rules, is_orcid_registered) yield from validator.validate()