Repository: getmoto/moto

Issue:
verify_email_address not working with display name in 1.3.8
The following tests passes with moto 1.3.6 / boto3 1.7.84 and fails with moto 1.3.8 / boto3 1.9.176:

```
    @mock_ses
    def test_send_email_notification(self):
        sender = 'Foo <foo@bar.baz>'
        conn = boto3.client('ses', region_name='us-east-1')
        conn.verify_email_identity(EmailAddress=sender)
        response = conn.send_email(
            Source=sender,
            Destination={
                'ToAddresses': ['your.friend@hotmail.com']
            },
            Message={
                'Subject': {
                    'Data': 'hi',
                },
                'Body': {
                    'Text': {
                        'Data': 'there',
                    }
                }
            },
        )
        self.assertIsNotNone(response['MessageId'])
        self.assertEquals(response['ResponseMetadata']['HTTPStatusCode'], 200)
```

The failure looks like:

```
======================================================================
ERROR: test_send_email_notification (tests.risk_offline.validation.test_jenkins.JenkinsValidationTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/moto/core/models.py", line 80, in wrapper
    result = func(*args, **kwargs)
  File "/Users/huguesbruant/repos/all-the-things/risk_offline/tests/risk_offline/validation/test_jenkins.py", line 47, in test_send_email_notification
    'Data': 'there',
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/botocore/client.py", line 357, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/botocore/client.py", line 648, in _make_api_call
    operation_model, request_dict, request_context)
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/botocore/client.py", line 667, in _make_request
    return self._endpoint.make_request(operation_model, request_dict)
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/botocore/endpoint.py", line 102, in make_request
    return self._send_request(request_dict, operation_model)
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/botocore/endpoint.py", line 135, in _send_request
    request, operation_model, context)
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/botocore/endpoint.py", line 167, in _get_response
    request, operation_model)
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/botocore/endpoint.py", line 218, in _do_get_response
    response_dict, operation_model.output_shape)
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/botocore/parsers.py", line 240, in parse
    parsed = self._do_error_parse(response, shape)
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/botocore/parsers.py", line 485, in _do_error_parse
    root = self._parse_xml_string_to_dom(xml_contents)
  File "/Users/huguesbruant/repos/all-the-things/deployable/risk-offline/src/.venv/lib/python2.7/site-packages/botocore/parsers.py", line 437, in _parse_xml_string_to_dom
    "invalid XML received:\n%s" % (e, xml_string))
ResponseParserError: Unable to parse response (not well-formed (invalid token): line 6, column 52), invalid XML received:
<?xml version="1.0" encoding="UTF-8"?>
  <Response>
    <Errors>
      <Error>
        <Code>MessageRejected</Code>
        <Message>Email address not verified Foo <foo@bar.baz></Message>

      </Error>
    </Errors>
  <RequestID>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestID>
</Response>
```

removing the display name / angle brackets fixes it


Discussion:
Thanks; I'm going to set this as a feature request to handle the proper encoding of these.

If you have an example of how the XML response should be encoded, that will help.

Resolving patch:
diff --git a/moto/ses/models.py b/moto/ses/models.py
--- a/moto/ses/models.py
+++ b/moto/ses/models.py
@@ -91,9 +91,11 @@ def _is_verified_address(self, source):
         return host in self.domains
 
     def verify_email_identity(self, address):
+        _, address = parseaddr(address)
         self.addresses.append(address)
 
     def verify_email_address(self, address):
+        _, address = parseaddr(address)
         self.email_addresses.append(address)
 
     def verify_domain(self, domain):


Test patch:
diff --git a/tests/test_ses/test_ses_boto3.py b/tests/test_ses/test_ses_boto3.py
--- a/tests/test_ses/test_ses_boto3.py
+++ b/tests/test_ses/test_ses_boto3.py
@@ -214,3 +214,16 @@ def test_send_raw_email_without_source_or_from():
     kwargs = dict(RawMessage={"Data": message.as_string()})
 
     conn.send_raw_email.when.called_with(**kwargs).should.throw(ClientError)
+
+
+@mock_ses
+def test_send_email_notification_with_encoded_sender():
+    sender = "Foo <foo@bar.baz>"
+    conn = boto3.client("ses", region_name="us-east-1")
+    conn.verify_email_identity(EmailAddress=sender)
+    response = conn.send_email(
+        Source=sender,
+        Destination={"ToAddresses": ["your.friend@hotmail.com"]},
+        Message={"Subject": {"Data": "hi",}, "Body": {"Text": {"Data": "there",}}},
+    )
+    response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)