diff --git a/custom_components/mail_and_packages/const.py b/custom_components/mail_and_packages/const.py index 45c1cd2f..0a7c2f48 100644 --- a/custom_components/mail_and_packages/const.py +++ b/custom_components/mail_and_packages/const.py @@ -388,6 +388,17 @@ }, "auspost_packages": {}, "auspost_tracking": {"pattern": ["\\d{7,10,12}|[A-Za-z]{2}[0-9]{9}AU "]}, + # Evri + "evri_delivered": { + "email": ["do-not-reply@evri.com"], + "subject": ["successfully delivered"], + }, + "evri_delivering": { + "email": ["do-not-reply@evri.com"], + "subject": ["is now with your local Evri courier for delivery"], + }, + "evri_packages": {}, + "evri_tracking": {"pattern": ["H[0-9A-Z]{15}"]}, } # Sensor definitions @@ -670,6 +681,25 @@ icon="mdi:package-variant-closed", key="gls_packages", ), + # Evri + "evri_delivered": SensorEntityDescription( + name="Mail Evri Delivered", + native_unit_of_measurement="package(s)", + icon="mdi:package-variant-closed", + key="evri_delivered", + ), + "evri_delivering": SensorEntityDescription( + name="Mail Evri Delivering", + native_unit_of_measurement="package(s)", + icon="mdi:truck-delivery", + key="evri_delivering", + ), + "evri_packages": SensorEntityDescription( + name="Mail Evri Packages", + native_unit_of_measurement="package(s)", + icon="mdi:package-variant-closed", + key="evri_packages", + ), ### # !!! Insert new sensors above these two !!! ### diff --git a/tests/conftest.py b/tests/conftest.py index 36ce5911..f1f1d7f8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -936,6 +936,7 @@ def mock_image_excpetion(): mock_image_excpetion.open.side_effect = Exception("SystemError") yield mock_image_excpetion + @pytest.fixture def mock_image_save_excpetion(): """Fixture to mock Image.""" @@ -946,12 +947,15 @@ def mock_image_save_excpetion(): mock_image_save_excpetion.Image.save.side_effect = Exception("ValueError") yield mock_image_save_excpetion + @pytest.fixture def mock_resizeimage(): """Fixture to mock splitext.""" with patch( "custom_components.mail_and_packages.helpers.Image" - ) as mock_resizeimage, patch("custom_components.mail_and_packages.helpers.ImageOps"): + ) as mock_resizeimage, patch( + "custom_components.mail_and_packages.helpers.ImageOps" + ): yield mock_resizeimage @@ -1034,6 +1038,32 @@ def mock_imap_hermes_out_for_delivery(): yield mock_conn +@pytest.fixture() +def mock_imap_evri_out_for_delivery(): + """Mock imap class values.""" + with patch( + "custom_components.mail_and_packages.helpers.imaplib" + ) as mock_imap_evri_out_for_delivery: + mock_conn = mock.Mock(spec=imaplib.IMAP4_SSL) + mock_imap_evri_out_for_delivery.IMAP4_SSL.return_value = mock_conn + + mock_conn.login.return_value = ( + "OK", + [b"user@fake.email 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/evri_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", []) + yield mock_conn + + @pytest.fixture() def mock_imap_royal_out_for_delivery(): """Mock imap class values.""" diff --git a/tests/test_emails/evri_delivered.eml b/tests/test_emails/evri_delivered.eml new file mode 100644 index 00000000..5a8f95cb --- /dev/null +++ b/tests/test_emails/evri_delivered.eml @@ -0,0 +1,315 @@ +Content-Type: text/html; charset=utf-8 +From: Evri +To: testuser@gmail.com +Subject: Evri has successfully delivered your UKVB parcel +Content-Transfer-Encoding: quoted-printable +Date: Sun, 21 Aug 2022 16:03:54 +0000 +MIME-Version: 1.0 + +
<= +div border=3D"0" width=3D"100%" cellpadding=3D"0" cellspacing=3D"0" bgcolor= +=3D"#EEF2F4" class=3D"hGutters" style=3D"margin: auto;; max-width: 600px; b= +ackground: #EEF2F4; padding: 0 24px">
 
3D"avatar-image"

Your parcel was deliv= +ered by your local courier

Rate your= + local courier to let us know how it went

Rate your local courier to let = +us know how it went

 
<= +tr> = +

Delivery photo

 
3D"Icon"
We ha= +ve a range of return methods
Parcel= +Shop drop off with label printing in ParcelShop, Locker drop off & Courier = +collection
 
<= +/tr>

Tracking num= +ber

H01QPZ0007431687

 
= +
= +

We sent you= + this email on behalf of UKVB as they've asked us to deliver a parcel to yo= +u.

= +We haven't signed you up to a mailing list, and we'll only use your email a= +ddress to contact you about this parcel.

<= +!--[if mso]>

Evri is trading name of Hermes Parcelnet= + Limited.

Registered in England and Wales No. 03900782

Registered office: Capitol House, 1 Capitol Close, M= +orley, Leeds, LS27 0WH

3D"" + diff --git a/tests/test_emails/evri_out_for_delivery.eml b/tests/test_emails/evri_out_for_delivery.eml new file mode 100644 index 00000000..893224d4 --- /dev/null +++ b/tests/test_emails/evri_out_for_delivery.eml @@ -0,0 +1,168 @@ +From: Evri +To: testuser@fake.email +Subject: Your UKVB parcel is now with your local Evri courier for delivery +Content-Transfer-Encoding: quoted-printable +Date: Wed, 20 Apr 2022 10:19:55 +0000 +MIME-Version: 1.0 + + = + = +
3D"Evri,
= +

