# HG changeset patch # User Goffi # Date 1727359921 -7200 # Node ID d27228b3c7047d3608ba87bfb4ed935f6bb76787 # Parent b56b1eae79945daa88630d768ea67abd8e8dcda3 test (unit): add test for email gateway: rel 450 diff -r b56b1eae7994 -r d27228b3c704 tests/unit/test_email_gateway.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/unit/test_email_gateway.py Thu Sep 26 16:12:01 2024 +0200 @@ -0,0 +1,170 @@ +#!/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 . + +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 email.message import EmailMessage +from libervia.backend.plugins.plugin_comp_email_gateway import EmailGatewayComponent +from libervia.backend.plugins.plugin_comp_email_gateway.models import ( + Credentials, + UserData, +) + + +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" ' + + 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=None + ) + + @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, + } + ], + } + }, + )