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) # Ensure that it's enabled but has offline RP and doesn't connect # automatically 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, 'AutomaticPresence', (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')) q.expect('dbus-return', method='Set') q.expect( 'dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('AutomaticPresence', (None, None, None))[1] == 'busy') call_async(q, account_props, 'Set', cs.ACCOUNT, 'ConnectAutomatically', False) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', True) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('Enabled')) # Requesting a channel will put us online user_action_time = dbus.Int64(1238582606) cd = bus.get_object(cs.CD, cs.CD_PATH) request = dbus.Dictionary( { cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': 'juliet', }, signature='sv') call_async(q, cd, 'CreateChannel', account.object_path, request, user_action_time, "", dbus_interface=cs.CD) ret = q.expect('dbus-return', method='CreateChannel') request_path = ret.value[0] cr = bus.get_object(cs.AM, request_path) request_props = cr.GetAll(cs.CR, dbus_interface=cs.PROPERTIES_IFACE) assert request_props['Account'] == account.object_path assert request_props['Requests'] == [request] assert request_props['UserActionTime'] == user_action_time assert request_props['PreferredHandler'] == "" assert request_props['Interfaces'] == [] # make sure RequestConnection doesn't get called until we Proceed events = [EventPattern('dbus-method-call', method='RequestConnection')] q.forbid_events(events) sync_dbus(bus, q, mc) q.unforbid_events(events) cr.Proceed(dbus_interface=cs.CR) 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) conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', 'myself', has_presence=True) q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) conn.presence = dbus.Struct((cs.PRESENCE_AVAILABLE, 'available', ''), signature='uss') _, cm_request_call = q.expect_many( EventPattern('dbus-method-call', path=conn.object_path, interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence', args=['busy', 'Testing automatic presence'], handled=True), EventPattern('dbus-method-call', path=conn.object_path, interface=cs.CONN_IFACE_REQUESTS, method='CreateChannel', args=[request], handled=False), ) q.dbus_emit(conn.object_path, cs.CONN_IFACE_SIMPLE_PRESENCE, 'PresencesChanged', { conn.self_handle: (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence') }, signature='a{u(uss)}') # Time passes. A channel is returned. channel_immutable = dbus.Dictionary(request) channel_immutable[cs.CHANNEL + '.InitiatorID'] = conn.self_ident channel_immutable[cs.CHANNEL + '.InitiatorHandle'] = conn.self_handle channel_immutable[cs.CHANNEL + '.Requested'] = True channel_immutable[cs.CHANNEL + '.Interfaces'] = \ dbus.Array([], signature='s') channel_immutable[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel = SimulatedChannel(conn, channel_immutable) # this order of events is guaranteed by telepathy-spec (since 0.17.14) q.dbus_return(cm_request_call.message, channel.object_path, channel.immutable, signature='oa{sv}') channel.announce() # there's no handler, so it gets shot down q.expect('dbus-method-call', path=channel.object_path, method='Close', handled=True)
def test(q, bus, unused, **kwargs): fake_accounts_service = kwargs['fake_accounts_service'] preseed(q, bus, fake_accounts_service) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') user_action_time = dbus.Int64(1238582606) # A client and a CM are already running client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False, implement_get_interfaces=False) simulated_cm = SimulatedConnectionManager(q, bus) # service-activate MC; it will try to introspect the running client. mc = MC(q, bus, wait_for_names=False) get_interfaces, = mc.wait_for_names( EventPattern('dbus-method-call', path=client.object_path, interface=cs.PROPERTIES_IFACE, method='Get', args=[cs.CLIENT, 'Interfaces'], handled=False)) # The client doesn't reply just yet; meanwhile, immediately make a channel # request account = bus.get_object( cs.MC, cs.tp_path_prefix + '/Account/fakecm/fakeprotocol/jc_2edenton_40unatco_2eint') cd = bus.get_object(cs.MC, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) request = dbus.Dictionary( { cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': '*****@*****.**', }, signature='sv') call_async(q, cd, 'CreateChannel', account.object_path, request, user_action_time, client.bus_name, dbus_interface=cs.CD) ret = q.expect('dbus-return', method='CreateChannel') request_path = ret.value[0] # chat UI connects to signals and calls ChannelRequest.Proceed() cr = bus.get_object(cs.MC, request_path) request_props = cr.GetAll(cs.CR, dbus_interface=cs.PROPERTIES_IFACE) assert request_props['Account'] == account.object_path assert request_props['Requests'] == [request] assert request_props['UserActionTime'] == user_action_time assert request_props['PreferredHandler'] == client.bus_name assert request_props['Interfaces'] == [] call_async(q, cr, 'Proceed', dbus_interface=cs.CR) e = q.expect('dbus-method-call', method='RequestConnection', args=[ 'fakeprotocol', { 'account': '*****@*****.**', 'password': '******', } ], destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', path=cs.tp_path_prefix + '/ConnectionManager/fakecm', interface=cs.tp_name_prefix + '.ConnectionManager', handled=False) conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', 'the_conn', '*****@*****.**') q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # A channel appears spontaneously announcement_immutable = dbus.Dictionary(text_fixed_properties) announcement_immutable[cs.CHANNEL + '.TargetID'] = '*****@*****.**' announcement_immutable[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, '*****@*****.**') announcement_immutable[cs.CHANNEL + '.InitiatorHandle'] = \ announcement_immutable[cs.CHANNEL + '.TargetHandle'] announcement_immutable[cs.CHANNEL + '.InitiatorID'] = \ announcement_immutable[cs.CHANNEL + '.TargetID'] announcement_immutable[cs.CHANNEL + '.Interfaces'] = \ dbus.Array([], signature='s') announcement_immutable[cs.CHANNEL + '.Requested'] = False announcement = SimulatedChannel(conn, announcement_immutable) announcement.announce() # Now the Client returns its info q.dbus_return( get_interfaces.message, dbus.Array( [cs.HANDLER, cs.OBSERVER, cs.APPROVER, cs.CLIENT_IFACE_REQUESTS], signature='s'), signature='v') expect_client_setup(q, [client], got_interfaces_already=True) # Now that the dispatcher is ready to go, we start looking for channels, # and also make the actual request # Empathy observes the channel we originally requested. _, a, cm_request_call = q.expect_many( EventPattern('dbus-method-call', interface=cs.PROPERTIES_IFACE, method='GetAll', args=[cs.CONN_IFACE_REQUESTS], path=conn.object_path, handled=True), EventPattern('dbus-method-call', path=client.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_REQUESTS, method='CreateChannel', path=conn.object_path, args=[request], handled=False), ) assert a.args[0] == account.object_path, a.args assert a.args[1] == conn.object_path, a.args assert a.args[3] != '/', a.args # there is a dispatch operation assert a.args[4] == [], a.args channels = a.args[2] assert len(channels) == 1, channels assert channels[0][0] == announcement.object_path, channels assert channels[0][1] == announcement_immutable, channels # Time passes. A channel is returned. channel_immutable = dbus.Dictionary(request) channel_immutable[cs.CHANNEL + '.InitiatorID'] = conn.self_ident channel_immutable[cs.CHANNEL + '.InitiatorHandle'] = conn.self_handle channel_immutable[cs.CHANNEL + '.Requested'] = True channel_immutable[cs.CHANNEL + '.Interfaces'] = \ dbus.Array([], signature='s') channel_immutable[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, '*****@*****.**') channel = SimulatedChannel(conn, channel_immutable) q.dbus_return(cm_request_call.message, channel.object_path, channel.immutable, signature='oa{sv}') channel.announce() # Empathy observes the newly-created channel. e = q.expect('dbus-method-call', path=client.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == '/', e.args # no dispatch operation assert e.args[4] == [request_path], e.args channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == channel.object_path, channels assert channels[0][1] == channel_immutable, channels # Observer says "OK, go" q.dbus_return(a.message, signature='') q.dbus_return(e.message, signature='') # Empathy is asked to handle the channel e = q.expect('dbus-method-call', path=client.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == channel.object_path, channels assert channels[0][1] == channel_immutable, channels assert e.args[3] == [request_path], e.args assert e.args[4] == user_action_time assert isinstance(e.args[5], dict) assert len(e.args) == 6
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Two clients want to observe, approve and handle channels empathy = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, bus, 'Kopete', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # Enable the account account.Set(cs.ACCOUNT, 'Enabled', True, dbus_interface=cs.PROPERTIES_IFACE) requested_presence = dbus.Struct( (dbus.UInt32(2L), dbus.String(u'available'), dbus.String(u''))) account.Set(cs.ACCOUNT, 'RequestedPresence', requested_presence, dbus_interface=cs.PROPERTIES_IFACE) 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) # Don't allow the Connection to have its list of channels # until we want it to, by avoiding a return from GetAll(Requests). conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', 'myself', implement_get_channels=False) q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') get_all_requests_call = q.expect('dbus-method-call', method='GetAll', args=[cs.CONN_IFACE_REQUESTS]) q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # Before returning from GetAll(Requests), make a Channel spring into # existence channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # Now reply to GetAll(Requests) conn.GetAll_Requests(get_all_requests_call) # A channel dispatch operation is created for the channel we already had e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [ cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete' ], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, signature='') q.dbus_return(e.message, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, signature='') q.dbus_return(k.message, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention # The user responds to Empathy first call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Empathy') # Empathy is asked to handle the channels e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy accepts the channels q.dbus_return(e.message, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, unused, **kwargs): fake_accounts_service = kwargs['fake_accounts_service'] preseed(q, bus, fake_accounts_service) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') user_action_time = dbus.Int64(1238582606) # A client and a CM are already running client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False, implement_get_interfaces=False) simulated_cm = SimulatedConnectionManager(q, bus) # service-activate MC; it will try to introspect the running client. mc = MC(q, bus, wait_for_names=False) get_interfaces, = mc.wait_for_names( EventPattern('dbus-method-call', path=client.object_path, interface=cs.PROPERTIES_IFACE, method='Get', args=[cs.CLIENT, 'Interfaces'], handled=False)) # The client doesn't reply just yet; meanwhile, immediately make a channel # request account = bus.get_object(cs.MC, cs.tp_path_prefix + '/Account/fakecm/fakeprotocol/jc_2edenton_40unatco_2eint') cd = bus.get_object(cs.MC, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) request = dbus.Dictionary({ cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': '*****@*****.**', }, signature='sv') call_async(q, cd, 'CreateChannel', account.object_path, request, user_action_time, client.bus_name, dbus_interface=cs.CD) ret = q.expect('dbus-return', method='CreateChannel') request_path = ret.value[0] # chat UI connects to signals and calls ChannelRequest.Proceed() cr = bus.get_object(cs.MC, request_path) request_props = cr.GetAll(cs.CR, dbus_interface=cs.PROPERTIES_IFACE) assert request_props['Account'] == account.object_path assert request_props['Requests'] == [request] assert request_props['UserActionTime'] == user_action_time assert request_props['PreferredHandler'] == client.bus_name assert request_props['Interfaces'] == [] call_async(q, cr, 'Proceed', dbus_interface=cs.CR) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', { 'account': '*****@*****.**', 'password': '******', }], destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', path=cs.tp_path_prefix + '/ConnectionManager/fakecm', interface=cs.tp_name_prefix + '.ConnectionManager', handled=False) conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', 'the_conn', '*****@*****.**') q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # A channel appears spontaneously announcement_immutable = dbus.Dictionary(text_fixed_properties) announcement_immutable[cs.CHANNEL + '.TargetID'] = '*****@*****.**' announcement_immutable[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, '*****@*****.**') announcement_immutable[cs.CHANNEL + '.InitiatorHandle'] = \ announcement_immutable[cs.CHANNEL + '.TargetHandle'] announcement_immutable[cs.CHANNEL + '.InitiatorID'] = \ announcement_immutable[cs.CHANNEL + '.TargetID'] announcement_immutable[cs.CHANNEL + '.Interfaces'] = \ dbus.Array([], signature='s') announcement_immutable[cs.CHANNEL + '.Requested'] = False announcement = SimulatedChannel(conn, announcement_immutable) announcement.announce() # Now the Client returns its info q.dbus_return(get_interfaces.message, dbus.Array([cs.HANDLER, cs.OBSERVER, cs.APPROVER, cs.CLIENT_IFACE_REQUESTS], signature='s'), signature='v') expect_client_setup(q, [client], got_interfaces_already=True) # Now that the dispatcher is ready to go, we start looking for channels, # and also make the actual request # Empathy observes the channel we originally requested. _, a, cm_request_call = q.expect_many( EventPattern('dbus-method-call', interface=cs.PROPERTIES_IFACE, method='GetAll', args=[cs.CONN_IFACE_REQUESTS], path=conn.object_path, handled=True), EventPattern('dbus-method-call', path=client.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_REQUESTS, method='CreateChannel', path=conn.object_path, args=[request], handled=False), ) assert a.args[0] == account.object_path, a.args assert a.args[1] == conn.object_path, a.args assert a.args[3] != '/', a.args # there is a dispatch operation assert a.args[4] == [], a.args channels = a.args[2] assert len(channels) == 1, channels assert channels[0][0] == announcement.object_path, channels assert channels[0][1] == announcement_immutable, channels # Time passes. A channel is returned. channel_immutable = dbus.Dictionary(request) channel_immutable[cs.CHANNEL + '.InitiatorID'] = conn.self_ident channel_immutable[cs.CHANNEL + '.InitiatorHandle'] = conn.self_handle channel_immutable[cs.CHANNEL + '.Requested'] = True channel_immutable[cs.CHANNEL + '.Interfaces'] = \ dbus.Array([], signature='s') channel_immutable[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, '*****@*****.**') channel = SimulatedChannel(conn, channel_immutable) q.dbus_return(cm_request_call.message, channel.object_path, channel.immutable, signature='oa{sv}') channel.announce() # Empathy observes the newly-created channel. e = q.expect('dbus-method-call', path=client.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == '/', e.args # no dispatch operation assert e.args[4] == [request_path], e.args channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == channel.object_path, channels assert channels[0][1] == channel_immutable, channels # Observer says "OK, go" q.dbus_return(a.message, signature='') q.dbus_return(e.message, signature='') # Empathy is asked to handle the channel e = q.expect('dbus-method-call', path=client.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == channel.object_path, channels assert channels[0][1] == channel_immutable, channels assert e.args[3] == [request_path], e.args assert e.args[4] == user_action_time assert isinstance(e.args[5], dict) assert len(e.args) == 6
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Two clients want to observe, approve and handle channels empathy = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, bus, 'Kopete', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # Enable the account account.Set(cs.ACCOUNT, 'Enabled', True, dbus_interface=cs.PROPERTIES_IFACE) requested_presence = dbus.Struct((dbus.UInt32(2L), dbus.String(u'available'), dbus.String(u''))) account.Set(cs.ACCOUNT, 'RequestedPresence', requested_presence, dbus_interface=cs.PROPERTIES_IFACE) 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) # Don't allow the Connection to have its list of channels # until we want it to, by avoiding a return from GetAll(Requests). conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', 'myself', implement_get_channels=False) q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') get_all_requests_call = q.expect('dbus-method-call', method='GetAll', args=[cs.CONN_IFACE_REQUESTS]) q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # Before returning from GetAll(Requests), make a Channel spring into # existence channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # Now reply to GetAll(Requests) conn.GetAll_Requests(get_all_requests_call) # A channel dispatch operation is created for the channel we already had e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, signature='') q.dbus_return(e.message, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, signature='') q.dbus_return(k.message, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention # The user responds to Empathy first call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Empathy') # Empathy is asked to handle the channels e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy accepts the channels q.dbus_return(e.message, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, unused, **kwargs): fake_accounts_service = kwargs['fake_accounts_service'] preseed(q, bus, fake_accounts_service) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', 'jc', '*****@*****.**') conn.StatusChanged(cs.CONN_STATUS_CONNECTED, 0) unhandled_properties = dbus.Dictionary(text_fixed_properties, signature='sv') unhandled_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') unhandled_properties[cs.CHANNEL + '.TargetID'] = '*****@*****.**' unhandled_properties[cs.CHANNEL + '.TargetHandle'] = \ dbus.UInt32(conn.ensure_handle(cs.HT_CONTACT, '*****@*****.**')) unhandled_properties[cs.CHANNEL + '.InitiatorHandle'] = dbus.UInt32( conn.self_handle) unhandled_properties[cs.CHANNEL + '.InitiatorID'] = conn.self_ident unhandled_properties[cs.CHANNEL + '.Requested'] = True unhandled_chan = SimulatedChannel(conn, unhandled_properties) unhandled_chan.announce() handled_properties = dbus.Dictionary(text_fixed_properties, signature='sv') handled_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') handled_properties[cs.CHANNEL + '.TargetID'] = '*****@*****.**' handled_properties[cs.CHANNEL + '.TargetHandle'] = \ dbus.UInt32(conn.ensure_handle(cs.HT_CONTACT, '*****@*****.**')) handled_properties[cs.CHANNEL + '.InitiatorHandle'] = dbus.UInt32( conn.self_handle) handled_properties[cs.CHANNEL + '.InitiatorID'] = conn.self_ident handled_properties[cs.CHANNEL + '.Requested'] = True handled_chan = SimulatedChannel(conn, handled_properties) handled_chan.announce() client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) client.handled_channels.append(handled_chan.object_path) # Service-activate MC. # We're told about the other channel as an observer... mc = MC(q, bus, wait_for_names=False) e, = mc.wait_for_names( EventPattern('dbus-method-call', path=client.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[1] == conn.object_path, e.args channels = e.args[2] assert channels[0][0] == unhandled_chan.object_path, channels q.dbus_return(e.message, signature='') # ... and as a handler e = q.expect('dbus-method-call', path=client.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) assert e.args[1] == conn.object_path, e.args channels = e.args[2] assert channels[0][0] == unhandled_chan.object_path, channels q.dbus_return(e.message, signature='')
def test(q, bus, mc): http_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': 1L, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_STREAM_TUBE, cs.CHANNEL_TYPE_STREAM_TUBE + '.Service': 'http' }, signature='sv') caps = dbus.Array([http_fixed_properties], signature='a{sv}') # Be a Client client = SimulatedClient(q, bus, 'downloader', observe=[], approve=[], handle=[http_fixed_properties], bypass_approval=False) expect_client_setup(q, [client]) # Create an account params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) # The account is initially valid but disabled, and hence offline props = account.GetAll(cs.ACCOUNT, dbus_interface=cs.PROPERTIES_IFACE) assert not props['Enabled'] assert props['Valid'] # The spec says it should be (Offline, "", "") but I don't think the # strings really matter. If anything, the second one should start out at # "offline". assertEquals(cs.PRESENCE_OFFLINE, props['CurrentPresence'][0]) # Enable the account account.Set(cs.ACCOUNT, 'Enabled', True, dbus_interface=cs.PROPERTIES_IFACE) q.expect('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT) props = account.GetAll(cs.ACCOUNT, dbus_interface=cs.PROPERTIES_IFACE) assert props['Enabled'] assert props['Valid'] # Ditto above re. string fields. assertEquals(cs.PRESENCE_OFFLINE, props['CurrentPresence'][0]) # Go online requested_presence = dbus.Struct((dbus.UInt32(2L), dbus.String(u'brb'), dbus.String(u'Be back soon!'))) account.Set(cs.ACCOUNT, 'RequestedPresence', requested_presence, dbus_interface=cs.PROPERTIES_IFACE) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=tp_name_prefix + '.ConnectionManager.fakecm', path=tp_path_prefix + '/ConnectionManager/fakecm', interface=tp_name_prefix + '.ConnectionManager', handled=False) conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', 'myself') q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') # MC does some setup, including fetching the list of Channels q.expect_many( EventPattern('dbus-method-call', interface=cs.PROPERTIES_IFACE, method='GetAll', args=[cs.CONN_IFACE_REQUESTS], path=conn.object_path, handled=True), ) # MC prepares the connection, does any pre-Connect setup, then # calls Connect q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) # Connect succeeds conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # Assert that the NormalizedName is harvested from the Connection at some # point while 1: e = q.expect('dbus-signal', interface=cs.ACCOUNT, signal='AccountPropertyChanged', path=account.object_path) if 'NormalizedName' in e.args[0]: assert e.args[0]['NormalizedName'] == 'myself', e.args break # Check the requested presence is online properties = account.GetAll(cs.ACCOUNT, dbus_interface=cs.PROPERTIES_IFACE) assert properties is not None assert properties.get('HasBeenOnline') assertEquals(requested_presence, properties.get('RequestedPresence')) # Since this Connection doesn't support SimplePresence, but it's online, # the spec says that CurrentPresence should be Unset. assertEquals((cs.PRESENCE_UNSET, "", ""), properties.get('CurrentPresence')) new_channel = http_fixed_properties buddy_handle = conn.ensure_handle(cs.HT_CONTACT, "buddy") new_channel[cs.CHANNEL + '.TargetID'] = "buddy" new_channel[cs.CHANNEL + '.TargetHandle'] = buddy_handle new_channel[cs.CHANNEL + '.Requested'] = False new_channel[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, new_channel) chan.announce() e = q.expect('dbus-method-call', method='HandleChannels') q.dbus_return(e.message, signature='') # Put the account offline requested_presence = (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '') account.Set(cs.ACCOUNT, 'RequestedPresence', requested_presence, dbus_interface=cs.PROPERTIES_IFACE) # In response, MC tells us to Disconnect, and we do. But it should not # Close() the open channel. q.forbid_events([ EventPattern('dbus-method-call', method='Close', path=conn.object_path), ]) q.expect('dbus-method-call', method='Disconnect', path=conn.object_path, handled=True) properties = account.GetAll(cs.ACCOUNT, dbus_interface=cs.PROPERTIES_IFACE) assertEquals('/', properties['Connection']) assertEquals(cs.CONN_STATUS_DISCONNECTED, properties['ConnectionStatus']) assertEquals(requested_presence, properties['CurrentPresence']) assertEquals(requested_presence, properties['RequestedPresence'])
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) # Ensure that it's enabled but has offline RP and doesn't connect # automatically 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, 'AutomaticPresence', (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('AutomaticPresence', (None, None, None))[1] == 'busy') call_async(q, account_props, 'Set', cs.ACCOUNT, 'ConnectAutomatically', False) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', True) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('Enabled')) # Requesting a channel will put us online user_action_time = dbus.Int64(1238582606) cd = bus.get_object(cs.CD, cs.CD_PATH) request = dbus.Dictionary({ cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': 'juliet', }, signature='sv') call_async(q, cd, 'CreateChannel', account.object_path, request, user_action_time, "", dbus_interface=cs.CD) ret = q.expect('dbus-return', method='CreateChannel') request_path = ret.value[0] cr = bus.get_object(cs.AM, request_path) request_props = cr.GetAll(cs.CR, dbus_interface=cs.PROPERTIES_IFACE) assert request_props['Account'] == account.object_path assert request_props['Requests'] == [request] assert request_props['UserActionTime'] == user_action_time assert request_props['PreferredHandler'] == "" assert request_props['Interfaces'] == [] # make sure RequestConnection doesn't get called until we Proceed events = [EventPattern('dbus-method-call', method='RequestConnection')] q.forbid_events(events) sync_dbus(bus, q, mc) q.unforbid_events(events) cr.Proceed(dbus_interface=cs.CR) 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) conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', 'myself', has_presence=True) q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) conn.presence = dbus.Struct((cs.PRESENCE_AVAILABLE, 'available', ''), signature='uss') _, cm_request_call = q.expect_many( EventPattern('dbus-method-call', path=conn.object_path, interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence', args=['busy', 'Testing automatic presence'], handled=True), EventPattern('dbus-method-call', path=conn.object_path, interface=cs.CONN_IFACE_REQUESTS, method='CreateChannel', args=[request], handled=False), ) q.dbus_emit(conn.object_path, cs.CONN_IFACE_SIMPLE_PRESENCE, 'PresencesChanged', {conn.self_handle: (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')}, signature='a{u(uss)}') # Time passes. A channel is returned. channel_immutable = dbus.Dictionary(request) channel_immutable[cs.CHANNEL + '.InitiatorID'] = conn.self_ident channel_immutable[cs.CHANNEL + '.InitiatorHandle'] = conn.self_handle channel_immutable[cs.CHANNEL + '.Requested'] = True channel_immutable[cs.CHANNEL + '.Interfaces'] = \ dbus.Array([], signature='s') channel_immutable[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel = SimulatedChannel(conn, channel_immutable) # this order of events is guaranteed by telepathy-spec (since 0.17.14) q.dbus_return(cm_request_call.message, channel.object_path, channel.immutable, signature='oa{sv}') channel.announce() # there's no handler, so it gets shot down q.expect('dbus-method-call', path=channel.object_path, method='Close', handled=True)