Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions opac/tests/test_main_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2283,6 +2283,79 @@ def test_journal_detail_with_attrib_is_public_false(self):
self.assertIn(unpublish_reason, response.data.decode("utf-8"))


class TestUpdatePolicy(BaseTestCase):
def test_update_policy_returns_200_when_page_exists(self):
"""
Teste da ``view function`` ``update_policy``, deve retornar uma página
que usa o template ``journal/update_policy.html`` quando a página
de política de atualização existe.
"""
with current_app.app_context():
utils.makeOneCollection()
journal = utils.makeOneJournal()
utils.makeOnePage(
{
"name": "update_policy",
"slug_name": "update-policy",
"language": "pt_BR",
"journal": journal.acronym,
}
)

response = self.client.get(
url_for("main.update_policy", url_seg=journal.url_segment)
)

self.assertStatus(response, 200)
self.assertTemplateUsed("journal/update_policy.html")

def test_update_policy_returns_404_when_no_page(self):
"""
Teste da ``view function`` ``update_policy``, deve retornar 404
quando não existe página de política de atualização cadastrada.
"""
with current_app.app_context():
utils.makeOneCollection()
journal = utils.makeOneJournal()

response = self.client.get(
url_for("main.update_policy", url_seg=journal.url_segment)
)

self.assertStatus(response, 404)

def test_update_policy_returns_404_when_journal_not_found(self):
"""
Teste da ``view function`` ``update_policy``, deve retornar 404
quando o periódico não existe.
"""
with current_app.app_context():
utils.makeOneCollection()

response = self.client.get(
url_for("main.update_policy", url_seg="unknown-journal")
)

self.assertStatus(response, 404)

def test_update_policy_returns_404_when_journal_not_public(self):
"""
Teste da ``view function`` ``update_policy``, deve retornar 404
quando o periódico não é público.
"""
with current_app.app_context():
utils.makeOneCollection()
journal = utils.makeOneJournal(
{"is_public": False, "unpublish_reason": "Motivo"}
)

response = self.client.get(
url_for("main.update_policy", url_seg=journal.url_segment)
)

self.assertStatus(response, 404)


