def announce_contact(self, name=CONTACT_NAME): basic_txt = { "txtvers": "1", "status": "avail" } self.contact_name = '%s@%s' % (name, get_host_name()) self.listener, port = setup_stream_listener(self.q, self.contact_name, protocol=IncomingXmppiChatStream) AvahiAnnouncer(self.contact_name, "_presence._tcp", port, basic_txt)
def announce_contact(self, name=CONTACT_NAME): basic_txt = { "txtvers": "1", "status": "avail" } self.contact_name = '%s@%s' % (name, get_host_name()) self.listener, port = setup_stream_listener(self.q, self.contact_name, protocol=IncomingXmppiChatStream) AvahiAnnouncer(self.contact_name, "_presence._tcp", port, basic_txt)
def my_request_ft_channel(self): self.contact_name = '%s@%s' % (self.CONTACT_NAME, get_host_name()) self.handle = self.conn.Contacts.GetContactByID(self.contact_name, [])[0] try: self.request_ft_channel() except dbus.DBusException, e: if e.get_dbus_name() != cs.NOT_AVAILABLE: raise
def test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = { "txtvers": "1", "status": "avail" } contact_name = "test-text-channel@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name = self_handle_name, protocol = avahi.PROTO_INET) service = e.service service.resolve() e = q.expect('service-resolved', service = service) xmpp_connection = connect_to_stream(q, contact_name, self_handle_name, str(e.pt), e.port) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection = xmpp_connection) # connected to salut, now send a messages as composing part # here be sillyness parts = OUTGOING_MESSAGE.split(" ") for x in xrange(1,len(parts)): message = domish.Element(('', 'message')) message.addElement('body', content=' '.join(parts[:x])) event = message.addElement('x', 'jabber:x:event') event.addElement('composing') event.addElement('id') xmpp_connection.send(message) message = domish.Element(('', 'message')) message.addElement('body', content=OUTGOING_MESSAGE) event = message.addElement('x', 'jabber:x:event') event.addElement('composing') xmpp_connection.send(message) e = q.expect('dbus-signal', signal='Received') assert e.args[2] == handle assert e.args[5] == OUTGOING_MESSAGE
def test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = {"txtvers": "1", "status": "avail"} contact_name = "test-text-channel@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name=self_handle_name, protocol=avahi.PROTO_INET) service = e.service service.resolve() e = q.expect('service-resolved', service=service) xmpp_connection = connect_to_stream(q, contact_name, self_handle_name, str(e.pt), e.port) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection=xmpp_connection) # connected to salut, now send a messages as composing part # here be sillyness parts = OUTGOING_MESSAGE.split(" ") for x in xrange(1, len(parts)): message = domish.Element(('', 'message')) message.addElement('body', content=' '.join(parts[:x])) event = message.addElement('x', 'jabber:x:event') event.addElement('composing') event.addElement('id') xmpp_connection.send(message) message = domish.Element(('', 'message')) message.addElement('body', content=OUTGOING_MESSAGE) event = message.addElement('x', 'jabber:x:event') event.addElement('composing') xmpp_connection.send(message) e = q.expect('dbus-signal', signal='Received') assert e.args[2] == handle assert e.args[5] == OUTGOING_MESSAGE
def announce_contact(self, name=CONTACT_NAME, metadata=True): client = 'http://telepathy.freedesktop.org/fake-client' features = [ns.IQ_OOB] if metadata: features += [ns.TP_FT_METADATA] ver = compute_caps_hash([], features, {}) txt_record = { "txtvers": "1", "status": "avail", "node": client, "ver": ver, "hash": "sha-1" } suffix = '@%s' % get_host_name() name += ('-' + os.path.splitext(os.path.basename(sys.argv[0]))[0]) self.contact_name = name + suffix if len(self.contact_name) > 63: allowed = 63 - len(suffix) self.contact_name = name[:allowed] + suffix self.listener, port = setup_stream_listener(self.q, self.contact_name) self.contact_service = AvahiAnnouncer(self.contact_name, "_presence._tcp", port, txt_record) self.handle = wait_for_contact_in_publish(self.q, self.bus, self.conn, self.contact_name) # expect salut to disco our caps e = self.q.expect('incoming-connection', listener=self.listener) stream = e.connection e = self.q.expect('stream-iq', to=self.contact_name, query_ns=ns.DISCO_INFO, connection=stream) assertEquals(client + '#' + ver, e.query['node']) send_disco_reply(stream, e.stanza, [], features) # lose the connection here to ensure connections are created # where necessary; I just wanted salut to know my caps. stream.send('</stream:stream>') # spend a bit of time in the main loop to ensure the last two # stanzas are actually received by salut before closing the # connection. sync_dbus(self.bus, self.q, self.conn) stream.transport.loseConnection()
def setup_tests(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = { "txtvers": "1", "status": "avail" } contact_name = "test-yst-message@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) return handle, contact_name, listener
def setup_tests(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = {"txtvers": "1", "status": "avail"} contact_name = "test-yst-message@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) return handle, contact_name, listener
def announce_contact(self, name=CONTACT_NAME, metadata=True): client = 'http://telepathy.freedesktop.org/fake-client' features = [ns.IQ_OOB] if metadata: features += [ns.TP_FT_METADATA] ver = compute_caps_hash([], features, {}) txt_record = { "txtvers": "1", "status": "avail", "node": client, "ver": ver, "hash": "sha-1"} suffix = '@%s' % get_host_name() name += ('-' + os.path.splitext(os.path.basename(sys.argv[0]))[0]) self.contact_name = name + suffix if len(self.contact_name) > 63: allowed = 63 - len(suffix) self.contact_name = name[:allowed] + suffix self.listener, port = setup_stream_listener(self.q, self.contact_name) self.contact_service = AvahiAnnouncer(self.contact_name, "_presence._tcp", port, txt_record) self.handle = wait_for_contact_in_publish(self.q, self.bus, self.conn, self.contact_name) # expect salut to disco our caps e = self.q.expect('incoming-connection', listener=self.listener) stream = e.connection e = self.q.expect('stream-iq', to=self.contact_name, query_ns=ns.DISCO_INFO, connection=stream) assertEquals(client + '#' + ver, e.query['node']) send_disco_reply(stream, e.stanza, [], features) # lose the connection here to ensure connections are created # where necessary; I just wanted salut to know my caps. stream.send('</stream:stream>') # spend a bit of time in the main loop to ensure the last two # stanzas are actually received by salut before closing the # connection. sync_dbus(self.bus, self.q, self.conn) stream.transport.loseConnection()
def test(q, bus, conn): AvahiListener(q).listen_for_service("_presence._tcp") conn.Connect() e = q.expect('service-added', name=PUBLISHED_NAME + "@" + avahitest.get_host_name()) service = e.service service.resolve() e = q.expect('service-resolved', service = service) for (key, val) in { "1st": FIRST_NAME, "last": LAST_NAME, "status": "avail", "txtvers": "1" }.iteritems(): v = txt_get_key(e.txt, key) assert v == val, (key, val, v)
def test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = {"txtvers": "1", "status": "avail"} self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") contact_name = "test-ichat-incoming-msg@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) # Create a connection to send msg stanza AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name=self_handle_name, protocol=avahi.PROTO_INET) service = e.service service.resolve() e = q.expect('service-resolved', service=service) outbound = connect_to_stream(q, contact_name, self_handle_name, str(e.pt), e.port, OutgoingXmppiChatStream) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection=outbound) msg = domish.Element((None, 'message')) msg['to'] = self_handle_name msg['type'] = 'chat' boddy = msg.addElement('body', content='hi') outbound.send(msg) e = q.expect('dbus-signal', signal='Received') assert e.args[2] == handle assert e.args[3] == cs.MT_NORMAL assert e.args[5] == "hi"
def test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = { "txtvers": "1", "status": "avail" } self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") contact_name = "test-ichat-incoming-msg@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) # Create a connection to send msg stanza AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name = self_handle_name, protocol = avahi.PROTO_INET) service = e.service service.resolve() e = q.expect('service-resolved', service = service) outbound = connect_to_stream(q, contact_name, self_handle_name, str(e.pt), e.port, OutgoingXmppiChatStream) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection = outbound) msg = domish.Element((None, 'message')) msg['to'] = self_handle_name msg['type'] = 'chat' boddy = msg.addElement('body', content='hi') outbound.send(msg) e = q.expect('dbus-signal', signal='Received') assert e.args[2] == handle assert e.args[3] == cs.MT_NORMAL assert e.args[5] == "hi"
def test(q, bus, conn): AvahiListener(q).listen_for_service("_presence._tcp") conn.Connect() e = q.expect('service-added', name=PUBLISHED_NAME + "@" + avahitest.get_host_name()) service = e.service service.resolve() e = q.expect('service-resolved', service=service) for (key, val) in { "1st": FIRST_NAME, "last": LAST_NAME, "status": "avail", "txtvers": "1" }.iteritems(): v = txt_get_key(e.txt, key) assert v == val, (key, val, v)
def test_ft_caps_from_contact(q, bus, conn, client): conn_caps_iface = dbus.Interface(conn, cs.CONN_IFACE_CONTACT_CAPS) conn_contacts_iface = dbus.Interface(conn, cs.CONN_IFACE_CONTACTS) # send presence with FT capa ver = compute_caps_hash([], [ns.IQ_OOB], {}) txt_record = { "txtvers": "1", "status": "avail", "node": client, "ver": ver, "hash": "sha-1" } contact_name = "test-caps-ft@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, txt_record) # this is the first presence, Salut connects to the contact e = q.expect('incoming-connection', listener=listener) incoming = e.connection # Salut looks up our capabilities event = q.expect('stream-iq', connection=incoming, query_ns='http://jabber.org/protocol/disco#info') query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assert query_node.attributes['node'] == \ client + '#' + ver, (query_node.attributes['node'], client, ver) contact_handle = conn_contacts_iface.GetContactByID(contact_name, [])[0] # send good reply result = make_result_iq(event.stanza) query = result.firstChildElement() query['node'] = client + '#' + ver feature = query.addElement('feature') feature['var'] = ns.IQ_OOB incoming.send(result) # FT capa is announced e = q.expect('dbus-signal', signal='ContactCapabilitiesChanged', predicate=lambda e: contact_handle in e.args[0]) caps = e.args[0][contact_handle] assertContains(ft_caps, caps) # check the Contacts interface give the same caps caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes( [contact_handle], [cs.CONN_IFACE_CONTACT_CAPS], False) \ [contact_handle][cs.CONN_IFACE_CONTACT_CAPS + '/capabilities'] assert caps_via_contacts_iface == caps, caps_via_contacts_iface # check if Salut announces the OOB capa self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name=self_handle_name, protocol=avahi.PROTO_INET) service = e.service service.resolve() receive_presence_and_ask_caps(q, incoming, service, contact_name) # capa announced without FT ver = compute_caps_hash([], ["http://telepathy.freedesktop.org/xmpp/pony"], {}) txt_record = { "txtvers": "1", "status": "avail", "node": client, "ver": ver, "hash": "sha-1" } contact_name = "test-caps-ft2@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, txt_record) # this is the first presence, Salut connects to the contact e = q.expect('incoming-connection', listener=listener) incoming = e.connection # Salut looks up our capabilities event = q.expect('stream-iq', connection=incoming, query_ns='http://jabber.org/protocol/disco#info') query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assert query_node.attributes['node'] == \ client + '#' + ver, (query_node.attributes['node'], client, ver) contact_handle = conn_contacts_iface.GetContactByID(contact_name, [])[0] # send good reply result = make_result_iq(event.stanza) query = result.firstChildElement() query['node'] = client + '#' + ver feature = query.addElement('feature') feature['var'] = "http://telepathy.freedesktop.org/xmpp/pony" incoming.send(result) # the FT capability is not announced e = q.expect('dbus-signal', signal='ContactCapabilitiesChanged') caps = e.args[0][contact_handle] assertDoesNotContain(ft_caps, caps) # check the Contacts interface give the same caps caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes( [contact_handle], [cs.CONN_IFACE_CONTACT_CAPS], False) \ [contact_handle][cs.CONN_IFACE_CONTACT_CAPS + '/capabilities'] assert caps_via_contacts_iface == caps, caps_via_contacts_iface # no capabilites announced (assume FT is supported to insure interop) txt_record = {"txtvers": "1", "status": "avail"} contact_name = "test-caps-ft-no-capa2@" + get_host_name() contact_handle = conn_contacts_iface.GetContactByID(contact_name, [])[0] listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, txt_record) # FT capa is announced e = q.expect('dbus-signal', signal='ContactCapabilitiesChanged', predicate=lambda e: contact_handle in e.args[0].keys()) caps = e.args[0][contact_handle] assertContains(ft_caps, caps) # check the Contacts interface give the same caps caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes( [contact_handle], [cs.CONN_IFACE_CONTACT_CAPS], False) \ [contact_handle][cs.CONN_IFACE_CONTACT_CAPS + '/capabilities'] assert caps_via_contacts_iface == caps, caps_via_contacts_iface
def test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = { "txtvers": "1", "status": "avail" } self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") contact_name = "test-text-channel@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) # create a clique room basic_txt = { "txtvers": "0"} AvahiAnnouncer("myroom", "_clique._udp", 41377, basic_txt) # connect a stream AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name = self_handle_name, protocol = avahi.PROTO_INET) service = e.service service.resolve() e = q.expect('service-resolved', service = service) xmpp_connection = connect_to_stream(q, contact_name, self_handle_name, str(e.pt), e.port) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection = xmpp_connection) # send an invitation message = domish.Element(('', 'message')) message['type'] = 'normal' message.addElement('body', content='You got a Clique chatroom invitation') invite = message.addElement((NS_CLIQUE, 'invite')) invite.addElement('roomname', content='myroom') invite.addElement('reason', content='Inviting to this room') invite.addElement('address', content='127.0.0.1') invite.addElement('port', content='41377') xmpp_connection.send(message) # group channel is created e = q.expect('dbus-signal', signal='NewChannel', predicate=lambda e: e.args[1] == cs.CHANNEL_TYPE_TEXT and e.args[2] == cs.HT_ROOM) path = e.args[0] channel = make_channel_proxy(conn, path, 'Channel') props_iface = dbus.Interface(bus.get_object(conn.object.bus_name, path), dbus.PROPERTIES_IFACE) q.expect('dbus-signal', signal='MembersChanged', path=path) lp_members = props_iface.Get('org.freedesktop.Telepathy.Channel.Interface.Group', 'LocalPendingMembers') assert len(lp_members) == 1 added, actor, reason, msg = lp_members[0] assert added == self_handle assert actor == handle assert reason == 4 #invited assert msg == 'Inviting to this room' # decline invitation channel.Close() q.expect('dbus-signal', signal='Closed')
def test(q, bus, conn): self_name = 'testsuite' + '@' + avahitest.get_host_name() conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) # FIXME: this is a hack to be sure to have all the contact list channels # announced so they won't interfere with the roomlist ones announces. wait_for_contact_list(q, conn) # check if we can request roomlist channels properties = conn.GetAll( tp_name_prefix + '.Connection.Interface.Requests', dbus_interface='org.freedesktop.DBus.Properties') assert ({tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_ROOM_LIST, tp_name_prefix + '.Channel.TargetHandleType': 0, }, [], ) in properties.get('RequestableChannelClasses'),\ properties['RequestableChannelClasses'] requestotron = dbus.Interface(conn, tp_name_prefix + '.Connection.Interface.Requests') # create roomlist channel using new API call_async(q, requestotron, 'CreateChannel', { tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_ROOM_LIST, tp_name_prefix + '.Channel.TargetHandleType': 0, }) ret, new_sig = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) path2 = ret.value[0] chan2 = wrap_channel(bus.get_object(conn.bus_name, path2), "RoomList") props = ret.value[1] assert props[tp_name_prefix + '.Channel.ChannelType'] ==\ cs.CHANNEL_TYPE_ROOM_LIST assert props[tp_name_prefix + '.Channel.TargetHandleType'] == 0 assert props[tp_name_prefix + '.Channel.TargetHandle'] == 0 assert props[tp_name_prefix + '.Channel.TargetID'] == '' assert props[tp_name_prefix + '.Channel.Requested'] == True assert props[tp_name_prefix + '.Channel.InitiatorHandle'] \ == conn.Properties.Get(cs.CONN, "SelfHandle") assert props[tp_name_prefix + '.Channel.InitiatorID'] \ == self_name assert props[tp_name_prefix + '.Channel.Type.RoomList.Server'] == '' assert new_sig.args[0][0][0] == path2 assert new_sig.args[0][0][1] == props assert chan2.Properties.Get(cs.CHANNEL_TYPE_ROOM_LIST, 'Server') == '' # ensure roomlist channel yours, ensured_path, ensured_props = requestotron.EnsureChannel( { tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_ROOM_LIST, tp_name_prefix + '.Channel.TargetHandleType': 0, }) assert not yours assert ensured_path == path2, (ensured_path, path2) # Closing roomlist channels crashed Salut for a while. chan2.Close() q.expect_many( EventPattern('dbus-signal', signal='Closed', path=path2), EventPattern('dbus-signal', signal='ChannelClosed', args=[path2]), ) conn.Disconnect() q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[2, 1]), )
def test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED]) assertContains(cs.CONN_IFACE_CONTACT_INFO, conn.Properties.Get(cs.CONN, "Interfaces")) ci_props = conn.Properties.GetAll(cs.CONN_IFACE_CONTACT_INFO) assertEquals(cs.CONTACT_INFO_FLAG_PUSH, ci_props['ContactInfoFlags']) assertEquals([ ('n', [], cs.CONTACT_INFO_FIELD_FLAG_PARAMETERS_EXACT, 1), ('fn', [], cs.CONTACT_INFO_FIELD_FLAG_PARAMETERS_EXACT, 1), ('email', ['type=internet' ], cs.CONTACT_INFO_FIELD_FLAG_PARAMETERS_EXACT, 1), ('x-jabber', [], cs.CONTACT_INFO_FIELD_FLAG_PARAMETERS_EXACT, 1), ], ci_props['SupportedFields']) # Just to verify that RCI does approximately nothing and doesn't crash. conn.ContactInfo.RefreshContactInfo([21, 42, 88]) basic_txt = {"txtvers": "1", "status": "avail"} contact_name = "aliastest@" + get_host_name() announcer = AvahiAnnouncer(contact_name, "_presence._tcp", 1234, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) alias = wait_for_aliases_changed(q, handle) assertEquals(contact_name, alias) for (alias, dict, expect_contact_info_changed) in [ # Contact publishes just one of 1st and last ("last", { "last": "last" }, True), ("1st", { "1st": "1st" }, True), # Contact publishes a meaningful value for one of 1st and last, and an # empty value for the other one and for "nick". Empty values should be # treated as if missing. ("last", { "last": "last", "1st": "", "nick": "" }, True), ("1st", { "1st": "1st", "last": "", "nick": "" }, True), # When a contact publishes both 1st and last, we have to join them # together in a stupid anglo-centric way, like iChat does. ("1st last", { "1st": "1st", "last": "last" }, True), # Nickname should be preferred as the alias to 1st or last. Since we # don't report nicknames in ContactInfo, and nothing else has changed # from the last update, no ContactInfo changes should be announced. ("nickname", { "1st": "1st", "last": "last", "nick": "nickname" }, False), # If the contact stops publishing any of this stuff, we should fall back # to their JID as their alias. (contact_name, {}, True) ]: txt = basic_txt.copy() txt.update(dict) announcer.set(txt) a = wait_for_aliases_changed(q, handle) assert a == alias, (a, alias, txt) if expect_contact_info_changed: info = wait_for_contact_info_changed(q, handle) check_contact_info(info, dict) attrs = conn.Contacts.GetContactAttributes([handle], [cs.CONN_IFACE_ALIASING], True)[handle] assertEquals(alias, attrs[cs.CONN_IFACE_ALIASING + "/alias"]) check_all_contact_info_methods(conn, handle, dict) for keys in [ # Check a few neat transitions, with no empty fields { "email": "*****@*****.**" }, { "jid": "*****@*****.**", "email": "*****@*****.**" }, { "jid": "*****@*****.**" }, # Check that empty fields are treated as if omitted { "email": "*****@*****.**", "jid": "" }, { "jid": "*****@*****.**", "email": "" }, ]: txt = basic_txt.copy() txt.update(keys) announcer.set(txt) info = wait_for_contact_info_changed(q, handle) check_contact_info(info, keys) check_all_contact_info_methods(conn, handle, keys) # Try an invalid handle. Request should return InvalidHandle. # (Technically so should RefreshContactInfo but I am lazy.) call_async(q, conn.ContactInfo, 'RequestContactInfo', 42) q.expect('dbus-error', method='RequestContactInfo', name=cs.INVALID_HANDLE) # Try a valid handle for whom we have no data from the network. # Request should fail. h = conn.Contacts.GetContactByID('rthrtha@octopus', [])[0] call_async(q, conn.ContactInfo, 'RequestContactInfo', h) q.expect('dbus-error', method='RequestContactInfo', name=cs.NOT_AVAILABLE)
def test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED]) assertContains(cs.CONN_IFACE_CONTACT_INFO, conn.Properties.Get(cs.CONN, "Interfaces")) ci_props = conn.Properties.GetAll(cs.CONN_IFACE_CONTACT_INFO) assertEquals(cs.CONTACT_INFO_FLAG_PUSH, ci_props['ContactInfoFlags']) assertEquals( [ ('n', [], cs.CONTACT_INFO_FIELD_FLAG_PARAMETERS_EXACT, 1), ('fn', [], cs.CONTACT_INFO_FIELD_FLAG_PARAMETERS_EXACT, 1), ('email', ['type=internet'], cs.CONTACT_INFO_FIELD_FLAG_PARAMETERS_EXACT, 1), ('x-jabber', [], cs.CONTACT_INFO_FIELD_FLAG_PARAMETERS_EXACT, 1), ], ci_props['SupportedFields']) # Just to verify that RCI does approximately nothing and doesn't crash. conn.ContactInfo.RefreshContactInfo([21,42,88]) basic_txt = { "txtvers": "1", "status": "avail" } contact_name = "aliastest@" + get_host_name() announcer = AvahiAnnouncer(contact_name, "_presence._tcp", 1234, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) alias = wait_for_aliases_changed(q, handle) assertEquals(contact_name, alias) for (alias, dict, expect_contact_info_changed) in [ # Contact publishes just one of 1st and last ("last", { "last": "last" }, True), ("1st", { "1st": "1st"}, True), # Contact publishes a meaningful value for one of 1st and last, and an # empty value for the other one and for "nick". Empty values should be # treated as if missing. ("last", { "last": "last", "1st": "", "nick": "" }, True), ("1st", { "1st": "1st", "last": "", "nick": "" }, True), # When a contact publishes both 1st and last, we have to join them # together in a stupid anglo-centric way, like iChat does. ("1st last", { "1st": "1st", "last": "last" }, True), # Nickname should be preferred as the alias to 1st or last. Since we # don't report nicknames in ContactInfo, and nothing else has changed # from the last update, no ContactInfo changes should be announced. ("nickname", { "1st": "1st", "last": "last", "nick": "nickname" }, False), # If the contact stops publishing any of this stuff, we should fall back # to their JID as their alias. (contact_name, {}, True) ]: txt = basic_txt.copy() txt.update(dict) announcer.set(txt) a = wait_for_aliases_changed (q, handle) assert a == alias, (a, alias, txt) if expect_contact_info_changed: info = wait_for_contact_info_changed(q, handle) check_contact_info(info, dict) attrs = conn.Contacts.GetContactAttributes([handle], [cs.CONN_IFACE_ALIASING], True)[handle] assertEquals(alias, attrs[cs.CONN_IFACE_ALIASING + "/alias"]) check_all_contact_info_methods(conn, handle, dict) for keys in [ # Check a few neat transitions, with no empty fields { "email": "*****@*****.**" }, { "jid": "*****@*****.**", "email": "*****@*****.**" }, { "jid": "*****@*****.**" }, # Check that empty fields are treated as if omitted { "email": "*****@*****.**", "jid": "" }, { "jid": "*****@*****.**", "email": "" }, ]: txt = basic_txt.copy() txt.update(keys) announcer.set(txt) info = wait_for_contact_info_changed(q, handle) check_contact_info(info, keys) check_all_contact_info_methods(conn, handle, keys) # Try an invalid handle. Request should return InvalidHandle. # (Technically so should RefreshContactInfo but I am lazy.) call_async(q, conn.ContactInfo, 'RequestContactInfo', 42) q.expect('dbus-error', method='RequestContactInfo', name=cs.INVALID_HANDLE) # Try a valid handle for whom we have no data from the network. # Request should fail. h = conn.Contacts.GetContactByID('rthrtha@octopus', [])[0] call_async(q, conn.ContactInfo, 'RequestContactInfo', h) q.expect('dbus-error', method='RequestContactInfo', name=cs.NOT_AVAILABLE)
def test(q, bus, conn): forbidden = [EventPattern('dbus-signal', signal='ServiceAdded'), EventPattern('dbus-signal', signal='ServiceRemoved')] q.forbid_events(forbidden) conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0, 0]) # announce a contact with the right caps ver = compute_caps_hash([], [], banshee) txt_record = { "txtvers": "1", "status": "avail", "node": CLIENT_NAME, "ver": ver, "hash": "sha-1"} contact_name = "test-service@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, txt_record) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) # this is the first presence, Salut connects to the contact e = q.expect('incoming-connection', listener=listener) incoming = e.connection # Salut looks up its capabilities event = q.expect('stream-iq', connection=incoming, query_ns=ns.DISCO_INFO) query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assertEquals(CLIENT_NAME + '#' + ver, query_node.attributes['node']) contact_handle = conn.RequestHandles(cs.HT_CONTACT, [contact_name])[0] # send good reply result = make_result_iq(event.stanza) query = result.firstChildElement() query['node'] = CLIENT_NAME + '#' + ver x = query.addElement((ns.X_DATA, 'x')) x['type'] = 'result' # FORM_TYPE field = x.addElement((None, 'field')) field['var'] = 'FORM_TYPE' field['type'] = 'hidden' field.addElement((None, 'value'), content='urn:ytstenut:capabilities#org.gnome.Banshee') # type field = x.addElement((None, 'field')) field['var'] = 'type' field.addElement((None, 'value'), content='application') # name field = x.addElement((None, 'field')) field['var'] = 'name' field.addElement((None, 'value'), content='en_GB/Banshee Media Player') field.addElement((None, 'value'), content='fr/Banshee Lecteur de Musique') # capabilities field = x.addElement((None, 'field')) field['var'] = 'capabilities' field.addElement((None, 'value'), content='urn:ytstenut:capabilities:yts-caps-audio') field.addElement((None, 'value'), content='urn:ytstenut:data:jingle:rtp') incoming.send(result) # 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) ver = compute_caps_hash([], [], tmp) txt_record['ver'] = ver announcer.update(txt_record) # Salut looks up our capabilities event = q.expect('stream-iq', connection=incoming, query_ns='http://jabber.org/protocol/disco#info') query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assert query_node.attributes['node'] == \ CLIENT_NAME + '#' + txt_record['ver'] # send good reply result['id'] = event.stanza['id'] query['node'] = CLIENT_NAME + '#' + ver x = query.addElement((ns.X_DATA, 'x')) x['type'] = 'result' # FORM_TYPE field = x.addElement((None, 'field')) field['var'] = 'FORM_TYPE' field['type'] = 'hidden' field.addElement((None, 'value'), content='urn:ytstenut:capabilities#org.gnome.Evince') # type field = x.addElement((None, 'field')) field['var'] = 'type' field.addElement((None, 'value'), content='application') # name field = x.addElement((None, 'field')) field['var'] = 'name' field.addElement((None, 'value'), content='en_GB/Evince Picture Viewer') field.addElement((None, 'value'), content='fr/Evince uh, ow do you say') # capabilities field = x.addElement((None, 'field')) field['var'] = 'capabilities' field.addElement((None, 'value'), content='urn:ytstenut:capabilities:pics') incoming.send(result) # 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]) # 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({contact_name: { '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 connect_two_accounts(q, bus, conn): # first connection: connect contact1_name = "testsuite" + "@" + get_host_name() conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED]) # FIXME: this is a hack to be sure to have all the contact list channels # announced so they won't interfere with other channels announces. wait_for_contact_list(q, conn) # second connection: connect conn2_params = { 'published-name': 'testsuite2', 'first-name': 'test2', 'last-name': 'suite2', } contact2_name = "testsuite2" + "@" + get_host_name() conn2 = make_connection(bus, lambda x: None, conn2_params) conn2.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED]) wait_for_contact_list(q, conn2) # first connection: get the contact list publish_handle = conn.RequestHandles(cs.HT_LIST, ["publish"])[0] conn1_publish = conn.RequestChannel(cs.CHANNEL_TYPE_CONTACT_LIST, cs.HT_LIST, publish_handle, False) conn1_publish_proxy = bus.get_object(conn.bus_name, conn1_publish) # second connection: get the contact list publish_handle = conn2.RequestHandles(cs.HT_LIST, ["publish"])[0] conn2_publish = conn2.RequestChannel(cs.CHANNEL_TYPE_CONTACT_LIST, cs.HT_LIST, publish_handle, False) conn2_publish_proxy = bus.get_object(conn2.bus_name, conn2_publish) # first connection: wait to see contact2 # The signal MembersChanged may be already emitted... check the Members # property first contact2_handle_on_conn1 = 0 conn1_members = conn1_publish_proxy.Get(cs.CHANNEL_IFACE_GROUP, 'Members', dbus_interface=cs.PROPERTIES_IFACE) for h in conn1_members: name = conn.InspectHandles(cs.HT_CONTACT, [h])[0] if name == contact2_name: contact2_handle_on_conn1 = h while contact2_handle_on_conn1 == 0: e = q.expect('dbus-signal', signal='MembersChanged', path=conn1_publish) for h in e.args[1]: name = conn.InspectHandles(cs.HT_CONTACT, [h])[0] if name == contact2_name: contact2_handle_on_conn1 = h # second connection: wait to see contact1 # The signal MembersChanged may be already emitted... check the Members # property first contact1_handle_on_conn2 = 0 conn2_members = conn2_publish_proxy.Get( 'org.freedesktop.Telepathy.Channel.Interface.Group', 'Members', dbus_interface='org.freedesktop.DBus.Properties') for h in conn2_members: name = conn2.InspectHandles(cs.HT_CONTACT, [h])[0] if name == contact1_name: contact1_handle_on_conn2 = h while contact1_handle_on_conn2 == 0: e = q.expect('dbus-signal', signal='MembersChanged', path=conn2_publish) for h in e.args[1]: name = conn2.InspectHandles(cs.HT_CONTACT, [h])[0] if name == contact1_name: contact1_handle_on_conn2 = h return contact1_name, conn2, contact2_name, contact2_handle_on_conn1, contact1_handle_on_conn2
def test(q, bus, conn): self_name = 'testsuite' + '@' + avahitest.get_host_name() conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) # FIXME: this is a hack to be sure to have all the contact list channels # announced so they won't interfere with the muc ones announces. wait_for_contact_list(q, conn) # check if we can request roomlist channels properties = conn.GetAll( tp_name_prefix + '.Connection.Interface.Requests', dbus_interface='org.freedesktop.DBus.Properties') assert ({tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_TEXT, tp_name_prefix + '.Channel.TargetHandleType': cs.HT_ROOM, }, [tp_name_prefix + '.Channel.TargetHandle', tp_name_prefix + '.Channel.TargetID'], ) in properties.get('RequestableChannelClasses'),\ properties['RequestableChannelClasses'] requestotron = dbus.Interface(conn, tp_name_prefix + '.Connection.Interface.Requests') # create muc channel using new API call_async(q, requestotron, 'CreateChannel', { tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_TEXT, tp_name_prefix + '.Channel.TargetHandleType': cs.HT_ROOM, tp_name_prefix + '.Channel.TargetID': 'my-second-room', }) ret, new_sig = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) path2 = ret.value[0] chan = make_channel_proxy(conn, path2, "Channel") props = ret.value[1] assert props[tp_name_prefix + '.Channel.ChannelType'] ==\ cs.CHANNEL_TYPE_TEXT assert props[tp_name_prefix + '.Channel.TargetHandleType'] == cs.HT_ROOM assert props[tp_name_prefix + '.Channel.TargetID'] == 'my-second-room' assert props[tp_name_prefix + '.Channel.Requested'] == True assert props[tp_name_prefix + '.Channel.InitiatorHandle'] \ == conn.Properties.Get(cs.CONN, "SelfHandle") assert props[tp_name_prefix + '.Channel.InitiatorID'] \ == self_name assert new_sig.args[0][0][0] == path2 assert new_sig.args[0][0][1] == props # ensure roomlist channel handle = props[tp_name_prefix + '.Channel.TargetHandle'] yours, ensured_path, ensured_props = ret.value = requestotron.EnsureChannel( { tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_TEXT, tp_name_prefix + '.Channel.TargetHandleType': cs.HT_ROOM, tp_name_prefix + '.Channel.TargetHandle': handle, }) assert not yours assert ensured_path == path2, (ensured_path, path2) conn.Disconnect() q.expect_many( EventPattern('dbus-signal', signal='Closed', path=path2), EventPattern('dbus-signal', signal='ChannelClosed', args=[path2]), EventPattern('dbus-signal', signal='StatusChanged', args=[2, 1]), )
def test(q, bus, conn): self_name = 'testsuite' + '@' + avahitest.get_host_name() conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) # FIXME: this is a hack to be sure to have all the contact list channels # announced so they won't interfere with the muc ones announces. wait_for_contact_list(q, conn) # check if we can request roomlist channels properties = conn.GetAll(tp_name_prefix + '.Connection.Interface.Requests', dbus_interface='org.freedesktop.DBus.Properties') assert ({tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_TEXT, tp_name_prefix + '.Channel.TargetHandleType': cs.HT_ROOM, }, [tp_name_prefix + '.Channel.TargetHandle', tp_name_prefix + '.Channel.TargetID'], ) in properties.get('RequestableChannelClasses'),\ properties['RequestableChannelClasses'] requestotron = dbus.Interface( conn, tp_name_prefix + '.Connection.Interface.Requests') # create muc channel using new API call_async( q, requestotron, 'CreateChannel', { tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_TEXT, tp_name_prefix + '.Channel.TargetHandleType': cs.HT_ROOM, tp_name_prefix + '.Channel.TargetID': 'my-second-room', }) ret, new_sig = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) path2 = ret.value[0] chan = make_channel_proxy(conn, path2, "Channel") props = ret.value[1] assert props[tp_name_prefix + '.Channel.ChannelType'] ==\ cs.CHANNEL_TYPE_TEXT assert props[tp_name_prefix + '.Channel.TargetHandleType'] == cs.HT_ROOM assert props[tp_name_prefix + '.Channel.TargetID'] == 'my-second-room' assert props[tp_name_prefix + '.Channel.Requested'] == True assert props[tp_name_prefix + '.Channel.InitiatorHandle'] \ == conn.Properties.Get(cs.CONN, "SelfHandle") assert props[tp_name_prefix + '.Channel.InitiatorID'] \ == self_name assert new_sig.args[0][0][0] == path2 assert new_sig.args[0][0][1] == props # ensure roomlist channel handle = props[tp_name_prefix + '.Channel.TargetHandle'] yours, ensured_path, ensured_props = ret.value = requestotron.EnsureChannel( { tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_TEXT, tp_name_prefix + '.Channel.TargetHandleType': cs.HT_ROOM, tp_name_prefix + '.Channel.TargetHandle': handle, }) assert not yours assert ensured_path == path2, (ensured_path, path2) conn.Disconnect() q.expect_many( EventPattern('dbus-signal', signal='Closed', path=path2), EventPattern('dbus-signal', signal='ChannelClosed', args=[path2]), EventPattern('dbus-signal', signal='StatusChanged', args=[2, 1]), )
def connect_two_accounts(q, bus, conn): # first connection: connect contact1_name = "testsuite" + "@" + get_host_name() conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED]) # FIXME: this is a hack to be sure to have all the contact list channels # announced so they won't interfere with other channels announces. wait_for_contact_list(q, conn) # second connection: connect conn2_params = { 'published-name': 'testsuite2', 'first-name': 'test2', 'last-name': 'suite2', } contact2_name = "testsuite2" + "@" + get_host_name() conn2 = make_connection(bus, lambda x: None, conn2_params) conn2.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED]) wait_for_contact_list(q, conn2) # first connection: get the contact list publish_handle = conn.RequestHandles(cs.HT_LIST, ["publish"])[0] conn1_publish = conn.RequestChannel(cs.CHANNEL_TYPE_CONTACT_LIST, cs.HT_LIST, publish_handle, False) conn1_publish_proxy = bus.get_object(conn.bus_name, conn1_publish) # second connection: get the contact list publish_handle = conn2.RequestHandles(cs.HT_LIST, ["publish"])[0] conn2_publish = conn2.RequestChannel(cs.CHANNEL_TYPE_CONTACT_LIST, cs.HT_LIST, publish_handle, False) conn2_publish_proxy = bus.get_object(conn2.bus_name, conn2_publish) # first connection: wait to see contact2 # The signal MembersChanged may be already emitted... check the Members # property first contact2_handle_on_conn1 = 0 conn1_members = conn1_publish_proxy.Get(cs.CHANNEL_IFACE_GROUP, 'Members', dbus_interface=cs.PROPERTIES_IFACE) for h in conn1_members: name = conn.InspectHandles(cs.HT_CONTACT, [h])[0] if name == contact2_name: contact2_handle_on_conn1 = h while contact2_handle_on_conn1 == 0: e = q.expect('dbus-signal', signal='MembersChanged', path=conn1_publish) for h in e.args[1]: name = conn.InspectHandles(cs.HT_CONTACT, [h])[0] if name == contact2_name: contact2_handle_on_conn1 = h # second connection: wait to see contact1 # The signal MembersChanged may be already emitted... check the Members # property first contact1_handle_on_conn2 = 0 conn2_members = conn2_publish_proxy.Get( 'org.freedesktop.Telepathy.Channel.Interface.Group', 'Members', dbus_interface='org.freedesktop.DBus.Properties') for h in conn2_members: name = conn2.InspectHandles(cs.HT_CONTACT, [h])[0] if name == contact1_name: contact1_handle_on_conn2 = h while contact1_handle_on_conn2 == 0: e = q.expect('dbus-signal', signal='MembersChanged', path=conn2_publish) for h in e.args[1]: name = conn2.InspectHandles(cs.HT_CONTACT, [h])[0] if name == contact1_name: contact1_handle_on_conn2 = h return contact1_name, conn2, contact2_name, contact2_handle_on_conn1, contact1_handle_on_conn2
def test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = {"txtvers": "1", "status": "avail"} self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") contact_name = "test-text-channel@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) # create a clique room basic_txt = {"txtvers": "0"} AvahiAnnouncer("myroom", "_clique._udp", 41377, basic_txt) # connect a stream AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name=self_handle_name, protocol=avahi.PROTO_INET) service = e.service service.resolve() e = q.expect('service-resolved', service=service) xmpp_connection = connect_to_stream(q, contact_name, self_handle_name, str(e.pt), e.port) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection=xmpp_connection) # send an invitation message = domish.Element(('', 'message')) message['type'] = 'normal' message.addElement('body', content='You got a Clique chatroom invitation') invite = message.addElement((NS_CLIQUE, 'invite')) invite.addElement('roomname', content='myroom') invite.addElement('reason', content='Inviting to this room') invite.addElement('address', content='127.0.0.1') invite.addElement('port', content='41377') xmpp_connection.send(message) # group channel is created e = q.expect('dbus-signal', signal='NewChannel', predicate=lambda e: e.args[1] == cs.CHANNEL_TYPE_TEXT and e. args[2] == cs.HT_ROOM) path = e.args[0] channel = make_channel_proxy(conn, path, 'Channel') props_iface = dbus.Interface(bus.get_object(conn.object.bus_name, path), dbus.PROPERTIES_IFACE) q.expect('dbus-signal', signal='MembersChanged', path=path) lp_members = props_iface.Get( 'org.freedesktop.Telepathy.Channel.Interface.Group', 'LocalPendingMembers') assert len(lp_members) == 1 added, actor, reason, msg = lp_members[0] assert added == self_handle assert actor == handle assert reason == 4 #invited assert msg == 'Inviting to this room' # decline invitation channel.Close() q.expect('dbus-signal', signal='Closed')
def test(q, bus, conn): self_name = 'testsuite' + '@' + avahitest.get_host_name() conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) # FIXME: this is a hack to be sure to have all the contact list channels # announced so they won't interfere with the muc ones announces. wait_for_contact_list(q, conn) # check if we can request tube channels properties = conn.Properties.GetAll(cs.CONN_IFACE_REQUESTS) assert ({cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM}, [cs.TARGET_HANDLE, cs.TARGET_ID, cs.STREAM_TUBE_SERVICE], ) in properties.get('RequestableChannelClasses'),\ properties['RequestableChannelClasses'] # create muc channel using new API call_async(q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: 'my-second-room', cs.STREAM_TUBE_SERVICE: 'loldongs', }) ret, new_sig = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) tube_path = ret.value[0] chan = wrap_channel(bus.get_object(conn.bus_name, tube_path), 'StreamTube') tube_props = ret.value[1] assert tube_props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE assert tube_props[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert tube_props[cs.TARGET_ID] == 'my-second-room' assert tube_props[cs.REQUESTED] == True assert tube_props[cs.INITIATOR_HANDLE] == conn.Properties.Get(cs.CONN, "SelfHandle") assert tube_props[cs.INITIATOR_ID] == self_name # text and tube channels are announced channels = new_sig.args[0] assert len(channels) == 1 handle = tube_props[cs.TARGET_HANDLE] path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE assert path == tube_path assert props == tube_props assert props[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert props[cs.TARGET_HANDLE] == handle assert props[cs.TARGET_ID] == 'my-second-room' assert props[cs.INITIATOR_HANDLE] == conn.Properties.Get(cs.CONN, "SelfHandle") assert props[cs.INITIATOR_ID] == self_name # ensure the same channel # TODO: the muc channel doesn't bother to look at existing tubes # before creating a new one. once that's fixed, uncomment this. # yours, ensured_path, _ = conn.Requests.EnsureChannel( # { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, # cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, # cs.TARGET_HANDLE: handle, # cs.STREAM_TUBE_SERVICE: 'loldongs', # }) # assert not yours # assert ensured_path == tube_path, (ensured_path, tube_path) conn.Disconnect() q.expect_many( EventPattern('dbus-signal', signal='Closed', path=tube_path), EventPattern('dbus-signal', signal='ChannelClosed', args=[tube_path]), EventPattern('dbus-signal', signal='StatusChanged', args=[2, 1]), )
def test(q, bus, conn): self_name = 'testsuite' + '@' + get_host_name() conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = { "txtvers": "1", "status": "avail" } contact_name = "test-request-im@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) # FIXME: this is a hack to be sure to have all the contact list channels # announced so they won't interfere with the muc ones announces. wait_for_contact_list(q, conn) AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) # check if we can request roomlist channels properties = conn.GetAll( tp_name_prefix + '.Connection.Interface.Requests', dbus_interface='org.freedesktop.DBus.Properties') assert ({tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_TEXT, tp_name_prefix + '.Channel.TargetHandleType': cs.HT_CONTACT, }, [tp_name_prefix + '.Channel.TargetHandle', tp_name_prefix + '.Channel.TargetID'], ) in properties.get('RequestableChannelClasses'),\ properties['RequestableChannelClasses'] # create muc channel requestotron = dbus.Interface(conn, tp_name_prefix + '.Connection.Interface.Requests') call_async(q, requestotron, 'CreateChannel', { tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_TEXT, tp_name_prefix + '.Channel.TargetHandleType': cs.HT_CONTACT, tp_name_prefix + '.Channel.TargetID': contact_name, }) ret, new_sig = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) path2 = ret.value[0] chan = make_channel_proxy(conn, path2, "Channel") props = ret.value[1] assert props[tp_name_prefix + '.Channel.ChannelType'] ==\ cs.CHANNEL_TYPE_TEXT assert props[tp_name_prefix + '.Channel.TargetHandleType'] == cs.HT_CONTACT assert props[tp_name_prefix + '.Channel.TargetHandle'] == handle assert props[tp_name_prefix + '.Channel.TargetID'] == contact_name assert props[tp_name_prefix + '.Channel.Requested'] == True assert props[tp_name_prefix + '.Channel.InitiatorHandle'] \ == conn.Properties.Get(cs.CONN, "SelfHandle") assert props[tp_name_prefix + '.Channel.InitiatorID'] \ == self_name assert new_sig.args[0][0][0] == path2 assert new_sig.args[0][0][1] == props # ensure roomlist channel yours, ensured_path, ensured_props = requestotron.EnsureChannel( { tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_TEXT, tp_name_prefix + '.Channel.TargetHandleType': cs.HT_CONTACT, tp_name_prefix + '.Channel.TargetHandle': handle, }) assert not yours assert ensured_path == path2, (ensured_path, path2) conn.Disconnect() q.expect_many( EventPattern('dbus-signal', signal='Closed', path=path2), EventPattern('dbus-signal', signal='ChannelClosed', args=[path2]), EventPattern('dbus-signal', signal='StatusChanged', args=[2, 1]), )
def test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = { "txtvers": "1", "status": "avail" } contact_name = "test-text-channel@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) t = conn.Requests.CreateChannel({ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_HANDLE: handle})[0] text_channel = make_channel_proxy(conn, t, "Channel.Type.Text") text_channel.Send(cs.MT_NORMAL, INCOMING_MESSAGE) e = q.expect('incoming-connection', listener = listener) incoming = e.connection e = q.expect('stream-message', connection = incoming) assert e.message_type == "chat" body = xpath.queryForNodes("/message/body", e.stanza ) assert map(str, body) == [ INCOMING_MESSAGE ] # drop the connection incoming.transport.loseConnection() # Now send a message to salut self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name = self_handle_name, protocol = avahi.PROTO_INET) service = e.service service.resolve() e = q.expect('service-resolved', service = service) outbound = connect_to_stream(q, contact_name, self_handle_name, str(e.pt), e.port) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection = outbound) # connected to salut, now send a message message = domish.Element(('', 'message')) message['type'] = "chat" message.addElement('body', content=OUTGOING_MESSAGE) e.connection.send(message) e = q.expect('dbus-signal', signal='Received') assert e.args[2] == handle assert e.args[3] == cs.MT_NORMAL assert e.args[5] == OUTGOING_MESSAGE
def test(q, bus, conn): 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 ver = compute_caps_hash([], [], banshee) txt_record = { "txtvers": "1", "status": "avail", "node": CLIENT_NAME, "ver": ver, "hash": "sha-1" } contact_name = "test-service@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, txt_record) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) # this is the first presence, Salut connects to the contact e = q.expect('incoming-connection', listener=listener) incoming = e.connection # Salut looks up its capabilities event = q.expect('stream-iq', connection=incoming, query_ns=ns.DISCO_INFO) query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assertEquals(CLIENT_NAME + '#' + ver, query_node.attributes['node']) contact_handle = conn.RequestHandles(cs.HT_CONTACT, [contact_name])[0] # send good reply result = make_result_iq(event.stanza) query = result.firstChildElement() query['node'] = CLIENT_NAME + '#' + ver x = query.addElement((ns.X_DATA, 'x')) x['type'] = 'result' # FORM_TYPE field = x.addElement((None, 'field')) field['var'] = 'FORM_TYPE' field['type'] = 'hidden' field.addElement((None, 'value'), content='urn:ytstenut:capabilities#org.gnome.Banshee') # type field = x.addElement((None, 'field')) field['var'] = 'type' field.addElement((None, 'value'), content='application') # name field = x.addElement((None, 'field')) field['var'] = 'name' field.addElement((None, 'value'), content='en_GB/Banshee Media Player') field.addElement((None, 'value'), content='fr/Banshee Lecteur de Musique') # capabilities field = x.addElement((None, 'field')) field['var'] = 'capabilities' field.addElement((None, 'value'), content='urn:ytstenut:capabilities:yts-caps-audio') field.addElement((None, 'value'), content='urn:ytstenut:data:jingle:rtp') incoming.send(result) # 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(contact_name, 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( { contact_name: { '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) ver = compute_caps_hash([], [], tmp) txt_record['ver'] = ver announcer.update(txt_record) # Salut looks up our capabilities event = q.expect('stream-iq', connection=incoming, query_ns='http://jabber.org/protocol/disco#info') query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assert query_node.attributes['node'] == \ CLIENT_NAME + '#' + txt_record['ver'] # send good reply result['id'] = event.stanza['id'] query['node'] = CLIENT_NAME + '#' + ver x = query.addElement((ns.X_DATA, 'x')) x['type'] = 'result' # FORM_TYPE field = x.addElement((None, 'field')) field['var'] = 'FORM_TYPE' field['type'] = 'hidden' field.addElement((None, 'value'), content='urn:ytstenut:capabilities#org.gnome.Evince') # type field = x.addElement((None, 'field')) field['var'] = 'type' field.addElement((None, 'value'), content='application') # name field = x.addElement((None, 'field')) field['var'] = 'name' field.addElement((None, 'value'), content='en_GB/Evince Picture Viewer') field.addElement((None, 'value'), content='fr/Evince uh, ow do you say') # capabilities field = x.addElement((None, 'field')) field['var'] = 'capabilities' field.addElement((None, 'value'), content='urn:ytstenut:capabilities:pics') incoming.send(result) e = q.expect('dbus-signal', signal='ServiceAdded') contact_id, service_name, details = e.args assertEquals(contact_name, 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( { contact_name: { '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 ver = compute_caps_hash([], [], banshee) txt_record['ver'] = ver forbidden = [ EventPattern('dbus-signal', signal='stream-iq', connection=incoming) ] q.forbid_events(forbidden) announcer.update(txt_record) e = q.expect('dbus-signal', signal='ServiceRemoved') contact_id, service_name = e.args assertEquals(contact_name, contact_id) assertEquals('org.gnome.Evince', service_name) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( { contact_name: { '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, incoming) q.unforbid_events(forbidden) # now just evince ver = compute_caps_hash([], [], evince) txt_record['ver'] = ver announcer.update(txt_record) # Salut looks up our capabilities event = q.expect('stream-iq', connection=incoming, query_ns='http://jabber.org/protocol/disco#info') query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assert query_node.attributes['node'] == \ CLIENT_NAME + '#' + txt_record['ver'] # send good reply result = make_result_iq(event.stanza) query = result.firstChildElement() query['node'] = CLIENT_NAME + '#' + ver x = query.addElement((ns.X_DATA, 'x')) x['type'] = 'result' # FORM_TYPE field = x.addElement((None, 'field')) field['var'] = 'FORM_TYPE' field['type'] = 'hidden' field.addElement((None, 'value'), content='urn:ytstenut:capabilities#org.gnome.Evince') # type field = x.addElement((None, 'field')) field['var'] = 'type' field.addElement((None, 'value'), content='application') # name field = x.addElement((None, 'field')) field['var'] = 'name' field.addElement((None, 'value'), content='en_GB/Evince Picture Viewer') field.addElement((None, 'value'), content='fr/Evince uh, ow do you say') # capabilities field = x.addElement((None, 'field')) field['var'] = 'capabilities' field.addElement((None, 'value'), content='urn:ytstenut:capabilities:pics') incoming.send(result) sa, sr = q.expect_many( EventPattern('dbus-signal', signal='ServiceAdded'), EventPattern('dbus-signal', signal='ServiceRemoved')) contact_id, service_name, details = sa.args assertEquals(contact_name, 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(contact_name, contact_id) assertEquals('org.gnome.Banshee', service_name) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals( { contact_name: { 'org.gnome.Evince': ('application', { 'en_GB': 'Evince Picture Viewer', 'fr': 'Evince uh, ow do you say' }, ['urn:ytstenut:capabilities:pics']) } }, discovered) # just banshee again ver = compute_caps_hash([], [], banshee) txt_record['ver'] = ver forbidden = [ EventPattern('dbus-signal', signal='stream-iq', connection=incoming) ] q.forbid_events(forbidden) announcer.update(txt_record) sr, sa = q.expect_many( EventPattern('dbus-signal', signal='ServiceRemoved'), EventPattern('dbus-signal', signal='ServiceAdded')) contact_id, service_name = sr.args assertEquals(contact_name, contact_id) assertEquals('org.gnome.Evince', service_name) contact_id, service_name, details = sa.args assertEquals(contact_name, 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( { contact_name: { '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, incoming) q.unforbid_events(forbidden) # both again ver = compute_caps_hash([], [], tmp) txt_record['ver'] = ver announcer.update(txt_record) sa = q.expect('dbus-signal', signal='ServiceAdded') contact_id, service_name, details = sa.args assertEquals(contact_name, 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( { contact_name: { '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, incoming) # and finally, nothing ver = compute_caps_hash([], [], {}) txt_record['ver'] = ver announcer.update(txt_record) # Salut looks up our capabilities event = q.expect('stream-iq', connection=incoming, query_ns='http://jabber.org/protocol/disco#info') query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assert query_node.attributes['node'] == \ CLIENT_NAME + '#' + txt_record['ver'] # send good reply result = make_result_iq(event.stanza) query = result.firstChildElement() query['node'] = CLIENT_NAME + '#' + ver incoming.send(result) q.expect_many( EventPattern('dbus-signal', signal='ServiceRemoved', args=[contact_name, 'org.gnome.Banshee']), EventPattern('dbus-signal', signal='ServiceRemoved', args=[contact_name, 'org.gnome.Evince'])) discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals({}, discovered)
def test(q, bus, conn): # 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 ver = compute_caps_hash([], [CAP_NAME + '+notify'], {}) txt_record = { "txtvers": "1", "status": "avail", "node": CLIENT_NAME, "ver": ver, "hash": "sha-1" } contact_name = "test-status@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, txt_record) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) # this is the first presence, Salut connects to the contact e = q.expect('incoming-connection', listener=listener) incoming = e.connection # Salut looks up its capabilities event = q.expect('stream-iq', connection=incoming, query_ns=ns.DISCO_INFO) query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assertEquals(CLIENT_NAME + '#' + ver, query_node.attributes['node']) contact_handle = conn.RequestHandles(cs.HT_CONTACT, [contact_name])[0] # send good reply result = make_result_iq(event.stanza) query = result.firstChildElement() query['node'] = CLIENT_NAME + '#' + ver feature = query.addElement('feature') feature['var'] = CAP_NAME + '+notify' incoming.send(result) # 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, _, sig = q.expect_many( EventPattern('stream-message', connection=incoming), EventPattern('dbus-return', method='AdvertiseStatus'), EventPattern('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE)) # check message message = e.stanza event = message.children[0] items = event.children[0] item = items.children[0] status_el = item.children[0] assertEquals('status', status_el.name) assertEquals('messing-with-your-stuff', status_el['activity']) assertEquals('ants.in.their.pants', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) # 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( { 'testsuite@testsuite': { 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, _, sig = q.expect_many( EventPattern('stream-message', connection=incoming), EventPattern('dbus-return', method='AdvertiseStatus'), EventPattern('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE)) # check message message = e.stanza event = message.children[0] items = event.children[0] item = items.children[0] status_el = item.children[0] assertEquals('status', status_el.name) assertEquals('rofling', status_el['activity']) assertEquals('bananaman.on.holiday', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) # 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( { 'testsuite@testsuite': { 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, _, sig = q.expect_many( EventPattern('stream-message', connection=incoming), EventPattern('dbus-return', method='AdvertiseStatus'), EventPattern('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE)) # check message message = e.stanza event = message.children[0] items = event.children[0] item = items.children[0] status_el = item.children[0] assertEquals('status', status_el.name) 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) # 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( { 'testsuite@testsuite': { 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, _, sig = q.expect_many( EventPattern('stream-message', connection=incoming), EventPattern('dbus-return', method='AdvertiseStatus'), EventPattern('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE)) # check message message = e.stanza event = message.children[0] items = event.children[0] item = items.children[0] status_el = item.children[0] assertEquals('status', status_el.name) 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) # 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 test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = {"txtvers": "1", "status": "avail"} self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") contact_name = "test-muc@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) requests_iface = dbus.Interface(conn, cs.CONN_IFACE_REQUESTS) # Create a connection to send the muc invite AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name=self_handle_name, protocol=avahi.PROTO_INET) service = e.service service.resolve() e = q.expect('service-resolved', service=service) outbound = connect_to_stream(q, contact_name, self_handle_name, str(e.pt), e.port) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection=outbound) # connected to Salut, now send the muc invite msg = domish.Element((None, 'message')) msg['to'] = self_handle_name msg['from'] = contact_name msg['type'] = 'normal' body = msg.addElement('body', content='You got a Clique chatroom invitation') invite = msg.addElement((NS_CLIQUE, 'invite')) invite.addElement('roomname', content='my-room') invite.addElement('reason', content='Inviting to this room') # FIXME: we should create a real Clique room and use its IP and port. # Hardcode values for now. The IP is a multicast address. invite.addElement('address', content='239.255.71.249') invite.addElement('port', content='62472') outbound.send(msg) e = q.expect('dbus-signal', signal='NewChannels', predicate=lambda e: e.args[0][0][1][cs.CHANNEL_TYPE] == cs. CHANNEL_TYPE_TEXT) channels = e.args[0] assert len(channels) == 1 path, props = channels[0] channel = make_channel_proxy(conn, path, "Channel") channel_group = make_channel_proxy(conn, path, "Channel.Interface.Group") # check channel properties # org.freedesktop.Telepathy.Channel D-Bus properties assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT assertContains(cs.CHANNEL_IFACE_GROUP, props[cs.INTERFACES]) assertContains(cs.CHANNEL_IFACE_MESSAGES, props[cs.INTERFACES]) assert props[cs.TARGET_ID] == 'my-room' assert props[cs.TARGET_HANDLE_TYPE] == HT_ROOM assert props[cs.REQUESTED] == False assert props[cs.INITIATOR_HANDLE] == handle assert props[cs.INITIATOR_ID] == contact_name # we are added to local pending e = q.expect('dbus-signal', signal='MembersChanged') msg, added, removed, lp, rp, actor, reason = e.args assert msg == 'Inviting to this room' assert added == [] assert removed == [] assert lp == [self_handle] assert rp == [] assert actor == handle assert reason == 4 # invited # TODO: join the muc, check if we are added to remote-pending and then # to members. This would need some tweak in Salut and/or the test framework # as Clique takes too much time to join the room and so the event times # out. # TODO: test sending invitations # FIXME: fd.o #30531: this ought to work, but doesn't #channel_group.RemoveMembersWithReason([self_handle], "bored now", 0) channel.Close() q.expect('dbus-signal', signal='Closed')
def test(q, bus, conn): # 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 ver = compute_caps_hash([], [CAP_NAME + '+notify'], {}) txt_record = { "txtvers": "1", "status": "avail", "node": CLIENT_NAME, "ver": ver, "hash": "sha-1"} contact_name = "test-status@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, txt_record) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) # this is the first presence, Salut connects to the contact e = q.expect('incoming-connection', listener=listener) incoming = e.connection # Salut looks up its capabilities event = q.expect('stream-iq', connection=incoming, query_ns=ns.DISCO_INFO) query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assertEquals(CLIENT_NAME + '#' + ver, query_node.attributes['node']) contact_handle = conn.RequestHandles(cs.HT_CONTACT, [contact_name])[0] # send good reply result = make_result_iq(event.stanza) query = result.firstChildElement() query['node'] = CLIENT_NAME + '#' + ver feature = query.addElement('feature') feature['var'] = CAP_NAME + '+notify' incoming.send(result) # 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, _, sig = q.expect_many(EventPattern('stream-message', connection=incoming), EventPattern('dbus-return', method='AdvertiseStatus'), EventPattern('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE)) # check message message = e.stanza event = message.children[0] items = event.children[0] item = items.children[0] status_el = item.children[0] assertEquals('status', status_el.name) assertEquals('messing-with-your-stuff', status_el['activity']) assertEquals('ants.in.their.pants', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) # 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({'testsuite@testsuite': {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, _, sig = q.expect_many(EventPattern('stream-message', connection=incoming), EventPattern('dbus-return', method='AdvertiseStatus'), EventPattern('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE)) # check message message = e.stanza event = message.children[0] items = event.children[0] item = items.children[0] status_el = item.children[0] assertEquals('status', status_el.name) assertEquals('rofling', status_el['activity']) assertEquals('bananaman.on.holiday', status_el['from-service']) assertEquals(CAP_NAME, status_el['capability']) # 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({'testsuite@testsuite': {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, _, sig = q.expect_many(EventPattern('stream-message', connection=incoming), EventPattern('dbus-return', method='AdvertiseStatus'), EventPattern('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE)) # check message message = e.stanza event = message.children[0] items = event.children[0] item = items.children[0] status_el = item.children[0] assertEquals('status', status_el.name) 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) # 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({'testsuite@testsuite': {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, _, sig = q.expect_many(EventPattern('stream-message', connection=incoming), EventPattern('dbus-return', method='AdvertiseStatus'), EventPattern('dbus-signal', signal='StatusChanged', interface=ycs.STATUS_IFACE)) # check message message = e.stanza event = message.children[0] items = event.children[0] item = items.children[0] status_el = item.children[0] assertEquals('status', status_el.name) 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) # 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 test(q, bus, conn): contact_name = "test-hct@" + get_host_name() call_async(q, conn.Future, 'EnsureSidecar', ycs.STATUS_IFACE) conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0, 0]) 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] AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name = self_handle_name, protocol = avahi.PROTO_INET) service = e.service service.resolve() q.expect('service-resolved', service=service) # now update the caps conn.ContactCapabilities.UpdateCapabilities([ ('well.gnome.name', [], ['org.freedesktop.ytstenut.xpmn.Channel/uid/org.gnome.Banshee', 'org.freedesktop.ytstenut.xpmn.Channel/type/application', 'org.freedesktop.ytstenut.xpmn.Channel/name/en_GB/Banshee Media Player', 'org.freedesktop.ytstenut.xpmn.Channel/name/fr/Banshee Lecteur de Musique', 'org.freedesktop.ytstenut.xpmn.Channel/caps/urn:ytstenut:capabilities:yts-caps-audio', 'org.freedesktop.ytstenut.xpmn.Channel/caps/urn:ytstenut:data:jingle:rtp'])]) e, _ = q.expect_many(EventPattern('service-resolved', service=service), EventPattern('dbus-signal', signal='ServiceAdded')) node = txt_get_key(e.txt, 'node') ver = txt_get_key(e.txt, 'ver') # don't check the hash here because it could change in salut and # it would break this test even though it wouldn't /actually/ be # broken outbound = connect_to_stream(q, contact_name, self_handle_name, str(e.pt), e.port) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection=outbound) # ask what this ver means request = \ elem_iq(outbound, 'get', from_=contact_name)( elem(ns.DISCO_INFO, 'query', node=(node + '#' + ver)) ) outbound.send(request) # receive caps e = q.expect('stream-iq', connection=outbound, query_ns=ns.DISCO_INFO, iq_id=request['id']) 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', [], ['org.freedesktop.ytstenut.xpmn.Channel/uid/org.gnome.Eog', 'org.freedesktop.ytstenut.xpmn.Channel/type/application', 'org.freedesktop.ytstenut.xpmn.Channel/name/en_GB/Eye Of Gnome', 'org.freedesktop.ytstenut.xpmn.Channel/name/it/Occhio Di uno Gnomo', 'org.freedesktop.ytstenut.xpmn.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({'testsuite@testsuite': {'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({'testsuite@testsuite': {'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 test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) basic_txt = { "txtvers": "1", "status": "avail" } self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") contact_name = "test-muc@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt) handle = wait_for_contact_in_publish(q, bus, conn, contact_name) requests_iface = dbus.Interface(conn, cs.CONN_IFACE_REQUESTS) # Create a connection to send the muc invite AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name = self_handle_name, protocol = avahi.PROTO_INET) service = e.service service.resolve() e = q.expect('service-resolved', service = service) outbound = connect_to_stream(q, contact_name, self_handle_name, str(e.pt), e.port) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection = outbound) # connected to Salut, now send the muc invite msg = domish.Element((None, 'message')) msg['to'] = self_handle_name msg['from'] = contact_name msg['type'] = 'normal' body = msg.addElement('body', content='You got a Clique chatroom invitation') invite = msg.addElement((NS_CLIQUE, 'invite')) invite.addElement('roomname', content='my-room') invite.addElement('reason', content='Inviting to this room') # FIXME: we should create a real Clique room and use its IP and port. # Hardcode values for now. The IP is a multicast address. invite.addElement('address', content='239.255.71.249') invite.addElement('port', content='62472') outbound.send(msg) e = q.expect('dbus-signal', signal='NewChannels', predicate=lambda e: e.args[0][0][1][cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT) channels = e.args[0] assert len(channels) == 1 path, props = channels[0] channel = make_channel_proxy(conn, path, "Channel") channel_group = make_channel_proxy(conn, path, "Channel.Interface.Group") # check channel properties # org.freedesktop.Telepathy.Channel D-Bus properties assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT assertContains(cs.CHANNEL_IFACE_GROUP, props[cs.INTERFACES]) assertContains(cs.CHANNEL_IFACE_MESSAGES, props[cs.INTERFACES]) assert props[cs.TARGET_ID] == 'my-room' assert props[cs.TARGET_HANDLE_TYPE] == HT_ROOM assert props[cs.REQUESTED] == False assert props[cs.INITIATOR_HANDLE] == handle assert props[cs.INITIATOR_ID] == contact_name # we are added to local pending e = q.expect('dbus-signal', signal='MembersChanged') msg, added, removed, lp, rp, actor, reason = e.args assert msg == 'Inviting to this room' assert added == [] assert removed == [] assert lp == [self_handle] assert rp == [] assert actor == handle assert reason == 4 # invited # TODO: join the muc, check if we are added to remote-pending and then # to members. This would need some tweak in Salut and/or the test framework # as Clique takes too much time to join the room and so the event times # out. # TODO: test sending invitations # FIXME: fd.o #30531: this ought to work, but doesn't #channel_group.RemoveMembersWithReason([self_handle], "bored now", 0) channel.Close() q.expect('dbus-signal', signal='Closed')
def test_ft_caps_from_contact(q, bus, conn, client): conn_caps_iface = dbus.Interface(conn, cs.CONN_IFACE_CONTACT_CAPS) conn_contacts_iface = dbus.Interface(conn, cs.CONN_IFACE_CONTACTS) # send presence with FT capa ver = compute_caps_hash([], [ns.IQ_OOB], {}) txt_record = { "txtvers": "1", "status": "avail", "node": client, "ver": ver, "hash": "sha-1"} contact_name = "test-caps-ft@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, txt_record) # this is the first presence, Salut connects to the contact e = q.expect('incoming-connection', listener = listener) incoming = e.connection # Salut looks up our capabilities event = q.expect('stream-iq', connection = incoming, query_ns='http://jabber.org/protocol/disco#info') query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assert query_node.attributes['node'] == \ client + '#' + ver, (query_node.attributes['node'], client, ver) contact_handle = conn_contacts_iface.GetContactByID(contact_name, [])[0] # send good reply result = make_result_iq(event.stanza) query = result.firstChildElement() query['node'] = client + '#' + ver feature = query.addElement('feature') feature['var'] = ns.IQ_OOB incoming.send(result) # FT capa is announced e = q.expect('dbus-signal', signal='ContactCapabilitiesChanged', predicate=lambda e: contact_handle in e.args[0]) caps = e.args[0][contact_handle] assertContains(ft_caps, caps) # check the Contacts interface give the same caps caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes( [contact_handle], [cs.CONN_IFACE_CONTACT_CAPS], False) \ [contact_handle][cs.CONN_IFACE_CONTACT_CAPS + '/capabilities'] assert caps_via_contacts_iface == caps, caps_via_contacts_iface # check if Salut announces the OOB capa self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") AvahiListener(q).listen_for_service("_presence._tcp") e = q.expect('service-added', name = self_handle_name, protocol = avahi.PROTO_INET) service = e.service service.resolve() receive_presence_and_ask_caps(q, incoming, service, contact_name) # capa announced without FT ver = compute_caps_hash([], ["http://telepathy.freedesktop.org/xmpp/pony"], {}) txt_record = { "txtvers": "1", "status": "avail", "node": client, "ver": ver, "hash": "sha-1"} contact_name = "test-caps-ft2@" + get_host_name() listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, txt_record) # this is the first presence, Salut connects to the contact e = q.expect('incoming-connection', listener = listener) incoming = e.connection # Salut looks up our capabilities event = q.expect('stream-iq', connection = incoming, query_ns='http://jabber.org/protocol/disco#info') query_node = xpath.queryForNodes('/iq/query', event.stanza)[0] assert query_node.attributes['node'] == \ client + '#' + ver, (query_node.attributes['node'], client, ver) contact_handle = conn_contacts_iface.GetContactByID(contact_name, [])[0] # send good reply result = make_result_iq(event.stanza) query = result.firstChildElement() query['node'] = client + '#' + ver feature = query.addElement('feature') feature['var'] = "http://telepathy.freedesktop.org/xmpp/pony" incoming.send(result) # the FT capability is not announced e = q.expect('dbus-signal', signal='ContactCapabilitiesChanged') caps = e.args[0][contact_handle] assertDoesNotContain(ft_caps, caps) # check the Contacts interface give the same caps caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes( [contact_handle], [cs.CONN_IFACE_CONTACT_CAPS], False) \ [contact_handle][cs.CONN_IFACE_CONTACT_CAPS + '/capabilities'] assert caps_via_contacts_iface == caps, caps_via_contacts_iface # no capabilites announced (assume FT is supported to insure interop) txt_record = { "txtvers": "1", "status": "avail"} contact_name = "test-caps-ft-no-capa2@" + get_host_name() contact_handle = conn_contacts_iface.GetContactByID(contact_name, [])[0] listener, port = setup_stream_listener(q, contact_name) announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, txt_record) # FT capa is announced e = q.expect('dbus-signal', signal='ContactCapabilitiesChanged', predicate=lambda e: contact_handle in e.args[0].keys()) caps = e.args[0][contact_handle] assertContains(ft_caps, caps) # check the Contacts interface give the same caps caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes( [contact_handle], [cs.CONN_IFACE_CONTACT_CAPS], False) \ [contact_handle][cs.CONN_IFACE_CONTACT_CAPS + '/capabilities'] assert caps_via_contacts_iface == caps, caps_via_contacts_iface
def test(q, bus, conn): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) activity_txt = { "type": "org.laptop.HelloMesh", "name": "HelloMesh", "color": "#7b83c1,#260993", "txtvers": "0", "activity-id": ACTIVITY_ID, "room": ACTIVITY_ID } # Listen for announcements l = AvahiListener(q).listen_for_service("_olpc-activity1._udp") # Assert that the testsuite doesn't announce the activity service_name = ACTIVITY_ID + ":" + TESTSUITE_PUBLISHED_NAME + "@" + get_host_name() forbiden_event = EventPattern('service-added', name=service_name) q.forbid_events([forbiden_event]) contact_name = PUBLISHED_NAME + "@" + get_host_name() activity_name = ACTIVITY_ID + ":" + PUBLISHED_NAME + "@" + get_host_name() AvahiAnnouncer(contact_name, "_presence._tcp", 1234, {}) act_hostname = ACTIVITY_ID + ":" + PUBLISHED_NAME + \ "._clique._udp." + get_domain_name() act_address = "239.253.70.70" announce_address(act_hostname, act_address) # FIXME, if we use the same name as the running salut will MembersChanged # isn't signalled later on, needs to be fixed. AvahiAnnouncer(ACTIVITY_ID + ":" + PUBLISHED_NAME, "_clique._udp", 12345, {}, hostname = act_hostname) AvahiAnnouncer(activity_name, "_olpc-activity1._udp", 0, activity_txt) # Publish a contact, now get it's handle handle = wait_for_contact_in_publish(q, bus, conn, contact_name) # Assert that the remote handles signals it joined the activity while True: e = q.expect('dbus-signal', signal = 'ActivitiesChanged') if e.args[0] == handle and e.args[1] != []: assert len(e.args[1]) == 1 assert e.args[1][0][0] == ACTIVITY_ID activity_handle = e.args[1][0][1] break act_prop_iface = dbus.Interface(conn, cs.ACTIVITY_PROPERTIES) act_properties = act_prop_iface.GetProperties(activity_handle) assert act_properties['private'] == False assert act_properties['color'] == activity_txt['color'] assert act_properties['name'] == activity_txt['name'] assert act_properties['type'] == activity_txt['type'] room_channel = conn.RequestChannel(CHANNEL_TYPE_TEXT, HT_ROOM, activity_handle, True) q.expect('dbus-signal', signal='MembersChanged', path=room_channel, args = [u'', [1L], [], [], [], 1L, 0L]) # Make it public that we joined the activity q.unforbid_events([forbiden_event]) buddy_info_iface = dbus.Interface(conn, cs.BUDDY_INFO) buddy_info_iface.SetActivities([(ACTIVITY_ID, activity_handle)]) q.expect('service-added', name = ACTIVITY_ID + ":" + TESTSUITE_PUBLISHED_NAME + "@" + get_host_name()) buddy_info_iface.SetActivities([]) q.expect('service-removed', name = ACTIVITY_ID + ":" + TESTSUITE_PUBLISHED_NAME + "@" + get_host_name())
def test(q, bus, conn): self_name = 'testsuite' + '@' + avahitest.get_host_name() conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L]) # FIXME: this is a hack to be sure to have all the contact list channels # announced so they won't interfere with the roomlist ones announces. wait_for_contact_list(q, conn) # check if we can request roomlist channels properties = conn.GetAll(tp_name_prefix + '.Connection.Interface.Requests', dbus_interface='org.freedesktop.DBus.Properties') assert ({tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_ROOM_LIST, tp_name_prefix + '.Channel.TargetHandleType': 0, }, [], ) in properties.get('RequestableChannelClasses'),\ properties['RequestableChannelClasses'] requestotron = dbus.Interface( conn, tp_name_prefix + '.Connection.Interface.Requests') # create roomlist channel using new API call_async( q, requestotron, 'CreateChannel', { tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_ROOM_LIST, tp_name_prefix + '.Channel.TargetHandleType': 0, }) ret, new_sig = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) path2 = ret.value[0] chan2 = wrap_channel(bus.get_object(conn.bus_name, path2), "RoomList") props = ret.value[1] assert props[tp_name_prefix + '.Channel.ChannelType'] ==\ cs.CHANNEL_TYPE_ROOM_LIST assert props[tp_name_prefix + '.Channel.TargetHandleType'] == 0 assert props[tp_name_prefix + '.Channel.TargetHandle'] == 0 assert props[tp_name_prefix + '.Channel.TargetID'] == '' assert props[tp_name_prefix + '.Channel.Requested'] == True assert props[tp_name_prefix + '.Channel.InitiatorHandle'] \ == conn.Properties.Get(cs.CONN, "SelfHandle") assert props[tp_name_prefix + '.Channel.InitiatorID'] \ == self_name assert props[tp_name_prefix + '.Channel.Type.RoomList.Server'] == '' assert new_sig.args[0][0][0] == path2 assert new_sig.args[0][0][1] == props assert chan2.Properties.Get(cs.CHANNEL_TYPE_ROOM_LIST, 'Server') == '' # ensure roomlist channel yours, ensured_path, ensured_props = requestotron.EnsureChannel({ tp_name_prefix + '.Channel.ChannelType': cs.CHANNEL_TYPE_ROOM_LIST, tp_name_prefix + '.Channel.TargetHandleType': 0, }) assert not yours assert ensured_path == path2, (ensured_path, path2) # Closing roomlist channels crashed Salut for a while. chan2.Close() q.expect_many( EventPattern('dbus-signal', signal='Closed', path=path2), EventPattern('dbus-signal', signal='ChannelClosed', args=[path2]), ) conn.Disconnect() q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[2, 1]), )