Skip to content

Commit

Permalink
fix: enable UTF8 IMAP capability (#671)
Browse files Browse the repository at this point in the history
  • Loading branch information
firstof9 authored May 23, 2022
2 parents 1867b73 + ef90c58 commit 470f653
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 11 deletions.
22 changes: 16 additions & 6 deletions custom_components/mail_and_packages/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,17 +534,27 @@ def email_search(
Returns a tuple
"""
utf8_flag, search = build_search(address, date, subject)
value = ("", [""])

if utf8_flag:
subject = subject.encode("utf-8")
account.literal = subject
cmd = None
try:
value = account.uid("SEARCH", "CHARSET", "UTF-8", search)
cmd = account.enable("UTF8=ACCEPT")
except Exception as err:
_LOGGER.warning(
"Error searching emails with unicode characters: %s", str(err)
)
_LOGGER.warning("UTF-8 not supported: %s", str(err))
value = "BAD", err.args[0]

if cmd == "OK":
subject = subject.encode("utf-8")
account.literal = subject
try:
value = account.uid("SEARCH", "CHARSET", "UTF-8", search)
except Exception as err:
_LOGGER.warning(
"Error searching emails with unicode characters: %s", str(err)
)
value = "BAD", err.args[0]

else:
try:
value = account.search(None, search)
Expand Down
38 changes: 34 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def mock_imap():
mock_conn.search.return_value = ("OK", [b"1"])
mock_conn.uid.return_value = ("OK", [b"1"])
mock_conn.select.return_value = ("OK", [])
mock_conn.enable.return_value = ("OK", [])
yield mock_conn


Expand Down Expand Up @@ -123,6 +124,7 @@ def mock_imap_no_email():
mock_conn.search.return_value = ("OK", [b""])
mock_conn.uid.return_value = ("OK", [b""])
mock_conn.select.return_value = ("OK", [])
mock_conn.enable.return_value = ("OK", [])
yield mock_conn


Expand Down Expand Up @@ -390,17 +392,44 @@ def mock_imap_dhl_out_for_delivery():
email_file = f.read()
mock_conn.fetch.return_value = ("OK", [(b"", email_file.encode("utf-8"))])
mock_conn.select.return_value = ("OK", [])
mock_conn.enable.return_value = ("OK", [])
yield mock_conn

@pytest.fixture()
def mock_imap_dhl_no_utf8():
"""Mock imap class values."""
with patch(
"custom_components.mail_and_packages.helpers.imaplib"
) as mock_imap_dhl_no_utf8:
mock_conn = mock.Mock(spec=imaplib.IMAP4_SSL)
mock_imap_dhl_no_utf8.IMAP4_SSL.return_value = mock_conn

mock_conn.login.return_value = (
"OK",
[b"[email protected] authenticated (Success)"],
)
mock_conn.list.return_value = (
"OK",
[b'(\\HasNoChildren) "/" "INBOX"'],
)
mock_conn.search.return_value = ("OK", [b"1"])
mock_conn.uid.return_value = ("OK", [b"1"])
f = open("tests/test_emails/dhl_out_for_delivery.eml", "r")
email_file = f.read()
mock_conn.fetch.return_value = ("OK", [(b"", email_file.encode("utf-8"))])
mock_conn.select.return_value = ("OK", [])
mock_conn.enable.side_effect = Exception("BAD", ["Unsupported"])
yield mock_conn


@pytest.fixture()
def mock_imap_fedex_out_for_delivery():
"""Mock imap class values."""
with patch(
"custom_components.mail_and_packages.helpers.imaplib"
) as mock_imap_dhl_out_for_delivery:
) as mock_imap_fedex_out_for_delivery:
mock_conn = mock.Mock(spec=imaplib.IMAP4_SSL)
mock_imap_dhl_out_for_delivery.IMAP4_SSL.return_value = mock_conn
mock_imap_fedex_out_for_delivery.IMAP4_SSL.return_value = mock_conn

mock_conn.login.return_value = (
"OK",
Expand All @@ -416,6 +445,7 @@ def mock_imap_fedex_out_for_delivery():
email_file = f.read()
mock_conn.fetch.return_value = ("OK", [(b"", email_file.encode("utf-8"))])
mock_conn.select.return_value = ("OK", [])
mock_conn.enable.return_value = ("OK", [])
yield mock_conn


Expand All @@ -424,9 +454,9 @@ def mock_imap_fedex_out_for_delivery_2():
"""Mock imap class values."""
with patch(
"custom_components.mail_and_packages.helpers.imaplib"
) as mock_imap_dhl_out_for_delivery:
) as mock_imap_fedex_out_for_delivery_2:
mock_conn = mock.Mock(spec=imaplib.IMAP4_SSL)
mock_imap_dhl_out_for_delivery.IMAP4_SSL.return_value = mock_conn
mock_imap_fedex_out_for_delivery_2.IMAP4_SSL.return_value = mock_conn

mock_conn.login.return_value = (
"OK",
Expand Down
11 changes: 10 additions & 1 deletion tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,12 +698,21 @@ async def test_usps_out_for_delivery(hass, mock_imap_usps_out_for_delivery):
assert result["tracking"] == ["92123456508577307776690000"]


async def test_dhl_out_for_delivery(hass, mock_imap_dhl_out_for_delivery):
async def test_dhl_out_for_delivery(hass, mock_imap_dhl_out_for_delivery, caplog):
result = get_count(
mock_imap_dhl_out_for_delivery, "dhl_delivering", True, "./", hass
)
assert result["count"] == 1
assert result["tracking"] == ["4212345678"]
assert "UTF-8 not supported." not in caplog.text

async def test_dhl_no_utf8(hass, mock_imap_dhl_no_utf8, caplog):
result = get_count(
mock_imap_dhl_no_utf8, "dhl_delivering", True, "./", hass
)
assert result["count"] == 1
assert result["tracking"] == ["4212345678"]
assert "UTF-8 not supported: ('BAD', ['Unsupported'])" in caplog.text


async def test_hermes_out_for_delivery(hass, mock_imap_hermes_out_for_delivery):
Expand Down

0 comments on commit 470f653

Please sign in to comment.