Valida pub-date "pub" contra hoje e contra collection (#1268) - #1273
Valida pub-date "pub" contra hoje e contra collection (#1268)#1273Rossi-Luciano wants to merge 2 commits into
Conversation
…on (scieloorg#1268) Adiciona duas novas regras em FulltextDatesValidation: pub-date[date-type="pub"] não pode estar no futuro além de uma tolerância em dias, e não pode ser mais de N meses anterior ao ano de pub-date[date-type="collection"]. Ambas as tolerâncias são parametrizáveis via article_dates_rules.json. Resolve o gap relatado na issue: um typo no ano de pub (ex. 2029 em vez de 2026) fazia o OPAC ocultar o artigo silenciosamente, sem gerar erro em nenhuma validação existente.
| expected=f'<pub-date date-type="pub"> no later than {limit.isoformat()}', | ||
| obtained=pub_date.isoformat(), | ||
| advice=f'<pub-date date-type="pub"> ({pub_date.isoformat()}) must not be later than {limit.isoformat()}', | ||
| advice_text=i18n._('<pub-date date-type="pub"> ({pub_date}) must not be later than {limit}'), |
There was a problem hiding this comment.
@Rossi-Luciano suspeito que isso não funciona:
i18n._('<pub-date date-type="pub"> ({pub_date}) must not be later than {limit}')
teria que ser
i18n._('<pub-date date-type="pub"> ({pub_date}) must not be later than {limit}').format(
pub_date=pub_date,
limit=limit
)
There was a problem hiding this comment.
@robertatakenaka checando com calma, isso segue o mesmo padrão usado em todo o módulo sps/validation/ (não é específico dessas duas linhas): advice_text=i18n._("...{pub_date}...{limit}") é armazenado como template (sem .format()), e os valores ficam separados em advice_params. O build_response() retorna os dois como adv_text (template traduzido) e adv_params (valores), para o consumidor renderizar com adv_text.format(**adv_params), exatamente como msg_text/msg_params já fazem, documentado em tests/sps/validation/test_i18n_message_rendering.py::render_message.
Testei manualmente as duas mensagens (regra 1 e regra 2) chamando adv_text.format(**adv_params) e ambas renderizam corretamente, sem KeyError:
<pub-date date-type="pub"> (2029-07-27) must not be later than 2026-06-15
<pub-date date-type="pub"> (2024-01-01) must not be more than 12 months before <pub-date date-type="collection"> year (2026)
Se eu aplicasse .format() aqui dentro do dates.py, o adv_text passaria a conter a string já interpolada em inglês, quebrando a tradução dinâmica para outros locales (diferente de todos os outros validators do módulo). Por isso preferi manter como está, mas se você já sabia disso e mesmo assim prefere mudar o padrão aqui, me avisa que ajusto.
Também adicionei em test_dates.py a renderização explícita de adv_text.format(**adv_params) nos casos de erro, para isso ficar coberto automaticamente daqui pra frente.
| expected=f'<pub-date date-type="pub"> no earlier than {earliest_allowed.isoformat()} ({tolerance_months} months before collection year {collection_year})', | ||
| obtained=pub_date.isoformat(), | ||
| advice=f'<pub-date date-type="pub"> ({pub_date.isoformat()}) must not be more than {tolerance_months} months before <pub-date date-type="collection"> year ({collection_year})', | ||
| advice_text=i18n._('<pub-date date-type="pub"> ({pub_date}) must not be more than {tolerance_months} months before <pub-date date-type="collection"> year ({collection_year})'), |
There was a problem hiding this comment.
@robertatakenaka mesma explicação do comentário na linha 592 (padrão advice_text/advice_params → adv_text/adv_params, formatado pelo consumidor, igual msg_text/msg_params). Também validei essa mensagem especificamente e renderiza corretamente com adv_text.format(**adv_params).
| "month_value_error_level":"ERROR", | ||
| "pub_date_future_error_level":"CRITICAL", | ||
| "pub_date_past_collection_error_level":"CRITICAL", | ||
| "pub_date_future_tolerance_days":0, |
There was a problem hiding this comment.
@robertatakenaka aplicado: mudei pub_date_future_tolerance_days de 0 para 7 no article_dates_rules.json. De quebra descobri que esse valor também tinha um default hardcoded (dessincronizado, ainda 0) em FulltextDatesValidation._get_default_params() no dates.py, que é o que os testes de fato usam quando instanciam o validator diretamente, então corrigi os dois lugares. Testes atualizados e passando (commit novo no PR).
| pub = date(collection_year - 2, 1, 1) # bem além da tolerância de 12 meses | ||
| _, distance = self._results(pub, collection_year=collection_year) | ||
| self.assertEqual("CRITICAL", distance[0]["response"]) | ||
| self.assertIn("must not be more than", distance[0]["advice"]) |
There was a problem hiding this comment.
@Rossi-Luciano alguns lugares está more than e later than...
There was a problem hiding this comment.
@robertatakenaka boa observação, mas não é acidental: são duas comparações diferentes. "later than {limit}" para a regra 1 (pub comparado a uma data-limite) e "more than {N} months before {collection}" para a regra 2 (pub comparado a uma duração/intervalo). Achei que cada frase fica mais natural para o tipo de comparação que descreve, mas se preferir uma redação única para as duas mensagens (facilita grep/padronização), me diga qual formato prefere que eu unifico.
| "'received' está presente no histórico e não deve aparecer em missing_events") | ||
|
|
||
|
|
||
| class TestPubDateFutureAndCollectionDistanceValidation(TestCase): |
There was a problem hiding this comment.
@Rossi-Luciano tem muitos testes em que é OK. Gostaria de ver mais testes apresentando a mensagem de erro, pois ajuda a visualizar a lógica.
There was a problem hiding this comment.
@robertatakenaka aplicado: adicionei assertIn/assertEqual sobre advice e sobre o adv_text.format(**adv_params) renderizado nos 3 casos de erro que antes só checavam o response ("CRITICAL"), cobrindo agora as duas regras e o caso de coleção retrospectiva + futuro. Commit novo no PR.
robertatakenaka
left a comment
There was a problem hiding this comment.
@Rossi-Luciano melhore os testes para ficar mais claro se a lógica está correta.
…cieloorg#1268) Aplica feedback da revisão em PR scieloorg#1273: tolerância de pub_date_future_tolerance_days alterada de 0 para 7 dias (confirmado pela equipe editorial), sincronizada tanto no default hardcoded de FulltextDatesValidation quanto em article_dates_rules.json (estavam dessincronizados). Adiciona asserções de conteúdo de mensagem de erro (via adv_text.format(**adv_params)) aos casos de erro que só verificavam o response level.
O que esse PR faz?
Adiciona duas novas regras de validação em
FulltextDatesValidation(packtools/sps/validation/dates.py), especificamente parapub-date[@date-type="pub"]:validate_pub_date_not_in_future—pubnão pode estar no futuro além de uma tolerância em dias (pub_date_future_tolerance_days, default0).validate_pub_date_not_too_far_before_collection—pubnão pode ser mais de N meses anterior ao ano depub-date[@date-type="collection"](pub_date_past_collection_tolerance_months, default12).Ambas as tolerâncias são parametrizáveis via
article_dates_rules.json(novas chavespub_date_future_tolerance_days,pub_date_past_collection_tolerance_months, e os respectivos*_error_level, defaultCRITICAL).Coleções retrospectivas (
pubmuito posterior aocollection, mas não no futuro) continuam permitidas — não há checagem que bloqueie esse caso, comportamento coberto por teste de regressão.Também adiciona as mensagens de advice correspondentes aos catálogos de i18n (
pt_BRees).Onde a revisão poderia começar?
packtools/sps/validation/dates.py— métodosvalidate_pub_date_not_in_futureevalidate_pub_date_not_too_far_before_collection, e o registro delas emFulltextDatesValidation.validate().packtools/sps/validation_rules/article_dates_rules.json— novas chaves de configuração.tests/sps/validation/test_dates.py— classeTestPubDateFutureAndCollectionDistanceValidation.Como este poderia ser testado manualmente?
Deve incluir
CRITICAL - pub-date pub not in future - ... must not be later than <hoje>.pytest tests/sps/validation/test_dates.py -vcobre os 8 casos descritos na issue (A–E da tabela), incluindo o cenário exato do bug relatado (pub=2029, collection=2026).Algum cenário de contexto que queira dar?
A issue relata que o artigo
0102-6720-abcd-39-e1948(PIDS0102-67202026000100609) ficou oculto silenciosamente em produção porquepub-date[@date-type="pub"]foi digitado como2029em vez de2026. O OPAC filtra artigos compubno futuro (mecanismo de "data de estreia" agendada), e nenhuma validação existente sinalizava isso — as validações atuais (schematron legado eyear_value/complete_datedo módulo novo) ou não checam valor de data, ou usam tolerâncias amplas (quase 1 ano) que não cobrem todos os casos, e nenhuma comparapubcomcollection.As tolerâncias exatas (dias no futuro / meses no passado) ficam parametrizáveis e usam os defaults sugeridos no pseudocódigo da própria issue; a issue menciona que os valores exatos ainda serão confirmados com a equipe editorial.
Quais são tickets relevantes?
Closes #1268
Referências
Pseudocódigo e tabela de casos de teste vieram diretamente da issue #1268.