def test(q, bus, conn, stream, image_data, mime_type):
    call_async(q, conn.Avatars, 'SetAvatar', image_data, mime_type)

    expect_and_handle_get_vcard(q, stream)

    def check(vcard):
        assertEquals(mime_type, xpath.queryForString('/vCard/PHOTO/TYPE',
                                                     vcard))

        binval = xpath.queryForString('/vCard/PHOTO/BINVAL', vcard)

        # <http://xmpp.org/extensions/xep-0153.html#bizrules-image> says:
        #
        #  5. The image data MUST conform to the base64Binary datatype and thus
        #     be encoded in accordance with Section 6.8 of RFC 2045, which
        #     recommends that base64 data should have lines limited to at most
        #     76 characters in length.
        lines = binval.split('\n')
        for line in lines:
            assert len(line) <= 76, line

        assertEquals(image_data, base64.decodestring(binval))

    expect_and_handle_set_vcard(q, stream, check=check)

    q.expect('dbus-return', method='SetAvatar')
def test(q, bus, conn, stream):
    self_handle = conn.GetSelfHandle()
    conn.Aliasing.SetAliases({self_handle: 'lala'})
    expect_and_handle_get_vcard(q, stream)

    pep_update = q.expect('stream-iq', iq_type='set', query_ns=ns.PUBSUB, query_name='pubsub')
    validate_pep_update(pep_update, 'lala')
    acknowledge_iq(stream, pep_update.stanza)

    def check(vCard):
        nickname = vCard.elements(uri=ns.VCARD_TEMP, name='NICKNAME').next()
        assertEquals('lala', nickname.children[0])
    expect_and_handle_set_vcard(q, stream, check=check)

    event = q.expect('dbus-signal', signal='AliasesChanged',
        args=[[(self_handle, u'lala')]])

    conn.Aliasing.SetAliases({self_handle: ''})
    pep_update = q.expect('stream-iq', iq_type='set', query_ns=ns.PUBSUB, query_name='pubsub')
    validate_pep_update(pep_update, None)

    expect_and_handle_get_vcard(q, stream)
    def check(vCard):
        # The vCard should be empty, rather than having an empty <NICKNAME/>
        # element.
        assertLength(0, vCard.children)
    expect_and_handle_set_vcard(q, stream, check=check)

    event = q.expect('dbus-signal', signal='AliasesChanged',
        args=[[(self_handle, u'test@localhost')]])
def test(q, bus, conn, stream):
    expect_and_handle_get_vcard(q, stream)
    sync_stream(q, stream)

    call_async(q, conn.Avatars, 'SetAvatar', b'william shatner',
               'image/x-actor-name')
    # Gabble request the last version of the vCard before changing it
    expect_and_handle_get_vcard(q, stream)

    set_vcard_event = q.expect('stream-iq',
                               query_ns=ns.VCARD_TEMP,
                               query_name='vCard',
                               iq_type='set')
    iq = set_vcard_event.stanza

    error = domish.Element((None, 'error'))
    error['code'] = '400'
    error['type'] = 'modify'
    error.addElement((ns.STANZA, 'bad-request'))

    send_error_reply(stream, iq, error)

    event = q.expect('dbus-error', method='SetAvatar')

    assert event.error.get_dbus_name() == cs.INVALID_ARGUMENT, \
        event.error.get_dbus_name()
def test(q, bus, conn, stream, image_data, mime_type):
    call_async(q, conn.Avatars, 'SetAvatar', image_data, mime_type)

    expect_and_handle_get_vcard(q, stream)

    def check(vcard):
        assertEquals(mime_type,
            xpath.queryForString('/vCard/PHOTO/TYPE', vcard))

        binval = xpath.queryForString('/vCard/PHOTO/BINVAL', vcard)

        # <http://xmpp.org/extensions/xep-0153.html#bizrules-image> says:
        #
        #  5. The image data MUST conform to the base64Binary datatype and thus
        #     be encoded in accordance with Section 6.8 of RFC 2045, which
        #     recommends that base64 data should have lines limited to at most
        #     76 characters in length.
        lines = binval.split('\n')
        for line in lines:
            assert len(line) <= 76, line

        assertEquals(image_data, base64.decodestring(binval))

    expect_and_handle_set_vcard(q, stream, check=check)

    q.expect('dbus-return', method='SetAvatar')
def test(q, bus, conn, stream):
    conn.Connect()

    expect_and_handle_get_vcard(q, stream)
    sync_stream(q, stream)

    call_async(q, conn.Avatars, 'SetAvatar', 'william shatner',
        'image/x-actor-name')
    # Gabble request the last version of the vCard before changing it
    expect_and_handle_get_vcard(q, stream)

    set_vcard_event = q.expect('stream-iq', query_ns=ns.VCARD_TEMP,
        query_name='vCard', iq_type='set')
    iq = set_vcard_event.stanza

    error = domish.Element((None, 'error'))
    error['code'] = '400'
    error['type'] = 'modify'
    error.addElement((ns.STANZA, 'bad-request'))

    send_error_reply(stream, iq, error)

    event = q.expect('dbus-error', method='SetAvatar')

    assert event.error.get_dbus_name() == cs.INVALID_ARGUMENT, \
        event.error.get_dbus_name()
