Skip to content

Commit 884d8a9

Browse files
committed
Add chat markers partial (see #23) test (twisted)
1 parent d860b97 commit 884d8a9

File tree

4 files changed

+233
-0
lines changed

4 files changed

+233
-0
lines changed

tests/twisted/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ TWISTED_TESTS = \
112112
text/initiate.py \
113113
text/initiate-requestotron.py \
114114
text/receipts.py \
115+
text/markers.py \
115116
text/respawn.py \
116117
text/send-error.py \
117118
text/send-to-correct-resource.py \

tests/twisted/ns.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
OLPC_CURRENT_ACTIVITY_NOTIFY = "%s+notify" % OLPC_CURRENT_ACTIVITY
5959
PUBSUB = "http://jabber.org/protocol/pubsub"
6060
PUBSUB_EVENT = "%s#event" % PUBSUB
61+
NS_CHAT_MARKERS = "urn:xmpp:chat-markers:0"
6162
RECEIPTS = "urn:xmpp:receipts"
6263
REGISTER = "jabber:iq:register"
6364
ROSTER = "jabber:iq:roster"

tests/twisted/text/markers.py

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
# coding=utf-8
2+
"""
3+
Test XEP-0333 markers.
4+
"""
5+
6+
from servicetest import (
7+
EventPattern, assertEquals, assertLength, sync_dbus, wrap_channel,
8+
)
9+
from gabbletest import exec_test, elem, sync_stream, acknowledge_iq
10+
import constants as cs
11+
import ns
12+
13+
import caps_helper
14+
import rostertest
15+
from presence.invisible_helper import Xep0186Stream
16+
17+
CONTACT = '[email protected]'
18+
CONTACT_FULL_JID = CONTACT + '/Sea Cucumber'
19+
20+
def send_received_report(stream, jid, received_id):
21+
stream.send(
22+
elem('message', from_=jid)(
23+
elem(ns.NS_CHAT_MARKERS, 'received', id=received_id)
24+
))
25+
26+
def marker_received_on_open_channel(q, bus, conn, stream, chan):
27+
received_id = 'fine-leather-jackets'
28+
29+
send_received_report(stream, CONTACT, received_id)
30+
e = q.expect('dbus-signal', signal='MessageReceived', path=chan.object_path)
31+
message, = e.args
32+
header, = message
33+
34+
assertEquals(cs.MT_DELIVERY_REPORT, header['message-type'])
35+
assertEquals(cs.DELIVERY_STATUS_DELIVERED, header['delivery-status'])
36+
assertEquals(received_id, header['delivery-token'])
37+
38+
def marker_ignored_without_channel(q, bus, conn, stream):
39+
q.forbid_events([EventPattern('dbus-signal', signal='MessageReceived')])
40+
send_received_report(stream, '[email protected]', 'only-one-candidate')
41+
sync_dbus(bus, q, conn)
42+
q.unforbid_all()
43+
44+
def not_sending_request_to_contact(q, bus, conn, stream, chan):
45+
message = [
46+
{ 'message-type': cs.MT_NORMAL,
47+
},
48+
{ 'content-type': 'text/plain',
49+
'content': 'Mancomb Seepgood?',
50+
}]
51+
chan.Messages.SendMessage(message, 0)
52+
53+
e = q.expect('stream-message', to=CONTACT)
54+
assertLength(0, list(e.stanza.elements(uri=ns.NS_CHAT_MARKERS, name='markable')))
55+
56+
def sending_request_to_presenceless_contact(q, bus, conn, stream, chan):
57+
"""
58+
Initially we know nothing of Guybrush's presence, so should just try our
59+
level best if asked to.
60+
"""
61+
message = [
62+
{ 'message-type': cs.MT_NORMAL,
63+
},
64+
{ 'content-type': 'text/plain',
65+
'content': 'Thriftweed?',
66+
}]
67+
chan.Messages.SendMessage(message, cs.MSG_SENDING_FLAGS_REPORT_READ)
68+
69+
e = q.expect('stream-message', to=CONTACT)
70+
assertLength(1, list(e.stanza.elements(uri=ns.NS_CHAT_MARKERS, name='markable')))
71+
72+
def sending_request_to_cappy_contact(q, bus, conn, stream, chan):
73+
"""
74+
Test that Gabble requests a marker from a contact whom we know supports
75+
this extension, but only if asked.
76+
"""
77+
78+
# Convince Gabble that Guybrush supports this extension
79+
caps = { 'node': 'http://whatever',
80+
# FIXME: should be markers, not receipt, see #23
81+
#'ver': caps_helper.compute_caps_hash([], [ns.NS_CHAT_MARKERS], {}),
82+
'ver': caps_helper.compute_caps_hash([], [ns.NS_CHAT_MARKERS, ns.RECEIPTS], {}),
83+
'hash': 'sha-1',
84+
}
85+
caps_helper.presence_and_disco(q, conn, stream, CONTACT_FULL_JID,
86+
disco=True,
87+
client=caps['node'],
88+
caps=caps,
89+
features=[ns.NS_CHAT_MARKERS, ns.RECEIPTS])
90+
sync_stream(q, stream)
91+
92+
# Don't ask, don't tell — even if we know Guybrush does support this.
93+
not_sending_request_to_contact(q, bus, conn, stream, chan)
94+
95+
# Ask, tell.
96+
message = [
97+
{ 'message-type': cs.MT_NORMAL,
98+
},
99+
{ 'content-type': 'text/plain',
100+
'content': 'Ulysses?',
101+
}]
102+
chan.Messages.SendMessage(message, cs.MSG_SENDING_FLAGS_REPORT_READ)
103+
104+
e = q.expect('stream-message', to=CONTACT)
105+
assertLength(1, list(e.stanza.elements(uri=ns.NS_CHAT_MARKERS, name='markable')))
106+
107+
def replying_to_requests(q, bus, conn, stream):
108+
109+
110+
# We shouldn't send markers to people who aren't on our roster.
111+
q.forbid_events([EventPattern('stream-message', to=jid)])
112+
stream.send(
113+
elem('message', from_=jid, type='chat', id='alpha')(
114+
elem('body')(
115+
u"You didn't kill me, you moron!"
116+
),
117+
elem(ns.NS_CHAT_MARKERS, 'markable')
118+
))
119+
120+
event = q.expect('dbus-signal', signal='NewChannels')
121+
path, props = event.args[0][0]
122+
text_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
123+
event = q.expect('dbus-signal', signal='MessageReceived')
124+
message = event.args[0]
125+
header, body = message
126+
message_id = header['pending-message-id']
127+
# FIXME: uncomment below once #23 is fixed
128+
#text_chan.Text.AcknowledgePendingMessages([message_id])
129+
130+
sync_stream(q, stream)
131+
q.unforbid_all()
132+
133+
# We should send markers to people on our roster, seeing as we're not
134+
# invisible.
135+
rostertest.send_roster_push(stream, jid, subscription='from')
136+
137+
stream.send(
138+
elem('message', from_=jid, type='chat', id='beta')(
139+
elem('body')(
140+
u"You've just destroyed my spiritual essences."
141+
),
142+
elem(ns.NS_CHAT_MARKERS, 'markable')
143+
))
144+
event = q.expect('dbus-signal', signal='MessageReceived')
145+
message = event.args[0]
146+
header, body = message
147+
message_id = header['pending-message-id']
148+
text_chan.Text.AcknowledgePendingMessages([message_id])
149+
150+
e = q.expect('stream-message', to=jid)
151+
receipt = next(e.stanza.elements(uri=ns.NS_CHAT_MARKERS, name='displayed'))
152+
assertEquals('beta', receipt['id'])
153+
# FIXME: there will be alpha now coming as well, as when we acked recent it acks previous
154+
q.expect('stream-message', to=jid)
155+
156+
# We would like requests in messages without id=''s not to crash Gabble,
157+
# and also for it not to send a reply.
158+
q.forbid_events([EventPattern('stream-message', to=jid)])
159+
stream.send(
160+
elem('message', from_=jid, type='chat')( # NB. no id='' attribute
161+
elem('body')(
162+
u"A favor that I shall now return!"
163+
),
164+
elem(ns.NS_CHAT_MARKERS, 'markable')
165+
))
166+
event = q.expect('dbus-signal', signal='MessageReceived')
167+
message = event.args[0]
168+
header, body = message
169+
message_id = header['pending-message-id']
170+
text_chan.Text.AcknowledgePendingMessages([message_id])
171+
172+
sync_stream(q, stream)
173+
q.unforbid_all()
174+
175+
# If we're invisible, LeChuck shouldn't get markers.
176+
conn.SimplePresence.SetPresence("hidden", "")
177+
event = q.expect('stream-iq', query_name='invisible')
178+
acknowledge_iq(stream, event.stanza)
179+
180+
q.forbid_events([EventPattern('stream-message', to=jid)])
181+
stream.send(
182+
elem('message', from_=jid, type='chat', id='epsilon')(
183+
elem('body')(
184+
u"… but where am I going to find a duck wearing burlap chaps?"
185+
),
186+
elem(ns.NS_CHAT_MARKERS, 'markable')
187+
))
188+
event = q.expect('dbus-signal', signal='MessageReceived')
189+
message = event.args[0]
190+
header, body = message
191+
message_id = header['pending-message-id']
192+
# FIXME: same as at the beginning - uncomment when fixed
193+
#text_chan.Text.AcknowledgePendingMessages([message_id])
194+
195+
sync_stream(q, stream)
196+
q.unforbid_all()
197+
198+
def test(q, bus, conn, stream):
199+
path = conn.Requests.CreateChannel(
200+
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
201+
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
202+
cs.TARGET_ID: CONTACT,
203+
})[0]
204+
chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
205+
206+
# Let's start out with an empty roster, eh?
207+
e = q.expect('stream-iq', iq_type='get', query_ns=ns.ROSTER)
208+
e.stanza['type'] = 'result'
209+
stream.send(e.stanza)
210+
211+
marker_received_on_open_channel(q, bus, conn, stream, chan)
212+
213+
# FIXME: not implemented because of partial implementation
214+
# See https://github.com/TelepathyIM/telepathy-gabble/issues/23 for details
215+
#report_ignored_without_channel(q, bus, conn, stream)
216+
217+
not_sending_request_to_contact(q, bus, conn, stream, chan)
218+
219+
# FIXME: it still relies on receipts support which is still unable to
220+
# identify whether message's contact is unknown or has no required cap
221+
#sending_request_to_presenceless_contact(q, bus, conn, stream, chan)
222+
223+
sending_request_to_cappy_contact(q, bus, conn, stream, chan)
224+
225+
replying_to_requests(q, bus, conn, stream)
226+
227+
228+
if __name__ == '__main__':
229+
params = {'send-chat-markers':True}
230+
exec_test(test, params=params, protocol=Xep0186Stream)

tests/twisted/text/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ twisted_tests += files([
55
'initiate.py',
66
'initiate-requestotron.py',
77
'receipts.py',
8+
'markers.py',
89
'respawn.py',
910
'send-error.py',
1011
'send-to-correct-resource.py',

0 commit comments

Comments
 (0)