diff --git a/packtools/sps/models/article_and_subarticles.py b/packtools/sps/models/article_and_subarticles.py index 2298005e6..034ea213e 100644 --- a/packtools/sps/models/article_and_subarticles.py +++ b/packtools/sps/models/article_and_subarticles.py @@ -48,6 +48,7 @@ def data(self): _data = [] if self.main_article_type: _data.append({ + "parent": "article", "lang": self.main_lang, "article_type": self.main_article_type, "article_id": None, @@ -61,6 +62,7 @@ def data(self): subject = sub_article.find('.//subject') _data.append({ + "parent": "sub-article", "lang": lang, "article_type": sub_article.get('article-type'), "article_id": sub_article.get('id'), diff --git a/packtools/sps/sps_versions/default/specific_use.json b/packtools/sps/sps_versions/default/specific_use.json index 81f5cfb31..5aa72570e 100644 --- a/packtools/sps/sps_versions/default/specific_use.json +++ b/packtools/sps/sps_versions/default/specific_use.json @@ -1,5 +1,5 @@ { - "specif_use_list": [ + "specific_use_list": [ "sps-1.1", "sps-1.2", "sps-1.3", diff --git a/packtools/sps/sps_versions/sps-1.10/article_type.json b/packtools/sps/sps_versions/sps-1.10/article_type.json index b8b5a06d2..dcd77012d 100644 --- a/packtools/sps/sps_versions/sps-1.10/article_type.json +++ b/packtools/sps/sps_versions/sps-1.10/article_type.json @@ -1,24 +1,41 @@ { "sps_version": "sps-1.10", - "article_type_list": [ - "addendum", - "article-commentary", - "book-review", - "brief-report", - "case-report", - "correction", - "editorial", - "data-article", - "letter", - "obituary", - "partial-retraction", - "product-review", - "rapid-communication", - "reply", - "research-article", - "retraction", - "review-article", - "reviewer-report", - "other" - ] + "article_type_list": { + "article": [ + "article-commentary", + "book-review", + "brief-report", + "case-report", + "correction", + "editorial", + "in-brief", + "letter", + "other", + "partial-retraction", + "rapid-communication", + "reply", + "research-article", + "retraction", + "review-article", + "data-article" + ], + "sub-article": [ + "translation", + "editorial", + "announcement", + "correction", + "retraction", + "letter", + "brief-report", + "addendum", + "reply", + "discussion", + "case-report", + "obituary", + "book-review", + "in-memoriam", + "news", + "other" + ] + } } 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..a2d268197 --- /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/article_type.json b/packtools/sps/sps_versions/sps-1.9/article_type.json index e519eb0e1..f7bbdd40f 100644 --- a/packtools/sps/sps_versions/sps-1.9/article_type.json +++ b/packtools/sps/sps_versions/sps-1.9/article_type.json @@ -1,22 +1,42 @@ { "sps_version": "sps-1.9", "source": "https://scielo.readthedocs.io/projects/scielo-publishing-schema/pt-br/1.9-branch/tagset/elemento-article.html?highlight=article-type#article", - "article_type_list": [ - "article-commentary", - "book-review", - "brief-report", - "case-report", - "correction", - "editorial", - "in-brief", - "letter", - "other", - "partial-retraction", - "rapid-communication", - "reply", - "research-article", - "retraction", - "review-article", - "data-article" - ] + "article_type_list": { + "article": [ + "article-commentary", + "book-review", + "brief-report", + "case-report", + "correction", + "editorial", + "in-brief", + "letter", + "other", + "partial-retraction", + "rapid-communication", + "reply", + "research-article", + "retraction", + "review-article", + "data-article" + ], + "sub-article": [ + "translation", + "editorial", + "announcement", + "correction", + "retraction", + "letter", + "brief-report", + "addendum", + "reply", + "discussion", + "case-report", + "obituary", + "book-review", + "in-memoriam", + "news", + "other" + ] + } } 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..a2d268197 --- /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/", - }, -] diff --git a/packtools/sps/sps_versions/sps-1.9/specific_use.json b/packtools/sps/sps_versions/sps-1.9/specific_use.json new file mode 100644 index 000000000..5aa72570e --- /dev/null +++ b/packtools/sps/sps_versions/sps-1.9/specific_use.json @@ -0,0 +1,14 @@ +{ + "specific_use_list": [ + "sps-1.1", + "sps-1.2", + "sps-1.3", + "sps-1.4", + "sps-1.5", + "sps-1.6", + "sps-1.7", + "sps-1.8", + "sps-1.9", + "sps-1.10" + ] +} diff --git a/packtools/sps/validation/article_and_subarticles.py b/packtools/sps/validation/article_and_subarticles.py index 6381eebe0..44d00b9e2 100644 --- a/packtools/sps/validation/article_and_subarticles.py +++ b/packtools/sps/validation/article_and_subarticles.py @@ -293,7 +293,7 @@ def __init__(self, xmltree, article_type_list=None, subjects_list=None, apply_to self.subjects_list = subjects_list self.apply_to_article_types = apply_to_article_types - def validate_article_type(self, article_type_list=None, error_level=None): + def validate_article_type(self, article_type_list=None, error_level="CRITICAL"): """ Check whether the article type attribute of the article matches the options provided in a standard list. @@ -345,44 +345,46 @@ def validate_article_type(self, article_type_list=None, error_level=None): },... ] """ - article_type = self.articles.main_article_type + articles_data = self.articles.data article_type_list = article_type_list or self.article_type_list - error_level = error_level or "CRITICAL" if not article_type_list: raise ValidationArticleAndSubArticlesArticleTypeException( "Function requires list of article types" ) - validated = article_type in article_type_list + for article_data in articles_data: + parent = article_data.get("parent") + article_type = article_data.get("article_type") - data = self.articles.data[0] - data.update({ - "specific_use": self.articles.main_specific_use, - "dtd_version": self.articles.main_dtd_version - }) + validated = article_type in (article_type_list.get(parent) or []) - yield format_response( - title="Article type validation", - parent="article", - parent_id=None, - parent_article_type=self.articles.main_article_type, - parent_lang=self.articles.main_lang, - item="article", - sub_item="@article-type", - validation_type="value in list", - is_valid=validated, - expected=article_type_list, - obtained=article_type, - advice="XML has {} as article-type, expected one item of this list: {}".format( - article_type, " | ".join(article_type_list) - ), - data=data, - error_level=error_level, - ) + article_data.update({ + "specific_use": self.articles.main_specific_use, + "dtd_version": self.articles.main_dtd_version + }) + + yield format_response( + title="Article type validation", + parent=parent, + parent_id=article_data.get("article_id"), + parent_article_type=article_data.get("article_type"), + parent_lang=article_data.get("lang"), + item="article", + sub_item="@article-type", + validation_type="value in list", + is_valid=validated, + expected=article_type_list.get(parent), + obtained=article_type, + advice="XML has {} as article-type, expected one item of this list: {}".format( + article_type, " | ".join(article_type_list.get(parent) or []) + ), + data=article_data, + error_level=error_level, + ) def validate_article_type_vs_subject_similarity( - self, subjects_list=None, expected_similarity=1, error_level=None, target_article_types=None + self, subjects_list=None, expected_similarity=1, error_level="ERROR", target_article_types=None ): """ Check how similar the type of article and its respective subjects are. @@ -496,8 +498,6 @@ def validate_article_type_vs_subject_similarity( "Function requires list of article types to check the similarity with subjects" ) - error_level = error_level or "ERROR" - articles = [article for article in self.articles.data if article.get("article_type") in target_article_types] for article in articles: diff --git a/packtools/sps/validation/journal_meta.py b/packtools/sps/validation/journal_meta.py index 84d09cba4..999df71f9 100644 --- a/packtools/sps/validation/journal_meta.py +++ b/packtools/sps/validation/journal_meta.py @@ -89,22 +89,27 @@ def __init__(self, xmltree): self.xmltree = xmltree self.journal_acronym = Acronym(xmltree) - def acronym_validation(self, expected_value): + def acronym_validation(self, expected_value, error_level="CRITICAL"): if not expected_value: raise ValidationJournalMetaException('Function requires a value to acronym') is_valid = self.journal_acronym.text == expected_value - return [ - { - 'title': 'Journal acronym element validation', - 'xpath': './/journal-meta//journal-id[@journal-id-type="publisher-id"]', - 'validation_type': 'value', - 'response': 'OK' if is_valid else 'ERROR', - 'expected_value': expected_value, - 'got_value': self.journal_acronym.text, - 'message': 'Got {} expected {}'.format(self.journal_acronym.text, expected_value), - 'advice': None if is_valid else 'Provide an acronym value as expected: {}'.format(expected_value) - } - ] + + yield format_response( + title='Journal acronym element validation', + parent='article', + parent_id=None, + parent_article_type=self.xmltree.get("article-type"), + parent_lang=self.xmltree.get("{http://www.w3.org/XML/1998/namespace}lang"), + item="journal-id", + sub_item="@journal-id-type='publisher-id'", + validation_type="value", + is_valid=is_valid, + expected=expected_value, + obtained=self.journal_acronym.text, + advice='Provide an acronym value as expected: {}'.format(expected_value), + data={"acronym": self.journal_acronym.text}, + error_level=error_level, + ) class TitleValidation: @@ -358,11 +363,9 @@ def validate(self, expected_values): publisher = PublisherNameValidation(self.xmltree) nlm_ta = JournalIdValidation(self.xmltree) - resp_journal_meta = list(issn.validate_issn(expected_values['issns'])) + \ - acronym.acronym_validation(expected_values['acronym']) + \ - title.journal_title_validation(expected_values['journal-title']) + \ - list(title.abbreviated_journal_title_validation(expected_values['abbrev-journal-title'])) + \ - list(publisher.validate_publisher_names(expected_values['publisher-name'])) + \ - list(nlm_ta.nlm_ta_id_validation(expected_values['nlm-ta'])) - - return resp_journal_meta + yield from issn.validate_issn(expected_values['issns']) + yield from acronym.acronym_validation(expected_values['acronym']) + yield from title.journal_title_validation(expected_values['journal-title']) + yield from title.abbreviated_journal_title_validation(expected_values['abbrev-journal-title']) + yield from publisher.validate_publisher_names(expected_values['publisher-name']) + yield from nlm_ta.nlm_ta_id_validation(expected_values['nlm-ta']) diff --git a/packtools/xml_validation.py b/packtools/xml_validation.py new file mode 100644 index 000000000..ea66cde0f --- /dev/null +++ b/packtools/xml_validation.py @@ -0,0 +1,472 @@ +import csv +import json +import logging +import sys +import os +import argparse +from importlib.resources import files + +from packtools.sps.utils import xml_utils +from packtools.sps.models.dates import ArticleDates +from packtools.sps.validation.aff import ( + AffiliationsListValidation, + AffiliationValidation, +) +from packtools.sps.validation.alternatives import ( + AlternativesValidation, + AlternativeValidation, +) +from packtools.sps.validation.article_abstract import ( + HighlightsValidation, + VisualAbstractsValidation, +) +from packtools.sps.validation.article_and_subarticles import ( + ArticleAttribsValidation, + ArticleIdValidation, + ArticleLangValidation, + ArticleTypeValidation, +) +from packtools.sps.validation.article_author_notes import AuthorNotesValidation +from packtools.sps.validation.article_citations import ( + ArticleCitationsValidation, + ArticleCitationValidation, +) +from packtools.sps.validation.article_contribs import ( + ArticleContribsValidation, + ContribsValidation, + ContribValidation, +) +from packtools.sps.validation.article_data_availability import ( + DataAvailabilityValidation, +) +from packtools.sps.validation.article_doi import ArticleDoiValidation +from packtools.sps.validation.article_lang import ArticleLangValidation as ArticleLangValidation2 +from packtools.sps.validation.article_license import ArticleLicenseValidation +from packtools.sps.validation.article_toc_sections import ArticleTocSectionsValidation +from packtools.sps.validation.article_xref import ArticleXrefValidation +from packtools.sps.validation.dates import ArticleDatesValidation +from packtools.sps.validation.footnotes import FootnoteValidation +from packtools.sps.validation.front_articlemeta_issue import IssueValidation, Pagination +from packtools.sps.validation.funding_group import FundingGroupValidation +from packtools.sps.validation.journal_meta import ( + AcronymValidation, + ISSNValidation, + JournalIdValidation, + JournalMetaValidation, + PublisherNameValidation, + TitleValidation, +) +from packtools.sps.validation.peer_review import ( + AuthorPeerReviewValidation, + CustomMetaPeerReviewValidation, + DatePeerReviewValidation, + PeerReviewsValidation, + RelatedArticleValidation, +) +from packtools.sps.validation.preprint import PreprintValidation +from packtools.sps.validation.related_articles import RelatedArticlesValidation +from packtools.sps.pid_provider.xml_sps_lib import XMLWithPre + + +def get_xml_tree(xml_file_path): + with open(xml_file_path, 'r') as file: + return xml_utils.get_xml_tree(file.read()) + + +def get_data(filename, key, sps_version=None): + sps_version = sps_version or "default" + # Reads contents with UTF-8 encoding and returns str. + content = ( + files(f"packtools.sps.sps_versions") + .joinpath(f"{sps_version}") + .joinpath(f"{filename}.json") + .read_text() + ) + x = " ".join(content.split()) + fixed = x.replace(", ]", "]").replace(", }", "}") + data = json.loads(fixed) + return data[key] + + +def create_report(report_file_path, xml_path, params, fieldnames=None): + for xml_with_pre in XMLWithPre.create(path=xml_path): + rows = validate_xml_content(xml_with_pre.filename, xml_with_pre.xmltree, params) + save_csv(report_file_path, rows, fieldnames) + print(f"Created {report_file_path}") + + +def save_csv(filepath, rows, fieldnames): + with open(filepath, 'w', newline='') as csvfile: + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + writer.writeheader() + for row in rows: + filtered_row = {key: row.get(key, '') for key in fieldnames} + writer.writerow(filtered_row) + + +def validate_xml_content(sps_pkg_name, xmltree, params): + validation_group_and_function_items = ( + ("journal", validate_journal), + ("article attributes", validate_article_attributes), + ("article attributes", validate_languages), + ("article attributes", validate_article_type), + # ("article-id", validate_article_id_other), + # ("article-id", validate_doi), + # ("dates", validate_dates), + # ("texts and languages", validate_article_languages), + # ("texts and languages", validate_toc_sections), + # ("author", validate_contribs), + # ("author affiliations", validate_affiliations), + # ("author notes", validate_author_notes), + # ("open science", validate_data_availability), + # ("open science", validate_licenses), + # ("open science", validate_preprint), + # ("peer review", validate_peer_review), + # ("funding", validate_funding_group), + # ("xref", validate_xref), + # ("references", validate_references), + # ("footnotes", validate_footnotes), + # ("table-wrap", validate_table_wrap), + # ("figures", validate_figures), + # ("formulas", validate_formulas), + # ("supplmentary material", validate_supplementary_material), + # ("related articles", validate_related_articles), + # ("special abstracts", validate_visual_abstracts), + # ("special abstracts", validate_highlights), + ) + + sps_version = xmltree.find(".").get("specific-use") + + for validation_group, f in validation_group_and_function_items: + try: + items = f(xmltree, sps_version, params) + for item in items: + try: + item["group"] = validation_group + yield item + except Exception as exc: + exc_type, exc_value, exc_traceback = sys.exc_info() + yield dict( + exception=exc, + exc_traceback=exc_traceback, + function=validation_group, + sps_pkg_name=sps_pkg_name, + item=item, + ) + except Exception as exc: + exc_type, exc_value, exc_traceback = sys.exc_info() + yield dict( + exception=exc, + exc_traceback=exc_traceback, + function=validation_group, + sps_pkg_name=sps_pkg_name, + ) + + +def validate_affiliations(xmltree, sps_version, params): + validator = AffiliationsListValidation(xmltree) + data = get_data("country_codes", "country_codes_list") + yield from validator.validade_affiliations_list(data) + + +def validate_highlights(xmltree, sps_version, params): + validator = HighlightsValidation(xmltree) + yield from validator.highlight_validation() + + +def validate_visual_abstracts(xmltree, sps_version, params): + validator = VisualAbstractsValidation(xmltree) + yield from validator.visual_abstracts_validation() + + +def validate_languages(xmltree, sps_version, params): + validator = ArticleLangValidation(xmltree) + yield from validator.validate_language(get_data("language_codes", "language_codes_list")) + + +def validate_article_attributes(xmltree, sps_version, params): + validator = ArticleAttribsValidation(xmltree) + + dtd_version_list = get_data("dtd_version", "dtd_version_list", sps_version) + specific_use_list = get_data("specific_use", "specific_use_list", sps_version) + + yield from validator.validate_dtd_version(dtd_version_list) + yield from validator.validate_specific_use(specific_use_list) + + +def validate_article_id_other(xmltree, sps_version, params): + validator = ArticleIdValidation(xmltree) + try: + return validator.validate_article_id_other() + except AttributeError: + return None + + +def validate_article_type(xmltree, sps_version, params): + validator = ArticleTypeValidation(xmltree) + + article_type_list = get_data("article_type", "article_type_list", sps_version) + + yield from validator.validate_article_type(article_type_list) + + yield from validator.validate_article_type_vs_subject_similarity() + + +def validate_author_notes(xmltree, sps_version, params): + data = { + "sps_1_9": ["conflict"], + "sps_1_10": ["coi-statement"] + } + validator = AuthorNotesValidation(xmltree, data.get(sps_version)) + yield from validator.validate_author_notes() + + +def validate_references(xmltree, sps_version, params): + # FIXME criar json para a versão sps_1_9 + publication_type_list = get_data("publication_types_references", "publication_type_list", "sps_1_10") + validator = ArticleCitationsValidation(xmltree, data.get(sps_version)) + start_year = None + + xml = ArticleDates(self.xmltree) + end_year = int(xml.collection_date["year"] or xml.article_date["year"]) + + # FIXME remover xmltree do método + yield from validator.validate_article_citations( + xmltree, publication_type_list, start_year, end_year) + + +def validate_contribs(xmltree, sps_version, params): + data = { + "credit_taxonomy_terms_and_urls": None, + "callable_get_data": None, + } + validator = ArticleContribsValidation(xmltree) + # FIXME + yield validator.validate_contribs_orcid_is_unique(error_level="CRITICAL") + # for contrib in validator.contribs.contribs: + # yield from ContribsValidation(contrib, data, content_types).validate() + + +def validate_data_availability(xmltree, sps_version, params): + validator = DataAvailabilityValidation(xmltree) + try: + specific_use_list = get_data("data_availability_specific_use", "specific_use", sps_version) + except Exception as e: + specific_use_list = None + + if specific_use_list: + yield validator.validate_data_availability( + specific_use_list, + error_level="ERROR", + ) + + +def validate_doi(xmltree, sps_version, params): + # FIXME falta de padrão + validator = ArticleDoiValidation(xmltree) + + if params.get("doi_required"): + error = "CRITICAL" + else: + error_level = "ERROR" + yield validator.validate_main_article_doi_exists(error_level=error_level) + yield from validator.validate_translations_doi_exists(error_level=error_level) + yield validator.validate_all_dois_are_unique(error_level="ERROR") + + callable_get_data = params.get("get_doi_data") + if callable_get_data: + # TODO + yield validator.validate_doi_registered(callable_get_data) + + +def validate_article_languages(xmltree, sps_version, params): + # FIXME falta de padrão + validator = ArticleLangValidation2(xmltree) + yield from validator.validate_article_lang() + + +def validate_licenses(xmltree, sps_version, params): + validator = ArticleLicenseValidation(xmltree) + # yield from validator.validate_license(license_expected_value) + # falta de json em sps_1_9 + yield from validator.validate_license_code( + get_data("license_data", "expected_data", sps_version)) + + +def validate_toc_sections(xmltree, sps_version, params): + validator = ArticleTocSectionsValidation(xmltree) + yield from validator.validate_article_toc_sections(params.get("expected_toc_sections")) + yield from validator.validade_article_title_is_different_from_section_titles() + + +def validate_xref(xmltree, sps_version, params): + validator = ArticleXrefValidation(xmltree) + yield from validator.validate_id() + yield from validator.validate_rid() + + +def validate_dates(xmltree, sps_version, params): + validator = ArticleDatesValidation(xmltree) + order = get_data( + "history_dates_order_of_events", "order", sps_version, + ) + required_events = get_data( + "history_dates_required_events", "required_events", sps_version, + ) + yield from validator.validate_history_dates(order, required_events) + yield from validator.validate_number_of_digits_in_article_date() + + # FIXME + yield validator.validate_article_date(future_date=None) + yield validator.validate_collection_date(future_date=None) + + +def validate_figures(xmltree, sps_version, params): + # FIXME faltam validações de label, caption, graphic ou alternatives + validator = FigValidation(xmltree) + yield from validator.validate_fig_existence() + + +def validate_footnotes(xmltree, sps_version, params): + # FIXME não existe somente um tipo de footnotes, faltam validações, error_level + validator = FootnoteValidation(xmltree) + yield from validator.fn_validation() + + +def validate_formulas(xmltree, sps_version, params): + # FIXME faltam validações de label, caption, graphic ou alternatives + validator = FormulaValidation(xmltree) + yield from validator.validate_formula_existence() + + +def validate_funding_group(xmltree, sps_version, params): + # FIXME ? _callable_extern_validate_default + # faltam validações + validator = FundingGroupValidation(xmltree) + yield from validator.funding_sources_exist_validation() + # ??? yield from validator.award_id_format_validation(_callable_extern_validate_default) + + +def validate_journal(xmltree, sps_version, params): + + validator = AcronymValidation(xmltree) + yield from validator.acronym_validation(params["journal_acron"]) + + validator = PublisherNameValidation(xmltree) + yield from validator.validate_publisher_names(params["publisher_name_list"]) + + try: + if params["nlm_ta"]: + validator = JournalIdValidation(xmltree) + yield from validator.nlm_ta_id_validation(params["nlm_ta"]) + except KeyError: + pass + + +def validate_peer_review(xmltree, sps_version, params): + # FIXME temos todos os json? + + validator = PeerReviewsValidation( + xml_tree, + contrib_type_list=get_data("specific_use_for_peer_review", "contrib_type_list", sps_version), + specific_use_list=get_data("specific_use_for_peer_review", "specif_use_list", sps_version), + date_type_list=get_data("specific_use_for_peer_review", "date_type_list", sps_version), + meta_value_list=get_data("meta_value", "meta_value_list", sps_version), + related_article_type_list=get_data("related_article_type", "related_article_type_list", sps_version), + link_type_list=get_data("related_article__ext_link_type", "related_article__ext_link_type_list", sps_version), + ) + yield from validator.validate() + + +def validate_preprint(xmltree, sps_version, params): + # FIXME fora de padrão + validator = PreprintValidation(xmltree) + yield from validator.preprint_validation() + + +def validate_related_articles(xmltree, sps_version, params): + validator = RelatedArticlesValidation(xmltree) + correspondence_list = get_data( + "related_article", "correspondence_list", sps_version, + ) + yield from validator.related_articles_matches_article_type_validation(correspondence_list) + yield from validator.related_articles_doi() + + +def validate_supplementary_material(xmltree, sps_version, params): + # FIXME validações incompletas + validator = SupplementaryMaterialValidation(xmltree) + yield from validator.validate_supplementary_material_existence() + + +def validate_table_wrap(xmltree, sps_version, params): + # FIXME validações incompletas + validator = TableWrapValidation(xmltree) + yield from validator.validate_tablewrap_existence() + + +def process_folder(input_folder, output_folder, params, selected_fields): + # Verifica se a pasta de saída existe, e caso não exista, cria a pasta + if not os.path.exists(output_folder): + os.makedirs(output_folder) + + # Percorre todos os arquivos na pasta de entrada + for filename in os.listdir(input_folder): + # Verifica se o arquivo termina com a extensão '.xml' + if filename.endswith('.xml'): + # Constrói o caminho completo do arquivo XML + file_path = os.path.join(input_folder, filename) + # Constrói o caminho completo do arquivo de saída CSV, usando o mesmo nome do arquivo XML, mas com extensão '.csv' + output_file = os.path.join(output_folder, f"{os.path.splitext(filename)[0]}.csv") + # Chama a função create_report para criar o relatório CSV com base no arquivo XML, passando os parâmetros e os campos selecionados + create_report(output_file, file_path, params, selected_fields) + + + +if __name__ == "__main__": + # Inicializa o analisador de argumentos para a linha de comando + parser = argparse.ArgumentParser(description="Validate XML files and save the results to CSV.") + + # Adiciona argumento obrigatório para a pasta de entrada contendo os arquivos XML a serem validados + parser.add_argument('-i', dest='input_folder', required=True, help='Folder path containing XML files to validate') + + # Adiciona argumento obrigatório para a pasta de saída onde os arquivos CSV com os resultados das validações serão salvos + parser.add_argument('-o', dest='output_folder', required=True, + help='Folder path to save the validation result CSV files') + + # Adiciona argumento opcional para listar os campos a serem incluídos no CSV + parser.add_argument('--fields', required=False, nargs='+', help='List of fields to include in the CSV') + + # Adiciona argumento opcional para especificar um dicionário com parâmetros a serem considerados nas validações + parser.add_argument('--params', required=False, nargs='+', + help='Dictionary with parameters to be considered in the validations') + + # Analisa os argumentos fornecidos na linha de comando + args = parser.parse_args() + + # Comenta a linha que pega os parâmetros dos argumentos + # params = args.params + + # Define um dicionário de parâmetros apenas para teste + params = { + "journal_acron": "aaa", + "publisher_name_list": ["aaa", "bbb"], + "nlm_ta": "ccc" + } + + # Verifica se os campos foram fornecidos nos argumentos + if args.fields: + # Se fornecido, usa os campos especificados pelo usuário + selected_fields = args.fields + else: + # Caso contrário, usa um conjunto padrão de campos + selected_fields = [ + "title", "parent", "parent_id", "parent_article_type", "parent_lang", + "item", "sub_item", "validation_type", "response", "expected_value", + "got_value", "message", "advice", "data", + "group", "exception", "exc_traceback", "function", "sps_pkg_name" + ] + + # Chama a função process_folder com as pastas de entrada e saída, os parâmetros e os campos selecionados + process_folder(args.input_folder, args.output_folder, params, selected_fields) + diff --git a/tests/sps/models/test_article_and_subarticles.py b/tests/sps/models/test_article_and_subarticles.py index bb3eb5223..f564c1fea 100644 --- a/tests/sps/models/test_article_and_subarticles.py +++ b/tests/sps/models/test_article_and_subarticles.py @@ -49,6 +49,7 @@ def test_elements_order(self): expected = [ { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'lang': 'pt', @@ -56,6 +57,7 @@ def test_elements_order(self): 'subject': 'ARTIGOS' }, { + 'parent': 'sub-article', 'article_id': 's2', 'article_type': 'reviewer-report', 'lang': 'pt', @@ -63,6 +65,7 @@ def test_elements_order(self): 'subject': 'Pareceres' }, { + 'parent': 'sub-article', 'article_id': 's3', 'article_type': 'reviewer-report', 'lang': 'pt', @@ -70,6 +73,7 @@ def test_elements_order(self): 'subject': 'Pareceres' }, { + 'parent': 'sub-article', 'article_id': 's1', 'article_type': 'translation', 'lang': 'en', @@ -77,6 +81,7 @@ def test_elements_order(self): 'subject': 'ARTICLES' }, { + 'parent': 'sub-article', 'article_id': 's5', 'article_type': 'reviewer-report', 'lang': 'en', @@ -84,6 +89,7 @@ def test_elements_order(self): 'subject': 'Reviews' }, { + 'parent': 'sub-article', 'article_id': 's6', 'article_type': 'reviewer-report', 'lang': 'en', diff --git a/tests/sps/validation/test_article_and_subarticles.py b/tests/sps/validation/test_article_and_subarticles.py index fd4c2c97a..253eae832 100644 --- a/tests/sps/validation/test_article_and_subarticles.py +++ b/tests/sps/validation/test_article_and_subarticles.py @@ -45,6 +45,7 @@ def test_article_has_no_language_attribute(self): 'message': "Got None, expected ['pt', 'en', 'es']", "advice": "
has None as language, expected one item of this list: pt | en | es", 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'lang': None, @@ -92,6 +93,7 @@ def test_article_has_valid_language(self): "message": "Got en, expected ['pt', 'en', 'es']", "advice": None, "data": { + 'parent': 'article', "article_id": None, 'article_type': 'research-article', 'lang': 'en', @@ -139,6 +141,7 @@ def test_article_has_invalid_language(self): 'message': "Got e, expected ['pt', 'en', 'es']", "advice": "
has e as language, expected one item of this list: pt | en | es", 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'lang': 'e', @@ -176,6 +179,7 @@ def test_article_and_subarticles_have_valid_languages(self): 'message': "Got en, expected ['pt', 'en', 'es']", "advice": None, 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'lang': 'en', @@ -198,6 +202,7 @@ def test_article_and_subarticles_have_valid_languages(self): 'message': "Got pt, expected ['pt', 'en', 'es']", "advice": None, 'data': { + 'parent': 'sub-article', 'article_id': 's1', 'article_type': 'translation', 'lang': 'pt', @@ -220,6 +225,7 @@ def test_article_and_subarticles_have_valid_languages(self): 'message': "Got es, expected ['pt', 'en', 'es']", "advice": None, 'data': { + 'parent': 'sub-article', 'article_id': 's2', 'article_type': 'translation', 'lang': 'es', @@ -264,6 +270,7 @@ def test_article_and_subarticles_with_three_valid_languages(self): 'message': "Got en, expected ['pt', 'en', 'es']", "advice": None, 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'lang': 'en', @@ -286,6 +293,7 @@ def test_article_and_subarticles_with_three_valid_languages(self): 'message': "Got pt, expected ['pt', 'en', 'es']", "advice": None, 'data': { + 'parent': 'sub-article', 'article_id': 's1', 'article_type': 'translation', 'lang': 'pt', @@ -308,6 +316,7 @@ def test_article_and_subarticles_with_three_valid_languages(self): 'message': "Got es, expected ['pt', 'en', 'es']", "advice": None, 'data': { + 'parent': 'sub-article', 'article_id': 's2', 'article_type': 'translation', 'lang': 'es', @@ -351,6 +360,7 @@ def test_article_and_subarticles_with_two_valid_languages_and_one_invalid(self): 'message': "Got en, expected ['pt', 'en', 'es']", "advice": None, 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'lang': 'en', @@ -373,6 +383,7 @@ def test_article_and_subarticles_with_two_valid_languages_and_one_invalid(self): 'message': "Got pt, expected ['pt', 'en', 'es']", "advice": None, 'data': { + 'parent': 'sub-article', 'article_id': 's1', 'article_type': 'translation', 'lang': 'pt', @@ -395,6 +406,7 @@ def test_article_and_subarticles_with_two_valid_languages_and_one_invalid(self): 'message': "Got , expected ['pt', 'en', 'es']", "advice": " has as language, expected one item of this list: pt | en | es", 'data': { + 'parent': 'sub-article', 'article_id': 's2', 'article_type': 'translation', 'lang': '', @@ -438,6 +450,7 @@ def test_article_and_subarticles_with_one_valid_language_one_empty_and_one_inval 'message': "Got en, expected ['pt', 'en', 'es']", "advice": None, 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'lang': 'en', @@ -460,6 +473,7 @@ def test_article_and_subarticles_with_one_valid_language_one_empty_and_one_inval 'message': "Got None, expected ['pt', 'en', 'es']", "advice": " has None as language, expected one item of this list: pt | en | es", 'data': { + 'parent': 'sub-article', 'article_id': 's1', 'article_type': 'translation', 'lang': None, @@ -482,6 +496,7 @@ def test_article_and_subarticles_with_one_valid_language_one_empty_and_one_inval 'message': "Got , expected ['pt', 'en', 'es']", "advice": " has as language, expected one item of this list: pt | en | es", 'data': { + 'parent': 'sub-article', 'article_id': 's2', 'article_type': 'translation', 'lang': '', @@ -526,6 +541,7 @@ def test_article_and_subarticles_with_two_invalid_languages(self): 'message': "Got portugol, expected ['pt', 'en', 'es']", "advice": "
has portugol as language, expected one item of this list: pt | en | es", 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'lang': 'portugol', @@ -548,6 +564,7 @@ def test_article_and_subarticles_with_two_invalid_languages(self): 'message': "Got en, expected ['pt', 'en', 'es']", "advice": None, 'data': { + 'parent': 'sub-article', 'article_id': 's1', 'article_type': 'translation', 'lang': 'en', @@ -570,6 +587,7 @@ def test_article_and_subarticles_with_two_invalid_languages(self): 'message': "Got thisisaninvalidlanguagecode, expected ['pt', 'en', 'es']", "advice": " has thisisaninvalidlanguagecode as language, expected one item of this list: pt | en | es", 'data': { + 'parent': 'sub-article', 'article_id': 's2', 'article_type': 'translation', 'lang': 'thisisaninvalidlanguagecode', @@ -616,6 +634,7 @@ def test_article_and_subarticles_specific_use(self): 'message': "Got sps-1.9, expected ['sps-1.9', 'preprint', 'special-issue']", "advice": None, 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'dtd_version': '1.1', @@ -663,6 +682,7 @@ def test_article_and_subarticles_without_specific_use(self): 'message': "Got None, expected ['sps-1.9', 'preprint', 'special-issue']", "advice": "XML research-article has None as specific-use, expected one item of this list: sps-1.9 | preprint | special-issue", 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'dtd_version': '1.1', @@ -710,6 +730,7 @@ def test_article_and_subarticles_dtd_version(self): 'message': "Got 1.1, expected ['1.1', '1.2', '1.3']", "advice": None, 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'dtd_version': '1.1', @@ -737,7 +758,10 @@ def test_article_and_subarticles_article_type_is_valid(self): obtained = list( ArticleTypeValidation(xml_tree).validate_article_type( - article_type_list=["research-article"] + article_type_list={ + "article": ["research-article"], + "sub-article": ["translation"] + } ) ) @@ -757,6 +781,7 @@ def test_article_and_subarticles_article_type_is_valid(self): 'message': "Got research-article, expected ['research-article']", "advice": None, 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'dtd_version': None, @@ -765,18 +790,70 @@ def test_article_and_subarticles_article_type_is_valid(self): 'specific_use': 'sps-1.9', 'subject': None } + }, + { + "title": "Article type validation", + 'parent': 'sub-article', + 'parent_id': 's1', + 'parent_article_type': 'translation', + 'parent_lang': 'en', + 'item': 'article', + 'sub_item': '@article-type', + "validation_type": "value in list", + "response": "OK", + 'expected_value': ['translation'], + 'got_value': 'translation', + 'message': "Got translation, expected ['translation']", + "advice": None, + 'data': { + 'parent': 'sub-article', + 'article_id': 's1', + 'article_type': 'translation', + 'dtd_version': None, + 'lang': 'en', + 'line_number': 3, + 'specific_use': 'sps-1.9', + 'subject': None + } + }, + { + "title": "Article type validation", + 'parent': 'sub-article', + 'parent_id': 's2', + 'parent_article_type': 'translation', + 'parent_lang': 'thisisaninvalidlanguagecode', + 'item': 'article', + 'sub_item': '@article-type', + "validation_type": "value in list", + "response": "OK", + 'expected_value': ['translation'], + 'got_value': 'translation', + 'message': "Got translation, expected ['translation']", + "advice": None, + 'data': { + 'parent': 'sub-article', + 'article_id': 's2', + 'article_type': 'translation', + 'dtd_version': None, + 'lang': 'thisisaninvalidlanguagecode', + 'line_number': 5, + 'specific_use': 'sps-1.9', + 'subject': None + } } ] - self.assertEqual(obtained, expected) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(item, obtained[i]) def test_article_and_subarticles_article_type_is_not_valid(self): self.maxDiff = None xml_str = """
- + - +
""" @@ -784,7 +861,10 @@ def test_article_and_subarticles_article_type_is_not_valid(self): obtained = list( ArticleTypeValidation(xml_tree).validate_article_type( - article_type_list=["research-article"] + article_type_list={ + "article": ["research-article"], + "sub-article": ["translation"] + } ) ) @@ -804,6 +884,7 @@ def test_article_and_subarticles_article_type_is_not_valid(self): 'message': "Got main, expected ['research-article']", "advice": "XML has main as article-type, expected one item of this list: research-article", 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'main', 'dtd_version': None, @@ -812,10 +893,62 @@ def test_article_and_subarticles_article_type_is_not_valid(self): 'specific_use': 'sps-1.9', 'subject': None }, + }, + { + "title": "Article type validation", + 'parent': 'sub-article', + 'parent_id': 's1', + 'parent_article_type': 'type_1', + 'parent_lang': 'en', + 'item': 'article', + 'sub_item': '@article-type', + "validation_type": "value in list", + "response": "CRITICAL", + "expected_value": ["translation"], + "got_value": "type_1", + 'message': "Got type_1, expected ['translation']", + 'advice': "XML has type_1 as article-type, expected one item of this list: translation", + 'data': { + 'parent': 'sub-article', + 'article_id': 's1', + 'article_type': 'type_1', + 'dtd_version': None, + 'lang': 'en', + 'line_number': 3, + 'specific_use': 'sps-1.9', + 'subject': None + }, + }, + { + "title": "Article type validation", + 'parent': 'sub-article', + 'parent_id': 's2', + 'parent_article_type': 'type_2', + 'parent_lang': 'thisisaninvalidlanguagecode', + 'item': 'article', + 'sub_item': '@article-type', + "validation_type": "value in list", + "response": "CRITICAL", + "expected_value": ["translation"], + "got_value": "type_2", + 'message': "Got type_2, expected ['translation']", + 'advice': "XML has type_2 as article-type, expected one item of this list: translation", + 'data': { + 'parent': 'sub-article', + 'article_id': 's2', + 'article_type': 'type_2', + 'dtd_version': None, + 'lang': 'thisisaninvalidlanguagecode', + 'line_number': 5, + 'specific_use': 'sps-1.9', + 'subject': None + }, } ] - self.assertEqual(obtained, expected) + for i, item in enumerate(expected): + with self.subTest(i): + self.assertDictEqual(item, obtained[i]) def test_article_and_subarticles_article_type_vs_subject_similarity(self): self.maxDiff = None @@ -875,6 +1008,7 @@ def test_article_and_subarticles_article_type_vs_subject_similarity(self): "advice": "The subject Scientific Article (en) does not match the items provided in the list: " "Original Article (en) | Artigo Original (pt) | Artículo Original (es)", 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'dtd_version': '1.1', @@ -900,6 +1034,7 @@ def test_article_and_subarticles_article_type_vs_subject_similarity(self): "advice": "The subject Artigo Científico (pt) does not match the items provided in the list: " "Original Article (en) | Artigo Original (pt) | Artículo Original (es)", 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'dtd_version': '1.1', @@ -925,6 +1060,7 @@ def test_article_and_subarticles_article_type_vs_subject_similarity(self): "advice": "The subject Artículo Científico (es) does not match the items provided in the list: " "Original Article (en) | Artigo Original (pt) | Artículo Original (es)", 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'dtd_version': '1.1', @@ -1096,6 +1232,7 @@ def test_article_and_subarticles_without_dtd_version(self): 'message': "Got None, expected ['1.1', '1.2', '1.3']", 'advice': 'XML research-article has None as dtd-version, expected one item of this list: 1.1 | 1.2 | 1.3', 'data': { + 'parent': 'article', 'article_id': None, 'article_type': 'research-article', 'dtd_version': None, diff --git a/tests/sps/validation/test_journal_meta.py b/tests/sps/validation/test_journal_meta.py index da1995709..3cfa12306 100644 --- a/tests/sps/validation/test_journal_meta.py +++ b/tests/sps/validation/test_journal_meta.py @@ -114,38 +114,50 @@ def test_acronym_validation_success(self): expected = [ { 'title': 'Journal acronym element validation', - 'xpath': './/journal-meta//journal-id[@journal-id-type="publisher-id"]', + 'parent': 'article', + 'parent_article_type': 'research-article', + 'parent_id': None, + 'parent_lang': 'pt', + 'item': 'journal-id', + 'sub_item': "@journal-id-type='publisher-id'", 'validation_type': 'value', 'response': 'OK', 'expected_value': 'hcsm', 'got_value': 'hcsm', - 'message': 'Got hcsm expected hcsm', - 'advice': None + 'message': 'Got hcsm, expected hcsm', + 'advice': None, + 'data': {'acronym': 'hcsm'} } ] - obtained = self.acronym.acronym_validation('hcsm') - for i, item in enumerate(obtained): + obtained = list(self.acronym.acronym_validation('hcsm')) + for i, item in enumerate(expected): with self.subTest(i): - self.assertDictEqual(expected[i], item) + self.assertDictEqual(obtained[i], item) def test_acronym_validation_fail(self): self.maxDiff = None expected = [ { 'title': 'Journal acronym element validation', - 'xpath': './/journal-meta//journal-id[@journal-id-type="publisher-id"]', + 'parent': 'article', + 'parent_article_type': 'research-article', + 'parent_id': None, + 'parent_lang': 'pt', + 'item': 'journal-id', + 'sub_item': "@journal-id-type='publisher-id'", 'validation_type': 'value', - 'response': 'ERROR', + 'response': 'CRITICAL', 'expected_value': 'hcs', 'got_value': 'hcsm', - 'message': 'Got hcsm expected hcs', - 'advice': 'Provide an acronym value as expected: hcs' + 'message': 'Got hcsm, expected hcs', + 'advice': 'Provide an acronym value as expected: hcs', + 'data': {'acronym': 'hcsm'} } ] - obtained = self.acronym.acronym_validation('hcs') - for i, item in enumerate(obtained): + obtained = list(self.acronym.acronym_validation('hcs')) + for i, item in enumerate(expected): with self.subTest(i): - self.assertDictEqual(expected[i], item) + self.assertDictEqual(obtained[i], item) class TitleTest(TestCase): @@ -633,13 +645,19 @@ def test_journal_meta_match(self): }, { 'title': 'Journal acronym element validation', - 'xpath': './/journal-meta//journal-id[@journal-id-type="publisher-id"]', + 'parent': 'article', + 'parent_article_type': 'research-article', + 'parent_id': None, + 'parent_lang': 'en', + 'item': 'journal-id', + 'sub_item': "@journal-id-type='publisher-id'", 'validation_type': 'value', 'response': 'OK', 'expected_value': 'hcsm', 'got_value': 'hcsm', - 'message': 'Got hcsm expected hcsm', - 'advice': None + 'message': 'Got hcsm, expected hcsm', + 'advice': None, + 'data': {'acronym': 'hcsm'} }, { 'title': 'Journal title element validation',