예제 #1
0
def expect_caps(q, conn, h):
    # we can now do audio and video calls
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged',
            predicate=lambda e: h in e.args[0]),
        )
    assert_rccs_callable(cc.args[0][h], require_video=True)
    check_caps(conn, h)
예제 #2
0
def expect_caps(q, conn, h):
    # we can now do audio and video calls
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged',
            predicate=lambda e: h in e.args[0]),
        )
    assert_rccs_callable(cc.args[0][h], require_video=True)
    check_caps(conn, h)
예제 #3
0
def test(q, bus, conn, stream):
    client = 'http://example.com/perverse-client'
    contact_bare_jid = '*****@*****.**'
    contact_with_resource = '[email protected]/hi'
    contact_handle = conn.get_contact_handle_sync(contact_bare_jid)

    # Gabble gets a presence stanza from a bare JID, which is a tad surprising.
    features = [
        ns.JINGLE_015,
        ns.JINGLE_015_AUDIO,
        ns.JINGLE_015_VIDEO,
        ns.GOOGLE_P2P,
    ]
    caps = {
        'node': client,
        'hash': 'sha-1',
        'ver': compute_caps_hash([], features, {}),
    }
    p = make_presence(contact_bare_jid, status='Hello', caps=caps)
    stream.send(p)

    # Gabble looks up the hash
    event = q.expect('stream-iq',
                     to=contact_bare_jid,
                     query_ns='http://jabber.org/protocol/disco#info')
    query_node = xpath.queryForNodes('/iq/query', event.stanza)[0]
    assertEquals(client + '#' + caps['ver'], query_node.attributes['node'])

    # The bare jid replies
    send_disco_reply(stream, event.stanza, [], features)

    # Gabble lets us know their caps have changed. (Gabble used to ignore the
    # reply.)
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'), )
    assert_rccs_callable(cc.args[0][contact_handle])

    # Gabble gets another presence stanza from the bare JID, with different
    # caps.
    features.append(ns.TUBES)
    caps = {
        'node': client,
        'hash': 'sha-1',
        'ver': compute_caps_hash([], features, {}),
    }
    p = make_presence(contact_bare_jid, status='Get out the abacus', caps=caps)
    stream.send(p)

    # Gabble looks up the new hash
    disco2 = q.expect('stream-iq',
                      to=contact_bare_jid,
                      query_ns='http://jabber.org/protocol/disco#info')
    query_node = xpath.queryForNodes('/iq/query', disco2.stanza)[0]
    assertEquals(client + '#' + caps['ver'], query_node.attributes['node'])

    # This time, before the bare JID replies, Gabble gets a presence from the
    # resourceful jid.
    features_ = features + [ns.CHAT_STATES]
    caps = {
        'node': client,
        'hash': 'sha-1',
        'ver': compute_caps_hash([], features_, {}),
    }
    p = make_presence(contact_with_resource, status='Count this', caps=caps)
    stream.send(p)

    # Gabble throws away presence from the bare JID when it gets presence from
    # a resource (and vice versa), so it should now say the contact is
    # incapable.  Gabble also looks up the resourceful JID's hash.
    cc, disco3 = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
        EventPattern('stream-iq',
                     to=contact_with_resource,
                     query_ns='http://jabber.org/protocol/disco#info'),
    )

    assert_rccs_not_callable(cc.args[0][contact_handle])

    query_node = xpath.queryForNodes('/iq/query', disco3.stanza)[0]
    assertEquals(client + '#' + caps['ver'], query_node.attributes['node'])

    # The bare jid replies! Getting a disco reply from a bare JID when we've
    # got presence from resources used to crash Gabble, but now it just ignores
    # it.
    send_disco_reply(stream, disco2.stanza, [], features)

    # Now the resourceful JID replies:
    send_disco_reply(stream, disco3.stanza, [], features_)

    # Gabble should announce that the contact has acquired some caps.
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'), )
    assert_rccs_callable(cc.args[0][contact_handle])
