diff --git a/opac/tests/test_main_views.py b/opac/tests/test_main_views.py index ebacc8eb0..df43c0ccb 100644 --- a/opac/tests/test_main_views.py +++ b/opac/tests/test_main_views.py @@ -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): """ diff --git a/opac/tests/test_utils.py b/opac/tests/test_utils.py index 079f5a87f..d64e50904 100644 --- a/opac/tests/test_utils.py +++ b/opac/tests/test_utils.py @@ -420,3 +420,82 @@ def test_migrate_page( '', 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="

Política de atualização

", + ) + 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="

Política de atualização

", + 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="

Política de atualização

", + 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="

Novo conteúdo

", + ) + self.assertEqual(page.id, existing_page.id) diff --git a/opac/webapp/__init__.py b/opac/webapp/__init__.py index e6141aa4e..2596544c1 100644 --- a/opac/webapp/__init__.py +++ b/opac/webapp/__init__.py @@ -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 diff --git a/opac/webapp/controllers.py b/opac/webapp/controllers.py index a80d5d8d8..bfafe082e 100644 --- a/opac/webapp/controllers.py +++ b/opac/webapp/controllers.py @@ -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: diff --git a/opac/webapp/main/views.py b/opac/webapp/main/views.py index b7ad99729..21832e681 100644 --- a/opac/webapp/main/views.py +++ b/opac/webapp/main/views.py @@ -659,6 +659,54 @@ def about_journal(url_seg): return render_template("journal/about.html", **context) +@main.route("/j//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=[ diff --git a/opac/webapp/templates/journal/includes/header.html b/opac/webapp/templates/journal/includes/header.html index bb7c8476f..f842b8035 100644 --- a/opac/webapp/templates/journal/includes/header.html +++ b/opac/webapp/templates/journal/includes/header.html @@ -42,11 +42,17 @@ help_outline {% trans %}Instruções aos autores{% endtrans %}
  • - help_outline {% trans %}Política editorial{% endtrans %} + help_outline {% trans %}Política editorial{% endtrans %}
  • email {% trans %}Contato{% endtrans %}
  • + {% set update_policy_page = get_update_policy_page(journal.acronym, session.get('lang', 'pt_BR')) %} + {% if update_policy_page %} +
  • + update {% trans %}Política de atualização{% endtrans %} +
  • + {% endif %} @@ -85,11 +91,17 @@ help_outline {% trans %}Instruções aos autores{% endtrans %}
  • - article {% trans %}Política editorial{% endtrans %} + article {% trans %}Política editorial{% endtrans %}
  • email {% trans %}Contato{% endtrans %}
  • + {% set update_policy_page = get_update_policy_page(journal.acronym, session.get('lang', 'pt_BR')) %} + {% if update_policy_page %} +
  • + update {% trans %}Política de atualização{% endtrans %} +
  • + {% endif %} diff --git a/opac/webapp/templates/journal/includes/journal_info.html b/opac/webapp/templates/journal/includes/journal_info.html index b48800cd0..8d72d7409 100644 --- a/opac/webapp/templates/journal/includes/journal_info.html +++ b/opac/webapp/templates/journal/includes/journal_info.html @@ -95,10 +95,14 @@

    launch {% trans %}Submissão de manuscritos{% endtrans %} {% endif %} info {% trans %}Sobre o periódico{% endtrans %} - article {% trans %}Política editorial{% endtrans %} + article {% trans %}Política editorial{% endtrans %} people {% trans %}Corpo Editorial{% endtrans %} help_outline {% trans %}Instruções aos autores{% endtrans %} markunread {% trans %}Contato{% endtrans %} + {% set update_policy_page = get_update_policy_page(journal.acronym, session.get('lang', 'pt_BR')) %} + {% if update_policy_page %} + update {% trans %}Política de atualização{% endtrans %} + {% endif %} {# {% if journal.enable_contact %} diff --git a/opac/webapp/templates/journal/update_policy.html b/opac/webapp/templates/journal/update_policy.html new file mode 100644 index 000000000..e36ed182e --- /dev/null +++ b/opac/webapp/templates/journal/update_policy.html @@ -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 %} + + + + + + + +
    +
    +
    +
    + +
    +
    + + {% if page and page.content %} + {{ page.content|safe }} + {% else %} + {% trans %}Conteúdo não cadastrado{% endtrans %} + {% endif %} + +
    +
    +
    +
    + {% include "includes/page_updated_at_info.html" %} +
    +
    +
    + +
    +
    +
    + + {% endblock %} + + {% include "journal/includes/contact_footer.html" %} + + {% include "includes/footer.html" %} + +{% endblock %} diff --git a/opac/webapp/utils/utils.py b/opac/webapp/utils/utils.py index 830d614d8..bb54dd0e8 100644 --- a/opac/webapp/utils/utils.py +++ b/opac/webapp/utils/utils.py @@ -385,6 +385,38 @@ def create_page(name, language, content, journal=None, description=None): return page +def create_update_policy_page(journal_acron, language, content, crossmark_url=None): + """ + Cria uma página de política de atualização (crossmark) para um periódico + no modelo Pages, mas somente se a URL está ausente ou segue o padrão + `https://domain/j/journal_acron/update_policy/`. + + Parâmetro journal_acron: acrônimo do periódico + Parâmetro language: idioma do texto da página + Parâmetro content: conteúdo em HTML da página + Parâmetro crossmark_url: URL do crossmark do periódico (opcional) + """ + standard_pattern = re.compile( + r"https?://[^/]+/j/" + re.escape(journal_acron) + r"/update_policy/?$" + ) + if crossmark_url is not None and not standard_pattern.match(crossmark_url): + return None + + existing = Pages.objects( + journal=journal_acron, slug_name="update-policy", language=language + ).first() + if existing: + return existing + + return create_page( + name="update_policy", + language=language, + content=content, + journal=journal_acron, + description="Política de atualização do periódico %s" % journal_acron, + ) + + def join_html_files_content(revistas_path, acron, files): """ Função que lê os arquivos aboutj.htm, instruct.htm e edboard.htm