From 400b42684dbeae1c1018c0d957b3fdf8da822e5b Mon Sep 17 00:00:00 2001 From: Bart Feenstra Date: Tue, 16 Jul 2024 22:00:53 +0100 Subject: [PATCH] Fix a bug where existing Jinja2 entity contexts would go lost upon setting another one (#1719) --- betty/jinja2/__init__.py | 4 +- betty/tests/coverage/test_coverage.py | 14 +++++- betty/tests/jinja2/__init__.py | 0 .../test___init__.py} | 43 ++++++++++++++++--- 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 betty/tests/jinja2/__init__.py rename betty/tests/{test_jinja2.py => jinja2/test___init__.py} (94%) diff --git a/betty/jinja2/__init__.py b/betty/jinja2/__init__.py index 855f3fc39..1f87eaa15 100644 --- a/betty/jinja2/__init__.py +++ b/betty/jinja2/__init__.py @@ -155,7 +155,9 @@ def __call__(self, *entities: Entity) -> EntityContexts: """ Create a new context with the given entities. """ - updated_contexts = EntityContexts() + updated_contexts = EntityContexts( + *(entity for entity in self._contexts.values() if entity is not None) + ) for entity in entities: updated_contexts._contexts[entity.type] = entity return updated_contexts diff --git a/betty/tests/coverage/test_coverage.py b/betty/tests/coverage/test_coverage.py index 670ac8740..48b97055b 100644 --- a/betty/tests/coverage/test_coverage.py +++ b/betty/tests/coverage/test_coverage.py @@ -397,7 +397,19 @@ class TestKnownToBeMissing: "fully_qualified_type_name": TestKnownToBeMissing, }, "betty/html.py": TestKnownToBeMissing, - "betty/jinja2/__init__.py": TestKnownToBeMissing, + "betty/jinja2/__init__.py": { + "context_app": TestKnownToBeMissing, + "context_job_context": TestKnownToBeMissing, + "context_localizer": TestKnownToBeMissing, + "Environment": TestKnownToBeMissing, + "Jinja2Provider": { + "new_context_vars": TestKnownToBeMissing, + "tests": TestKnownToBeMissing, + }, + "Jinja2Renderer": { + "file_extensions": TestKnownToBeMissing, + }, + }, "betty/jinja2/filter.py": TestKnownToBeMissing, "betty/jinja2/test.py": TestKnownToBeMissing, "betty/job.py": { diff --git a/betty/tests/jinja2/__init__.py b/betty/tests/jinja2/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/betty/tests/test_jinja2.py b/betty/tests/jinja2/test___init__.py similarity index 94% rename from betty/tests/test_jinja2.py rename to betty/tests/jinja2/test___init__.py index 861899b1b..d1811ac44 100644 --- a/betty/tests/test_jinja2.py +++ b/betty/tests/jinja2/test___init__.py @@ -8,7 +8,8 @@ from aiofiles.tempfile import TemporaryDirectory from betty.app import App -from betty.jinja2 import Jinja2Renderer, _Citer, Jinja2Provider +from betty.fs import ASSETS_DIRECTORY_PATH +from betty.jinja2 import Jinja2Renderer, _Citer, Jinja2Provider, EntityContexts from betty.locale import Date, Datey, DateRange, Localized from betty.media_type import MediaType from betty.model import get_entity_type_name, Entity @@ -189,7 +190,7 @@ class TestFilterFile(TemplateTestCase): ("expected", "template", "file"), [ ( - "/file/F1/file/test_jinja2.py", + "/file/F1/file/test___init__.py", "{{ file | file }}", File( id="F1", @@ -197,7 +198,7 @@ class TestFilterFile(TemplateTestCase): ), ), ( - "/file/F1/file/test_jinja2.py:/file/F1/file/test_jinja2.py", + "/file/F1/file/test___init__.py:/file/F1/file/test___init__.py", "{{ file | file }}:{{ file | file }}", File( id="F1", @@ -221,9 +222,7 @@ async def test(self, expected: str, template: str, file: File) -> None: class TestFilterImage(TemplateTestCase): - image_path = ( - Path(__file__).parents[1] / "assets" / "public" / "static" / "betty-512x512.png" - ) + image_path = ASSETS_DIRECTORY_PATH / "public" / "static" / "betty-512x512.png" @pytest.mark.parametrize( ("expected", "template", "file"), @@ -671,3 +670,35 @@ async def test( }, ) as (actual, _): assert expected == actual + + +class EntityContextsTestEntityA(Entity): + pass + + +class EntityContextsTestEntityB(Entity): + pass + + +class TestEntityContexts: + async def test___getitem__(self) -> None: + sut = EntityContexts() + assert sut[EntityContextsTestEntityA] is None + + async def test___getitem___with___init__(self) -> None: + a = EntityContextsTestEntityA() + sut = EntityContexts(a) + assert sut[EntityContextsTestEntityA] is a + + async def test___call__(self) -> None: + a = EntityContextsTestEntityA() + contexts = EntityContexts() + sut = contexts(a) + assert sut[EntityContextsTestEntityA] is a + + async def test___call___with___init__(self) -> None: + a = EntityContextsTestEntityA() + b = EntityContextsTestEntityA() + contexts = EntityContexts(a) + sut = contexts(b) + assert sut[EntityContextsTestEntityA] is b