From 71628cf811da38b2cc0db831b32cfdc982ea8549 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Thu, 12 Sep 2024 14:33:16 -0300 Subject: [PATCH 01/36] =?UTF-8?q?Adapta=20a=20classe=20de=20valida=C3=A7?= =?UTF-8?q?=C3=A3o=20ao=20novo=20modelo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/related_articles.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index ab5ea804a..d92b42200 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -1,16 +1,14 @@ -from packtools.sps.models import ( - related_articles, - article_and_subarticles -) +from packtools.sps.models.v2.related_articles import RelatedArticles +from packtools.sps.models import article_and_subarticles from packtools.sps.validation.exceptions import ValidationRelatedArticleException from packtools.sps.validation.utils import format_response class RelatedArticlesValidation: - def __init__(self, xmltree): - self.related_articles = [related for related in related_articles.RelatedItems(xmltree).related_articles] - self.article_type = article_and_subarticles.ArticleAndSubArticles(xmltree).main_article_type + def __init__(self, xml_tree): + self.related_articles = list(RelatedArticles(xml_tree).related_articles()) + self.article_type = article_and_subarticles.ArticleAndSubArticles(xml_tree).main_article_type def related_articles_matches_article_type_validation(self, correspondence_list=None, error_level="ERROR"): """ From 8cd2d4e9dfc7b22c66546dae45e306906227ebf7 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Thu, 12 Sep 2024 14:33:35 -0300 Subject: [PATCH 02/36] Adapta os testes --- tests/sps/validation/test_related_articles.py | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/tests/sps/validation/test_related_articles.py b/tests/sps/validation/test_related_articles.py index c14613390..30b0b63d7 100644 --- a/tests/sps/validation/test_related_articles.py +++ b/tests/sps/validation/test_related_articles.py @@ -13,9 +13,11 @@ def test_related_articles_matches_article_type_validation_match(self): """
+ +
""" @@ -56,11 +58,12 @@ def test_related_articles_matches_article_type_validation_match(self): 'ext-link-type': 'doi', 'href': '10.1590/1808-057x202090350', 'id': 'ra1', - 'related-article-type': 'corrected-article' + 'related-article-type': 'corrected-article', + 'text': '' } } ] - + self.assertEqual(len(obtained), 1) for i, item in enumerate(expected): with self.subTest(i): self.assertDictEqual(obtained[i], item) @@ -69,11 +72,13 @@ def test_related_articles_matches_article_type_validation_not_match(self): self.maxDiff = None xmltree = etree.fromstring( """ -
+ +
""" @@ -115,11 +120,13 @@ def test_related_articles_matches_article_type_validation_not_match(self): 'ext-link-type': 'doi', 'href': '10.1590/1808-057x202090350', 'id': 'ra1', - 'related-article-type': 'retraction-forward' + 'related-article-type': 'retraction-forward', + 'text': '' } } ] + self.assertEqual(len(obtained), 1) for i, item in enumerate(expected): with self.subTest(i): self.assertDictEqual(obtained[i], item) @@ -128,11 +135,13 @@ def test_related_articles_has_doi(self): self.maxDiff = None xmltree = etree.fromstring( """ -
+ +
""" @@ -162,11 +171,13 @@ def test_related_articles_has_doi(self): 'ext-link-type': 'doi', 'href': '10.1590/1808-057x202090350', 'id': 'ra1', - 'related-article-type': 'corrected-article' + 'related-article-type': 'corrected-article', + 'text': '' } } ] + self.assertEqual(len(obtained), 1) for i, item in enumerate(expected): with self.subTest(i): self.assertDictEqual(obtained[i], item) @@ -175,11 +186,13 @@ def test_related_articles_does_not_have_doi(self): self.maxDiff = None xmltree = etree.fromstring( """ -
+ +
""" @@ -209,11 +222,14 @@ def test_related_articles_does_not_have_doi(self): 'parent_lang': 'en', 'ext-link-type': 'doi', 'id': 'ra1', - 'related-article-type': 'corrected-article' + 'related-article-type': 'corrected-article', + 'text': '', + 'href': None } } ] + self.assertEqual(len(obtained), 1) for i, item in enumerate(expected): with self.subTest(i): self.assertDictEqual(obtained[i], item) From 4f19b32cc0192c652045b550f395fefa989bd995 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Fri, 13 Sep 2024 10:54:23 -0300 Subject: [PATCH 03/36] =?UTF-8?q?Adiciona=20valida=C3=A7=C3=A3o=20para=20o?= =?UTF-8?q?s=20atributos=20de=20'related-article'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/related_articles.py | 25 +++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index d92b42200..9a7595ffe 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -1,5 +1,5 @@ from packtools.sps.models.v2.related_articles import RelatedArticles -from packtools.sps.models import article_and_subarticles +from packtools.sps.models import article_and_subarticles, article_dates from packtools.sps.validation.exceptions import ValidationRelatedArticleException from packtools.sps.validation.utils import format_response @@ -9,6 +9,7 @@ class RelatedArticlesValidation: def __init__(self, xml_tree): self.related_articles = list(RelatedArticles(xml_tree).related_articles()) self.article_type = article_and_subarticles.ArticleAndSubArticles(xml_tree).main_article_type + self.history_events = list(article_dates.ArticleDates(xml_tree).history_dates_dict) def related_articles_matches_article_type_validation(self, correspondence_list=None, error_level="ERROR"): """ @@ -134,3 +135,25 @@ def related_articles_doi(self, error_level="ERROR"): data=related_article, error_level=error_level ) + + def related_article_attributes_validation(self, error_level="ERROR"): + for related_article in self.related_articles: + for attrib in ("related-article-type", "id", "href", "ext-link-type"): + if not related_article[attrib]: + yield format_response( + title='Related article type validation', + parent=related_article.get("parent"), + parent_id=related_article.get("parent_id"), + parent_article_type=related_article.get("parent_article_type"), + parent_lang=related_article.get("parent_lang"), + item='related-article', + sub_item=f'@{attrib}', + validation_type='exist', + is_valid=False, + expected=f"a value for @{attrib}", + obtained=None, + advice=f"Provide a value for @{attrib}", + data=related_article, + error_level=error_level + ) + From e1c0ad1a774d12da00ae954e6bbac40229121388 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Fri, 13 Sep 2024 10:54:52 -0300 Subject: [PATCH 04/36] =?UTF-8?q?Adiciona=20valida=C3=A7=C3=A3o=20para=20e?= =?UTF-8?q?vento=20em=20'history'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/related_articles.py | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index 9a7595ffe..435ae7638 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -157,3 +157,27 @@ def related_article_attributes_validation(self, error_level="ERROR"): error_level=error_level ) + def related_articles_matches_history_date_validation(self, correspondence_list=None, error_level="ERROR"): + if not correspondence_list: + raise ValidationRelatedArticleException("Function requires a dictionary with article type and history date event") + + for related_article in self.related_articles: + expected_event = correspondence_list.get(self.article_type) + obtained_events = self.history_events + is_valid = expected_event in obtained_events + yield format_response( + title='Related article type validation', + parent=related_article.get("parent"), + parent_id=related_article.get("parent_id"), + parent_article_type=related_article.get("parent_article_type"), + parent_lang=related_article.get("parent_lang"), + item='date', + sub_item='@date-type', + validation_type='exist', + is_valid=is_valid, + expected=expected_event, + obtained=obtained_events, + advice=f"Provide {expected_event} event in ", + data=related_article, + error_level=error_level + ) From 641094a1a3c17baaab0bb01aea799f461f4256b0 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Fri, 13 Sep 2024 10:55:09 -0300 Subject: [PATCH 05/36] Adiciona testes --- tests/sps/validation/test_related_articles.py | 261 ++++++++++++++++++ 1 file changed, 261 insertions(+) diff --git a/tests/sps/validation/test_related_articles.py b/tests/sps/validation/test_related_articles.py index 30b0b63d7..445e7a64f 100644 --- a/tests/sps/validation/test_related_articles.py +++ b/tests/sps/validation/test_related_articles.py @@ -234,6 +234,267 @@ def test_related_articles_does_not_have_doi(self): with self.subTest(i): self.assertDictEqual(obtained[i], item) + def test_related_articles_attribute_validation(self): + self.maxDiff = None + xmltree = etree.fromstring( + """ +
+ + + + + +
+ + """ + ) + obtained = list(RelatedArticlesValidation(xmltree).related_article_attributes_validation()) + + expected = [ + { + 'title': 'Related article type validation', + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'item': 'related-article', + 'sub_item': '@id', + 'validation_type': 'exist', + 'response': 'ERROR', + 'expected_value': 'a value for @id', + 'got_value': None, + 'message': 'Got None, expected a value for @id', + 'advice': 'Provide a value for @id', + 'data': { + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'ext-link-type': None, + 'href': None, + 'id': None, + 'related-article-type': 'corrected-article', + 'text': '' + } + }, + { + 'title': 'Related article type validation', + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'item': 'related-article', + 'sub_item': '@href', + 'validation_type': 'exist', + 'response': 'ERROR', + 'expected_value': 'a value for @href', + 'got_value': None, + 'message': 'Got None, expected a value for @href', + 'advice': 'Provide a value for @href', + 'data': { + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'ext-link-type': None, + 'href': None, + 'id': None, + 'related-article-type': 'corrected-article', + 'text': '' + } + }, + { + 'title': 'Related article type validation', + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'item': 'related-article', + 'sub_item': '@ext-link-type', + 'validation_type': 'exist', + 'response': 'ERROR', + 'expected_value': 'a value for @ext-link-type', + 'got_value': None, + 'message': 'Got None, expected a value for @ext-link-type', + 'advice': 'Provide a value for @ext-link-type', + 'data': { + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'ext-link-type': None, + 'href': None, + 'id': None, + 'related-article-type': 'corrected-article', + 'text': '' + } + } + ] + self.assertEqual(len(obtained), 3) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(obtained[i], item) + + def test_related_articles_matches_history_date_validation_success(self): + self.maxDiff = None + xmltree = etree.fromstring( + """ +
+ + + + + + + 05 + 01 + 1998 + + + 14 + 03 + 1998 + + + 24 + 05 + 1998 + + + 06 + 06 + 1998 + + + 01 + 06 + 2012 + + + +
+ + """ + ) + obtained = list(RelatedArticlesValidation(xmltree).related_articles_matches_history_date_validation( + { + "correction": "corrected", + "retraction": "retracted" + } + )) + + expected = [ + { + 'title': 'Related article type validation', + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'item': 'date', + 'sub_item': '@date-type', + 'validation_type': 'exist', + 'response': 'OK', + 'expected_value': 'corrected', + 'got_value': ['received', 'rev-request', 'rev-recd', 'accepted', 'corrected'], + 'message': "Got ['received', 'rev-request', 'rev-recd', 'accepted', 'corrected'], expected corrected", + 'advice': None, + 'data': { + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'ext-link-type': 'doi', + 'href': '10.1590/1808-057x202090350', + 'id': 'ra1', + 'related-article-type': 'corrected-article', + 'text': '' + } + } + ] + self.assertEqual(len(obtained), 1) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(obtained[i], item) + + def test_related_articles_matches_history_date_validation_fail(self): + self.maxDiff = None + xmltree = etree.fromstring( + """ +
+ + + + + + + 05 + 01 + 1998 + + + 14 + 03 + 1998 + + + 24 + 05 + 1998 + + + 06 + 06 + 1998 + + + +
+ + """ + ) + obtained = list(RelatedArticlesValidation(xmltree).related_articles_matches_history_date_validation( + { + "correction": "corrected", + "retraction": "retracted" + } + )) + + expected = [ + { + 'title': 'Related article type validation', + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'item': 'date', + 'sub_item': '@date-type', + 'validation_type': 'exist', + 'response': 'ERROR', + 'expected_value': 'corrected', + 'got_value': ['received', 'rev-request', 'rev-recd', 'accepted'], + 'message': "Got ['received', 'rev-request', 'rev-recd', 'accepted'], expected corrected", + 'advice': 'Provide corrected event in ', + 'data': { + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'ext-link-type': 'doi', + 'href': '10.1590/1808-057x202090350', + 'id': 'ra1', + 'related-article-type': 'corrected-article', + 'text': '' + } + } + ] + self.assertEqual(len(obtained), 1) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(obtained[i], item) + if __name__ == '__main__': unittest.main() From 7beefdce0a723ca537e7f8ce5720c752c472f7c7 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Sat, 14 Sep 2024 18:56:38 -0300 Subject: [PATCH 06/36] Remove 'related_articles_matches_history_date_validation' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Será considerado em outra validação. --- packtools/sps/validation/related_articles.py | 27 +------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index 435ae7638..f9ff63a60 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -141,7 +141,7 @@ def related_article_attributes_validation(self, error_level="ERROR"): for attrib in ("related-article-type", "id", "href", "ext-link-type"): if not related_article[attrib]: yield format_response( - title='Related article type validation', + title='Related article attributes validation', parent=related_article.get("parent"), parent_id=related_article.get("parent_id"), parent_article_type=related_article.get("parent_article_type"), @@ -156,28 +156,3 @@ def related_article_attributes_validation(self, error_level="ERROR"): data=related_article, error_level=error_level ) - - def related_articles_matches_history_date_validation(self, correspondence_list=None, error_level="ERROR"): - if not correspondence_list: - raise ValidationRelatedArticleException("Function requires a dictionary with article type and history date event") - - for related_article in self.related_articles: - expected_event = correspondence_list.get(self.article_type) - obtained_events = self.history_events - is_valid = expected_event in obtained_events - yield format_response( - title='Related article type validation', - parent=related_article.get("parent"), - parent_id=related_article.get("parent_id"), - parent_article_type=related_article.get("parent_article_type"), - parent_lang=related_article.get("parent_lang"), - item='date', - sub_item='@date-type', - validation_type='exist', - is_valid=is_valid, - expected=expected_event, - obtained=obtained_events, - advice=f"Provide {expected_event} event in ", - data=related_article, - error_level=error_level - ) From 8e9232f165ab6aeb242368e313465663ae187e16 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Sat, 14 Sep 2024 18:56:52 -0300 Subject: [PATCH 07/36] Adapta os testes --- tests/sps/validation/test_related_articles.py | 165 +----------------- 1 file changed, 3 insertions(+), 162 deletions(-) diff --git a/tests/sps/validation/test_related_articles.py b/tests/sps/validation/test_related_articles.py index 445e7a64f..c96e3e173 100644 --- a/tests/sps/validation/test_related_articles.py +++ b/tests/sps/validation/test_related_articles.py @@ -253,7 +253,7 @@ def test_related_articles_attribute_validation(self): expected = [ { - 'title': 'Related article type validation', + 'title': 'Related article attributes validation', 'parent': 'article', 'parent_article_type': 'correction', 'parent_id': None, @@ -279,7 +279,7 @@ def test_related_articles_attribute_validation(self): } }, { - 'title': 'Related article type validation', + 'title': 'Related article attributes validation', 'parent': 'article', 'parent_article_type': 'correction', 'parent_id': None, @@ -305,7 +305,7 @@ def test_related_articles_attribute_validation(self): } }, { - 'title': 'Related article type validation', + 'title': 'Related article attributes validation', 'parent': 'article', 'parent_article_type': 'correction', 'parent_id': None, @@ -336,165 +336,6 @@ def test_related_articles_attribute_validation(self): with self.subTest(i): self.assertDictEqual(obtained[i], item) - def test_related_articles_matches_history_date_validation_success(self): - self.maxDiff = None - xmltree = etree.fromstring( - """ -
- - - - - - - 05 - 01 - 1998 - - - 14 - 03 - 1998 - - - 24 - 05 - 1998 - - - 06 - 06 - 1998 - - - 01 - 06 - 2012 - - - -
- - """ - ) - obtained = list(RelatedArticlesValidation(xmltree).related_articles_matches_history_date_validation( - { - "correction": "corrected", - "retraction": "retracted" - } - )) - - expected = [ - { - 'title': 'Related article type validation', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'item': 'date', - 'sub_item': '@date-type', - 'validation_type': 'exist', - 'response': 'OK', - 'expected_value': 'corrected', - 'got_value': ['received', 'rev-request', 'rev-recd', 'accepted', 'corrected'], - 'message': "Got ['received', 'rev-request', 'rev-recd', 'accepted', 'corrected'], expected corrected", - 'advice': None, - 'data': { - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'ext-link-type': 'doi', - 'href': '10.1590/1808-057x202090350', - 'id': 'ra1', - 'related-article-type': 'corrected-article', - 'text': '' - } - } - ] - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(obtained[i], item) - - def test_related_articles_matches_history_date_validation_fail(self): - self.maxDiff = None - xmltree = etree.fromstring( - """ -
- - - - - - - 05 - 01 - 1998 - - - 14 - 03 - 1998 - - - 24 - 05 - 1998 - - - 06 - 06 - 1998 - - - -
- - """ - ) - obtained = list(RelatedArticlesValidation(xmltree).related_articles_matches_history_date_validation( - { - "correction": "corrected", - "retraction": "retracted" - } - )) - - expected = [ - { - 'title': 'Related article type validation', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'item': 'date', - 'sub_item': '@date-type', - 'validation_type': 'exist', - 'response': 'ERROR', - 'expected_value': 'corrected', - 'got_value': ['received', 'rev-request', 'rev-recd', 'accepted'], - 'message': "Got ['received', 'rev-request', 'rev-recd', 'accepted'], expected corrected", - 'advice': 'Provide corrected event in ', - 'data': { - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'ext-link-type': 'doi', - 'href': '10.1590/1808-057x202090350', - 'id': 'ra1', - 'related-article-type': 'corrected-article', - 'text': '' - } - } - ] - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(obtained[i], item) - if __name__ == '__main__': unittest.main() From fdc7fb05ccd022f4be39c7d61e0936503d33e389 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Sun, 22 Sep 2024 16:36:53 -0300 Subject: [PATCH 08/36] =?UTF-8?q?Refatora=20e=20complementa=20valida=C3=A7?= =?UTF-8?q?=C3=A3o=20de=20'errata'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/errata.py | 150 +++++++++++++++-------------- 1 file changed, 78 insertions(+), 72 deletions(-) diff --git a/packtools/sps/validation/errata.py b/packtools/sps/validation/errata.py index 068904e90..1f2506cdc 100644 --- a/packtools/sps/validation/errata.py +++ b/packtools/sps/validation/errata.py @@ -3,6 +3,21 @@ from packtools.sps.models.article_dates import HistoryDates +def _get_related_articles(xml_tree, expected_related_article_type): + return [ + article for article in RelatedItems(xml_tree).related_articles + if article.get("related-article-type") == expected_related_article_type + ] + + +def _format_obtained(related_article): + return ( + f'' + ) + + class ValidationBase: def __init__(self, xml_tree, expected_article_type, expected_related_article_type): self.xml_tree = xml_tree @@ -10,17 +25,11 @@ def __init__(self, xml_tree, expected_article_type, expected_related_article_typ self.article_type = xml_tree.find(".").get("article-type") self.expected_article_type = expected_article_type self.expected_related_article_type = expected_related_article_type - self.related_articles = self._get_related_articles() + self.related_articles = _get_related_articles(xml_tree, expected_related_article_type) def validate_related_article(self, title, error_level="ERROR"): """ Validates the related articles against the expected type and other criteria. - - Args: - error_level (str, optional): The error level for the validation response. Defaults to "ERROR". - - Yields: - dict: A formatted response indicating whether the validation passed or failed. """ if self.article_type != self.expected_article_type: return @@ -40,7 +49,7 @@ def validate_related_article(self, title, error_level="ERROR"): validation_type="match", is_valid=True, expected=expected_response, - obtained=self._format_obtained(related_article), + obtained=_format_obtained(related_article), advice=None, data=related_article, error_level=error_level @@ -65,87 +74,84 @@ def validate_related_article(self, title, error_level="ERROR"): error_level=error_level ) - def _get_related_articles(self,): - return [ - article for article in RelatedItems(self.xml_tree).related_articles - if article.get("related-article-type") == self.expected_related_article_type - ] + def validate_history_dates(self, expected_history_event, error_level="ERROR"): + """ + Validates that the number of related articles matches the number of corresponding corrected dates. + """ + history_data = list(HistoryDates(self.xml_tree).history_dates()) + history_dates = [date for date in history_data if expected_history_event in date.get("history")] + history_date_count = len(history_dates) + related_article_count = len(self.related_articles) + + if history_date_count < related_article_count: + yield format_response( + title="validation related and corrected dates count", + parent="article", + parent_id=None, + parent_article_type=self.article_type, + parent_lang=self.article_lang, + item="related-article", + sub_item="@related-article-type", + validation_type="exist", + is_valid=False, + expected=f'equal numbers of and ', + obtained=f'{related_article_count} and {history_date_count} ', + advice=f'for each , there must be a corresponding in ', + data=history_data, + error_level=error_level, + ) - def _format_obtained(self, related_article): - return ( - f'' - ) +class SpecificValidation(ValidationBase): + """ + Base class for specific validations to handle common functionality for Errata, ArticleCorrected, + ArticleRetracted, and ArticlePartiallyRetracted validations. + """ -class ErrataValidation(ValidationBase): def __init__(self, xml_tree, expected_article_type, expected_related_article_type): super().__init__(xml_tree, expected_article_type, expected_related_article_type) - def validate_related_article(self, error_level="ERROR", title="validation matching 'correction' and 'corrected-article'"): + def validate_related_article(self, error_level="ERROR", title=None): """ - Validates related articles specifically for corrected articles. - - Args: - error_level (str, optional): The error level for the validation response. Defaults to "ERROR". + Common logic for validating related articles, where `title` must be provided by subclasses. + """ + if title is None: + raise ValueError("Title must be provided for the validation.") + yield from super().validate_related_article(title=title, error_level=error_level) - Yields: - dict: A formatted response indicating whether the validation passed or failed. + def validate_history_dates(self, error_level="ERROR", expected_history_event=None): """ - yield from super().validate_related_article(error_level=error_level, title=title) + Common logic for validating history dates, where `expected_history_event` must be provided by subclasses. + """ + if expected_history_event is None: + raise ValueError("Expected history event must be provided.") + yield from super().validate_history_dates(expected_history_event=expected_history_event, error_level=error_level) -class CorrectedArticleValidation(ValidationBase): - def __init__(self, xml_tree, expected_article_type, expected_related_article_type): - super().__init__(xml_tree, expected_article_type, expected_related_article_type) - self.history_dates = self._get_history_dates() +class ErrataValidation(SpecificValidation): + def validate_related_article(self, error_level="ERROR", title="validation matching 'correction' and 'corrected-article'"): + yield from super().validate_related_article(error_level=error_level, title=title) + +class ArticleCorrectedValidation(SpecificValidation): def validate_related_article(self, error_level="ERROR", title="validation matching 'correction' and 'correction-forward'"): - """ - Validates related articles specifically for corrected articles. + yield from super().validate_related_article(error_level=error_level, title=title) - Args: - error_level (str, optional): The error level for the validation response. Defaults to "ERROR". + def validate_history_dates(self, error_level="ERROR", expected_history_event="corrected"): + yield from super().validate_history_dates(error_level=error_level, expected_history_event=expected_history_event) - Yields: - dict: A formatted response indicating whether the validation passed or failed. - """ - yield from super().validate_related_article(error_level=error_level, title=title) - def validate_history_dates(self, error_level="ERROR"): - """ - Validates that the number of related articles matches the number of corresponding corrected dates. +class ArticleRetractedInFullValidation(SpecificValidation): + def validate_related_article(self, error_level="ERROR", title="validation matching 'retraction' and 'retracted-article'"): + yield from super().validate_related_article(error_level=error_level, title=title) - Args: - error_level (str, optional): The error level for the validation response. Defaults to "ERROR". + def validate_history_dates(self, error_level="ERROR", expected_history_event="retracted"): + yield from super().validate_history_dates(error_level=error_level, expected_history_event=expected_history_event) - Yields: - dict: A formatted response indicating whether the validation passed or failed. - """ - history_date_count = len(self.history_dates) - related_article_count = len(self.related_articles) - if history_date_count < related_article_count: - yield format_response( - title="validation related and corrected dates count", - parent="article", - parent_id=None, - parent_article_type=self.article_type, - parent_lang=self.article_lang, - item="related-article", - sub_item="@related-article-type", - validation_type="exist", - is_valid=False, - expected='equal numbers of and ', - obtained=f'{related_article_count} and {history_date_count} ', - advice='for each , there must be a corresponding in ', - data=self.history_dates, - error_level=error_level, - ) +class ArticlePartiallyRetractedValidation(SpecificValidation): + def validate_related_article(self, error_level="ERROR", title="validation matching 'retraction' and 'partial-retraction'"): + yield from super().validate_related_article(error_level=error_level, title=title) - def _get_history_dates(self): - return [ - date for date in HistoryDates(self.xml_tree).history_dates() - if "corrected" in date.get("history") - ] + def validate_history_dates(self, error_level="ERROR", expected_history_event="retracted"): + yield from super().validate_history_dates(error_level=error_level, expected_history_event=expected_history_event) From e35d721d9bbe64a3a52e78ce0b9c789bec99c221 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Sun, 22 Sep 2024 16:37:16 -0300 Subject: [PATCH 09/36] Adapta e adiciona testes --- tests/sps/validation/test_errata.py | 366 +++++++++++++++++++++++++++- 1 file changed, 361 insertions(+), 5 deletions(-) diff --git a/tests/sps/validation/test_errata.py b/tests/sps/validation/test_errata.py index f792eae1c..ae935f453 100644 --- a/tests/sps/validation/test_errata.py +++ b/tests/sps/validation/test_errata.py @@ -1,7 +1,7 @@ from unittest import TestCase from packtools.sps.utils.xml_utils import get_xml_tree -from packtools.sps.validation.errata import ErrataValidation, CorrectedArticleValidation +from packtools.sps.validation.errata import ErrataValidation, ArticleCorrectedValidation, ArticleRetractedInFullValidation, ArticlePartiallyRetractedValidation class ErrataValidationTest(TestCase): @@ -96,7 +96,7 @@ def test_validate_related_article_found(self): self.assertDictEqual(item, obtained[i]) -class CorrectedArticleValidationTest(TestCase): +class ArticleCorrectedValidationTest(TestCase): def test_validate_related_article_not_found(self): self.maxDiff = None self.xml_tree = get_xml_tree( @@ -107,7 +107,7 @@ def test_validate_related_article_not_found(self): """ ) - obtained = list(CorrectedArticleValidation( + obtained = list(ArticleCorrectedValidation( self.xml_tree, expected_article_type="correction", expected_related_article_type="correction-forward" @@ -175,7 +175,7 @@ def test_validate_related_article_found(self): """ ) - obtained = list(CorrectedArticleValidation( + obtained = list(ArticleCorrectedValidation( self.xml_tree, expected_article_type="correction", expected_related_article_type="correction-forward" @@ -253,7 +253,7 @@ def test_validate_count_related_article_count_date(self): """ ) - obtained = list(CorrectedArticleValidation( + obtained = list(ArticleCorrectedValidation( self.xml_tree, expected_article_type="correction", expected_related_article_type="correction-forward" @@ -298,3 +298,359 @@ def test_validate_count_related_article_count_date(self): for i, item in enumerate(expected): with self.subTest(i): self.assertDictEqual(item, obtained[i]) + + +class ArticleRetractedInFullValidationTest(TestCase): + def test_validate_related_article_not_found(self): + self.maxDiff = None + self.xml_tree = get_xml_tree( + """ +
+
+ + """ + ) + obtained = list(ArticleRetractedInFullValidation( + self.xml_tree, + expected_article_type="retraction", + expected_related_article_type="retracted-article" + ).validate_related_article()) + expected = [ + { + "title": "validation matching 'retraction' and 'retracted-article'", + "parent": "article", + "parent_id": None, + "parent_article_type": "retraction", + "parent_lang": "en", + "item": "related-article", + "sub_item": "@related-article-type", + "validation_type": "exist", + "response": "ERROR", + "expected_value": 'at least one ', + "got_value": None, + "message": f'Got None, expected at least one ', + 'advice': 'provide ', + "data": None, + } + ] + self.assertEqual(len(obtained), 1) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(item, obtained[i]) + + def test_validate_related_article_found(self): + self.maxDiff = None + self.xml_tree = get_xml_tree( + """ +
+ + + + +
+ + """ + ) + obtained = list(ArticleRetractedInFullValidation( + self.xml_tree, + expected_article_type="retraction", + expected_related_article_type="retracted-article" + ).validate_related_article()) + expected = [ + { + "title": "validation matching 'retraction' and 'retracted-article'", + "parent": "article", + "parent_id": None, + "parent_article_type": "retraction", + "parent_lang": "en", + "item": "related-article", + "sub_item": "@related-article-type", + "validation_type": "match", + "response": "OK", + "expected_value": 'at least one ', + "got_value": '', + "message": f'Got , ' + f'expected at least one ', + "advice": None, + "data": { + 'ext-link-type': 'doi', + 'href': '10.5935/abc.20160032', + 'id': 'RA1', + 'parent': 'article', + 'parent_article_type': 'retraction', + 'parent_id': None, + 'parent_lang': 'en', + 'related-article-type': 'retracted-article' + }, + } + ] + self.assertEqual(len(obtained), 1) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(item, obtained[i]) + + def test_validate_count_related_article_count_date(self): + self.maxDiff = None + self.xml_tree = get_xml_tree( + """ +
+ + + + + + 05 + 01 + 1998 + + + 14 + 03 + 1998 + + + 24 + 05 + 1998 + + + 06 + 06 + 1998 + + + 01 + 06 + 2012 + + + +
+ """ + ) + obtained = list(ArticleRetractedInFullValidation( + self.xml_tree, + expected_article_type="retraction", + expected_related_article_type="retracted-article" + ).validate_history_dates()) + expected = [ + { + "title": "validation related and corrected dates count", + "parent": "article", + "parent_id": None, + "parent_article_type": "retraction", + "parent_lang": "en", + "item": "related-article", + "sub_item": "@related-article-type", + "validation_type": "exist", + "response": "ERROR", + "expected_value": 'equal numbers of and ', + "got_value": '2 and 1 ', + "message": 'Got 2 and 1 , ' + 'expected equal numbers of and ', + "advice": 'for each , there must be a corresponding in ', + "data": [ + { + 'parent': 'article', + 'parent_article_type': 'retraction', + 'parent_id': None, + 'parent_lang': 'en', + 'article_date': None, + 'collection_date': None, + 'history': { + 'accepted': {'day': '06', 'month': '06', 'type': 'accepted', 'year': '1998'}, + 'retracted': {'day': '01', 'month': '06', 'type': 'retracted', 'year': '2012'}, + 'received': {'day': '05', 'month': '01', 'type': 'received', 'year': '1998'}, + 'rev-recd': {'day': '24', 'month': '05', 'type': 'rev-recd', 'year': '1998'}, + 'rev-request': {'day': '14', 'month': '03', 'type': 'rev-request', 'year': '1998'} + }, + } + ] + } + ] + self.assertEqual(len(obtained), 1) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(item, obtained[i]) + + +class ArticlePartiallyRetractedValidationTest(TestCase): + def test_validate_related_article_not_found(self): + self.maxDiff = None + self.xml_tree = get_xml_tree( + """ +
+
+ + """ + ) + obtained = list(ArticlePartiallyRetractedValidation( + self.xml_tree, + expected_article_type="retraction", + expected_related_article_type="partial-retraction" + ).validate_related_article()) + expected = [ + { + "title": "validation matching 'retraction' and 'partial-retraction'", + "parent": "article", + "parent_id": None, + "parent_article_type": "retraction", + "parent_lang": "en", + "item": "related-article", + "sub_item": "@related-article-type", + "validation_type": "exist", + "response": "ERROR", + "expected_value": 'at least one ', + "got_value": None, + "message": f'Got None, expected at least one ', + 'advice': 'provide ', + "data": None, + } + ] + self.assertEqual(len(obtained), 1) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(item, obtained[i]) + + def test_validate_related_article_found(self): + self.maxDiff = None + self.xml_tree = get_xml_tree( + """ +
+ + + + +
+ + """ + ) + obtained = list(ArticleRetractedInFullValidation( + self.xml_tree, + expected_article_type="retraction", + expected_related_article_type="partial-retraction" + ).validate_related_article()) + expected = [ + { + "title": "validation matching 'retraction' and 'retracted-article'", + "parent": "article", + "parent_id": None, + "parent_article_type": "retraction", + "parent_lang": "en", + "item": "related-article", + "sub_item": "@related-article-type", + "validation_type": "match", + "response": "OK", + "expected_value": 'at least one ', + "got_value": '', + "message": f'Got , ' + f'expected at least one ', + "advice": None, + "data": { + 'ext-link-type': 'doi', + 'href': '10.5935/abc.20160032', + 'id': 'RA1', + 'parent': 'article', + 'parent_article_type': 'retraction', + 'parent_id': None, + 'parent_lang': 'en', + 'related-article-type': 'partial-retraction' + }, + } + ] + self.assertEqual(len(obtained), 1) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(item, obtained[i]) + + def test_validate_count_related_article_count_date(self): + self.maxDiff = None + self.xml_tree = get_xml_tree( + """ +
+ + + + + + 05 + 01 + 1998 + + + 14 + 03 + 1998 + + + 24 + 05 + 1998 + + + 06 + 06 + 1998 + + + 01 + 06 + 2012 + + + +
+ """ + ) + obtained = list(ArticlePartiallyRetractedValidation( + self.xml_tree, + expected_article_type="retraction", + expected_related_article_type="partial-retraction" + ).validate_history_dates()) + expected = [ + { + "title": "validation related and corrected dates count", + "parent": "article", + "parent_id": None, + "parent_article_type": "retraction", + "parent_lang": "en", + "item": "related-article", + "sub_item": "@related-article-type", + "validation_type": "exist", + "response": "ERROR", + "expected_value": 'equal numbers of and ', + "got_value": '2 and 1 ', + "message": 'Got 2 and 1 , ' + 'expected equal numbers of and ', + "advice": 'for each , there must be a corresponding in ', + "data": [ + { + 'parent': 'article', + 'parent_article_type': 'retraction', + 'parent_id': None, + 'parent_lang': 'en', + 'article_date': None, + 'collection_date': None, + 'history': { + 'accepted': {'day': '06', 'month': '06', 'type': 'accepted', 'year': '1998'}, + 'retracted': {'day': '01', 'month': '06', 'type': 'retracted', 'year': '2012'}, + 'received': {'day': '05', 'month': '01', 'type': 'received', 'year': '1998'}, + 'rev-recd': {'day': '24', 'month': '05', 'type': 'rev-recd', 'year': '1998'}, + 'rev-request': {'day': '14', 'month': '03', 'type': 'rev-request', 'year': '1998'} + }, + } + ] + } + ] + self.assertEqual(len(obtained), 1) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(item, obtained[i]) From 5cb951163c748c91ddf90b21b32a46defa0bf567 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Sun, 22 Sep 2024 16:45:28 -0300 Subject: [PATCH 10/36] Remove 'validation' de 'title' --- packtools/sps/validation/errata.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packtools/sps/validation/errata.py b/packtools/sps/validation/errata.py index 1f2506cdc..cb4a1710a 100644 --- a/packtools/sps/validation/errata.py +++ b/packtools/sps/validation/errata.py @@ -85,7 +85,7 @@ def validate_history_dates(self, expected_history_event, error_level="ERROR"): if history_date_count < related_article_count: yield format_response( - title="validation related and corrected dates count", + title="related and corrected dates count", parent="article", parent_id=None, parent_article_type=self.article_type, @@ -129,12 +129,12 @@ def validate_history_dates(self, error_level="ERROR", expected_history_event=Non class ErrataValidation(SpecificValidation): - def validate_related_article(self, error_level="ERROR", title="validation matching 'correction' and 'corrected-article'"): + def validate_related_article(self, error_level="ERROR", title="matching 'correction' and 'corrected-article'"): yield from super().validate_related_article(error_level=error_level, title=title) class ArticleCorrectedValidation(SpecificValidation): - def validate_related_article(self, error_level="ERROR", title="validation matching 'correction' and 'correction-forward'"): + def validate_related_article(self, error_level="ERROR", title="matching 'correction' and 'correction-forward'"): yield from super().validate_related_article(error_level=error_level, title=title) def validate_history_dates(self, error_level="ERROR", expected_history_event="corrected"): @@ -142,7 +142,7 @@ def validate_history_dates(self, error_level="ERROR", expected_history_event="co class ArticleRetractedInFullValidation(SpecificValidation): - def validate_related_article(self, error_level="ERROR", title="validation matching 'retraction' and 'retracted-article'"): + def validate_related_article(self, error_level="ERROR", title="matching 'retraction' and 'retracted-article'"): yield from super().validate_related_article(error_level=error_level, title=title) def validate_history_dates(self, error_level="ERROR", expected_history_event="retracted"): @@ -150,7 +150,7 @@ def validate_history_dates(self, error_level="ERROR", expected_history_event="re class ArticlePartiallyRetractedValidation(SpecificValidation): - def validate_related_article(self, error_level="ERROR", title="validation matching 'retraction' and 'partial-retraction'"): + def validate_related_article(self, error_level="ERROR", title="matching 'retraction' and 'partial-retraction'"): yield from super().validate_related_article(error_level=error_level, title=title) def validate_history_dates(self, error_level="ERROR", expected_history_event="retracted"): From 96a3999ce0f3c1e29b4f0ff9e4b3a9f0eb4bd0a6 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Sun, 22 Sep 2024 16:45:38 -0300 Subject: [PATCH 11/36] Adapta os testes --- tests/sps/validation/test_errata.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/sps/validation/test_errata.py b/tests/sps/validation/test_errata.py index ae935f453..6637bb0dc 100644 --- a/tests/sps/validation/test_errata.py +++ b/tests/sps/validation/test_errata.py @@ -22,7 +22,7 @@ def test_validate_related_article_not_found(self): ).validate_related_article()) expected = [ { - "title": "validation matching 'correction' and 'corrected-article'", + "title": "matching 'correction' and 'corrected-article'", "parent": "article", "parent_id": None, "parent_article_type": "correction", @@ -64,7 +64,7 @@ def test_validate_related_article_found(self): ).validate_related_article()) expected = [ { - "title": "validation matching 'correction' and 'corrected-article'", + "title": "matching 'correction' and 'corrected-article'", "parent": "article", "parent_id": None, "parent_article_type": "correction", @@ -114,7 +114,7 @@ def test_validate_related_article_not_found(self): ).validate_related_article()) expected = [ { - "title": "validation matching 'correction' and 'correction-forward'", + "title": "matching 'correction' and 'correction-forward'", "parent": "article", "parent_id": None, "parent_article_type": "correction", @@ -182,7 +182,7 @@ def test_validate_related_article_found(self): ).validate_related_article()) expected = [ { - "title": "validation matching 'correction' and 'correction-forward'", + "title": "matching 'correction' and 'correction-forward'", "parent": "article", "parent_id": None, "parent_article_type": "correction", @@ -260,7 +260,7 @@ def test_validate_count_related_article_count_date(self): ).validate_history_dates()) expected = [ { - "title": "validation related and corrected dates count", + "title": "related and corrected dates count", "parent": "article", "parent_id": None, "parent_article_type": "correction", @@ -318,7 +318,7 @@ def test_validate_related_article_not_found(self): ).validate_related_article()) expected = [ { - "title": "validation matching 'retraction' and 'retracted-article'", + "title": "matching 'retraction' and 'retracted-article'", "parent": "article", "parent_id": None, "parent_article_type": "retraction", @@ -360,7 +360,7 @@ def test_validate_related_article_found(self): ).validate_related_article()) expected = [ { - "title": "validation matching 'retraction' and 'retracted-article'", + "title": "matching 'retraction' and 'retracted-article'", "parent": "article", "parent_id": None, "parent_article_type": "retraction", @@ -438,7 +438,7 @@ def test_validate_count_related_article_count_date(self): ).validate_history_dates()) expected = [ { - "title": "validation related and corrected dates count", + "title": "related and corrected dates count", "parent": "article", "parent_id": None, "parent_article_type": "retraction", @@ -496,7 +496,7 @@ def test_validate_related_article_not_found(self): ).validate_related_article()) expected = [ { - "title": "validation matching 'retraction' and 'partial-retraction'", + "title": "matching 'retraction' and 'partial-retraction'", "parent": "article", "parent_id": None, "parent_article_type": "retraction", @@ -538,7 +538,7 @@ def test_validate_related_article_found(self): ).validate_related_article()) expected = [ { - "title": "validation matching 'retraction' and 'retracted-article'", + "title": "matching 'retraction' and 'retracted-article'", "parent": "article", "parent_id": None, "parent_article_type": "retraction", @@ -616,7 +616,7 @@ def test_validate_count_related_article_count_date(self): ).validate_history_dates()) expected = [ { - "title": "validation related and corrected dates count", + "title": "related and corrected dates count", "parent": "article", "parent_id": None, "parent_article_type": "retraction", From d3facd9bc5db2e3fd93a488625ebb03c3810ba66 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Tue, 24 Sep 2024 10:27:52 -0300 Subject: [PATCH 12/36] =?UTF-8?q?Refatora=20valida=C3=A7=C3=A3o=20de=20'er?= =?UTF-8?q?rata'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/errata.py | 169 ++++++++--------------------- 1 file changed, 43 insertions(+), 126 deletions(-) diff --git a/packtools/sps/validation/errata.py b/packtools/sps/validation/errata.py index cb4a1710a..fb20eac3e 100644 --- a/packtools/sps/validation/errata.py +++ b/packtools/sps/validation/errata.py @@ -1,157 +1,74 @@ from packtools.sps.validation.utils import format_response -from packtools.sps.models.related_articles import RelatedItems -from packtools.sps.models.article_dates import HistoryDates +from packtools.sps.models.v2.related_articles import RelatedArticles +from packtools.sps.models.article_dates import ArticleDates -def _get_related_articles(xml_tree, expected_related_article_type): - return [ - article for article in RelatedItems(xml_tree).related_articles - if article.get("related-article-type") == expected_related_article_type - ] - +class RelatedArticlesValidation: + def __init__(self, xml_tree, correspondence_list): + self.xml_tree = xml_tree + self.correspondence_list = correspondence_list + self.article_type = xml_tree.find(".").get("article-type") + self.related_articles = list(RelatedArticles(xml_tree).related_articles()) + self.history_dates = ArticleDates(xml_tree).history_dates_dict -def _format_obtained(related_article): - return ( - f'' - ) + def get_related_article_types_by_article_type(self, obtained_article_type): + return {item['related-article-type'] for item in self.correspondence_list + if item['article-type'] == obtained_article_type} + def get_related_article_types(self): + return {item['related-article-type'] for item in self.related_articles} -class ValidationBase: - def __init__(self, xml_tree, expected_article_type, expected_related_article_type): - self.xml_tree = xml_tree - self.article_lang = xml_tree.get("{http://www.w3.org/XML/1998/namespace}lang") - self.article_type = xml_tree.find(".").get("article-type") - self.expected_article_type = expected_article_type - self.expected_related_article_type = expected_related_article_type - self.related_articles = _get_related_articles(xml_tree, expected_related_article_type) + def get_history_events_by_related_article_type(self): + obtained_related_article_types = self.get_related_article_types() + return {item['date-type'] for item in self.correspondence_list + if item['related-article-type'] in obtained_related_article_types and item['date-type']} - def validate_related_article(self, title, error_level="ERROR"): - """ - Validates the related articles against the expected type and other criteria. - """ - if self.article_type != self.expected_article_type: - return + def get_history_events(self): + return set(self.history_dates.keys()) - expected_response = f'at least one ' + def validate_related_articles(self, error_level="ERROR"): + expected_related_article_types = self.get_related_article_types_by_article_type(self.article_type) + obtained_related_article_types = self.get_related_article_types() - if self.related_articles: - yield from ( - format_response( - title=title, - parent=related_article.get("parent"), - parent_id=related_article.get("parent_id"), - parent_article_type=related_article.get("parent_article_type"), - parent_lang=related_article.get("parent_lang"), - item="related-article", - sub_item="@related-article-type", - validation_type="match", - is_valid=True, - expected=expected_response, - obtained=_format_obtained(related_article), - advice=None, - data=related_article, - error_level=error_level - ) - for related_article in self.related_articles - ) - else: + missing_types = expected_related_article_types - obtained_related_article_types + if missing_types: + related_article_type = next(iter(missing_types)) yield format_response( - title=title, + title=f"matching '{self.article_type}' and '{related_article_type}'", parent="article", parent_id=None, parent_article_type=self.article_type, - parent_lang=self.article_lang, + parent_lang=self.xml_tree.find(".").get("{http://www.w3.org/XML/1998/namespace}lang"), item="related-article", sub_item="@related-article-type", - validation_type="exist", + validation_type="match", is_valid=False, - expected=expected_response, + expected=f'at least one ', obtained=None, - advice=f'provide ', - data=None, + advice=f'provide ', + data=self.related_articles, error_level=error_level ) - def validate_history_dates(self, expected_history_event, error_level="ERROR"): - """ - Validates that the number of related articles matches the number of corresponding corrected dates. - """ - history_data = list(HistoryDates(self.xml_tree).history_dates()) - history_dates = [date for date in history_data if expected_history_event in date.get("history")] - history_date_count = len(history_dates) - related_article_count = len(self.related_articles) + def validate_history_events(self, error_level="ERROR"): + expected_history_events = self.get_history_events_by_related_article_type() + obtained_history_events = self.get_history_events() - if history_date_count < related_article_count: + missing_events = expected_history_events - obtained_history_events + if missing_events: yield format_response( - title="related and corrected dates count", + title="exist historical date event for the related-article", parent="article", parent_id=None, parent_article_type=self.article_type, - parent_lang=self.article_lang, + parent_lang=self.xml_tree.find(".").get("{http://www.w3.org/XML/1998/namespace}lang"), item="related-article", sub_item="@related-article-type", validation_type="exist", is_valid=False, - expected=f'equal numbers of and ', - obtained=f'{related_article_count} and {history_date_count} ', - advice=f'for each , there must be a corresponding in ', - data=history_data, + expected=' '.join([f'' for event in missing_events]), + obtained=None, + advice='provide ' + ' '.join([f'' for event in missing_events]), + data=self.history_dates, error_level=error_level, ) - - -class SpecificValidation(ValidationBase): - """ - Base class for specific validations to handle common functionality for Errata, ArticleCorrected, - ArticleRetracted, and ArticlePartiallyRetracted validations. - """ - - def __init__(self, xml_tree, expected_article_type, expected_related_article_type): - super().__init__(xml_tree, expected_article_type, expected_related_article_type) - - def validate_related_article(self, error_level="ERROR", title=None): - """ - Common logic for validating related articles, where `title` must be provided by subclasses. - """ - if title is None: - raise ValueError("Title must be provided for the validation.") - yield from super().validate_related_article(title=title, error_level=error_level) - - def validate_history_dates(self, error_level="ERROR", expected_history_event=None): - """ - Common logic for validating history dates, where `expected_history_event` must be provided by subclasses. - """ - if expected_history_event is None: - raise ValueError("Expected history event must be provided.") - yield from super().validate_history_dates(expected_history_event=expected_history_event, error_level=error_level) - - -class ErrataValidation(SpecificValidation): - def validate_related_article(self, error_level="ERROR", title="matching 'correction' and 'corrected-article'"): - yield from super().validate_related_article(error_level=error_level, title=title) - - -class ArticleCorrectedValidation(SpecificValidation): - def validate_related_article(self, error_level="ERROR", title="matching 'correction' and 'correction-forward'"): - yield from super().validate_related_article(error_level=error_level, title=title) - - def validate_history_dates(self, error_level="ERROR", expected_history_event="corrected"): - yield from super().validate_history_dates(error_level=error_level, expected_history_event=expected_history_event) - - -class ArticleRetractedInFullValidation(SpecificValidation): - def validate_related_article(self, error_level="ERROR", title="matching 'retraction' and 'retracted-article'"): - yield from super().validate_related_article(error_level=error_level, title=title) - - def validate_history_dates(self, error_level="ERROR", expected_history_event="retracted"): - yield from super().validate_history_dates(error_level=error_level, expected_history_event=expected_history_event) - - -class ArticlePartiallyRetractedValidation(SpecificValidation): - def validate_related_article(self, error_level="ERROR", title="matching 'retraction' and 'partial-retraction'"): - yield from super().validate_related_article(error_level=error_level, title=title) - - def validate_history_dates(self, error_level="ERROR", expected_history_event="retracted"): - yield from super().validate_history_dates(error_level=error_level, expected_history_event=expected_history_event) From 530ad59d888a7571db34c32531ee3f8d1ca0f928 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Tue, 24 Sep 2024 10:28:19 -0300 Subject: [PATCH 13/36] Adapta os testes --- tests/sps/validation/test_errata.py | 867 ++++++++++++++++++---------- 1 file changed, 559 insertions(+), 308 deletions(-) diff --git a/tests/sps/validation/test_errata.py b/tests/sps/validation/test_errata.py index 6637bb0dc..c7557a8c2 100644 --- a/tests/sps/validation/test_errata.py +++ b/tests/sps/validation/test_errata.py @@ -1,7 +1,7 @@ from unittest import TestCase from packtools.sps.utils.xml_utils import get_xml_tree -from packtools.sps.validation.errata import ErrataValidation, ArticleCorrectedValidation, ArticleRetractedInFullValidation, ArticlePartiallyRetractedValidation +from packtools.sps.validation.errata import RelatedArticlesValidation class ErrataValidationTest(TestCase): @@ -11,15 +11,46 @@ def test_validate_related_article_not_found(self): """
+
""" ) - obtained = list(ErrataValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="correction", - expected_related_article_type="corrected-article" - ).validate_related_article()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_related_articles()) expected = [ { "title": "matching 'correction' and 'corrected-article'", @@ -29,13 +60,13 @@ def test_validate_related_article_not_found(self): "parent_lang": "en", "item": "related-article", "sub_item": "@related-article-type", - "validation_type": "exist", + "validation_type": "match", "response": "ERROR", "expected_value": 'at least one ', "got_value": None, "message": f'Got None, expected at least one ', "advice": 'provide ', - "data": None, + "data": [], } ] self.assertEqual(len(obtained), 1) @@ -43,25 +74,57 @@ def test_validate_related_article_not_found(self): with self.subTest(i): self.assertDictEqual(item, obtained[i]) - def test_validate_related_article_found(self): + def test_validate_related_article_does_not_match(self): self.maxDiff = None self.xml_tree = get_xml_tree( """ -
- + + +
""" ) - obtained = list(ErrataValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="correction", - expected_related_article_type="corrected-article" - ).validate_related_article()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_related_articles()) expected = [ { "title": "matching 'correction' and 'corrected-article'", @@ -72,23 +135,36 @@ def test_validate_related_article_found(self): "item": "related-article", "sub_item": "@related-article-type", "validation_type": "match", - "response": "OK", + "response": "ERROR", "expected_value": 'at least one ', - "got_value": '', - "message": f'Got , ' - f'expected at least one ', - "advice": None, - "data": { - 'ext-link-type': 'doi', - 'href': '10.5935/abc.20160032', - 'id': 'RA1', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'related-article-type': 'corrected-article' - }, - } + "got_value": None, + "message": 'Got None, expected at least one ', + "advice": 'provide ', + "data": [ + { + 'ext-link-type': 'doi', + 'href': '10.5935/abc.20160032', + 'id': 'RA1', + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'related-article-type': 'correction-forward', + 'text': '' + }, + { + 'ext-link-type': 'doi', + 'href': '10.5935/abc.20150051', + 'id': 'RA2', + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'related-article-type': 'commentary', + 'text': '' + } + ], + }, ] self.assertEqual(len(obtained), 1) for i, item in enumerate(expected): @@ -96,38 +172,68 @@ def test_validate_related_article_found(self): self.assertDictEqual(item, obtained[i]) -class ArticleCorrectedValidationTest(TestCase): +class RelatedArticlesTest(TestCase): def test_validate_related_article_not_found(self): self.maxDiff = None self.xml_tree = get_xml_tree( """ -
""" ) - obtained = list(ArticleCorrectedValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="correction", - expected_related_article_type="correction-forward" - ).validate_related_article()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_related_articles()) expected = [ { - "title": "matching 'correction' and 'correction-forward'", + "title": "matching 'correction' and 'corrected-article'", "parent": "article", "parent_id": None, "parent_article_type": "correction", "parent_lang": "en", "item": "related-article", "sub_item": "@related-article-type", - "validation_type": "exist", + "validation_type": "match", "response": "ERROR", - "expected_value": 'at least one ', + "expected_value": 'at least one ', "got_value": None, - "message": f'Got None, expected at least one ', - "advice": 'provide ', - "data": None, + "message": f'Got None, expected at least one ', + "advice": 'provide ', + "data": [], } ] self.assertEqual(len(obtained), 1) @@ -135,54 +241,59 @@ def test_validate_related_article_not_found(self): with self.subTest(i): self.assertDictEqual(item, obtained[i]) - def test_validate_related_article_found(self): + def test_validate_related_article_does_not_match(self): self.maxDiff = None self.xml_tree = get_xml_tree( """ -
+ - - - 05 - 01 - 1998 - - - 14 - 03 - 1998 - - - 24 - 05 - 1998 - - - 06 - 06 - 1998 - - - 01 - 06 - 2012 - - +
""" ) - obtained = list(ArticleCorrectedValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="correction", - expected_related_article_type="correction-forward" - ).validate_related_article()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_related_articles()) expected = [ { - "title": "matching 'correction' and 'correction-forward'", + "title": "matching 'correction' and 'corrected-article'", "parent": "article", "parent_id": None, "parent_article_type": "correction", @@ -190,22 +301,35 @@ def test_validate_related_article_found(self): "item": "related-article", "sub_item": "@related-article-type", "validation_type": "match", - "response": "OK", - "expected_value": 'at least one ', - "got_value": '', - "message": f'Got , ' - f'expected at least one ', - "advice": None, - "data": { - 'ext-link-type': 'doi', - 'href': '10.5935/abc.20160032', - 'id': 'RA1', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'related-article-type': 'correction-forward' - }, + "response": "ERROR", + "expected_value": 'at least one ', + "got_value": None, + "message": f'Got None, expected at least one ', + "advice": 'provide ', + "data": [ + { + 'ext-link-type': 'doi', + 'href': '10.5935/abc.20160032', + 'id': 'RA1', + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'related-article-type': 'correction-forward', + 'text': '' + }, + { + 'ext-link-type': 'doi', + 'href': '10.5935/abc.20150051', + 'id': 'RA2', + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'en', + 'related-article-type': 'commentary', + 'text': '' + } + ], } ] self.assertEqual(len(obtained), 1) @@ -217,50 +341,61 @@ def test_validate_count_related_article_count_date(self): self.maxDiff = None self.xml_tree = get_xml_tree( """ -
+ - 05 01 1998 - - 14 - 03 - 1998 - - - 24 - 05 - 1998 - - - 06 - 06 - 1998 - - - 01 - 06 - 2012 - +
""" ) - obtained = list(ArticleCorrectedValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="correction", - expected_related_article_type="correction-forward" - ).validate_history_dates()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_history_events()) expected = [ { - "title": "related and corrected dates count", + "title": 'exist historical date event for the related-article', "parent": "article", "parent_id": None, "parent_article_type": "correction", @@ -269,29 +404,18 @@ def test_validate_count_related_article_count_date(self): "sub_item": "@related-article-type", "validation_type": "exist", "response": "ERROR", - "expected_value": 'equal numbers of and ', - "got_value": '2 and 1 ', - "message": 'Got 2 and 1 , ' - 'expected equal numbers of and ', - "advice": 'for each , there must be a corresponding in ', - "data": [ - { - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'article_date': None, - 'collection_date': None, - 'history': { - 'accepted': {'day': '06', 'month': '06', 'type': 'accepted', 'year': '1998'}, - 'corrected': {'day': '01', 'month': '06', 'type': 'corrected', 'year': '2012'}, - 'received': {'day': '05', 'month': '01', 'type': 'received', 'year': '1998'}, - 'rev-recd': {'day': '24', 'month': '05', 'type': 'rev-recd', 'year': '1998'}, - 'rev-request': {'day': '14', 'month': '03', 'type': 'rev-request', 'year': '1998'} - }, + "expected_value": '', + "got_value": None, + "message": 'Got None, expected ', + 'advice': 'provide ', + "data": { + 'received': { + 'day': '05', + 'month': '01', + 'type': 'received', + 'year': '1998' } - ] + } } ] self.assertEqual(len(obtained), 1) @@ -305,17 +429,47 @@ def test_validate_related_article_not_found(self): self.maxDiff = None self.xml_tree = get_xml_tree( """ -
""" ) - obtained = list(ArticleRetractedInFullValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="retraction", - expected_related_article_type="retracted-article" - ).validate_related_article()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_related_articles()) expected = [ { "title": "matching 'retraction' and 'retracted-article'", @@ -325,13 +479,13 @@ def test_validate_related_article_not_found(self): "parent_lang": "en", "item": "related-article", "sub_item": "@related-article-type", - "validation_type": "exist", + "validation_type": "match", "response": "ERROR", "expected_value": 'at least one ', "got_value": None, "message": f'Got None, expected at least one ', 'advice': 'provide ', - "data": None, + "data": [], } ] self.assertEqual(len(obtained), 1) @@ -339,25 +493,56 @@ def test_validate_related_article_not_found(self): with self.subTest(i): self.assertDictEqual(item, obtained[i]) - def test_validate_related_article_found(self): + def test_validate_related_article_does_not_match(self): self.maxDiff = None self.xml_tree = get_xml_tree( """ -
- + +
""" ) - obtained = list(ArticleRetractedInFullValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="retraction", - expected_related_article_type="retracted-article" - ).validate_related_article()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_related_articles()) expected = [ { "title": "matching 'retraction' and 'retracted-article'", @@ -368,22 +553,24 @@ def test_validate_related_article_found(self): "item": "related-article", "sub_item": "@related-article-type", "validation_type": "match", - "response": "OK", + "response": "ERROR", "expected_value": 'at least one ', - "got_value": '', - "message": f'Got , ' - f'expected at least one ', - "advice": None, - "data": { - 'ext-link-type': 'doi', - 'href': '10.5935/abc.20160032', - 'id': 'RA1', - 'parent': 'article', - 'parent_article_type': 'retraction', - 'parent_id': None, - 'parent_lang': 'en', - 'related-article-type': 'retracted-article' - }, + "got_value": None, + "message": f'Got None, expected at least one ', + "advice": 'provide ', + "data": [ + { + 'ext-link-type': 'doi', + 'href': '10.5935/abc.20150051', + 'id': 'RA2', + 'parent': 'article', + 'parent_article_type': 'retraction', + 'parent_id': None, + 'parent_lang': 'en', + 'related-article-type': 'commentary', + 'text': '' + } + ] } ] self.assertEqual(len(obtained), 1) @@ -395,50 +582,61 @@ def test_validate_count_related_article_count_date(self): self.maxDiff = None self.xml_tree = get_xml_tree( """ -
- - + + 05 01 1998 - - 14 - 03 - 1998 - - - 24 - 05 - 1998 - - - 06 - 06 - 1998 - - - 01 - 06 - 2012 - +
""" ) - obtained = list(ArticleRetractedInFullValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="retraction", - expected_related_article_type="retracted-article" - ).validate_history_dates()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_history_events()) expected = [ { - "title": "related and corrected dates count", + "title": 'exist historical date event for the related-article', "parent": "article", "parent_id": None, "parent_article_type": "retraction", @@ -447,29 +645,18 @@ def test_validate_count_related_article_count_date(self): "sub_item": "@related-article-type", "validation_type": "exist", "response": "ERROR", - "expected_value": 'equal numbers of and ', - "got_value": '2 and 1 ', - "message": 'Got 2 and 1 , ' - 'expected equal numbers of and ', - "advice": 'for each , there must be a corresponding in ', - "data": [ - { - 'parent': 'article', - 'parent_article_type': 'retraction', - 'parent_id': None, - 'parent_lang': 'en', - 'article_date': None, - 'collection_date': None, - 'history': { - 'accepted': {'day': '06', 'month': '06', 'type': 'accepted', 'year': '1998'}, - 'retracted': {'day': '01', 'month': '06', 'type': 'retracted', 'year': '2012'}, - 'received': {'day': '05', 'month': '01', 'type': 'received', 'year': '1998'}, - 'rev-recd': {'day': '24', 'month': '05', 'type': 'rev-recd', 'year': '1998'}, - 'rev-request': {'day': '14', 'month': '03', 'type': 'rev-request', 'year': '1998'} - }, + "expected_value": '', + "got_value": None, + "message": 'Got None, expected ', + "advice": 'provide ', + "data": { + 'received': { + 'day': '05', + 'month': '01', + 'type': 'received', + 'year': '1998' } - ] + } } ] self.assertEqual(len(obtained), 1) @@ -483,33 +670,63 @@ def test_validate_related_article_not_found(self): self.maxDiff = None self.xml_tree = get_xml_tree( """ -
+
""" ) - obtained = list(ArticlePartiallyRetractedValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="retraction", - expected_related_article_type="partial-retraction" - ).validate_related_article()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_related_articles()) expected = [ { - "title": "matching 'retraction' and 'partial-retraction'", + "title": "matching 'partial-retraction' and 'retracted-article'", "parent": "article", "parent_id": None, - "parent_article_type": "retraction", + "parent_article_type": "partial-retraction", "parent_lang": "en", "item": "related-article", "sub_item": "@related-article-type", - "validation_type": "exist", + "validation_type": "match", "response": "ERROR", - "expected_value": 'at least one ', + "expected_value": 'at least one ', "got_value": None, - "message": f'Got None, expected at least one ', - 'advice': 'provide ', - "data": None, + "message": f'Got None, expected at least one ', + 'advice': 'provide ', + "data": [], } ] self.assertEqual(len(obtained), 1) @@ -521,47 +738,80 @@ def test_validate_related_article_found(self): self.maxDiff = None self.xml_tree = get_xml_tree( """ -
+
- + +
""" ) - obtained = list(ArticleRetractedInFullValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="retraction", - expected_related_article_type="partial-retraction" - ).validate_related_article()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_related_articles()) expected = [ { - "title": "matching 'retraction' and 'retracted-article'", + "title": "matching 'partial-retraction' and 'retracted-article'", "parent": "article", "parent_id": None, - "parent_article_type": "retraction", + "parent_article_type": "partial-retraction", "parent_lang": "en", "item": "related-article", "sub_item": "@related-article-type", "validation_type": "match", - "response": "OK", - "expected_value": 'at least one ', - "got_value": '', - "message": f'Got , ' - f'expected at least one ', - "advice": None, - "data": { - 'ext-link-type': 'doi', - 'href': '10.5935/abc.20160032', - 'id': 'RA1', - 'parent': 'article', - 'parent_article_type': 'retraction', - 'parent_id': None, - 'parent_lang': 'en', - 'related-article-type': 'partial-retraction' - }, + "response": "ERROR", + "expected_value": 'at least one ', + "got_value": None, + "message": 'Got None, expected at least one ', + "advice": 'provide ', + "data": [ + { + 'ext-link-type': 'doi', + 'href': '10.5935/abc.20150051', + 'id': 'RA2', + 'parent': 'article', + 'parent_article_type': 'partial-retraction', + 'parent_id': None, + 'parent_lang': 'en', + 'related-article-type': 'commentary', + 'text': '' + } + ], } ] self.assertEqual(len(obtained), 1) @@ -573,9 +823,10 @@ def test_validate_count_related_article_count_date(self): self.maxDiff = None self.xml_tree = get_xml_tree( """ -
+
+ @@ -584,70 +835,70 @@ def test_validate_count_related_article_count_date(self): 01 1998 - - 14 - 03 - 1998 - - - 24 - 05 - 1998 - - - 06 - 06 - 1998 - - - 01 - 06 - 2012 - +
""" ) - obtained = list(ArticlePartiallyRetractedValidation( + obtained = list(RelatedArticlesValidation( self.xml_tree, - expected_article_type="retraction", - expected_related_article_type="partial-retraction" - ).validate_history_dates()) + correspondence_list=[ + { + 'article-type': 'correction', + 'related-article-type': 'corrected-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'correction-forward', + 'date-type': 'corrected' + }, + { + 'article-type': 'retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': 'partial-retraction', + 'related-article-type': 'retracted-article', + 'date-type': None + }, + { + 'article-type': None, + 'related-article-type': 'retraction-forward', + 'date-type': 'retracted' + }, + { + 'article-type': None, + 'related-article-type': 'partial-retraction', + 'date-type': 'retracted' + }, + ] + ).validate_history_events()) expected = [ { - "title": "related and corrected dates count", + "title": 'exist historical date event for the related-article', "parent": "article", "parent_id": None, - "parent_article_type": "retraction", + "parent_article_type": 'partial-retraction', "parent_lang": "en", "item": "related-article", "sub_item": "@related-article-type", "validation_type": "exist", "response": "ERROR", - "expected_value": 'equal numbers of and ', - "got_value": '2 and 1 ', - "message": 'Got 2 and 1 , ' - 'expected equal numbers of and ', - "advice": 'for each , there must be a corresponding in ', - "data": [ - { - 'parent': 'article', - 'parent_article_type': 'retraction', - 'parent_id': None, - 'parent_lang': 'en', - 'article_date': None, - 'collection_date': None, - 'history': { - 'accepted': {'day': '06', 'month': '06', 'type': 'accepted', 'year': '1998'}, - 'retracted': {'day': '01', 'month': '06', 'type': 'retracted', 'year': '2012'}, - 'received': {'day': '05', 'month': '01', 'type': 'received', 'year': '1998'}, - 'rev-recd': {'day': '24', 'month': '05', 'type': 'rev-recd', 'year': '1998'}, - 'rev-request': {'day': '14', 'month': '03', 'type': 'rev-request', 'year': '1998'} - }, + "expected_value": '', + "got_value": None, + "message": 'Got None, expected ', + "advice": 'provide ', + "data": { + 'received': { + 'day': '05', + 'month': '01', + 'type': 'received', + 'year': '1998' } - ] + }, } ] self.assertEqual(len(obtained), 1) From 80664efd99b4809648d3e0ce969ec2c732a25a85 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Mon, 30 Sep 2024 11:35:37 -0300 Subject: [PATCH 14/36] Adiciona argumento "related_article_type" --- packtools/sps/models/v2/related_articles.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packtools/sps/models/v2/related_articles.py b/packtools/sps/models/v2/related_articles.py index 041379025..aa2cafec0 100644 --- a/packtools/sps/models/v2/related_articles.py +++ b/packtools/sps/models/v2/related_articles.py @@ -32,18 +32,19 @@ def data(self): class RelatedArticlesByNode: def __init__(self, node): - self.node = node self.node = node self.parent = self.node.tag self.parent_id = self.node.get("id") self.article_type = node.get("article-type") self.lang = self.node.get("{http://www.w3.org/XML/1998/namespace}lang") - def related_articles(self): + def related_articles(self, related_article_type=None): if self.parent == "article": path = ".//article-meta//related-article" else: path = ".//front-stub//related-article" + if related_article_type: + path += f"[@related-article-type='{related_article_type}']" for related_article in self.node.xpath(path): data = RelatedArticle(related_article).data() yield put_parent_context( @@ -52,15 +53,16 @@ def related_articles(self): class RelatedArticles: - def __init__(self, xml_tree): + def __init__(self, xml_tree, related_article_type=None): self.xml_tree = xml_tree + self.related_article_type = related_article_type def article(self): - yield from RelatedArticlesByNode(self.xml_tree.find(".")).related_articles() + yield from RelatedArticlesByNode(self.xml_tree.find(".")).related_articles(self.related_article_type) def sub_articles(self): for sub_article in self.xml_tree.xpath(".//sub-article"): - yield from RelatedArticlesByNode(sub_article).related_articles() + yield from RelatedArticlesByNode(sub_article).related_articles(self.related_article_type) def related_articles(self): yield from self.article() From 078c2b8b178804017b65f5f542764e8c4aa6c053 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Mon, 30 Sep 2024 11:35:47 -0300 Subject: [PATCH 15/36] Adiciona teste --- tests/sps/models/v2/test_related_articles.py | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/sps/models/v2/test_related_articles.py b/tests/sps/models/v2/test_related_articles.py index c638cd799..0706c7136 100644 --- a/tests/sps/models/v2/test_related_articles.py +++ b/tests/sps/models/v2/test_related_articles.py @@ -152,3 +152,33 @@ def test_related_articles(self): obtained = list(RelatedArticles(self.xml_tree).related_articles()) self.assertEqual(len(obtained), 18) + + def test_related_articles_by_related_article_type(self): + xml = """ +
+ + + + + + +
+ """ + obtained = list(RelatedArticles(xml_utils.get_xml_tree(xml), related_article_type="commentary-article").related_articles()) + expected = [ + { + 'ext-link-type': 'doi', + 'href': '10.1590/0101-3173.2022.v45n1.p139', + 'id': 'A01', + 'parent': 'article', + 'parent_article_type': 'article-commentary', + 'parent_id': None, + 'parent_lang': 'pt', + 'related-article-type': 'commentary-article', + 'text': '' + }, + + ] + self.assertEqual(len(obtained), 1) + self.assertDictEqual(obtained[0], expected[0]) From 3c9f8ef51e94d45aaceaed0fa01fb9597ca79c8f Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:18:55 -0300 Subject: [PATCH 16/36] =?UTF-8?q?Remove=20o=20m=C3=B3dulo=20de=20valida?= =?UTF-8?q?=C3=A7=C3=A3o=20de=20'preprint'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/preprint.py | 81 ---------------------------- 1 file changed, 81 deletions(-) delete mode 100644 packtools/sps/validation/preprint.py diff --git a/packtools/sps/validation/preprint.py b/packtools/sps/validation/preprint.py deleted file mode 100644 index c21a374d0..000000000 --- a/packtools/sps/validation/preprint.py +++ /dev/null @@ -1,81 +0,0 @@ -from packtools.sps.models.related_articles import RelatedItems -from packtools.sps.models.dates import ArticleDates - - -class PreprintValidation: - def __init__(self, xmltree): - self.related_articles = RelatedItems(xmltree).related_articles - self.article_dates = ArticleDates(xmltree).history_dates_dict - - def _extract_preprint_status(self): - return [item.get('preprint') for item in self.related_articles] - - def _extract_preprint_date(self): - preprint_date = self.article_dates.get('preprint') - return '-'.join([preprint_date[key] for key in ['year', 'month', 'day']]) if preprint_date else None - - def preprint_validation(self): - """ - Checks whether an article that has a preprint has the corresponding date in the history. - - XML input - --------- -
- - - - - 18 - 10 - 2002 - - - - - -
- - Returns - ------- - dict, such as: - { - 'title': 'Preprint validation', - 'xpath': './/related-article[@related-article-type="preprint"] .//history//date[@date-type="preprint"]', - 'validation_type': 'exist, match', - 'response': 'OK', - 'expected_value': '2002-10-18', - 'got_value': '2002-10-18', - 'message': 'Got 2002-10-18 expected 2002-10-18', - 'advice': None - } - """ - has_preprint = self._extract_preprint_status() - has_preprint_date = self._extract_preprint_date() - - if not (has_preprint or has_preprint_date): - return [] - - response, expected_value, got_value, advice = 'OK', has_preprint_date, has_preprint_date, None - - if has_preprint and not has_preprint_date: - response, expected_value, got_value, advice = \ - 'ERROR', 'The preprint publication date', None, 'Provide the publication date of the preprint' - elif not has_preprint and has_preprint_date: - response, expected_value, got_value, advice = \ - 'ERROR', None, has_preprint_date, 'The article does not reference the preprint, ' \ - 'provide it as in the example: ' - - return [ - { - 'title': 'Preprint validation', - 'xpath': './/related-article[@related-article-type="preprint"] .//history//date[@date-type="preprint"]', - 'validation_type': 'match', - 'response': response, - 'expected_value': expected_value, - 'got_value': got_value, - 'message': f'Got {got_value} expected {expected_value}', - 'advice': advice - } - ] From a1fc8655c91e4ac8537a4f6ae3cd54b5073d9814 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:19:24 -0300 Subject: [PATCH 17/36] =?UTF-8?q?Remove=20o=20m=C3=B3dulo=20de=20valida?= =?UTF-8?q?=C3=A7=C3=A3o=20de=20'errata'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/errata.py | 74 ------------------------------ 1 file changed, 74 deletions(-) delete mode 100644 packtools/sps/validation/errata.py diff --git a/packtools/sps/validation/errata.py b/packtools/sps/validation/errata.py deleted file mode 100644 index fb20eac3e..000000000 --- a/packtools/sps/validation/errata.py +++ /dev/null @@ -1,74 +0,0 @@ -from packtools.sps.validation.utils import format_response -from packtools.sps.models.v2.related_articles import RelatedArticles -from packtools.sps.models.article_dates import ArticleDates - - -class RelatedArticlesValidation: - def __init__(self, xml_tree, correspondence_list): - self.xml_tree = xml_tree - self.correspondence_list = correspondence_list - self.article_type = xml_tree.find(".").get("article-type") - self.related_articles = list(RelatedArticles(xml_tree).related_articles()) - self.history_dates = ArticleDates(xml_tree).history_dates_dict - - def get_related_article_types_by_article_type(self, obtained_article_type): - return {item['related-article-type'] for item in self.correspondence_list - if item['article-type'] == obtained_article_type} - - def get_related_article_types(self): - return {item['related-article-type'] for item in self.related_articles} - - def get_history_events_by_related_article_type(self): - obtained_related_article_types = self.get_related_article_types() - return {item['date-type'] for item in self.correspondence_list - if item['related-article-type'] in obtained_related_article_types and item['date-type']} - - def get_history_events(self): - return set(self.history_dates.keys()) - - def validate_related_articles(self, error_level="ERROR"): - expected_related_article_types = self.get_related_article_types_by_article_type(self.article_type) - obtained_related_article_types = self.get_related_article_types() - - missing_types = expected_related_article_types - obtained_related_article_types - if missing_types: - related_article_type = next(iter(missing_types)) - yield format_response( - title=f"matching '{self.article_type}' and '{related_article_type}'", - parent="article", - parent_id=None, - parent_article_type=self.article_type, - parent_lang=self.xml_tree.find(".").get("{http://www.w3.org/XML/1998/namespace}lang"), - item="related-article", - sub_item="@related-article-type", - validation_type="match", - is_valid=False, - expected=f'at least one ', - obtained=None, - advice=f'provide ', - data=self.related_articles, - error_level=error_level - ) - - def validate_history_events(self, error_level="ERROR"): - expected_history_events = self.get_history_events_by_related_article_type() - obtained_history_events = self.get_history_events() - - missing_events = expected_history_events - obtained_history_events - if missing_events: - yield format_response( - title="exist historical date event for the related-article", - parent="article", - parent_id=None, - parent_article_type=self.article_type, - parent_lang=self.xml_tree.find(".").get("{http://www.w3.org/XML/1998/namespace}lang"), - item="related-article", - sub_item="@related-article-type", - validation_type="exist", - is_valid=False, - expected=' '.join([f'' for event in missing_events]), - obtained=None, - advice='provide ' + ' '.join([f'' for event in missing_events]), - data=self.history_dates, - error_level=error_level, - ) From 35158fc5812f5abc9656662ac518014966c72f94 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:20:52 -0300 Subject: [PATCH 18/36] =?UTF-8?q?Corrige=20a=20extens=C3=A3o=20dos=20arqui?= =?UTF-8?q?vos=20de=20listas=20controladas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sps-1.10/role_content_type.json | 60 +++++++++++++++++++ .../sps-1.10/role_content_type.json.py | 58 ------------------ .../sps-1.9/role_content_type.json | 60 +++++++++++++++++++ .../sps-1.9/role_content_type.json.py | 58 ------------------ 4 files changed, 120 insertions(+), 116 deletions(-) create mode 100644 packtools/sps/sps_versions/sps-1.10/role_content_type.json delete mode 100644 packtools/sps/sps_versions/sps-1.10/role_content_type.json.py create mode 100644 packtools/sps/sps_versions/sps-1.9/role_content_type.json delete mode 100644 packtools/sps/sps_versions/sps-1.9/role_content_type.json.py diff --git a/packtools/sps/sps_versions/sps-1.10/role_content_type.json b/packtools/sps/sps_versions/sps-1.10/role_content_type.json new file mode 100644 index 000000000..86d2aa7be --- /dev/null +++ b/packtools/sps/sps_versions/sps-1.10/role_content_type.json @@ -0,0 +1,60 @@ +{ + "credit_taxonomy_terms_and_urls": [ + { + "term": "Conceptualization", + "uri": "https://credit.niso.org/contributor-roles/conceptualization/" + }, + { + "term": "Data curation", + "uri": "https://credit.niso.org/contributor-roles/data-curation/" + }, + { + "term": "Formal analysis", + "uri": "https://credit.niso.org/contributor-roles/formal-analysis/" + }, + { + "term": "Funding acquisition", + "uri": "https://credit.niso.org/contributor-roles/funding-acquisition/" + }, + { + "term": "Investigation", + "uri": "https://credit.niso.org/contributor-roles/investigation/" + }, + { + "term": "Methodology", + "uri": "https://credit.niso.org/contributor-roles/methodology/" + }, + { + "term": "Project administration", + "uri": "https://credit.niso.org/contributor-roles/project-administration/" + }, + { + "term": "Resources", + "uri": "https://credit.niso.org/contributor-roles/resources/" + }, + { + "term": "Software", + "uri": "https://credit.niso.org/contributor-roles/software/" + }, + { + "term": "Supervision", + "uri": "https://credit.niso.org/contributor-roles/supervision/" + }, + { + "term": "Validation", + "uri": "https://credit.niso.org/contributor-roles/validation/" + }, + { + "term": "Visualization", + "uri": "https://credit.niso.org/contributor-roles/visualization/" + }, + { + "term": "Writing – original draft", + "uri": "https://credit.niso.org/contributor-roles/writing-original-draft/" + }, + { + "term": "Writing – review e editing", + "uri": "https://credit.niso.org/contributor-roles/writing-review-editing/" + } + ] +} diff --git a/packtools/sps/sps_versions/sps-1.10/role_content_type.json.py b/packtools/sps/sps_versions/sps-1.10/role_content_type.json.py deleted file mode 100644 index 746325519..000000000 --- a/packtools/sps/sps_versions/sps-1.10/role_content_type.json.py +++ /dev/null @@ -1,58 +0,0 @@ -credit_taxonomy_terms_and_urls = [ - { - "term": "Conceptualization", - "uri": "https://credit.niso.org/contributor-roles/conceptualization/", - }, - { - "term": "Data curation", - "uri": "https://credit.niso.org/contributor-roles/data-curation/", - }, - { - "term": "Formal analysis", - "uri": "https://credit.niso.org/contributor-roles/formal-analysis/", - }, - { - "term": "Funding acquisition", - "uri": "https://credit.niso.org/contributor-roles/funding-acquisition/", - }, - { - "term": "Investigation", - "uri": "https://credit.niso.org/contributor-roles/investigation/", - }, - { - "term": "Methodology", - "uri": "https://credit.niso.org/contributor-roles/methodology/", - }, - { - "term": "Project administration", - "uri": "https://credit.niso.org/contributor-roles/project-administration/", - }, - { - "term": "Resources", - "uri": "https://credit.niso.org/contributor-roles/resources/", - }, - { - "term": "Software", - "uri": "https://credit.niso.org/contributor-roles/software/", - }, - { - "term": "Supervision", - "uri": "https://credit.niso.org/contributor-roles/supervision/", - }, - { - "term": "Validation", - "uri": "https://credit.niso.org/contributor-roles/validation/", - }, - { - "term": "Visualization", - "uri": "https://credit.niso.org/contributor-roles/visualization/", - }, - { - "term": "Writing – original draft", - "uri": "https://credit.niso.org/contributor-roles/writing-original-draft/", - }, - { - "term": "Writing – review e editing", - "uri": "https://credit.niso.org/contributor-roles/writing-review-editing/", - }, -] diff --git a/packtools/sps/sps_versions/sps-1.9/role_content_type.json b/packtools/sps/sps_versions/sps-1.9/role_content_type.json new file mode 100644 index 000000000..86d2aa7be --- /dev/null +++ b/packtools/sps/sps_versions/sps-1.9/role_content_type.json @@ -0,0 +1,60 @@ +{ + "credit_taxonomy_terms_and_urls": [ + { + "term": "Conceptualization", + "uri": "https://credit.niso.org/contributor-roles/conceptualization/" + }, + { + "term": "Data curation", + "uri": "https://credit.niso.org/contributor-roles/data-curation/" + }, + { + "term": "Formal analysis", + "uri": "https://credit.niso.org/contributor-roles/formal-analysis/" + }, + { + "term": "Funding acquisition", + "uri": "https://credit.niso.org/contributor-roles/funding-acquisition/" + }, + { + "term": "Investigation", + "uri": "https://credit.niso.org/contributor-roles/investigation/" + }, + { + "term": "Methodology", + "uri": "https://credit.niso.org/contributor-roles/methodology/" + }, + { + "term": "Project administration", + "uri": "https://credit.niso.org/contributor-roles/project-administration/" + }, + { + "term": "Resources", + "uri": "https://credit.niso.org/contributor-roles/resources/" + }, + { + "term": "Software", + "uri": "https://credit.niso.org/contributor-roles/software/" + }, + { + "term": "Supervision", + "uri": "https://credit.niso.org/contributor-roles/supervision/" + }, + { + "term": "Validation", + "uri": "https://credit.niso.org/contributor-roles/validation/" + }, + { + "term": "Visualization", + "uri": "https://credit.niso.org/contributor-roles/visualization/" + }, + { + "term": "Writing – original draft", + "uri": "https://credit.niso.org/contributor-roles/writing-original-draft/" + }, + { + "term": "Writing – review e editing", + "uri": "https://credit.niso.org/contributor-roles/writing-review-editing/" + } + ] +} diff --git a/packtools/sps/sps_versions/sps-1.9/role_content_type.json.py b/packtools/sps/sps_versions/sps-1.9/role_content_type.json.py deleted file mode 100644 index 746325519..000000000 --- a/packtools/sps/sps_versions/sps-1.9/role_content_type.json.py +++ /dev/null @@ -1,58 +0,0 @@ -credit_taxonomy_terms_and_urls = [ - { - "term": "Conceptualization", - "uri": "https://credit.niso.org/contributor-roles/conceptualization/", - }, - { - "term": "Data curation", - "uri": "https://credit.niso.org/contributor-roles/data-curation/", - }, - { - "term": "Formal analysis", - "uri": "https://credit.niso.org/contributor-roles/formal-analysis/", - }, - { - "term": "Funding acquisition", - "uri": "https://credit.niso.org/contributor-roles/funding-acquisition/", - }, - { - "term": "Investigation", - "uri": "https://credit.niso.org/contributor-roles/investigation/", - }, - { - "term": "Methodology", - "uri": "https://credit.niso.org/contributor-roles/methodology/", - }, - { - "term": "Project administration", - "uri": "https://credit.niso.org/contributor-roles/project-administration/", - }, - { - "term": "Resources", - "uri": "https://credit.niso.org/contributor-roles/resources/", - }, - { - "term": "Software", - "uri": "https://credit.niso.org/contributor-roles/software/", - }, - { - "term": "Supervision", - "uri": "https://credit.niso.org/contributor-roles/supervision/", - }, - { - "term": "Validation", - "uri": "https://credit.niso.org/contributor-roles/validation/", - }, - { - "term": "Visualization", - "uri": "https://credit.niso.org/contributor-roles/visualization/", - }, - { - "term": "Writing – original draft", - "uri": "https://credit.niso.org/contributor-roles/writing-original-draft/", - }, - { - "term": "Writing – review e editing", - "uri": "https://credit.niso.org/contributor-roles/writing-review-editing/", - }, -] From 2af892dc25fce905a5185c45048444c4ecebe00e Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:21:25 -0300 Subject: [PATCH 19/36] Adiciona 'related_article.json' --- .../sps-1.10/related_article.json | 44 +++++++++---------- .../sps_versions/sps-1.9/related_article.json | 44 +++++++++---------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/packtools/sps/sps_versions/sps-1.10/related_article.json b/packtools/sps/sps_versions/sps-1.10/related_article.json index f39e8cdad..f938f3105 100644 --- a/packtools/sps/sps_versions/sps-1.10/related_article.json +++ b/packtools/sps/sps_versions/sps-1.10/related_article.json @@ -2,26 +2,26 @@ "_comment": "List of possible correspondences between article type and related article types", "source": "SciELO. Guia para o registro, marcação e publicação de retratação [online]. SciELO,\n2023 [cited 10 July 2024]. Available from: \nhttps://wp.scielo.org/wp-content/uploads/guia_retratacao.pdf \nhttps://wp.scielo.org/wp-content/uploads/guia_errata.pdf \nhttps://wp.scielo.org/wp-content/uploads/guia_adendo.pdf", "sps_version": "sps-1.10", - "correspondence_list": [ - { - "article-type": "research-article", - "related-article-types": ["retraction-forward", "partial-retraction", "correction-forward", "addendum"] - }, - { - "article-type": "retraction", - "related-article-types": ["retracted-article", "retraction-forward"] - }, - { - "article-type": "partial-retraction", - "related-article-types": ["retracted-article", "partial-retraction"] - }, - { - "article-type": "correction", - "related-article-types": ["corrected-article"] - }, - { - "article-type": "addendum", - "related-article-types": ["article"] - } - ] + "correspondence_dict": { + "research-article": [ + "retraction-forward", + "partial-retraction", + "correction-forward", + "addendum" + ], + "retraction": [ + "retracted-article", + "retraction-forward" + ], + "partial-retraction": [ + "retracted-article", + "partial-retraction" + ], + "correction": [ + "corrected-article" + ], + "addendum": [ + "article" + ] + } } diff --git a/packtools/sps/sps_versions/sps-1.9/related_article.json b/packtools/sps/sps_versions/sps-1.9/related_article.json index f39e8cdad..f938f3105 100644 --- a/packtools/sps/sps_versions/sps-1.9/related_article.json +++ b/packtools/sps/sps_versions/sps-1.9/related_article.json @@ -2,26 +2,26 @@ "_comment": "List of possible correspondences between article type and related article types", "source": "SciELO. Guia para o registro, marcação e publicação de retratação [online]. SciELO,\n2023 [cited 10 July 2024]. Available from: \nhttps://wp.scielo.org/wp-content/uploads/guia_retratacao.pdf \nhttps://wp.scielo.org/wp-content/uploads/guia_errata.pdf \nhttps://wp.scielo.org/wp-content/uploads/guia_adendo.pdf", "sps_version": "sps-1.10", - "correspondence_list": [ - { - "article-type": "research-article", - "related-article-types": ["retraction-forward", "partial-retraction", "correction-forward", "addendum"] - }, - { - "article-type": "retraction", - "related-article-types": ["retracted-article", "retraction-forward"] - }, - { - "article-type": "partial-retraction", - "related-article-types": ["retracted-article", "partial-retraction"] - }, - { - "article-type": "correction", - "related-article-types": ["corrected-article"] - }, - { - "article-type": "addendum", - "related-article-types": ["article"] - } - ] + "correspondence_dict": { + "research-article": [ + "retraction-forward", + "partial-retraction", + "correction-forward", + "addendum" + ], + "retraction": [ + "retracted-article", + "retraction-forward" + ], + "partial-retraction": [ + "retracted-article", + "partial-retraction" + ], + "correction": [ + "corrected-article" + ], + "addendum": [ + "article" + ] + } } From 14f341f0eb05ade60e0212269629e80ecb120950 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:22:23 -0300 Subject: [PATCH 20/36] Adiciona 'related_article_type_date_type.json' --- .../sps-1.10/related_article_type_date_type.json | 6 ++++++ .../sps-1.9/related_article_type_date_type.json | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 packtools/sps/sps_versions/sps-1.10/related_article_type_date_type.json create mode 100644 packtools/sps/sps_versions/sps-1.9/related_article_type_date_type.json diff --git a/packtools/sps/sps_versions/sps-1.10/related_article_type_date_type.json b/packtools/sps/sps_versions/sps-1.10/related_article_type_date_type.json new file mode 100644 index 000000000..2e858545a --- /dev/null +++ b/packtools/sps/sps_versions/sps-1.10/related_article_type_date_type.json @@ -0,0 +1,6 @@ +{ + "sps_version": "sps-1.10", + "corrected-article": "corrected", + "retraction-forward": "retracted", + "partial-retraction": "retracted" +} diff --git a/packtools/sps/sps_versions/sps-1.9/related_article_type_date_type.json b/packtools/sps/sps_versions/sps-1.9/related_article_type_date_type.json new file mode 100644 index 000000000..46a59d791 --- /dev/null +++ b/packtools/sps/sps_versions/sps-1.9/related_article_type_date_type.json @@ -0,0 +1,6 @@ +{ + "sps_version": "sps-1.9", + "corrected-article": "corrected", + "retraction-forward": "retracted", + "partial-retraction": "retracted" +} From 619c161ab598af96e5d35b7e52c38da16fc2ec61 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:24:10 -0300 Subject: [PATCH 21/36] Renomeia classe --- packtools/sps/models/v2/related_articles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packtools/sps/models/v2/related_articles.py b/packtools/sps/models/v2/related_articles.py index aa2cafec0..c4d877b2e 100644 --- a/packtools/sps/models/v2/related_articles.py +++ b/packtools/sps/models/v2/related_articles.py @@ -30,7 +30,7 @@ def data(self): } -class RelatedArticlesByNode: +class RelatedArticlesParent: def __init__(self, node): self.node = node self.parent = self.node.tag From acfb059cdc011933e2115fc9f02c63decd9e6b12 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:24:46 -0300 Subject: [PATCH 22/36] Adiciona 'remove_namespaces()' --- packtools/sps/models/v2/related_articles.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packtools/sps/models/v2/related_articles.py b/packtools/sps/models/v2/related_articles.py index c4d877b2e..047b6101e 100644 --- a/packtools/sps/models/v2/related_articles.py +++ b/packtools/sps/models/v2/related_articles.py @@ -8,7 +8,17 @@ """ -from packtools.sps.utils.xml_utils import put_parent_context, process_subtags +from packtools.sps.utils.xml_utils import put_parent_context, process_subtags, tostring + + +def remove_namespaces(xml_string): + namespaces_to_remove = [ + 'xmlns:xlink="http://www.w3.org/1999/xlink"', + 'xmlns:mml="http://www.w3.org/1998/Math/MathML"', + ] + for ns in namespaces_to_remove: + xml_string = xml_string.replace(ns + " ", "") + return xml_string class RelatedArticle: From 6f6b968e37d6b74457d84b7c65ec038f623567a7 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:25:11 -0300 Subject: [PATCH 23/36] =?UTF-8?q?Aplica=20formata=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/models/v2/related_articles.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packtools/sps/models/v2/related_articles.py b/packtools/sps/models/v2/related_articles.py index 047b6101e..fd4fcc62c 100644 --- a/packtools/sps/models/v2/related_articles.py +++ b/packtools/sps/models/v2/related_articles.py @@ -25,7 +25,9 @@ class RelatedArticle: def __init__(self, related_article_node): self.related_article_node = related_article_node self.ext_link_type = self.related_article_node.get("ext-link-type") - self.related_article_type = self.related_article_node.get("related-article-type") + self.related_article_type = self.related_article_node.get( + "related-article-type" + ) self.id = self.related_article_node.get("id") self.href = self.related_article_node.get("{http://www.w3.org/1999/xlink}href") self.text = process_subtags(self.related_article_node) @@ -36,7 +38,10 @@ def data(self): "id": self.id, "related-article-type": self.related_article_type, "href": self.href, - "text": self.text + "text": self.text, + "full_tag": remove_namespaces( + tostring(self.related_article_node, xml_declaration=False) + ), } @@ -68,11 +73,15 @@ def __init__(self, xml_tree, related_article_type=None): self.related_article_type = related_article_type def article(self): - yield from RelatedArticlesByNode(self.xml_tree.find(".")).related_articles(self.related_article_type) + yield from RelatedArticlesParent(self.xml_tree.find(".")).related_articles( + self.related_article_type + ) def sub_articles(self): for sub_article in self.xml_tree.xpath(".//sub-article"): - yield from RelatedArticlesByNode(sub_article).related_articles(self.related_article_type) + yield from RelatedArticlesParent(sub_article).related_articles( + self.related_article_type + ) def related_articles(self): yield from self.article() From cfac0fa17e4a01d70f91f75c1db743abf580703e Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:27:28 -0300 Subject: [PATCH 24/36] Adiciona 'full_tag' --- tests/sps/models/v2/test_related_articles.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/sps/models/v2/test_related_articles.py b/tests/sps/models/v2/test_related_articles.py index 0706c7136..bdf210b1c 100644 --- a/tests/sps/models/v2/test_related_articles.py +++ b/tests/sps/models/v2/test_related_articles.py @@ -99,6 +99,8 @@ def test_article(self): 'parent_lang': 'pt', 'related-article-type': 'corrected-article', 'text': '' + "full_tag": '', }, { 'ext-link-type': 'doi', @@ -110,6 +112,8 @@ def test_article(self): 'parent_lang': 'pt', 'related-article-type': 'corrected-article', 'text': '' + "full_tag": '', }, ] @@ -130,6 +134,8 @@ def test_sub_articles(self): 'parent_lang': 'en', 'related-article-type': 'corrected-article', 'text': '' + "full_tag": '', }, { 'ext-link-type': 'doi', @@ -141,6 +147,8 @@ def test_sub_articles(self): 'parent_lang': 'en', 'related-article-type': 'corrected-article', 'text': '' + "full_tag": '', }, ] @@ -177,6 +185,8 @@ def test_related_articles_by_related_article_type(self): 'parent_lang': 'pt', 'related-article-type': 'commentary-article', 'text': '' + "full_tag": '', }, ] From 626fdd3628e617bfa6f7641e518ac8baf3a72710 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:28:01 -0300 Subject: [PATCH 25/36] =?UTF-8?q?Aplica=20formata=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/sps/models/v2/test_related_articles.py | 151 ++++++++++++------- 1 file changed, 94 insertions(+), 57 deletions(-) diff --git a/tests/sps/models/v2/test_related_articles.py b/tests/sps/models/v2/test_related_articles.py index bdf210b1c..5f5e6bf5a 100644 --- a/tests/sps/models/v2/test_related_articles.py +++ b/tests/sps/models/v2/test_related_articles.py @@ -11,11 +11,16 @@ from unittest import TestCase from packtools.sps.utils import xml_utils -from packtools.sps.models.v2.related_articles import RelatedArticle, RelatedArticlesByNode, RelatedArticles +from packtools.sps.models.v2.related_articles import ( + RelatedArticle, + RelatedArticlesParent, + RelatedArticles, +) class RelatedArticleTest(TestCase): def test_related_article(self): + self.maxDiff = None xml = """
@@ -29,21 +34,35 @@ def test_related_article(self):
""" - obtained = RelatedArticle(xml_utils.get_xml_tree(xml).xpath(".//related-article")[0]).data() + obtained = RelatedArticle( + xml_utils.get_xml_tree(xml).xpath(".//related-article")[0] + ).data() expected = { "ext-link-type": "doi", "id": "A01", "related-article-type": "commentary-article", "href": "10.1590/0101-3173.2022.v45n1.p139", "text": "Referência do artigo comentado: FREITAS, J. H. de. Cinismo e indiferenciación: la huella de " - "Glucksmann en El coraje de la verdad de Foucault. Trans/form/ação : revista de Filosofia " - "da Unesp, v. 45, n. 1, p. 139-158, 2022." + "Glucksmann en El coraje de la verdad de Foucault. Trans/form/ação : revista de Filosofia " + "da Unesp, v. 45, n. 1, p. 139-158, 2022.", + "full_tag": '\n' + " Referência do artigo comentado: FREITAS, J. H. " + "de. Cinismo e indiferenciación: la huella de Glucksmann en\n" + " El coraje de la verdad\n" + " de Foucault.\n" + " Trans/form/ação\n" + " : revista de Filosofia da Unesp, v. 45, n. 1, p. " + "139-158, 2022.\n" + " ", } self.assertDictEqual(obtained, expected) class RelatedArticlesByNodeTest(TestCase): def test_related_articles(self): + self.maxDiff = None xml = """
@@ -60,7 +79,11 @@ def test_related_articles(self):
""" - obtained = list(RelatedArticlesByNode(xml_utils.get_xml_tree(xml).find(".")).related_articles()) + obtained = list( + RelatedArticlesParent( + xml_utils.get_xml_tree(xml).find(".") + ).related_articles() + ) expected = [ { "parent": "article", @@ -72,8 +95,19 @@ def test_related_articles(self): "related-article-type": "commentary-article", "href": "10.1590/0101-3173.2022.v45n1.p139", "text": "Referência do artigo comentado: FREITAS, J. H. de. Cinismo e indiferenciación: la huella de " - "Glucksmann en El coraje de la verdad de Foucault. Trans/form/ação : revista de Filosofia " - "da Unesp, v. 45, n. 1, p. 139-158, 2022." + "Glucksmann en El coraje de la verdad de Foucault. Trans/form/ação : revista de Filosofia " + "da Unesp, v. 45, n. 1, p. 139-158, 2022.", + "full_tag": '\n' + " Referência do artigo comentado: FREITAS, J. H. de. " + "Cinismo e indiferenciación: la huella de Glucksmann en\n" + " El coraje de la verdad\n" + " de Foucault.\n" + " Trans/form/ação\n" + " : revista de Filosofia da Unesp, v. 45, n. 1, p. " + "139-158, 2022.\n" + " ", } ] self.assertEqual(len(obtained), 1) @@ -84,38 +118,39 @@ def test_related_articles(self): class RelatedArticlesTest(TestCase): def setUp(self): - self.xml_tree = xml_utils.get_xml_tree("tests/fixtures/htmlgenerator/related-article/varias_erratas.xml") + self.xml_tree = xml_utils.get_xml_tree( + "tests/fixtures/htmlgenerator/related-article/varias_erratas.xml" + ) def test_article(self): obtained = list(RelatedArticles(self.xml_tree).article()) expected = [ { - 'ext-link-type': 'doi', - 'href': '10.1590/s1413-65382620000100001', - 'id': 'RA1', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'pt', - 'related-article-type': 'corrected-article', - 'text': '' + "ext-link-type": "doi", + "href": "10.1590/s1413-65382620000100001", + "id": "RA1", + "parent": "article", + "parent_article_type": "correction", + "parent_id": None, + "parent_lang": "pt", + "related-article-type": "corrected-article", + "text": "", "full_tag": '', }, { - 'ext-link-type': 'doi', - 'href': '10.1590/s1413-65382620000100009', - 'id': 'RA9', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'pt', - 'related-article-type': 'corrected-article', - 'text': '' + "ext-link-type": "doi", + "href": "10.1590/s1413-65382620000100009", + "id": "RA9", + "parent": "article", + "parent_article_type": "correction", + "parent_id": None, + "parent_lang": "pt", + "related-article-type": "corrected-article", + "text": "", "full_tag": '', }, - ] self.assertEqual(len(obtained), 9) self.assertDictEqual(obtained[0], expected[0]) @@ -125,32 +160,31 @@ def test_sub_articles(self): obtained = list(RelatedArticles(self.xml_tree).sub_articles()) expected = [ { - 'ext-link-type': 'doi', - 'href': '10.1590/s1413-65382620000100001', - 'id': 'RA10', - 'parent': 'sub-article', - 'parent_article_type': 'translation', - 'parent_id': "s1", - 'parent_lang': 'en', - 'related-article-type': 'corrected-article', - 'text': '' + "ext-link-type": "doi", + "href": "10.1590/s1413-65382620000100001", + "id": "RA10", + "parent": "sub-article", + "parent_article_type": "translation", + "parent_id": "s1", + "parent_lang": "en", + "related-article-type": "corrected-article", + "text": "", "full_tag": '', }, { - 'ext-link-type': 'doi', - 'href': '10.1590/s1413-65382620000100009', - 'id': 'RA18', - 'parent': 'sub-article', - 'parent_article_type': 'translation', - 'parent_id': "s1", - 'parent_lang': 'en', - 'related-article-type': 'corrected-article', - 'text': '' + "ext-link-type": "doi", + "href": "10.1590/s1413-65382620000100009", + "id": "RA18", + "parent": "sub-article", + "parent_article_type": "translation", + "parent_id": "s1", + "parent_lang": "en", + "related-article-type": "corrected-article", + "text": "", "full_tag": '', }, - ] self.assertEqual(len(obtained), 9) self.assertDictEqual(obtained[0], expected[0]) @@ -173,22 +207,25 @@ def test_related_articles_by_related_article_type(self):
""" - obtained = list(RelatedArticles(xml_utils.get_xml_tree(xml), related_article_type="commentary-article").related_articles()) + obtained = list( + RelatedArticles( + xml_utils.get_xml_tree(xml), related_article_type="commentary-article" + ).related_articles() + ) expected = [ { - 'ext-link-type': 'doi', - 'href': '10.1590/0101-3173.2022.v45n1.p139', - 'id': 'A01', - 'parent': 'article', - 'parent_article_type': 'article-commentary', - 'parent_id': None, - 'parent_lang': 'pt', - 'related-article-type': 'commentary-article', - 'text': '' + "ext-link-type": "doi", + "href": "10.1590/0101-3173.2022.v45n1.p139", + "id": "A01", + "parent": "article", + "parent_article_type": "article-commentary", + "parent_id": None, + "parent_lang": "pt", + "related-article-type": "commentary-article", + "text": "", "full_tag": '', }, - ] self.assertEqual(len(obtained), 1) self.assertDictEqual(obtained[0], expected[0]) From df03ab37cafcc8023ab8fa2d8b421a93c35c2cca Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:28:29 -0300 Subject: [PATCH 26/36] =?UTF-8?q?Corrige=20importa=C3=A7=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/related_articles.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index f9ff63a60..c0873da51 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -1,6 +1,7 @@ -from packtools.sps.models.v2.related_articles import RelatedArticles -from packtools.sps.models import article_and_subarticles, article_dates +import re +from packtools.sps.models.v2.related_articles import RelatedArticles +from packtools.sps.models import article_dates from packtools.sps.validation.exceptions import ValidationRelatedArticleException from packtools.sps.validation.utils import format_response From f9191848dbde4679626d01b4080c773853f6376a Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:31:14 -0300 Subject: [PATCH 27/36] Corrige e adiciona 'docstring' --- packtools/sps/validation/related_articles.py | 158 ++++++++++++------- 1 file changed, 103 insertions(+), 55 deletions(-) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index c0873da51..22015178e 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -7,6 +7,11 @@ class RelatedArticlesValidation: + """ + Class to validate related articles in an XML tree, ensuring the article type matches + predefined correspondence rules and other criteria like DOI presence and attribute order. + """ + def __init__(self, xml_tree): self.related_articles = list(RelatedArticles(xml_tree).related_articles()) self.article_type = article_and_subarticles.ArticleAndSubArticles(xml_tree).main_article_type @@ -14,45 +19,39 @@ def __init__(self, xml_tree): def related_articles_matches_article_type_validation(self, correspondence_list=None, error_level="ERROR"): """ - Check whether the article type attribute of the article matches the options provided in a standard list. + Validate related articles in the XML tree against correspondence rules for article types. - XML input - --------- -
- -
+ Parameters + ---------- + correspondence_dict : dict + Dictionary mapping article types to valid related article types, like: + "correspondence_dict": { + "research-article": ["retraction-forward", "partial-retraction", "correction-forward", "addendum"], + "retraction": ["retracted-article", "retraction-forward"], + "partial-retraction": ["retracted-article", "partial-retraction"], + "correction": ["corrected-article"], + "addendum": ["article"] + } + absence_error_level : str, optional + Error level when related-article is missing (default is "ERROR"). + match_error_level : str, optional + Error level when related-article type does not match expected type (default is "ERROR"). + doi_error_level : str, optional + Error level for DOI validation (default is "ERROR"). + order_error_level : str, optional + Error level for attribute order validation (default is "ERROR"). + date_error_level : str, optional + Error level for date validation (default is "ERROR"). - Params + Yields ------ - correspondence_list : list of dict, such as: - [ - { - 'article-type': 'correction', - 'related-article-types': ['corrected-article'] - }, - { - 'article-type': 'retraction', - 'related-article-types': ['retracted-article'] - }, ... - ] + dict + A validation response for each check performed. - Returns - ------- - list of dict - A list of dictionaries, such as: - [ - { - 'title': 'Related article type validation', - 'xpath': './article[@article-type] .//related-article[@related-article-type]', - 'validation_type': 'match', - 'response': 'OK', - 'expected_value': ['corrected-article'], - 'got_value': 'corrected-article', - 'message': 'Got corrected-article, expected one of the following items: ['corrected-article'], - 'advice': None - }, ... - ] + Raises + ------ + ValidationRelatedArticleException + If the correspondence_dict is not provided. """ if not correspondence_list: raise ValidationRelatedArticleException("Function requires a list of dictionary with article type and related article types") @@ -87,32 +86,81 @@ def related_articles_matches_article_type_validation(self, correspondence_list=N ) def related_articles_doi(self, error_level="ERROR"): + """ + Class to validate individual related article elements within the XML structure. + """ + """ + Initialize the RelatedArticleValidation class. + + Parameters + ---------- + related_article_dict : dict + Dictionary representing the attributes of a related article element in the XML, like: + { + 'ext-link-type': 'doi', + 'href': '10.1590/s1413-65382620000100001', + 'id': 'RA1', + 'parent': 'article', + 'parent_article_type': 'correction', + 'parent_id': None, + 'parent_lang': 'pt', + 'related-article-type': 'corrected-article', + 'text': '', + 'full_tag': '', + } + """ + """ - Checks if there is a DOI for related articles. + Validate that the related-article type matches the expected types based on the article type. - XML input - --------- -
- -
+ Parameters + ---------- + expected_related_article_types : list of str, optional + A list of valid related-article types. + error_level : str, optional + The error level for the validation (default is "ERROR"). Returns ------- - list of dict - A list of dictionaries, such as: - [ - { - 'title': 'Related article doi validation', - 'xpath': './/related-article/@xLink:href', - 'validation_type': 'exist', - 'response': 'OK', - 'expected_value': '10.1590/1808-057x202090350', - 'got_value': '10.1590/1808-057x202090350', - 'message': 'Got 10.1590/1808-057x202090350, expected 10.1590/1808-057x202090350', - 'advice': None + dict + Validation response indicating whether the related-article type matches the expected types. + + Raises + ------ + ValidationRelatedArticleException + If the expected_related_article_types is not provided. + """ + """ + Validate that the expected history date type exists within the related-article history events. + + Parameters + ---------- + expected_date_type : str + The expected date type (e.g., 'received', 'accepted'). + history_events : dict + Dictionary of historical events and their associated dates, like: + { + "accepted": { + "day": "06", + "month": "06", + "type": "accepted", + "year": "1998", + }, + "corrected": { + "day": "01", + "month": "06", + "type": "corrected", + "year": "2012", },... - ] + } + error_level : str, optional + The error level for the validation (default is "ERROR"). + + Returns + ------- + dict or None + Validation response indicating whether the expected date type is present, or None if not applicable. """ for related_article in self.related_articles: From c1a45b2d6020439ad51021bba680b89cf4e6d8d3 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:34:03 -0300 Subject: [PATCH 28/36] =?UTF-8?q?Remove=20valida=C3=A7=C3=A3o=20de=20atrib?= =?UTF-8?q?utos=20(substitu=C3=ADda=20pela=20valida=C3=A7=C3=A3o=20de=20or?= =?UTF-8?q?dem)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/related_articles.py | 21 -------------------- 1 file changed, 21 deletions(-) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index 22015178e..9b996e4ac 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -184,24 +184,3 @@ def related_articles_doi(self, error_level="ERROR"): data=related_article, error_level=error_level ) - - def related_article_attributes_validation(self, error_level="ERROR"): - for related_article in self.related_articles: - for attrib in ("related-article-type", "id", "href", "ext-link-type"): - if not related_article[attrib]: - yield format_response( - title='Related article attributes validation', - parent=related_article.get("parent"), - parent_id=related_article.get("parent_id"), - parent_article_type=related_article.get("parent_article_type"), - parent_lang=related_article.get("parent_lang"), - item='related-article', - sub_item=f'@{attrib}', - validation_type='exist', - is_valid=False, - expected=f"a value for @{attrib}", - obtained=None, - advice=f"Provide a value for @{attrib}", - data=related_article, - error_level=error_level - ) From 2d946ec48e25942183aea3c1ef9b2d776500558f Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:35:43 -0300 Subject: [PATCH 29/36] Adiciona 'validate_history_date' --- packtools/sps/validation/related_articles.py | 46 +++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index 9b996e4ac..9715a9c48 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -131,6 +131,10 @@ def related_articles_doi(self, error_level="ERROR"): ValidationRelatedArticleException If the expected_related_article_types is not provided. """ + + def validate_history_date( + self, expected_date_type, history_events, error_level="ERROR" + ): """ Validate that the expected history date type exists within the related-article history events. @@ -162,25 +166,25 @@ def related_articles_doi(self, error_level="ERROR"): dict or None Validation response indicating whether the expected date type is present, or None if not applicable. """ - - for related_article in self.related_articles: - doi = related_article.get('href') - is_valid = doi is not None - expected_value = doi if doi else 'A valid DOI or URI for related-article/@xlink:href' - yield format_response( - title='Related article doi validation', - parent=related_article.get("parent"), - parent_id=related_article.get("parent_id"), - parent_article_type=related_article.get("parent_article_type"), - parent_lang=related_article.get("parent_lang"), - item='related-article', - sub_item='xlink:href', - validation_type='exist', - is_valid=is_valid, - expected=expected_value, - obtained=doi, - advice=f'Provide a valid DOI for ', - data=related_article, - error_level=error_level + if not expected_date_type: + return + + if expected_date_type not in history_events: + return format_response( + title="history date", + parent=self.related_article_dict.get("parent"), + parent_id=self.related_article_dict.get("parent_id"), + parent_article_type=self.related_article_dict.get( + "parent_article_type" + ), + parent_lang=self.related_article_dict.get("parent_lang"), + item="related-article / date", + sub_item=f'@related-article-type={self.related_article_dict.get("related-article-type")} / @date-type={expected_date_type}', + validation_type="exist", + is_valid=False, + expected=expected_date_type, + obtained=history_events, + advice=f"Provide the publication date of the {expected_date_type}", + data=history_events, + error_level=error_level, ) From fdc7e896958f3dc9f6ad0df93a70a70128c9c422 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:36:27 -0300 Subject: [PATCH 30/36] =?UTF-8?q?Adiciona=20valida=C3=A7=C3=A3o=20de=20ord?= =?UTF-8?q?em=20dos=20atributos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/related_articles.py | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index 9715a9c48..9595ac5e7 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -132,6 +132,30 @@ def related_articles_doi(self, error_level="ERROR"): If the expected_related_article_types is not provided. """ + def validate_attrib_order_in_related_article_tag(self, error_level="ERROR"): + pattern = r'' + full_tag = self.related_article_dict.get("full_tag") + + if not re.match(pattern, full_tag): + return format_response( + title="attrib order in related article tag", + parent=self.related_article_dict.get("parent"), + parent_id=self.related_article_dict.get("parent_id"), + parent_article_type=self.related_article_dict.get( + "parent_article_type" + ), + parent_lang=self.related_article_dict.get("parent_lang"), + item="related-article", + sub_item=None, + validation_type="match", + is_valid=False, + expected='', + obtained=full_tag, + advice="Provide the attributes in the specified order", + data=self.related_article_dict, + error_level=error_level, + ) + def validate_history_date( self, expected_date_type, history_events, error_level="ERROR" ): From 3d347e65abc4ffbb60d72318b027d300be2646b2 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:36:48 -0300 Subject: [PATCH 31/36] =?UTF-8?q?Adiciona=20valida=C3=A7=C3=A3o=20de=20DOI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/related_articles.py | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index 9595ac5e7..6c8a66c6c 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -132,6 +132,30 @@ def related_articles_doi(self, error_level="ERROR"): If the expected_related_article_types is not provided. """ + def validate_related_article_doi(self, error_level="ERROR"): + doi = self.related_article_dict.get("href") + is_valid = doi is not None + expected_value = ( + doi if doi else "A valid DOI or URI for related-article/@xlink:href" + ) + return format_response( + title="Related article doi validation", + parent=self.related_article_dict.get("parent"), + parent_id=self.related_article_dict.get("parent_id"), + parent_article_type=self.related_article_dict.get("parent_article_type"), + parent_lang=self.related_article_dict.get("parent_lang"), + item="related-article", + sub_item="xlink:href", + validation_type="exist", + is_valid=is_valid, + expected=expected_value, + obtained=doi, + advice=f'Provide a valid DOI for ', + data=self.related_article_dict, + error_level=error_level, + ) + def validate_attrib_order_in_related_article_tag(self, error_level="ERROR"): pattern = r'' full_tag = self.related_article_dict.get("full_tag") From 4d373d3d23e021ceab0a0ada374709331fa35b16 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:38:28 -0300 Subject: [PATCH 32/36] Adiciona 'validate' --- packtools/sps/validation/related_articles.py | 93 +++++++++++++------- 1 file changed, 59 insertions(+), 34 deletions(-) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index 6c8a66c6c..b6097200c 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -13,11 +13,18 @@ class RelatedArticlesValidation: """ def __init__(self, xml_tree): + self.xml_tree = xml_tree self.related_articles = list(RelatedArticles(xml_tree).related_articles()) - self.article_type = article_and_subarticles.ArticleAndSubArticles(xml_tree).main_article_type - self.history_events = list(article_dates.ArticleDates(xml_tree).history_dates_dict) - def related_articles_matches_article_type_validation(self, correspondence_list=None, error_level="ERROR"): + def validate( + self, + correspondence_dict=None, + absence_error_level="ERROR", + match_error_level="ERROR", + doi_error_level="ERROR", + order_error_level="ERROR", + date_error_level="ERROR", + ): """ Validate related articles in the XML tree against correspondence rules for article types. @@ -53,39 +60,57 @@ def related_articles_matches_article_type_validation(self, correspondence_list=N ValidationRelatedArticleException If the correspondence_dict is not provided. """ - if not correspondence_list: - raise ValidationRelatedArticleException("Function requires a list of dictionary with article type and related article types") - - expected_values_for_related_article_type = None - for item in correspondence_list: - if isinstance(item, dict) and item.get('article-type') == self.article_type: - expected_values_for_related_article_type = item['related-article-types'] - break + if not correspondence_dict: + raise ValidationRelatedArticleException( + "Function requires a dictionary with article type and related article types" + ) - if expected_values_for_related_article_type: + if not self.related_articles: + parent_article_type = self.xml_tree.get("article-type") + yield format_response( + title="Related article type validation", + parent="article", + parent_id=None, + parent_article_type=parent_article_type, + parent_lang=self.xml_tree.get( + "{http://www.w3.org/XML/1998/namespace}lang" + ), + item="related-article", + sub_item="related-article-type", + validation_type="match", + is_valid=False, + expected=correspondence_dict[parent_article_type], + obtained=self.related_articles, + advice=f"The article-type: {parent_article_type} does not match the related-article-type: " + f"{correspondence_dict[parent_article_type]}, provide one of the following items: " + f"{correspondence_dict[parent_article_type]}", + data=None, + error_level=absence_error_level, + ) + else: + history_events = article_dates.HistoryDates(self.xml_tree).history_dates() for related_article in self.related_articles: - obtained_related_article = related_article.get('related-article-type') - is_valid = obtained_related_article in expected_values_for_related_article_type - yield format_response( - title='Related article type validation', - parent=related_article.get("parent"), - parent_id=related_article.get("parent_id"), - parent_article_type=related_article.get("parent_article_type"), - parent_lang=related_article.get("parent_lang"), - item='related-article', - sub_item='related-article-type', - validation_type='match', - is_valid=is_valid, - expected=expected_values_for_related_article_type, - obtained=obtained_related_article, - advice=f"The article-type: {self.article_type} does not match the related-article-type: " - f"{obtained_related_article}, provide one of the following items: " - f"{expected_values_for_related_article_type}", - data=related_article, - error_level=error_level - ) - - def related_articles_doi(self, error_level="ERROR"): + related_article_validation = RelatedArticleValidation(related_article) + if related_article_types := correspondence_dict.get( + related_article.get("parent_article_type") + ): + yield related_article_validation.validate_related_article_matches_article_type( + expected_related_article_types=related_article_types, + error_level=match_error_level, + ) + yield related_article_validation.validate_related_article_doi( + error_level=doi_error_level + ) + yield related_article_validation.validate_attrib_order_in_related_article_tag( + error_level=order_error_level + ) + yield related_article_validation.validate_history_date( + expected_date_type=None, + history_events=history_events, + error_level=date_error_level, + ) + + """ Class to validate individual related article elements within the XML structure. """ From 47c459834328ca93d26ecb57d34f692c8c900635 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:39:10 -0300 Subject: [PATCH 33/36] Adiciona 'validate_related_article_matches_article_type' --- packtools/sps/validation/related_articles.py | 32 ++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packtools/sps/validation/related_articles.py b/packtools/sps/validation/related_articles.py index b6097200c..1ce4abb79 100644 --- a/packtools/sps/validation/related_articles.py +++ b/packtools/sps/validation/related_articles.py @@ -111,9 +111,12 @@ def validate( ) +class RelatedArticleValidation: """ Class to validate individual related article elements within the XML structure. """ + + def __init__(self, related_article_dict): """ Initialize the RelatedArticleValidation class. @@ -135,7 +138,11 @@ def validate( 'xlink:href="10.1590/s1413-65382620000100001"/>', } """ + self.related_article_dict = related_article_dict + def validate_related_article_matches_article_type( + self, expected_related_article_types=None, error_level="ERROR" + ): """ Validate that the related-article type matches the expected types based on the article type. @@ -156,6 +163,31 @@ def validate( ValidationRelatedArticleException If the expected_related_article_types is not provided. """ + if not expected_related_article_types: + raise ValidationRelatedArticleException( + "Function requires a list of expected related article types" + ) + + obtained_related_article = self.related_article_dict.get("related-article-type") + is_valid = obtained_related_article in expected_related_article_types + return format_response( + title="Related article type validation", + parent=self.related_article_dict.get("parent"), + parent_id=self.related_article_dict.get("parent_id"), + parent_article_type=self.related_article_dict.get("parent_article_type"), + parent_lang=self.related_article_dict.get("parent_lang"), + item="related-article", + sub_item="related-article-type", + validation_type="match", + is_valid=is_valid, + expected=expected_related_article_types, + obtained=obtained_related_article, + advice=f"The article-type: {self.related_article_dict.get('parent_article_type')} does not match the related-article-type: " + f"{obtained_related_article}, provide one of the following items: " + f"{expected_related_article_types}", + data=self.related_article_dict, + error_level=error_level, + ) def validate_related_article_doi(self, error_level="ERROR"): doi = self.related_article_dict.get("href") From cbb03fe4ab2231e39a06313b7f21719542f34146 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:39:47 -0300 Subject: [PATCH 34/36] Adapta testes de artigos relacionados --- tests/sps/validation/test_related_articles.py | 457 ++++++++---------- 1 file changed, 195 insertions(+), 262 deletions(-) diff --git a/tests/sps/validation/test_related_articles.py b/tests/sps/validation/test_related_articles.py index c96e3e173..cc78d2b95 100644 --- a/tests/sps/validation/test_related_articles.py +++ b/tests/sps/validation/test_related_articles.py @@ -2,185 +2,169 @@ from lxml import etree -from packtools.sps.validation.related_articles import RelatedArticlesValidation +from packtools.sps.validation.related_articles import RelatedArticleValidation +from packtools.sps.models.v2.related_articles import RelatedArticles -class RelatedArticlesValidationTest(unittest.TestCase): +class RelatedArticleValidationTest(unittest.TestCase): - def test_related_articles_matches_article_type_validation_match(self): + def test_related_article_matches_article_type_validation_match(self): self.maxDiff = None xmltree = etree.fromstring( """
- - + + -
""" ) - obtained = list(RelatedArticlesValidation(xmltree).related_articles_matches_article_type_validation( - [ - { - 'article-type': 'correction', - 'related-article-types': ['corrected-article'] - }, - { - 'article-type': 'retraction', - 'related-article-types': ['retracted-article'] - } - ] - )) + related_article_dict = list(RelatedArticles(xmltree).related_articles())[0] + obtained = RelatedArticleValidation( + related_article_dict + ).validate_related_article_matches_article_type( + expected_related_article_types=["corrected-article"] + ) - expected = [ - { - 'title': 'Related article type validation', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'item': 'related-article', - 'sub_item': 'related-article-type', - 'validation_type': 'match', - 'response': 'OK', - 'expected_value': ['corrected-article'], - 'got_value': 'corrected-article', - 'message': "Got corrected-article, expected ['corrected-article']", - 'advice': None, - 'data': { - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'ext-link-type': 'doi', - 'href': '10.1590/1808-057x202090350', - 'id': 'ra1', - 'related-article-type': 'corrected-article', - 'text': '' - } - } - ] - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(obtained[i], item) + expected = { + "title": "Related article type validation", + "parent": "article", + "parent_article_type": "correction", + "parent_id": None, + "parent_lang": "en", + "item": "related-article", + "sub_item": "related-article-type", + "validation_type": "match", + "response": "OK", + "expected_value": ["corrected-article"], + "got_value": "corrected-article", + "message": "Got corrected-article, expected ['corrected-article']", + "advice": None, + "data": { + "parent": "article", + "parent_article_type": "correction", + "parent_id": None, + "parent_lang": "en", + "ext-link-type": "doi", + "href": "10.1590/1808-057x202090350", + "id": "ra1", + "related-article-type": "corrected-article", + "text": "", + "full_tag": '', + }, + } + + self.assertDictEqual(obtained, expected) - def test_related_articles_matches_article_type_validation_not_match(self): + def test_related_article_matches_article_type_validation_not_match(self): self.maxDiff = None xmltree = etree.fromstring( """
- - + + -
""" ) - obtained = list(RelatedArticlesValidation(xmltree).related_articles_matches_article_type_validation( - [ - { - 'article-type': 'correction', - 'related-article-types': ['corrected-article'] - }, - { - 'article-type': 'retraction', - 'related-article-types': ['retracted-article', 'article-retracted'] - } - ] - )) + related_article_dict = list(RelatedArticles(xmltree).related_articles())[0] + obtained = RelatedArticleValidation( + related_article_dict + ).validate_related_article_matches_article_type( + expected_related_article_types=["retracted-article", "article-retracted"] + ) - expected = [ - { - 'title': 'Related article type validation', - 'parent': 'article', - 'parent_article_type': 'retraction', - 'parent_id': None, - 'parent_lang': 'en', - 'item': 'related-article', - 'sub_item': 'related-article-type', - 'validation_type': 'match', - 'response': 'ERROR', - 'expected_value': ['retracted-article', 'article-retracted'], - 'got_value': 'retraction-forward', - 'message': "Got retraction-forward, expected ['retracted-article', 'article-retracted']", - 'advice': "The article-type: retraction does not match the related-article-type: retraction-forward, " - "provide one of the following items: ['retracted-article', 'article-retracted']", - 'data': { - 'parent': 'article', - 'parent_article_type': 'retraction', - 'parent_id': None, - 'parent_lang': 'en', - 'ext-link-type': 'doi', - 'href': '10.1590/1808-057x202090350', - 'id': 'ra1', - 'related-article-type': 'retraction-forward', - 'text': '' - } - } - ] + expected = { + "title": "Related article type validation", + "parent": "article", + "parent_article_type": "retraction", + "parent_id": None, + "parent_lang": "en", + "item": "related-article", + "sub_item": "related-article-type", + "validation_type": "match", + "response": "ERROR", + "expected_value": ["retracted-article", "article-retracted"], + "got_value": "retraction-forward", + "message": "Got retraction-forward, expected ['retracted-article', 'article-retracted']", + "advice": "The article-type: retraction does not match the related-article-type: retraction-forward, " + "provide one of the following items: ['retracted-article', 'article-retracted']", + "data": { + "parent": "article", + "parent_article_type": "retraction", + "parent_id": None, + "parent_lang": "en", + "ext-link-type": "doi", + "href": "10.1590/1808-057x202090350", + "id": "ra1", + "related-article-type": "retraction-forward", + "text": "", + "full_tag": '', + }, + } - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(obtained[i], item) + self.assertDictEqual(obtained, expected) - def test_related_articles_has_doi(self): + def test_related_article_has_doi(self): self.maxDiff = None xmltree = etree.fromstring( """
- - + + -
""" ) - obtained = list(RelatedArticlesValidation(xmltree).related_articles_doi()) + related_article_dict = list(RelatedArticles(xmltree).related_articles())[0] + obtained = RelatedArticleValidation( + related_article_dict + ).validate_related_article_doi() - expected = [ - { - 'title': 'Related article doi validation', - 'parent': 'article', - 'parent_article_type': 'correction-forward', - 'parent_id': None, - 'parent_lang': 'en', - 'item': 'related-article', - 'sub_item': 'xlink:href', - 'validation_type': 'exist', - 'response': 'OK', - 'expected_value': '10.1590/1808-057x202090350', - 'got_value': '10.1590/1808-057x202090350', - 'message': 'Got 10.1590/1808-057x202090350, expected 10.1590/1808-057x202090350', - 'advice': None, - 'data': { - 'parent': 'article', - 'parent_article_type': 'correction-forward', - 'parent_id': None, - 'parent_lang': 'en', - 'ext-link-type': 'doi', - 'href': '10.1590/1808-057x202090350', - 'id': 'ra1', - 'related-article-type': 'corrected-article', - 'text': '' - } - } - ] + expected = { + "title": "Related article doi validation", + "parent": "article", + "parent_article_type": "correction-forward", + "parent_id": None, + "parent_lang": "en", + "item": "related-article", + "sub_item": "xlink:href", + "validation_type": "exist", + "response": "OK", + "expected_value": "10.1590/1808-057x202090350", + "got_value": "10.1590/1808-057x202090350", + "message": "Got 10.1590/1808-057x202090350, expected 10.1590/1808-057x202090350", + "advice": None, + "data": { + "parent": "article", + "parent_article_type": "correction-forward", + "parent_id": None, + "parent_lang": "en", + "ext-link-type": "doi", + "href": "10.1590/1808-057x202090350", + "id": "ra1", + "related-article-type": "corrected-article", + "text": "", + "full_tag": '', + }, + } - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(obtained[i], item) + self.assertDictEqual(obtained, expected) def test_related_articles_does_not_have_doi(self): self.maxDiff = None @@ -188,154 +172,103 @@ def test_related_articles_does_not_have_doi(self): """
- - + + -
""" ) - obtained = list(RelatedArticlesValidation(xmltree).related_articles_doi()) + related_article_dict = list(RelatedArticles(xmltree).related_articles())[0] + obtained = RelatedArticleValidation( + related_article_dict + ).validate_related_article_doi() - expected = [ - { - 'title': 'Related article doi validation', - 'parent': 'article', - 'parent_article_type': 'correction-forward', - 'parent_id': None, - 'parent_lang': 'en', - 'item': 'related-article', - 'sub_item': 'xlink:href', - 'validation_type': 'exist', - 'response': 'ERROR', - 'expected_value': 'A valid DOI or URI for related-article/@xlink:href', - 'got_value': None, - 'message': 'Got None, expected A valid DOI or URI for related-article/@xlink:href', - 'advice': 'Provide a valid DOI for ', - 'data': { - 'parent': 'article', - 'parent_article_type': 'correction-forward', - 'parent_id': None, - 'parent_lang': 'en', - 'ext-link-type': 'doi', - 'id': 'ra1', - 'related-article-type': 'corrected-article', - 'text': '', - 'href': None - } - } - ] + expected = { + "title": "Related article doi validation", + "parent": "article", + "parent_article_type": "correction-forward", + "parent_id": None, + "parent_lang": "en", + "item": "related-article", + "sub_item": "xlink:href", + "validation_type": "exist", + "response": "ERROR", + "expected_value": "A valid DOI or URI for related-article/@xlink:href", + "got_value": None, + "message": "Got None, expected A valid DOI or URI for related-article/@xlink:href", + "advice": 'Provide a valid DOI for ', + "data": { + "parent": "article", + "parent_article_type": "correction-forward", + "parent_id": None, + "parent_lang": "en", + "ext-link-type": "doi", + "id": "ra1", + "related-article-type": "corrected-article", + "text": "", + "href": None, + "full_tag": '', + }, + } - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(obtained[i], item) + self.assertDictEqual(obtained, expected) def test_related_articles_attribute_validation(self): self.maxDiff = None xmltree = etree.fromstring( """ -
- - + + -
""" ) - obtained = list(RelatedArticlesValidation(xmltree).related_article_attributes_validation()) + related_article_dict = list(RelatedArticles(xmltree).related_articles())[0] + obtained = RelatedArticleValidation( + related_article_dict + ).validate_attrib_order_in_related_article_tag() - expected = [ - { - 'title': 'Related article attributes validation', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'item': 'related-article', - 'sub_item': '@id', - 'validation_type': 'exist', - 'response': 'ERROR', - 'expected_value': 'a value for @id', - 'got_value': None, - 'message': 'Got None, expected a value for @id', - 'advice': 'Provide a value for @id', - 'data': { - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'ext-link-type': None, - 'href': None, - 'id': None, - 'related-article-type': 'corrected-article', - 'text': '' - } + expected = { + "title": "attrib order in related article tag", + "parent": "article", + "parent_article_type": "correction", + "parent_id": None, + "parent_lang": "en", + "item": "related-article", + "sub_item": None, + "validation_type": "match", + "response": "ERROR", + "expected_value": '', + "got_value": '', + "message": 'Got , expected ' + '', + "advice": "Provide the attributes in the specified order", + "data": { + "parent": "article", + "parent_article_type": "correction", + "parent_id": None, + "parent_lang": "en", + "ext-link-type": None, + "href": None, + "id": None, + "related-article-type": "corrected-article", + "text": "", + "full_tag": "', }, - { - 'title': 'Related article attributes validation', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'item': 'related-article', - 'sub_item': '@href', - 'validation_type': 'exist', - 'response': 'ERROR', - 'expected_value': 'a value for @href', - 'got_value': None, - 'message': 'Got None, expected a value for @href', - 'advice': 'Provide a value for @href', - 'data': { - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'ext-link-type': None, - 'href': None, - 'id': None, - 'related-article-type': 'corrected-article', - 'text': '' - } - }, - { - 'title': 'Related article attributes validation', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'item': 'related-article', - 'sub_item': '@ext-link-type', - 'validation_type': 'exist', - 'response': 'ERROR', - 'expected_value': 'a value for @ext-link-type', - 'got_value': None, - 'message': 'Got None, expected a value for @ext-link-type', - 'advice': 'Provide a value for @ext-link-type', - 'data': { - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'ext-link-type': None, - 'href': None, - 'id': None, - 'related-article-type': 'corrected-article', - 'text': '' - } - } - ] - self.assertEqual(len(obtained), 3) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(obtained[i], item) + } + + self.assertDictEqual(obtained, expected) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() From e324186522c6c8029ffddf94a913c3e81037248a Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:40:07 -0300 Subject: [PATCH 35/36] Adapta testes de 'errata' --- tests/sps/validation/test_errata.py | 1012 ++++++++++----------------- 1 file changed, 354 insertions(+), 658 deletions(-) diff --git a/tests/sps/validation/test_errata.py b/tests/sps/validation/test_errata.py index c7557a8c2..3857a0ed5 100644 --- a/tests/sps/validation/test_errata.py +++ b/tests/sps/validation/test_errata.py @@ -1,13 +1,17 @@ from unittest import TestCase from packtools.sps.utils.xml_utils import get_xml_tree -from packtools.sps.validation.errata import RelatedArticlesValidation +from packtools.sps.validation.related_articles import ( + RelatedArticleValidation, + RelatedArticlesValidation, +) +from packtools.sps.models.v2.related_articles import RelatedArticles class ErrataValidationTest(TestCase): def test_validate_related_article_not_found(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -16,59 +20,33 @@ def test_validate_related_article_not_found(self): """ ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_related_articles()) + + obtained = list( + RelatedArticlesValidation(xml_tree).validate( + correspondence_dict={"correction": ["corrected-article"]} + ) + ) + expected = [ { - "title": "matching 'correction' and 'corrected-article'", + "title": "Related article type validation", "parent": "article", "parent_id": None, "parent_article_type": "correction", "parent_lang": "en", "item": "related-article", - "sub_item": "@related-article-type", + "sub_item": "related-article-type", "validation_type": "match", "response": "ERROR", - "expected_value": 'at least one ', - "got_value": None, - "message": f'Got None, expected at least one ', - "advice": 'provide ', - "data": [], + "expected_value": ["corrected-article"], + "got_value": [], + "message": "Got [], expected ['corrected-article']", + "advice": "The article-type: correction does not match the related-article-type: [" + "'corrected-article'], provide one of the following items: ['corrected-article']", + "data": None, } ] + self.assertEqual(len(obtained), 1) for i, item in enumerate(expected): with self.subTest(i): @@ -76,7 +54,7 @@ def test_validate_related_article_not_found(self): def test_validate_related_article_does_not_match(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -90,92 +68,52 @@ def test_validate_related_article_does_not_match(self): """ ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_related_articles()) - expected = [ - { - "title": "matching 'correction' and 'corrected-article'", + related_article_dict = list(RelatedArticles(xml_tree).related_articles())[0] + obtained = RelatedArticleValidation( + related_article_dict + ).validate_related_article_matches_article_type( + expected_related_article_types=["corrected-article"] + ) + + expected = { + "title": "Related article type validation", + "parent": "article", + "parent_id": None, + "parent_article_type": "correction", + "parent_lang": "en", + "item": "related-article", + "sub_item": "related-article-type", + "validation_type": "match", + "response": "ERROR", + "expected_value": ["corrected-article"], + "got_value": "correction-forward", + "message": "Got correction-forward, expected ['corrected-article']", + "advice": "The article-type: correction does not match the " + "related-article-type: correction-forward, provide one of the " + "following items: ['corrected-article']", + "data": { + "ext-link-type": "doi", + "href": "10.5935/abc.20160032", + "id": "RA1", "parent": "article", - "parent_id": None, "parent_article_type": "correction", + "parent_id": None, "parent_lang": "en", - "item": "related-article", - "sub_item": "@related-article-type", - "validation_type": "match", - "response": "ERROR", - "expected_value": 'at least one ', - "got_value": None, - "message": 'Got None, expected at least one ', - "advice": 'provide ', - "data": [ - { - 'ext-link-type': 'doi', - 'href': '10.5935/abc.20160032', - 'id': 'RA1', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'related-article-type': 'correction-forward', - 'text': '' - }, - { - 'ext-link-type': 'doi', - 'href': '10.5935/abc.20150051', - 'id': 'RA2', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'related-article-type': 'commentary', - 'text': '' - } - ], + "related-article-type": "correction-forward", + "text": "", + "full_tag": '', }, - ] - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(item, obtained[i]) + } + + self.assertDictEqual(obtained, expected) class RelatedArticlesTest(TestCase): def test_validate_related_article_not_found(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -183,57 +121,29 @@ def test_validate_related_article_not_found(self): """ ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_related_articles()) + obtained = list( + RelatedArticlesValidation(xml_tree).validate( + correspondence_dict={"correction": ["corrected-article"]} + ) + ) + expected = [ { - "title": "matching 'correction' and 'corrected-article'", + "title": "Related article type validation", "parent": "article", "parent_id": None, "parent_article_type": "correction", "parent_lang": "en", "item": "related-article", - "sub_item": "@related-article-type", + "sub_item": "related-article-type", "validation_type": "match", "response": "ERROR", - "expected_value": 'at least one ', - "got_value": None, - "message": f'Got None, expected at least one ', - "advice": 'provide ', - "data": [], + "expected_value": ["corrected-article"], + "got_value": [], + "message": "Got [], expected ['corrected-article']", + "advice": "The article-type: correction does not match the related-article-type: [" + "'corrected-article'], provide one of the following items: ['corrected-article']", + "data": None, } ] self.assertEqual(len(obtained), 1) @@ -243,7 +153,7 @@ def test_validate_related_article_not_found(self): def test_validate_related_article_does_not_match(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -256,90 +166,49 @@ def test_validate_related_article_does_not_match(self):
""" ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_related_articles()) - expected = [ - { - "title": "matching 'correction' and 'corrected-article'", + related_article_dict = list(RelatedArticles(xml_tree).related_articles())[0] + obtained = RelatedArticleValidation( + related_article_dict + ).validate_related_article_matches_article_type( + expected_related_article_types=["corrected-article"] + ) + + expected = { + "title": "Related article type validation", + "parent": "article", + "parent_id": None, + "parent_article_type": "correction", + "parent_lang": "en", + "item": "related-article", + "sub_item": "related-article-type", + "validation_type": "match", + "response": "ERROR", + "expected_value": ["corrected-article"], + "got_value": "correction-forward", + "message": "Got correction-forward, expected ['corrected-article']", + "advice": "The article-type: correction does not match the related-article-type: correction-forward, " + "provide one of the following items: ['corrected-article']", + "data": { + "ext-link-type": "doi", + "href": "10.5935/abc.20160032", + "id": "RA1", "parent": "article", - "parent_id": None, "parent_article_type": "correction", + "parent_id": None, "parent_lang": "en", - "item": "related-article", - "sub_item": "@related-article-type", - "validation_type": "match", - "response": "ERROR", - "expected_value": 'at least one ', - "got_value": None, - "message": f'Got None, expected at least one ', - "advice": 'provide ', - "data": [ - { - 'ext-link-type': 'doi', - 'href': '10.5935/abc.20160032', - 'id': 'RA1', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'related-article-type': 'correction-forward', - 'text': '' - }, - { - 'ext-link-type': 'doi', - 'href': '10.5935/abc.20150051', - 'id': 'RA2', - 'parent': 'article', - 'parent_article_type': 'correction', - 'parent_id': None, - 'parent_lang': 'en', - 'related-article-type': 'commentary', - 'text': '' - } - ], - } - ] - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(item, obtained[i]) + "related-article-type": "correction-forward", + "text": "", + "full_tag": '', + }, + } - def test_validate_count_related_article_count_date(self): + self.assertDictEqual(obtained, expected) + + def test_validate_history_date(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -358,76 +227,57 @@ def test_validate_count_related_article_count_date(self):
""" ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_history_events()) - expected = [ - { - "title": 'exist historical date event for the related-article', - "parent": "article", - "parent_id": None, - "parent_article_type": "correction", - "parent_lang": "en", - "item": "related-article", - "sub_item": "@related-article-type", - "validation_type": "exist", - "response": "ERROR", - "expected_value": '', - "got_value": None, - "message": 'Got None, expected ', - 'advice': 'provide ', - "data": { - 'received': { - 'day': '05', - 'month': '01', - 'type': 'received', - 'year': '1998' - } + related_article_dict = list(RelatedArticles(xml_tree).related_articles())[0] + obtained = RelatedArticleValidation(related_article_dict).validate_history_date( + expected_date_type="corrected", + history_events={ + "received": { + "day": "05", + "month": "01", + "type": "received", + "year": "1998", } - } - ] - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(item, obtained[i]) + }, + ) + + expected = { + "title": "history date", + "parent": "article", + "parent_id": None, + "parent_article_type": "correction", + "parent_lang": "en", + "item": "related-article / date", + "sub_item": "@related-article-type=correction-forward / @date-type=corrected", + "validation_type": "exist", + "response": "ERROR", + "expected_value": "corrected", + "got_value": { + "received": { + "day": "05", + "month": "01", + "type": "received", + "year": "1998", + } + }, + "message": "Got {'received': {'day': '05', 'month': '01', 'type': 'received', 'year': '1998'}}, expected corrected", + "advice": "Provide the publication date of the corrected", + "data": { + "received": { + "day": "05", + "month": "01", + "type": "received", + "year": "1998", + } + }, + } + + self.assertDictEqual(obtained, expected) class ArticleRetractedInFullValidationTest(TestCase): def test_validate_related_article_not_found(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -435,57 +285,29 @@ def test_validate_related_article_not_found(self): """ ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_related_articles()) + obtained = list( + RelatedArticlesValidation(xml_tree).validate( + correspondence_dict={"retraction": ["retracted-article"]} + ) + ) + expected = [ { - "title": "matching 'retraction' and 'retracted-article'", + "title": "Related article type validation", "parent": "article", "parent_id": None, "parent_article_type": "retraction", "parent_lang": "en", "item": "related-article", - "sub_item": "@related-article-type", + "sub_item": "related-article-type", "validation_type": "match", "response": "ERROR", - "expected_value": 'at least one ', - "got_value": None, - "message": f'Got None, expected at least one ', - 'advice': 'provide ', - "data": [], + "expected_value": ["retracted-article"], + "got_value": [], + "message": "Got [], expected ['retracted-article']", + "advice": "The article-type: retraction does not match the related-article-type: [" + "'retracted-article'], provide one of the following items: ['retracted-article']", + "data": None, } ] self.assertEqual(len(obtained), 1) @@ -495,7 +317,7 @@ def test_validate_related_article_not_found(self): def test_validate_related_article_does_not_match(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -508,79 +330,49 @@ def test_validate_related_article_does_not_match(self): """ ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_related_articles()) - expected = [ - { - "title": "matching 'retraction' and 'retracted-article'", + related_article_dict = list(RelatedArticles(xml_tree).related_articles())[0] + obtained = RelatedArticleValidation( + related_article_dict + ).validate_related_article_matches_article_type( + expected_related_article_types=["retracted-article"] + ) + + expected = { + "title": "Related article type validation", + "parent": "article", + "parent_id": None, + "parent_article_type": "retraction", + "parent_lang": "en", + "item": "related-article", + "sub_item": "related-article-type", + "validation_type": "match", + "response": "ERROR", + "expected_value": ["retracted-article"], + "got_value": "commentary", + "message": "Got commentary, expected ['retracted-article']", + "advice": "The article-type: retraction does not match the related-article-type: commentary, " + "provide one of the following items: ['retracted-article']", + "data": { + "ext-link-type": "doi", + "href": "10.5935/abc.20150051", + "id": "RA2", "parent": "article", - "parent_id": None, "parent_article_type": "retraction", + "parent_id": None, "parent_lang": "en", - "item": "related-article", - "sub_item": "@related-article-type", - "validation_type": "match", - "response": "ERROR", - "expected_value": 'at least one ', - "got_value": None, - "message": f'Got None, expected at least one ', - "advice": 'provide ', - "data": [ - { - 'ext-link-type': 'doi', - 'href': '10.5935/abc.20150051', - 'id': 'RA2', - 'parent': 'article', - 'parent_article_type': 'retraction', - 'parent_id': None, - 'parent_lang': 'en', - 'related-article-type': 'commentary', - 'text': '' - } - ] - } - ] - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(item, obtained[i]) + "related-article-type": "commentary", + "text": "", + "full_tag": '', + }, + } - def test_validate_count_related_article_count_date(self): + self.assertDictEqual(obtained, expected) + + def test_validate_history_date(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -599,76 +391,57 @@ def test_validate_count_related_article_count_date(self):
""" ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_history_events()) - expected = [ - { - "title": 'exist historical date event for the related-article', - "parent": "article", - "parent_id": None, - "parent_article_type": "retraction", - "parent_lang": "en", - "item": "related-article", - "sub_item": "@related-article-type", - "validation_type": "exist", - "response": "ERROR", - "expected_value": '', - "got_value": None, - "message": 'Got None, expected ', - "advice": 'provide ', - "data": { - 'received': { - 'day': '05', - 'month': '01', - 'type': 'received', - 'year': '1998' - } + related_article_dict = list(RelatedArticles(xml_tree).related_articles())[0] + obtained = RelatedArticleValidation(related_article_dict).validate_history_date( + expected_date_type="corrected", + history_events={ + "received": { + "day": "05", + "month": "01", + "type": "received", + "year": "1998", } - } - ] - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(item, obtained[i]) + }, + ) + + expected = { + "title": "history date", + "parent": "article", + "parent_id": None, + "parent_article_type": "retraction", + "parent_lang": "en", + "item": "related-article / date", + "sub_item": "@related-article-type=retraction-forward / @date-type=corrected", + "validation_type": "exist", + "response": "ERROR", + "expected_value": "corrected", + "got_value": { + "received": { + "day": "05", + "month": "01", + "type": "received", + "year": "1998", + } + }, + "message": "Got {'received': {'day': '05', 'month': '01', 'type': 'received', 'year': '1998'}}, expected corrected", + "advice": "Provide the publication date of the corrected", + "data": { + "received": { + "day": "05", + "month": "01", + "type": "received", + "year": "1998", + } + }, + } + + self.assertDictEqual(obtained, expected) class ArticlePartiallyRetractedValidationTest(TestCase): def test_validate_related_article_not_found(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -676,57 +449,29 @@ def test_validate_related_article_not_found(self): """ ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_related_articles()) + obtained = list( + RelatedArticlesValidation(xml_tree).validate( + correspondence_dict={"partial-retraction": ["retracted-article"]} + ) + ) + expected = [ { - "title": "matching 'partial-retraction' and 'retracted-article'", + "title": "Related article type validation", "parent": "article", "parent_id": None, "parent_article_type": "partial-retraction", "parent_lang": "en", "item": "related-article", - "sub_item": "@related-article-type", + "sub_item": "related-article-type", "validation_type": "match", "response": "ERROR", - "expected_value": 'at least one ', - "got_value": None, - "message": f'Got None, expected at least one ', - 'advice': 'provide ', - "data": [], + "expected_value": ["retracted-article"], + "got_value": [], + "message": "Got [], expected ['retracted-article']", + "advice": "The article-type: partial-retraction does not match the related-article-type: [" + "'retracted-article'], provide one of the following items: ['retracted-article']", + "data": None, } ] self.assertEqual(len(obtained), 1) @@ -734,9 +479,9 @@ def test_validate_related_article_not_found(self): with self.subTest(i): self.assertDictEqual(item, obtained[i]) - def test_validate_related_article_found(self): + def test_validate_related_article_does_not_match(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -749,79 +494,49 @@ def test_validate_related_article_found(self): """ ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_related_articles()) - expected = [ - { - "title": "matching 'partial-retraction' and 'retracted-article'", + related_article_dict = list(RelatedArticles(xml_tree).related_articles())[0] + obtained = RelatedArticleValidation( + related_article_dict + ).validate_related_article_matches_article_type( + expected_related_article_types=["retracted-article"] + ) + + expected = { + "title": "Related article type validation", + "parent": "article", + "parent_id": None, + "parent_article_type": "partial-retraction", + "parent_lang": "en", + "item": "related-article", + "sub_item": "related-article-type", + "validation_type": "match", + "response": "ERROR", + "expected_value": ["retracted-article"], + "got_value": "commentary", + "message": "Got commentary, expected ['retracted-article']", + "advice": "The article-type: partial-retraction does not match the related-article-type: commentary, " + "provide one of the following items: ['retracted-article']", + "data": { + "ext-link-type": "doi", + "href": "10.5935/abc.20150051", + "id": "RA2", "parent": "article", - "parent_id": None, "parent_article_type": "partial-retraction", + "parent_id": None, "parent_lang": "en", - "item": "related-article", - "sub_item": "@related-article-type", - "validation_type": "match", - "response": "ERROR", - "expected_value": 'at least one ', - "got_value": None, - "message": 'Got None, expected at least one ', - "advice": 'provide ', - "data": [ - { - 'ext-link-type': 'doi', - 'href': '10.5935/abc.20150051', - 'id': 'RA2', - 'parent': 'article', - 'parent_article_type': 'partial-retraction', - 'parent_id': None, - 'parent_lang': 'en', - 'related-article-type': 'commentary', - 'text': '' - } - ], - } - ] - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(item, obtained[i]) + "related-article-type": "commentary", + "text": "", + "full_tag": '', + }, + } + + self.assertDictEqual(obtained, expected) def test_validate_count_related_article_count_date(self): self.maxDiff = None - self.xml_tree = get_xml_tree( + xml_tree = get_xml_tree( """
@@ -841,67 +556,48 @@ def test_validate_count_related_article_count_date(self):
""" ) - obtained = list(RelatedArticlesValidation( - self.xml_tree, - correspondence_list=[ - { - 'article-type': 'correction', - 'related-article-type': 'corrected-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'correction-forward', - 'date-type': 'corrected' - }, - { - 'article-type': 'retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': 'partial-retraction', - 'related-article-type': 'retracted-article', - 'date-type': None - }, - { - 'article-type': None, - 'related-article-type': 'retraction-forward', - 'date-type': 'retracted' - }, - { - 'article-type': None, - 'related-article-type': 'partial-retraction', - 'date-type': 'retracted' - }, - ] - ).validate_history_events()) - expected = [ - { - "title": 'exist historical date event for the related-article', - "parent": "article", - "parent_id": None, - "parent_article_type": 'partial-retraction', - "parent_lang": "en", - "item": "related-article", - "sub_item": "@related-article-type", - "validation_type": "exist", - "response": "ERROR", - "expected_value": '', - "got_value": None, - "message": 'Got None, expected ', - "advice": 'provide ', - "data": { - 'received': { - 'day': '05', - 'month': '01', - 'type': 'received', - 'year': '1998' - } - }, - } - ] - self.assertEqual(len(obtained), 1) - for i, item in enumerate(expected): - with self.subTest(i): - self.assertDictEqual(item, obtained[i]) + related_article_dict = list(RelatedArticles(xml_tree).related_articles())[0] + obtained = RelatedArticleValidation(related_article_dict).validate_history_date( + expected_date_type="retracted", + history_events={ + "received": { + "day": "05", + "month": "01", + "type": "received", + "year": "1998", + } + }, + ) + + expected = { + "title": "history date", + "parent": "article", + "parent_id": None, + "parent_article_type": "partial-retraction", + "parent_lang": "en", + "item": "related-article / date", + "sub_item": "@related-article-type=partial-retraction / @date-type=retracted", + "validation_type": "exist", + "response": "ERROR", + "expected_value": "retracted", + "got_value": { + "received": { + "day": "05", + "month": "01", + "type": "received", + "year": "1998", + } + }, + "message": "Got {'received': {'day': '05', 'month': '01', 'type': 'received', 'year': '1998'}}, expected retracted", + "advice": "Provide the publication date of the retracted", + "data": { + "received": { + "day": "05", + "month": "01", + "type": "received", + "year": "1998", + } + }, + } + + self.assertDictEqual(obtained, expected) From 59464187230ba4e9ce8bf628bf95015ca145b742 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Wed, 9 Oct 2024 11:40:30 -0300 Subject: [PATCH 36/36] Adapta testes de 'preprint' --- tests/sps/validation/test_preprint.py | 190 ++++++++++++++------------ 1 file changed, 99 insertions(+), 91 deletions(-) diff --git a/tests/sps/validation/test_preprint.py b/tests/sps/validation/test_preprint.py index 7718748ed..72feae491 100644 --- a/tests/sps/validation/test_preprint.py +++ b/tests/sps/validation/test_preprint.py @@ -1,17 +1,19 @@ import unittest from packtools.sps.utils.xml_utils import get_xml_tree - -from packtools.sps.validation.preprint import PreprintValidation +from packtools.sps.models.v2.related_articles import RelatedArticles +from packtools.sps.validation.related_articles import RelatedArticleValidation class PreprintValidationTest(unittest.TestCase): - def test_preprint_validation_preprint_ok_and_date_ok(self): + def test_preprint_validation_preprint(self): self.maxDiff = None xml_str = """ -
+
+ 18 @@ -21,68 +23,57 @@ def test_preprint_validation_preprint_ok_and_date_ok(self): -
""" - - obtained = PreprintValidation(get_xml_tree(xml_str)).preprint_validation() - - expected = [ - { - 'title': 'Preprint validation', - 'xpath': './/related-article[@related-article-type="preprint"] .//history//date[@date-type="preprint"]', - 'validation_type': 'match', - 'response': 'OK', - 'expected_value': '2002-10-18', - 'got_value': '2002-10-18', - 'message': 'Got 2002-10-18 expected 2002-10-18', - 'advice': None - - } - ] - - for i, item in enumerate(obtained): - with self.subTest(i): - self.assertDictEqual(expected[i], item) - - def test_preprint_validation_preprint_ok_and_date_not_ok(self): + xml_tree = get_xml_tree(xml_str) + + related_article_dict = list(RelatedArticles(xml_tree).related_articles())[0] + obtained = RelatedArticleValidation( + related_article_dict + ).validate_related_article_matches_article_type( + expected_related_article_types=["preprint"] + ) + + expected = { + "title": "Related article type validation", + "parent": "article", + "parent_article_type": "research-article", + "parent_id": None, + "parent_lang": "en", + "item": "related-article", + "sub_item": "related-article-type", + "validation_type": "match", + "response": "OK", + "expected_value": ["preprint"], + "got_value": "preprint", + "message": "Got preprint, expected ['preprint']", + "advice": None, + "data": { + "parent": "article", + "parent_article_type": "research-article", + "parent_id": None, + "parent_lang": "en", + "ext-link-type": "doi", + "href": "10.1590/SciELOPreprints.1174", + "id": "pp1", + "related-article-type": "preprint", + "text": "", + "full_tag": '', + }, + } + + self.assertDictEqual(expected, obtained) + + def test_preprint_validation_preprint_date(self): self.maxDiff = None xml_str = """ -
+
- - -
- """ - - obtained = PreprintValidation(get_xml_tree(xml_str)).preprint_validation() - - expected = [ - { - 'title': 'Preprint validation', - 'xpath': './/related-article[@related-article-type="preprint"] .//history//date[@date-type="preprint"]', - 'validation_type': 'match', - 'response': 'ERROR', - 'expected_value': 'The preprint publication date', - 'got_value': None, - 'message': 'Got None expected The preprint publication date', - 'advice': 'Provide the publication date of the preprint' - - } - ] - - for i, item in enumerate(obtained): - with self.subTest(i): - self.assertDictEqual(expected[i], item) - - def test_preprint_validation_preprint_not_ok_and_date_ok(self): - self.maxDiff = None - xml_str = """ -
- - 18 @@ -94,44 +85,61 @@ def test_preprint_validation_preprint_not_ok_and_date_ok(self):
""" - - obtained = PreprintValidation(get_xml_tree(xml_str)).preprint_validation() - - expected = [ - { - 'title': 'Preprint validation', - 'xpath': './/related-article[@related-article-type="preprint"] .//history//date[@date-type="preprint"]', - 'validation_type': 'match', - 'response': 'ERROR', - 'expected_value': None, - 'got_value': '2002-10-18', - 'message': 'Got 2002-10-18 expected None', - 'advice': 'The article does not reference the preprint, provide it as in the example: ' - '' - - } - ] - - for i, item in enumerate(obtained): - with self.subTest(i): - self.assertDictEqual(expected[i], item) - - def test_preprint_validation_preprint_not_ok_and_date_not_ok(self): + xml_tree = get_xml_tree(xml_str) + + related_article_dict = list(RelatedArticles(xml_tree).related_articles())[0] + obtained = RelatedArticleValidation(related_article_dict).validate_history_date( + expected_date_type="preprint", + history_events={ + "preprint": { + "day": "18", + "month": "10", + "type": "preprint", + "year": "2022", + } + }, + ) + + self.assertIsNone(obtained) + + def test_preprint_validation_preprint_date_not_ok(self): self.maxDiff = None xml_str = """ -
+
+
""" - - obtained = PreprintValidation(get_xml_tree(xml_str)).preprint_validation() - - self.assertEqual([], obtained) - - -if __name__ == '__main__': + xml_tree = get_xml_tree(xml_str) + + related_article_dict = list(RelatedArticles(xml_tree).related_articles())[0] + obtained = RelatedArticleValidation(related_article_dict).validate_history_date( + expected_date_type="preprint", history_events={} + ) + + expected = { + "title": "history date", + "parent": "article", + "parent_id": None, + "parent_article_type": "research-article", + "parent_lang": "en", + "item": "related-article / date", + "sub_item": "@related-article-type=preprint / @date-type=preprint", + "validation_type": "exist", + "response": "ERROR", + "expected_value": "preprint", + "got_value": {}, + "message": "Got {}, expected preprint", + "advice": "Provide the publication date of the preprint", + "data": {}, + } + + self.assertDictEqual(expected, obtained) + + +if __name__ == "__main__": unittest.main()