def test_returns_error_payload_if_expected_already_subscribed_email_error(self, get_email_hash):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))

        with mock.patch.object(
            dm_mailchimp_client._client.lists.members, 'create_or_update', autospec=True
        ) as create_or_update:

            response = mock.MagicMock(__bool__=False)
            expected_error = "[email protected] is already a list member. Use PUT to insert or update list members."

            response.status_code = 400
            response.message = (
                "Bad Request for url: https://us5.api.mailchimp.com/3.0/lists/list_id/members/member_id"
            )
            response.json.return_value = {"detail": expected_error}
            create_or_update.side_effect = HTTPError("400 Client Error", response=response)

            with assert_external_service_log_entry(successful_call=False, extra_modules=['mailchimp']) as log_catcher:
                res = dm_mailchimp_client.subscribe_new_email_to_list('list_id', '*****@*****.**')

            assert res == {"status": "error", "error_type": "already_subscribed", "status_code": 400}
            assert log_catcher.records[1].msg == (
                "Expected error: Mailchimp failed to add user (foo) to list (list_id). "
                "API error: This email address is already subscribed."
            )
            assert log_catcher.records[1].error == "400 Client Error"
            assert log_catcher.records[1].levelname == 'WARNING'
    def test_returns_error_payload_if_user_previously_unsubscribed_error(self, get_email_hash):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))

        with mock.patch.object(
            dm_mailchimp_client._client.lists.members, 'create_or_update', autospec=True
        ) as create_or_update:

            response = mock.MagicMock(__bool__=False)
            expected_error = "[email protected] was permanently deleted and cannot be re-imported. " \
                             "The contact must re-subscribe to get back on the list."

            response.status_code = 400
            response.message = (
                "Bad Request for url: https://us5.api.mailchimp.com/3.0/lists/list_id/members/member_id"
            )
            response.json.return_value = {"detail": expected_error}
            create_or_update.side_effect = HTTPError("400 Client Error", response=response)

            with assert_external_service_log_entry(successful_call=False, extra_modules=['mailchimp']) as log_catcher:
                res = dm_mailchimp_client.subscribe_new_email_to_list('list_id', '*****@*****.**')

            assert res == {"status": "error", "error_type": "deleted_user", "status_code": 400}
            assert log_catcher.records[1].msg == (
                "Expected error: Mailchimp cannot automatically subscribe user (foo) to list (list_id) as the user "
                "has been permanently deleted."
            )
            assert log_catcher.records[1].error == "400 Client Error"
            assert log_catcher.records[1].levelname == 'WARNING'
Exemplo n.º 3
0
def test_success_does_not_perform_retry():
    dm_mailchimp_client = DMMailChimpClient('username',
                                            'api key',
                                            mock.MagicMock(),
                                            retries=2)
    with mock.patch.object(dm_mailchimp_client._client.lists.members,
                           'all',
                           autospec=True) as all_members:
        all_members.side_effect = [
            {
                "members": [
                    {
                        "email_address": "*****@*****.**"
                    },
                    {
                        "email_address": "*****@*****.**"
                    },
                ]
            },
            {
                "members": []
            },
        ]
        dm_mailchimp_client.get_email_addresses_from_list('a_list_id')
        assert all_members.mock_calls == [
            mock.call('a_list_id', count=1000, offset=0),
            mock.call('a_list_id', count=1000, offset=1000),
        ]
    def test_returns_error_payload_if_email_fails_validation(self, get_email_hash):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))

        with mock.patch.object(
            dm_mailchimp_client._client.lists.members, 'create_or_update', autospec=True
        ) as create_or_update:
            create_or_update.side_effect = MailChimpError(
                {
                    "detail": "Please provide a valid email address.",
                    'title': 'Invalid Resource',
                    'status': 400
                }
            )

            with assert_external_service_log_entry(successful_call=False, extra_modules=['mailchimp']) as log_catcher:
                res = dm_mailchimp_client.subscribe_new_email_to_list('list_id', '*****@*****.**')

            assert res == {"status": "error", "error_type": "invalid_email", "status_code": 400}
            assert log_catcher.records[1].msg == (
                "Expected error: Mailchimp failed to add user (foo) to list (list_id). "
                "API error: The email address was invalid."
            )
            assert log_catcher.records[1].error == "{'detail': 'Please provide a valid email address.', " \
                "'title': 'Invalid Resource', 'status': 400}"
            assert log_catcher.records[1].levelname == 'WARNING'
