Mercurial > libervia-backend
comparison tests/unit/test_plugin_xep_0033.py @ 4307:6a0155f410bd
test (unit): add test for plugin XEP-0033:
those replace the legacy XEP-0033 test from libervia/backend/test/test_plugin_xep_0033.py.
rel 450
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 26 Sep 2024 16:12:01 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4306:94e0968987cd | 4307:6a0155f410bd |
---|---|
1 #!/usr/bin/env python3 | |
2 | |
3 # Libervia: an XMPP client | |
4 # Copyright (C) 2009-2024 Jérôme Poisson (goffi@goffi.org) | |
5 | |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 of the License, or | |
9 # (at your option) any later version. | |
10 | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 from typing import cast | |
20 from unittest.mock import AsyncMock, MagicMock, patch | |
21 | |
22 from pytest_twisted import ensureDeferred as ed | |
23 from twisted.words.protocols.jabber import jid | |
24 from twisted.words.xish import domish | |
25 | |
26 from libervia.backend.models.core import MessageData | |
27 from libervia.backend.plugins.plugin_xep_0033 import ( | |
28 AddressType, | |
29 AddressesData, | |
30 NS_ADDRESS, | |
31 XEP_0033, | |
32 ) | |
33 | |
34 | |
35 class TestXEP0033: | |
36 def test_address_type_from_element(self): | |
37 """ | |
38 AddressType instance is correctly created from an XML <address> element. | |
39 """ | |
40 address_elt = domish.Element((NS_ADDRESS, "address")) | |
41 address_elt["jid"] = "test@example.com" | |
42 address_elt["desc"] = "Test Description" | |
43 address_elt["delivered"] = "true" | |
44 address = AddressType.from_element(address_elt) | |
45 assert address.jid == jid.JID("test@example.com") | |
46 assert address.desc == "Test Description" | |
47 assert address.delivered is True | |
48 | |
49 def test_address_type_to_element(self): | |
50 """ | |
51 XML <address> element is correctly built from an AddressType instance. | |
52 """ | |
53 address = AddressType( | |
54 jid=jid.JID("test@example.com"), | |
55 desc="Test Description", | |
56 delivered=True, | |
57 ) | |
58 address_elt = address.to_element() | |
59 assert address_elt.uri == NS_ADDRESS | |
60 assert address_elt.name == "address" | |
61 assert address_elt["jid"] == "test@example.com" | |
62 assert address_elt["desc"] == "Test Description" | |
63 assert address_elt["delivered"] == "true" | |
64 | |
65 def test_addresses_data_from_element(self): | |
66 """ | |
67 AddressesData instance is correctly created from an XML <addresses> element. | |
68 """ | |
69 addresses_elt = domish.Element((NS_ADDRESS, "addresses")) | |
70 address_elt1 = addresses_elt.addElement("address") | |
71 address_elt1["type"] = "to" | |
72 address_elt1["jid"] = "test1@example.com" | |
73 address_elt2 = addresses_elt.addElement("address") | |
74 address_elt2["type"] = "cc" | |
75 address_elt2["jid"] = "test2@example.com" | |
76 address_elt3 = addresses_elt.addElement("address") | |
77 address_elt3["type"] = "bcc" | |
78 address_elt3["jid"] = "test3@example.com" | |
79 address_elt4 = addresses_elt.addElement("address") | |
80 address_elt4["type"] = "noreply" | |
81 addresses = AddressesData.from_element(addresses_elt) | |
82 assert addresses.to is not None and len(addresses.to) == 1 | |
83 assert addresses.to[0].jid == jid.JID("test1@example.com") | |
84 assert addresses.cc is not None and len(addresses.cc) == 1 | |
85 assert addresses.cc[0].jid == jid.JID("test2@example.com") | |
86 assert addresses.bcc is not None and len(addresses.bcc) == 1 | |
87 assert addresses.bcc[0].jid == jid.JID("test3@example.com") | |
88 assert addresses.noreply | |
89 | |
90 def test_addresses_data_to_element(self): | |
91 """ | |
92 XML <addresses> element is correctly built from an AddressesData instance. | |
93 """ | |
94 addresses = AddressesData( | |
95 to=[AddressType(jid=jid.JID("test1@example.com"))], | |
96 cc=[AddressType(jid=jid.JID("test2@example.com"))], | |
97 bcc=[AddressType(jid=jid.JID("test3@example.com"))], | |
98 noreply=True, | |
99 ) | |
100 addresses_elt = addresses.to_element() | |
101 assert addresses_elt.uri == NS_ADDRESS | |
102 assert addresses_elt.name == "addresses" | |
103 assert len(addresses_elt.children) == 4 | |
104 for elt in addresses_elt.children: | |
105 assert elt.uri == NS_ADDRESS | |
106 assert elt.name == "address" | |
107 assert addresses_elt.children[0]["type"] == "to" | |
108 assert addresses_elt.children[0]["jid"] == "test1@example.com" | |
109 assert addresses_elt.children[1]["type"] == "cc" | |
110 assert addresses_elt.children[1]["jid"] == "test2@example.com" | |
111 assert addresses_elt.children[2]["type"] == "bcc" | |
112 assert addresses_elt.children[2]["jid"] == "test3@example.com" | |
113 assert addresses_elt.children[3]["type"] == "noreply" | |
114 | |
115 @ed | |
116 async def test_handle_addresses(self): | |
117 """ | |
118 Server JID is used, <addresses> element is added and messages are delivered. | |
119 """ | |
120 xep_0033 = XEP_0033(MagicMock()) | |
121 client = MagicMock() | |
122 client.server_jid = jid.JID("server.example.com") | |
123 client.profile = "test_profile" | |
124 | |
125 mess_data = MessageData( | |
126 { | |
127 "to": jid.JID("recipient@example.com"), | |
128 "extra": { | |
129 "addresses": { | |
130 "to": [{"jid": "to@example.com"}], | |
131 "cc": [{"jid": "cc@example.com"}], | |
132 } | |
133 }, | |
134 "xml": domish.Element(("jabber:client", "message")), | |
135 } | |
136 ) | |
137 | |
138 xep_0033.host.memory.disco.has_feature = AsyncMock(return_value=True) | |
139 xep_0033.deliver_messages = AsyncMock() | |
140 | |
141 with patch.object(xep_0033, "_stop_if_all_delivered", AsyncMock()): | |
142 result = await xep_0033._handle_addresses(client, mess_data) | |
143 cast(AsyncMock, xep_0033._stop_if_all_delivered).assert_called_once() | |
144 | |
145 assert result["to"] == client.server_jid | |
146 assert "addresses" in result["xml"].children[0].name | |
147 xep_0033.deliver_messages.assert_called_once() | |
148 | |
149 @ed | |
150 async def test_deliver_messages(self): | |
151 """Delivery is done for all recipients.""" | |
152 xep_0033 = XEP_0033(MagicMock()) | |
153 client = MagicMock() | |
154 client.server_jid = jid.JID("server.example.com") | |
155 client.a_send = AsyncMock() | |
156 | |
157 mess_data = MessageData( | |
158 { | |
159 "xml": domish.Element(("jabber:client", "message")), | |
160 } | |
161 ) | |
162 to_example_addr = AddressType(jid=jid.JID("to@example.com")) | |
163 cc_example_addr = AddressType(jid=jid.JID("cc@example.com")) | |
164 bcc_example_addr = AddressType(jid=jid.JID("bcc@other.com")) | |
165 | |
166 addr_data = AddressesData( | |
167 to=[to_example_addr], | |
168 cc=[cc_example_addr], | |
169 bcc=[bcc_example_addr], | |
170 ) | |
171 | |
172 domains = { | |
173 "example.com": [ | |
174 to_example_addr, | |
175 cc_example_addr, | |
176 ], | |
177 "other.com": [bcc_example_addr], | |
178 } | |
179 | |
180 xep_0033.host.memory.disco.has_feature = AsyncMock(return_value=True) | |
181 | |
182 await xep_0033.deliver_messages(client, mess_data, addr_data, domains) | |
183 | |
184 # Check that messages were sent to the multicast domain and individual recipients | |
185 assert client.a_send.call_count == 2 | |
186 calls = client.a_send.call_args_list | |
187 # First call is to the multicast service. | |
188 assert calls[0][0][0]["to"] == "example.com" | |
189 # Second call is the individual BCC. | |
190 assert calls[1][0][0]["to"] == "bcc@other.com" | |
191 | |
192 # Everything must have been delivered. | |
193 assert all(address.delivered for address in addr_data.addresses) | |
194 | |
195 # And BCC must have been removed. | |
196 assert addr_data.bcc is None | |
197 | |
198 @ed | |
199 async def test_deliver_messages_multicast_only(self): | |
200 """Delivery is done only to multicast services.""" | |
201 xep_0033 = XEP_0033(MagicMock()) | |
202 client = MagicMock() | |
203 client.server_jid = jid.JID("server.example.com") | |
204 client.a_send = AsyncMock() | |
205 | |
206 mess_data = MessageData( | |
207 { | |
208 "xml": domish.Element(("jabber:client", "message")), | |
209 } | |
210 ) | |
211 to_example_addr = AddressType(jid=jid.JID("to@example.com")) | |
212 cc_example_addr = AddressType(jid=jid.JID("cc@example.com")) | |
213 bcc_example_addr = AddressType(jid=jid.JID("bcc@other.com")) | |
214 | |
215 addr_data = AddressesData( | |
216 to=[to_example_addr], | |
217 cc=[cc_example_addr], | |
218 bcc=[bcc_example_addr], | |
219 ) | |
220 | |
221 domains = { | |
222 "example.com": [ | |
223 to_example_addr, | |
224 cc_example_addr, | |
225 ], | |
226 "other.com": [bcc_example_addr], | |
227 } | |
228 | |
229 xep_0033.host.memory.disco.has_feature = AsyncMock(return_value=True) | |
230 | |
231 await xep_0033.deliver_messages( | |
232 client, mess_data, addr_data, domains, multicast_only=True | |
233 ) | |
234 | |
235 # Check that only the multicast message was sent | |
236 assert client.a_send.call_count == 1 | |
237 assert client.a_send.call_args[0][0]["to"] == "example.com" | |
238 | |
239 # Check that only addresses from the multicast domain are marked as delivered | |
240 assert addr_data.to and addr_data.to[0].delivered is True | |
241 assert addr_data.cc and addr_data.cc[0].delivered is True | |
242 assert addr_data.bcc and addr_data.bcc[0].delivered is None |