Exemple #6
0
def test(q, bus, conn, stream):
    expect_and_handle_get_vcard(q, stream)

    self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
    conn.Aliasing.SetAliases({self_handle: 'lala'})

    expect_and_handle_set_vcard(q, stream)

    event = q.expect('dbus-signal',
                     signal='AliasesChanged',
                     args=[[(self_handle, u'lala')]])

    room_jid = '*****@*****.**'

    # muc stream tube
    call_async(
        q, conn.Requests, 'CreateChannel', {
            cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
            cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
            cs.TARGET_ID: room_jid
        })

    gfc, _, _ = q.expect_many(
        EventPattern('dbus-signal', signal='GroupFlagsChanged'),
        EventPattern(
            'dbus-signal',
            signal='MembersChangedDetailed',
            predicate=lambda e: e.args[0] == [] and  # added
            e.args[1] == [] and  # removed
            e.args[2] == [] and  # local pending
            len(e.args[3]) == 1 and  # remote pending
            e.args[4].get('actor', 0) == 0 and e.args[4].get(
                'change-reason', 0) == 0 and e.args[4]['contact-ids'][e.args[
                    3][0]] == '[email protected]/lala'),
        EventPattern('stream-presence', to='%s/lala' % room_jid))
    assert gfc.args[1] == 0

    # Send presence for other member of room.
    stream.send(make_muc_presence('owner', 'moderator', room_jid, 'bob'))

    # Send presence for own membership of room.
    stream.send(make_muc_presence('none', 'participant', room_jid, 'lala'))

    event = q.expect(
        'dbus-signal',
        signal='MembersChangedDetailed',
        predicate=lambda e: len(e.args[0]) == 2 and  # added
        e.args[1] == [] and  # removed
        e.args[2] == [] and  # local pending
        e.args[3] == [] and  # remote pending
        e.args[4].get('actor', 0) == 0 and e.args[4].get('change-reason', 0) ==
        0 and set([e.args[4]['contact-ids'][h] for h in e.args[0]]) == set(
            ['[email protected]/lala', '[email protected]/bob']))

    event = q.expect('dbus-return', method='CreateChannel')
def test(q, bus, conn, stream):
    expect_and_handle_get_vcard(q, stream)

    def check_vcard(vcard):
        for e in vcard.elements():
            if e.name == 'NICKNAME':
                assert str(e) == 'Some Guy', e.toXml()
                return
        assert False, vcard.toXml()

    expect_and_handle_set_vcard(q, stream, check_vcard)
def test(q, bus, conn, stream):
    expect_and_handle_get_vcard(q, stream)

    def check_vcard(vcard):
        for e in vcard.elements():
            if e.name == 'NICKNAME':
                assert str(e) == 'Some Guy', e.toXml()
                return
        assert False, vcard.toXml()

    expect_and_handle_set_vcard(q, stream, check_vcard)
def test(q, bus, conn, stream):
    expect_and_handle_get_vcard(q, stream)

    # Ensure that Gabble's actually got the initial vCard reply; if it hasn't
    # processed it by the time we call SetAliases, the latter will wait for it
    # to reply and then set immediately.
    sync_stream(q, stream)

    handle = conn.Properties.Get(cs.CONN, "SelfHandle")

    call_async(q, conn.Aliasing, 'SetAliases', {handle: 'Some Guy'})

    # SetAliases requests vCard v1
    get_vcard_event = q.expect('stream-iq',
                               query_ns=ns.VCARD_TEMP,
                               query_name='vCard',
                               iq_type='get')

    iq = get_vcard_event.stanza
    vcard = iq.firstChildElement()
    assert vcard.name == 'vCard', vcard.toXml()

    call_async(q, conn.Avatars, 'SetAvatar', 'hello', 'image/png')

    # We don't expect Gabble to send a second vCard request, since there's one
    # outstanding. But we want to ensure that SetAvatar reaches Gabble before
    # the empty vCard does.
    sync_dbus(bus, q, conn)

    # Send back current empty vCard
    result = make_result_iq(stream, iq)
    # result already includes the <vCard/> from the query, which is all we need
    stream.send(result)

    def has_nickname_and_photo(vcard):
        nicknames = xpath.queryForNodes('/vCard/NICKNAME', vcard)
        assert nicknames is not None
        assert len(nicknames) == 1
        assert str(nicknames[0]) == 'Some Guy'

        photos = xpath.queryForNodes('/vCard/PHOTO', vcard)
        assert photos is not None and len(photos) == 1, repr(photos)
        types = xpath.queryForNodes('/PHOTO/TYPE', photos[0])
        binvals = xpath.queryForNodes('/PHOTO/BINVAL', photos[0])
        assert types is not None and len(types) == 1, repr(types)
        assert binvals is not None and len(binvals) == 1, repr(binvals)
        assert str(types[0]) == 'image/png'
        got = str(binvals[0]).strip()
        exp = base64.b64encode('hello')
        assertEquals(exp, got)

    # Now Gabble should set a new vCard with both of the above changes.
    expect_and_handle_set_vcard(q, stream, has_nickname_and_photo)