Exemplo n.º 5
0
def test_get_email_addresses_from_list():
    dm_mailchimp_client = DMMailChimpClient('username', 'api key',
                                            mock.MagicMock())
    with mock.patch.object(dm_mailchimp_client._client.lists.members,
                           'all',
                           autospec=True) as all_members:

        all_members.side_effect = [
            {
                "members": [
                    {
                        "email_address": "*****@*****.**"
                    },
                    {
                        "email_address": "*****@*****.**"
                    },
                ]
            },
            {
                "members": []
            },
        ]

        res = dm_mailchimp_client.get_email_addresses_from_list('list_id')

        assert res == ["*****@*****.**", "*****@*****.**"]

        assert all_members.call_args_list == [
            mock.call('list_id', count=1000, offset=0),
            mock.call('list_id', count=1000, offset=1000),
        ]
    def test_get_email_addresses_from_list_generates_emails(self):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))
        with mock.patch.object(dm_mailchimp_client._client.lists.members, 'all', autospec=True) as all_members:
            all_members.side_effect = [
                {
                    "members": [
                        {"email_address": "*****@*****.**"},
                        {"email_address": "*****@*****.**"},
                    ]
                },
                {
                    "members": []
                },
            ]

            res = dm_mailchimp_client.get_email_addresses_from_list('list_id')

            assert isinstance(res, types.GeneratorType)
            assert all_members.call_args_list == []

            with assert_external_service_log_entry(extra_modules=['mailchimp'], count=2):
                assert list(res) == ["*****@*****.**", "*****@*****.**"]

            assert all_members.call_args_list == [
                mock.call('list_id', count=100, offset=0),
                mock.call('list_id', count=100, offset=100),
            ]
def join_open_framework_notification_mailing_list():
    status = 200

    form = EmailAddressForm()
    if form.validate_on_submit():
        dmmc_client = DMMailChimpClient(
            current_app.config["DM_MAILCHIMP_USERNAME"],
            current_app.config["DM_MAILCHIMP_API_KEY"],
            current_app.logger,
        )

        mc_response = dmmc_client.subscribe_new_email_to_list(
            current_app.config["DM_MAILCHIMP_OPEN_FRAMEWORK_NOTIFICATION_MAILING_LIST_ID"],
            form.data["email_address"],
        )
        if mc_response.get('status') == 'success':
            data_api_client.create_audit_event(
                audit_type=AuditTypes.mailing_list_subscription,
                data={
                    "subscribedEmail": form.data["email_address"],
                    "mailchimp": {k: mc_response.get(k) for k in (
                        "id",
                        "unique_email_id",
                        "timestamp_opt",
                        "last_changed",
                        "list_id",
                    )},
                },
            )

            flash(JOIN_OPEN_FRAMEWORK_NOTIFICATION_MAILING_LIST_SUCCESS_MESSAGE.format(
                email_address=form.data["email_address"],
            ), "success")

            return redirect("/")
        else:
            if mc_response.get('error_type') == 'already_subscribed':
                flash(JOIN_OPEN_FRAMEWORK_NOTIFICATION_MAILING_LIST_ALREADY_SUBSCRIBED_MESSAGE.format(
                    support_email_address=current_app.config['SUPPORT_EMAIL_ADDRESS']
                ), "error")
            elif mc_response.get('error_type') in ['deleted_user', 'invalid_email']:
                flash(JOIN_OPEN_FRAMEWORK_NOTIFICATION_MAILING_LIST_UNSUBSCRIBED_MESSAGE.format(
                    support_email_address=current_app.config['SUPPORT_EMAIL_ADDRESS']
                ), "error")
            else:
                flash(JOIN_OPEN_FRAMEWORK_NOTIFICATION_MAILING_LIST_ERROR_MESSAGE.format(
                    support_email_address=current_app.config['SUPPORT_EMAIL_ADDRESS']
                ), "error")
            # If no status code supplied, something has probably gone wrong
            status = mc_response.get('status_code', 503)
            # fall through to re-display form with error
    elif request.method == "POST":
        status = 400
        # fall through to re-display form with errors

    return render_template(
        "suppliers/join_open_framework_notification_mailing_list.html",
        form=form,
        errors=get_errors_from_wtform(form),
    ), status
    def test_timeout_exception_is_not_propagated_for_create_or_update(self):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))
        with mock.patch.object(
                dm_mailchimp_client._client.lists.members, 'create_or_update', autospec=True) as create_or_update:
            create_or_update.side_effect = ConnectTimeout()

            assert dm_mailchimp_client.subscribe_new_email_to_list('a_list_id', '*****@*****.**') == \
                {"status": "error", "error_type": "unexpected_error", "status_code": 500}
            assert create_or_update.called is True
    def test_send_campaign(self):
        campaign_id = "1"
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, mock.MagicMock())
        with mock.patch.object(dm_mailchimp_client._client.campaigns.actions, 'send', autospec=True) as send:
            with assert_external_service_log_entry():
                res = dm_mailchimp_client.send_campaign(campaign_id)

            assert res is True
            send.assert_called_once_with(campaign_id)
