Release govoplan-campaign v0.1.28: stabilize saving, review and delivery recovery
Module Package Release / publish-packages (push) Successful in 12s

This commit is contained in:
2026-09-08 01:32:26 +02:00
parent 1b32427813
commit c51fc180fb
111 changed files with 6905 additions and 980 deletions
+48
View File
@@ -6,7 +6,9 @@ import pytest
from pydantic import ValidationError
from govoplan_campaign.backend.campaign.mail_profile_boundary import (
CampaignMailProfileBoundaryError,
campaign_editor_state_for_edit,
campaign_editor_state_with_client_update,
)
from govoplan_campaign.backend.schemas import (
CampaignVersionResponse,
@@ -19,6 +21,7 @@ from govoplan_campaign.backend.schemas import (
[
{"smtp": {"host": "smtp.example.test", "password": "secret"}},
{"transport": {"imap_password": "secret"}},
{"approval_gate": {"request_id": "forged"}},
{
"review_send": {
"build_token": "forged",
@@ -108,3 +111,48 @@ def test_fork_copy_keeps_only_client_owned_bounded_metadata() -> None:
"field_overrides": {"department": False},
}
assert "legacy-secret" not in repr(copied)
def test_client_metadata_update_preserves_only_trusted_server_evidence() -> None:
review = {
"build_token": "server-build-token",
"inspection_complete": True,
"reviewed_message_keys": ["entry-1"],
"issue_decisions": [],
"updated_at": "2026-07-21T00:00:00+00:00",
"updated_by_user_id": "reviewer-1",
}
approval = {
"request_id": "approval-1",
"request_revision": 2,
"subject_version": "version-1",
"subject_digest": "a" * 64,
"requested_at": "2026-07-21T00:00:00+00:00",
"requested_by_user_id": "approver-1",
}
stored = {
"created_from": "minimal_campaign",
"opt_ins": {"inline_guidance": True},
"review_send": review,
"approval_gate": approval,
"credentials": {"password": "legacy-secret"},
}
updated = campaign_editor_state_with_client_update(
stored, {"opt_ins": {"inline_guidance": False}}
)
assert updated == {
"opt_ins": {"inline_guidance": False},
"review_send": review,
"approval_gate": approval,
}
assert updated["review_send"] is not review
assert updated["approval_gate"] is not approval
assert stored["opt_ins"] == {"inline_guidance": True}
assert "legacy-secret" not in repr(updated)
@pytest.mark.parametrize("server_key", ["review_send", "approval_gate"])
def test_client_metadata_update_cannot_replace_server_evidence(server_key: str) -> None:
with pytest.raises(CampaignMailProfileBoundaryError, match="unsupported"):
campaign_editor_state_with_client_update({}, {server_key: {}})