Mercurial > libervia-backend
view tests/unit/test_email_gateway.py @ 4320:9658c534287e
plugin XEP-0215, XEP-0376: fix bad calls to `hasFeature`:
`hasFeature` was called like blocking code, missing the `await`. This has been fixed, and
is now using the `memory.disco.has_feature` version.
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 30 Sep 2024 14:14:38 +0200 |
parents | 27bb22eace65 |
children |
line wrap: on
line source
#!/usr/bin/env python3 # Libervia: an XMPP client # Copyright (C) 2009-2024 Jérôme Poisson (goffi@goffi.org) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from email.message import EmailMessage from email.parser import BytesParser from email.utils import formataddr from unittest.mock import AsyncMock, MagicMock import pytest from pytest_twisted import ensureDeferred as ed from twisted.words.protocols.jabber import jid from libervia.backend.plugins.plugin_comp_email_gateway import ( EmailGatewayComponent, SendMailExtra, ) from libervia.backend.plugins.plugin_comp_email_gateway.models import ( Credentials, UserData, ) from libervia.backend.plugins.plugin_xep_0131 import HeadersData, Urgency class TestEmailGatewayComponent: @pytest.fixture def email_gw(self, host): email_gw = EmailGatewayComponent(host) email_gw.storage = MagicMock() email_gw.users_data = {} return email_gw def test_jid_to_email_gateway_jid(self, email_gw): """JID from the gateway is converted to an email address.""" client = MagicMock() client.jid = jid.JID("gateway.example.org") address_jid = jid.JID(r"user\40some-email-domain.example@gateway.example.org") credentials = {"user_email": "user@example.org"} result = email_gw.jid_to_email(client, address_jid, credentials) assert result == "user@some-email-domain.example" def test_jid_to_email_non_gateway_jid(self, email_gw): """Non-gateway JID is converted to an email address with ``xmpp:``.""" client = MagicMock() client.jid = jid.JID("gateway.example.org") address_jid = jid.JID("external@example.org") credentials = {"user_email": "user@example.org"} result = email_gw.jid_to_email(client, address_jid, credentials) assert result == '"xmpp:external@example.org" <user@example.org>' def test_email_to_jid_user_email(self, email_gw): """User email returns user JID if no "xmpp:" scheme is used.""" client = MagicMock() client.jid = jid.JID("gateway.example.org") email_name = "" email_addr = "user@example.org" user_email = "user@example.org" user_jid = jid.JID("gw-user@example.org") result, name = email_gw.email_to_jid( client, user_email, user_jid, email_name, email_addr ) assert result == jid.JID("gw-user@example.org") assert name is None def test_email_to_jid_xmpp_address(self, email_gw): """Email address with XMPP in name part is converted to a JID.""" client = MagicMock() client.jid = jid.JID("gateway.example.org") email_name = "xmpp:user@example.net" email_addr = "user@example.org" user_email = "user@example.org" user_jid = jid.JID("gw-user@example.org") result, name = email_gw.email_to_jid( client, user_email, user_jid, email_name, email_addr ) assert result == jid.JID("user@example.net") assert name is None def test_email_to_jid_regular_email(self, email_gw): """Regular email address is converted to a JID with escaped local part.""" client = MagicMock() client.jid = jid.JID("gateway.example.org") email_name = "User Name" email_addr = "user@some-email-domain.example" user_email = "user@example.org" user_jid = jid.JID("gw-user@example.org") result, name = email_gw.email_to_jid( client, user_email, user_jid, email_name, email_addr ) assert result == jid.JID(r"user\40some-email-domain.example@gateway.example.org") assert name == "User Name" @ed async def test_on_new_email_single_recipient(self, email_gw): """Email with a single recipient is correctly processed and sent as a message.""" client = MagicMock() client.get_virtual_client = lambda __: client client.jid = jid.JID("gateway.example.org") client.sendMessage = AsyncMock() email_gw.client = client email = EmailMessage() email["from"] = formataddr(("User Name", "sender@somewhere.example")) email["to"] = "user@example.org" email.set_content("Hello, world!") to_jid = jid.JID("gw-user@example.org") user_email = "user@example.org" user_data = UserData(Credentials({"user_email": user_email})) await email_gw.on_new_email(user_data, to_jid, email) client.sendMessage.assert_called_once() call_args = client.sendMessage.call_args[0] assert call_args[0] == to_jid assert call_args[1] == {"": "Hello, world!\n"} assert call_args[2] == None client.sendMessage.assert_called_once_with( to_jid, {"": "Hello, world!\n"}, None, extra={} ) @ed async def test_on_new_email_multiple_recipients(self, email_gw): """Email with multiple recipients is correctly processed and sent .""" client = MagicMock() client.get_virtual_client = lambda __: client client.jid = jid.JID("gateway.example.org") client.sendMessage = AsyncMock() email_gw.client = client email = EmailMessage() email["from"] = formataddr(("User Name", "user@example.org")) email["to"] = "user@example.org" email["cc"] = "recipient2@example.org" email["bcc"] = "recipient3@example.org" email.set_content("Hello, world!") user_jid = jid.JID("gw-user@example.org") user_email = "user@example.org" user_data = UserData(Credentials({"user_email": user_email})) await email_gw.on_new_email(user_data, user_jid, email) client.sendMessage.assert_called_once_with( user_jid, {"": "Hello, world!\n"}, None, extra={ "addresses": { "to": [{"jid": "gw-user@example.org", "delivered": True}], "cc": [ { "jid": "recipient2\\40example.org@gateway.example.org", "delivered": True, } ], "bcc": [ { "jid": "recipient3\\40example.org@gateway.example.org", "delivered": True, } ], } }, ) @ed async def test_send_email_with_headers(self, email_gw, monkeypatch): """Email is sent with correct headers.""" email_gw.client = MagicMock() email_gw.client.jid = jid.JID("gateway.example.org") email_gw.storage = MagicMock() email_gw.storage.get = AsyncMock( return_value={ "user_email": "user@example.org", "user_name": "Sender Name", "smtp_host": "smtp.example.org", "smtp_port": "587", "smtp_username": "sender", "smtp_password": "password", } ) from_jid = jid.JID("user@example.org") to_email = "recipient@example.com" body = "Hello, world!" subject = "Test email" headers = HeadersData(keywords="important,urgent", urgency=Urgency.high) # Mock the smtp.sendmail function sendmail_mock = AsyncMock() monkeypatch.setattr("twisted.mail.smtp.sendmail", sendmail_mock) await email_gw.send_email( from_jid, to_email, body, subject, extra=SendMailExtra(headers=headers) ) sendmail_mock.assert_called_once() # Extract the email content from the call arguments call_args = sendmail_mock.call_args[0] _, _, _, email_content_bytes = call_args # Parse the email content parser = BytesParser() msg = parser.parsebytes(email_content_bytes) # Assert the headers are correctly set assert msg["Keywords"] == headers.keywords assert msg["Importance"] == "high" @ed async def test_on_new_email_with_headers(self, email_gw): """Headers from the email are correctly processed and included in the message.""" client = MagicMock() client.get_virtual_client = lambda __: client client.jid = jid.JID("gateway.example.org") client.sendMessage = AsyncMock() email_gw.client = client email = EmailMessage() email["from"] = formataddr(("User Name", "sender@somewhere.example")) email["to"] = "user@example.org" email.set_content("Hello, world!") email["Keywords"] = "test, example" email["Importance"] = "high" to_jid = jid.JID("gw-user@example.org") user_email = "user@example.org" user_data = UserData(Credentials({"user_email": user_email})) await email_gw.on_new_email(user_data, to_jid, email) client.sendMessage.assert_called_once_with( to_jid, {"": "Hello, world!\n"}, None, extra={"headers": {"keywords": "test, example", "urgency": "high"}}, )