예제 #4
0
def test_hash(q, bus, conn, stream, contact, contact_handle, client):
    presence = make_presence(contact, status='hello')
    stream.send(presence)

    q.expect('dbus-signal', signal='PresencesChanged',
            args=[{contact_handle:
                (2, u'available', 'hello')}])

    # no special capabilities
    for rcc in get_contacts_capabilities_sync(conn, [contact_handle])[contact_handle]:
        assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))

    # send updated presence with Jingle caps info
    presence = make_presence(contact, status='hello',
        caps={'node': client,
              'ver':  '0.1',
             })
    stream.send(presence)

    # Gabble looks up our capabilities
    event = q.expect('stream-iq', to=contact,
        query_ns='http://jabber.org/protocol/disco#info')
    query_node = xpath.queryForNodes('/iq/query', event.stanza)[0]
    assert query_node.attributes['node'] == \
        client + '#' + '0.1'

    # send good reply
    send_disco_reply(stream, event.stanza, [], jingle_av_features)

    # we can now do audio calls
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
        )

    assert_rccs_callable(cc.args[0][contact_handle])
    assertEquals(cc.args[0],
            get_contacts_capabilities_sync(conn, [contact_handle]))

    # Send presence without any capabilities. XEP-0115 §8.4 Caps Optimization
    # says “receivers of presence notifications MUST NOT expect an annotation
    # on every presence notification they receive”, so the contact should still
    # be media-capable afterwards.
    stream.send(make_presence(contact, status='very capable'))
    q.expect('dbus-signal', signal='PresencesChanged',
        args=[{contact_handle: (2, u'available', 'very capable')}])
    # still exactly the same capabilities
    assertEquals(cc.args[0],
            get_contacts_capabilities_sync(conn, [contact_handle]))

    # send bogus presence
    caps = {
        'node': client,
        'ver':  'ceci=nest=pas=un=hash',
        'hash': 'sha-1',
        }
    presence = make_presence(contact, status='hello', caps=caps)
    stream.send(presence)

    # Gabble looks up our capabilities
    event = q.expect('stream-iq', to=contact,
        query_ns='http://jabber.org/protocol/disco#info')
    query_node = xpath.queryForNodes('/iq/query', event.stanza)[0]
    assert query_node.attributes['node'] == \
        client + '#' + caps['ver']

    # send bogus reply
    send_disco_reply(stream, event.stanza, [],
        ['http://jabber.org/protocol/bogus-feature'])

    # don't receive any D-Bus signal
    forbidden = [
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
        ]
    q.forbid_events(forbidden)
    sync_dbus(bus, q, conn)
    sync_stream(q, stream)

    # send presence with empty caps
    presence = make_presence(contact, status='hello',
        caps={'node': client,
              'ver':  '0.0',
             })
    stream.send(presence)

    # Gabble looks up our capabilities
    event = q.expect('stream-iq', to=contact,
        query_ns='http://jabber.org/protocol/disco#info')
    query_node = xpath.queryForNodes('/iq/query', event.stanza)[0]
    assert query_node.attributes['node'] == \
        client + '#' + '0.0'

    # still don't receive any D-Bus signal
    sync_dbus(bus, q, conn)

    # send good reply
    q.unforbid_events(forbidden)
    result = make_result_iq(stream, event.stanza)
    query = result.firstChildElement()
    stream.send(result)

    # we can now do nothing
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
        )
    for rcc in cc.args[0][contact_handle]:
        assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))
    assert_rccs_not_callable(cc.args[0][contact_handle])
    assertEquals(cc.args[0],
            get_contacts_capabilities_sync(conn, [contact_handle]))

    # send correct presence
    ver = compute_caps_hash(some_identities, jingle_av_features, fake_client_dataforms)
    caps = {
        'node': client,
        'ver':  ver,
        'hash': 'sha-1',
        }
    presence = make_presence(contact, status='hello', caps=caps)
    stream.send(presence)

    # Gabble looks up our capabilities
    event = q.expect('stream-iq', to=contact,
        query_ns='http://jabber.org/protocol/disco#info')
    query_node = xpath.queryForNodes('/iq/query', event.stanza)[0]
    assert query_node.attributes['node'] == \
        client + '#' + caps['ver']

    # don't receive any D-Bus signal
    q.forbid_events(forbidden)
    sync_dbus(bus, q, conn)
    q.unforbid_events(forbidden)

    # send good reply
    send_disco_reply(
        stream, event.stanza, some_identities, jingle_av_features, fake_client_dataforms)

    # we can now do audio calls
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
        )
    assert_rccs_callable(cc.args[0][contact_handle])
    assertEquals(cc.args[0],
            get_contacts_capabilities_sync(conn, [contact_handle]))
