def process_event_to_emails_with_full_context( self, is_secure: bool, timestamp: int, context: dict, thread_store: ThreadStore) -> list[OutgoingEmail]: """Turn the raw Phabricator context into outgoing emails.""" batch = MailBatch(self._template_store) actor = Actor.parse(context["actor"]) body = parse_body(context["eventKind"], is_secure, context["body"], batch) if is_secure: revision = SecureRevision.parse(context["revision"]) thread = thread_store.get_or_create(revision.id) thread.email_count += 1 return batch.process_secure( revision, actor, thread.email_count, timestamp, body, ) else: revision = Revision.parse(context["revision"]) thread = thread_store.get_or_create(revision.id) thread.email_count += 1 return batch.process( revision, actor, thread.email_count, timestamp, body, )
def process_event_to_emails( self, event: Dict, thread_store: ThreadStore) -> List[OutgoingEmail]: """Turn the raw Phabricator event into an outgoing email.""" is_secure = event["isSecure"] kind = event["eventKind"] timestamp = event["timestamp"] actor_name = event["actorName"] body = event["body"] batch = MailBatch(self._template_store) body = parse_body(kind, is_secure, body, batch) if is_secure: revision = SecureRevision.parse(event["revision"]) thread = thread_store.get_or_create(revision.id) thread.email_count += 1 return batch.process_secure( revision, actor_name, thread.email_count, timestamp, body, ) else: revision = Revision.parse(event["revision"]) thread = thread_store.get_or_create(revision.id) thread.email_count += 1 return batch.process( revision, actor_name, thread.email_count, timestamp, body, )
def test_process_public_event(): store = MockTemplateStore() batch = MailBatch(store) batch.target(NON_ACTOR_RECIPIENT, "template-author") emails = batch.process(PUBLIC_REVISION, "actor", 0, 0, EVENT) assert len(emails) == 1 email = emails[0] assert email.subject == "D1: revision" assert store.last_template_path == PUBLIC_TEMPLATE_PATH_PREFIX + "template-author"
def test_process_secure_event(): store = MockTemplateStore() batch = MailBatch(store) batch.target(NON_ACTOR_RECIPIENT, "template-author") emails = batch.process_secure( SecureRevision(2, "link", SecureBug(1, "bug link")), "actor", 0, 0, EVENT ) assert len(emails) == 1 email = emails[0] assert email.subject == "D2: (secure bug 1)" assert store.last_template_path == SECURE_TEMPLATE_PATH_PREFIX + "template-author"
def test_target(): batch = MailBatch(MockTemplateStore()) batch.target(Recipient("1@mail", "1", timezone.utc, False), "template-author") batch.target(Recipient("2@mail", "2", timezone.utc, False), "template-reviewer") emails = batch.process(PUBLIC_REVISION, "actor", 0, 0, EVENT) assert len(emails) == 2 assert emails[0].to == "1@mail" assert emails[1].to == "2@mail"
def test_passes_arguments_to_template(): store = MockTemplateStore() batch = MailBatch(store) batch.target(NON_ACTOR_RECIPIENT, "template-author", extra_template_param="value") batch.process(PUBLIC_REVISION, ACTOR, 0, 0, EVENT) assert store.last_template_params()["extra_template_param"] == "value"
def test_only_sends_to_each_recipient_once(): batch = MailBatch(MockTemplateStore()) batch.target(Recipient("1@mail", "1", timezone.utc, False), "template-author") batch.target_many( [ Recipient("1@mail", "1", timezone.utc, False), Recipient("2@mail", "2", timezone.utc, False), ], "template-reviewer", ) emails = batch.process(PUBLIC_REVISION, ACTOR, 0, 0, EVENT) assert len(emails) == 2 assert emails[0].to == "1@mail" assert emails[1].to == "2@mail"
def test_target_many(): batch = MailBatch(MockTemplateStore()) batch.target_many( [ Recipient("1@mail", "1", timezone.utc, False), Recipient("2@mail", "2", timezone.utc, False), ], "template-reviewer", ) batch.target_many( [ Recipient("3@mail", "3", timezone.utc, False), Recipient("4@mail", "4", timezone.utc, False), ], "template-reviewer", ) emails = batch.process(PUBLIC_REVISION, "actor", 0, 0, EVENT) assert len(emails) == 4 assert emails[0].to == "1@mail" assert emails[1].to == "2@mail" assert emails[2].to == "3@mail" assert emails[3].to == "4@mail"
def test_filter_target_is_actor(): batch = MailBatch(MockTemplateStore()) batch.target(Recipient("1@mail", "1", timezone.utc, True), "template-author") emails = batch.process(PUBLIC_REVISION, "actor", 0, 0, EVENT) assert len(emails) == 0
def test_filter_target_no_recipient(): batch = MailBatch(MockTemplateStore()) batch.target(None, "template-author") emails = batch.process(PUBLIC_REVISION, "actor", 0, 0, EVENT) assert len(emails) == 0
def parse_body(kind: str, is_secure: bool, raw_body: dict, batch: MailBatch): if kind == RevisionAccepted.KIND: if is_secure: body = SecureRevisionAccepted.parse(raw_body) else: body = RevisionAccepted.parse(raw_body) batch.target(body.author, "accepted-as-author") batch.target_many(body.reviewers, "accepted") batch.target_many(body.subscribers, "accepted") elif kind == RevisionMetadataEdited.KIND: # There's no "insecure" variant for when metadata is edited body = RevisionMetadataEdited.parse(raw_body) batch.target(body.author, "edited-metadata") for reviewer in body.reviewers: if reviewer.metadata_change == ExistenceChange.ADDED: batch.target_many(reviewer.recipients, "added-as-reviewer", reviewer=reviewer) elif reviewer.metadata_change == ExistenceChange.REMOVED: batch.target_many(reviewer.recipients, "removed-as-reviewer") else: batch.target_many( reviewer.recipients, "edited-metadata-as-reviewer", reviewer=reviewer, ) batch.target_many(body.subscribers, "edited-metadata") elif kind == RevisionCommented.KIND: if is_secure: body = SecureRevisionCommented.parse(raw_body) else: body = RevisionCommented.parse(raw_body) batch.target(body.author, "commented") batch.target_many(body.reviewers, "commented") batch.target_many(body.subscribers, "commented") elif kind == RevisionClosed.KIND or _is_legacy_revision_landed( kind, raw_body): if is_secure: body = SecureRevisionClosed.parse(raw_body) else: body = RevisionClosed.parse(raw_body) batch.target(body.author, "closed") batch.target_many(body.reviewers, "closed") batch.target_many(body.subscribers, "closed") elif kind == RevisionLanded.KIND: if is_secure: body = SecureRevisionLanded.parse(raw_body) else: body = RevisionLanded.parse(raw_body) batch.target(body.author, "landed") batch.target_many(body.reviewers, "landed") batch.target_many(body.subscribers, "landed") elif kind == RevisionCommentPinged.KIND: if is_secure: body = SecureRevisionCommentPinged.parse(raw_body) else: body = RevisionCommentPinged.parse(raw_body) batch.target(body.recipient, "pinged") elif kind == RevisionRequestedChanges.KIND: if is_secure: body = SecureRevisionRequestedChanges.parse(raw_body) else: body = RevisionRequestedChanges.parse(raw_body) batch.target(body.author, "requested-changes-as-author") batch.target_many(body.reviewers, "requested-changes") batch.target_many(body.subscribers, "requested-changes") elif kind == RevisionRequestedReview.KIND: if is_secure: body = SecureRevisionRequestedReview.parse(raw_body) else: body = RevisionRequestedReview.parse(raw_body) for reviewer in body.reviewers: batch.target_many(reviewer.recipients, "requested-review-as-reviewer", reviewer=reviewer) batch.target_many(body.subscribers, "requested-review") elif kind == RevisionUpdated.KIND: if is_secure: body = SecureRevisionUpdated.parse(raw_body) else: body = RevisionUpdated.parse(raw_body) for reviewer in body.reviewers: batch.target_many(reviewer.recipients, "updated-as-reviewer", reviewer=reviewer) batch.target_many(body.subscribers, "updated") elif kind == RevisionAbandoned.KIND: if is_secure: body = SecureRevisionAbandoned.parse(raw_body) else: body = RevisionAbandoned.parse(raw_body) batch.target_many(body.reviewers, "abandoned") batch.target_many(body.subscribers, "abandoned") elif kind == RevisionReclaimed.KIND: if is_secure: body = SecureRevisionReclaimed.parse(raw_body) else: body = RevisionReclaimed.parse(raw_body) for reviewer in body.reviewers: batch.target_many(reviewer.recipients, "reclaimed-as-reviewer", reviewer=reviewer) batch.target_many(body.subscribers, "reclaimed") elif kind == RevisionCreated.KIND: if is_secure: body = SecureRevisionCreated.parse(raw_body) else: body = RevisionCreated.parse(raw_body) for reviewer in body.reviewers: batch.target_many(reviewer.recipients, "created-as-reviewer", reviewer=reviewer) batch.target_many(body.subscribers, "created") else: raise ParseError(f"Unexpected revision event kind: {kind}") return body
def test_dont_override_target(): batch = MailBatch(MockTemplateStore()) batch.target(NON_ACTOR_RECIPIENT, "template-author") batch.target(NON_ACTOR_RECIPIENT, "template-subscriber") emails = batch.process(PUBLIC_REVISION, ACTOR, 0, 0, EVENT) assert len(emails) == 1