def test(q, bus, conn, stream):
    conn.Connect()

    expect_and_handle_get_vcard(q, stream)

    # Ensure that Gabble's actually got the initial vCard reply; if it hasn't
    # processed it by the time we call SetAliases, the latter will wait for it
    # to reply and then set immediately.
    sync_stream(q, stream)

    handle = conn.GetSelfHandle()

    call_async(q, conn.Aliasing, 'SetAliases', {handle: 'Some Guy'})

    # SetAliases requests vCard v1
    get_vcard_event = q.expect('stream-iq', query_ns=ns.VCARD_TEMP,
        query_name='vCard', iq_type='get')

    iq = get_vcard_event.stanza
    vcard = iq.firstChildElement()
    assert vcard.name == 'vCard', vcard.toXml()

    call_async(q, conn.Avatars, 'SetAvatar', 'hello', 'image/png')

    # We don't expect Gabble to send a second vCard request, since there's one
    # outstanding. But we want to ensure that SetAvatar reaches Gabble before
    # the empty vCard does.
    sync_dbus(bus, q, conn)

    # Send back current empty vCard
    result = make_result_iq(stream, iq)
    # result already includes the <vCard/> from the query, which is all we need
    stream.send(result)

    def has_nickname_and_photo(vcard):
        nicknames = xpath.queryForNodes('/vCard/NICKNAME', vcard)
        assert nicknames is not None
        assert len(nicknames) == 1
        assert str(nicknames[0]) == 'Some Guy'

        photos = xpath.queryForNodes('/vCard/PHOTO', vcard)
        assert photos is not None and len(photos) == 1, repr(photos)
        types = xpath.queryForNodes('/PHOTO/TYPE', photos[0])
        binvals = xpath.queryForNodes('/PHOTO/BINVAL', photos[0])
        assert types is not None and len(types) == 1, repr(types)
        assert binvals is not None and len(binvals) == 1, repr(binvals)
        assert str(types[0]) == 'image/png'
        got = str(binvals[0])
        exp = base64.b64encode('hello')
        assert got == exp, (got, exp)

    # Now Gabble should set a new vCard with both of the above changes.
    expect_and_handle_set_vcard(q, stream, has_nickname_and_photo)
def test(q, bus, conn, stream):
    expect_and_handle_get_vcard(q, stream)

    self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
    conn.Aliasing.SetAliases({self_handle: 'lala'})

    expect_and_handle_set_vcard(q, stream)

    event = q.expect('dbus-signal', signal='AliasesChanged',
        args=[[(self_handle, u'lala')]])

    room_jid = '*****@*****.**'

    # muc stream tube
    call_async(q, conn.Requests, 'CreateChannel', {
        cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
        cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
        cs.TARGET_ID: room_jid})

    gfc, _, _ = q.expect_many(
        EventPattern('dbus-signal', signal='GroupFlagsChanged'),
        EventPattern('dbus-signal', signal='MembersChangedDetailed',
            predicate=lambda e:
                e.args[0] == [] and         # added
                e.args[1] == [] and         # removed
                e.args[2] == [] and         # local pending
                len(e.args[3]) == 1 and     # remote pending
                e.args[4].get('actor', 0) == 0 and
                e.args[4].get('change-reason', 0) == 0 and
                e.args[4]['contact-ids'][e.args[3][0]] == '[email protected]/lala'),
        EventPattern('stream-presence', to='%s/lala' % room_jid))
    assert gfc.args[1] == 0

    # Send presence for other member of room.
    stream.send(make_muc_presence('owner', 'moderator', room_jid, 'bob'))

    # Send presence for own membership of room.
    stream.send(make_muc_presence('none', 'participant', room_jid, 'lala'))

    event = q.expect('dbus-signal', signal='MembersChangedDetailed',
            predicate=lambda e:
                len(e.args[0]) == 2 and     # added
                e.args[1] == [] and         # removed
                e.args[2] == [] and         # local pending
                e.args[3] == [] and         # remote pending
                e.args[4].get('actor', 0) == 0 and
                e.args[4].get('change-reason', 0) == 0 and
                set([e.args[4]['contact-ids'][h] for h in e.args[0]]) ==
                set(['[email protected]/lala', '[email protected]/bob']))

    event = q.expect('dbus-return', method='CreateChannel')