예제 #5
0
def test_two_clients(q, bus, conn, stream, contact1, contact2,
        contact_handle1, contact_handle2, client, broken_hash):

    presence = make_presence(contact1, status='hello')
    stream.send(presence)

    q.expect('dbus-signal', signal='PresencesChanged',
            args=[{contact_handle1:
                (2, u'available', 'hello')}])

    presence = make_presence(contact2, status='hello')
    stream.send(presence)

    q.expect('dbus-signal', signal='PresencesChanged',
            args=[{contact_handle2:
                (2, u'available', 'hello')}])

    # no special capabilities
    for h in (contact_handle1, contact_handle2):
        for rcc in get_contacts_capabilities_sync(conn, [h])[h]:
            assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))

    # send updated presence with Jingle caps info
    ver = compute_caps_hash(some_identities, jingle_av_features, {})
    caps = {
        'node': client,
        'ver': ver,
        'hash': 'sha-1',
        }
    presence = make_presence(contact1, status='hello', caps=caps)
    stream.send(presence)
    presence = make_presence(contact2, status='hello', caps=caps)
    stream.send(presence)

    # Gabble looks up our capabilities
    event = q.expect('stream-iq', to=contact1,
        query_ns='http://jabber.org/protocol/disco#info')
    query_node = xpath.queryForNodes('/iq/query', event.stanza)[0]
    assert query_node.attributes['node'] == \
        client + '#' + ver

    # don't receive any D-Bus signal
    forbidden = [
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
        ]
    q.forbid_events(forbidden)
    sync_dbus(bus, q, conn)
    q.unforbid_events(forbidden)

    result = make_caps_disco_reply(
        stream, event.stanza, some_identities, jingle_av_features)

    if broken_hash:
        # make the hash break!
        query = result.firstChildElement()
        query.addElement('feature')['var'] = 'http://example.com/another-feature'

    stream.send(result)

    if broken_hash:
        # Gabble looks up our capabilities again because the first contact
        # failed to provide a valid hash
        event = q.expect('stream-iq', to=contact2,
            query_ns='http://jabber.org/protocol/disco#info')
        query_node = xpath.queryForNodes('/iq/query', event.stanza)[0]
        assert query_node.attributes['node'] == \
            client + '#' + ver

        # don't receive any D-Bus signal
        q.forbid_events(forbidden)
        sync_dbus(bus, q, conn)
        q.unforbid_events(forbidden)

        # send good reply
        send_disco_reply(stream, event.stanza, some_identities, jingle_av_features)

    # we can now do audio calls
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged',
            predicate=lambda e: contact_handle2 in e.args[0]),
        )
    assert_rccs_callable(cc.args[0][contact_handle2])

    if not broken_hash:
        # if the first contact failed to provide a good hash, it does not
        # deserve its capabilities to be understood by Gabble!
        cc, = q.expect_many(
            EventPattern('dbus-signal', signal='ContactCapabilitiesChanged',
                predicate=lambda e: contact_handle1 in e.args[0]),
            )
        assert_rccs_callable(cc.args[0][contact_handle1])

    # don't receive any further signals
    q.forbid_events(forbidden)
    sync_dbus(bus, q, conn)
    q.unforbid_events(forbidden)
