787
|
1 #!/usr/bin/python |
|
2 # -*- coding: utf-8 -*- |
|
3 |
|
4 # SAT: a jabber client |
|
5 # Copyright (C) 2009, 2010, 2011, 2012, 2013 Jérôme Poisson (goffi@goffi.org) |
|
6 # Copyright (C) 2013 Adrien Cossa (souliane@mailoo.org) |
|
7 |
|
8 # This program is free software: you can redistribute it and/or modify |
|
9 # it under the terms of the GNU Affero General Public License as published by |
|
10 # the Free Software Foundation, either version 3 of the License, or |
|
11 # (at your option) any later version. |
|
12 |
|
13 # This program is distributed in the hope that it will be useful, |
|
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16 # GNU Affero General Public License for more details. |
|
17 |
|
18 # You should have received a copy of the GNU Affero General Public License |
|
19 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
20 |
|
21 """ Plugin extended addressing stanzas """ |
|
22 |
|
23 from constants import Const |
|
24 from sat.test import helpers |
|
25 from sat.plugins import plugin_xep_0033 as plugin |
|
26 from sat.memory.memory import NO_SECURITY_LIMIT |
|
27 from sat.core.sat_main import AbortSendMessage, MessageSentAndStored |
|
28 from copy import deepcopy |
|
29 from twisted.internet import defer |
|
30 from wokkel.generic import parseXml |
|
31 from twisted.words.protocols.jabber.jid import JID |
|
32 |
|
33 |
|
34 class XEP_0033Test(helpers.SatTestCase): |
|
35 |
|
36 def setUp(self): |
|
37 self.host = helpers.FakeSAT() |
|
38 self.plugin = plugin.XEP_0033(self.host) |
|
39 |
|
40 def test_messageReceived(self): |
|
41 self.host.memory.init() |
|
42 xml = u""" |
|
43 <message type="chat" from="%s" to="%s" id="test_1"> |
|
44 <body>test</body> |
|
45 <addresses xmlns='http://jabber.org/protocol/address'> |
|
46 <address type='to' jid='%s'/> |
|
47 <address type='cc' jid='%s'/> |
|
48 <address type='bcc' jid='%s'/> |
|
49 </addresses> |
|
50 </message> |
|
51 """ % (Const.TEST_JID_2_STR, self.host.getClientHostJid(Const.TEST_PROFILE), |
|
52 Const.TEST_JID_STR, Const.TEST_JID_2_STR, Const.TEST_JID_3_STR) |
|
53 stanza = parseXml(xml.encode("utf-8")) |
|
54 treatments = defer.Deferred() |
|
55 self.plugin.messageReceivedTrigger(stanza, treatments, Const.TEST_PROFILE) |
|
56 data = {'extra': {}} |
|
57 |
|
58 def assert_(data): |
|
59 expected = ('to', Const.TEST_JID_STR, 'cc', Const.TEST_JID_2_STR, 'bcc', Const.TEST_JID_3_STR) |
|
60 assert(data['extra']['addresses'] == '%s:%s\n%s:%s\n%s:%s\n' % expected) |
|
61 |
|
62 treatments.addCallback(assert_) |
|
63 treatments.callback(data) |
|
64 |
|
65 def test_sendMessageTrigger(self): |
|
66 mess_data = {"to": self.host.getClientHostJid(Const.TEST_PROFILE), |
|
67 "type": "chat", |
|
68 "message": "content", |
|
69 "extra": {} |
|
70 } |
|
71 addresses = ('to', Const.TEST_JID_STR, 'cc', Const.TEST_JID_2_STR, 'bcc', Const.TEST_JID_3_STR) |
|
72 mess_data["extra"]["address"] = '%s:%s\n%s:%s\n%s:%s\n' % addresses |
|
73 original_stanza = u""" |
|
74 <message type="chat" from="%s" to="%s" id="test_1"> |
|
75 <body>content</body> |
|
76 </message> |
|
77 """ % (Const.TEST_JID_2_STR, self.host.getClientHostJid(Const.TEST_PROFILE)) |
|
78 mess_data['xml'] = parseXml(original_stanza.encode("utf-8")) |
|
79 expected = deepcopy(mess_data['xml']) |
|
80 addresses_extra = """ |
|
81 <addresses xmlns='http://jabber.org/protocol/address'> |
|
82 <address type='%s' jid='%s'/> |
|
83 <address type='%s' jid='%s'/> |
|
84 <address type='%s' jid='%s'/> |
|
85 </addresses>""" % addresses |
|
86 addresses_element = parseXml(addresses_extra.encode('utf-8')) |
|
87 expected.addChild(addresses_element) |
|
88 |
|
89 def assert_(mess_data): |
|
90 """The mess_data that we got here as been modified by self.plugin.sendMessageTrigger, |
|
91 check that the addresses element has been added to the stanza.""" |
|
92 self.assertEqualXML(mess_data['xml'].toXml().encode("utf-8"), expected.toXml().encode("utf-8")) |
|
93 |
|
94 def fail_(failure, exception_class): |
|
95 """If the failure does encapsulate the expected exception, it will be silently |
|
96 trapped, otherwise it will be re-raised and will make the test fail""" |
|
97 if exception_class == MessageSentAndStored: |
|
98 assert_(failure.value.mess_data) |
|
99 failure.trap(exception_class) |
|
100 |
|
101 def checkSentAndStored(): |
|
102 """Check that all the recipients got their messages and that the history has been filled. |
|
103 /!\ see the comments in XEP_0033.sendAndStoreMessage""" |
|
104 sent = [] |
|
105 stored = [] |
|
106 cache = set() |
|
107 for to_s in [addresses[1], addresses[3], addresses[5]]: |
|
108 to_jid = JID(to_s) |
|
109 host = JID(to_jid.host) |
|
110 if self.host.memory.hasServerFeature(plugin.NS_ADDRESS, host, Const.TEST_PROFILE): |
|
111 if host not in cache: |
|
112 sent.append(host) |
|
113 stored.append(host) |
|
114 cache.add(host) |
|
115 stored.append(to_jid) |
|
116 else: |
|
117 sent.append(to_jid) |
|
118 stored.append(to_jid) |
|
119 try: |
|
120 assert(len(self.host.sent_messages) == len(sent)) |
|
121 assert(len(self.host.stored_messages) == len(stored)) |
|
122 assert(set(self.host.sent_messages) == set(sent)) |
|
123 assert(set(self.host.stored_messages) == set(stored)) |
|
124 except AssertionError as e: |
|
125 print "----------------------------------------------------" |
|
126 print "Comparing sent and stored messages failed!" |
|
127 print self.host.sent_messages |
|
128 print sent |
|
129 print self.host.stored_messages |
|
130 print stored |
|
131 print "/!\ see the comments in XEP_0033.sendAndStoreMessage" |
|
132 print "----------------------------------------------------" |
|
133 raise e |
|
134 |
|
135 # feature is not supported, abort the message |
|
136 self.host.memory.init() |
|
137 treatments = defer.Deferred() |
|
138 data = deepcopy(mess_data) |
|
139 self.plugin.sendMessageTrigger(data, treatments, Const.TEST_PROFILE) |
|
140 treatments.addCallbacks(assert_, lambda failure: fail_(failure, AbortSendMessage)) |
|
141 treatments.callback(data) |
|
142 |
|
143 # feature is supported |
|
144 self.host.init() |
|
145 self.host.memory.init() |
|
146 self.host.memory.addServerFeature(plugin.NS_ADDRESS, self.host.getClientHostJid(Const.TEST_PROFILE), Const.TEST_PROFILE) |
|
147 treatments = defer.Deferred() |
|
148 data = deepcopy(mess_data) |
|
149 self.plugin.sendMessageTrigger(data, treatments, Const.TEST_PROFILE) |
|
150 treatments.addCallbacks(assert_, lambda failure: fail_(failure, MessageSentAndStored)) |
|
151 treatments.callback(data) |
|
152 checkSentAndStored() |
|
153 |
|
154 # check that a wrong recipient entity is fixed by the backend |
|
155 self.host.init() |
|
156 self.host.memory.init() |
|
157 self.host.memory.addServerFeature(plugin.NS_ADDRESS, self.host.getClientHostJid(Const.TEST_PROFILE), Const.TEST_PROFILE) |
|
158 treatments = defer.Deferred() |
|
159 data = deepcopy(mess_data) |
|
160 data["to"] = Const.TEST_JID |
|
161 self.plugin.sendMessageTrigger(data, treatments, Const.TEST_PROFILE) |
|
162 treatments.addCallbacks(assert_, lambda failure: fail_(failure, MessageSentAndStored)) |
|
163 treatments.callback(mess_data) |
|
164 checkSentAndStored() |