def test(q, bus, mc): account_manager = get_account_manager(bus) account_manager_iface = dbus.Interface(account_manager, cs.AM) # fd.o #25684: creating similarly-named accounts in very quick succession # used to fail params = dbus.Dictionary({ "account": "create-twice", "password": "******" }, signature='sv') simulated_cm = SimulatedConnectionManager(q, bus) account_manager = bus.get_object(cs.AM, cs.AM_PATH) am_iface = dbus.Interface(account_manager, cs.AM) call_async(q, am_iface, 'CreateAccount', 'fakecm', 'fakeprotocol', 'fakeaccount', params, {}) call_async(q, am_iface, 'CreateAccount', 'fakecm', 'fakeprotocol', 'fakeaccount', params, {}) ret1 = q.expect('dbus-return', method='CreateAccount') ret2 = q.expect('dbus-return', method='CreateAccount') path1 = ret1.value[0] path2 = ret2.value[0] assert path1 != path2
def test(q, bus, conn, stream): # Request a sidecar thate we support before we're connected; it should just # wait around until we're connected. call_async(q, conn.Sidecars1, 'EnsureSidecar', PLUGIN_IFACE) conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]) # Now we're connected, the call we made earlier should return. path, props = q.expect('dbus-return', method='EnsureSidecar').value # This sidecar doesn't even implement get_immutable_properties; it # should just get the empty dict filled in for it. assertEquals({}, props) gateways_iface = dbus.Interface(bus.get_object(conn.bus_name, path), PLUGIN_IFACE) test_success(q, gateways_iface, stream) test_conflict(q, gateways_iface, stream) test_not_acceptable(q, gateways_iface, stream) call_async(q, conn, 'Disconnect') q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_DISCONNECTED, cs.CSR_REQUESTED]), EventPattern('stream-closed'), ) stream.sendFooter() q.expect('dbus-return', method='Disconnect')
def test(q, bus, conn, stream): event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, event.stanza) # Force Gabble to process the vCard before calling any methods. sync_stream(q, stream) # Request our alias and avatar, expect them to be resolved from cache. handle = conn.Properties.Get(cs.CONN, "SelfHandle") call_async(q, conn.Avatars, 'RequestAvatars', [handle]) call_async(q, conn.Aliasing, 'RequestAliases', [handle]) # FIXME - find out why RequestAliases returns before RequestAvatar even # though everything's cached. Probably due to queueing, which means # conn-avatars don't look into the cache before making a request. Prolly # should make vcard_request look into the cache itself, and return # immediately. Or not, if it's g_idle()'d. So it's better if conn-aliasing # look into the cache itself. r1, r2 = q.expect_many( EventPattern('dbus-return', method='RequestAliases'), EventPattern('dbus-return', method='RequestAvatars')) # Default alias is our jid assert r1.value[0] == ['test@localhost']
def test_ensure_ensure(q, conn, bus, stream, room_jid): # Call Ensure twice for the same channel. call_async(q, conn.Requests, 'EnsureChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: room_jid, }) call_async(q, conn.Requests, 'EnsureChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: room_jid, }) mc, _ = q.expect_many( EventPattern('dbus-signal', signal='MembersChangedDetailed'), EventPattern('stream-presence', to=('%s/test' % room_jid))) added, removed, local_pending, remote_pending, details = mc.args assert added == [], mc.args assert removed == [], mc.args assert local_pending == [], mc.args assert len(remote_pending) == 1, mc.args # 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, 'test')) mc = q.expect('dbus-signal', signal='MembersChangedDetailed') added, removed, local_pending, remote_pending, details = mc.args assert len(added) == 2, mc.args assert removed == [], mc.args assert local_pending == [], mc.args assert remote_pending == [], mc.args members = conn.inspect_contacts_sync(added) members.sort() assert members == ['%s/bob' % room_jid, '%s/test' % room_jid], members # We should get two EnsureChannel returns es = [] while len(es) < 2: e = q.expect('dbus-return', method='EnsureChannel') es.append(e) e1, e2 = es assert len(e1.value) == 3 yours1, path1, props1 = e1.value assert len(e2.value) == 3 yours2, path2, props2 = e2.value # Exactly one Ensure should get Yours=True. assert (yours1 == (not yours2)) assert path1 == path2, (path1, path2) assert props1 == props2, (props1, props2)
def try_to_join_muc(q, bus, conn, stream, muc, request=None): """ Ask Gabble to join a MUC, and expect it to send <presence/> Returns: the stream-presence Event object. """ if request is None: request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: muc, } call_async(q, conn.Requests, 'CreateChannel', dbus.Dictionary(request, signature='sv')) join_event = q.expect('stream-presence', to='%s/test' % muc) # XEP-0045 §7.1.2 sez: # “MUC clients SHOULD signal their ability to speak the MUC protocol by # including in the initial presence stanza an empty <x/> element # qualified by the 'http://jabber.org/protocol/muc' namespace.” x_muc_nodes = xpath.queryForNodes('/presence/x[@xmlns="%s"]' % ns.MUC, join_event.stanza) assertLength(1, x_muc_nodes) return join_event
def text_remains_after_tube(q, bus, conn, stream): jid = '*****@*****.**' tube_chan, tube_path, _ = stream_tube(q, bus, conn, stream, 'CreateChannel', jid) text_chan, text_path, _ = text_channel(q, bus, conn, stream, 'CreateChannel', jid, presence=False) sync_dbus(bus, q, conn) tube_chan.Close() expect_close(q, tube_path) assert_not_on_bus(q, tube_chan) assert_on_bus(q, text_chan) call_async(q, text_chan.Properties, 'GetAll', cs.CHANNEL_TYPE_TEXT) q.expect('dbus-return', method='GetAll') text_chan.Close() expect_close(q, text_path, stream, jid) assert_not_on_bus(q, tube_chan) assert_not_on_bus(q, text_chan)
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 request_ft_channel(self): request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_FILE_TRANSFER, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_HANDLE: self.handle, cs.FT_CONTENT_TYPE: self.file.content_type, cs.FT_FILENAME: self.file.name, cs.FT_SIZE: self.file.size, cs.FT_CONTENT_HASH_TYPE: self.file.hash_type, cs.FT_CONTENT_HASH: self.file.hash, cs.FT_DESCRIPTION: self.file.description, cs.FT_DATE: self.file.date, cs.FT_INITIAL_OFFSET: 0, cs.FT_SERVICE_NAME: self.service_name, cs.FT_METADATA: dbus.Dictionary(self.metadata, signature='sas') } call_async(self.q, self.conn.Requests, 'CreateChannel', request) # no support for metadata, soz self.q.expect('dbus-error', method='CreateChannel', name=cs.NOT_CAPABLE) return True
def test(q, bus, conn, stream): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]) chan = join(q, bus, conn) stream.sendMessage('PRIVMSG', CHANNEL, ":who's underlined you?", prefix='marnie') q.expect('dbus-signal', signal='MessageReceived') # Without acking the message, destroy the channel. call_async(q, chan.Destroyable, "Destroy") q.expect_many( EventPattern('stream-PART'), EventPattern('dbus-signal', signal='Closed', path=chan.object_path), EventPattern('dbus-signal', signal='ChannelClosed', args=[chan.object_path]), EventPattern('dbus-return', method='Destroy'), ) # Now Create it again. If we haven't actually left the channel, this will # fail. chan = join(q, bus, conn) # The message should be gone. messages = chan.Properties.Get(cs.CHANNEL_IFACE_MESSAGES, 'PendingMessages') assertLength(0, messages)
def test(q, bus, conn, stream): # This sidecar sends a stanza, and waits for a reply, before being # created. pattern = EventPattern('stream-iq', to='sidecar.example.com', query_ns='http://example.com/sidecar') call_async(q, conn.Sidecars1, 'EnsureSidecar', TEST_PLUGIN_IFACE + ".IQ") e = q.expect_many(pattern)[0] # The server said yes, so we should get a sidecar back! acknowledge_iq(stream, e.stanza) q.expect('dbus-return', method='EnsureSidecar') identities = ["test/app-list//Test"] features = ["com.example.test1", "com.example.test2"] ver = compute_caps_hash(identities, features, {}) iq = IQ(stream, "get") query = iq.addElement((ns.DISCO_INFO, 'query')) query['node'] = ns.GABBLE_CAPS + '#' + ver stream.send(iq) e = q.expect('stream-iq', query_ns='http://jabber.org/protocol/disco#info') returned_features = [feature['var'] for feature in xpath.queryForNodes('/iq/query/feature', e.stanza)] assertEquals(features, returned_features) returned_identities = [identity['category'] + "/" + identity['type']+"//" + identity['name'] for identity in xpath.queryForNodes('/iq/query/identity', e.stanza)] assertEquals(identities, returned_identities) new_ver = compute_caps_hash(returned_identities, returned_features, {}) assertEquals(new_ver, ver)
def test(q, bus, conn, stream): event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, event.stanza) handle = conn.get_contact_handle_sync('*****@*****.**') call_async(q, conn.Aliasing, 'RequestAliases', [handle]) # First, Gabble sends a PEP query event = q.expect('stream-iq', to='*****@*****.**', iq_type='get', query_ns='http://jabber.org/protocol/pubsub', query_name='pubsub') # We disconnect too soon to get a reply disconnect_conn(q, conn, stream) # fd.o #31412 was that while the request pipeline was shutting down, # it would give the PEP query an error; the aliasing code would # respond by falling back to vCard via the request pipeline, which # was no longer there, *crash*. # check that Gabble hasn't crashed sync_dbus(bus, q, conn)
def test_deny_unblock_remove(q, bus, conn, stream, stored, deny): """ Test unblocking a contact, and, while that request is pending, deleting them. """ self_handle = conn.GetSelfHandle() # This contact was on our roster, blocked and subscribed, when we started. contact = '*****@*****.**' handle = conn.RequestHandles(cs.HT_CONTACT, [contact])[0] # They're blocked, and we have a bidi subscription, so they should be on # deny and stored. (We already checked this earlier, but we've been messing # with the roster so let's be sure the preconditions are okay...) assertContains(handle, deny.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members")) assertContains(handle, stored.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members")) # Unblock them. call_async(q, deny.Group, 'RemoveMembers', [handle], "") roster_event = q.expect('stream-iq', query_ns=ns.ROSTER) item = roster_event.query.firstChildElement() assertEquals(contact, item['jid']) assertDoesNotContain((ns.GOOGLE_ROSTER, 't'), item.attributes) # If we now remove them from stored, the edit shouldn't be sent until the # unblock event has had a reply. q.forbid_events(remove_events) call_async(q, stored.Group, 'RemoveMembers', [handle], "") # Make sure if the remove is sent prematurely, we catch it. sync_stream(q, stream) q.unforbid_events(remove_events) # So now we send a roster push and reply for the unblock request. stream.send(make_set_roster_iq(stream, 'test@localhost/Resource', contact, 'both', False, attrs={})) acknowledge_iq(stream, roster_event.stanza) # And on receiving the push and reply, Gabble should show them being # removed from deny, and send a remove. _, roster_event = q.expect_many( EventPattern('dbus-signal', signal='MembersChanged', args=['', [], [handle], [], [], self_handle, cs.GC_REASON_NONE], predicate=is_deny), remove_events[0], ) item = roster_event.query.firstChildElement() assertEquals(contact, item['jid']) stream.send(make_set_roster_iq(stream, 'test@localhost/Resource', contact, 'remove', False, attrs={})) acknowledge_iq(stream, roster_event.stanza) q.expect('dbus-signal', signal='MembersChanged', args=['', [], [handle], [], [], 0, cs.GC_REASON_NONE], predicate=is_stored)
def test(q, bus, conn, stream): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[0, 1]) # join a chat room with the same name as our nick call_async( q, conn.Requests, 'CreateChannel', { CHANNEL_TYPE: CHANNEL_TYPE_TEXT, TARGET_HANDLE_TYPE: HT_ROOM, TARGET_ID: CHANNEL }) # wait for the join to finish ret = q.expect('dbus-return', method='CreateChannel') muc_path = ret.value chan = bus.get_object(conn.bus_name, ret.value[0]) group_text_chan = dbus.Interface(chan, CHANNEL_TYPE_TEXT) group_text_chan.connect_to_signal('Received', group_received_cb) q.expect('dbus-signal', signal='MembersChanged') stream.sendMessage('PRIVMSG', NICK, ':PRIVATE', prefix=REMOTEUSER) event = q.expect('dbus-signal', signal='Received') # this seems a bit fragile, but I'm not entirely sure how else to ensure # that the message is not delivered to the MUC channel assert event.path not in muc_path # verify that we didn't receive a 'Received' D-Bus signal on the group text # channel global group_received_flag sync_dbus(bus, q, conn) assert group_received_flag == False call_async(q, conn, 'Disconnect') return True
def test(q, bus, conn, stream, is_google=False): props = conn.GetAll(cs.CONN_IFACE_CONTACT_INFO, dbus_interface=cs.PROPERTIES_IFACE) check_normal_props(props) conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]) props = conn.GetAll(cs.CONN_IFACE_CONTACT_INFO, dbus_interface=cs.PROPERTIES_IFACE) if is_google: check_google_props(props) # on a Google server, we can't use most vCard fields call_async(q, conn.ContactInfo, 'SetContactInfo', [('x-jabber', [], ['*****@*****.**'])]) q.expect('dbus-error', method='SetContactInfo', name=cs.INVALID_ARGUMENT) else: check_normal_props(props)
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()
def test(q, bus, conn, stream): conn.Connect() roster_event = q.expect('stream-iq', query_ns=ns.ROSTER) roster_event.stanza['type'] = 'result' call_async(q, conn, "RequestHandles", cs.HT_GROUP, ['test']) event = q.expect('dbus-return', method='RequestHandles') test_handle = event.value[0][0] # send an empty roster stream.send(roster_event.stanza) sync_stream(q, stream) sync_dbus(bus, q, conn) call_async(q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST, cs.TARGET_HANDLE_TYPE: cs.HT_GROUP, cs.TARGET_HANDLE: test_handle, }) event = q.expect('dbus-return', method='CreateChannel') ret_path, ret_props = event.value event = q.expect('dbus-signal', signal='NewChannels') path, props = event.args[0][0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_CONTACT_LIST, props assert props[cs.TARGET_HANDLE_TYPE] == cs.HT_GROUP, props assert props[cs.TARGET_HANDLE] == test_handle, props assert props[cs.TARGET_ID] == 'test', props assert ret_path == path, (ret_path, path) assert ret_props == props, (ret_props, props)
def request_stream_tube(q, bus, conn, method, jid): call_async(q, conn.Requests, method, { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: jid, cs.STREAM_TUBE_SERVICE: 'the.service', })
def test_error(q, bus, conn, stream): assertContains( cs.CONN_IFACE_POWER_SAVING, conn.Get(cs.CONN, "Interfaces", dbus_interface=cs.PROPERTIES_IFACE)) assertEquals( False, conn.Get(cs.CONN_IFACE_POWER_SAVING, "PowerSavingActive", dbus_interface=cs.PROPERTIES_IFACE)) call_async(q, conn.PowerSaving, 'SetPowerSaving', True) stanza = expect_command(q, 'enable') error = domish.Element((None, 'error')) error.addElement((ns.STANZA, 'service-unavailable')) send_error_reply(stream, stanza, error) q.expect('dbus-error', method='SetPowerSaving', name=cs.NOT_AVAILABLE) # Power saving state should remain false assertEquals( False, conn.Get(cs.CONN_IFACE_POWER_SAVING, "PowerSavingActive", dbus_interface=cs.PROPERTIES_IFACE))
def test_error(q, bus, conn, stream): assertContains(cs.CONN_IFACE_POWER_SAVING, conn.Get(cs.CONN, "Interfaces", dbus_interface=cs.PROPERTIES_IFACE)) assertEquals (False, conn.Get(cs.CONN_IFACE_POWER_SAVING, "PowerSavingActive", dbus_interface=cs.PROPERTIES_IFACE)) call_async(q, conn.PowerSaving, 'SetPowerSaving', True) stanza = expect_command(q, 'enable') error = domish.Element((None, 'error')) error.addElement((ns.STANZA, 'service-unavailable')) send_error_reply(stream, stanza, error) q.expect('dbus-error', method='SetPowerSaving', name=cs.NOT_AVAILABLE) # Power saving state should remain false assertEquals (False, conn.Get(cs.CONN_IFACE_POWER_SAVING, "PowerSavingActive", dbus_interface=cs.PROPERTIES_IFACE))
def request_text_channel(q, bus, conn, method, jid): call_async( q, conn.Requests, method, { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: jid, })
def test(q, bus, conn, stream): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]) self_handle = conn.GetSelfHandle() jids = ['*****@*****.**', '*****@*****.**'] call_async(q, conn, 'RequestHandles', 1, jids) event = q.expect('dbus-return', method='RequestHandles') handles = event.value[0] properties = conn.GetAll( cs.CONN_IFACE_REQUESTS, dbus_interface=cs.PROPERTIES_IFACE) assert properties.get('Channels') == [], properties['Channels'] assert ({cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, }, [cs.TARGET_HANDLE, cs.TARGET_ID], ) in properties.get('RequestableChannelClasses'),\ properties['RequestableChannelClasses'] test_ensure_ensure(q, conn, self_handle, jids[0], handles[0]) test_request_ensure(q, conn, self_handle, jids[1], handles[1])
def disconnected_before_reply(q, stream, conn): iq = call_create(q, conn, 'slow.localhost') call_async(q, conn, 'Disconnect') event = q.expect('dbus-error', method='CreateChannel') assertDBusError(cs.DISCONNECTED, event.error)
def test(q, bus, conn, stream): event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, event.stanza) # Force Gabble to process the vCard before calling any methods. sync_stream(q, stream) handle = conn.Properties.Get(cs.CONN, "SelfHandle") call_async(q, conn.Avatars, 'SetAvatar', 'william shatner', 'image/x-actor-name') event = q.expect('stream-iq', iq_type='get', to=None, query_ns='vcard-temp', query_name='vCard') reply = make_result_iq(stream, event.stanza) reply['type'] = 'error' reply.addChild( elem('error')(elem(ns.STANZA, 'forbidden')(), elem(ns.STANZA, 'text')(u'zomg whoops'))) stream.send(reply) event = q.expect('dbus-error', method='SetAvatar', name=cs.NOT_AVAILABLE)
def test(q, bus, conn, stream): conn_props = dbus.Interface(conn, cs.PROPERTIES_IFACE) # Try to CreateChannel with unknown properties # Gabble must return an error call_async(q, conn.Requests, 'CreateChannel', {cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_ID: "*****@*****.**", 'this.property.does.not.exist': 'this.value.should.not.exist' }) ret = q.expect('dbus-error', method='CreateChannel') check_no_tubes(conn_props) # Try to CreateChannel with missing properties ("Service") # Gabble must return an error call_async(q, conn.Requests, 'CreateChannel', {cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_ID: "*****@*****.**", }) ret = q.expect('dbus-error', method='CreateChannel') check_no_tubes(conn_props)
def test(q, bus, conn, stream): roster_event = q.expect('stream-iq', query_ns=ns.ROSTER) roster_event.stanza['type'] = 'result' call_async(q, conn, "RequestHandles", cs.HT_GROUP, ['test']) event = q.expect('dbus-return', method='RequestHandles') test_handle = event.value[0][0] call_async(q, conn, 'RequestChannel', cs.CHANNEL_TYPE_CONTACT_LIST, cs.HT_GROUP, test_handle, True) # A previous incarnation of this test --- written with the intention that # RequestChannel would be called before the roster was received, to expose # a bug in Gabble triggered by that ordering --- was racy: if the D-Bus # daemon happened to be particularly busy, the call to RequestChannel # reached Gabble after the roster stanza. (The race was discovered when # that reversed order triggered a newly-introduced instance of the # opposite bug to the one the test was targetting!) So we sync the XMPP # stream and D-Bus queue here. sync_stream(q, stream) sync_dbus(bus, q, conn) # send an empty roster stream.send(roster_event.stanza) event = q.expect('dbus-return', method='RequestChannel') path = event.value[0] while True: event = q.expect('dbus-signal', signal='NewChannel') assert event.args[0] == path, (event.args, path) _, type, handle_type, handle, suppress_handler = event.args if handle_type == cs.HT_GROUP and handle == test_handle: break
def test(q, bus, conn, stream): conn.Connect() q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[1, 1]), EventPattern('irc-connected')) q.expect('dbus-signal', signal='SelfHandleChanged', args=[1]) q.expect('dbus-signal', signal='StatusChanged', args=[0, 1]) CHANNEL_NAME = "#idletest" self_handle = conn.Get(CONN, 'SelfHandle', dbus_interface=PROPERTIES_IFACE) # The bouncer initiates a JOIN. path = test_join_bouncer(q, conn, stream, CHANNEL_NAME) # We PART. chan = make_channel_proxy(conn, path, 'Channel') chan.RemoveMembers([self_handle], "bye bye cruel world", dbus_interface=CHANNEL_IFACE_GROUP) q.expect('dbus-signal', signal='MembersChanged') # The bouncer initiates a JOIN to force the issue. test_join_bouncer(q, conn, stream, CHANNEL_NAME) call_async(q, conn, 'Disconnect') q.expect_many( EventPattern('dbus-return', method='Disconnect'), EventPattern('dbus-signal', signal='StatusChanged', args=[2, 1])) return True
def test(q, bus, conn, stream): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]) # Need to call this asynchronously as it involves Gabble sending us a # query. jids = ['*****@*****.**', '*****@*****.**'] call_async(q, conn, 'RequestHandles', 2, jids) # Gabble is stupid and discos the alleged conf server twice. for i in [0,1]: event = q.expect('stream-iq', to='conf.localhost', query_ns='http://jabber.org/protocol/disco#info') result = make_result_iq(stream, event.stanza) feature = result.firstChildElement().addElement('feature') feature['var'] = 'http://jabber.org/protocol/muc' stream.send(result) event = q.expect('dbus-return', method='RequestHandles') room_handles = event.value[0] test_create_ensure(q, conn, bus, stream, jids[0], room_handles[0]) test_ensure_ensure(q, conn, bus, stream, jids[1], room_handles[1])
def test(q, bus, conn, stream): event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, event.stanza) handle = conn.get_contact_handle_sync('*****@*****.**') call_async(q, conn.Aliasing, 'RequestAliases', [handle]) # Nack PEP query. event = q.expect('stream-iq', to='*****@*****.**', iq_type='get', query_ns='http://jabber.org/protocol/pubsub', query_name='pubsub') items = event.query.firstChildElement() assert items.name == 'items' assert items['node'] == "http://jabber.org/protocol/nick" result = make_result_iq(stream, event.stanza) result['type'] = 'error' error = result.addElement('error') error['type'] = 'auth' error.addElement('forbidden', 'urn:ietf:params:xml:ns:xmpp-stanzas') stream.send(result) event = q.expect('stream-iq', to='*****@*****.**', query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, event.stanza) q.expect('dbus-return', method='RequestAliases', value=([u'*****@*****.**'],)) # A second request should be satisfied from the cache. assert conn.Aliasing.RequestAliases([handle]) == ['*****@*****.**']
def run_test(q, bus, conn, stream, jt, decloak_allowed): """ Requests streams on a media channel to jt.remote_jid without having their presence at all. """ call_async(q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CALL, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_ID: jt.peer, cs.CALL_INITIAL_AUDIO: True, cs.CALL_INITIAL_VIDEO: False, }) e = q.expect('stream-presence', to=jt.peer_bare_jid, presence_type=None) nodes = [ node for node in e.stanza.elements(uri=ns.TEMPPRES, name='temppres') ] assertLength(1, nodes) assertEquals('media', nodes[0].getAttribute('reason')) if decloak_allowed: jt.send_presence_and_caps() # RequestStreams should now happily complete q.expect('dbus-return', method='CreateChannel') else: q.expect('dbus-error', method='CreateChannel', name=cs.OFFLINE)
def test(q, bus, conn, stream): conn.Connect() # Initial vCard request. Respond only after we call SetAliases(). vcard_get_event = q.expect('stream-iq', iq_type='get', to=None, query_ns=ns.VCARD_TEMP, query_name='vCard') sync_stream(q, stream) handle = conn.GetSelfHandle() call_async(q, conn.Aliasing, 'SetAliases', {handle: 'Some Guy'}) sync_dbus(bus, q, conn) acknowledge_iq(stream, vcard_get_event.stanza) # Gabble sets a new vCard with our nickname. vcard_set_event = q.expect('stream-iq', iq_type='set', query_ns=ns.VCARD_TEMP, query_name='vCard') # Before the server replies, the user sets their avatar. call_async(q, conn.Avatars, 'SetAvatar', 'hello', 'image/png') sync_dbus(bus, q, conn) acknowledge_iq(stream, vcard_set_event.stanza) vcard_set_event = q.expect('stream-iq', iq_type='set', query_ns=ns.VCARD_TEMP, query_name='vCard') acknowledge_iq(stream, vcard_set_event.stanza) q.expect('dbus-return', method='SetAvatar') # And then crashes. sync_stream(q, stream) conn.Disconnect() q.expect('dbus-signal', signal='StatusChanged', args=[2, 1])
def test(q, bus, conn, stream): conn_props = dbus.Interface(conn, cs.PROPERTIES_IFACE) # Try to CreateChannel with unknown properties # Gabble must return an error call_async( q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_ID: "*****@*****.**", 'this.property.does.not.exist': 'this.value.should.not.exist' }) ret = q.expect('dbus-error', method='CreateChannel') check_no_tubes(conn_props) # Try to CreateChannel with missing properties ("Service") # Gabble must return an error call_async( q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_ID: "*****@*****.**", }) ret = q.expect('dbus-error', method='CreateChannel') check_no_tubes(conn_props)
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 request_random_activity_view(q, stream, conn, max, id, activities): requests_iface = dbus.Interface(conn, cs.CONN_IFACE_REQUESTS) call_async(q, requests_iface, 'CreateChannel', { cs.CHANNEL_TYPE: 'org.laptop.Telepathy.Channel.Type.ActivityView', 'org.laptop.Telepathy.Channel.Interface.View.MaxSize': max }) iq_event, return_event = q.expect_many( EventPattern('stream-iq', to='gadget.localhost', query_ns=ns.OLPC_ACTIVITY), EventPattern('dbus-return', method='CreateChannel')) view = iq_event.stanza.firstChildElement() assert view.name == 'view' assert view['id'] == id assert view['size'] == str(max) random = xpath.queryForNodes('/iq/view/random', iq_event.stanza) send_reply_to_activity_view_request(stream, iq_event.stanza, activities) props = return_event.value[1] assert props['org.laptop.Telepathy.Channel.Type.ActivityView.Properties'] == {} assert props['org.laptop.Telepathy.Channel.Type.ActivityView.Participants'] == [] return return_event.value[0]
def test_too_slow(self, req1, req2, too_slow): """ Regression test for a bug where if the channel was closed before the HTTP responses arrived, the responses finally arriving crashed Gabble. """ # User gets bored, and ends the call. e = EventPattern('dbus-signal', signal='Closed', path=chan.object_path) if too_slow == TOO_SLOW_CLOSE: call_async(self.q, self.chan, 'Close', dbus_interface=cs.CHANNEL) elif too_slow == TOO_SLOW_REMOVE_SELF: self.chan.Hangup (0, "", "", dbus_interface=cs.CHANNEL_TYPE_CALL) elif too_slow == TOO_SLOW_DISCONNECT: disconnect_conn(q, conn, stream, [e]) try: chan.GetMembers() except dbus.DBusException, e: # This should fail because the object's gone away, not because # Gabble's crashed. assert cs.DBUS_ERROR_UNKNOWN_METHOD == e.get_dbus_name(), \ "maybe Gabble crashed? %s" % e else: # Gabble will probably also crash in a moment, because the http # request callbacks will be called after the channel's meant to # have died, which will cause the channel to try to call # methods on the (finalized) connection. assert False, "the channel should be dead by now" return
def gadget_publish(q, stream, conn, publish): gadget_iface = dbus.Interface(conn, 'org.laptop.Telepathy.Gadget') call_async(q, gadget_iface, 'Publish', publish) if publish: q.expect_many( EventPattern('stream-presence', presence_type='subscribe'), EventPattern('dbus-return', method='Publish')) # accept the request presence = elem('presence', to='test@localhost', from_='gadget.localhost', type='subscribed') stream.send(presence) # send a subscribe request presence = elem('presence', to='test@localhost', from_='gadget.localhost', type='subscribe') stream.send(presence) q.expect('stream-presence', presence_type='subscribed'), else: q.expect_many( EventPattern('stream-presence', presence_type='unsubscribe'), EventPattern('stream-presence', presence_type='unsubscribed'), EventPattern('dbus-return', method='Publish')) # Gadget tries to subscribe but is refused now presence = elem('presence', to='test@localhost', from_='gadget.localhost', type='subscribe') stream.send(presence)
def test(q, bus, conn, stream): # Request a sidecar thate we support before we're connected; it should just # wait around until we're connected. call_async(q, conn.Future, 'EnsureSidecar', PLUGIN_IFACE) conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]) # Now we're connected, the call we made earlier should return. path, props = q.expect('dbus-return', method='EnsureSidecar').value # This sidecar doesn't even implement get_immutable_properties; it # should just get the empty dict filled in for it. assertEquals({}, props) gateways_iface = dbus.Interface(bus.get_object(conn.bus_name, path), PLUGIN_IFACE) test_success(q, gateways_iface, stream) test_conflict(q, gateways_iface, stream) test_not_acceptable(q, gateways_iface, stream) call_async(q, conn, 'Disconnect') q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_DISCONNECTED, cs.CSR_REQUESTED]), EventPattern('stream-closed'), ) stream.sendFooter() q.expect('dbus-return', method='Disconnect')
def join_muc(q, bus, conn, stream, muc, request=None): """ Joins 'muc', returning the muc's handle, a proxy object for the channel, its path and its immutable properties just after the CreateChannel event has fired. The room contains one other member. """ if request is None: request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: muc, } muc_handle = request_muc_handle(q, conn, stream, muc) requests = dbus.Interface(conn, cs.CONN_IFACE_REQUESTS) call_async(q, requests, 'CreateChannel', dbus.Dictionary(request, signature='sv')) q.expect('stream-presence', to='%s/test' % muc) # Send presence for other member of room. stream.send(make_muc_presence('owner', 'moderator', muc, 'bob')) # Send presence for own membership of room. stream.send(make_muc_presence('none', 'participant', muc, 'test')) event = q.expect('dbus-return', method='CreateChannel') path, props = event.value chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text', ['Messages']) return (muc_handle, chan, path, props)
def offer_dbus_tube(q, bus, conn, stream): connect_and_announce_alice(q, bus, conn, stream) # Offer a private D-Bus tube just to check if the proxy is present in the # SOCKS5 offer call_async(q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_DBUS_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_ID: 'alice@localhost', cs.DBUS_TUBE_SERVICE_NAME: 'com.example.TestCase'}) # Proxy queries are send when creating the channel return_event, e1, e2 = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), proxy_query_events[0], proxy_query_events[1]) send_socks5_reply(stream, e1.stanza) send_socks5_reply(stream, e2.stanza) path, props = return_event.value tube_chan = bus.get_object(conn.bus_name, path) dbus_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_DBUS_TUBE) dbus_tube_iface.Offer({}, cs.SOCKET_ACCESS_CONTROL_CREDENTIALS) proxies = wait_si_and_return_proxies(q, stream) check_proxies([('fallback2-proxy.localhost', '127.0.0.1', '6789'), ('fallback1-proxy.localhost', '127.0.0.1', '12345')], proxies)
def setup(q, bus, conn, stream, op_user=True): conn.Connect() q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]) # test MUC channel call_async(q, conn.Requests, 'CreateChannel', {cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: '#test'}) ret, _, _ = q.expect_many(EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='MembersChanged'), EventPattern('stream-MODE', data=['#test'])) chan = wrap_channel(bus.get_object(conn.bus_name, ret.value[0]), 'Text', extra=['RoomConfig1']) change_channel_mode(stream, '+n') q.expect('dbus-signal', signal='PropertiesChanged', args=[cs.CHANNEL_IFACE_ROOM_CONFIG, {'ConfigurationRetrieved': True}, []]) if op_user: change_channel_mode(stream, '+o test') q.expect_many(EventPattern('dbus-signal', signal='GroupFlagsChanged', args=[cs.GF_MESSAGE_REMOVE | cs.GF_CAN_REMOVE, 0]), EventPattern('dbus-signal', signal='PropertiesChanged', args=[cs.CHANNEL_IFACE_ROOM_CONFIG, {'CanUpdateConfiguration': True}, []])) return chan
def test_mode_no_op(q, bus, conn, stream): chan = setup(q, bus, conn, stream, op_user=False) # we haven't been opped, so we can't be allowed to change these # values for key, val in [('InviteOnly', True), ('Moderated', True), ('Private', True), ('Password', True), ('Limit', 99)]: call_async(q, chan.RoomConfig1, 'UpdateConfiguration', {key: val}) q.expect('dbus-error', method='UpdateConfiguration', name=cs.PERMISSION_DENIED) # op the user change_channel_mode(stream, '+o test') q.expect('dbus-signal', signal='PropertiesChanged', args=[cs.CHANNEL_IFACE_ROOM_CONFIG, {'CanUpdateConfiguration': True}, []]) # remove ops again change_channel_mode(stream, '-o test') q.expect('dbus-signal', signal='PropertiesChanged', args=[cs.CHANNEL_IFACE_ROOM_CONFIG, {'CanUpdateConfiguration': False}, []])
def test_channels(q, bus, conn, stream): jid = '*****@*****.**' tube_chan, _, _ = stream_tube(q, bus, conn, stream, 'CreateChannel', jid) text_chan, text_path, _ = text_channel(q, bus, conn, stream, 'CreateChannel', jid, presence=False) text_chan.Close() expect_close(q, text_path) # the following are basically the same as assert_[not_]on_bus() # but they look pretty. # methods on the text channel should fail call_async(q, text_chan.Properties, 'GetAll', cs.CHANNEL_TYPE_TEXT) q.expect('dbus-error', method='GetAll') # but methods on the tube should pass call_async(q, tube_chan.Properties, 'GetAll', cs.CHANNEL_TYPE_STREAM_TUBE) q.expect('dbus-return', method='GetAll')
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(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '')) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', False) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'ConnectAutomatically', False) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing Enabled')) q.expect('dbus-return', method='Set') # Go online by setting Enabled call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', True) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', path=cs.tp_path_prefix + '/ConnectionManager/fakecm', interface=cs.tp_name_prefix + '.ConnectionManager', handled=False)
def test(q, bus, conn, stream): conn.Connect() q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[1, 1]), EventPattern('irc-connected')) q.expect('dbus-signal', signal='SelfHandleChanged', args=[1L]) q.expect('dbus-signal', signal='StatusChanged', args=[0, 1]) CHANNEL_NAME = "#idletest" self_handle = conn.Get(CONN, 'SelfHandle', dbus_interface=PROPERTIES_IFACE) # The bouncer initiates a JOIN. path = test_join_bouncer(q, conn, stream, CHANNEL_NAME) # We PART. chan = make_channel_proxy(conn, path, 'Channel') chan.RemoveMembers([self_handle], "bye bye cruel world", dbus_interface=CHANNEL_IFACE_GROUP) q.expect('dbus-signal', signal='MembersChanged') # The bouncer initiates a JOIN to force the issue. test_join_bouncer(q, conn, stream, CHANNEL_NAME) call_async(q, conn, 'Disconnect') q.expect_many( EventPattern('dbus-return', method='Disconnect'), EventPattern('dbus-signal', signal='StatusChanged', args=[2, 1])) return True
def test_sending(q, bus, conn, stream, chan): # Send a message using Text API text_chan = dbus.Interface(chan, cs.CHANNEL_TYPE_TEXT) call_async(q, text_chan, 'Send', cs.MT_NORMAL, "Hi!") q.expect_many( EventPattern('dbus-signal', interface=cs.CHANNEL_IFACE_MESSAGES, signal='MessageSent'), EventPattern('dbus-signal', interface=cs.CHANNEL_TYPE_TEXT, signal='Sent'), EventPattern('dbus-return', method='Send')) # Send a message using Messages API msg_iface = dbus.Interface(chan, cs.CHANNEL_IFACE_MESSAGES) message = [{ 'message-type': cs.MT_NORMAL }, { 'content-type': 'text/plain', 'content': 'What\'s up?', }] call_async(q, msg_iface, 'SendMessage', message, 0) q.expect_many( EventPattern('dbus-signal', interface=cs.CHANNEL_IFACE_MESSAGES, signal='MessageSent'), EventPattern('dbus-signal', interface=cs.CHANNEL_TYPE_TEXT, signal='Sent'), EventPattern('dbus-return', method='SendMessage'))
def test(q, bus, conn, stream): conn.Connect() q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[1, 1]), EventPattern('irc-connected')) q.expect('dbus-signal', signal='SelfHandleChanged', args=[1L]) q.expect('dbus-signal', signal='StatusChanged', args=[0, 1]) call_async(q, conn.Requests, 'CreateChannel', { CHANNEL_TYPE: CHANNEL_TYPE_TEXT, TARGET_HANDLE_TYPE: HT_ROOM, TARGET_ID: '#idletest' }) q.expect('stream-JOIN') event = q.expect('dbus-return', method='CreateChannel') obj_path = event.value[0] pattern = EventPattern('dbus-signal', signal='NewChannels') event = q.expect_many(pattern)[0] q.forbid_events([pattern]) channel_details = event.args[0] assert len(channel_details) == 1 path, props = channel_details[0] assert path == obj_path assert props[TARGET_HANDLE_TYPE] == HT_ROOM assert props[CHANNEL_TYPE] == CHANNEL_TYPE_TEXT q.expect('dbus-signal', signal='MembersChanged') call_async(q, conn, 'Disconnect') q.expect_many( EventPattern('dbus-return', method='Disconnect'), EventPattern('dbus-signal', signal='StatusChanged', args=[2, 1])) return True
def test(q, bus, conn, stream): event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, event.stanza) handle = conn.RequestHandles(1, ['*****@*****.**'])[0] call_async(q, conn.Aliasing, 'RequestAliases', [handle]) # Nack PEP query. event = q.expect('stream-iq', to='*****@*****.**', iq_type='get', query_ns='http://jabber.org/protocol/pubsub', query_name='pubsub') items = event.query.firstChildElement() assert items.name == 'items' assert items['node'] == "http://jabber.org/protocol/nick" result = make_result_iq(stream, event.stanza) result['type'] = 'error' error = result.addElement('error') error['type'] = 'auth' error.addElement('forbidden', 'urn:ietf:params:xml:ns:xmpp-stanzas') stream.send(result) event = q.expect('stream-iq', to='*****@*****.**', query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, event.stanza) q.expect('dbus-return', method='RequestAliases', value=([u'*****@*****.**'],)) # A second request should be satisfied from the cache. assert conn.Aliasing.RequestAliases([handle]) == ['*****@*****.**']
def test(q, bus, mc): account_manager = get_account_manager(bus) account_manager_iface = dbus.Interface(account_manager, cs.AM) # fd.o #25684: creating similarly-named accounts in very quick succession # used to fail params = dbus.Dictionary({"account": "create-twice", "password": "******"}, signature='sv') simulated_cm = SimulatedConnectionManager(q, bus) account_manager = bus.get_object(cs.AM, cs.AM_PATH) am_iface = dbus.Interface(account_manager, cs.AM) call_async(q, am_iface, 'CreateAccount', 'fakecm', 'fakeprotocol', 'fakeaccount', params, {}) call_async(q, am_iface, 'CreateAccount', 'fakecm', 'fakeprotocol', 'fakeaccount', params, {}) ret1 = q.expect('dbus-return', method='CreateAccount') ret2 = q.expect('dbus-return', method='CreateAccount') path1 = ret1.value[0] path2 = ret2.value[0] assert path1 != path2
def test(q, bus, conn, stream): conn.Connect() _, event = q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]), EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard')) acknowledge_iq(stream, event.stanza) # Force Gabble to process the vCard before calling any methods. sync_stream(q, stream) handle = conn.GetSelfHandle() call_async(q, conn.Avatars, 'SetAvatar', 'william shatner', 'image/x-actor-name') event = q.expect('stream-iq', iq_type='get', to=None, query_ns='vcard-temp', query_name='vCard') reply = make_result_iq(stream, event.stanza) reply['type'] = 'error' reply.addChild(elem('error')( elem(ns.STANZA, 'forbidden')(), elem(ns.STANZA, 'text')(u'zomg whoops'))) stream.send(reply) event = q.expect('dbus-error', method='SetAvatar', name=cs.NOT_AVAILABLE)