예제 #6
0
def test(q, bus, conn, stream):
    bob = conn.get_contact_handle_sync('*****@*****.**')

    presence = make_presence('[email protected]/Foo', status='hello')
    stream.send(presence)

    q.expect('dbus-signal', signal='PresencesChanged',
           args=[{bob: (cs.PRESENCE_AVAILABLE, u'available', 'hello')}])

    basic_caps = [(bob, cs.CHANNEL_TYPE_TEXT, 3, 0)]

    # only Text
    for rcc in get_contacts_capabilities_sync(conn, [bob])[bob]:
        assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))

    # holding the handle here: see below
    assertEquals(
            { bob: {
                cs.ATTR_CONTACT_CAPABILITIES:
                    get_contacts_capabilities_sync(conn, [bob])[bob],
                cs.CONN + '/contact-id': '*****@*****.**',
                },
            },
            conn.Contacts.GetContactAttributes([bob], [cs.CONN_IFACE_CONTACT_CAPS], True))

    # send updated presence with Jingle audio/video caps info. we turn on both
    # audio and video at the same time to test that all of the capabilities are
    # discovered before any capabilities change signal is emitted
    presence = make_presence('[email protected]/Foo', status='hello',
        caps={
            'node': 'http://telepathy.freedesktop.org/fake-client',
            'ver' : '0.1',
            'ext' : 'video',
        })
    stream.send(presence)

    # Gabble looks up both the version and the video bundles, in any order
    (version_event, video_event) = q.expect_many(
        EventPattern('stream-iq', to='[email protected]/Foo',
            query_ns='http://jabber.org/protocol/disco#info',
            query_node='http://telepathy.freedesktop.org/fake-client#0.1'),
        EventPattern('stream-iq', to='[email protected]/Foo',
            query_ns='http://jabber.org/protocol/disco#info',
            query_node='http://telepathy.freedesktop.org/fake-client#video'))

    # reply to the video bundle query first - this capability alone is not
    # sufficient to make us callable
    result = make_result_iq(stream, video_event.stanza)
    query = result.firstChildElement()
    feature = query.addElement('feature')
    feature['var'] = 'http://jabber.org/protocol/jingle/description/video'
    stream.send(result)

    # reply to the version bundle query, which should make us audio and
    # video callable
    result = make_result_iq(stream, version_event.stanza)
    query = result.firstChildElement()
    feature = query.addElement('feature')
    feature['var'] = 'http://jabber.org/protocol/jingle'
    feature = query.addElement('feature')
    feature['var'] = 'http://jabber.org/protocol/jingle/description/audio'
    feature = query.addElement('feature')
    feature['var'] = 'http://www.google.com/transport/p2p'
    stream.send(result)

    # we can now do audio and video calls
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged',
            predicate=lambda e: check_rccs_callable(e.args[0][bob])),
        )
    assert_rccs_callable(cc.args[0][bob], require_video=True,
            mutable_contents=True)

    assertEquals(
            { bob: {
                cs.ATTR_CONTACT_CAPABILITIES:
                    cc.args[0][bob],
                cs.CONN + '/contact-id': '*****@*****.**',
                },
            },
            conn.Contacts.GetContactAttributes([bob],
                [cs.CONN_IFACE_CONTACT_CAPS], True))

    # send updated presence without video support
    presence = make_presence('[email protected]/Foo', status='hello',
        caps={
            'node': 'http://telepathy.freedesktop.org/fake-client',
            'ver' : '0.1',
        })
    stream.send(presence)

    # we can now do only audio calls (and as a result have the ImmutableStreams
    # cap)
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
        )
    assert_rccs_callable(cc.args[0][bob])
    assert_rccs_not_callable(cc.args[0][bob], require_audio=False,
            require_video=True, mutable_contents=False)

    assertEquals(
            { bob: {
                cs.ATTR_CONTACT_CAPABILITIES:
                    cc.args[0][bob],
                cs.CONN + '/contact-id': '*****@*****.**',
                },
            },
            conn.Contacts.GetContactAttributes([bob],
                [cs.CONN_IFACE_CONTACT_CAPS], True))

    # go offline
    presence = make_presence('[email protected]/Foo', type='unavailable')
    stream.send(presence)

    # can't do audio calls any more
    q.expect_many(
            EventPattern('dbus-signal', signal='PresencesChanged',
                args=[{bob: (cs.PRESENCE_OFFLINE, 'offline', '')}]),
            EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
            )

    # Contact went offline. Previously, this test asserted that the handle
    # became invalid, but that's not guaranteed to happen immediately; so we
    # now hold the handle (above), to guarantee that it does *not* become
    # invalid.
    rccs = get_contacts_capabilities_sync(conn, [bob])[bob]
    for rcc in rccs:
        assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))

    assertEquals(
            { bob: {
                cs.ATTR_CONTACT_CAPABILITIES: rccs,
                cs.CONN + '/contact-id': '*****@*****.**',
                },
            },
            conn.Contacts.GetContactAttributes([bob],
                [cs.CONN_IFACE_CONTACT_CAPS], True))

    # What about a handle that's not valid?
    assertEquals({}, conn.Contacts.GetContactAttributes(
        [31337], [cs.CONN_IFACE_CONTACT_CAPS], False))
