feat(mail): add governed JMAP mailbox sync and search
Module Package Release / publish-packages (push) Successful in 12s

This commit is contained in:
2026-08-22 17:09:05 +02:00
parent fd808336bc
commit 1cbf4acaf4
29 changed files with 2481 additions and 183 deletions
+79
View File
@@ -821,6 +821,85 @@ class ProfileActorAuthorizationTests(unittest.TestCase):
self.assertFalse(response.refreshing)
self.assertEqual(session.commits, 1)
def test_jmap_mailbox_list_uses_protocol_neutral_response_and_provider_search(self) -> None:
principal = _Principal({"mail:mailbox:read", "mail:profile:use"})
jmap = SimpleNamespace(session_url="https://jmap.example.test/.well-known/jmap")
provider_result = SimpleNamespace(
host="jmap.example.test",
port=443,
security="https",
folder="INBOX",
messages=[],
total_count=0,
offset=0,
limit=25,
uidvalidity="query-state-1",
cursor_reset=False,
)
with (
patch("govoplan_mail.backend.router._jmap_config_for_principal", return_value=jmap),
patch("govoplan_mail.backend.router.list_jmap_messages", return_value=provider_result) as provider,
patch("govoplan_mail.backend.router._next_jmap_mailbox_cursor", return_value=(None, True)),
):
response = router.list_profile_mailbox_messages(
"profile-1",
folder="INBOX",
limit=25,
offset=0,
cursor=None,
refresh=False,
protocol="jmap",
q="budget",
principal=principal, # type: ignore[arg-type]
session=_Session(), # type: ignore[arg-type]
)
provider.assert_called_once_with(
jmap_config=jmap,
folder="INBOX",
limit=25,
offset=0,
expected_query_state=None,
query="budget",
)
self.assertEqual("profile-1", response.profile_id)
self.assertEqual("INBOX", response.folder)
self.assertEqual([], response.messages)
self.assertTrue(response.cursor_stable)
def test_jmap_changes_maps_bounded_incremental_state(self) -> None:
principal = _Principal({"mail:mailbox:read", "mail:profile:use"})
jmap = SimpleNamespace(session_url="https://jmap.example.test/.well-known/jmap")
changes = SimpleNamespace(
account_id="account-1",
old_state="state-1",
new_state="state-2",
has_more_changes=False,
created=("email-1",),
updated=("email-2",),
destroyed=("email-3",),
)
with (
patch("govoplan_mail.backend.router._jmap_config_for_principal", return_value=jmap),
patch("govoplan_mail.backend.router.get_jmap_email_changes", return_value=changes) as provider,
):
response = router.get_profile_mailbox_changes(
"profile-1",
since_state="state-1",
max_changes=50,
principal=principal, # type: ignore[arg-type]
session=_Session(), # type: ignore[arg-type]
)
provider.assert_called_once_with(
jmap_config=jmap,
since_state="state-1",
max_changes=50,
)
self.assertEqual("jmap", response.protocol)
self.assertEqual(["email-1"], response.created)
self.assertEqual("state-2", response.new_state)
def test_unauthorized_profile_test_fails_before_credentials_or_provider_effect(self) -> None:
principal = _Principal({"mail:profile:test", "mail:profile:use"})
with (