feat: strengthen module contracts and shared WebUI runtime

This commit is contained in:
2026-07-29 14:16:28 +02:00
parent 53e947935a
commit 68328f3d8e
57 changed files with 4358 additions and 371 deletions

View File

@@ -52,6 +52,7 @@ engine = _database.engine
SessionLocal = _database.SessionLocal
from govoplan_core.server.app import app
from govoplan_campaign.backend.sending.execution import SNAPSHOT_VERSION
class ApiSmokeTests(unittest.TestCase):
@@ -764,7 +765,7 @@ class ApiSmokeTests(unittest.TestCase):
assert version is not None
self.assertEqual(version.raw_json["server"], {"mail_profile_id": profile_id})
snapshot = version.execution_snapshot or {}
self.assertEqual(snapshot["snapshot_version"], "5")
self.assertEqual(snapshot["snapshot_version"], SNAPSHOT_VERSION)
self.assertEqual(snapshot["mail_profile_id"], profile_id)
self.assertNotIn("smtp", snapshot)
self.assertNotIn("imap", snapshot)
@@ -774,8 +775,10 @@ class ApiSmokeTests(unittest.TestCase):
deleted = self.client.delete(f"/api/v1/mail/profiles/{profile_id}", headers=headers)
self.assertEqual(deleted.status_code, 200, deleted.text)
self.assertFalse(deleted.json()["is_active"])
self.assertFalse(deleted.json()["smtp_password_configured"])
self.assertFalse(deleted.json()["imap_password_configured"])
# Reusable hierarchy credentials outlive a deactivated profile. The
# profile's retired legacy secret columns are still scrubbed below.
self.assertTrue(deleted.json()["smtp_password_configured"])
self.assertTrue(deleted.json()["imap_password_configured"])
from govoplan_audit.backend.db.models import AuditLog
@@ -864,7 +867,10 @@ class ApiSmokeTests(unittest.TestCase):
self.assertIsNotNone(version)
assert version is not None
snapshot_payload = version.execution_snapshot or {}
self.assertEqual(snapshot_payload["snapshot_version"], "5")
self.assertEqual(
snapshot_payload["snapshot_version"],
SNAPSHOT_VERSION,
)
self.assertEqual(snapshot_payload["mail_profile_id"], profile_id)
self.assertNotIn("smtp", snapshot_payload)
self.assertNotIn("imap", snapshot_payload)
@@ -2945,7 +2951,7 @@ class ApiSmokeTests(unittest.TestCase):
self.assertEqual(delta_payload["jobs"][0]["send_status"], "outcome_unknown")
self.assertEqual(
delta_payload["jobs"][0]["last_error"],
"SMTP delivery outcome requires operator reconciliation.",
"Delivery outcome requires operator reconciliation.",
)
self.assertEqual(delta_payload["counts"]["send"]["outcome_unknown"], 1)
self.assertTrue(str(delta_payload["watermark"]).startswith("seq:"))
@@ -4172,7 +4178,7 @@ class ApiSmokeTests(unittest.TestCase):
)
from govoplan_campaign.backend.db.models import CampaignJob, CampaignVersion, SendAttempt
from govoplan_mail.backend.db.models import MailServerProfile
from govoplan_mail.backend.db.models import MailServerEndpoint, MailServerProfile
with SessionLocal() as session:
version = session.get(CampaignVersion, version_id)
@@ -4180,7 +4186,7 @@ class ApiSmokeTests(unittest.TestCase):
assert version is not None
snapshot = version.execution_snapshot
self.assertIsInstance(snapshot, dict)
self.assertEqual(snapshot["snapshot_version"], "5")
self.assertEqual(snapshot["snapshot_version"], SNAPSHOT_VERSION)
self.assertEqual(snapshot["job_count"], 1)
self.assertEqual(snapshot["queueable_job_count"], 1)
self.assertTrue(snapshot["job_manifest_sha256"])
@@ -4195,9 +4201,17 @@ class ApiSmokeTests(unittest.TestCase):
profile = session.get(MailServerProfile, snapshot["mail_profile_id"])
self.assertIsNotNone(profile)
assert profile is not None
profile.smtp_config = {**profile.smtp_config, "host": "smtp.example.invalid"}
profile.smtp_transport_revision = "manually-rotated-transport-revision"
session.add(profile)
smtp_server_id = snapshot.get("smtp_server_id")
self.assertTrue(smtp_server_id)
smtp_server = session.get(MailServerEndpoint, smtp_server_id)
self.assertIsNotNone(smtp_server)
assert smtp_server is not None
smtp_server.config = {
**smtp_server.config,
"host": "smtp.example.invalid",
}
smtp_server.transport_revision = "manually-rotated-transport-revision"
session.add(smtp_server)
session.commit()
sent = self.client.post(