class TestJournalGrid(BaseTestCase):
def test_issue_grid(self):
"""
Expand Down
79 changes: 79 additions & 0 deletions opac/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,3 +420,82 @@ def test_migrate_page(
'<a href="http://www.scielo.br/avaliacao/avaliacao_en.htm"></a>',
new_content,
)


class CreateUpdatePolicyPageTestCase(BaseTestCase):
def test_create_update_policy_page_creates_page_when_no_url(self):
"""
Teste da função create_update_policy_page().
Deve criar uma página quando crossmark_url está ausente.
"""
with self._ctx.app.app_context():
utils.makeOneCollection()
journal = utils.makeOneJournal()
page = wutils.create_update_policy_page(
journal_acron=journal.acronym,
language="pt_BR",
content="<p>Política de atualização</p>",
)
self.assertIsNotNone(page)
self.assertEqual(page.slug_name, "update-policy")
self.assertEqual(page.journal, journal.acronym)
self.assertEqual(page.language, "pt_BR")

def test_create_update_policy_page_creates_page_when_standard_url(self):
"""
Teste da função create_update_policy_page().
Deve criar uma página quando crossmark_url segue o padrão padrão.
"""
with self._ctx.app.app_context():
utils.makeOneCollection()
journal = utils.makeOneJournal()
standard_url = (
"https://scielo.br/j/%s/update_policy/" % journal.acronym
)
page = wutils.create_update_policy_page(
journal_acron=journal.acronym,
language="pt_BR",
content="<p>Política de atualização</p>",
crossmark_url=standard_url,
)
self.assertIsNotNone(page)
self.assertEqual(page.slug_name, "update-policy")

def test_create_update_policy_page_returns_none_when_external_url(self):
"""
Teste da função create_update_policy_page().
Deve retornar None quando crossmark_url é uma URL externa não padrão.
"""
with self._ctx.app.app_context():
utils.makeOneCollection()
journal = utils.makeOneJournal()
page = wutils.create_update_policy_page(
journal_acron=journal.acronym,
language="pt_BR",
content="<p>Política de atualização</p>",
crossmark_url="https://doi.org/10.1016/crossmark-policy",
)
self.assertIsNone(page)

def test_create_update_policy_page_returns_existing_page(self):
"""
Teste da função create_update_policy_page().
Deve retornar a página existente ao invés de criar outra.
"""
with self._ctx.app.app_context():
utils.makeOneCollection()
journal = utils.makeOneJournal()
existing_page = utils.makeOnePage(
{
"name": "update_policy",
"slug_name": "update-policy",
"language": "pt_BR",
"journal": journal.acronym,
}
)
page = wutils.create_update_policy_page(
journal_acron=journal.acronym,
language="pt_BR",
content="<p>Novo conteúdo</p>",
)
self.assertEqual(page.id, existing_page.id)
7 changes: 7 additions & 0 deletions opac/webapp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@ def create_app():
app.jinja_env.filters["datetimefilter"] = custom_filters.datetimefilter
app.jinja_env.filters["absolute_url"] = custom_filters.make_absolute_url

# Registrando funções globais no Jinja2
from webapp import controllers as ctrl

app.jinja_env.globals[
"get_update_policy_page"
] = ctrl.get_update_policy_page_by_journal_acron_lang

# i18n
babel.init_app(app)
# Debug Toolbar
Expand Down
9 changes: 9 additions & 0 deletions opac/webapp/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,15 @@ def get_page_by_slug_name(slug_name, lang=None, is_draft=False):
return Pages.objects(language=lang, slug_name=slug_name, is_draft=is_draft).first()


def get_update_policy_page_by_journal_acron_lang(acron, language, is_draft=False):
return Pages.objects(
language=language,
journal=acron,
slug_name="update-policy",
is_draft=is_draft,
).first()


def related_links(article):
expr = []
if article.title or article.section:
Expand Down
48 changes: 48 additions & 0 deletions opac/webapp/main/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,54 @@ def about_journal(url_seg):
return render_template("journal/about.html", **context)


@main.route("/j/<string:url_seg>/update_policy/", methods=["GET"])
@cache.cached(key_prefix=cache_key_with_lang)
def update_policy(url_seg):
language = session.get("lang", get_locale())
journal = controllers.get_journal_by_url_seg(url_seg)

if not journal:
abort(404, _("Periódico não encontrado"))

if not journal.is_public:
abort(404, JOURNAL_UNPUBLISH + _(journal.unpublish_reason))

page = controllers.get_update_policy_page_by_journal_acron_lang(
journal.acronym, language
)

if not page:
abort(404, _("Página não encontrada"))

controllers.set_last_issue_and_issue_count(journal)

latest_issue = journal.last_issue

if latest_issue:
latest_issue_legend = descriptive_short_format(
title=journal.title,
short_title=journal.short_title,
pubdate=str(latest_issue.year),
volume=latest_issue.volume,
number=latest_issue.number,
suppl=latest_issue.suppl_text,
language=language[:2].lower(),
)
else:
latest_issue_legend = None

context = {
"journal": journal,
"latest_issue_legend": latest_issue_legend,
"last_issue": latest_issue,
"journal_study_areas": [
STUDY_AREAS.get(study_area.upper()) for study_area in journal.study_areas
],
"page": page,
}
return render_template("journal/update_policy.html", **context)


@main.route(
"/journals/search/alpha/ajax/",
methods=[
Expand Down
16 changes: 14 additions & 2 deletions opac/webapp/templates/journal/includes/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,17 @@
<a href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#instructions" class="dropdown-item"><span class="material-icons-outlined">help_outline</span> {% trans %}Instruções aos autores{% endtrans %}</a>
</li>
<li>
<a href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#item2" class="dropdown-item"><span class="material-icons-outlined">help_outline</span> {% trans %}Política editorial{% endtrans %}</a>
<a href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#editorialpolicy" class="dropdown-item"><span class="material-icons-outlined">help_outline</span> {% trans %}Política editorial{% endtrans %}</a>
</li>
<li>
<a href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#contact" class="dropdown-item"><span class="material-icons-outlined">email</span> {% trans %}Contato{% endtrans %}</a>
</li>
{% set update_policy_page = get_update_policy_page(journal.acronym, session.get('lang', 'pt_BR')) %}
{% if update_policy_page %}
<li>
<a href="{{ url_for('.update_policy', url_seg=journal.url_segment) }}" class="dropdown-item"><span class="material-icons-outlined">update</span> {% trans %}Política de atualização{% endtrans %}</a>
Comment on lines +50 to +53
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aqui há uma chamada a get_update_policy_page(...) dentro do template, que (via controllers) faz query em Pages. Como este header tem dois menus (breakpoints diferentes), isso vira pelo menos 2 queries por request só neste arquivo (mais outra no journal_info.html). Sugestão: calcular update_policy_page uma única vez por request (ex.: via context processor / g / variável de contexto do view) e reutilizar nos includes.

Copilot uses AI. Check for mistakes.
</li>
{% endif %}
</ul>
</div>
</div>
Expand Down Expand Up @@ -85,11 +91,17 @@
<a href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#instructions" class="dropdown-item"><span class="material-icons-outlined">help_outline</span> {% trans %}Instruções aos autores{% endtrans %}</a>
</li>
<li>
<a href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#item2" class="dropdown-item"><span class="material-icons-outlined">article</span> {% trans %}Política editorial{% endtrans %}</a>
<a href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#editorialpolicy" class="dropdown-item"><span class="material-icons-outlined">article</span> {% trans %}Política editorial{% endtrans %}</a>
</li>
<li>
<a href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#contact" class="dropdown-item"><span class="material-icons-outlined">email</span> {% trans %}Contato{% endtrans %}</a>
</li>
{% set update_policy_page = get_update_policy_page(journal.acronym, session.get('lang', 'pt_BR')) %}
{% if update_policy_page %}
<li>
<a href="{{ url_for('.update_policy', url_seg=journal.url_segment) }}" class="dropdown-item"><span class="material-icons-outlined">update</span> {% trans %}Política de atualização{% endtrans %}</a>
Comment on lines +99 to +102
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mesma questão de performance do outro menu: esta chamada a get_update_policy_page(...) dispara nova query no Mongo para cada renderização deste bloco. Sugestão: reutilizar o mesmo valor calculado uma vez (evitar duplicar queries entre os dois menus responsivos).

Copilot uses AI. Check for mistakes.
</li>
{% endif %}
</ul>
</div>
</div>
Expand Down
6 changes: 5 additions & 1 deletion opac/webapp/templates/journal/includes/journal_info.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,14 @@ <h1 class="h4" style="margin: 1rem auto">
<a class="list-group-item" href="{{ journal.online_submission_url|default('', true) }}" target="_blank"><span class="material-icons-outlined">launch</span> {% trans %}Submissão de manuscritos{% endtrans %}</a>
{% endif %}
<a class="list-group-item" href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#about" class="scroll"><span class="material-icons-outlined">info</span> {% trans %}Sobre o periódico{% endtrans %}</a>
<a class="list-group-item" href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#item-2" class="scroll"><span class="material-icons-outlined">article</span> {% trans %}Política editorial{% endtrans %}</a>
<a class="list-group-item" href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#editorialpolicy" class="scroll"><span class="material-icons-outlined">article</span> {% trans %}Política editorial{% endtrans %}</a>
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A âncora do link de Política editorial foi alterada para #editorialpolicy, mas ainda há referências no código para #item2 e #item-2 (ex.: templates/article/includes/header.html e templates/collection/includes/journal_list_row.html). Isso pode causar navegação inconsistente entre páginas/menus. Sugestão: padronizar todas as ocorrências para a mesma âncora (ou garantir compatibilidade no HTML da página about).

Copilot uses AI. Check for mistakes.
<a class="list-group-item" href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#editors" class="scroll"><span class="material-icons-outlined">people</span> {% trans %}Corpo Editorial{% endtrans %}</a>
<a class="list-group-item" href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#instructions" class="scroll"><span class="material-icons-outlined">help_outline</span> {% trans %}Instruções aos autores{% endtrans %}</a>
<a class="list-group-item" href="{{ url_for('.about_journal', url_seg=journal.url_segment) }}#contact" class="scroll"><span class="material-icons-outlined">markunread</span> {% trans %}Contato{% endtrans %}</a>
{% set update_policy_page = get_update_policy_page(journal.acronym, session.get('lang', 'pt_BR')) %}
{% if update_policy_page %}
<a class="list-group-item" href="{{ url_for('.update_policy', url_seg=journal.url_segment) }}"><span class="material-icons-outlined">update</span> {% trans %}Política de atualização{% endtrans %}</a>
Comment on lines +102 to +104
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Este include também consulta get_update_policy_page(...) (query em Pages) e, junto com as duas chamadas no journal/includes/header.html, pode adicionar 3 queries extras por request em páginas que incluem ambos. Sugestão: centralizar esse cálculo (context processor/variável de contexto) para reaproveitar o resultado em todos os templates incluídos.

Copilot uses AI. Check for mistakes.
{% endif %}

{#
{% if journal.enable_contact %}
Expand Down
88 changes: 88 additions & 0 deletions opac/webapp/templates/journal/update_policy.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{% extends "base.html" %}
{% block body_class %}journal update-policy{% endblock %}
{% block content %}
{% include "journal/includes/header.html" %}
{% include "journal/includes/journal_info.html" %}
{% include "journal/includes/levelMenu.html" %}

{% block main_content %}

<!-- Only on mobile -->
<section class="d-flex d-sm-none breadcrumb mt-3 mb-5 py-0 py-1">
<div class="container px-0">
<div class="row">
<div class="col ps-0">

<ol class="breadcrumb mb-0 ps-0">
<li class="breadcrumb-item"><a href="{{ url_for('.collection_list') }}?status=current"><span class="material-icons-outlined">navigate_before</span> {% trans %}Periódicos{% endtrans %}</a></li>
</ol>

</div>
<div class="col-3 pt-3">

<!-- share -->
{% include "includes/share.html" %}

</div>
</div>
</div>
</section>

<!-- Only on Desktop -->
<section class="d-none d-sm-flex breadcrumb mt-3 mb-5 py-0 py-1">
<div class="container">
<div class="row">
<div class="col">

<ol class="breadcrumb mb-0 ps-0">
<li class="breadcrumb-item"><a href="{{ url_for('.index') }}" alt="{% trans %}Home{% endtrans %}"><span class="material-icons-outlined">home</span></a></li>
<li class="breadcrumb-item"><a href="{{ url_for('.collection_list') }}?status=current">{% trans %}Periódicos{% endtrans %}</a></li>
<li class="breadcrumb-item"><a href="{{ url_for('.journal_detail', url_seg=journal.url_segment) }}">{{ journal.title }}</a></li>
<li class="breadcrumb-item">{% trans %}Política de atualização{% endtrans %}</li>
</ol>

</div>
<div class="col-3 pt-3">

<!-- share -->
{% include "includes/share.html" %}

</div>
</div>
</div>
</section>

<section class="journalContent">
<div class="container">
<div class="row">
<div class="col-md-12 content journalSecundary">

<div class="row">
<div class="col-12">

{% if page and page.content %}
{{ page.content|safe }}
{% else %}
{% trans %}Conteúdo não cadastrado{% endtrans %}
{% endif %}

</div>
</div>
<div class="row">
<div class="col">
{% include "includes/page_updated_at_info.html" %}
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O include includes/page_updated_at_info.html depende de uma variável page_updated_at, mas este template não a define (nem o view adiciona ao contexto). Do jeito que está, a informação de “atualizado em” não será exibida. Sugestão: passar page.updated_at via um {% with page_updated_at=page.updated_at %} (como em collection/about.html) ou remover o include se não for necessário.

Suggested change
{% include "includes/page_updated_at_info.html" %}
{% with page_updated_at=page.updated_at %}
{% include "includes/page_updated_at_info.html" %}
{% endwith %}

Copilot uses AI. Check for mistakes.
</div>
</div>
</div>

</div>
</div>
</section>

{% endblock %}

{% include "journal/includes/contact_footer.html" %}

{% include "includes/footer.html" %}

{% endblock %}
Loading