feat: complete postbox access evidence
This commit is contained in:
+120
-1
@@ -49,7 +49,7 @@ from govoplan_postbox.backend.db.models import (
|
||||
PostboxTemplate,
|
||||
PostboxTemplateRevision,
|
||||
)
|
||||
from govoplan_postbox.backend.service import PostboxService
|
||||
from govoplan_postbox.backend.service import PostboxError, PostboxService
|
||||
|
||||
|
||||
POSTBOX_TABLES = (
|
||||
@@ -915,6 +915,12 @@ class PostboxServiceTests(unittest.TestCase):
|
||||
actor=self.actor,
|
||||
state="acknowledged",
|
||||
)
|
||||
receipt_summary = service.delivery_receipt_summaries(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
producer_module="campaigns",
|
||||
delivery_ids=(first.delivery_id,),
|
||||
)[first.delivery_id]
|
||||
session.commit()
|
||||
|
||||
self.assertFalse(first.duplicate)
|
||||
@@ -922,6 +928,20 @@ class PostboxServiceTests(unittest.TestCase):
|
||||
self.assertEqual(first.message_id, second.message_id)
|
||||
self.assertIsNotNone(marked.read_at)
|
||||
self.assertIsNotNone(marked.acknowledged_at)
|
||||
self.assertTrue(receipt_summary.currently_readable)
|
||||
self.assertEqual(1, receipt_summary.current_holder_count)
|
||||
self.assertEqual(1, receipt_summary.read_receipt_count)
|
||||
self.assertEqual(1, receipt_summary.acknowledged_receipt_count)
|
||||
self.assertEqual(0, receipt_summary.withdrawn_message_count)
|
||||
self.assertEqual(
|
||||
{},
|
||||
service.delivery_receipt_summaries(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
producer_module="another-module",
|
||||
delivery_ids=(first.delivery_id,),
|
||||
),
|
||||
)
|
||||
self.assertEqual(
|
||||
1,
|
||||
session.query(PostboxMessage).count(),
|
||||
@@ -971,6 +991,95 @@ class PostboxServiceTests(unittest.TestCase):
|
||||
[event.type for event in events],
|
||||
)
|
||||
|
||||
def test_withdrawn_and_expired_messages_keep_metadata_but_hide_content(
|
||||
self,
|
||||
) -> None:
|
||||
self.idm.assignments.append(self.assignment)
|
||||
with Session(self.engine) as session:
|
||||
postbox = self._create_exact(session)
|
||||
withdrawn = self.service.deliver(
|
||||
session,
|
||||
PostboxDeliveryRequest(
|
||||
tenant_id="tenant-1",
|
||||
target=PostboxTargetRef(postbox_id=postbox.id),
|
||||
producer_module="campaigns",
|
||||
producer_resource_type="campaign_recipient",
|
||||
producer_resource_id="recipient-withdrawn",
|
||||
idempotency_key="withdrawn-message",
|
||||
subject="Withdrawn decision",
|
||||
body_text="Sensitive withdrawn content",
|
||||
),
|
||||
)
|
||||
expired = self.service.deliver(
|
||||
session,
|
||||
PostboxDeliveryRequest(
|
||||
tenant_id="tenant-1",
|
||||
target=PostboxTargetRef(postbox_id=postbox.id),
|
||||
producer_module="campaigns",
|
||||
producer_resource_type="campaign_recipient",
|
||||
producer_resource_id="recipient-expired",
|
||||
idempotency_key="expired-message",
|
||||
subject="Expired decision",
|
||||
body_text="Sensitive expired content",
|
||||
expires_at=utc_now() - timedelta(minutes=1),
|
||||
),
|
||||
)
|
||||
withdrawn_model = session.get(PostboxMessage, withdrawn.message_id)
|
||||
assert withdrawn_model is not None
|
||||
withdrawn_model.withdrawn_at = utc_now()
|
||||
session.flush()
|
||||
|
||||
withdrawn_ref = self.service.get_message(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
message_id=withdrawn.message_id,
|
||||
actor=self.actor,
|
||||
)
|
||||
expired_ref = self.service.get_message(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
message_id=expired.message_id,
|
||||
actor=self.actor,
|
||||
)
|
||||
|
||||
assert withdrawn_ref is not None
|
||||
assert expired_ref is not None
|
||||
self.assertEqual("withdrawn", withdrawn_ref.availability)
|
||||
self.assertIsNone(withdrawn_ref.body_text)
|
||||
self.assertEqual((), withdrawn_ref.attachments)
|
||||
self.assertEqual("expired", expired_ref.availability)
|
||||
self.assertIsNone(expired_ref.body_text)
|
||||
with self.assertRaisesRegex(PostboxError, "withdrawn"):
|
||||
self.service.mark_message(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
message_id=withdrawn.message_id,
|
||||
actor=self.actor,
|
||||
state="read",
|
||||
)
|
||||
with self.assertRaisesRegex(PostboxError, "expired"):
|
||||
self.service.mark_message(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
message_id=expired.message_id,
|
||||
actor=self.actor,
|
||||
state="acknowledged",
|
||||
)
|
||||
|
||||
summaries = self.service.delivery_receipt_summaries(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
producer_module="campaigns",
|
||||
delivery_ids=(withdrawn.delivery_id, expired.delivery_id),
|
||||
)
|
||||
self.assertFalse(summaries[withdrawn.delivery_id].currently_readable)
|
||||
self.assertEqual(
|
||||
1,
|
||||
summaries[withdrawn.delivery_id].withdrawn_message_count,
|
||||
)
|
||||
self.assertFalse(summaries[expired.delivery_id].currently_readable)
|
||||
self.assertEqual(1, summaries[expired.delivery_id].expired_message_count)
|
||||
|
||||
def test_hierarchy_linked_copy_snapshots_path_and_independent_state(
|
||||
self,
|
||||
) -> None:
|
||||
@@ -1023,6 +1132,16 @@ class PostboxServiceTests(unittest.TestCase):
|
||||
session.commit()
|
||||
receipts = session.query(PostboxMessageReceipt).all()
|
||||
self.assertEqual([route.target_message_id], [item.message_id for item in receipts])
|
||||
summary = service.delivery_receipt_summaries(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
producer_module="campaigns",
|
||||
delivery_ids=(result.delivery_id,),
|
||||
)[result.delivery_id]
|
||||
self.assertEqual(2, summary.message_count)
|
||||
self.assertEqual(1, summary.routed_message_count)
|
||||
self.assertEqual(1, summary.read_receipt_count)
|
||||
self.assertEqual({"accepted": 1}, summary.route_status_counts)
|
||||
|
||||
def test_hierarchy_dry_run_explains_gates_depth_and_parallel_structure(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user