<commit_before>"""
Test OLPC extensions to MUC invitations.
"""

import dbus

from twisted.words.xish import domish, xpath

from gabbletest import go, make_result_iq, exec_test
from servicetest import call_async, EventPattern

def test(q, bus, conn, stream):
    conn.Connect()

    q.expect('dbus-signal', signal='StatusChanged', args=[0, 1])

    handles = {}
    handles['bob'] = conn.RequestHandles(1, ['<EMAIL>'])[0]

    buddy_iface = dbus.Interface(conn, 'org.laptop.Telepathy.BuddyInfo')
    call_async(q, buddy_iface, 'GetActivities', handles['bob'])

    event = q.expect('stream-iq', iq_type='get', to='bob@localhost')
    # Bob has no activities
    event.stanza['type'] = 'result'
    event.stanza['to'] = '<EMAIL>'
    event.stanza['from'] = '<EMAIL>'
    stream.send(event.stanza)

    event = q.expect('dbus-return', method='GetActivities')
    # initially, Bob has no activities
    assert event.value == ([],)

    # Bob sends an activity properties message
    message = domish.Element(('jabber:client', 'message'))
    message['from'] = '<EMAIL>'
    message['to'] = '<EMAIL>'
    properties = message.addElement(
        ('http://laptop.org/xmpp/activity-properties', 'properties'))
    properties['room'] = '<EMAIL>'
    properties['activity'] = 'foo_id'
    property = properties.addElement((None, 'property'))
    property['type'] = 'str'
    property['name'] = 'color'
    property.addContent('#ffff00,#00ffff')
    property = properties.addElement((None, 'property'))
    property['type'] = 'bool'
    property['name'] = 'private'
    property.addContent('1')

    stream.send(message)

    event = q.expect('dbus-signal', signal='ActivityPropertiesChanged')
    handles['chat'], props = event.args
    assert props == {'color': '#ffff00,#00ffff', 'private' : True}

    event = q.expect('dbus-signal', signal='ActivitiesChanged')
    assert event.args[0] == handles['bob']
    acts = event.args[1]
    assert len(acts) == 1
    assert acts[0] == ('foo_id', handles['chat'])

    # Bobs invites us to the activity
    message = domish.Element((None, 'message'))
    message['from'] = '<EMAIL>'
    message['to'] = 'test@<EMAIL>'
    x = message.addElement(('http://jabber.org/protocol/muc#user', 'x'))
    invite = x.addElement((None, 'invite'))
    invite['from'] = 'bob@localhost'
    reason = invite.addElement((None, 'reason'))
    reason.addContent('No good reason')

    stream.send(message)

    event = q.expect('dbus-signal', signal='NewChannel')
    assert event.args[1] == 'org.freedesktop.Telepathy.Channel.Type.Text'

    assert event.args[2] == 2   # handle type
    assert event.args[3] == handles['chat']   # handle

    text_chan = bus.get_object(conn.bus_name, event.args[0])
    group_iface = dbus.Interface(text_chan,
            'org.freedesktop.Telepathy.Channel.Interface.Group')

    members = group_iface.GetAllMembers()[0]
    local_pending = group_iface.GetAllMembers()[1]
    remote_pending = group_iface.GetAllMembers()[2]

    assert len(members) == 1
    assert conn.InspectHandles(1, members)[0] == 'bob@localhost'
    assert len(local_pending) == 1
    # FIXME: the username-part-is-nickname assumption
    assert conn.InspectHandles(1, local_pending)[0] == \
            'chat@<EMAIL>.localhost/test'
    assert len(remote_pending) == 0

    handles['chat_self'] = group_iface.GetSelfHandle()
    assert handles['chat_self'] == local_pending[0]

    # by now, we should have picked up the extra activity properties
    buddy_iface = dbus.Interface(conn, 'org.laptop.Telepathy.BuddyInfo')
    call_async(q, buddy_iface, 'GetActivities', handles['bob'])

    event = q.expect('stream-iq', iq_type='get', to='bob@<EMAIL>')
    # Bob still has no (public) activities
    event.stanza['type'] = 'result'
    event.stanza['to'] = 'test@<EMAIL>'
    event.stanza['from'] = '<EMAIL>@<EMAIL>'
    stream.send(event.stanza)

    event = q.expect('dbus-return', method='GetActivities')

    assert event.value == ([('foo_id', handles['chat'])],)

    # OK, now accept the invitation
    call_async(q, group_iface, 'AddMembers', [handles['chat_self']], 'Oh, OK then')

    _, event, _ = q.expect_many(
        EventPattern('stream-presence', to='chat<EMAIL>/test'),
        EventPattern('dbus-signal', signal='MembersChanged'),
        EventPattern('dbus-return', method='AddMembers')
        )

    assert event.args == ['', [], [handles['bob']], [],
            [handles['chat_self']], 0, handles['chat_self']]

    # Send presence for own membership of room.
    presence = domish.Element((None, 'presence'))
    presence['from'] = 'chat<EMAIL>/test'
    x = presence.addElement(('http://jabber.org/protocol/muc#user', 'x'))
    item = x.addElement('item')
    item['affiliation'] = 'owner'
    item['role'] = 'moderator'
    stream.send(presence)

    event = q.expect('dbus-signal', signal='MembersChanged')
    assert event.args == ['', [handles['chat_self']], [], [], [], 0, 0]

    call_async(q, buddy_iface, 'SetActivities', [('foo_id', handles['chat'])])

    event = q.expect('stream-iq', iq_type='set')
    event.stanza['type'] = 'result'
    event.stanza['to'] = 'test@<EMAIL>'
    event.stanza['from'] = 'test@<EMAIL>'
    stream.send(event.stanza)

    q.expect('dbus-return', method='SetActivities')
    act_prop_iface = dbus.Interface(conn, 'org.laptop.Telepathy.ActivityProperties')
    call_async(q, act_prop_iface, 'SetProperties',
        handles['chat'], {'color': '#ffff00,#00ffff', 'private': True})

    event = q.expect('dbus-signal', signal='ActivityPropertiesChanged')
    chat_handle, props = event.args
    assert chat_handle == handles['chat']
    assert props == {'color': '#ffff00,#00ffff', 'private' : True}

    q.expect('dbus-return', method='SetProperties')
    # Test sending an invitation
    handles['alice'] = conn.RequestHandles(1,
        ['<EMAIL>'])[0]
    call_async(q, group_iface, 'AddMembers', [handles['alice']],
            'I want to test invitations')

    event = q.expect('stream-message', to='<EMAIL>')
    message = event.stanza

    properties = xpath.queryForNodes('/message/properties', message)
    assert (properties is not None and len(properties) == 1), repr(properties)
    assert properties[0].uri == 'http://laptop.org/xmpp/activity-properties'
    assert properties[0]['room'] == '<EMAIL>'
    assert properties[0]['activity'] == 'foo_id'

    property = xpath.queryForNodes('/properties/property', properties[0])
    assert (property is not None and len(property) == 2), repr(property)
    seen = set()
    for p in property:
        seen.add(p['name'])
        if p['name'] == 'color':
            assert p['type'] == 'str'
            assert str(p) == '#ffff00,#00ffff'
        elif p['name'] == 'private':
            assert p['type'] == 'bool'
            assert str(p) == '1'
        else:
            assert False, 'Unexpected property %s' % p['name']
    assert 'color' in seen, seen
    assert 'private' in seen, seen

    event = q.expect('stream-message', to='<EMAIL>')
    message = event.stanza

    x = xpath.queryForNodes('/message/x', message)
    assert (x is not None and len(x) == 1), repr(x)
    assert x[0].uri == 'http://jabber.org/protocol/muc#user'

    invites = xpath.queryForNodes('/x/invite', x[0])
    assert (invites is not None and len(invites) == 1), repr(invites)
    assert invites[0]['to'] == 'alice@localhost'

    reasons = xpath.queryForNodes('/invite/reason', invites[0])
    assert (reasons is not None and len(reasons) == 1), repr(reasons)
    assert str(reasons[0]) == 'I want to test invitations'

    call_async(q, act_prop_iface, 'SetProperties',
        handles['chat'], {'color': '#f00baa,#f00baa', 'private': True})

    event = q.expect('stream-message', to='<EMAIL>@<EMAIL>')
    message = event.stanza

    properties = xpath.queryForNodes('/message/properties', message)
    assert (properties is not None and len(properties) == 1), repr(properties)
    assert properties[0].uri == 'http://laptop.org/xmpp/activity-properties'
    assert properties[0]['room'] == '<EMAIL>'
    assert properties[0]['activity'] == 'foo_id'

    property = xpath.queryForNodes('/properties/property', properties[0])
    assert (property is not None and len(property) == 2), repr(property)
    seen = set()
    for p in property:
        seen.add(p['name'])
        if p['name'] == 'color':
            assert p['type'] == 'str'
            assert str(p) == '#f00baa,#f00baa'
        elif p['name'] == 'private':
            assert p['type'] == 'bool'
            assert str(p) == '1'
        else:
            assert False, 'Unexpected property %s' % p['name']
    assert 'color' in seen, seen
    assert 'private' in seen, seen

    event = q.expect('dbus-signal', signal='ActivityPropertiesChanged')
    chat_handle, props = event.args
    assert chat_handle == handles['chat']
    assert props == {'color': '#f00baa,#f00baa', 'private' : True}

    q.expect('dbus-return', method='SetProperties')

    conn.Disconnect()

    q.expect('dbus-signal', signal='StatusChanged', args=[2, 1])

