From b89f6fe0bcacef9340f633ab09b275122c6db644 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 2 Oct 2013 13:08:45 +0100 Subject: Implement Contacts properly on SimulatedConnection, and fix tests Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69885 Reviewed-by: Guillaume Desmottes [Cherry-picked from commit 15510bd on master. -smcv] Conflicts: tests/twisted/constants.py tests/twisted/mctest.py --- tests/twisted/account-manager/avatar-persist.py | 8 +-- tests/twisted/account-manager/avatar-refresh.py | 6 +- tests/twisted/account-manager/irc.py | 28 ++++++-- tests/twisted/account-manager/nickname.py | 6 +- tests/twisted/constants.py | 5 ++ tests/twisted/mctest.py | 93 +++++++++++++++++++++---- 6 files changed, 112 insertions(+), 34 deletions(-) diff --git a/tests/twisted/account-manager/avatar-persist.py b/tests/twisted/account-manager/avatar-persist.py index 7dedb188..dafc5efe 100644 --- a/tests/twisted/account-manager/avatar-persist.py +++ b/tests/twisted/account-manager/avatar-persist.py @@ -110,12 +110,8 @@ def test(q, bus, unused, **kwargs): # We haven't changed the avatar since we last signed in, so we don't set # it - on the contrary, we pick up the remote avatar (which has changed - # since we were last here) to store it in the Account - _, request_avatars_call, e = q.expect_many( - EventPattern('dbus-method-call', - interface=cs.CONN_IFACE_AVATARS, method='GetKnownAvatarTokens', - args=[[conn.self_handle]], - handled=True), + # since we were last here) to store it in the Account. + request_avatars_call, e = q.expect_many( EventPattern('dbus-method-call', interface=cs.CONN_IFACE_AVATARS, method='RequestAvatars', args=[[conn.self_handle]], diff --git a/tests/twisted/account-manager/avatar-refresh.py b/tests/twisted/account-manager/avatar-refresh.py index 817a623e..333a116f 100644 --- a/tests/twisted/account-manager/avatar-refresh.py +++ b/tests/twisted/account-manager/avatar-refresh.py @@ -102,11 +102,7 @@ def test(q, bus, unused, **kwargs): conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) - _, _, e = q.expect_many( - EventPattern('dbus-method-call', - interface=cs.CONN_IFACE_AVATARS, method='GetKnownAvatarTokens', - args=[[conn.self_handle]], - handled=True), + _, e = q.expect_many( EventPattern('dbus-method-call', interface=cs.CONN_IFACE_AVATARS, method='SetAvatar', args=['Deus Ex', 'image/jpeg'], diff --git a/tests/twisted/account-manager/irc.py b/tests/twisted/account-manager/irc.py index 6575aed6..2b249f19 100644 --- a/tests/twisted/account-manager/irc.py +++ b/tests/twisted/account-manager/irc.py @@ -51,7 +51,11 @@ def test(q, bus, mc): expect_after_connect = [ EventPattern('dbus-method-call', - interface=cs.CONN_IFACE_ALIASING, method='GetAliases', + interface=cs.CONN_IFACE_CONTACTS, + predicate=(lambda e: e.method in ( + 'GetContactAttributes', 'GetContactByID' + ) and + cs.CONN_IFACE_ALIASING in e.args[1]), handled=True), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', @@ -83,14 +87,19 @@ def test(q, bus, mc): conn.change_self_alias('TheBatman') get_aliases, _ = q.expect_many( - EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, - method='GetAliases', handled=True), + EventPattern('dbus-method-call', + interface=cs.CONN_IFACE_CONTACTS, + predicate=(lambda e: e.method in ( + 'GetContactAttributes', 'GetContactByID' + ) and + cs.CONN_IFACE_ALIASING in e.args[1]), + handled=True), EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, predicate=(lambda e: e.args[0].get('NormalizedName') == 'thebatman')), ) - assert get_aliases.args[0] == [ conn.self_handle ] + assert get_aliases.args[0] in ([conn.self_handle], conn.self_id) q.expect('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'Nickname': 'TheBatman'}]) @@ -117,14 +126,19 @@ def test(q, bus, mc): # In response to the self-handle change, we check our nickname again get_aliases, _ = q.expect_many( - EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, - method='GetAliases', handled=True), + EventPattern('dbus-method-call', + interface=cs.CONN_IFACE_CONTACTS, + predicate=(lambda e: e.method in ( + 'GetContactAttributes', 'GetContactByID' + ) and + cs.CONN_IFACE_ALIASING in e.args[1]), + handled=True), EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, predicate=(lambda e: e.args[0].get('NormalizedName') == 'brucewayne')), ) - assert get_aliases.args[0] == [ conn.self_handle ] + assert get_aliases.args[0] in ([conn.self_handle], conn.self_id) forbidden = [EventPattern('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: 'Nickname' in e.args[0])] diff --git a/tests/twisted/account-manager/nickname.py b/tests/twisted/account-manager/nickname.py index f23f0729..b128942c 100644 --- a/tests/twisted/account-manager/nickname.py +++ b/tests/twisted/account-manager/nickname.py @@ -51,7 +51,11 @@ def test(q, bus, mc, nickname): # OK, let's go online expect_after_connect = [ EventPattern('dbus-method-call', - interface=cs.CONN_IFACE_ALIASING, method='GetAliases', + interface=cs.CONN_IFACE_CONTACTS, + predicate=(lambda e: e.method in ( + 'GetContactAttributes', 'GetContactByID' + ) and + cs.CONN_IFACE_ALIASING in e.args[1]), handled=True), ] forbidden = [] diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py index 0b359ff1..3a844d54 100644 --- a/tests/twisted/constants.py +++ b/tests/twisted/constants.py @@ -71,6 +71,11 @@ CONN_STATUS_CONNECTED = 0 CONN_STATUS_CONNECTING = 1 CONN_STATUS_DISCONNECTED = 2 +ATTR_CONTACT_ID = CONN + '/contact-id' +ATTR_ALIAS = CONN_IFACE_ALIASING + '/alias' +ATTR_AVATAR_TOKEN = CONN_IFACE_AVATARS + '/token' +ATTR_PRESENCE = CONN_IFACE_SIMPLE_PRESENCE + '/presence' + CONN_STATUS_REASON_NONE = 0 CONN_STATUS_REASON_REQUESTED = 1 CONN_STATUS_REASON_NETWORK_ERROR = 2 diff --git a/tests/twisted/mctest.py b/tests/twisted/mctest.py index edd8a240..8db2fa72 100644 --- a/tests/twisted/mctest.py +++ b/tests/twisted/mctest.py @@ -254,6 +254,7 @@ class SimulatedConnection(object): self.extra_interfaces = extra_interfaces[:] self.interfaces = [] + self.interfaces.append(cs.CONN_IFACE_CONTACTS) if self.has_requests: self.interfaces.append(cs.CONN_IFACE_REQUESTS) @@ -309,6 +310,13 @@ class SimulatedConnection(object): q.add_dbus_method_impl(self.GetContactAttributes, path=self.object_path, interface=cs.CONN_IFACE_CONTACTS, method='GetContactAttributes') + q.add_dbus_method_impl(self.GetContactByID, + path=self.object_path, + interface=cs.CONN_IFACE_CONTACTS, method='GetContactByID') + q.add_dbus_method_impl(self.Get_ContactAttributeInterfaces, + path=self.object_path, + interface=cs.PROPERTIES_IFACE, method='Get', + args=[cs.CONN_IFACE_CONTACTS, 'ContactAttributeInterfaces']) q.add_dbus_method_impl(self.GetAll_Contacts, path=self.object_path, interface=cs.PROPERTIES_IFACE, method='GetAll', @@ -374,8 +382,10 @@ class SimulatedConnection(object): if has_hidden: self.statuses['hidden'] = (cs.PRESENCE_TYPE_HIDDEN, True, True) - self.presence = dbus.Struct((cs.PRESENCE_TYPE_OFFLINE, 'offline', ''), - signature='uss') + # "dbus.UInt32" to work around + # https://bugs.freedesktop.org/show_bug.cgi?id=69967 + self.presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), + 'offline', ''), signature='uss') def change_self_ident(self, ident): self.self_ident = ident @@ -467,7 +477,9 @@ class SimulatedConnection(object): def SetPresence(self, e): if e.args[0] in self.statuses: - presence = dbus.Struct((self.statuses[e.args[0]][0], + # "dbus.UInt32" to work around + # https://bugs.freedesktop.org/show_bug.cgi?id=69967 + presence = dbus.Struct((dbus.UInt32(self.statuses[e.args[0]][0]), e.args[0], e.args[1]), signature='uss') old_presence = self.presence @@ -475,11 +487,10 @@ class SimulatedConnection(object): if presence != old_presence: self.presence = presence - if self.status == cs.CONN_STATUS_CONNECTED: - self.q.dbus_emit(self.object_path, - cs.CONN_IFACE_SIMPLE_PRESENCE, 'PresencesChanged', - { self.self_handle : presence }, - signature='a{u(uss)}') + self.q.dbus_emit(self.object_path, + cs.CONN_IFACE_SIMPLE_PRESENCE, 'PresencesChanged', + { self.self_handle : presence }, + signature='a{u(uss)}') self.q.dbus_return(e.message, signature='') else: @@ -547,7 +558,10 @@ class SimulatedConnection(object): status, reason, signature='uu') if self.status == cs.CONN_STATUS_CONNECTED and self.has_presence: if self.presence[0] == cs.PRESENCE_TYPE_OFFLINE: - self.presence = dbus.Struct((cs.PRESENCE_TYPE_AVAILABLE, + # "dbus.UInt32" to work around + # https://bugs.freedesktop.org/show_bug.cgi?id=69967 + self.presence = dbus.Struct(( + dbus.UInt32(cs.PRESENCE_TYPE_AVAILABLE), 'available', ''), signature='uss') self.q.dbus_emit(self.object_path, @@ -609,24 +623,73 @@ class SimulatedConnection(object): for channel in channels], signature='a(oa{sv})') + def get_contact_attributes(self, h, ifaces): + id = self.inspect_handles([h])[0] + ifaces = set(ifaces).intersection( + self.get_contact_attribute_interfaces()) + + ret = dbus.Dictionary({}, signature='sv') + ret[cs.ATTR_CONTACT_ID] = id + + if cs.CONN_IFACE_ALIASING in ifaces: + if h == self.self_handle: + ret[cs.ATTR_ALIAS] = self.self_alias + else: + ret[cs.ATTR_ALIAS] = id + + if cs.CONN_IFACE_AVATARS in ifaces: + if h == self.self_handle: + if self.avatar is not None: + # we just stringify the avatar as the token + # (also, empty avatar => no avatar => empty token) + ret[cs.ATTR_AVATAR_TOKEN] = str(self.avatar[0]) + + if cs.CONN_IFACE_SIMPLE_PRESENCE in ifaces: + if h == self.self_handle: + ret[cs.ATTR_PRESENCE] = self.presence + else: + # stub - MC doesn't care + # "dbus.UInt32" to work around + # https://bugs.freedesktop.org/show_bug.cgi?id=69967 + ret[cs.ATTR_PRESENCE] = (dbus.UInt32(cs.PRESENCE_UNKNOWN), + 'unknown', '') + + return ret + + def get_contact_attribute_interfaces(self): + return set(self.interfaces).intersection(set([ + cs.CONN_IFACE_ALIASING, + cs.CONN_IFACE_AVATARS, + cs.CONN_IFACE_SIMPLE_PRESENCE, + ])) + def GetContactAttributes(self, e): - ret = {} + ret = dbus.Dictionary({}, signature='ua{sv}') try: for h in e.args[0]: - id = self.inspect_handles(h)[0] - ret[dbus.UInt32(h)] = dbus.Dictionary({telepathy.CONN_IFACE + '/contact-id': id}, - signature='sv') + ret[dbus.UInt32(h)] = self.get_contact_attributes(h, e.args[1]) - q.dbus_return(e.message, ret, signature='a{ua{sv}}') + self.q.dbus_return(e.message, ret, signature='a{ua{sv}}') except e: self.q.dbus_raise(e.message, INVALID_HANDLE, str(e.args[0])) + def GetContactByID(self, e): + h = self.ensure_handle(e.args[0]) + self.q.dbus_return(e.message, h, + self.get_contact_attributes(h, e.args[1]), signature='ua{sv}') + def GetAll_Contacts(self, e): self.q.dbus_return(e.message, { - 'ContactAttributeInterfaces': [] + 'ContactAttributeInterfaces': + self.get_contact_attribute_interfaces(), }, signature='a{sv}') + def Get_ContactAttributeInterfaces(self, e): + self.q.dbus_return(e.message, + dbus.Array(self.get_contact_attribute_interfaces(), signature='s'), + signature='v') + class SimulatedChannel(object): def __init__(self, conn, immutable, mutable={}, destroyable=False, group=False): -- cgit v1.2.1