Exemplo n.º 10
0
def test_create_campaign():
    dm_mailchimp_client = DMMailChimpClient('username', 'api key', 'logger')
    with mock.patch.object(dm_mailchimp_client._client.campaigns,
                           'create',
                           autospec=True) as create:
        create.return_value = {"id": "100"}
        res = dm_mailchimp_client.create_campaign({"example": "data"})

        assert res == "100"
        create.assert_called_once_with({"example": "data"})
 def test_default_timeout_retry_performs_no_retries(self):
     dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))
     with mock.patch.object(dm_mailchimp_client._client.lists.members, 'all', autospec=True) as all_members:
         all_members.side_effect = HTTPError(response=mock.Mock(status_code=504))
         with pytest.raises(HTTPError):
             with assert_external_service_log_entry(successful_call=False, extra_modules=['mailchimp']):
                 list(dm_mailchimp_client.get_email_addresses_from_list('a_list_id'))
         assert all_members.call_args_list == [
             mock.call('a_list_id', count=100, offset=0),
         ]
    def test_create_campaign(self):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, 'logger')
        with mock.patch.object(dm_mailchimp_client._client.campaigns, 'create', autospec=True) as create:
            create.return_value = {"id": "100"}

            with assert_external_service_log_entry():
                res = dm_mailchimp_client.create_campaign({"example": "data"})

            assert res == "100"
            create.assert_called_once_with({"example": "data"})
