Add conditional localized form definitions

This commit is contained in:
2026-08-01 20:57:26 +02:00
parent 343a208894
commit e2033640a1
11 changed files with 1346 additions and 33 deletions
+132 -1
View File
@@ -1,6 +1,6 @@
from __future__ import annotations
from dataclasses import dataclass
from dataclasses import dataclass, replace
from datetime import UTC, datetime, timedelta
import unittest
@@ -9,7 +9,11 @@ from sqlalchemy.orm import Session
from govoplan_core.core.institutional import (
FormDefinition,
FormConditionExpression,
FormFieldDefinition,
FormLocalization,
FormPageDefinition,
FormSectionDefinition,
InstitutionalReference,
TemporalRevision,
)
@@ -17,7 +21,11 @@ from govoplan_forms.backend.db.models import FormDefinitionRevision
from govoplan_forms.backend.service import (
FormDefinitionStoreError,
SqlFormDefinitionProvider,
assess_form_definition_fragment,
export_form_definition_fragment,
form_definition_diagnostics,
form_definition_history,
import_form_definition_fragment,
record_form_definition,
)
@@ -162,6 +170,129 @@ class FormsTests(unittest.TestCase):
tenant_id="tenant-1",
)
def test_pages_conditions_and_localization_are_validated(self) -> None:
item = definition()
composed = replace(
item,
fields=(
item.fields[0],
replace(
item.fields[1],
visibility_condition=FormConditionExpression(
kind="predicate",
field_key="name",
operator="is_not_empty",
),
),
),
pages=(
FormPageDefinition(
key="application",
title="Application",
sections=(
FormSectionDefinition(
key="details",
title="Details",
field_keys=("name", "delivery"),
),
),
),
),
fallback_locale="de",
localizations=(
FormLocalization(
locale="de",
title="Antrag",
field_labels={"name": "Name", "delivery": "Zustellung"},
option_labels={"delivery": {"portal": "Portal", "mail": "Post"}},
page_titles={"application": "Antrag"},
section_titles={"details": "Angaben"},
),
),
)
stored = record_form_definition(
self.session,
self.principal,
definition=composed,
)
self.assertEqual("application", stored.pages[0].key)
self.assertEqual((), form_definition_diagnostics(stored))
cyclic = replace(
definition(revision="2"),
fields=(
replace(
item.fields[0],
visibility_condition=FormConditionExpression(
kind="predicate",
field_key="delivery",
operator="eq",
value="portal",
),
),
replace(
item.fields[1],
visibility_condition=FormConditionExpression(
kind="predicate",
field_key="name",
operator="is_not_empty",
),
),
),
)
with self.assertRaisesRegex(FormDefinitionStoreError, "dependency cycle"):
record_form_definition(
self.session,
self.principal,
definition=cyclic,
expected_revision="1",
)
def test_package_fragment_is_verified_assessed_and_imported_as_draft(self) -> None:
source = definition(tenant_id="tenant-source")
fragment = export_form_definition_fragment(
source,
exported_at=NOW,
exported_by="source-account",
)
assessment = assess_form_definition_fragment(
self.session,
self.principal,
fragment=fragment,
)
self.assertEqual("create", assessment["outcome"])
self.assertTrue(assessment["requires_remap"])
imported = import_form_definition_fragment(
self.session,
self.principal,
fragment=fragment,
target_form_id="local-permit",
target_key="local-permit",
expected_revision=None,
change_reason="Import reviewed package.",
recorded_at=NOW,
)
self.assertEqual("tenant-1", imported.reference.tenant_id)
self.assertEqual("draft", imported.publication_state)
self.assertEqual(
"tenant-source",
imported.metadata["package_import"]["source_tenant_id"],
)
tampered = dict(fragment)
tampered["definition"] = {**fragment["definition"], "title": "Tampered"}
with self.assertRaisesRegex(FormDefinitionStoreError, "digest"):
assess_form_definition_fragment(
self.session,
self.principal,
fragment=tampered,
)
if __name__ == "__main__":
unittest.main()
(assess_form_definition_fragment,)
(export_form_definition_fragment,)
(form_definition_diagnostics,)
(import_form_definition_fragment,)