예제 #7
0
def test(q, bus, conn, stream):
    bob = conn.get_contact_handle_sync('*****@*****.**')

    presence = make_presence('[email protected]/Foo', status='hello')
    stream.send(presence)

    q.expect('dbus-signal',
             signal='PresencesChanged',
             args=[{
                 bob: (cs.PRESENCE_AVAILABLE, u'available', 'hello')
             }])

    basic_caps = [(bob, cs.CHANNEL_TYPE_TEXT, 3, 0)]

    # only Text
    for rcc in get_contacts_capabilities_sync(conn, [bob])[bob]:
        assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))

    # holding the handle here: see below
    assertEquals(
        {
            bob: {
                cs.ATTR_CONTACT_CAPABILITIES:
                get_contacts_capabilities_sync(conn, [bob])[bob],
                cs.CONN + '/contact-id':
                '*****@*****.**',
            },
        },
        conn.Contacts.GetContactAttributes([bob], [cs.CONN_IFACE_CONTACT_CAPS],
                                           True))

    # send updated presence with Jingle audio/video caps info. we turn on both
    # audio and video at the same time to test that all of the capabilities are
    # discovered before any capabilities change signal is emitted
    presence = make_presence(
        '[email protected]/Foo',
        status='hello',
        caps={
            'node': 'http://telepathy.freedesktop.org/fake-client',
            'ver': '0.1',
            'ext': 'video',
        })
    stream.send(presence)

    # Gabble looks up both the version and the video bundles, in any order
    (version_event, video_event) = q.expect_many(
        EventPattern(
            'stream-iq',
            to='[email protected]/Foo',
            query_ns='http://jabber.org/protocol/disco#info',
            query_node='http://telepathy.freedesktop.org/fake-client#0.1'),
        EventPattern(
            'stream-iq',
            to='[email protected]/Foo',
            query_ns='http://jabber.org/protocol/disco#info',
            query_node='http://telepathy.freedesktop.org/fake-client#video'))

    # reply to the video bundle query first - this capability alone is not
    # sufficient to make us callable
    result = make_result_iq(stream, video_event.stanza)
    query = result.firstChildElement()
    feature = query.addElement('feature')
    feature['var'] = 'http://jabber.org/protocol/jingle/description/video'
    stream.send(result)

    # reply to the version bundle query, which should make us audio and
    # video callable
    result = make_result_iq(stream, version_event.stanza)
    query = result.firstChildElement()
    feature = query.addElement('feature')
    feature['var'] = 'http://jabber.org/protocol/jingle'
    feature = query.addElement('feature')
    feature['var'] = 'http://jabber.org/protocol/jingle/description/audio'
    feature = query.addElement('feature')
    feature['var'] = 'http://www.google.com/transport/p2p'
    stream.send(result)

    # we can now do audio and video calls
    cc, = q.expect_many(
        EventPattern(
            'dbus-signal',
            signal='ContactCapabilitiesChanged',
            predicate=lambda e: check_rccs_callable(e.args[0][bob])), )
    assert_rccs_callable(cc.args[0][bob],
                         require_video=True,
                         mutable_contents=True)

    assertEquals(
        {
            bob: {
                cs.ATTR_CONTACT_CAPABILITIES: cc.args[0][bob],
                cs.CONN + '/contact-id': '*****@*****.**',
            },
        },
        conn.Contacts.GetContactAttributes([bob], [cs.CONN_IFACE_CONTACT_CAPS],
                                           True))

    # send updated presence without video support
    presence = make_presence(
        '[email protected]/Foo',
        status='hello',
        caps={
            'node': 'http://telepathy.freedesktop.org/fake-client',
            'ver': '0.1',
        })
    stream.send(presence)

    # we can now do only audio calls (and as a result have the ImmutableStreams
    # cap)
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'), )
    assert_rccs_callable(cc.args[0][bob])
    assert_rccs_not_callable(cc.args[0][bob],
                             require_audio=False,
                             require_video=True,
                             mutable_contents=False)

    assertEquals(
        {
            bob: {
                cs.ATTR_CONTACT_CAPABILITIES: cc.args[0][bob],
                cs.CONN + '/contact-id': '*****@*****.**',
            },
        },
        conn.Contacts.GetContactAttributes([bob], [cs.CONN_IFACE_CONTACT_CAPS],
                                           True))

    # go offline
    presence = make_presence('[email protected]/Foo', type='unavailable')
    stream.send(presence)

    # can't do audio calls any more
    q.expect_many(
        EventPattern('dbus-signal',
                     signal='PresencesChanged',
                     args=[{
                         bob: (cs.PRESENCE_OFFLINE, 'offline', '')
                     }]),
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
    )

    # Contact went offline. Previously, this test asserted that the handle
    # became invalid, but that's not guaranteed to happen immediately; so we
    # now hold the handle (above), to guarantee that it does *not* become
    # invalid.
    rccs = get_contacts_capabilities_sync(conn, [bob])[bob]
    for rcc in rccs:
        assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))

    assertEquals(
        {
            bob: {
                cs.ATTR_CONTACT_CAPABILITIES: rccs,
                cs.CONN + '/contact-id': '*****@*****.**',
            },
        },
        conn.Contacts.GetContactAttributes([bob], [cs.CONN_IFACE_CONTACT_CAPS],
                                           True))

    # What about a handle that's not valid?
    assertEquals({},
                 conn.Contacts.GetContactAttributes(
                     [31337], [cs.CONN_IFACE_CONTACT_CAPS], False))