Exemple #12
0
def test(q, bus, conn, stream):
    photo = current_vcard.addElement((None, 'PHOTO'))
    photo.addElement((None, 'TYPE')).addContent('image/fake')
    photo.addElement((None, 'BINVAL')).addContent('NYANYANYANYANYAN')

    call_async(q, conn.Avatars, 'ClearAvatar')

    expect_and_handle_get_vcard(q, stream)

    def check(vcard):
        assert len(vcard.children) == 0, vcard.toXml()

    expect_and_handle_set_vcard(q, stream, check=check)

    q.expect('dbus-return', method='ClearAvatar')
def test(q, bus, conn, stream):
    expect_and_handle_get_vcard(q, stream)
    sync_stream(q, stream)

    call_async(
        q, conn.Avatars, 'SetAvatar', 'Guy.brush', 'image/x-mighty-pirate')
    expect_and_handle_get_vcard(q, stream)
    iq_event = q.expect(
        'stream-iq', iq_type='set', query_ns='vcard-temp', query_name='vCard')
    call_async(
        q, conn.Avatars, 'SetAvatar', 'LeChuck.brush', 'image/x-ghost-pirate')

    disconnect_conn(q, conn, stream)

    q.expect('dbus-error', method='SetAvatar', name=cs.NOT_AVAILABLE)
    q.expect('dbus-error', method='SetAvatar', name=cs.NOT_AVAILABLE)
    sync_dbus(bus, q, conn)
def test(q, bus, conn, stream):
    expect_and_handle_get_vcard(q, stream)
    sync_stream(q, stream)

    call_async(
        q, conn.Avatars, 'SetAvatar', b'Guy.brush', 'image/x-mighty-pirate')
    expect_and_handle_get_vcard(q, stream)
    iq_event = q.expect(
        'stream-iq', iq_type='set', query_ns='vcard-temp', query_name='vCard')
    call_async(
        q, conn.Avatars, 'SetAvatar', b'LeChuck.brush', 'image/x-ghost-pirate')

    disconnect_conn(q, conn, stream)

    q.expect('dbus-error', method='SetAvatar', name=cs.NOT_AVAILABLE)
    q.expect('dbus-error', method='SetAvatar', name=cs.NOT_AVAILABLE)
    sync_dbus(bus, q, conn)
Exemple #15
0
def test(q, bus, conn, stream):
    self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
    conn.Aliasing.SetAliases({self_handle: 'lala'})
    expect_and_handle_get_vcard(q, stream)

    pep_update = q.expect('stream-iq',
                          iq_type='set',
                          query_ns=ns.PUBSUB,
                          query_name='pubsub')
    validate_pep_update(pep_update, 'lala')
    acknowledge_iq(stream, pep_update.stanza)

    def check(vCard):
        nickname = next(vCard.elements(uri=ns.VCARD_TEMP, name='NICKNAME'))
        assertEquals('lala', nickname.children[0])

    expect_and_handle_set_vcard(q, stream, check=check)

    event = q.expect('dbus-signal',
                     signal='AliasesChanged',
                     args=[[(self_handle, u'lala')]])

    conn.Aliasing.SetAliases({self_handle: ''})
    pep_update = q.expect('stream-iq',
                          iq_type='set',
                          query_ns=ns.PUBSUB,
                          query_name='pubsub')
    validate_pep_update(pep_update, None)

    expect_and_handle_get_vcard(q, stream)

    def check(vCard):
        # The vCard should be empty, rather than having an empty <NICKNAME/>
        # element.
        assertLength(0, vCard.children)

    expect_and_handle_set_vcard(q, stream, check=check)

    event = q.expect('dbus-signal',
                     signal='AliasesChanged',
                     args=[[(self_handle, u'test@localhost')]])
def test(q, bus, conn, stream):
    conn.Connect()

    expect_and_handle_get_vcard(q, stream)

    self_handle = conn.GetSelfHandle()
    conn.Aliasing.SetAliases({self_handle: 'lala'})

    expect_and_handle_set_vcard(q, stream)

    event = q.expect('dbus-signal', signal='AliasesChanged',
        args=[[(self_handle, u'lala')]])

    room_jid = '*****@*****.**'
    room_handle = request_muc_handle(q, conn, stream, room_jid)

    call_async(q, conn, 'RequestChannel', cs.CHANNEL_TYPE_TEXT, cs.HT_ROOM,
        room_handle, True)

    gfc, _, _ = q.expect_many(
        EventPattern('dbus-signal', signal='GroupFlagsChanged'),
        EventPattern('dbus-signal', signal='MembersChanged',
            args=[u'', [], [], [], [2], 0, 0]),
        EventPattern('stream-presence', to='%s/lala' % room_jid))
    assert gfc.args[1] == 0

    # Send presence for other member of room.
    stream.send(make_muc_presence('owner', 'moderator', room_jid, 'bob'))

    # Send presence for own membership of room.
    stream.send(make_muc_presence('none', 'participant', room_jid, 'lala'))

    event = q.expect('dbus-signal', signal='MembersChanged',
        args=[u'', [2, 3], [], [], [], 0, 0])
    assert conn.InspectHandles(1, [2]) == ['[email protected]/lala']
    assert conn.InspectHandles(1, [3]) == ['[email protected]/bob']

    event = q.expect('dbus-return', method='RequestChannel')
