summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonny Lamb <jonny.lamb@collabora.co.uk>2011-09-07 17:00:59 +0100
committerJonny Lamb <jonny.lamb@collabora.co.uk>2011-09-07 17:00:59 +0100
commitbe1c6ddf830329b477b1c0600eafcbf368379eaf (patch)
tree17a46864fe5f2f81af1b11ac9bbee5b89f9dd72a
parentbb053a5d5bdee08686ab063b98b357875e77a029 (diff)
gabble/status: look at the roster for other services when ensured
If we ensure the status sidecar way into a connection, Gabble might already know about services, so the status needs to update its properties. Finally, now it can! I even added a test. Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
-rw-r--r--gabble/status.c60
-rw-r--r--tests/twisted/Makefile.am3
-rw-r--r--tests/twisted/gabble/slow-service.py137
3 files changed, 186 insertions, 14 deletions
diff --git a/gabble/status.c b/gabble/status.c
index 07ee7a9..0947ecf 100644
--- a/gabble/status.c
+++ b/gabble/status.c
@@ -451,15 +451,49 @@ capabilities_changed_cb (GSignalInvocationHint *ihint,
return TRUE;
}
+static void
+check_contact_capabilities (TpHandleSet *set,
+ TpHandle handle,
+ gpointer user_data)
+{
+ YtstStatus *self = user_data;
+ YtstStatusPrivate *priv = self->priv;
+ WockyXep0115Capabilities *caps;
+
+ caps = gabble_connection_get_caps (priv->connection,
+ handle);
+
+ if (caps != NULL)
+ contact_capabilities_changed (self, caps, FALSE);
+}
+
+static void
+contact_list_state_changed_cb (GabbleConnection *connection,
+ TpContactListState state,
+ YtstStatus *self)
+{
+ TpBaseContactList *contact_list;
+ TpHandleSet *contacts;
+
+ if (state != TP_CONTACT_LIST_STATE_SUCCESS)
+ return;
+
+ contact_list = gabble_connection_get_contact_list (connection);
+ contacts = tp_base_contact_list_dup_contacts (contact_list);
+
+ tp_handle_set_foreach (contacts,
+ check_contact_capabilities, self);
+
+ tp_handle_set_destroy (contacts);
+}
+
static gboolean
capabilities_idle_cb (gpointer data)
{
YtstStatus *self = YTST_STATUS (data);
YtstStatusPrivate *priv = self->priv;
- /* TODO
- WockyContactFactory *factory;
- GList *contacts, *l;
- */
+ TpBaseContactList *contact_list;
+ TpContactListState contact_list_state;
/* connect to all capabilities-changed signals */
priv->capabilities_changed_id = g_signal_add_emission_hook (
@@ -468,18 +502,18 @@ capabilities_idle_cb (gpointer data)
/* and now look through all the contacts that had caps before this
* sidecar was ensured */
- /* TODO
- factory = wocky_session_get_contact_factory (priv->session);
- contacts = wocky_contact_factory_get_ll_contacts (factory);
+ contact_list = gabble_connection_get_contact_list (priv->connection);
+ contact_list_state = tp_base_contact_list_get_state (contact_list, NULL);
- for (l = contacts; l != NULL; l = l->next)
+ if (contact_list_state == TP_CONTACT_LIST_STATE_SUCCESS)
{
- if (WOCKY_IS_XEP_0115_CAPABILITIES (l->data))
- contact_capabilities_changed (self, l->data, FALSE);
+ contact_list_state_changed_cb (priv->connection, contact_list_state, self);
+ }
+ else
+ {
+ tp_g_signal_connect_object (priv->connection, "contact-list-state-changed",
+ G_CALLBACK (contact_list_state_changed_cb), self, 0);
}
-
- g_list_free (contacts);
- */
return FALSE;
}
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index f64b0b1..1b26802 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -15,7 +15,8 @@ TWISTED_BASIC_TESTS += \
gabble/message.py \
gabble/status.py \
gabble/service.py \
- gabble/hct.py
+ gabble/hct.py \
+ gabble/slow-service.py
endif
diff --git a/tests/twisted/gabble/slow-service.py b/tests/twisted/gabble/slow-service.py
new file mode 100644
index 0000000..d51cdd8
--- /dev/null
+++ b/tests/twisted/gabble/slow-service.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2011 Intel Corp.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+import dbus
+
+from gabbleservicetest import call_async, EventPattern, assertEquals, \
+ ProxyWrapper, assertNotEquals, assertSameSets
+from gabbletest import exec_test, make_result_iq, sync_stream
+import gabbleconstants as cs
+import yconstants as ycs
+from gabblecaps_helper import *
+
+from twisted.words.xish import xpath
+from twisted.words.xish.domish import Element
+from twisted.words.xish import domish
+
+CLIENT_NAME = 'il-cliente-del-futuro'
+
+client = 'http://telepathy.im/fake'
+client_caps = {'ver': '0.1', 'node': client}
+features = [
+ ns.JINGLE_015,
+ ns.JINGLE_015_AUDIO,
+ ns.JINGLE_015_VIDEO,
+ ns.GOOGLE_P2P,
+ ]
+identity = ['client/pc/en/Lolclient 0.L0L']
+
+banshee = {
+ 'urn:ytstenut:capabilities#org.gnome.Banshee':
+ {'type': ['application'],
+ 'name': ['en_GB/Banshee Media Player',
+ 'fr/Banshee Lecteur de Musique'],
+ 'capabilities': ['urn:ytstenut:capabilities:yts-caps-audio',
+ 'urn:ytstenut:data:jingle:rtp']
+ }
+}
+
+evince = {
+ 'urn:ytstenut:capabilities#org.gnome.Evince':
+ {'type': ['application'],
+ 'name': ['en_GB/Evince Picture Viewer',
+ 'fr/Evince uh, ow do you say'],
+ 'capabilities': ['urn:ytstenut:capabilities:pics'],
+ }
+}
+
+def test(q, bus, conn, stream):
+ bare_jid = "test-service@example.com"
+ full_jid = bare_jid + "/NeeNawNeeNawIAmAnAmbulance"
+
+ # we don't want these two signalled, ever.
+ forbidden = [EventPattern('dbus-signal', signal='ServiceAdded'),
+ EventPattern('dbus-signal', signal='ServiceRemoved')]
+ q.forbid_events(forbidden)
+
+ conn.Connect()
+
+ _, e = q.expect_many(EventPattern('dbus-signal', signal='StatusChanged',
+ args=[0, 1]),
+ EventPattern('stream-iq', query_ns=ns.ROSTER,
+ iq_type='get', query_name='query'))
+
+ e.stanza['type'] = 'result'
+
+ item = e.query.addElement('item')
+ item['jid'] = bare_jid
+ item['subscription'] = 'both'
+
+ stream.send(e.stanza)
+
+ q.expect('dbus-signal', signal='ContactListStateChanged',
+ args=[cs.CONTACT_LIST_STATE_SUCCESS])
+
+ # announce a contact with the right caps
+ contact_handle = conn.RequestHandles(cs.HT_CONTACT, [bare_jid])[0]
+
+ client_caps['ver'] = compute_caps_hash(identity, features, banshee)
+ presence_and_disco(q, conn, stream, full_jid, True, client, client_caps,
+ features, identity, banshee, True, None)
+
+ # this will be fired as text channel caps will be fired
+ q.expect('dbus-signal', signal='ContactCapabilitiesChanged',
+ predicate=lambda e: contact_handle in e.args[0])
+
+ # add evince
+ tmp = banshee.copy()
+ tmp.update(evince)
+ client_caps['ver'] = compute_caps_hash(identity, features, tmp)
+ presence_and_disco(q, conn, stream, full_jid, True, client, client_caps,
+ features, identity, tmp, False)
+
+ sync_stream(q, stream)
+
+ # now finally ensure the sidecar
+ path, props = conn.Future.EnsureSidecar(ycs.STATUS_IFACE)
+ assertEquals({}, props)
+
+ status = ProxyWrapper(bus.get_object(conn.bus_name, path),
+ ycs.STATUS_IFACE, {})
+
+ discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices',
+ dbus_interface=dbus.PROPERTIES_IFACE)
+ assertEquals({bare_jid: {
+ 'org.gnome.Banshee':
+ ('application',
+ {'en_GB': 'Banshee Media Player',
+ 'fr': 'Banshee Lecteur de Musique'},
+ ['urn:ytstenut:capabilities:yts-caps-audio',
+ 'urn:ytstenut:data:jingle:rtp']),
+ 'org.gnome.Evince':
+ ('application',
+ {'en_GB': 'Evince Picture Viewer',
+ 'fr': 'Evince uh, ow do you say'},
+ ['urn:ytstenut:capabilities:pics'])}
+ }, discovered)
+
+ # sweet.
+
+if __name__ == '__main__':
+ exec_test(test, do_connect=False)