def test_send_email_handles_reply_to_address(notify_api, mocker, reply_to_address, expected_value): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) with notify_api.app_context(): aws_ses_client.send_email(source='*****@*****.**', to_addresses='*****@*****.**', subject='Subject', body='Body', reply_to_address=reply_to_address) boto_mock.send_raw_email.assert_called()
def test_send_email_handles_punycode_to_address(notify_api, mocker): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) with notify_api.app_context(): aws_ses_client.send_email( '*****@*****.**', to_addresses='føøøø@bååååår.com', subject='Subject', body='Body', ) boto_mock.send_raw_email.assert_called()
def test_send_email_handles_reply_to_address(notify_api, mocker, reply_to_address, expected_value): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) with notify_api.app_context(): aws_ses_client.send_email(source=Mock(), to_addresses='*****@*****.**', subject=Mock(), body=Mock(), reply_to_address=reply_to_address) boto_mock.send_email.assert_called_once_with( Source=ANY, Destination=ANY, Message=ANY, ReplyToAddresses=expected_value)
def test_send_email_handles_punycode_to_address(notify_api, mocker): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) with notify_api.app_context(): aws_ses_client.send_email( Mock(), to_addresses='føøøø@bååååår.com', subject=Mock(), body=Mock() ) boto_mock.send_email.assert_called_once_with( Source=ANY, Destination={'ToAddresses': ['føøøø@xn--br-yiaaaaa.com'], 'CcAddresses': [], 'BccAddresses': []}, Message=ANY, ReplyToAddresses=ANY )
def test_send_email_handles_punycode_to_address(notify_api, mocker): boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) mocker.patch.object(aws_ses_client, "statsd_client", create=True) with notify_api.app_context(): aws_ses_client.send_email( "*****@*****.**", to_addresses="føøøø@bååååår.com", subject="Subject", body="Body", ) boto_mock.send_raw_email.assert_called() raw_message = boto_mock.send_raw_email.call_args.kwargs["RawMessage"][ "Data"] expected_to = email_b64_encoding( punycode_encode_email("føøøø@bååååår.com")) assert f"To: {expected_to}" in raw_message
def test_send_email_handles_reply_to_address(notify_api, mocker, reply_to_address, expected_value): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) with notify_api.app_context(): aws_ses_client.send_email( Mock(), Mock(), Mock(), Mock(), reply_to_address=reply_to_address ) boto_mock.send_email.assert_called_once_with( Source=ANY, Destination=ANY, Message=ANY, ReplyToAddresses=expected_value )
def test_send_email_txt_and_html_email(notify_api, mocker): boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) mocker.patch.object(aws_ses_client, "statsd_client", create=True) with notify_api.app_context(): aws_ses_client.send_email( "*****@*****.**", to_addresses="*****@*****.**", subject="Subject", body="email body", html_body="<p>email body</p>", reply_to_address="*****@*****.**", ) boto_mock.send_raw_email.assert_called_once() raw_message = boto_mock.send_raw_email.call_args.kwargs["RawMessage"][ "Data"] regex = dedent(r""" Content-Type: multipart\/alternative; boundary="===============(?P<boundary>.+)==" MIME-Version: 1\.0 Subject: Subject From: from@example\.com To: destination@example\.com reply-to: reply@example\.com --===============(?P<b1>.+)== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1\.0 Content-Transfer-Encoding: 7bit email body --===============(?P<b2>.+)== Content-Type: text/html; charset="us-ascii" MIME-Version: 1\.0 Content-Transfer-Encoding: 7bit <p>email body</p> --===============(?P<b3>.+)==-- """).strip() assert len(set(re.findall(regex, raw_message))) == 1 assert re.match(regex, raw_message)
def test_send_email_does_not_raise_AwsSesClientThrottlingSendRateException_if_non_send_rate_throttling(mocker): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) error_response = { 'Error': { 'Code': 'Throttling', 'Message': 'Daily message quota exceeded', 'Type': 'Sender' } } boto_mock.send_email.side_effect = botocore.exceptions.ClientError(error_response, 'opname') with pytest.raises(AwsSesClientException): aws_ses_client.send_email( source=Mock(), to_addresses='*****@*****.**', subject=Mock(), body=Mock() )
def test_send_email_handles_reply_to_address(notify_api, mocker, reply_to_address, expected_value): boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) mocker.patch.object(aws_ses_client, "statsd_client", create=True) with notify_api.app_context(): aws_ses_client.send_email( source="*****@*****.**", to_addresses="*****@*****.**", subject="Subject", body="Body", reply_to_address=reply_to_address, ) boto_mock.send_raw_email.assert_called() raw_message = boto_mock.send_raw_email.call_args.kwargs["RawMessage"][ "Data"] if not expected_value: assert "reply-to" not in raw_message else: assert f"reply-to: {expected_value}" in raw_message
def test_send_email_raises_other_errs_as_AwsSesClientException(mocker): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) error_response = { 'Error': { 'Code': 'ServiceUnavailable', 'Message': 'some error message from amazon', 'Type': 'Sender' } } boto_mock.send_raw_email.side_effect = botocore.exceptions.ClientError( error_response, 'opname') mocker.patch.object(aws_ses_client, 'statsd_client', create=True) with pytest.raises(AwsSesClientException) as excinfo: aws_ses_client.send_email(source='*****@*****.**', to_addresses='*****@*****.**', subject='Subject', body='Body') assert 'some error message from amazon' in str(excinfo.value)
def test_send_email_raises_other_errs_as_AwsSesClientException(mocker): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) error_response = { 'Error': { 'Code': 'ServiceUnavailable', 'Message': 'some error message from amazon', 'Type': 'Sender' } } boto_mock.send_email.side_effect = botocore.exceptions.ClientError(error_response, 'opname') mocker.patch.object(aws_ses_client, 'statsd_client', create=True) with pytest.raises(AwsSesClientException) as excinfo: aws_ses_client.send_email( source=Mock(), to_addresses=Mock(), subject=Mock(), body=Mock() ) assert 'some error message from amazon' in str(excinfo.value)
def test_send_email_raises_invalid_parameter_value_error_as_EmailClientNonRetryableException( mocker): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) error_response = { 'Error': { 'Code': 'InvalidParameterValue', 'Message': 'some error message from amazon', 'Type': 'Sender' } } boto_mock.send_email.side_effect = botocore.exceptions.ClientError( error_response, 'opname') mocker.patch.object(aws_ses_client, 'statsd_client', create=True) with pytest.raises(EmailClientNonRetryableException) as excinfo: aws_ses_client.send_email(source=Mock(), to_addresses='definitely@invalid_email.com', subject=Mock(), body=Mock()) assert 'some error message from amazon' in str(excinfo.value)
def test_send_email_raises_bad_email_as_InvalidEmailError(mocker): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) error_response = { 'Error': { 'Code': 'InvalidParameterValue', 'Message': 'some error message from amazon', 'Type': 'Sender' } } boto_mock.send_raw_email.side_effect = botocore.exceptions.ClientError( error_response, 'opname') mocker.patch.object(aws_ses_client, 'statsd_client', create=True) with pytest.raises(InvalidEmailError) as excinfo: aws_ses_client.send_email(source='*****@*****.**', to_addresses='definitely@invalid_email.com', subject='Subject', body='Body') assert 'some error message from amazon' in str(excinfo.value) assert 'definitely@invalid_email.com' in str(excinfo.value)
def test_send_email_raises_bad_email_as_InvalidEmailError(mocker): boto_mock = mocker.patch.object(aws_ses_client, '_client', create=True) mocker.patch.object(aws_ses_client, 'statsd_client', create=True) error_response = { 'Error': { 'Code': 'InvalidParameterValue', 'Message': 'some error message from amazon', 'Type': 'Sender' } } boto_mock.send_email.side_effect = botocore.exceptions.ClientError(error_response, 'opname') mocker.patch.object(aws_ses_client, 'statsd_client', create=True) with pytest.raises(InvalidEmailError) as excinfo: aws_ses_client.send_email( source=Mock(), to_addresses='clearly@[email protected]', subject=Mock(), body=Mock() ) assert 'some error message from amazon' in excinfo.value.message assert 'clearly@[email protected]' in excinfo.value.message
def test_send_email_raises_other_errs_as_AwsSesClientException(mocker): boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) mocker.patch.object(aws_ses_client, "statsd_client", create=True) error_response = { "Error": { "Code": "ServiceUnavailable", "Message": "some error message from amazon", "Type": "Sender", } } boto_mock.send_raw_email.side_effect = botocore.exceptions.ClientError( error_response, "opname") mocker.patch.object(aws_ses_client, "statsd_client", create=True) with pytest.raises(AwsSesClientException) as excinfo: aws_ses_client.send_email( source="*****@*****.**", to_addresses="*****@*****.**", subject="Subject", body="Body", ) assert "some error message from amazon" in str(excinfo.value)
def test_send_email_raises_bad_email_as_InvalidEmailError(mocker): boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) mocker.patch.object(aws_ses_client, "statsd_client", create=True) error_response = { "Error": { "Code": "InvalidParameterValue", "Message": "some error message from amazon", "Type": "Sender", } } boto_mock.send_raw_email.side_effect = botocore.exceptions.ClientError( error_response, "opname") mocker.patch.object(aws_ses_client, "statsd_client", create=True) with pytest.raises(InvalidEmailError) as excinfo: aws_ses_client.send_email( source="*****@*****.**", to_addresses="definitely@invalid_email.com", subject="Subject", body="Body", ) assert "some error message from amazon" in str(excinfo.value) assert "definitely@invalid_email.com" in str(excinfo.value)
def test_send_email_txt_and_html_email_with_attachment(notify_api, mocker): boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) mocker.patch.object(aws_ses_client, "statsd_client", create=True) with notify_api.app_context(): aws_ses_client.send_email( "*****@*****.**", to_addresses="*****@*****.**", subject="Subject", body="email body", html_body="<p>email body</p>", attachments=[{ "data": "Canada", "name": "file.txt", "mime_type": "text/plain" }], reply_to_address="*****@*****.**", ) boto_mock.send_raw_email.assert_called_once() raw_message = boto_mock.send_raw_email.call_args.kwargs["RawMessage"][ "Data"] regex = dedent(r""" Content-Type: multipart/mixed; boundary="===============(?P<boundary>.+)==" MIME-Version: 1\.0 Subject: Subject From: from@example\.com To: destination@example\.com reply-to: reply@example\.com --===============(?P<b1>.+)== Content-Type: multipart/alternative; boundary="===============(?P<b2>.+)==" MIME-Version: 1\.0 --===============(?P<b3>.+)== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1\.0 Content-Transfer-Encoding: 7bit email body --===============(?P<b4>.+)== Content-Type: text/html; charset="us-ascii" MIME-Version: 1\.0 Content-Transfer-Encoding: 7bit <p>email body</p> --===============(?P<b5>.+)==-- --===============(?P<b6>.+)== Content-Type: application/octet-stream MIME-Version: 1\.0 Content-Transfer-Encoding: base64 Content-Type: text/plain; name="file\.txt" Content-Disposition: attachment; filename="file\.txt" Q2FuYWRh --===============(?P<b7>.+)==-- """).strip() groups = re.match(regex, raw_message).groupdict() assert groups["boundary"] == groups["b7"] == groups["b6"] == groups["b1"] assert groups["b2"] == groups["b3"] == groups["b4"] == groups["b5"] assert re.match(regex, raw_message)