def test(q, bus, conn, stream):
    expect_and_handle_get_vcard(q, stream)

    jid = u'*****@*****.**'
    alias = u'Horza'
    handle = conn.get_contact_handle_sync(jid)

    # We don't have an interesting alias for Horza
    assertEquals({handle: jid}, get_aliases(conn, [handle]))

    # Horza sends us a message containing his preferred nickname.
    stream.send(
        elem('message', from_=jid,
             type='chat')(elem('body')(u"It's a long story."),
                          elem(ns.NICK, 'nick')(alias)))
    _, mr = q.expect_many(
        EventPattern('dbus-signal',
                     signal='AliasesChanged',
                     args=[[(handle, alias)]]),
        EventPattern('dbus-signal', signal='MessageReceived'),
    )

    channel = wrap_channel(bus.get_object(conn.bus_name, mr.path), 'Text')

    # So now we know his alias.
    assertEquals({handle: alias}, get_aliases(conn, [handle]))

    # Presumably to avoid non-contacts being able to make Gabble's memory
    # footprint grow forever, Gabble throws the alias away when we close the
    # channel.
    header = mr.args[0][0]
    channel.Text.AcknowledgePendingMessages([header['pending-message-id']])
    channel.Close()

    # FIXME: Gabble forgets the alias, but it doesn't signal that it has done
    # so; it probably should.
    # q.expect('dbus-signal', signal='AliasesChanged', args=[[(handle, jid)]])
    assertEquals({handle: jid}, get_aliases(conn, [handle]))

    # Basically the same test, but in a MUC.
    #
    # It's a bit questionable whether this ought to work.
    # <http://xmpp.org/extensions/xep-0172.html#muc> doesn't have anything to
    # say about including <nick/> in messages; it does talk about including
    # <nick> in your MUC presence, which is actually equally sketchy! If I join
    # a muc with the resource '/wjt', and you join with resource '/ohai' but
    # say that your nickname is 'wjt', what on earth is Alice's UI supposed to
    # show when you send a message?
    #
    # But anyway, at the time of writing this "works", so I'm adding a test to
    # make it explicit.  Perhaps in future we might change this test to verify
    # that it doesn't "work".
    room_jid = '*****@*****.**'
    muc, _, _ = join_muc(q, bus, conn, stream, room_jid)

    bob_jid = room_jid + '/bob'
    bob_handle = conn.get_contact_handle_sync(bob_jid)

    assertEquals({bob_handle: 'bob'}, get_aliases(conn, [bob_handle]))

    stream.send(
        elem('message', from_=bob_jid, type='groupchat')(
            elem('body')(u'My religion dies with me.'),
            elem(ns.NICK, 'nick')(alias),
        ))

    q.expect_many(
        EventPattern('dbus-signal',
                     signal='AliasesChanged',
                     args=[[(bob_handle, alias)]]),
        EventPattern('dbus-signal', signal='MessageReceived'),
    )

    assertEquals({bob_handle: alias}, get_aliases(conn, [bob_handle]))

    muc.Close()
    q.expect('stream-presence', to=room_jid + '/test')
    echo = make_muc_presence('member', 'none', room_jid, 'test')
    echo['type'] = 'unavailable'
    stream.send(echo)
    q.expect('dbus-signal', signal='ChannelClosed')

    # FIXME: Gabble forgets the alias, but it doesn't signal that it has done
    # so; it probably should.
    # q.expect('dbus-signal', signal='AliasesChanged',
    #     args=[[(bob_handle, 'bob')]])
    assertEquals({bob_handle: 'bob'}, get_aliases(conn, [bob_handle]))
