def disco_caps(q, stream, presence): c_nodes = xpath.queryForNodes('/presence/c', presence.stanza) assert c_nodes is not None assertLength(1, c_nodes) hash = c_nodes[0].attributes['hash'] ver = c_nodes[0].attributes['ver'] node = c_nodes[0].attributes['node'] assertEquals('sha-1', hash) # ask caps request = \ elem_iq(stream, 'get', from_='[email protected]/resource')( elem(ns.DISCO_INFO, 'query', node=(node + '#' + ver)) ) stream.send(request) # receive caps event = q.expect('stream-iq', query_ns=ns.DISCO_INFO, iq_id=request['id']) # Check that Gabble's announcing the identity we think it should be. (identities, features, dataforms) = extract_disco_parts(event.stanza) # Check if the hash matches the announced capabilities assertEquals(compute_caps_hash(identities, features, dataforms), ver) return (event, features, dataforms)
def extract_disco_parts(stanza): identity_nodes = xpath.queryForNodes('/iq/query/identity', stanza) assertLength(1, identity_nodes) identity_node = identity_nodes[0] assertEquals('client', identity_node['category']) assertDoesNotContain('xml:lang', identity_node.attributes) identity = 'client/%s//%s' % (identity_node['type'], identity_node['name']) features = [] for feature in xpath.queryForNodes('/iq/query/feature', stanza): features.append(feature['var']) # a quick and ugly data form extractor x_nodes = xpath.queryForNodes('/iq/query/x', stanza) or [] dataforms = {} for form in x_nodes: name = None fields = {} for field in xpath.queryForNodes('/x/field', form): if field['var'] == 'FORM_TYPE': name = str(field.firstChildElement()) else: values = [str(x) for x in xpath.queryForNodes('/field/value', field)] fields[field['var']] = values if name is not None: dataforms[name] = fields return ([identity], features, dataforms)
def send_presence(q, conn, stream, contact, caps, initial=True, show=None): h = conn.RequestHandles(cs.HT_CONTACT, [contact])[0] if initial: stream.send(make_presence(contact, status='hello')) q.expect_many( EventPattern('dbus-signal', signal='PresenceUpdate', args=[{ h: (0L, { u'available': { 'message': 'hello' } }) }]), EventPattern('dbus-signal', signal='PresencesChanged', args=[{ h: (2, u'available', 'hello') }])) # no special capabilities assertEquals([(h, cs.CHANNEL_TYPE_TEXT, 3, 0)], conn.Capabilities.GetCapabilities([h])) # send updated presence with caps info stream.send(make_presence(contact, show=show, status='hello', caps=caps)) return h
def extract_disco_parts(stanza): identity_nodes = xpath.queryForNodes('/iq/query/identity', stanza) assertLength(1, identity_nodes) identity_node = identity_nodes[0] assertEquals('client', identity_node['category']) assertDoesNotContain('xml:lang', identity_node.attributes) identity = 'client/%s//%s' % (identity_node['type'], identity_node['name']) features = [] for feature in xpath.queryForNodes('/iq/query/feature', stanza): features.append(feature['var']) # a quick and ugly data form extractor x_nodes = xpath.queryForNodes('/iq/query/x', stanza) or [] dataforms = {} for form in x_nodes: name = None fields = {} for field in xpath.queryForNodes('/x/field', form): if field['var'] == 'FORM_TYPE': name = str(field.firstChildElement()) else: values = [ str(x) for x in xpath.queryForNodes('/field/value', field) ] fields[field['var']] = values if name is not None: dataforms[name] = fields return ([identity], features, dataforms)
def test(q, bus, conn, stream): call_async(q, conn.Future, 'EnsureSidecar', STATUS_IFACE) conn.Connect() # Now we're connected, the call we made earlier should return. e = q.expect('dbus-return', method='EnsureSidecar') path, props = e.value assertEquals({}, props)
def outgoing_reply(q, bus, conn, stream): path, stanza = setup_outgoing_tests(q, bus, conn, stream) # reply with nothing reply = make_result_iq(stream, stanza) stream.send(reply) e = q.expect('dbus-signal', signal='Replied', path=path) args, xml = e.args assertEquals({}, args) assertEquals('<?xml version="1.0" encoding="UTF-8"?>\n' \ + '<message xmlns="urn:ytstenut:message"/>\n', xml)
def bindIq(self, iq): resource = xpath.queryForString('/iq/bind/resource', iq) if self.resource is not None: assertEquals(self.resource, resource) else: assert resource is not None result = IQ(self.xmlstream, "result") result["id"] = iq["id"] bind = result.addElement((ns.NS_XMPP_BIND, 'bind')) self.bare_jid = '%s@localhost' % self.username self.full_jid = '%s/%s' % (self.bare_jid, resource) jid = bind.addElement('jid', content=self.full_jid) self.xmlstream.send(result) self.xmlstream.dispatch(self.xmlstream, xmlstream.STREAM_AUTHD_EVENT)
def respondToSecondIq(self, iq): username = xpath.queryForNodes('/iq/query/username', iq) assert map(str, username) == [self.username] digest = xpath.queryForNodes('/iq/query/digest', iq) expect = hashlib.sha1(self.xmlstream.sid + self.password).hexdigest() assert map(str, digest) == [expect] resource = xpath.queryForNodes('/iq/query/resource', iq) assertLength(1, resource) if self.resource is not None: assertEquals(self.resource, str(resource[0])) self.bare_jid = '%s@localhost' % self.username self.full_jid = '%s/%s' % (self.bare_jid, resource) result = IQ(self.xmlstream, "result") result["id"] = iq["id"] self.xmlstream.send(result) self.xmlstream.dispatch(self.xmlstream, xmlstream.STREAM_AUTHD_EVENT)
def setup_outgoing_tests(q, bus, conn, stream, announce=True): handle, _, _ = setup_tests(q, bus, conn, stream, announce) # okay we got our contact, let's go request_props = { cs.CHANNEL_TYPE: ycs.CHANNEL_IFACE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_HANDLE: handle, ycs.REQUEST_TYPE: ycs.REQUEST_TYPE_GET, ycs.REQUEST_ATTRIBUTES: { 'hi': 'mom' }, ycs.TARGET_SERVICE: 'the.target.service', ycs.INITIATOR_SERVICE: 'the.initiator.service' } call_async(q, conn.Requests, 'CreateChannel', request_props) e, _ = q.expect_many(EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels')) path, props = e.value for k, v in request_props.items(): assertEquals(v, props[k]) # finally we have our channel chan = wrap_channel(bus, conn, path) # let's check we can't call Fail()/Reply() call_async(q, chan, 'Fail', ycs.ERROR_TYPE_CANCEL, 'lol', 'whut', 'pear') q.expect('dbus-error', method='Fail') call_async(q, chan, 'Reply', {'lol': 'whut'}, '') q.expect('dbus-error', method='Reply') # okay enough, let's move on. call_async(q, chan, 'Request') e, _ = q.expect_many(EventPattern('stream-iq'), EventPattern('dbus-return', method='Request')) assertEquals('get', e.iq_type) assertEquals('message', e.query_name) assertEquals('urn:ytstenut:message', e.query_ns) # we shouldn't be able to call this again call_async(q, chan, 'Request') q.expect('dbus-error', method='Request') return path, e.stanza
def send_presence(q, conn, stream, contact, caps, initial=True, show=None): h = conn.RequestHandles(cs.HT_CONTACT, [contact])[0] if initial: stream.send(make_presence(contact, status='hello')) q.expect_many( EventPattern('dbus-signal', signal='PresenceUpdate', args=[{h: (0L, {u'available': {'message': 'hello'}})}]), EventPattern('dbus-signal', signal='PresencesChanged', args=[{h: (2, u'available', 'hello')}])) # no special capabilities assertEquals([(h, cs.CHANNEL_TYPE_TEXT, 3, 0)], conn.Capabilities.GetCapabilities([h])) # send updated presence with caps info stream.send(make_presence(contact, show=show, status='hello', caps=caps)) return h
def setup_outgoing_tests(q, bus, conn, stream, announce=True): handle, _, _ = setup_tests(q, bus, conn, stream, announce) # okay we got our contact, let's go request_props = { cs.CHANNEL_TYPE: ycs.CHANNEL_IFACE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_HANDLE: handle, ycs.REQUEST_TYPE: ycs.REQUEST_TYPE_GET, ycs.REQUEST_ATTRIBUTES: {'hi': 'mom'}, ycs.TARGET_SERVICE: 'the.target.service', ycs.INITIATOR_SERVICE: 'the.initiator.service' } call_async(q, conn.Requests, 'CreateChannel', request_props) e, _ = q.expect_many(EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels')) path, props = e.value for k, v in request_props.items(): assertEquals(v, props[k]) # finally we have our channel chan = wrap_channel(bus, conn, path) # let's check we can't call Fail()/Reply() call_async(q, chan, 'Fail', ycs.ERROR_TYPE_CANCEL, 'lol', 'whut', 'pear') q.expect('dbus-error', method='Fail') call_async(q, chan, 'Reply', {'lol':'whut'}, '') q.expect('dbus-error', method='Reply') # okay enough, let's move on. call_async(q, chan, 'Request') e, _ = q.expect_many(EventPattern('stream-iq'), EventPattern('dbus-return', method='Request')) assertEquals('get', e.iq_type) assertEquals('message', e.query_name) assertEquals('urn:ytstenut:message', e.query_ns) # we shouldn't be able to call this again call_async(q, chan, 'Request') q.expect('dbus-error', method='Request') return path, e.stanza
def outgoing_fail(q, bus, conn, stream): path, stanza = setup_outgoing_tests(q, bus, conn, stream) # construct a nice error reply reply = IQ(None, 'error') reply['id'] = stanza['id'] reply['from'] = stanza['to'] error = reply.addElement('error') error['type'] = 'cancel' error['code'] = '409' error.addElement((ns.STANZA, 'conflict')) error.addElement((ycs.MESSAGE_NS, 'yodawg')) text = error.addElement((ns.STANZA, 'text'), content='imma let you finish') stream.send(reply) e = q.expect('dbus-signal', signal='Failed', path=path) error_type, stanza_error_name, yst_error_name, text = e.args assertEquals(ycs.ERROR_TYPE_CANCEL, error_type) assertEquals('conflict', stanza_error_name) assertEquals('yodawg', yst_error_name) assertEquals('imma let you finish', text)
def setup_incoming_tests(q, bus, conn, stream): handle, bare_jid, full_jid = setup_tests(q, bus, conn, stream) self_handle = conn.GetSelfHandle() self_handle_name = conn.InspectHandles(cs.HT_CONTACT, [self_handle])[0] iq = IQ(None, 'get') iq['id'] = 'le-loldongs' iq['from'] = full_jid iq['to'] = self_handle_name msg = iq.addElement((ycs.MESSAGE_NS, 'message')) msg['from-service'] = 'the.from.service' msg['to-service'] = 'the.to.service' msg['owl-companions'] = 'the pussy cat' msg['destination'] = 'sea' msg['seacraft'] = 'beautiful pea green boat' lol = msg.addElement((None, 'lol')) lol['some'] = 'stuff' lol['to'] = 'fill' lol['the'] = 'time' lol.addElement((None, 'look-into-my-eyes'), content='and tell me how boring writing these tests is') stream.send(iq) e = q.expect('dbus-signal', signal='NewChannels', predicate=lambda e: e.args[0][0][1][cs.CHANNEL_TYPE] == ycs.CHANNEL_IFACE) path, props = e.args[0][0] assertEquals(handle, props[cs.INITIATOR_HANDLE]) assertEquals(bare_jid, props[cs.INITIATOR_ID]) assertEquals(False, props[cs.REQUESTED]) assertEquals(handle, props[cs.TARGET_HANDLE]) assertEquals(cs.HT_CONTACT, props[cs.TARGET_HANDLE_TYPE]) assertEquals(bare_jid, props[cs.TARGET_ID]) assertEquals('the.from.service', props[ycs.INITIATOR_SERVICE]) assertEquals('the.to.service', props[ycs.TARGET_SERVICE]) assertEquals(ycs.REQUEST_TYPE_GET, props[ycs.REQUEST_TYPE]) assertEquals({'destination': 'sea', 'owl-companions': 'the pussy cat', 'seacraft': 'beautiful pea green boat'}, props[ycs.REQUEST_ATTRIBUTES]) assertEquals('<?xml version="1.0" encoding="UTF-8"?>\n' \ '<message seacraft="beautiful pea green boat" ' \ 'from-service="the.from.service" destination="sea" ' \ 'owl-companions="the pussy cat" to-service="the.to.service" ' \ 'xmlns="urn:ytstenut:message">' \ '<lol to="fill" the="time" some="stuff">' \ '<look-into-my-eyes>and tell me how boring ' \ 'writing these tests is</look-into-my-eyes>' \ '</lol></message>\n', props[ycs.REQUEST_BODY]) # finally we have our channel chan = wrap_channel(bus, conn, path) # let's check we can't call Request() call_async(q, chan, 'Request') q.expect('dbus-error', method='Request') return chan, bare_jid, full_jid, self_handle_name
def check_pep_set(iq): pubsub = iq.children[0] publish = pubsub.children[0] item = publish.children[0] status_el = item.children[0] desc = None if status_el.children: desc = status_el.children[0] assertEquals('set', iq['type']) assertEquals(1, len(iq.children)) assertEquals('pubsub', pubsub.name) assertEquals(ns.PUBSUB, pubsub.uri) assertEquals(1, len(pubsub.children)) assertEquals('publish', publish.name) assertEquals(CAP_NAME, publish['node']) assertEquals(1, len(publish.children)) assertEquals('item', item.name) assertEquals(1, len(item.children)) assertEquals('status', status_el.name) if desc: assertEquals(1, len(status_el.children)) assertEquals('description', desc.name) assertEquals(1, len(desc.children)) return status_el, desc
def test(q, bus, conn, stream): bare_jid = "*****@*****.**" full_jid = bare_jid + "/LikeLava" call_async(q, conn.Future, 'EnsureSidecar', ycs.STATUS_IFACE) conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0, 1]) e = q.expect('dbus-return', method='EnsureSidecar') path, props = e.value assertEquals({}, props) status = ProxyWrapper(bus.get_object(conn.bus_name, path), ycs.STATUS_IFACE, {}) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered) self_handle = conn.GetSelfHandle() self_handle_name = conn.InspectHandles(cs.HT_CONTACT, [self_handle])[0] caps = {'ver': '0.1', 'node': client} presence_and_disco(q, conn, stream, full_jid, True, client, caps, features, identity, {}, True, None) # now update the caps conn.ContactCapabilities.UpdateCapabilities([ ('well.gnome.name', [], ['com.meego.xpmn.ytstenut.Channel/uid/org.gnome.Banshee', 'com.meego.xpmn.ytstenut.Channel/type/application', 'com.meego.xpmn.ytstenut.Channel/name/en_GB/Banshee Media Player', 'com.meego.xpmn.ytstenut.Channel/name/fr/Banshee Lecteur de Musique', 'com.meego.xpmn.ytstenut.Channel/caps/urn:ytstenut:capabilities:yts-caps-audio', 'com.meego.xpmn.ytstenut.Channel/caps/urn:ytstenut:data:jingle:rtp'])]) _, e = q.expect_many(EventPattern('dbus-signal', signal='ServiceAdded'), EventPattern('stream-presence')) e, _, _ = disco_caps(q, stream, e) iq = e.stanza query = iq.children[0] x = None for child in query.children: if child.name == 'x' and child.uri == ns.X_DATA: # we should only have one child assert x is None x = child # don't break here as we can waste time to make sure x # isn't assigned twice assert x is not None for field in x.children: if field['var'] == 'FORM_TYPE': assertEquals('hidden', field['type']) assertEquals('urn:ytstenut:capabilities#org.gnome.Banshee', field.children[0].children[0]) elif field['var'] == 'type': assertEquals('application', field.children[0].children[0]) elif field['var'] == 'name': names = [a.children[0] for a in field.children] assertLength(2, names) assertContains('en_GB/Banshee Media Player', names) assertContains('fr/Banshee Lecteur de Musique', names) elif field['var'] == 'capabilities': caps = [a.children[0] for a in field.children] assertLength(2, caps) assertContains('urn:ytstenut:capabilities:yts-caps-audio', caps) assertContains('urn:ytstenut:data:jingle:rtp', caps) else: assert False # now add another service forbidden = [EventPattern('dbus-signal', signal='ServiceRemoved')] q.forbid_events(forbidden) conn.ContactCapabilities.UpdateCapabilities([ ('another.nice.gname', [], ['com.meego.xpmn.ytstenut.Channel/uid/org.gnome.Eog', 'com.meego.xpmn.ytstenut.Channel/type/application', 'com.meego.xpmn.ytstenut.Channel/name/en_GB/Eye Of Gnome', 'com.meego.xpmn.ytstenut.Channel/name/it/Occhio Di uno Gnomo', 'com.meego.xpmn.ytstenut.Channel/caps/urn:ytstenut:capabilities:yts-picz'])]) e = q.expect('dbus-signal', signal='ServiceAdded') sync_dbus(bus, q, conn) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({'test@localhost': {'org.gnome.Banshee': ('application', {'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique'}, ['urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp']), 'org.gnome.Eog': ('application', {'en_GB': 'Eye Of Gnome', 'it': 'Occhio Di uno Gnomo'}, ['urn:ytstenut:capabilities:yts-picz'])}}, discovered) q.unforbid_events(forbidden) forbidden = [EventPattern('dbus-signal', signal='ServiceRemoved', args=[self_handle_name, 'org.gnome.Eog'])] q.forbid_events(forbidden) conn.ContactCapabilities.UpdateCapabilities([ ('well.gnome.name', [], [])]) e = q.expect('dbus-signal', signal='ServiceRemoved', args=[self_handle_name, 'org.gnome.Banshee']) sync_dbus(bus, q, conn) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({'test@localhost': {'org.gnome.Eog': ('application', {'en_GB': 'Eye Of Gnome', 'it': 'Occhio Di uno Gnomo'}, ['urn:ytstenut:capabilities:yts-picz'])}}, discovered) q.unforbid_events(forbidden) conn.ContactCapabilities.UpdateCapabilities([ ('another.nice.gname', [], [])]) e = q.expect('dbus-signal', signal='ServiceRemoved', args=[self_handle_name, 'org.gnome.Eog']) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered)
def incoming_fail(q, bus, conn, stream): chan, bare_jid, full_jid, self_handle_name = \ setup_incoming_tests(q, bus, conn, stream) call_async(q, chan, 'Fail', ycs.ERROR_TYPE_AUTH, 'auth', 'omgwtfbbq', 'I most certainly dont feel like dancing') _, e = q.expect_many(EventPattern('dbus-return', method='Fail'), EventPattern('stream-message')) iq = e.stanza assertEquals('le-loldongs', iq['id']) assertEquals('error', iq['type']) assertEquals(self_handle_name, iq['from']) assertEquals(full_jid, iq['to']) assertEquals(2, len(iq.children)) def check_message(message): assertEquals('message', message.name) assertEquals(ycs.MESSAGE_NS, message.uri) assertEquals('beautiful pea green boat', message['seacraft']) assertEquals('sea', message['destination']) assertEquals('the pussy cat', message['owl-companions']) assertEquals('the.from.service', message['from-service']) assertEquals('the.to.service', message['to-service']) assertEquals(1, len(message.children)) lol = message.children[0] assertEquals('lol', lol.name) assertEquals('fill', lol['to']) assertEquals('time', lol['the']) assertEquals('stuff', lol['some']) assertEquals(1, len(lol.children)) look = lol.children[0] assertEquals('look-into-my-eyes', look.name) assertEquals(1, len(look.children)) assertEquals('and tell me how boring writing these tests is', look.children[0]) def check_error(error): assertEquals('error', error.name) assertEquals('auth', error['type']) assertEquals(3, len(error.children)) for c in error.children: if c.name == 'auth': assertEquals(ns.STANZA, c.uri) elif c.name == 'omgwtfbbq': assertEquals(ycs.MESSAGE_NS, c.uri) elif c.name == 'text': assertEquals(ns.STANZA, c.uri) assertEquals(1, len(c.children)) assertEquals('I most certainly dont feel like dancing', c.children[0]) else: raise for child in iq.children: if child.name == 'message': check_message(child) elif child.name == 'error': check_error(child) else: raise # check we can't call anything any more call_async(q, chan, 'Fail', ycs.ERROR_TYPE_CANCEL, 'lol', 'whut', 'pear') q.expect('dbus-error', method='Fail') call_async(q, chan, 'Reply', {'lol':'whut'}, '') q.expect('dbus-error', method='Reply') call_async(q, chan, 'Request') q.expect('dbus-error', method='Request')
# Gabble looks up our capabilities event = q.expect('stream-iq', to=contact, query_ns=ns.DISCO_INFO) assertEquals(client + '#' + caps['ver'], event.query['node']) return event.stanza def send_disco_reply(stream, stanza, identities, features, dataforms={}): stream.send( make_caps_disco_reply(stream, stanza, identities, features, dataforms)) if __name__ == '__main__': # example from XEP-0115 assertEquals('QgayPKawpkPSDYmwT/WM94uAlu0=', compute_caps_hash(['client/pc//Exodus 0.9.1'], ["http://jabber.org/protocol/disco#info", "http://jabber.org/protocol/disco#items", "http://jabber.org/protocol/muc", "http://jabber.org/protocol/caps"], {})) # another example from XEP-0115 identities = [u'client/pc/en/Psi 0.11', u'client/pc/el/Ψ 0.11'] features = [ u'http://jabber.org/protocol/caps', u'http://jabber.org/protocol/disco#info', u'http://jabber.org/protocol/disco#items', u'http://jabber.org/protocol/muc', ] dataforms = { u'urn:xmpp:dataforms:softwareinfo': { u'ip_version': [u'ipv4', u'ipv6'],
def incoming_reply(q, bus, conn, stream): chan, bare_jid, full_jid, self_handle_name = \ setup_incoming_tests(q, bus, conn, stream) moar = Element((ycs.MESSAGE_NS, 'message')) moar['ninety-nine-problems'] = 'but a sauvignon blanc aint one' moar['also'] = 'my mum said hi' trollface = moar.addElement('trollface', content='problem?') call_async( q, chan, 'Reply', { 'ninety-nine-problems': 'but a sauvignon blanc aint one', 'also': 'my mum said hi' }, moar.toXml()) _, e = q.expect_many(EventPattern('dbus-return', method='Reply'), EventPattern('stream-message')) iq = e.stanza assertEquals('le-loldongs', iq['id']) assertEquals('result', iq['type']) assertEquals(self_handle_name, iq['from']) assertEquals(full_jid, iq['to']) assertEquals(1, len(iq.children)) message = iq.children[0] assertEquals('message', message.name) assertEquals(ycs.MESSAGE_NS, message.uri) assertEquals('my mum said hi', message['also']) assertEquals('but a sauvignon blanc aint one', message['ninety-nine-problems']) assertEquals('the.from.service', message['to-service']) assertEquals('the.to.service', message['from-service']) assertEquals(1, len(message.children)) trollface = message.children[0] assertEquals('trollface', trollface.name) assertEquals(1, len(trollface.children)) assertEquals('problem?', trollface.children[0]) # check we can't call anything any more call_async(q, chan, 'Fail', ycs.ERROR_TYPE_CANCEL, 'lol', 'whut', 'pear') q.expect('dbus-error', method='Fail') call_async(q, chan, 'Reply', {'lol': 'whut'}, '') q.expect('dbus-error', method='Reply') call_async(q, chan, 'Request') q.expect('dbus-error', method='Request')
def check_message(message): assertEquals('message', message.name) assertEquals(ycs.MESSAGE_NS, message.uri) assertEquals('beautiful pea green boat', message['seacraft']) assertEquals('sea', message['destination']) assertEquals('the pussy cat', message['owl-companions']) assertEquals('the.from.service', message['from-service']) assertEquals('the.to.service', message['to-service']) assertEquals(1, len(message.children)) lol = message.children[0] assertEquals('lol', lol.name) assertEquals('fill', lol['to']) assertEquals('time', lol['the']) assertEquals('stuff', lol['some']) assertEquals(1, len(lol.children)) look = lol.children[0] assertEquals('look-into-my-eyes', look.name) assertEquals(1, len(look.children)) assertEquals('and tell me how boring writing these tests is', look.children[0])
def expect_disco(q, contact, client, caps): # Gabble looks up our capabilities event = q.expect('stream-iq', to=contact, query_ns=ns.DISCO_INFO) assertEquals(client + '#' + caps['ver'], event.query['node']) return event.stanza
def check_error(error): assertEquals('error', error.name) assertEquals('auth', error['type']) assertEquals(3, len(error.children)) for c in error.children: if c.name == 'auth': assertEquals(ns.STANZA, c.uri) elif c.name == 'omgwtfbbq': assertEquals(ycs.MESSAGE_NS, c.uri) elif c.name == 'text': assertEquals(ns.STANZA, c.uri) assertEquals(1, len(c.children)) assertEquals('I most certainly dont feel like dancing', c.children[0]) else: raise
def test(q, bus, conn, stream): call_async(q, conn.Future, 'EnsureSidecar', ycs.STATUS_IFACE) conn.Connect() # Now we're connected, the call we made earlier should return. e = q.expect('dbus-return', method='EnsureSidecar') path, props = e.value assertEquals({}, props) status = ProxyWrapper(bus.get_object(conn.bus_name, path), ycs.STATUS_IFACE, {}) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered) # announce a contact with the right caps bare_jid = "*****@*****.**" full_jid = bare_jid + "/NeeNawNeeNawIAmAnAmbulance" contact_handle = conn.RequestHandles(cs.HT_CONTACT, [bare_jid])[0] client_caps['ver'] = compute_caps_hash(identity, features, banshee) presence_and_disco(q, conn, stream, full_jid, True, client, client_caps, features, identity, banshee, True, None) # this will be fired as text channel caps will be fired _, e = q.expect_many(EventPattern('dbus-signal', signal='ContactCapabilitiesChanged', predicate=lambda e: contact_handle in e.args[0]), EventPattern('dbus-signal', signal='ServiceAdded')) contact_id, service_name, details = e.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Banshee', service_name) type, name_map, caps = details assertEquals('application', type) assertEquals({'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique'}, name_map) assertSameSets(['urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp'], caps) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({bare_jid: { 'org.gnome.Banshee': ('application', {'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique'}, ['urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp'])}, }, discovered) # add evince tmp = banshee.copy() tmp.update(evince) client_caps['ver'] = compute_caps_hash(identity, features, tmp) presence_and_disco(q, conn, stream, full_jid, True, client, client_caps, features, identity, tmp, False) e = q.expect('dbus-signal', signal='ServiceAdded') contact_id, service_name, details = e.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Evince', service_name) type, name_map, caps = details assertEquals('application', type) assertEquals({'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say'}, name_map) assertSameSets(['urn:ytstenut:capabilities:pics'], caps) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({bare_jid: { 'org.gnome.Banshee': ('application', {'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique'}, ['urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp']), 'org.gnome.Evince': ('application', {'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say'}, ['urn:ytstenut:capabilities:pics'])} }, discovered) # remove evince forbidden = [EventPattern('dbus-signal', signal='stream-iq')] q.forbid_events(forbidden) client_caps['ver'] = compute_caps_hash(identity, features, banshee) send_presence(q, conn, stream, full_jid, client_caps, initial=False) e = q.expect('dbus-signal', signal='ServiceRemoved') contact_id, service_name = e.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Evince', service_name) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({bare_jid: { 'org.gnome.Banshee': ('application', {'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique'}, ['urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp'])}, }, discovered) sync_stream(q, stream) q.unforbid_events(forbidden) # now just evince client_caps['ver'] = compute_caps_hash(identity, features, evince) presence_and_disco(q, conn, stream, full_jid, True, client, client_caps, features, identity, evince, False) sa, sr = q.expect_many(EventPattern('dbus-signal', signal='ServiceAdded'), EventPattern('dbus-signal', signal='ServiceRemoved')) contact_id, service_name, details = sa.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Evince', service_name) type, name_map, caps = details assertEquals('application', type) assertEquals({'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say'}, name_map) assertSameSets(['urn:ytstenut:capabilities:pics'], caps) contact_id, service_name = sr.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Banshee', service_name) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({bare_jid: { 'org.gnome.Evince': ('application', {'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say'}, ['urn:ytstenut:capabilities:pics'])} }, discovered) # just banshee again forbidden = [EventPattern('dbus-signal', signal='stream-iq')] q.forbid_events(forbidden) client_caps['ver'] = compute_caps_hash(identity, features, banshee) send_presence(q, conn, stream, full_jid, client_caps, initial=False) sr, sa = q.expect_many(EventPattern('dbus-signal', signal='ServiceRemoved'), EventPattern('dbus-signal', signal='ServiceAdded')) contact_id, service_name = sr.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Evince', service_name) contact_id, service_name, details = sa.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Banshee', service_name) type, name_map, caps = details assertEquals('application', type) assertEquals({'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique'}, name_map) assertSameSets(['urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp'], caps) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({bare_jid: { 'org.gnome.Banshee': ('application', {'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique'}, ['urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp'])} }, discovered) sync_stream(q, stream) # both again client_caps['ver'] = compute_caps_hash(identity, features, tmp) send_presence(q, conn, stream, full_jid, client_caps, initial=False) sa = q.expect('dbus-signal', signal='ServiceAdded') contact_id, service_name, details = sa.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Evince', service_name) type, name_map, caps = details assertEquals('application', type) assertEquals({'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say'}, name_map) assertSameSets(['urn:ytstenut:capabilities:pics'], caps) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({bare_jid: { 'org.gnome.Banshee': ('application', {'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique'}, ['urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp']), 'org.gnome.Evince': ('application', {'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say'}, ['urn:ytstenut:capabilities:pics'])} }, discovered) sync_stream(q, stream) q.unforbid_events(forbidden) # and finally, nothing client_caps['ver'] = compute_caps_hash(identity, features, {}) presence_and_disco(q, conn, stream, full_jid, True, client, client_caps, features, identity, {}, False) q.expect_many(EventPattern('dbus-signal', signal='ServiceRemoved', args=[bare_jid, 'org.gnome.Banshee']), EventPattern('dbus-signal', signal='ServiceRemoved', args=[bare_jid, 'org.gnome.Evince'])) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered)
def test(q, bus, conn, stream): bare_jid = "*****@*****.**" full_jid = bare_jid + "/NeeNawNeeNawIAmAnAmbulance" # we don't want these two signalled, ever. forbidden = [EventPattern('dbus-signal', signal='ServiceAdded'), EventPattern('dbus-signal', signal='ServiceRemoved')] q.forbid_events(forbidden) conn.Connect() _, e = q.expect_many(EventPattern('dbus-signal', signal='StatusChanged', args=[0, 1]), EventPattern('stream-iq', query_ns=ns.ROSTER, iq_type='get', query_name='query')) e.stanza['type'] = 'result' item = e.query.addElement('item') item['jid'] = bare_jid item['subscription'] = 'both' stream.send(e.stanza) q.expect('dbus-signal', signal='ContactListStateChanged', args=[cs.CONTACT_LIST_STATE_SUCCESS]) # announce a contact with the right caps contact_handle = conn.RequestHandles(cs.HT_CONTACT, [bare_jid])[0] client_caps['ver'] = compute_caps_hash(identity, features, banshee) presence_and_disco(q, conn, stream, full_jid, True, client, client_caps, features, identity, banshee, True, None) # this will be fired as text channel caps will be fired q.expect('dbus-signal', signal='ContactCapabilitiesChanged', predicate=lambda e: contact_handle in e.args[0]) # add evince tmp = banshee.copy() tmp.update(evince) client_caps['ver'] = compute_caps_hash(identity, features, tmp) presence_and_disco(q, conn, stream, full_jid, True, client, client_caps, features, identity, tmp, False) sync_stream(q, stream) # now finally ensure the sidecar path, props = conn.Future.EnsureSidecar(ycs.STATUS_IFACE) assertEquals({}, props) status = ProxyWrapper(bus.get_object(conn.bus_name, path), ycs.STATUS_IFACE, {}) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({bare_jid: { 'org.gnome.Banshee': ('application', {'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique'}, ['urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp']), 'org.gnome.Evince': ('application', {'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say'}, ['urn:ytstenut:capabilities:pics'])} }, discovered)
def test(q, bus, conn, stream): # we won't be using any data forms, so these two shouldn't ever be # fired. q.forbid_events([ EventPattern('dbus-signal', signal='ServiceAdded'), EventPattern('dbus-signal', signal='ServiceRemoved') ]) call_async(q, conn.Future, 'EnsureSidecar', ycs.STATUS_IFACE) conn.Connect() # Now we're connected, the call we made earlier should return. e = q.expect('dbus-return', method='EnsureSidecar') path, props = e.value assertEquals({}, props) status = ProxyWrapper(bus.get_object(conn.bus_name, path), ycs.STATUS_IFACE, {}) # bad capability argument call_async(q, status, 'AdvertiseStatus', '', 'service.name', '') q.expect('dbus-error', method='AdvertiseStatus') # bad service name call_async(q, status, 'AdvertiseStatus', CAP_NAME, '', '') q.expect('dbus-error', method='AdvertiseStatus') # we can't test that the message type="headline" stanza is # actually received because it's thrown into the loopback stream # immediately. # announce a contact with the right caps bare_jid = "*****@*****.**" full_jid = bare_jid + "/BIGGESTRESOURCEEVAAAAHHH" contact_handle = conn.RequestHandles(cs.HT_CONTACT, [bare_jid])[0] presence_and_disco(q, conn, stream, full_jid, True, client, caps, features, identity, {}, True, None) # this will be fired as text channel caps will be fired q.expect('dbus-signal', signal='ContactCapabilitiesChanged', predicate=lambda e: contact_handle in e.args[0]) # okay now we know about the contact's caps, we can go ahead discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredStatuses', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered) el = Element(('urn:ytstenut:status', 'status')) el['activity'] = 'messing-with-your-stuff' desc = el.addElement('ytstenut:description', content='Yeah sorry about that') desc['xml:lang'] = 'en-GB' call_async(q, status, 'AdvertiseStatus', CAP_NAME, 'ants.in.their.pants', el.toXml()) e, _ = q.expect_many(EventPattern('stream-iq'), EventPattern('dbus-return', method='AdvertiseStatus')) status_el, desc = check_pep_set(e.stanza) assertEquals('messing-with-your-stuff', status_el['activity']) assertEquals('ants.in.their.pants', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) assertEquals('Yeah sorry about that', desc.children[0]) acknowledge_iq(stream, e.stanza) send_back_pep_event(stream, status_el) sig = q.expect('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE) # check signal contact_id, capability, service_name, status_str = sig.args assertEquals(CAP_NAME, capability) assertEquals('ants.in.their.pants', service_name) assertNotEquals('', status_str) # check property discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredStatuses', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( {'test@localhost': { CAP_NAME: { 'ants.in.their.pants': status_str } }}, discovered) # set another el = Element(('urn:ytstenut:status', 'status')) el['activity'] = 'rofling' desc = el.addElement('ytstenut:description', content='U MAD?') desc['xml:lang'] = 'en-GB' call_async(q, status, 'AdvertiseStatus', CAP_NAME, 'bananaman.on.holiday', el.toXml()) e, _ = q.expect_many(EventPattern('stream-iq'), EventPattern('dbus-return', method='AdvertiseStatus')) status_el, desc = check_pep_set(e.stanza) assertEquals('rofling', status_el['activity']) assertEquals('bananaman.on.holiday', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) assertEquals('U MAD?', desc.children[0]) acknowledge_iq(stream, e.stanza) send_back_pep_event(stream, status_el) sig = q.expect('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE) # check signal contact_id, capability, service_name, bananaman_status_str = sig.args assertEquals(CAP_NAME, capability) assertEquals('bananaman.on.holiday', service_name) assertNotEquals('', bananaman_status_str) # check property discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredStatuses', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( { 'test@localhost': { CAP_NAME: { 'ants.in.their.pants': status_str, 'bananaman.on.holiday': bananaman_status_str } } }, discovered) # unset the status from one service call_async(q, status, 'AdvertiseStatus', CAP_NAME, 'ants.in.their.pants', '') e, _, = q.expect_many( EventPattern('stream-iq'), EventPattern('dbus-return', method='AdvertiseStatus')) status_el, desc = check_pep_set(e.stanza) assertEquals('ants.in.their.pants', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) assert 'activity' not in status_el.attributes assertEquals([], status_el.children) acknowledge_iq(stream, e.stanza) send_back_pep_event(stream, status_el) sig = q.expect('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE) # check signal contact_id, capability, service_name, status_str = sig.args assertEquals(CAP_NAME, capability) assertEquals('ants.in.their.pants', service_name) assertEquals('', status_str) # check property discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredStatuses', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( { 'test@localhost': { CAP_NAME: { 'bananaman.on.holiday': bananaman_status_str } } }, discovered) # unset the status from the other service call_async(q, status, 'AdvertiseStatus', CAP_NAME, 'bananaman.on.holiday', '') e, _ = q.expect_many(EventPattern('stream-iq'), EventPattern('dbus-return', method='AdvertiseStatus')) # check message status_el, desc = check_pep_set(e.stanza) assertEquals('bananaman.on.holiday', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) assert 'activity' not in status_el.attributes assertEquals([], status_el.children) acknowledge_iq(stream, e.stanza) send_back_pep_event(stream, status_el) sig = q.expect('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE) # check signal contact_id, capability, service_name, status_str = sig.args assertEquals(CAP_NAME, capability) assertEquals('bananaman.on.holiday', service_name) assertEquals('', status_str) # check property discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredStatuses', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered)
def setup_incoming_tests(q, bus, conn, stream): handle, bare_jid, full_jid = setup_tests(q, bus, conn, stream) self_handle = conn.GetSelfHandle() self_handle_name = conn.InspectHandles(cs.HT_CONTACT, [self_handle])[0] iq = IQ(None, 'get') iq['id'] = 'le-loldongs' iq['from'] = full_jid iq['to'] = self_handle_name msg = iq.addElement((ycs.MESSAGE_NS, 'message')) msg['from-service'] = 'the.from.service' msg['to-service'] = 'the.to.service' msg['owl-companions'] = 'the pussy cat' msg['destination'] = 'sea' msg['seacraft'] = 'beautiful pea green boat' lol = msg.addElement((None, 'lol')) lol['some'] = 'stuff' lol['to'] = 'fill' lol['the'] = 'time' lol.addElement((None, 'look-into-my-eyes'), content='and tell me how boring writing these tests is') stream.send(iq) e = q.expect('dbus-signal', signal='NewChannels', predicate=lambda e: e.args[0][0][1][cs.CHANNEL_TYPE] == ycs. CHANNEL_IFACE) path, props = e.args[0][0] assertEquals(handle, props[cs.INITIATOR_HANDLE]) assertEquals(bare_jid, props[cs.INITIATOR_ID]) assertEquals(False, props[cs.REQUESTED]) assertEquals(handle, props[cs.TARGET_HANDLE]) assertEquals(cs.HT_CONTACT, props[cs.TARGET_HANDLE_TYPE]) assertEquals(bare_jid, props[cs.TARGET_ID]) assertEquals('the.from.service', props[ycs.INITIATOR_SERVICE]) assertEquals('the.to.service', props[ycs.TARGET_SERVICE]) assertEquals(ycs.REQUEST_TYPE_GET, props[ycs.REQUEST_TYPE]) assertEquals( { 'destination': 'sea', 'owl-companions': 'the pussy cat', 'seacraft': 'beautiful pea green boat' }, props[ycs.REQUEST_ATTRIBUTES]) assertEquals('<?xml version="1.0" encoding="UTF-8"?>\n' \ '<message seacraft="beautiful pea green boat" ' \ 'from-service="the.from.service" destination="sea" ' \ 'owl-companions="the pussy cat" to-service="the.to.service" ' \ 'xmlns="urn:ytstenut:message">' \ '<lol to="fill" the="time" some="stuff">' \ '<look-into-my-eyes>and tell me how boring ' \ 'writing these tests is</look-into-my-eyes>' \ '</lol></message>\n', props[ycs.REQUEST_BODY]) # finally we have our channel chan = wrap_channel(bus, conn, path) # let's check we can't call Request() call_async(q, chan, 'Request') q.expect('dbus-error', method='Request') return chan, bare_jid, full_jid, self_handle_name
def incoming_fail(q, bus, conn, stream): chan, bare_jid, full_jid, self_handle_name = \ setup_incoming_tests(q, bus, conn, stream) call_async(q, chan, 'Fail', ycs.ERROR_TYPE_AUTH, 'auth', 'omgwtfbbq', 'I most certainly dont feel like dancing') _, e = q.expect_many(EventPattern('dbus-return', method='Fail'), EventPattern('stream-message')) iq = e.stanza assertEquals('le-loldongs', iq['id']) assertEquals('error', iq['type']) assertEquals(self_handle_name, iq['from']) assertEquals(full_jid, iq['to']) assertEquals(2, len(iq.children)) def check_message(message): assertEquals('message', message.name) assertEquals(ycs.MESSAGE_NS, message.uri) assertEquals('beautiful pea green boat', message['seacraft']) assertEquals('sea', message['destination']) assertEquals('the pussy cat', message['owl-companions']) assertEquals('the.from.service', message['from-service']) assertEquals('the.to.service', message['to-service']) assertEquals(1, len(message.children)) lol = message.children[0] assertEquals('lol', lol.name) assertEquals('fill', lol['to']) assertEquals('time', lol['the']) assertEquals('stuff', lol['some']) assertEquals(1, len(lol.children)) look = lol.children[0] assertEquals('look-into-my-eyes', look.name) assertEquals(1, len(look.children)) assertEquals('and tell me how boring writing these tests is', look.children[0]) def check_error(error): assertEquals('error', error.name) assertEquals('auth', error['type']) assertEquals(3, len(error.children)) for c in error.children: if c.name == 'auth': assertEquals(ns.STANZA, c.uri) elif c.name == 'omgwtfbbq': assertEquals(ycs.MESSAGE_NS, c.uri) elif c.name == 'text': assertEquals(ns.STANZA, c.uri) assertEquals(1, len(c.children)) assertEquals('I most certainly dont feel like dancing', c.children[0]) else: raise for child in iq.children: if child.name == 'message': check_message(child) elif child.name == 'error': check_error(child) else: raise # check we can't call anything any more call_async(q, chan, 'Fail', ycs.ERROR_TYPE_CANCEL, 'lol', 'whut', 'pear') q.expect('dbus-error', method='Fail') call_async(q, chan, 'Reply', {'lol': 'whut'}, '') q.expect('dbus-error', method='Reply') call_async(q, chan, 'Request') q.expect('dbus-error', method='Request')
def test(q, bus, conn, stream): # we won't be using any data forms, so these two shouldn't ever be # fired. q.forbid_events([EventPattern('dbus-signal', signal='ServiceAdded'), EventPattern('dbus-signal', signal='ServiceRemoved')]) call_async(q, conn.Future, 'EnsureSidecar', ycs.STATUS_IFACE) conn.Connect() # Now we're connected, the call we made earlier should return. e = q.expect('dbus-return', method='EnsureSidecar') path, props = e.value assertEquals({}, props) status = ProxyWrapper(bus.get_object(conn.bus_name, path), ycs.STATUS_IFACE, {}) # bad capability argument call_async(q, status, 'AdvertiseStatus', '', 'service.name', '') q.expect('dbus-error', method='AdvertiseStatus') # bad service name call_async(q, status, 'AdvertiseStatus', CAP_NAME, '', '') q.expect('dbus-error', method='AdvertiseStatus') # we can't test that the message type="headline" stanza is # actually received because it's thrown into the loopback stream # immediately. # announce a contact with the right caps bare_jid = "*****@*****.**" full_jid = bare_jid + "/BIGGESTRESOURCEEVAAAAHHH" contact_handle = conn.RequestHandles(cs.HT_CONTACT, [bare_jid])[0] presence_and_disco(q, conn, stream, full_jid, True, client, caps, features, identity, {}, True, None) # this will be fired as text channel caps will be fired q.expect('dbus-signal', signal='ContactCapabilitiesChanged', predicate=lambda e: contact_handle in e.args[0]) # okay now we know about the contact's caps, we can go ahead discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredStatuses', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered) el = Element(('urn:ytstenut:status', 'status')) el['activity'] = 'messing-with-your-stuff' desc = el.addElement('ytstenut:description', content='Yeah sorry about that') desc['xml:lang'] = 'en-GB' call_async(q, status, 'AdvertiseStatus', CAP_NAME, 'ants.in.their.pants', el.toXml()) e, _ = q.expect_many(EventPattern('stream-iq'), EventPattern('dbus-return', method='AdvertiseStatus')) status_el, desc = check_pep_set(e.stanza) assertEquals('messing-with-your-stuff', status_el['activity']) assertEquals('ants.in.their.pants', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) assertEquals('Yeah sorry about that', desc.children[0]) acknowledge_iq(stream, e.stanza) send_back_pep_event(stream, status_el) sig = q.expect('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE) # check signal contact_id, capability, service_name, status_str = sig.args assertEquals(CAP_NAME, capability) assertEquals('ants.in.their.pants', service_name) assertNotEquals('', status_str) # check property discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredStatuses', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({'test@localhost': {CAP_NAME: {'ants.in.their.pants': status_str}}}, discovered) # set another el = Element(('urn:ytstenut:status', 'status')) el['activity'] = 'rofling' desc = el.addElement('ytstenut:description', content='U MAD?') desc['xml:lang'] = 'en-GB' call_async(q, status, 'AdvertiseStatus', CAP_NAME, 'bananaman.on.holiday', el.toXml()) e, _ = q.expect_many(EventPattern('stream-iq'), EventPattern('dbus-return', method='AdvertiseStatus')) status_el, desc = check_pep_set(e.stanza) assertEquals('rofling', status_el['activity']) assertEquals('bananaman.on.holiday', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) assertEquals('U MAD?', desc.children[0]) acknowledge_iq(stream, e.stanza) send_back_pep_event(stream, status_el) sig = q.expect('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE) # check signal contact_id, capability, service_name, bananaman_status_str = sig.args assertEquals(CAP_NAME, capability) assertEquals('bananaman.on.holiday', service_name) assertNotEquals('', bananaman_status_str) # check property discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredStatuses', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({'test@localhost': {CAP_NAME: { 'ants.in.their.pants': status_str, 'bananaman.on.holiday': bananaman_status_str}}}, discovered) # unset the status from one service call_async(q, status, 'AdvertiseStatus', CAP_NAME, 'ants.in.their.pants', '') e, _, = q.expect_many(EventPattern('stream-iq'), EventPattern('dbus-return', method='AdvertiseStatus')) status_el, desc = check_pep_set(e.stanza) assertEquals('ants.in.their.pants', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) assert 'activity' not in status_el.attributes assertEquals([], status_el.children) acknowledge_iq(stream, e.stanza) send_back_pep_event(stream, status_el) sig = q.expect('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE) # check signal contact_id, capability, service_name, status_str = sig.args assertEquals(CAP_NAME, capability) assertEquals('ants.in.their.pants', service_name) assertEquals('', status_str) # check property discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredStatuses', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({'test@localhost': {CAP_NAME: { 'bananaman.on.holiday': bananaman_status_str}}}, discovered) # unset the status from the other service call_async(q, status, 'AdvertiseStatus', CAP_NAME, 'bananaman.on.holiday', '') e, _ = q.expect_many(EventPattern('stream-iq'), EventPattern('dbus-return', method='AdvertiseStatus')) # check message status_el, desc = check_pep_set(e.stanza) assertEquals('bananaman.on.holiday', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) assert 'activity' not in status_el.attributes assertEquals([], status_el.children) acknowledge_iq(stream, e.stanza) send_back_pep_event(stream, status_el) sig = q.expect('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE) # check signal contact_id, capability, service_name, status_str = sig.args assertEquals(CAP_NAME, capability) assertEquals('bananaman.on.holiday', service_name) assertEquals('', status_str) # check property discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredStatuses', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered)
def incoming_reply(q, bus, conn, stream): chan, bare_jid, full_jid, self_handle_name = \ setup_incoming_tests(q, bus, conn, stream) moar = Element((ycs.MESSAGE_NS, 'message')) moar['ninety-nine-problems'] = 'but a sauvignon blanc aint one' moar['also'] = 'my mum said hi' trollface = moar.addElement('trollface', content='problem?') call_async(q, chan, 'Reply', {'ninety-nine-problems': 'but a sauvignon blanc aint one', 'also': 'my mum said hi'}, moar.toXml()) _, e = q.expect_many(EventPattern('dbus-return', method='Reply'), EventPattern('stream-message')) iq = e.stanza assertEquals('le-loldongs', iq['id']) assertEquals('result', iq['type']) assertEquals(self_handle_name, iq['from']) assertEquals(full_jid, iq['to']) assertEquals(1, len(iq.children)) message = iq.children[0] assertEquals('message', message.name) assertEquals(ycs.MESSAGE_NS, message.uri) assertEquals('my mum said hi', message['also']) assertEquals('but a sauvignon blanc aint one', message['ninety-nine-problems']) assertEquals('the.from.service', message['to-service']) assertEquals('the.to.service', message['from-service']) assertEquals(1, len(message.children)) trollface = message.children[0] assertEquals('trollface', trollface.name) assertEquals(1, len(trollface.children)) assertEquals('problem?', trollface.children[0]) # check we can't call anything any more call_async(q, chan, 'Fail', ycs.ERROR_TYPE_CANCEL, 'lol', 'whut', 'pear') q.expect('dbus-error', method='Fail') call_async(q, chan, 'Reply', {'lol':'whut'}, '') q.expect('dbus-error', method='Reply') call_async(q, chan, 'Request') q.expect('dbus-error', method='Request')
def test(q, bus, conn, stream): call_async(q, conn.Future, 'EnsureSidecar', ycs.STATUS_IFACE) conn.Connect() # Now we're connected, the call we made earlier should return. e = q.expect('dbus-return', method='EnsureSidecar') path, props = e.value assertEquals({}, props) status = ProxyWrapper(bus.get_object(conn.bus_name, path), ycs.STATUS_IFACE, {}) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered) # announce a contact with the right caps bare_jid = "*****@*****.**" full_jid = bare_jid + "/NeeNawNeeNawIAmAnAmbulance" contact_handle = conn.RequestHandles(cs.HT_CONTACT, [bare_jid])[0] client_caps['ver'] = compute_caps_hash(identity, features, banshee) presence_and_disco(q, conn, stream, full_jid, True, client, client_caps, features, identity, banshee, True, None) # this will be fired as text channel caps will be fired _, e = q.expect_many( EventPattern('dbus-signal', signal='ContactCapabilitiesChanged', predicate=lambda e: contact_handle in e.args[0]), EventPattern('dbus-signal', signal='ServiceAdded')) contact_id, service_name, details = e.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Banshee', service_name) type, name_map, caps = details assertEquals('application', type) assertEquals( { 'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique' }, name_map) assertSameSets([ 'urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp' ], caps) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( { bare_jid: { 'org.gnome.Banshee': ('application', { 'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique' }, [ 'urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp' ]) }, }, discovered) # add evince tmp = banshee.copy() tmp.update(evince) client_caps['ver'] = compute_caps_hash(identity, features, tmp) presence_and_disco(q, conn, stream, full_jid, True, client, client_caps, features, identity, tmp, False) e = q.expect('dbus-signal', signal='ServiceAdded') contact_id, service_name, details = e.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Evince', service_name) type, name_map, caps = details assertEquals('application', type) assertEquals( { 'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say' }, name_map) assertSameSets(['urn:ytstenut:capabilities:pics'], caps) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( { bare_jid: { 'org.gnome.Banshee': ('application', { 'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique' }, [ 'urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp' ]), 'org.gnome.Evince': ('application', { 'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say' }, ['urn:ytstenut:capabilities:pics']) } }, discovered) # remove evince forbidden = [EventPattern('dbus-signal', signal='stream-iq')] q.forbid_events(forbidden) client_caps['ver'] = compute_caps_hash(identity, features, banshee) send_presence(q, conn, stream, full_jid, client_caps, initial=False) e = q.expect('dbus-signal', signal='ServiceRemoved') contact_id, service_name = e.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Evince', service_name) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( { bare_jid: { 'org.gnome.Banshee': ('application', { 'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique' }, [ 'urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp' ]) }, }, discovered) sync_stream(q, stream) q.unforbid_events(forbidden) # now just evince client_caps['ver'] = compute_caps_hash(identity, features, evince) presence_and_disco(q, conn, stream, full_jid, True, client, client_caps, features, identity, evince, False) sa, sr = q.expect_many( EventPattern('dbus-signal', signal='ServiceAdded'), EventPattern('dbus-signal', signal='ServiceRemoved')) contact_id, service_name, details = sa.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Evince', service_name) type, name_map, caps = details assertEquals('application', type) assertEquals( { 'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say' }, name_map) assertSameSets(['urn:ytstenut:capabilities:pics'], caps) contact_id, service_name = sr.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Banshee', service_name) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( { bare_jid: { 'org.gnome.Evince': ('application', { 'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say' }, ['urn:ytstenut:capabilities:pics']) } }, discovered) # just banshee again forbidden = [EventPattern('dbus-signal', signal='stream-iq')] q.forbid_events(forbidden) client_caps['ver'] = compute_caps_hash(identity, features, banshee) send_presence(q, conn, stream, full_jid, client_caps, initial=False) sr, sa = q.expect_many( EventPattern('dbus-signal', signal='ServiceRemoved'), EventPattern('dbus-signal', signal='ServiceAdded')) contact_id, service_name = sr.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Evince', service_name) contact_id, service_name, details = sa.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Banshee', service_name) type, name_map, caps = details assertEquals('application', type) assertEquals( { 'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique' }, name_map) assertSameSets([ 'urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp' ], caps) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( { bare_jid: { 'org.gnome.Banshee': ('application', { 'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique' }, [ 'urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp' ]) } }, discovered) sync_stream(q, stream) # both again client_caps['ver'] = compute_caps_hash(identity, features, tmp) send_presence(q, conn, stream, full_jid, client_caps, initial=False) sa = q.expect('dbus-signal', signal='ServiceAdded') contact_id, service_name, details = sa.args assertEquals(bare_jid, contact_id) assertEquals('org.gnome.Evince', service_name) type, name_map, caps = details assertEquals('application', type) assertEquals( { 'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say' }, name_map) assertSameSets(['urn:ytstenut:capabilities:pics'], caps) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( { bare_jid: { 'org.gnome.Banshee': ('application', { 'en_GB': 'Banshee Media Player', 'fr': 'Banshee Lecteur de Musique' }, [ 'urn:ytstenut:capabilities:yts-caps-audio', 'urn:ytstenut:data:jingle:rtp' ]), 'org.gnome.Evince': ('application', { 'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say' }, ['urn:ytstenut:capabilities:pics']) } }, discovered) sync_stream(q, stream) q.unforbid_events(forbidden) # and finally, nothing client_caps['ver'] = compute_caps_hash(identity, features, {}) presence_and_disco(q, conn, stream, full_jid, True, client, client_caps, features, identity, {}, False) q.expect_many( EventPattern('dbus-signal', signal='ServiceRemoved', args=[bare_jid, 'org.gnome.Banshee']), EventPattern('dbus-signal', signal='ServiceRemoved', args=[bare_jid, 'org.gnome.Evince'])) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered)
assertEquals(client + '#' + caps['ver'], event.query['node']) return event.stanza def send_disco_reply(stream, stanza, identities, features, dataforms={}): stream.send( make_caps_disco_reply(stream, stanza, identities, features, dataforms)) if __name__ == '__main__': # example from XEP-0115 assertEquals( 'QgayPKawpkPSDYmwT/WM94uAlu0=', compute_caps_hash(['client/pc//Exodus 0.9.1'], [ "http://jabber.org/protocol/disco#info", "http://jabber.org/protocol/disco#items", "http://jabber.org/protocol/muc", "http://jabber.org/protocol/caps" ], {})) # another example from XEP-0115 identities = [u'client/pc/en/Psi 0.11', u'client/pc/el/Ψ 0.11'] features = [ u'http://jabber.org/protocol/caps', u'http://jabber.org/protocol/disco#info', u'http://jabber.org/protocol/disco#items', u'http://jabber.org/protocol/muc', ] dataforms = { u'urn:xmpp:dataforms:softwareinfo': { u'ip_version': [u'ipv4', u'ipv6'],