From adbf8ca0c21a20a34a26adc4c1397536bdc09869 Mon Sep 17 00:00:00 2001 From: Rossi-Luciano Date: Fri, 26 Jun 2026 12:02:28 -0300 Subject: [PATCH 1/2] Atualiza packtools de 4.12.6 para 4.16.5 Closes #7 Co-Authored-By: Claude Sonnet 4.6 --- spsvalidator/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spsvalidator/pyproject.toml b/spsvalidator/pyproject.toml index 68db3dc..1e2a1a0 100644 --- a/spsvalidator/pyproject.toml +++ b/spsvalidator/pyproject.toml @@ -11,7 +11,7 @@ requires-python = ">=3.11" dependencies = [ "Flask>=3.0.0", "lxml>=5.0.0", - "packtools @ git+https://git@github.com/scieloorg/packtools@4.12.6", + "packtools @ git+https://git@github.com/scieloorg/packtools@4.16.5", "pywebview>=5.1", "setuptools>=68,<82", "requests>=2.31.0", From 11df52514322b67cd964b81766bad7c393662cf5 Mon Sep 17 00:00:00 2001 From: Rossi-Luciano Date: Sat, 27 Jun 2026 14:51:58 -0300 Subject: [PATCH 2/2] =?UTF-8?q?Adiciona=20testes=20de=20cobertura=20e=20co?= =?UTF-8?q?mportamento=20para=20valida=C3=A7=C3=B5es=20do=20packtools=204.?= =?UTF-8?q?16.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 36 testes de cobertura verificam que validate_sps_zip chama todas as funções validate_* do packtools via monkeypatch. 12 testes de comportamento confirmam que grupos novos do 4.16.x (table-wrap, sec, permissions, fig, fn, history, list, related-article, reference, ext-link, graphic, abstract) detectam problemas reais em XML mínimo e autocontido. Co-Authored-By: Claude Sonnet 4.6 --- .../tests/test_packtools_validations.py | 322 ++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 spsvalidator/tests/test_packtools_validations.py diff --git a/spsvalidator/tests/test_packtools_validations.py b/spsvalidator/tests/test_packtools_validations.py new file mode 100644 index 0000000..f453e62 --- /dev/null +++ b/spsvalidator/tests/test_packtools_validations.py @@ -0,0 +1,322 @@ +""" +Verifica que validate_sps_zip exercita todos os 36 grupos de validação +definidos no packtools 4.16.5 xml_validator.py. + +Duas camadas de testes: + 1. Cobertura — cada função validate_* é chamada por validate_sps_zip. + 2. Comportamento — grupos novos no 4.16.x detectam problemas em XML real. +""" +from __future__ import annotations + +import zipfile +from textwrap import dedent + +import pytest + +from spsvalidator.domain.validation import validate_sps_zip + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _make_zip(tmp_path, xml_content: str) -> str: + zip_path = tmp_path / "test.zip" + with zipfile.ZipFile(zip_path, "w") as zf: + zf.writestr("article.xml", xml_content) + return str(zip_path) + + +def _rows_groups(result) -> set[str]: + return {r["group"] for r in result["rows"]} + + +def _all_groups(result) -> set[str]: + """Grupos em rows E em exceptions (inclui casos onde packtools lança exceção).""" + return _rows_groups(result) | {r["group"] for r in result["exceptions"]} + + +def _article( + *, + body: str = "", + back: str = "", + extra_meta: str = "", + include_permissions: bool = True, +) -> str: + permissions_block = ( + dedent("""\ + + + Open access. + + """) + if include_permissions + else "" + ) + default_body = "Introduction

Text.

" + return ( + '\n' + '
\n' + "\n" + "\n" + 'Rev Test\n' + "" + "Revista de Teste" + 'Rev. Teste' + "\n" + '1234-5678\n' + "Publisher\n" + "\n" + "\n" + '10.1234/test.2023.001\n' + 'S1234-56782023000100001\n' + "" + 'Original Article' + "\n" + "Test Article Title\n" + "" + '' + "SilvaJoão" + "" + "\n" + '' + "20230101" + "\n" + "1\n" + "e001\n" + + permissions_block + "\n" + + extra_meta + "\n" + "\n" + "\n" + "" + (body or default_body) + "\n" + "" + back + "\n" + "
\n" + ) + + +# --------------------------------------------------------------------------- +# 1. Cobertura: cada função validate_* é chamada por validate_sps_zip +# --------------------------------------------------------------------------- + +# (group_name, function_name em xml_validations) +VALIDATION_FUNCTIONS = [ + ("journal-meta", "validate_journal_meta"), + ("bibliographic strip", "validate_bibliographic_strip"), + ("article attributes", "validate_article"), + ("article-id", "validate_article_ids"), + ("article dates", "validate_article_dates"), + ("history", "validate_history"), + ("article languages (1)", "validate_article_languages"), + ("article languages (2)", "validate_metadata_languages"), + ("subject", "validate_article_toc_sections"), + ("article-type", "validate_article_type"), + ("contrib", "validate_article_contribs"), + ("aff", "validate_affiliations"), + ("author-notes", "validate_author_notes"), + ("abstract", "validate_abstracts"), + ("open science", "validate_open_science_actions"), + ("funding data", "validate_funding_data"), + ("id and rid", "validate_id_and_rid_match"), + ("fig", "validate_figs"), + ("table-wrap", "validate_tablewraps"), + ("disp-formula", "validate_equations"), + ("inline-formula", "validate_inline_equations"), + ("reference", "validate_references"), + ("related-article", "validate_related_articles"), + ("fn", "validate_fns"), + ("reviewer-report", "validate_peer_reviews"), + ("accessibility", "validate_accessibility_data"), + ("media", "validate_media"), + ("app", "validate_app_group"), + ("supplementary-material", "validate_supplementary_materials"), + ("ext-link", "validate_ext_links"), + ("list", "validate_lists"), + ("graphic", "validate_graphics"), + ("response", "validate_response"), + ("sec", "validate_secs"), + ("product", "validate_products"), + ("permissions", "validate_permissions"), +] + + +@pytest.mark.parametrize( + "group,func_name", + VALIDATION_FUNCTIONS, + ids=[func for _, func in VALIDATION_FUNCTIONS], +) +def test_validation_function_is_called(tmp_path, monkeypatch, group, func_name): + """Cada função validate_* do packtools deve ser chamada por validate_sps_zip.""" + from packtools.sps.validation import xml_validations + + called = {"yes": False} + original = getattr(xml_validations, func_name) + + def spy(*args, **kwargs): + called["yes"] = True + return original(*args, **kwargs) + + monkeypatch.setattr(xml_validations, func_name, spy) + validate_sps_zip(_make_zip(tmp_path, _article())) + + assert called["yes"], f"{func_name} não foi chamada por validate_sps_zip" + + +# --------------------------------------------------------------------------- +# 2. Comportamento: grupos novos no 4.16.x detectam problemas reais +# --------------------------------------------------------------------------- + + +def test_table_wrap_sem_label_e_caption_reporta_issue(tmp_path): + """ sem