Exemplo n.º 13
0
def test_send_campaign():
    campaign_id = "1"
    dm_mailchimp_client = DMMailChimpClient('username', 'api key',
                                            mock.MagicMock())
    with mock.patch.object(dm_mailchimp_client._client.campaigns.actions,
                           'send',
                           autospec=True) as send:
        res = dm_mailchimp_client.send_campaign(campaign_id)

        assert res is True
        send.assert_called_once_with(campaign_id)
    def test_set_campaign_content(self):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, 'logger')
        with mock.patch.object(dm_mailchimp_client._client.campaigns.content, 'update', autospec=True) as update:
            campaign_id = '1'
            html_content = {'html': '<p>One or two words</p>'}
            update.return_value = html_content
            with assert_external_service_log_entry():
                res = dm_mailchimp_client.set_campaign_content(campaign_id, html_content)

            assert res == html_content
            dm_mailchimp_client._client.campaigns.content.update.assert_called_once_with(campaign_id, html_content)
    def test_log_error_message_if_error_setting_campaign_content(self, exception, expected_error):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))
        with mock.patch.object(dm_mailchimp_client._client.campaigns.content, 'update', autospec=True) as update:
            update.side_effect = exception

            with assert_external_service_log_entry(successful_call=False, extra_modules=['mailchimp']) as log_catcher:
                res = dm_mailchimp_client.set_campaign_content('1', {"html": "some html"})

            assert res is False

            assert log_catcher.records[1].msg == "Mailchimp failed to set content for campaign id '1'"
            assert log_catcher.records[1].error == expected_error
    def test_log_error_message_if_error_creating_campaign(self, exception, expected_error):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, mock.MagicMock())
        with mock.patch.object(dm_mailchimp_client._client.campaigns, 'create', autospec=True) as create:
            create.side_effect = exception
            with mock.patch.object(dm_mailchimp_client.logger, 'error', autospec=True) as error:
                with assert_external_service_log_entry(successful_call=False):
                    res = dm_mailchimp_client.create_campaign({"example": "data", 'settings': {'title': 'Foo'}})

                assert res is False
                error.assert_called_once_with(
                    "Mailchimp failed to create campaign for 'campaign title'", extra=expected_error
                )
Exemplo n.º 17
0
def test_default_timeout_retry_performs_no_retries():
    dm_mailchimp_client = DMMailChimpClient('username', 'api key',
                                            mock.MagicMock())
    with mock.patch.object(dm_mailchimp_client._client.lists.members,
                           'all',
                           autospec=True) as all_members:
        all_members.side_effect = HTTPError(response=mock.Mock(
            status_code=504))
        with pytest.raises(HTTPError):
            dm_mailchimp_client.get_email_addresses_from_list('a_list_id')
        assert all_members.call_args_list == [
            mock.call('a_list_id', count=1000, offset=0),
        ]
    def test_subscribe_new_emails_to_list_tries_all_emails_returns_false_on_error(self):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, mock.MagicMock())
        with mock.patch.object(
                dm_mailchimp_client, 'subscribe_new_email_to_list', autospec=True) as subscribe_new_email_to_list:
            subscribe_new_email_to_list.side_effect = [False, True]

            with assert_external_service_log_entry(count=2):
                res = dm_mailchimp_client.subscribe_new_emails_to_list('list_id', ['foo', '*****@*****.**'])

            calls = [mock.call('list_id', 'foo'), mock.call('list_id', '*****@*****.**')]

            assert res is False
            subscribe_new_email_to_list.assert_has_calls(calls)
Exemplo n.º 19
0
def test_log_error_message_if_error_sending_campaign(logger):
    dm_mailchimp_client = DMMailChimpClient('username', 'api key', logger)
    with mock.patch.object(dm_mailchimp_client._client.campaigns.actions,
                           'send',
                           autospec=True) as send:
        send.side_effect = RequestException("error sending")

        res = dm_mailchimp_client.send_campaign("1")

        assert res is False
        logger.error.assert_called_once_with(
            "Mailchimp failed to send campaign id '1'",
            extra={"error": "error sending"})
    def test_log_error_message_if_error_sending_campaign(self, exception, expected_error):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))
        with mock.patch.object(dm_mailchimp_client._client.campaigns.actions, 'send', autospec=True) as send:
            send.side_effect = exception

            with assert_external_service_log_entry(successful_call=False, extra_modules=['mailchimp']) as log_catcher:
                res = dm_mailchimp_client.send_campaign("1")

            assert res is False

            assert log_catcher.records[1].msg == "Mailchimp failed to send campaign id '1'"
            assert log_catcher.records[1].levelname == 'ERROR'
            assert log_catcher.records[1].error == expected_error
    def test_subscribe_new_emails_to_list(self):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, mock.MagicMock())
        with mock.patch.object(dm_mailchimp_client, 'subscribe_new_email_to_list', autospec=True, return_value=True):

            with assert_external_service_log_entry(count=2):
                res = dm_mailchimp_client.subscribe_new_emails_to_list(
                    'list_id',
                    ['*****@*****.**', '*****@*****.**']
                )

            assert res is True
            assert dm_mailchimp_client.subscribe_new_email_to_list.call_args_list == [
                mock.call('list_id', '*****@*****.**'), mock.call('list_id', '*****@*****.**')
            ]
