def test_processes_with_minimal_context_if_full_context_error(): event = { "isSecure": True, "timestamp": 0, "context": { "thisContextIsMissingProperties": True, }, "minimalContext": { "revision": { "revisionId": 1, "link": "link", }, "recipients": [{ "username": "******", "email": "2@mail", "timezoneOffset": 0, "isActor": False, }], }, } mail = MockMail() render = Render(JinjaTemplateStore("", "", False)) logger = logging.create_dev_logger() with spy_on(mail.send) as spy: process_event(event, render, MockThreadStore(), logger, 0, Mock(), mail) assert len(spy.calls) == 1 assert spy.calls[0].args[0].template_path == "minimal"
def test_processes_secure_events(): render = Render(MockTemplateStore()) thread_store = MockThreadStore() emails = render.process_event_to_emails(_create_secure_event(1, 2), thread_store) assert len(emails) == 1 email = emails[0] assert email.subject == "D1: (secure bug 2)" assert email.to == "reviewer@mail"
def test_processes_events(): render = Render(MockTemplateStore()) thread_store = MockThreadStore() emails = render.process_event_to_emails(_create_public_event(), thread_store) assert len(emails) == 1 email = emails[0] assert email.subject == "D1: revision" assert email.timestamp == 123 assert email.to == "reviewer@mail"
def test_poll_caught_up(): position = QueryPosition() position.up_to_key = 10 def pipeline(*unused): return 10 worker = PhabricatorWorker(create_dev_logger(), 60, False) caught_up = worker._poll(MockQueryPositionStore(position=position), MockThreadStore(), pipeline) assert caught_up is True
def test_unique_number_is_different_for_each_thread_email(): template_store = MockTemplateStore() render = Render(template_store) thread_store = MockThreadStore() render.process_event_to_emails(_create_public_event(1), thread_store) assert template_store.last_template_params["unique_number"] == 1 render.process_event_to_emails(_create_public_event(1), thread_store) assert template_store.last_template_params["unique_number"] == 2 render.process_event_to_emails(_create_public_event(2), thread_store) assert template_store.last_template_params["unique_number"] == 1
def test_poll_fresh_events(): position = QueryPosition() position.up_to_key = 10 def pipeline(*unused): return 20 worker = PhabricatorWorker(create_dev_logger(), 60) caught_up = worker._poll( MockQueryPositionStore(position=position), MockThreadStore(), pipeline ) assert caught_up is False assert position.up_to_key == 20
def test_pipeline_updates_position_even_if_no_new_events(): # Sometimes, a feed event may happen that isn't relevant to emails. Phabricator # will report a newer feed position while returning an empty event list. source = MockSource(next_result={ "data": { "events": [], "storyErrors": 0 }, "cursor": { "after": 20 } }) logger = logging.create_dev_logger() pipeline = Pipeline(source, Mock(), MockMail(), logger, 0, Mock(), False) new_position = pipeline.run(MockThreadStore(), 10) assert new_position == 20
def test_integration_pipeline(): source = MockSource( next_result={ "data": { "storyErrors": 0, "events": [ { "isSecure": True, "timestamp": 0, "context": { "eventKind": "revision-reclaimed", "actor": { "userName": "******", "realName": "1" }, "body": { "reviewers": [ { "name": "2", "isActionable": False, "status": "accepted", "recipients": [{ "timezoneOffset": 0, "username": "******", "email": "2@mail", "isActor": False, }], }, { "name": "3", "isActionable": True, "status": "requested-changes", "recipients": [{ "timezoneOffset": 0, "username": "******", "email": "3@mail", "isActor": False, }], }, ], "subscribers": [{ "email": "3@mail", "username": "******", "timezoneOffset": 0, "isActor": False, }], "commentCount": 1, "transactionLink": "link", }, "revision": { "revisionId": 1, "repositoryName": "repo", "link": "link", "bug": { "bugId": 1, "link": "link" }, }, }, }, { "isSecure": False, "timestamp": 1, "context": { "eventKind": "revision-abandoned", "actor": { "userName": "******", "realName": "4" }, "body": { "reviewers": [{ "username": "******", "email": "5@mail", "timezoneOffset": 0, "isActor": False, }], "subscribers": [], "mainCommentMessage": { "asText": "Main comment", "asHtml": "<p>Main comment</p>", }, "inlineComments": [{ "contextKind": "code", "context": { "diff": [{ "lineNumber": 10, "type": "added", "rawContent": "hello world", }] }, "fileContext": "/README:20", "link": "link", "message": { "asText": "great content here.", "asHtml": "<em>great content here.</em>", }, }], "transactionLink": "link", }, "revision": { "revisionId": 2, "name": "name 2", "repositoryName": "repo", "link": "link", }, }, }, ], }, "cursor": { "after": 20 }, }) mail = MockMail() render = Render(JinjaTemplateStore("", "", False)) logger = logging.create_dev_logger() pipeline = Pipeline(source, render, mail, logger, 0, Mock(), False) with spy_on(mail.send) as send_spy, spy_on(source.fetch_next) as fetch_spy: new_position = pipeline.run(MockThreadStore(), 10) assert new_position == 20 assert fetch_spy.calls[0].args[0] == 10 emails = [] for call in send_spy.calls: emails.append(call.args[0]) _assert_mail( emails[0], "D1: (secure bug 1)", "2@mail", "1 reclaimed this revision that you've accepted and submitted a comment.", ) _assert_mail( emails[1], "D1: (secure bug 1)", "3@mail", "1 reclaimed this revision and submitted a comment.", ) _assert_mail( emails[2], "D2: name 2", "5@mail", "4 abandoned this revision and submitted comments.", )
def test_retries_failed_full_sends_with_minimal_emails(send_emails_fn): event = { "timestamp": 0, "isSecure": True, "context": { "eventKind": "revision-reclaimed", "actor": { "userName": "******", "realName": "1" }, "body": { "reviewers": [{ "name": "2", "isActionable": False, "status": "unreviewed", "recipients": [ { "username": "******", "email": "2@mail", "timezoneOffset": 0, "isActor": False, }, { "username": "******", "email": "3@mail", "timezoneOffset": 0, "isActor": False, }, ], }], "subscribers": [], "commentCount": 1, "transactionLink": "link", }, "revision": { "revisionId": 1, "link": "link", "bug": { "bugId": 1, "link": "link" }, }, }, "minimalContext": { "revision": { "revisionId": 1, "link": "link", }, "recipients": [ { "username": "******", "email": "2@mail", "timezoneOffset": 0, "isActor": False, }, { "username": "******", "email": "3@mail", "timezoneOffset": 0, "isActor": False, }, ], }, } send_emails_fn.side_effect = [["2@mail"], []] render = Render(JinjaTemplateStore("", "", False)) logger = logging.create_dev_logger() process_event(event, render, MockThreadStore(), logger, 0, Mock(), None) assert len(send_emails_fn.call_args_list) == 2 assert len(send_emails_fn.call_args_list[1][0][3]) == 1 _assert_mail( send_emails_fn.call_args_list[1][0][3][0], "D1", "2@mail", "An (unknown) action occurred", )
def test_pipeline_returns_same_position_if_fetch_fails(): source = MockSource(fail_on_fetch_next=True) pipeline = Pipeline(source, Mock(), Mock(), logging.create_dev_logger(), 0, Mock(), False) assert pipeline.run(MockThreadStore(), 10) == 10