Exemple #18
0
def test(q, bus, conn, stream):
    self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")

    # When Gabble initially requests its avatar from the server, it discovers
    # it has none.
    expect_and_handle_get_vcard(q, stream)
    handle, signalled_token = q.expect('dbus-signal',
                                       signal='AvatarUpdated').args

    assertEquals(self_handle, handle)
    assertEquals('', signalled_token)

    # The user sets an avatar.
    call_async(q, conn.Avatars, 'SetAvatar', AVATAR_1_DATA, AVATAR_1_MIME_TYPE)
    expect_and_handle_get_vcard(q, stream)
    expect_and_handle_set_vcard(q, stream)

    # It's signalled on D-Bus …
    set_ret, avatar_updated = q.expect_many(
        EventPattern('dbus-return', method='SetAvatar'),
        EventPattern('dbus-signal', signal='AvatarUpdated'),
    )

    returned_token, = set_ret.value
    handle, signalled_token = avatar_updated.args

    assertEquals(self_handle, handle)
    assertEquals(returned_token, signalled_token)

    # … and also on XMPP.
    broadcast = q.expect('stream-presence', to=None)
    broadcast_hash = extract_hash_from_presence(broadcast.stanza)
    assertEquals(AVATAR_1_SHA1, broadcast_hash)

    # If applications ask Gabble for information about the user's own avatar,
    # it should be able to answer. (Strictly speaking, expecting Gabble to know
    # the avatar data is risky because Gabble discards cached vCards after a
    # while, but we happen to know it takes 20 seconds or so for that to
    # happen.)
    known = conn.Avatars.GetKnownAvatarTokens([self_handle])
    assertEquals({self_handle: signalled_token}, known)

    conn.Avatars.RequestAvatars([self_handle])
    retrieved = q.expect('dbus-signal', signal='AvatarRetrieved')
    handle, token, data, mime_type = retrieved.args
    assertEquals(self_handle, handle)
    assertEquals(signalled_token, token)
    assertEquals(AVATAR_1_DATA, data)
    assertEquals(AVATAR_1_MIME_TYPE, mime_type)

    # Well, that was quite easy. How about we join a MUC? XEP-0153 §4.1 says:
    #     If a client supports the protocol defined herein, it […] SHOULD
    #     also include the update child in directed presence stanzas (e.g.,
    #     directed presence sent when joining Multi-User Chat [5] rooms).
    #         — http://xmpp.org/extensions/xep-0153.html#bizrules-presence
    join_event = try_to_join_muc(q, bus, conn, stream, MUC)
    directed_hash = extract_hash_from_presence(join_event.stanza)
    assertEquals(AVATAR_1_SHA1, directed_hash)

    # There are two others in the MUC: fredrik has no avatar, wendy has an
    # avatar. We, of course, have our own avatar.
    stream.send(make_muc_presence('none', 'participant', MUC, 'fredrik'))
    stream.send(
        make_muc_presence('none',
                          'participant',
                          MUC,
                          'wendy',
                          photo=AVATAR_2_SHA1))
    stream.send(
        make_muc_presence('owner',
                          'moderator',
                          MUC,
                          'test',
                          photo=AVATAR_1_SHA1))

    path, _ = q.expect('dbus-return', method='CreateChannel').value
    chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')

    members = chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'Members')
    assertLength(3, members)

    fredrik, wendy, muc_self_handle = conn.get_contact_handles_sync(
        ['%s/%s' % (MUC, x) for x in ["fredrik", "wendy", "test"]])

    known = conn.Avatars.GetKnownAvatarTokens(members)
    # <https://bugs.freedesktop.org/show_bug.cgi?id=32017>: this assertion
    # failed, the MUC self handle's token was the empty string.
    assertEquals(AVATAR_1_SHA1, known[muc_self_handle])
    assertEquals(AVATAR_2_SHA1, known[wendy])
    assertEquals('', known[fredrik])

    # 'k, cool. Wendy loves our avatar and switches to it.
    stream.send(
        make_muc_presence('none',
                          'participant',
                          MUC,
                          'wendy',
                          photo=AVATAR_1_SHA1))
    # Okay this is technically assuming that we just expose the SHA1 sums
    # directly which is not guaranteed … but we do.
    q.expect('dbus-signal',
             signal='AvatarUpdated',
             args=[wendy, AVATAR_1_SHA1])

    # Fredrik switches too.
    stream.send(
        make_muc_presence('none',
                          'participant',
                          MUC,
                          'fredrik',
                          photo=AVATAR_1_SHA1))
    q.expect('dbus-signal',
             signal='AvatarUpdated',
             args=[fredrik, AVATAR_1_SHA1])

    # And we switch to some other avatar. Gabble should update its vCard, and
    # then update its MUC presence (which the test, acting as the MUC server,
    # must echo).
    call_async(q, conn.Avatars, 'SetAvatar', AVATAR_2_DATA, AVATAR_2_MIME_TYPE)
    expect_and_handle_get_vcard(q, stream)
    expect_and_handle_set_vcard(q, stream)

    muc_presence = q.expect('stream-presence', to=('%s/test' % MUC))
    directed_hash = extract_hash_from_presence(muc_presence.stanza)
    stream.send(
        make_muc_presence('owner',
                          'moderator',
                          MUC,
                          'test',
                          photo=directed_hash))

    # Gabble should signal an avatar update for both our global self-handle and
    # our MUC self-handle. (The first of these of course does not need to wait
    # for the MUC server to echo our presence.)
    q.expect_many(
        EventPattern('dbus-signal',
                     signal='AvatarUpdated',
                     args=[self_handle, AVATAR_2_SHA1]),
        EventPattern('dbus-signal',
                     signal='AvatarUpdated',
                     args=[muc_self_handle, AVATAR_2_SHA1]),
    )
