From 00004609b0190020e27225d5daf2eb61ec198207 Mon Sep 17 00:00:00 2001 From: Mirek Simek Date: Wed, 23 Oct 2024 10:33:25 +0200 Subject: [PATCH 1/3] fix: translation only applied on app start * the problem was that with gettext the translations for facets have been only be calculated on boot time. * using lazy_gettext instead fixes that, because it calculates the translation at the request level Co-authored-by: Mirek Simek --- invenio_banners/services/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invenio_banners/services/config.py b/invenio_banners/services/config.py index 1be0724..6bc7c36 100644 --- a/invenio_banners/services/config.py +++ b/invenio_banners/services/config.py @@ -7,7 +7,7 @@ """Banners Service configuration.""" -from invenio_i18n import gettext as _ +from invenio_i18n import lazy_gettext as _ from invenio_records_resources.services import Link, RecordServiceConfig from invenio_records_resources.services.records.links import pagination_links from sqlalchemy import asc, desc From 4855f634eb27a1dd5b220879728286c880474b96 Mon Sep 17 00:00:00 2001 From: Mirek Simek Date: Fri, 25 Oct 2024 21:06:10 +0200 Subject: [PATCH 2/3] test: Tests that translations of this package work * there were no tests for translations in administration interface in this package * this commit adds tests that at least some of the strings get translated and translations work Note: In order that the test runs successfully, you need to invoke python setup.py compile_catalog prior running the tests --- run-tests.sh | 1 + setup.cfg | 2 + tests/ui/conftest.py | 103 +++++++++++++++++++++++++++ tests/ui/test_i18n_administration.py | 73 +++++++++++++++++++ 4 files changed, 179 insertions(+) create mode 100644 tests/ui/conftest.py create mode 100644 tests/ui/test_i18n_administration.py diff --git a/run-tests.sh b/run-tests.sh index 3f87ca6..8715344 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -20,6 +20,7 @@ trap cleanup EXIT python -m check_manifest --ignore ".*-requirements.txt" python -m sphinx.cmd.build -qnNW docs docs/_build/html eval "$(docker-services-cli up --db ${DB:-postgresql} --search ${SEARCH:-opensearch} --env)" +python setup.py compile_catalog python -m pytest tests_exit_code=$? python -m sphinx.cmd.build -qnNW -b doctest docs docs/_build/doctest diff --git a/setup.cfg b/setup.cfg index 000387c..39b8954 100644 --- a/setup.cfg +++ b/setup.cfg @@ -56,6 +56,8 @@ invenio_administration.views = invenio_banners_details = invenio_banners.administration.banners:BannerDetailView invenio_banners_edit = invenio_banners.administration.banners:BannerEditView invenio_banners_create = invenio_banners.administration.banners:BannerCreateView +invenio_i18n.translations = + invenio_banners = invenio_banners [build_sphinx] diff --git a/tests/ui/conftest.py b/tests/ui/conftest.py new file mode 100644 index 0000000..8ae5e0f --- /dev/null +++ b/tests/ui/conftest.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 CESNET z.s.p.o. +# +# Invenio-Banners is free software; you can redistribute it and/or modify it +# under the terms of the MIT License; see LICENSE file for more details. + +"""UI tests configuration. + +Note: need to call python setup.py compile_catalog to compile the translations before +running the tests. +""" +import json +from pathlib import Path + +import pytest +from flask_security import login_user +from invenio_accounts.testutils import login_user_via_session +from invenio_app.factory import create_app as _create_app +from invenio_i18n import lazy_gettext as _ + + +@pytest.fixture(scope="module") +def create_app(instance_path): + """Application factory fixture.""" + return _create_app + + +@pytest.fixture(scope="module") +def app_config(app_config): + """Override pytest-invenio app_config fixture. + + Set languages for the app. + """ + app_config["I18N_LANGUAGES"] = [ + ("cs", _("Czech")), + ] + return app_config + + +@pytest.fixture() +def admin_identity(admin): + """Identity of the admin user.""" + return admin.identity + + +@pytest.fixture() +def admin_client(db, client, admin): + """Log in a user to the client.""" + + login_user(admin.user, remember=True) + login_user_via_session(client, email=admin.user.email) + + return client + + +def add_to_manifest(manifest, filename): + manifest.setdefault("assets", {})[filename] = {"publicPath": filename} + filename_without_ext = filename.rsplit(".", 1)[0] + manifest.setdefault("chunks", {}).setdefault(filename_without_ext, []).append( + filename + ) + + +@pytest.fixture() +def fake_manifest(app, instance_path): + app.static_folder = str(Path(instance_path) / "static") + + manifest_path = Path(instance_path) / "static" / "dist" / "manifest.json" + manifest_path.parent.mkdir(parents=True, exist_ok=True) + + manifest = { + "status": "done", + "publicPath": "/static/dist/", + } + add_to_manifest(manifest, "base.js") + add_to_manifest(manifest, "base-admin-theme.js") + + add_to_manifest(manifest, "i18n_app.js") + add_to_manifest(manifest, "invenio-administration-details.js") + add_to_manifest(manifest, "invenio-administration-search.js") + + add_to_manifest(manifest, "theme.css") + add_to_manifest(manifest, "theme.js") + + manifest_path.write_text(json.dumps(manifest)) + return manifest_path + + +@pytest.fixture() +def clear_babel_context(): + + # force babel reinitialization when language is switched + def _clear_babel_context(): + try: + from flask import g + from flask_babel import SimpleNamespace + + g._flask_babel = SimpleNamespace() + except ImportError: + return + + return _clear_babel_context diff --git a/tests/ui/test_i18n_administration.py b/tests/ui/test_i18n_administration.py new file mode 100644 index 0000000..2d77055 --- /dev/null +++ b/tests/ui/test_i18n_administration.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 CESNET z.s.p.o. +# +# Invenio-Banners is free software; you can redistribute it and/or modify it +# under the terms of the MIT License; see LICENSE file for more details. + +"""Test the i18n of the administration interface. + +Note: this does not test the actual translation of the messages, but rather that the +translation kicks in and that some of the labels are localized - so that we know that +the lazy_gettext is working. +""" + +from datetime import datetime, timedelta + +from invenio_banners.proxies import current_banners_service as service + + +def test_list_is_localized(app, admin_client, fake_manifest, clear_babel_context): + """Test that the administration page is localized and that the labels are translated.""" + + clear_babel_context() + resp = admin_client.get("/administration/banners") + assert resp.status_code == 200 + assert resp.content_type == "text/html; charset=utf-8" + # check that the string "Active" is in the response twice (sort order, column number) + assert len(resp.text.split('"Active"')) == 3 + + clear_babel_context() + resp = admin_client.get( + "/administration/banners", headers=[("Accept-Language", "cs")] + ) + assert resp.status_code == 200 + assert resp.content_type == "text/html; charset=utf-8" + assert ' Date: Sat, 26 Oct 2024 16:59:58 +0200 Subject: [PATCH 3/3] fix: .mo files were not included in source distribution --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 17b93b5..3cec69a 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -30,5 +30,6 @@ recursive-include docs Makefile recursive-include invenio_banners *.html recursive-include invenio_banners *.py recursive-include invenio_banners *.po +recursive-include invenio_banners *.mo recursive-include invenio_banners *.pot recursive-include tests *.py