Exemplo n.º 22
0
def test_set_campaign_content():
    dm_mailchimp_client = DMMailChimpClient('username', 'api key', 'logger')
    with mock.patch.object(dm_mailchimp_client._client.campaigns.content,
                           'update',
                           autospec=True) as update:
        campaign_id = '1'
        html_content = {'html': '<p>One or two words</p>'}
        update.return_value = html_content
        res = dm_mailchimp_client.set_campaign_content(campaign_id,
                                                       html_content)

        assert res == html_content
        dm_mailchimp_client._client.campaigns.content.update.assert_called_once_with(
            campaign_id, html_content)
Exemplo n.º 23
0
def test_log_error_message_if_error_setting_campaign_content(logger):
    dm_mailchimp_client = DMMailChimpClient('username', 'api key', logger)
    with mock.patch.object(dm_mailchimp_client._client.campaigns.content,
                           'update',
                           autospec=True) as update:
        update.side_effect = RequestException("error message")

        res = dm_mailchimp_client.set_campaign_content('1',
                                                       {"html": "some html"})

        assert res is False
        logger.error.assert_called_once_with(
            "Mailchimp failed to set content for campaign id '1'",
            extra={"error": "error message"})
    def test_log_mailchimp_error_unexpected_error_payload_if_error_subscribing_email_to_list(self, get_email_hash):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))
        with mock.patch.object(
                dm_mailchimp_client._client.lists.members, 'create_or_update', autospec=True) as create_or_update:
            create_or_update.side_effect = MailChimpError({'request': 'failed', 'status': 500})

            with assert_external_service_log_entry(successful_call=False, extra_modules=['mailchimp']) as log_catcher:
                res = dm_mailchimp_client.subscribe_new_email_to_list('list_id', '*****@*****.**')

            assert res == {"status": "error", "error_type": "unexpected_error", "status_code": 500}

            assert log_catcher.records[1].msg == "Mailchimp failed to add user (foo) to list (list_id)"
            assert log_catcher.records[1].error == "{'request': 'failed', 'status': 500}"
            assert log_catcher.records[1].levelname == 'ERROR'
    def test_handles_responses_with_invalid_json(self, get_email_hash):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))
        with mock.patch.object(
                dm_mailchimp_client._client.lists.members, 'create_or_update', autospec=True) as create_or_update:
            response = mock.Mock()
            response.json.side_effect = JSONDecodeError('msg', 'doc', 0)
            create_or_update.side_effect = RequestException("error sending", response=response)

            with assert_external_service_log_entry(successful_call=False, extra_modules=['mailchimp']) as log_catcher:
                res = dm_mailchimp_client.subscribe_new_email_to_list('list_id', '*****@*****.**')

            assert res == {'error_type': 'unexpected_error', 'status': 'error', 'status_code': 500}
            assert log_catcher.records[1].msg == 'Mailchimp failed to add user (foo) to list (list_id)'
            assert log_catcher.records[1].error == "error sending"
            assert log_catcher.records[1].levelname == 'ERROR'
Exemplo n.º 26
0
def test_subscribe_new_email_to_list(get_email_hash):
    dm_mailchimp_client = DMMailChimpClient('username', 'api key',
                                            mock.MagicMock())
    with mock.patch.object(dm_mailchimp_client._client.lists.members,
                           'create_or_update',
                           autospec=True) as create_or_update:

        create_or_update.return_value = {"response": "data"}
        res = dm_mailchimp_client.subscribe_new_email_to_list(
            'list_id', '*****@*****.**')

        assert res == {"response": "data"}
        create_or_update.assert_called_once_with('list_id', "foo", {
            "email_address": "*****@*****.**",
            "status_if_new": "subscribed"
        })
