Build custom container images / build (map[base_image:php:8-fpm-alpine build_args:PHP_VERSION=8
context:php8-pgsql fingerprint_command:{ apk info -v | LC_ALL=C sort; find /usr/local/lib/php/extensions /usr/local/etc/php/conf.d -type f -exec sha256sum {} + | LC_ALL=C sort; }
name:ph… (push) Successful in 48s
Build custom container images / build (map[base_image:postgres:18 build_args:PG_VERSION=18
POSTGIS_VERSION=3
VCHORD_VERSION=0.5.3
context:postgres fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; find /usr/lib/postgresql -type f -exec sha256su… (push) Successful in 55s
Build custom container images / build (map[base_image:python:3 build_args:PYTHON_VERSION=3
context:python-tools fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; pip freeze | LC_ALL=C sort; }
name:python-tools oci_labels:org.opencontainers.ima… (push) Successful in 54s
Build custom container images / build (map[base_image:python:3.12-slim build_args:PYTHON_VERSION=3.12-slim
context:linkki-tiedotus fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; pip freeze | LC_ALL=C sort; }
name:linkki-tiedotus oci_labels:… (push) Successful in 39s
47 lines
1.5 KiB
Python
47 lines
1.5 KiB
Python
import json
|
|
from pathlib import Path
|
|
|
|
from webapp.i18n import load_translations
|
|
|
|
|
|
def test_load_translations_uses_english_fallback_for_missing_values() -> None:
|
|
translations = load_translations("fi")
|
|
|
|
assert translations["nav.instructions"]
|
|
assert translations["app.title"] == "Linkki Botti"
|
|
|
|
|
|
def test_load_translations_prefers_requested_language_value() -> None:
|
|
translations = load_translations("sv")
|
|
|
|
assert translations["nav.instructions"] != "Instructions"
|
|
|
|
|
|
def test_translation_catalog_has_no_common_utf8_mojibake_in_finnish_or_swedish() -> None:
|
|
catalog = json.loads(
|
|
(Path(__file__).resolve().parents[1] / "webapp/translations/catalog.json").read_text(
|
|
encoding="utf-8"
|
|
)
|
|
)
|
|
|
|
def visit(value: object) -> list[str]:
|
|
if isinstance(value, str):
|
|
return [value]
|
|
if isinstance(value, list):
|
|
result: list[str] = []
|
|
for item in value:
|
|
result.extend(visit(item))
|
|
return result
|
|
if isinstance(value, dict):
|
|
result: list[str] = []
|
|
for nested in value.values():
|
|
result.extend(visit(nested))
|
|
return result
|
|
return []
|
|
|
|
suspicious_markers = ("\u00c3", "\u00c2", "\ufffd")
|
|
for entry in catalog.values():
|
|
for language in ("fi", "sv"):
|
|
for text in visit(entry.get(language, "")):
|
|
assert not any(marker in text for marker in suspicious_markers), text
|