def test_props_present(q, bus, conn, stream): chan = setup(q, bus, conn, stream) props = chan.Properties.GetAll(cs.CHANNEL_IFACE_ROOM_CONFIG) assertContains('PasswordProtected', props) assertContains('Password', props) assertContains('Description', props) assertContains('Title', props) assertContains('ConfigurationRetrieved', props) assertContains('Persistent', props) assertContains('Private', props) assertContains('Limit', props) assertContains('Anonymous', props) assertContains('CanUpdateConfiguration', props) assertContains('PasswordHint', props) assertContains('Moderated', props) assertContains('InviteOnly', props) assertContains('MutableProperties', props) # this should do nothing forbidden = [EventPattern('dbus-signal', signal='PropertiesChanged')] q.forbid_events(forbidden) call_async(q, chan.RoomConfig1, 'UpdateConfiguration', {}) sync_stream(q, stream) q.unforbid_events(forbidden) # we should have these mutable ones mutable_props = ['InviteOnly', 'Limit', 'Moderated', 'Private', 'PasswordProtected', 'Password'] assertEquals(mutable_props, props['MutableProperties'])
def test_limit(q, bus, conn, stream): chan = setup(q, bus, conn, stream) # do nothing, really forbidden = [EventPattern('stream-MODE'), EventPattern('dbus-signal', signal='PropertiesChanged')] q.forbid_events(forbidden) call_async(q, chan.RoomConfig1, 'UpdateConfiguration', {'Limit': dbus.UInt32(0)}) q.expect_many(EventPattern('dbus-return', method='UpdateConfiguration')) sync_stream(q, stream) q.unforbid_events(forbidden) # set a limit call_async(q, chan.RoomConfig1, 'UpdateConfiguration', {'Limit': dbus.UInt32(1337)}) # totally 1337 q.expect_many(EventPattern('dbus-return', method='UpdateConfiguration'), EventPattern('stream-MODE', data=['#test', '+l', '1337']), EventPattern('dbus-signal', signal='PropertiesChanged', args=[cs.CHANNEL_IFACE_ROOM_CONFIG, {'Limit': 1337}, []]) ) # unset the limit call_async(q, chan.RoomConfig1, 'UpdateConfiguration', {'Limit': dbus.UInt32(0)}) q.expect_many(EventPattern('dbus-return', method='UpdateConfiguration'), EventPattern('stream-MODE', data=['#test', '-l']), EventPattern('dbus-signal', signal='PropertiesChanged', args=[cs.CHANNEL_IFACE_ROOM_CONFIG, {'Limit': 0}, []]) )
def test(q, bus, conn, stream, use_room=False): conn.Connect() q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[1, 1]), EventPattern('irc-connected')) q.expect('dbus-signal', signal='SelfHandleChanged') q.expect('dbus-signal', signal='StatusChanged', args=[0, 1]) self_handle = conn.Get(cs.CONN, 'SelfHandle', dbus_interface=cs.PROPERTIES_IFACE) request = build_request(conn, '#idletest', use_room) call_async(q, conn.Requests, 'CreateChannel', request) # Idle should try to join the channel. q.expect('stream-JOIN') # Meanwhile, in another application... call_async(q, conn, 'EnsureChannel', request, dbus_interface=cs.CONN_IFACE_REQUESTS) sync_dbus(bus, q, conn) # Now the ircd responds: stream.sendJoin('#idletest') cc, ec = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-return', method='EnsureChannel'), ) nc = q.expect('dbus-signal', signal='NewChannels') path, props = cc.value assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT assertSameSets([ cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_PASSWORD, cs.CHANNEL_IFACE_MESSAGES, cs.CHANNEL_IFACE_ROOM, cs.CHANNEL_IFACE_SUBJECT, cs.CHANNEL_IFACE_ROOM_CONFIG, cs.CHANNEL_IFACE_DESTROYABLE, ], props[cs.INTERFACES]) assert props[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert props[cs.TARGET_ID] == '#idletest' assertEquals('#idletest', props[cs.ROOM_NAME]) assertEquals('', props[cs.ROOM_SERVER]) assert props[cs.REQUESTED] assert props[cs.INITIATOR_HANDLE] == self_handle assert props[cs.INITIATOR_ID] == \ conn.inspect_contacts_sync([self_handle])[0] ec_yours, ec_path, ec_props = ec.value assert not ec_yours assert ec_path == path assert ec_props == props channels = nc.args[0] assert len(channels) == 1 nc_path, nc_props = channels[0] assert nc_path == path assert nc_props == props # And again? ec_ = conn.EnsureChannel(request, dbus_interface=cs.CONN_IFACE_REQUESTS) assert ec.value == ec_ chans = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE) assert len(chans) == 1 assert chans[0] == (path, props) chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text', ['Destroyable', 'Messages']) # Put an unacknowledged message into the channel stream.sendMessage('PRIVMSG', '#idletest', ':oi oi', prefix='lol') q.expect('dbus-signal', signal='MessageReceived', path=path) # Make sure Close()ing the channel makes it respawn. This avoids the old # bug where empathy-chat crashing booted you out of all your channels. patterns = [EventPattern('stream-PART')] q.forbid_events(patterns) chan.Close() q.expect('dbus-signal', signal='Closed', path=chan.object_path) e = q.expect('dbus-signal', signal='NewChannels') path, props = e.args[0][0] assertEquals(chan.object_path, path) # We requested the channel originally, but we didn't request it popping # back up. assertEquals(0, props[cs.INITIATOR_HANDLE]) assert not props[cs.REQUESTED] # The unacknowledged message should still be there and be marked as rescued. messages = chan.Properties.Get(cs.CHANNEL_IFACE_MESSAGES, 'PendingMessages') assertLength(1, messages) assert messages[0][0]['rescued'], messages[0] # Check that ensuring a respawned channel does what you'd expect. ec_yours, ec_path, ec_props = conn.EnsureChannel( request, dbus_interface=cs.CONN_IFACE_REQUESTS) assert not ec_yours assertEquals(chan.object_path, ec_path) assertEquals(props, ec_props) sync_stream(q, stream) q.unforbid_events(patterns) chan.RemoveMembers([self_handle], "bye bye cruel\r\nworld", dbus_interface=cs.CHANNEL_IFACE_GROUP) part_event = q.expect('stream-PART') # This is a regression test for # <https://bugs.freedesktop.org/show_bug.cgi?id=34812>, where part messages # were not correctly colon-quoted. # # It is also a regression test for # <https://bugs.freedesktop.org/show_bug.cgi?id=34840>, where newlines # weren't stripped from part messages. We check that both \r and \n are # replaced by harmless spaces. assertEquals("bye bye cruel world", part_event.data[1]) stream.sendPart('#idletest', stream.nick) q.expect('dbus-signal', signal='Closed') chans = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE) assert len(chans) == 0
def test(q, bus, conn, stream): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0, 1]) alice_handle, bob_handle = conn.get_contact_handles_sync(['alice', 'bob']) call_async( q, conn.Requests, 'CreateChannel', { CHANNEL_TYPE: CHANNEL_TYPE_TEXT, TARGET_HANDLE_TYPE: HT_ROOM, TARGET_ID: room }) q.expect('stream-JOIN') event = q.expect('dbus-return', method='CreateChannel') path = event.value[0] channel = wrap_channel(bus.get_object(conn.bus_name, path), 'Text', ['Subject2']) assertContains(CHANNEL_IFACE_SUBJECT, channel.Properties.Get(CHANNEL, 'Interfaces')) # No topic set subject_props = channel.Properties.GetAll(CHANNEL_IFACE_SUBJECT) assertEquals('', subject_props['Subject']) assertEquals(0x7fffffffffffffffL, subject_props['Timestamp']) assertEquals('', subject_props['Actor']) assertEquals(0, subject_props['ActorHandle']) # Before the topic arrives from the server, check that our API works okay. # FIXME: when we make SetSubject return asynchronously, this will need # revising. test_can_set(q, stream, channel) # We're told the channel's topic, and (in a separte message) who set it and # when. stream.sendMessage('332', stream.nick, room, ':Test123', prefix='idle.test.server') stream.sendMessage('333', stream.nick, room, 'bob', '1307802600', prefix='idle.test.server') # FIXME: signal these together, if possible. expect_subject_props_changed(q, {'Subject': 'Test123'}) expect_subject_props_changed(q, { 'Timestamp': 1307802600, 'Actor': 'bob', 'ActorHandle': bob_handle, }, exact_timestamp=True) # Another user changes the topic. stream.sendMessage('TOPIC', room, ':I am as high as a kite', prefix='alice') expect_subject_props_changed( q, { 'Subject': 'I am as high as a kite', 'Actor': 'alice', 'ActorHandle': alice_handle, 'Timestamp': 1234, }) # BIP omits the : for the trailing parameter if it's a single word, make # sure we pass that as well stream.sendMessage('TOPIC', room, 'badgers!', prefix='alice') expect_subject_props_changed( q, { 'Subject': 'badgers!', 'Actor': 'alice', 'ActorHandle': alice_handle, 'Timestamp': 1234, }) test_can_set(q, stream, channel) # Topic is read/write, if we get ops it should stay that way forbidden = [ EventPattern('dbus-signal', signal='PropertiesChanged', predicate=lambda e: e.args[0] == CHANNEL_IFACE_SUBJECT) ] q.forbid_events(forbidden) # Set ops, check that t flag becomes a no-op change_channel_mode(stream, '+o ' + stream.nick) change_channel_mode(stream, '+t') change_channel_mode(stream, '-t') change_channel_mode(stream, '-o ' + stream.nick) # Check that other flags don't cause issues change_channel_mode(stream, '+n') change_channel_mode(stream, '+n') change_channel_mode(stream, '+to ' + stream.nick) change_channel_mode(stream, '-to ' + stream.nick) sync_stream(q, stream) sync_dbus(bus, q, conn) q.unforbid_events(forbidden) # back to normal? test_can_set(q, stream, channel) # Check if setting ops gives us write access on +t channels change_channel_mode(stream, '+t') expect_and_check_can_set(q, channel, False) change_channel_mode(stream, '+o ' + stream.nick) expect_and_check_can_set(q, channel, True) change_channel_mode(stream, '-o ' + stream.nick) expect_and_check_can_set(q, channel, False) change_channel_mode(stream, '-t') expect_and_check_can_set(q, channel, True) # And back to normal again ? test_can_set(q, stream, channel) channel.Subject2.SetSubject('') # Verify that we send an empty final parameter ("clear the topic") as # opposed to no final parameter ("what is the topic"). q.expect('stream-TOPIC', data=[room, ''])
def test_simple_bools(q, bus, conn, stream): chan = setup(q, bus, conn, stream) # the three easy booleans for (prop, mode) in [('InviteOnly', 'i'), ('Moderated', 'm'), ('Private', 's')]: # first set them all to true call_async(q, chan.RoomConfig1, 'UpdateConfiguration', {prop: True}) q.expect_many(EventPattern('dbus-return', method='UpdateConfiguration'), EventPattern('stream-MODE', data=['#test', '+' + mode]), EventPattern('dbus-signal', signal='PropertiesChanged', args=[cs.CHANNEL_IFACE_ROOM_CONFIG, {prop: True}, []]) ) # then them all to false call_async(q, chan.RoomConfig1, 'UpdateConfiguration', {prop: False}) q.expect_many(EventPattern('dbus-return', method='UpdateConfiguration'), EventPattern('stream-MODE', data=['#test', '-' + mode]), EventPattern('dbus-signal', signal='PropertiesChanged', args=[cs.CHANNEL_IFACE_ROOM_CONFIG, {prop: False}, []]) ) # set them all to true now call_async(q, chan.RoomConfig1, 'UpdateConfiguration', {'InviteOnly': True, 'Moderated': True, 'Private': True}) # ... and a monster return q.expect_many(EventPattern('dbus-return', method='UpdateConfiguration'), EventPattern('stream-MODE', data=['#test', '+i']), EventPattern('stream-MODE', data=['#test', '+m']), EventPattern('stream-MODE', data=['#test', '+s']), EventPattern('dbus-signal', signal='PropertiesChanged', args=[cs.CHANNEL_IFACE_ROOM_CONFIG, {'InviteOnly': True, 'Moderated': True, 'Private': True}, []]) ) # set only moderated to false, forbidden = [EventPattern('stream-MODE', data=['#test', '+i']), EventPattern('stream-MODE', data=['#test', '+s'])] q.forbid_events(forbidden) call_async(q, chan.RoomConfig1, 'UpdateConfiguration', {'InviteOnly': True, 'Moderated': False, 'Private': True}) # ... and another monster return q.expect_many(EventPattern('dbus-return', method='UpdateConfiguration'), EventPattern('stream-MODE', data=['#test', '-m']), EventPattern('dbus-signal', signal='PropertiesChanged', args=[cs.CHANNEL_IFACE_ROOM_CONFIG, {'Moderated': False}, []]) ) sync_stream(q, stream) q.unforbid_events(forbidden)
def test(q, bus, conn, stream, use_room=False): conn.Connect() q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[1, 1]), EventPattern('irc-connected')) q.expect('dbus-signal', signal='SelfHandleChanged') q.expect('dbus-signal', signal='StatusChanged', args=[0, 1]) self_handle = conn.Get(cs.CONN, 'SelfHandle', dbus_interface=cs.PROPERTIES_IFACE) request = build_request(conn, '#idletest', use_room) call_async(q, conn.Requests, 'CreateChannel', request) # Idle should try to join the channel. q.expect('stream-JOIN') # Meanwhile, in another application... call_async(q, conn, 'EnsureChannel', request, dbus_interface=cs.CONN_IFACE_REQUESTS) sync_dbus(bus, q, conn) # Now the ircd responds: stream.sendJoin('#idletest') cc, ec = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-return', method='EnsureChannel'), ) nc = q.expect('dbus-signal', signal='NewChannels') path, props = cc.value assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT assertSameSets( [cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_PASSWORD, cs.CHANNEL_IFACE_MESSAGES, cs.CHANNEL_IFACE_ROOM, cs.CHANNEL_IFACE_SUBJECT, cs.CHANNEL_IFACE_ROOM_CONFIG, cs.CHANNEL_IFACE_DESTROYABLE, ], props[cs.INTERFACES]) assert props[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert props[cs.TARGET_ID] == '#idletest' assertEquals('#idletest', props[cs.ROOM_NAME]) assertEquals('', props[cs.ROOM_SERVER]) assert props[cs.REQUESTED] assert props[cs.INITIATOR_HANDLE] == self_handle assert props[cs.INITIATOR_ID] == \ conn.inspect_contacts_sync([self_handle])[0] ec_yours, ec_path, ec_props = ec.value assert not ec_yours assert ec_path == path assert ec_props == props channels = nc.args[0] assert len(channels) == 1 nc_path, nc_props = channels[0] assert nc_path == path assert nc_props == props # And again? ec_ = conn.EnsureChannel(request, dbus_interface=cs.CONN_IFACE_REQUESTS) assert ec.value == ec_ chans = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE) assert len(chans) == 1 assert chans[0] == (path, props) chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text', ['Destroyable', 'Messages']) # Put an unacknowledged message into the channel stream.sendMessage('PRIVMSG', '#idletest', ':oi oi', prefix='lol') q.expect('dbus-signal', signal='MessageReceived', path=path) # Make sure Close()ing the channel makes it respawn. This avoids the old # bug where empathy-chat crashing booted you out of all your channels. patterns = [EventPattern('stream-PART')] q.forbid_events(patterns) chan.Close() q.expect('dbus-signal', signal='Closed', path=chan.object_path) e = q.expect('dbus-signal', signal='NewChannels') path, props = e.args[0][0] assertEquals(chan.object_path, path) # We requested the channel originally, but we didn't request it popping # back up. assertEquals(0, props[cs.INITIATOR_HANDLE]) assert not props[cs.REQUESTED] # The unacknowledged message should still be there and be marked as rescued. messages = chan.Properties.Get(cs.CHANNEL_IFACE_MESSAGES, 'PendingMessages') assertLength(1, messages) assert messages[0][0]['rescued'], messages[0] # Check that ensuring a respawned channel does what you'd expect. ec_yours, ec_path, ec_props = conn.EnsureChannel(request, dbus_interface=cs.CONN_IFACE_REQUESTS) assert not ec_yours assertEquals(chan.object_path, ec_path) assertEquals(props, ec_props) sync_stream(q, stream) q.unforbid_events(patterns) chan.RemoveMembers([self_handle], "bye bye cruel\r\nworld", dbus_interface=cs.CHANNEL_IFACE_GROUP) part_event = q.expect('stream-PART') # This is a regression test for # <https://bugs.freedesktop.org/show_bug.cgi?id=34812>, where part messages # were not correctly colon-quoted. # # It is also a regression test for # <https://bugs.freedesktop.org/show_bug.cgi?id=34840>, where newlines # weren't stripped from part messages. We check that both \r and \n are # replaced by harmless spaces. assertEquals("bye bye cruel world", part_event.data[1]) stream.sendPart('#idletest', stream.nick) q.expect('dbus-signal', signal='Closed') chans = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE) assert len(chans) == 0
def test(q, bus, conn, stream): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0, 1]) alice_handle, bob_handle = conn.get_contact_handles_sync(['alice', 'bob']) call_async(q, conn.Requests, 'CreateChannel', { CHANNEL_TYPE: CHANNEL_TYPE_TEXT, TARGET_HANDLE_TYPE: HT_ROOM, TARGET_ID: room }) q.expect('stream-JOIN') event = q.expect('dbus-return', method='CreateChannel') path = event.value[0] channel = wrap_channel(bus.get_object(conn.bus_name, path), 'Text', ['Subject2']) assertContains(CHANNEL_IFACE_SUBJECT, channel.Properties.Get(CHANNEL, 'Interfaces')) # No topic set subject_props = channel.Properties.GetAll(CHANNEL_IFACE_SUBJECT) assertEquals('', subject_props['Subject']) assertEquals(0x7fffffffffffffffL, subject_props['Timestamp']) assertEquals('', subject_props['Actor']) assertEquals(0, subject_props['ActorHandle']) # Before the topic arrives from the server, check that our API works okay. # FIXME: when we make SetSubject return asynchronously, this will need # revising. test_can_set(q, stream, channel) # We're told the channel's topic, and (in a separte message) who set it and # when. stream.sendMessage('332', stream.nick, room, ':Test123', prefix='idle.test.server') stream.sendMessage('333', stream.nick, room, 'bob', '1307802600', prefix='idle.test.server') # FIXME: signal these together, if possible. expect_subject_props_changed(q, { 'Subject': 'Test123' }) expect_subject_props_changed(q, { 'Timestamp': 1307802600, 'Actor': 'bob', 'ActorHandle': bob_handle, }, exact_timestamp=True) # Another user changes the topic. stream.sendMessage('TOPIC', room, ':I am as high as a kite', prefix='alice') expect_subject_props_changed(q, { 'Subject': 'I am as high as a kite', 'Actor': 'alice', 'ActorHandle': alice_handle, 'Timestamp': 1234, }) # BIP omits the : for the trailing parameter if it's a single word, make # sure we pass that as well stream.sendMessage('TOPIC', room, 'badgers!', prefix='alice') expect_subject_props_changed(q, { 'Subject': 'badgers!', 'Actor': 'alice', 'ActorHandle': alice_handle, 'Timestamp': 1234, }) test_can_set(q, stream, channel) # Topic is read/write, if we get ops it should stay that way forbidden = [ EventPattern('dbus-signal', signal='PropertiesChanged', predicate=lambda e: e.args[0] == CHANNEL_IFACE_SUBJECT) ] q.forbid_events(forbidden) # Set ops, check that t flag becomes a no-op change_channel_mode (stream, '+o ' + stream.nick) change_channel_mode (stream, '+t') change_channel_mode (stream, '-t') change_channel_mode (stream, '-o ' + stream.nick) # Check that other flags don't cause issues change_channel_mode (stream, '+n') change_channel_mode (stream, '+n') change_channel_mode (stream, '+to ' + stream.nick) change_channel_mode (stream, '-to ' + stream.nick) sync_stream(q, stream) sync_dbus(bus, q, conn) q.unforbid_events(forbidden) # back to normal? test_can_set(q, stream, channel) # Check if setting ops gives us write access on +t channels change_channel_mode (stream, '+t') expect_and_check_can_set(q, channel, False) change_channel_mode (stream, '+o ' + stream.nick) expect_and_check_can_set(q, channel, True) change_channel_mode (stream, '-o ' + stream.nick) expect_and_check_can_set(q, channel, False) change_channel_mode (stream, '-t') expect_and_check_can_set(q, channel, True) # And back to normal again ? test_can_set(q, stream, channel) channel.Subject2.SetSubject('') # Verify that we send an empty final parameter ("clear the topic") as # opposed to no final parameter ("what is the topic"). q.expect('stream-TOPIC', data=[room, ''])