Exemplo n.º 27
0
def test_subscribe_new_emails_to_list():
    dm_mailchimp_client = DMMailChimpClient('username', 'api key',
                                            mock.MagicMock())
    with mock.patch.object(dm_mailchimp_client,
                           'subscribe_new_email_to_list',
                           autospec=True):
        dm_mailchimp_client.subscribe_new_email_to_list.return_value = True
        res = dm_mailchimp_client.subscribe_new_emails_to_list(
            'list_id', ['*****@*****.**', '*****@*****.**'])
        calls = [
            mock.call('list_id', '*****@*****.**'),
            mock.call('list_id', '*****@*****.**')
        ]

        assert res is True
        dm_mailchimp_client.subscribe_new_email_to_list.assert_has_calls(calls)
    def test_log_request_exception_error_message_if_error_subscribing_email_to_list(self, get_email_hash):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))
        with mock.patch.object(
                dm_mailchimp_client._client.lists.members, 'create_or_update', autospec=True) as create_or_update:
            # The 400 response from MailChimp is actually falsey
            response = mock.MagicMock(__bool__=False)
            response.json.return_value = {"detail": "Unexpected error."}
            create_or_update.side_effect = RequestException("error sending", response=response)

            with assert_external_service_log_entry(successful_call=False, extra_modules=['mailchimp']) as log_catcher:
                res = dm_mailchimp_client.subscribe_new_email_to_list('list_id', '*****@*****.**')

            assert res == {"status": "error", "error_type": "unexpected_error", "status_code": 500}

            assert log_catcher.records[1].msg == "Mailchimp failed to add user (foo) to list (list_id)"
            assert log_catcher.records[1].error == "error sending"
            assert log_catcher.records[1].levelname == 'ERROR'
Exemplo n.º 29
0
def test_subscribe_new_emails_to_list_tries_all_emails_returns_false_on_error(
):
    dm_mailchimp_client = DMMailChimpClient('username', 'api key',
                                            mock.MagicMock())
    with mock.patch.object(dm_mailchimp_client,
                           'subscribe_new_email_to_list',
                           autospec=True) as subscribe_new_email_to_list:
        subscribe_new_email_to_list.side_effect = [False, True]
        res = dm_mailchimp_client.subscribe_new_emails_to_list(
            'list_id', ['foo', '*****@*****.**'])
        calls = [
            mock.call('list_id', 'foo'),
            mock.call('list_id', '*****@*****.**')
        ]

        assert res is False
        subscribe_new_email_to_list.assert_has_calls(calls)
    def test_create_or_update_returns_error_payload_for_expected_request_exception(self, get_email_hash):
        dm_mailchimp_client = DMMailChimpClient('username', DUMMY_MAILCHIMP_API_KEY, logging.getLogger('mailchimp'))
        with mock.patch.object(
                dm_mailchimp_client._client.lists.members, 'create_or_update', autospec=True) as create_or_update:
            response = mock.MagicMock(__bool__=False)
            response.json.return_value = {"detail": "foo looks fake or invalid, please enter a real email address."}
            create_or_update.side_effect = RequestException("error sending", response=response)

            with assert_external_service_log_entry(successful_call=False, extra_modules=['mailchimp']) as log_catcher:
                res = dm_mailchimp_client.subscribe_new_email_to_list('list_id', '*****@*****.**')

            assert res == {"status": "error", "error_type": "invalid_email", "status_code": 400}
            assert log_catcher.records[1].msg == (
                "Expected error: Mailchimp failed to add user (foo) to list (list_id). "
                "API error: The email address looks fake or invalid, please enter a real email address."
            )
            assert log_catcher.records[1].error == "error sending"
            assert log_catcher.records[1].levelname == 'WARNING'