Exemple #19
0
def test(q, bus, conn, stream):
    self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")

    # When Gabble initially requests its avatar from the server, it discovers
    # it has none.
    expect_and_handle_get_vcard(q, stream)
    handle, signalled_token = q.expect('dbus-signal', signal='AvatarUpdated').args

    assertEquals(self_handle, handle)
    assertEquals('', signalled_token)

    # The user sets an avatar.
    call_async(q, conn.Avatars, 'SetAvatar', AVATAR_1_DATA, AVATAR_1_MIME_TYPE)
    expect_and_handle_get_vcard(q, stream)
    expect_and_handle_set_vcard(q, stream)

    # It's signalled on D-Bus …
    set_ret, avatar_updated = q.expect_many(
        EventPattern('dbus-return', method='SetAvatar'),
        EventPattern('dbus-signal', signal='AvatarUpdated'),
        )

    returned_token, = set_ret.value
    handle, signalled_token = avatar_updated.args

    assertEquals(self_handle, handle)
    assertEquals(returned_token, signalled_token)

    # … and also on XMPP.
    broadcast = q.expect('stream-presence', to=None)
    broadcast_hash = extract_hash_from_presence(broadcast.stanza)
    assertEquals(AVATAR_1_SHA1, broadcast_hash)

    # If applications ask Gabble for information about the user's own avatar,
    # it should be able to answer. (Strictly speaking, expecting Gabble to know
    # the avatar data is risky because Gabble discards cached vCards after a
    # while, but we happen to know it takes 20 seconds or so for that to
    # happen.)
    known = conn.Avatars.GetKnownAvatarTokens([self_handle])
    assertEquals({self_handle: signalled_token}, known)

    conn.Avatars.RequestAvatars([self_handle])
    retrieved = q.expect('dbus-signal', signal='AvatarRetrieved')
    handle, token, data, mime_type = retrieved.args
    assertEquals(self_handle, handle)
    assertEquals(signalled_token, token)
    assertEquals(AVATAR_1_DATA, data)
    assertEquals(AVATAR_1_MIME_TYPE, mime_type)

    # Well, that was quite easy. How about we join a MUC? XEP-0153 §4.1 says:
    #     If a client supports the protocol defined herein, it […] SHOULD
    #     also include the update child in directed presence stanzas (e.g.,
    #     directed presence sent when joining Multi-User Chat [5] rooms).
    #         — http://xmpp.org/extensions/xep-0153.html#bizrules-presence
    join_event = try_to_join_muc(q, bus, conn, stream, MUC)
    directed_hash = extract_hash_from_presence(join_event.stanza)
    assertEquals(AVATAR_1_SHA1, directed_hash)

    # There are two others in the MUC: fredrik has no avatar, wendy has an
    # avatar. We, of course, have our own avatar.
    stream.send(make_muc_presence('none', 'participant', MUC, 'fredrik'))
    stream.send(make_muc_presence('none', 'participant', MUC, 'wendy',
          photo=AVATAR_2_SHA1))
    stream.send(make_muc_presence('owner', 'moderator', MUC, 'test',
          photo=AVATAR_1_SHA1))

    path, _ = q.expect('dbus-return', method='CreateChannel').value
    chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')

    members = chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'Members')
    assertLength(3, members)

    fredrik, wendy, muc_self_handle = conn.get_contact_handles_sync(
        ['%s/%s' % (MUC, x) for x in ["fredrik", "wendy", "test"]])

    known = conn.Avatars.GetKnownAvatarTokens(members)
    # <https://bugs.freedesktop.org/show_bug.cgi?id=32017>: this assertion
    # failed, the MUC self handle's token was the empty string.
    assertEquals(AVATAR_1_SHA1, known[muc_self_handle])
    assertEquals(AVATAR_2_SHA1, known[wendy])
    assertEquals('', known[fredrik])

    # 'k, cool. Wendy loves our avatar and switches to it.
    stream.send(make_muc_presence('none', 'participant', MUC, 'wendy',
          photo=AVATAR_1_SHA1))
    # Okay this is technically assuming that we just expose the SHA1 sums
    # directly which is not guaranteed … but we do.
    q.expect('dbus-signal', signal='AvatarUpdated',
        args=[wendy, AVATAR_1_SHA1])

    # Fredrik switches too.
    stream.send(make_muc_presence('none', 'participant', MUC, 'fredrik',
          photo=AVATAR_1_SHA1))
    q.expect('dbus-signal', signal='AvatarUpdated',
        args=[fredrik, AVATAR_1_SHA1])

    # And we switch to some other avatar. Gabble should update its vCard, and
    # then update its MUC presence (which the test, acting as the MUC server,
    # must echo).
    call_async(q, conn.Avatars, 'SetAvatar', AVATAR_2_DATA, AVATAR_2_MIME_TYPE)
    expect_and_handle_get_vcard(q, stream)
    expect_and_handle_set_vcard(q, stream)

    muc_presence = q.expect('stream-presence', to=('%s/test' % MUC))
    directed_hash = extract_hash_from_presence(muc_presence.stanza)
    stream.send(make_muc_presence('owner', 'moderator', MUC, 'test',
          photo=directed_hash))

    # Gabble should signal an avatar update for both our global self-handle and
    # our MUC self-handle. (The first of these of course does not need to wait
    # for the MUC server to echo our presence.)
    q.expect_many(
        EventPattern('dbus-signal', signal='AvatarUpdated',
            args=[self_handle, AVATAR_2_SHA1]),
        EventPattern('dbus-signal', signal='AvatarUpdated',
            args=[muc_self_handle, AVATAR_2_SHA1]),
        )