if __name__ == '__main__':
    exec_test(test)
<commit_msg>olpc-muc-invitation.py: check if act_prop_iface.GetProperties returns the right properties<commit_after>"""
Test OLPC extensions to MUC invitations.
"""

import dbus

from twisted.words.xish import domish, xpath

from gabbletest import go, make_result_iq, exec_test
from servicetest import call_async, EventPattern

def test(q, bus, conn, stream):
    conn.Connect()

    q.expect('dbus-signal', signal='StatusChanged', args=[0, 1])

    handles = {}
    handles['bob'] = conn.RequestHandles(1, ['bob@localhost'])[0]

    buddy_iface = dbus.Interface(conn, 'org.laptop.Telepathy.BuddyInfo')
    act_prop_iface = dbus.Interface(conn, 'org.laptop.Telepathy.ActivityProperties')
    call_async(q, buddy_iface, 'GetActivities', handles['bob'])

    event = q.expect('stream-iq', iq_type='get', to='bob@localhost')
    # Bob has no activities
    event.stanza['type'] = 'result'
    event.stanza['to'] = 'test@localhost'
    event.stanza['from'] = 'bob@localhost'
    stream.send(event.stanza)

    event = q.expect('dbus-return', method='GetActivities')
    # initially, Bob has no activities
    assert event.value == ([],)

    # Bob sends an activity properties message
    message = domish.Element(('jabber:client', 'message'))
    message['from'] = 'bob@localhost'
    message['to'] = 'test@localhost'
    properties = message.addElement(
        ('http://laptop.org/xmpp/activity-properties', 'properties'))
    properties['room'] = '<EMAIL>'
    properties['activity'] = 'foo_id'
    property = properties.addElement((None, 'property'))
    property['type'] = 'str'
    property['name'] = 'color'
    property.addContent('#ffff00,#00ffff')
    property = properties.addElement((None, 'property'))
    property['type'] = 'bool'
    property['name'] = 'private'
    property.addContent('1')

    stream.send(message)

    event = q.expect('dbus-signal', signal='ActivityPropertiesChanged')
    handles['chat'], props = event.args
    assert props == {'color': '#ffff00,#00ffff', 'private' : True}

    event = q.expect('dbus-signal', signal='ActivitiesChanged')
    assert event.args[0] == handles['bob']
    acts = event.args[1]
    assert len(acts) == 1
    assert acts[0] == ('foo_id', handles['chat'])

    props = act_prop_iface.GetProperties(handles['chat'])
    assert props == {'color': '#ffff00,#00ffff', 'private' : True}

    # Bobs invites us to the activity
    message = domish.Element((None, 'message'))
    message['from'] = '<EMAIL>'
    message['to'] = 'test@localhost'
    x = message.addElement(('http://jabber.org/protocol/muc#user', 'x'))
    invite = x.addElement((None, 'invite'))
    invite['from'] = 'bob@localhost'
    reason = invite.addElement((None, 'reason'))
    reason.addContent('No good reason')

    stream.send(message)

    event = q.expect('dbus-signal', signal='NewChannel')
    assert event.args[1] == 'org.freedesktop.Telepathy.Channel.Type.Text'

    assert event.args[2] == 2   # handle type
    assert event.args[3] == handles['chat']   # handle

    text_chan = bus.get_object(conn.bus_name, event.args[0])
    group_iface = dbus.Interface(text_chan,
            'org.freedesktop.Telepathy.Channel.Interface.Group')

    members = group_iface.GetAllMembers()[0]
    local_pending = group_iface.GetAllMembers()[1]
    remote_pending = group_iface.GetAllMembers()[2]

    assert len(members) == 1
    assert conn.InspectHandles(1, members)[0] == 'bob@localhost'
    assert len(local_pending) == 1
    # FIXME: the username-part-is-nickname assumption
    assert conn.InspectHandles(1, local_pending)[0] == \
            'chat@conf.localhost/test'
    assert len(remote_pending) == 0

    handles['chat_self'] = group_iface.GetSelfHandle()
    assert handles['chat_self'] == local_pending[0]

    # by now, we should have picked up the extra activity properties
    call_async(q, buddy_iface, 'GetActivities', handles['bob'])

    event = q.expect('stream-iq', iq_type='get', to='bob@localhost')
    # Bob still has no (public) activities
    event.stanza['type'] = 'result'
    event.stanza['to'] = '<EMAIL>'
    event.stanza['from'] = '<EMAIL>@<EMAIL>'
    stream.send(event.stanza)

    event = q.expect('dbus-return', method='GetActivities')

    assert event.value == ([('foo_id', handles['chat'])],)

    # OK, now accept the invitation
    call_async(q, group_iface, 'AddMembers', [handles['chat_self']], 'Oh, OK then')

    _, event, _ = q.expect_many(
        EventPattern('stream-presence', to='chat@conf.localhost/test'),
        EventPattern('dbus-signal', signal='MembersChanged'),
        EventPattern('dbus-return', method='AddMembers')
        )

    assert event.args == ['', [], [handles['bob']], [],
            [handles['chat_self']], 0, handles['chat_self']]

    # Send presence for own membership of room.
    presence = domish.Element((None, 'presence'))
    presence['from'] = 'chat@conf.localhost/test'
    x = presence.addElement(('http://jabber.org/protocol/muc#user', 'x'))
    item = x.addElement('item')
    item['affiliation'] = 'owner'
    item['role'] = 'moderator'
    stream.send(presence)

    event = q.expect('dbus-signal', signal='MembersChanged')
    assert event.args == ['', [handles['chat_self']], [], [], [], 0, 0]

    call_async(q, buddy_iface, 'SetActivities', [('foo_id', handles['chat'])])

    event = q.expect('stream-iq', iq_type='set')
    event.stanza['type'] = 'result'
    event.stanza['to'] = '<EMAIL>'
    event.stanza['from'] = '<EMAIL>'
    stream.send(event.stanza)

    q.expect('dbus-return', method='SetActivities')
    call_async(q, act_prop_iface, 'SetProperties',
        handles['chat'], {'color': '#ffff00,#00ffff', 'private': True})

    event = q.expect('dbus-signal', signal='ActivityPropertiesChanged')
    chat_handle, props = event.args
    assert chat_handle == handles['chat']
    assert props == {'color': '#ffff00,#00ffff', 'private' : True}

    q.expect('dbus-return', method='SetProperties')
    # Test sending an invitation
    handles['alice'] = conn.RequestHandles(1,
        ['alice@<EMAIL>'])[0]
    call_async(q, group_iface, 'AddMembers', [handles['alice']],
            'I want to test invitations')

    event = q.expect('stream-message', to='<EMAIL>')
    message = event.stanza

    properties = xpath.queryForNodes('/message/properties', message)
    assert (properties is not None and len(properties) == 1), repr(properties)
    assert properties[0].uri == 'http://laptop.org/xmpp/activity-properties'
    assert properties[0]['room'] == '<EMAIL>'
    assert properties[0]['activity'] == 'foo_id'

    property = xpath.queryForNodes('/properties/property', properties[0])
    assert (property is not None and len(property) == 2), repr(property)
    seen = set()
    for p in property:
        seen.add(p['name'])
        if p['name'] == 'color':
            assert p['type'] == 'str'
            assert str(p) == '#ffff00,#00ffff'
        elif p['name'] == 'private':
            assert p['type'] == 'bool'
            assert str(p) == '1'
        else:
            assert False, 'Unexpected property %s' % p['name']
    assert 'color' in seen, seen
    assert 'private' in seen, seen

    event = q.expect('stream-message', to='<EMAIL>')
    message = event.stanza

    x = xpath.queryForNodes('/message/x', message)
    assert (x is not None and len(x) == 1), repr(x)
    assert x[0].uri == 'http://jabber.org/protocol/muc#user'

    invites = xpath.queryForNodes('/x/invite', x[0])
    assert (invites is not None and len(invites) == 1), repr(invites)
    assert invites[0]['to'] == 'alice@localhost'

    reasons = xpath.queryForNodes('/invite/reason', invites[0])
    assert (reasons is not None and len(reasons) == 1), repr(reasons)
    assert str(reasons[0]) == 'I want to test invitations'

    call_async(q, act_prop_iface, 'SetProperties',
        handles['chat'], {'color': '#f00baa,#f00baa', 'private': True})

    event = q.expect('stream-message', to='alice@localhost')
    message = event.stanza

    properties = xpath.queryForNodes('/message/properties', message)
    assert (properties is not None and len(properties) == 1), repr(properties)
    assert properties[0].uri == 'http://laptop.org/xmpp/activity-properties'
    assert properties[0]['room'] == '<EMAIL>'
    assert properties[0]['activity'] == 'foo_id'

    property = xpath.queryForNodes('/properties/property', properties[0])
    assert (property is not None and len(property) == 2), repr(property)
    seen = set()
    for p in property:
        seen.add(p['name'])
        if p['name'] == 'color':
            assert p['type'] == 'str'
            assert str(p) == '#f00baa,#f00baa'
        elif p['name'] == 'private':
            assert p['type'] == 'bool'
            assert str(p) == '1'
        else:
            assert False, 'Unexpected property %s' % p['name']
    assert 'color' in seen, seen
    assert 'private' in seen, seen

    event = q.expect('dbus-signal', signal='ActivityPropertiesChanged')
    chat_handle, props = event.args
    assert chat_handle == handles['chat']
    assert props == {'color': '#f00baa,#f00baa', 'private' : True}

    q.expect('dbus-return', method='SetProperties')

    conn.Disconnect()

    q.expect('dbus-signal', signal='StatusChanged', args=[2, 1])

if __name__ == '__main__':
    exec_test(test)

{'fraction_non_alphanumeric': 0.17358161820755744, 'fraction_numerical': 0.00958292497005336, 'mean_word_length': 3.693841042678252, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 3, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3301200', 'n_tokens_mistral': 6043, 'n_tokens_neox': 5847, 'n_words': 1260}