Repository navigation
Corrige testes relacionados com editorialboard journal issue - #1486
robertatakenaka merged 12 commits into
Conversation
…esquisador A importação via CSV passa a registrar os membros com NewResearcher em vez do modelo legado Researcher. A afiliação, o ORCID, o Lattes e o e-mail passam a ser gravados nas estruturas próprias do novo modelo, e o ano informado é armazenado como data. Detalhes de implementação: - substitui Researcher.create_or_update por NewResearcher.get_or_create - cria a afiliação com Organization.create_or_update quando a coluna "Instituição" está preenchida, usando a localização da linha - cria o ORCID com ResearcherOrcid.get_or_create quando a coluna "ORCID iD" está preenchida - associa o Lattes e o e-mail com researcher.add_lattes_id e researcher.add_email - converte a coluna "Data" em date(ano, 1, 1) para editorial_board_initial_year e editorial_board_final_year - deixa de repassar declared_name, aff_div1 e aff_div2, que não fazem parte de NewResearcher
…or e o fluxo real do formulário
Os testes passam a usar NewResearcher e ResearcherOrcid e a validar o formulário da mesma forma que o admin do Wagtail o recebe, com dados submetidos. As verificações condicionais foram substituídas por asserções explícitas, para que falhas de gravação não passem despercebidas.
Detalhes de implementação:
- adiciona get_editorialboard_form, que gera a classe de formulário a partir dos panels (get_edit_handler) e inclui o management form do InlinePanel role_editorial_board
- adiciona autocomplete_value para montar o valor esperado pelo widget de AutocompletePanel (researcher e manual_institution_country)
- substitui a criação de ResearcherIds para ORCID, Lattes e e-mail por ResearcherOrcid, add_lattes_id e add_email no setUp
- chama form.is_valid() antes de save_all e verifica non_field_errors no lugar de chamar clean() diretamente
- usa translation.override("en") para verificar a mensagem original, pois LANGUAGE_CODE é pt-br
- troca os blocos if por assertIsNotNone e assertEqual para afiliação, ORCID, Lattes e e-mail
- corrige o Lattes esperado para o valor completo de 16 dígitos
- no teste de importação, guarda o membro, o pesquisador e o cargo em variáveis locais, inclui verificações de afiliação e ORCID e compara initial_year e final_year com date(2020, 1, 1)
- altera o ORCID do CSV de teste e o acrônimo da organização
- remove o caso de ORCID com dígito verificador inválido do teste de clean_orcid, que valida somente o formato (o dígito verificador é validado por ResearcherOrcid.validate_orcid)
…a coleta do ArticleMeta Os eventos inesperados gerados no registro de periódicos vindos do ArticleMeta passam a informar o identificador pelo campo atual do modelo, evitando falha ao montar o detalhe do erro. Detalhes de implementação: - substitui journal_am.scielo_issn por journal_am.pid no campo "issn" do detail dos dois UnexpectedEvent de _register_journal_data - remove os comentários provisórios sobre a troca de campo
…de uso A carga de licenças de uso a partir dos dados do ArticleMeta passa a obter o identificador do periódico pelo campo atual do modelo AMJournal. Detalhes de implementação: - em load_license_of_use_in_journal, substitui journal.scielo_issn por journal.pid
…e de migração confiável O teste da migração de URLs do periódico foi reescrito para funcionar com o Django 5.2 e não deixar o banco de testes em estado inconsistente para as execuções seguintes. Os demais testes passam a usar os nomes de campos atuais dos modelos. Detalhes de implementação: - MigrationTestCase passa a herdar de TransactionTestCase e recebe @tag(MIGRATION_TEST_MARKER), pois o Migrator recria o banco no estado de migrate_from - usa Migrator diretamente porque MigratorTestCase (django-test-migrations 1.3.0) é incompatível com Django 5.2 - define migrate_from e migrate_to como atributos da classe - une os testes de ida e de reversão em test_migration_adding_and_deleting_journal_urls - na reversão, verifica que o modelo JournalURL deixa de existir no estado histórico e que a tabela é removida do banco - registra cleanups para executar migrator.reset() e depois remover o periódico criado - sobrescreve _fixture_teardown para não fazer flush, preservando os dados das data migrations (ex.: coleção raiz do Wagtail) com --keepdb / --reuse-db - substitui scielo_issn por pid na criação de AMJournal - substitui name por main_name na criação de Collection - em RawOrganizationMixinTestCase, deixa de passar raw_text e verifica que ele recebe o valor de original_data
… core_settings As verificações do membro importado passam a indicar explicitamente quando o membro ou o cargo não foram criados, em vez de falhar com AttributeError. Detalhes de implementação: - guarda o membro e o primeiro cargo em variáveis locais, evitando repetir as consultas - adiciona assertIsNotNone para o membro e para o cargo antes das demais asserções
… 5.2 e independente do banco O teste da migração journal.0025_journalurl deixa de aplicar e reverter migrações reais, o que dependia do django-test-migrations (incompatível com Django 5.2), exigia contornos no teardown para não apagar dados das data migrations e tornava a execução lenta e frágil com --keepdb/--reuse-db. Passa a validar diretamente as funções de RunPython da migração, com os modelos mockados, cobrindo tanto a transferência de Journal.journal_url para JournalURL quanto a reversão. Detalhes de implementação: - MigrationTestCase passa de TransactionTestCase para SimpleTestCase, garantindo que nenhuma consulta ao banco seja feita - remove o uso de Migrator, MIGRATION_TEST_MARKER, connection, _fixture_teardown e a limpeza manual do Journal criado - importa a migração via importlib e mocka apps.get_model para devolver MagicMocks de Journal e JournalURL - verifica que a última operação da migração é o RunPython com transfer_journal_url_to_journal_urls_inline_panel e reverse_transfer_journal_url_to_journal_urls_inline_panel - verifica o filtro journal_url__isnull=False, a criação de JournalURL com journal e url e o bulk_create - verifica que a reversão chama JournalURL.objects.all().delete()
…ports Allows importing CSV files using 'organization_name' header while maintaining backward compatibility with 'affiliation'.
Include 'journal_toc' alongside 'journal_toc__language' in the select_related assertion.
|
@robertatakenaka, o PR #1486 está com conflito com a É preciso atualizar a branch com a |
|
@pitangainnovare por favor, revisar novamente |
| ) | ||
| orcid = None | ||
| if row.get("ORCID iD"): | ||
| orcid = ResearcherOrcid.get_or_create( |
There was a problem hiding this comment.
Notei que o save do ResearcherOrcid salva apenas o código, removendo http e outros elementos. A busca, no entanto, apenas valida o conteúdo frente a um regex que permite ou não ter http. Tudo bem, o sistema funciona assim, mas seria interessante padronizar (buscar também só pelo código orcid usando o mesmo normalizador de dados usado no save).
Isso não bloqueia o PR.
| aff_name=row.get("Instituição"), | ||
| ) | ||
| researcher.add_lattes_id(row.get("CV Lattes"), user) | ||
| researcher.add_email(row.get("Email"), user) |
There was a problem hiding this comment.
Como agora estamos usando o NewResearcher.get_or_create(...) e antes era Researcher.create_or_update(...), algumas coisas deixaram de ser usadas. Por exemplo, no email lá no antigo havia um tratamento que substituía , por ; e depois fazia .split(";"). Assim mais de um email informado era corretamente registrado no modelo.
Agora na nova versão, tem-se apenas o add_email, sem qualquer tratamento.
Isso não bloqueia o PR, mas pode ser importante colocar algum tratamento em algum lugar caso haja mais de um email na linha separado por , ou ;.
| given_names=given_names, | ||
| last_name=last_name, | ||
| suffix=row.get("Suffix"), | ||
| declared_name=row.get("declared_person_name"), |
There was a problem hiding this comment.
O valor da coluna declared_person_name deixou de ser enviado ao modelo, então o campo declared_name fica vazio nos novos registros.
Não é grave a ponto de bloquear o PR.
| city=row.get("city_name"), | ||
| state=row.get("state_name"), | ||
| organization_name=row.get("affiliation"), | ||
| organization_name=row.get("organization_name") or row.get("affiliation"), |
There was a problem hiding this comment.
Não faz parte de alteração do PR, mas em core_settings/views.py:12, na função validate_columns_csv():
required = MODEL_TO_IMPORT_CSV.get(type_csv)
columns = {item.strip().lower() for item in columns}
if not required.issubset(columns):exige-se todas as colunas definidas em MODEL_TO_IMPORT_CSV, em config/settings/base.py:688. Lá não tem nada sobre affliation (o fallback usado aqui). Para pesquisadores e membros do conselho, essa configuração inclui organization_name.
Por isso, um CSV com apenas affiliation é rejeitado antes de executar a tarefa que contém o fallback.
| city=row.get("city_name"), | ||
| state=row.get("state_name"), | ||
| organization_name=row.get("affiliation"), | ||
| organization_name=row.get("organization_name") or row.get("affiliation"), |
O que esse PR faz?
Este Pull Request engloba duas melhorias e ajustes principais na aplicação:
core_settings): Adiciona suporte ao cabeçalhoorganization_namenas tarefas de importação de pesquisadores (importar_csv_task_newresearcher) e membros do conselho editorial (importar_csv_task_editorialboardmember). A chave mantém um fallback seguro paraaffiliation, garantindo compatibilidade com arquivos antigos.issue): Atualiza as asserções do testetest_format_code_sections.pypara validar que o parâmetrojournal_tocé passado junto comjournal_toc__languagenas chamadas do métodoselect_related.Onde a revisão poderia começar?
Recomenda-se iniciar a revisão pelo arquivo principal das tarefas:
core_settings/tasks.py— Verifique a lógica do.get("organization_name") or row.get("affiliation").core_settings/tests.py— Observe os cabeçalhos atualizados dos arquivos CSV de teste.issue/test_format_code_sections.py— Avalie o ajuste na asserção doselect_related.Como este poderia ser testado manualmente?
Execute a suíte de testes com o
pytestoumanage.py test:python manage.py test core_settings issueorganization_nameem vez deaffiliatione verifique se o cadastro do usuário/organização ocorre com sucesso.affiliation) para validar a compatibilidade retroativa.Algum cenário de contexto que queira dar?
Alguns fornecedores e fluxos externos passaram a gerar os relatórios utilizando a nomenclatura
organization_nameem vez deaffiliation. Para evitar falhas silenciosas na importação de dados e garantir maior resiliência no processamento assíncrono do Celery/Django, adicionou-se a validação flexível. O ajuste no teste do móduloissueadequa o mocking às consultas otimizadas do ORM.Screenshots
N/A (Alterações restritas a rotinas de backend, testes e processamento de tarefas em segundo plano).
Quais são os tickets relevantes?
Referências
select_related)Segurança da informação (NSI.04)
Este PR manipula dados sensíveis ou pessoais (LGPD)?
Este PR altera autenticação, autorização, controle de acesso ou gerenciamento de sessão?
Este PR introduz, atualiza ou remove dependências de terceiros?
Sim — as novas dependências foram verificadas no SBOM/Trivy sem vulnerabilidades críticas/altas em aberto?
Verificado e aprovado
Pendente / vulnerabilidade aceita com justificativa:
Não
Este PR foi validado pelo pipeline de segurança (SonarQube / Trivy)?
Este PR concatena, monta ou executa comandos SQL, HTML ou JavaScript a partir de entrada externa?
Este PR expõe novos endpoints, telas ou serviços?
Algum segredo, senha, chave ou token está sendo adicionado ao código-fonte?