def test(q, bus, conn, stream):
    expect_and_handle_get_vcard(q, stream)

    jid = u"*****@*****.**"
    alias = u"Horza"
    handle = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]

    # We don't have an interesting alias for Horza
    assertEquals({handle: jid}, conn.Aliasing.GetAliases([handle]))

    # Horza sends us a message containing his preferred nickname.
    stream.send(
        elem("message", from_=jid, type="chat")(elem("body")(u"It's a long story."), elem(ns.NICK, "nick")(alias))
    )
    _, mr = q.expect_many(
        EventPattern("dbus-signal", signal="AliasesChanged", args=[[(handle, alias)]]),
        EventPattern("dbus-signal", signal="MessageReceived"),
    )

    channel = wrap_channel(bus.get_object(conn.bus_name, mr.path), "Text")

    # So now we know his alias.
    assertEquals({handle: alias}, conn.Aliasing.GetAliases([handle]))

    # Presumably to avoid non-contacts being able to make Gabble's memory
    # footprint grow forever, Gabble throws the alias away when we close the
    # channel.
    header = mr.args[0][0]
    channel.Text.AcknowledgePendingMessages([header["pending-message-id"]])
    channel.Close()

    # FIXME: Gabble forgets the alias, but it doesn't signal that it has done
    # so; it probably should.
    # q.expect('dbus-signal', signal='AliasesChanged', args=[[(handle, jid)]])
    assertEquals({handle: jid}, conn.Aliasing.GetAliases([handle]))

    # Basically the same test, but in a MUC.
    #
    # It's a bit questionable whether this ought to work.
    # <http://xmpp.org/extensions/xep-0172.html#muc> doesn't have anything to
    # say about including <nick/> in messages; it does talk about including
    # <nick> in your MUC presence, which is actually equally sketchy! If I join
    # a muc with the resource '/wjt', and you join with resource '/ohai' but
    # say that your nickname is 'wjt', what on earth is Alice's UI supposed to
    # show when you send a message?
    #
    # But anyway, at the time of writing this "works", so I'm adding a test to
    # make it explicit.  Perhaps in future we might change this test to verify
    # that it doesn't "work".
    room_jid = "*****@*****.**"
    _, muc, _, _ = join_muc(q, bus, conn, stream, room_jid)

    bob_jid = room_jid + "/bob"
    bob_handle = conn.RequestHandles(cs.HT_CONTACT, [bob_jid])[0]

    assertEquals({bob_handle: "bob"}, conn.Aliasing.GetAliases([bob_handle]))

    stream.send(
        elem("message", from_=bob_jid, type="groupchat")(
            elem("body")(u"My religion dies with me."), elem(ns.NICK, "nick")(alias)
        )
    )

    q.expect_many(
        EventPattern("dbus-signal", signal="AliasesChanged", args=[[(bob_handle, alias)]]),
        EventPattern("dbus-signal", signal="MessageReceived"),
    )

    assertEquals({bob_handle: alias}, conn.Aliasing.GetAliases([bob_handle]))

    muc.Close()
    q.expect("stream-presence", to=room_jid + "/test")
    echo = make_muc_presence("member", "none", room_jid, "test")
    echo["type"] = "unavailable"
    stream.send(echo)
    q.expect("dbus-signal", signal="ChannelClosed")

    # FIXME: Gabble forgets the alias, but it doesn't signal that it has done
    # so; it probably should.
    # q.expect('dbus-signal', signal='AliasesChanged',
    #     args=[[(bob_handle, 'bob')]])
    assertEquals({bob_handle: "bob"}, conn.Aliasing.GetAliases([bob_handle]))