From 9ac609c97c82a329f1c902deae4f02819a1898d6 Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Tue, 1 Sep 2026 11:31:25 -0300 Subject: [PATCH 1/5] Align pkg_name lookup with the authoritative source of name variations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delega a obtenção das variações de pkg_name para `xml_with_pre.pkg_name_variations`, que já concentra os nomes depreciados/alternativos do pacote. Mantém o cálculo local como fallback, capturando AttributeError, para preservar a compatibilidade com versões de packtools que ainda não expõem esse atributo. --- pid_provider/query_params.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pid_provider/query_params.py b/pid_provider/query_params.py index 77df860e..b00b66ce 100644 --- a/pid_provider/query_params.py +++ b/pid_provider/query_params.py @@ -7,6 +7,15 @@ from pid_provider import exceptions +def fix_xml_with_pre_data(xml_with_pre): + data = xml_with_pre.data + try: + data["pkg_names"] = xml_with_pre.pkg_name_variations + except AttributeError: + pass + return data + + def fix_get_data_to_compare(xml_adapter): """ packtools 4.16.11 @@ -217,6 +226,10 @@ def pkg_name_list(self): todos os nomes depreciados/alternativos já usados no passado. Valores falsy são descartados. """ + try: + return self.xml_adapter.xml_with_pre.pkg_name_variations + except AttributeError: + pass pkg_names = set() if self.xml_adapter.pkg_name: pkg_names.add(self.xml_adapter.pkg_name) From e12d2b9e61920a5a2d071e8b6578214ed5bd8251 Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Tue, 1 Sep 2026 11:32:39 -0300 Subject: [PATCH 2/5] Normalize XML input data before recording it in provider responses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passa a obter os dados de entrada por `fix_xml_with_pre_data(xml_with_pre)` no lugar do acesso direto a `xml_with_pre.data`, tanto no registro do `input_data` quanto na resposta de consulta. Importa a função a partir de `pid_provider.query_params`, mantendo a normalização de formato concentrada nesse módulo. --- pid_provider/models.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pid_provider/models.py b/pid_provider/models.py index 7544809f..1cdda209 100644 --- a/pid_provider/models.py +++ b/pid_provider/models.py @@ -39,6 +39,7 @@ QueryBuilderPidProviderXML, fix_get_article_data, fix_get_data_to_compare, + fix_xml_with_pre_data, ) from tracker.models import BaseEvent, UnexpectedEvent @@ -787,7 +788,7 @@ def register( xml_adapter_data = None input_data = {} - input_data.update(xml_with_pre.data) + input_data.update(fix_xml_with_pre_data(xml_with_pre)) input_data.update(fix_get_article_data(xml_with_pre)) input_data["origin"] = origin response["input_data"] = input_data @@ -1387,7 +1388,7 @@ def is_registered( try: select_record_response = None response = {} - response["input_data"] = xml_with_pre.data + response["input_data"] = fix_xml_with_pre_data(xml_with_pre) xml_adapter = xml_sps_adapter.PidProviderXMLAdapter(xml_with_pre) response["xml_adapter_data"] = xml_adapter.data From 2abc862ad4219da35f4a08f125cbf7a118aa209a Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Tue, 1 Sep 2026 11:33:09 -0300 Subject: [PATCH 3/5] Make asynchronous task execution the default behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Altera o valor padrão de `RUN_ASYNC` de 0 para 1 em `config/settings/base.py`, de modo que o comportamento assíncrono passe a valer sem depender de configuração explícita no ambiente. --- config/settings/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/settings/base.py b/config/settings/base.py index aa9360af..dcf01b4b 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -542,7 +542,7 @@ # Tempo máximo em segundos que uma tarefa pode levar para ser concluída (timeout "suave"). # `env.int()` garante que o valor lido seja um inteiro. TASK_TIMEOUT = env.int('TASK_TIMEOUT', default=5 * 60) -RUN_ASYNC = env.bool('RUN_ASYNC', default=0) +RUN_ASYNC = env.bool('RUN_ASYNC', default=1) # Celery Results # ------------------------------------------------------------------------------ # https://django-celery-results.readthedocs.io/en/latest/getting_started.html From 26593ca752fcf1112b5bcb4d67c3341ef6f47446 Mon Sep 17 00:00:00 2001 From: Roberta Takenaka Date: Tue, 1 Sep 2026 11:33:17 -0300 Subject: [PATCH 4/5] Allow the local development host name instead of a fixed machine address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Substitui o IP fixo `192.168.1.98` por `core.local` em `ALLOWED_HOSTS`, evitando um endereço vinculado a uma máquina específica no ambiente de desenvolvimento. --- config/settings/local.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/settings/local.py b/config/settings/local.py index 8c0bd947..196f3ee1 100755 --- a/config/settings/local.py +++ b/config/settings/local.py @@ -11,7 +11,7 @@ default="FMiraeekXCSl3zHfg7D4oHx7ufT46HRnwnsawKgTCC53BYajVkVzb8HhOvBOHakR", ) # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts -ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1", "192.168.1.98"] +ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1", "core.local"] # CACHES # ------------------------------------------------------------------------------ From 360329378f80a68366dc8ef130c86c657a6f6aa9 Mon Sep 17 00:00:00 2001 From: Rafael JPD Date: Tue, 1 Sep 2026 13:51:53 -0300 Subject: [PATCH 5/5] Normalize pkg name variations in provider responses Filter falsy package names and serialize response data as a deterministic list while preserving set semantics for queries. Cover the authoritative packtools source and the compatibility fallback. --- pid_provider/query_params.py | 13 ++++--- pid_provider/tests/test_query_params.py | 47 ++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/pid_provider/query_params.py b/pid_provider/query_params.py index b00b66ce..7a33eb7e 100644 --- a/pid_provider/query_params.py +++ b/pid_provider/query_params.py @@ -10,9 +10,11 @@ def fix_xml_with_pre_data(xml_with_pre): data = xml_with_pre.data try: - data["pkg_names"] = xml_with_pre.pkg_name_variations + pkg_names = xml_with_pre.pkg_name_variations except AttributeError: - pass + return data + + data["pkg_names"] = sorted(item for item in (pkg_names or []) if item) return data @@ -227,16 +229,19 @@ def pkg_name_list(self): Valores falsy são descartados. """ try: - return self.xml_adapter.xml_with_pre.pkg_name_variations + pkg_names = self.xml_adapter.xml_with_pre.pkg_name_variations except AttributeError: pass + else: + return {item for item in (pkg_names or []) if item} + pkg_names = set() if self.xml_adapter.pkg_name: pkg_names.add(self.xml_adapter.pkg_name) if self.xml_adapter.sps_pkg_name: pkg_names.add(self.xml_adapter.sps_pkg_name) pkg_names.update(self.xml_adapter.xml_with_pre.deprecated_sps_pkg_name_list) - return set(item for item in pkg_names if item) + return {item for item in pkg_names if item} def validate_input_data(self): """ diff --git a/pid_provider/tests/test_query_params.py b/pid_provider/tests/test_query_params.py index 98f168f7..62a02041 100644 --- a/pid_provider/tests/test_query_params.py +++ b/pid_provider/tests/test_query_params.py @@ -23,6 +23,8 @@ para o módulo real onde essas classes/funções estão definidas no projeto, caso seja diferente. """ +import json +from types import SimpleNamespace from unittest.mock import MagicMock, patch from django.test import SimpleTestCase @@ -34,6 +36,7 @@ compare, compare_items, compare_lists, + fix_xml_with_pre_data, get_score, zero_to_none, ) @@ -82,7 +85,10 @@ def make_xml_adapter( # configurado explicitamente aqui, senão vira um MagicMock não # configurado (nunca None nem o valor esperado). adapter.z_partial_body = (data or {}).get("z_partial_body") - adapter.xml_with_pre.deprecated_sps_pkg_name_list = deprecated_sps_pkg_name_list or [] + del adapter.xml_with_pre.pkg_name_variations + adapter.xml_with_pre.deprecated_sps_pkg_name_list = ( + deprecated_sps_pkg_name_list or [] + ) adapter.xml_with_pre.body_fragment_fingerprint = body_fragment_fingerprint adapter.xml_with_pre.body_fingerprint = body_fingerprint # QueryBuilderPidProviderXML.__init__ lê xml_with_pre.readable_data @@ -100,6 +106,27 @@ def make_xml_adapter( return adapter +class FixXMLWithPreDataTests(SimpleTestCase): + + def test_uses_json_safe_normalized_pkg_name_variations(self): + xml_with_pre = SimpleNamespace( + data={"pid_v3": "V3", "pkg_names": ["legacy"]}, + pkg_name_variations={"pkg-b", None, "", "pkg-a"}, + ) + + result = fix_xml_with_pre_data(xml_with_pre) + + self.assertEqual(result["pkg_names"], ["pkg-a", "pkg-b"]) + json.dumps(result) + + def test_keeps_original_pkg_names_when_attribute_is_unavailable(self): + xml_with_pre = SimpleNamespace(data={"pkg_names": ["legacy"]}) + + result = fix_xml_with_pre_data(xml_with_pre) + + self.assertEqual(result, {"pkg_names": ["legacy"]}) + + class ValidateInputDataTests(SimpleTestCase): def test_raises_when_pub_year_missing(self): @@ -188,6 +215,24 @@ def test_raises_not_enough_parameters_when_body_fragment_is_blank(self): class PkgNameListTests(SimpleTestCase): + def test_uses_authoritative_variations_and_drops_falsy(self): + adapter = make_xml_adapter( + data={}, + pkg_name="fallback-name", + sps_pkg_name="fallback-sps-name", + deprecated_sps_pkg_name_list=["fallback-deprecated-name"], + ) + adapter.xml_with_pre.pkg_name_variations = { + "pkg-b", + None, + "", + "pkg-a", + } + + qbuilder = QueryBuilderPidProviderXML(adapter) + + self.assertEqual(qbuilder.pkg_name_list, {"pkg-a", "pkg-b"}) + def test_combines_all_sources_and_drops_falsy(self): adapter = make_xml_adapter( data={},