Hi Test User

We've got your UKVB parcel and we're = +delivering it today between 15:30 and 17:30.

= +
 = +
= +
 

It'll be delivered to:

123 Fake Road, = +London, N2 8JJ

 
 
 

Tra= +cking number

H01= +QDA0004416687

 

We sent you this email on behalf of= + UKVB as they've asked us to deliver a parcel to you.

We haven't = +signed you up to a mailing list, and we'll only use your email address to = +contact you about this parcel.

Evri = +is trading name of Hermes Parcelnet Limited.

Registered in England = +and Wales No. 03900782

Registered = +office: Capitol House, 1 Capitol Close, Morley, Leeds, LS27 0WH

= +
= +
= + diff --git a/tests/test_emails/usps_out_for_delivery.eml b/tests/test_emails/usps_out_for_delivery.eml index 09104227..58a60fcd 100644 --- a/tests/test_emails/usps_out_for_delivery.eml +++ b/tests/test_emails/usps_out_for_delivery.eml @@ -7,27 +7,6 @@ Subject: =?UTF-8?Q?USPS=C2=AE_Expected_Delivery_on_Wednesday,_September_23,_202? MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_1009358_255325476.1600872547127" -X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrILMWRmVeSWpSXmKPExsVicV6jWjc5ITve4PshSYs9b9+zODB67Jx1 - lz2AMYrbJimxpCw4Mz1P3y6BO+PtxxcsBT+TK35uOMDcwNgT3cXIySEhYCKxbvZ5pi5GLg4h - gZOMEuvOrWKESbztnMQIkbjIKDHx7h62LkYODjYBSYlnHWYgNSwC2hLLbhxmAbGFBaQlns+4 - BmaLCIhJzD93CmwOr0CoxOXlEHOEBaYzSlw++IQZIiEocXLmE7AGZoFwiZ/H5rGDFEkIrGOV - 6DjZAnWFmMS0he+ZJjDyzULSMwtJD4QtLnF91X9mCBvoqIWvmRcwsqxilEjP1k3WTc1NzMzR - Ky4qK9YrLS4o1kvPL9vECAo7hn6BHYw7PqccYmTiYDzEKMHBrCTCe0MtO16INyWxsiq1KD++ - qDQntfgQozQHi5I478uFyfFCAumJJanZqakFqUUwWSYOTpBuLimR4tS8lNSixNKSjHhQ2McX - AwNfqoHxZnL1v4fygt9yF896MPlnUqPAwhn1GkcF0j51zH2h+eBu9lk22RdTRV/O/nfmYOaL - RVt458u+veHpMrOxc3+SFddnlp31POx/fV6HS+fLfC1M3Db5VEba3vZnJWvz083vPvJcFD01 - O9Fmhn/E+/9dgozzpBWY1fXuXr7OOLPMIUH7j2yaseElJZbijERDLeai4kQAwRb4IkQCAAA= -X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrIJMWRmVeSWpSXmKPExsVicfL+Bd3khOx4g1WbOCz2vH3P4sDosXPW - XfYAxigum5TUnMyy1CJ9uwSujLcfX7AU/Eyu+LnhAHMDY090FyMnh4SAicTbzkmMXYxcHEIC - FxklJt7dw9bFyMHBJiAp8azDDKSGRUBbYtmNwywgtrCAtMTzGdfAbBEBMYn5504xgti8AqES - l5dDzBEWmM4ocfngE2aIhKDEyZlPwBqYBcIlfh6bxz6BkWsWktQsJCkIW1zi+qr/zBA20O6F - r5kXMLKsYhTLTczMKUrNSazUTTbN1CstLijWS88v28QICobzGs92ML7ZY3+IkYmD8RCjBAez - kgjvDbXseCHelMTKqtSi/Pii0pzU4kOM0hwsSuK8z3M04oUE0hNLUrNTUwtSi2CyTBycUg2M - mpZzOmXvh/7gWGPTPq22dUr5ciuny33R3MGsC13YH+vZTVXPcjZ4WuK9csOGry/jIt0fcr6a - Vr12idKlH/MP+DO36JyZdMrKMS259Jakzvev+7oPlzwVm178z6+j5FkJT8cpuf2bPl571bij - UXFNJ8czPcfJa/8bORzYHm5x8sLiq3LSGaEtSizFGYmGWsxFxYkAKflt8fQBAAA= -X-CFilter-Eagan: DLP07 - ------=_Part_1009358_255325476.1600872547127 Content-Type: text/html Content-Transfer-Encoding: quoted-printable diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 1c16920b..56f14767 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -714,6 +714,14 @@ async def test_hermes_out_for_delivery(hass, mock_imap_hermes_out_for_delivery): assert result["tracking"] == ["8888888888888888"] +async def test_evri_out_for_delivery(hass, mock_imap_evri_out_for_delivery): + result = get_count( + mock_imap_evri_out_for_delivery, "evri_delivering", True, "./", hass + ) + assert result["count"] == 1 + assert result["tracking"] == ["H01QPZ0007431687"] + + async def test_royal_out_for_delivery(hass, mock_imap_royal_out_for_delivery): result = get_count( mock_imap_royal_out_for_delivery, "royal_delivering", True, "./", hass