예제 #8
0
def check_caps(conn, h):
    caps = get_contacts_capabilities_sync(conn, [h])
    assert_rccs_callable(caps[h], require_video=True)
예제 #9
0
def test(q, bus, conn, stream):
    client = 'http://example.com/perverse-client'
    contact_bare_jid = '*****@*****.**'
    contact_with_resource = '[email protected]/hi'
    contact_handle = conn.get_contact_handle_sync(contact_bare_jid)

    # Gabble gets a presence stanza from a bare JID, which is a tad surprising.
    features = [
        ns.JINGLE_015,
        ns.JINGLE_015_AUDIO,
        ns.JINGLE_015_VIDEO,
        ns.GOOGLE_P2P,
        ]
    caps = {'node': client,
            'hash': 'sha-1',
            'ver': compute_caps_hash([], features, {}),
           }
    p = make_presence(contact_bare_jid, status='Hello', caps=caps)
    stream.send(p)

    # Gabble looks up the hash
    event = q.expect('stream-iq', to=contact_bare_jid,
        query_ns='http://jabber.org/protocol/disco#info')
    query_node = xpath.queryForNodes('/iq/query', event.stanza)[0]
    assertEquals(client + '#' + caps['ver'], query_node.attributes['node'])

    # The bare jid replies
    send_disco_reply(stream, event.stanza, [], features)

    # Gabble lets us know their caps have changed. (Gabble used to ignore the
    # reply.)
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
        )
    assert_rccs_callable(cc.args[0][contact_handle])

    # Gabble gets another presence stanza from the bare JID, with different
    # caps.
    features.append(ns.TUBES)
    caps = {'node': client,
            'hash': 'sha-1',
            'ver': compute_caps_hash([], features, {}),
           }
    p = make_presence(contact_bare_jid, status='Get out the abacus', caps=caps)
    stream.send(p)

    # Gabble looks up the new hash
    disco2 = q.expect('stream-iq', to=contact_bare_jid,
        query_ns='http://jabber.org/protocol/disco#info')
    query_node = xpath.queryForNodes('/iq/query', disco2.stanza)[0]
    assertEquals(client + '#' + caps['ver'], query_node.attributes['node'])

    # This time, before the bare JID replies, Gabble gets a presence from the
    # resourceful jid.
    features_ = features + [ns.CHAT_STATES]
    caps = {'node': client,
            'hash': 'sha-1',
            'ver': compute_caps_hash([], features_, {}),
           }
    p = make_presence(contact_with_resource, status='Count this', caps=caps)
    stream.send(p)

    # Gabble throws away presence from the bare JID when it gets presence from
    # a resource (and vice versa), so it should now say the contact is
    # incapable.  Gabble also looks up the resourceful JID's hash.
    cc, disco3 = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
        EventPattern('stream-iq', to=contact_with_resource,
            query_ns='http://jabber.org/protocol/disco#info'),
        )

    assert_rccs_not_callable(cc.args[0][contact_handle])

    query_node = xpath.queryForNodes('/iq/query', disco3.stanza)[0]
    assertEquals(client + '#' + caps['ver'], query_node.attributes['node'])

    # The bare jid replies! Getting a disco reply from a bare JID when we've
    # got presence from resources used to crash Gabble, but now it just ignores
    # it.
    send_disco_reply(stream, disco2.stanza, [], features)

    # Now the resourceful JID replies:
    send_disco_reply(stream, disco3.stanza, [], features_)

    # Gabble should announce that the contact has acquired some caps.
    cc, = q.expect_many(
        EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
        )
    assert_rccs_callable(cc.args[0][contact_handle])
def capabilities_changed(q, contact_handle):
    e = q.expect('dbus-signal', signal='ContactCapabilitiesChanged')
    assertContains(contact_handle, e.args[0])
    assert_rccs_callable(e.args[0][contact_handle], require_video=True)
    assertContains(xiangqi_tube_cap, e.args[0][contact_handle])
예제 #11
0
def check_caps(conn, h):
    caps = get_contacts_capabilities_sync(conn, [h])
    assert_rccs_callable(caps[h], require_video=True)
def capabilities_changed(q, contact_handle):
    e = q.expect('dbus-signal', signal='ContactCapabilitiesChanged')
    assertContains(contact_handle, e.args[0])
    assert_rccs_callable(e.args[0][contact_handle], require_video=True)
    assertContains(xiangqi_tube_cap, e.args[0][contact_handle])