summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Thompson <will.thompson@collabora.co.uk>2012-01-31 17:06:00 +0000
committerWill Thompson <will.thompson@collabora.co.uk>2012-01-31 17:06:00 +0000
commitd1896284653c29577b3ecb037406a9ab84a810df (patch)
treec0832de4eebdec6c12544333ac19db0cd9b6d4c3
parentfef0ba21349c8f1434ed93766b6e35c787cbbbae (diff)
parentf481ea91d5278178ca25abd9fd1f95283d2b0794 (diff)
Merge branch '45400-pep-service-rummage-for-items'
-rw-r--r--tests/wocky-pep-service-test.c69
-rw-r--r--wocky/wocky-pep-service.c40
-rw-r--r--wocky/wocky-pep-service.h9
3 files changed, 94 insertions, 24 deletions
diff --git a/tests/wocky-pep-service-test.c b/tests/wocky-pep-service-test.c
index 668f6ea..bb8bcae 100644
--- a/tests/wocky-pep-service-test.c
+++ b/tests/wocky-pep-service-test.c
@@ -33,10 +33,27 @@ static void
test_changed_signal_cb (WockyPepService *pep,
WockyBareContact *contact,
WockyStanza *stanza,
+ WockyNode *item,
test_data_t *test)
{
- g_assert (!wocky_strdiff (wocky_bare_contact_get_jid (contact),
- "alice@example.org"));
+ const gchar *id = wocky_node_get_attribute (
+ wocky_stanza_get_top_node (stanza), "id");
+
+ g_assert_cmpstr (wocky_bare_contact_get_jid (contact), ==,
+ "alice@example.org");
+
+ /* the id happens to hold the number of <item> children; we expect to get the
+ * first one if there is more than one. */
+ if (wocky_strdiff (id, "0"))
+ {
+ g_assert (item != NULL);
+ g_assert_cmpstr (item->name, ==, "item");
+ g_assert_cmpstr (wocky_node_get_attribute (item, "id"), ==, "1");
+ }
+ else
+ {
+ g_assert (item == NULL);
+ }
test->outstanding--;
g_main_loop_quit (test->loop);
@@ -45,27 +62,42 @@ test_changed_signal_cb (WockyPepService *pep,
static void
send_pep_event (WockyPorter *porter,
- const gchar *node)
+ const gchar *node,
+ guint n_items)
{
WockyStanza *stanza;
+ WockyNode *items;
+ gchar *n_items_str = g_strdup_printf ("%d", n_items);
+ guint i;
stanza = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE,
WOCKY_STANZA_SUB_TYPE_NONE,
"alice@example.org", NULL,
+ /* This is a hint for test_changed_signal_cb. */
+ '@', "id", n_items_str,
'(', "event",
':', WOCKY_XMPP_NS_PUBSUB_EVENT,
'(', "items",
- '@', "node", node,
- '(', "item",
- '@', "id", "1",
- '(', "payload", ')',
- ')',
+ '@', "node", node,
+ '*', &items,
')',
')',
NULL);
+ for (i = 1; i <= n_items; i++)
+ {
+ gchar *i_str = g_strdup_printf ("%d", i);
+ wocky_node_add_build (items,
+ '(', "item",
+ '@', "id", i_str,
+ '(', "payload", ')',
+ ')', NULL);
+ g_free (i_str);
+ }
+
wocky_porter_send (porter, stanza);
g_object_unref (stanza);
+ g_free (n_items_str);
}
static void
@@ -83,22 +115,24 @@ test_changed_signal (void)
wocky_porter_start (test->sched_out);
wocky_porter_start (test->sched_in);
- /* send event on the right node */
+ /* send events on the right node */
event_received = FALSE;
- send_pep_event (test->sched_in, TEST_NODE1);
+ send_pep_event (test->sched_in, TEST_NODE1, 0);
+ send_pep_event (test->sched_in, TEST_NODE1, 1);
+ send_pep_event (test->sched_in, TEST_NODE1, 2);
- test->outstanding += 1;
+ test->outstanding += 3;
test_wait_pending (test);
g_assert (event_received);
event_received = FALSE;
/* send event on the wrong node */
- send_pep_event (test->sched_in, TEST_NODE2);
+ send_pep_event (test->sched_in, TEST_NODE2, 1);
g_object_unref (pep);
/* send event to the right node after the PEP service has been destroyed */
- send_pep_event (test->sched_in, TEST_NODE1);
+ send_pep_event (test->sched_in, TEST_NODE1, 1);
test_close_both_porters (test);
teardown_test (test);
@@ -113,17 +147,22 @@ test_send_query_cb (GObject *source_object,
{
test_data_t *test = (test_data_t *) user_data;
WockyStanza *reply;
+ WockyNode *item;
WockyStanzaType type;
WockyStanzaSubType sub_type;
reply = wocky_pep_service_get_finish (WOCKY_PEP_SERVICE (source_object), res,
- NULL);
+ &item, NULL);
g_assert (reply != NULL);
wocky_stanza_get_type_info (reply, &type, &sub_type);
g_assert (type == WOCKY_STANZA_TYPE_IQ);
g_assert (sub_type == WOCKY_STANZA_SUB_TYPE_RESULT);
+ g_assert (item != NULL);
+ g_assert_cmpstr (item->name, ==, "item");
+ g_assert_cmpstr (wocky_node_get_attribute (item, "id"), ==, "1");
+
g_object_unref (reply);
test->outstanding--;
@@ -169,7 +208,7 @@ test_send_query_failed_cb (GObject *source_object,
GError *error = NULL;
reply = wocky_pep_service_get_finish (WOCKY_PEP_SERVICE (source_object), res,
- &error);
+ NULL, &error);
g_assert (reply == NULL);
g_assert_error (error, WOCKY_XMPP_CONNECTION_ERROR,
WOCKY_XMPP_CONNECTION_ERROR_CLOSED);
diff --git a/wocky/wocky-pep-service.c b/wocky/wocky-pep-service.c
index c9302d2..3e6193d 100644
--- a/wocky/wocky-pep-service.c
+++ b/wocky/wocky-pep-service.c
@@ -1,6 +1,6 @@
/*
* wocky-pep-service.c - WockyPepService
- * Copyright (C) 2009 Collabora Ltd.
+ * Copyright © 2009,2012 Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -209,6 +209,8 @@ wocky_pep_service_class_init (WockyPepServiceClass *wocky_pep_service_class)
* @self: a #WockyPepService object
* @contact: the #WockyBareContact who changed the node
* @stanza: the #WockyStanza
+ * @item: the first—and typically only—&lt;item&gt; element in @stanza, or
+ * %NULL if there is none.
*
* Emitted when the node value changes.
*/
@@ -217,8 +219,8 @@ wocky_pep_service_class_init (WockyPepServiceClass *wocky_pep_service_class)
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
NULL, NULL,
- _wocky_signals_marshal_VOID__OBJECT_OBJECT,
- G_TYPE_NONE, 2, WOCKY_TYPE_BARE_CONTACT, WOCKY_TYPE_STANZA);
+ _wocky_signals_marshal_VOID__OBJECT_OBJECT_POINTER,
+ G_TYPE_NONE, 3, WOCKY_TYPE_BARE_CONTACT, WOCKY_TYPE_STANZA, G_TYPE_POINTER);
}
/**
@@ -251,6 +253,7 @@ msg_event_cb (WockyPorter *porter,
const gchar *from;
WockyBareContact *contact;
WockyStanzaSubType sub_type;
+ WockyNode *event, *items, *item;
from = wocky_stanza_get_from (stanza);
if (from == NULL)
@@ -269,10 +272,17 @@ msg_event_cb (WockyPorter *porter,
return FALSE;
}
+ event = wocky_node_get_child_ns (wocky_stanza_get_top_node (stanza),
+ "event", WOCKY_XMPP_NS_PUBSUB_EVENT);
+ g_return_val_if_fail (event != NULL, FALSE);
+ items = wocky_node_get_child (event, "items");
+ g_return_val_if_fail (items != NULL, FALSE);
+ item = wocky_node_get_child (items, "item");
+
contact = wocky_contact_factory_ensure_bare_contact (
priv->contact_factory, from);
- g_signal_emit (G_OBJECT (self), signals[CHANGED], 0, contact, stanza);
+ g_signal_emit (G_OBJECT (self), signals[CHANGED], 0, contact, stanza, item);
g_object_unref (contact);
return TRUE;
@@ -400,6 +410,8 @@ wocky_pep_service_get_async (WockyPepService *self,
* wocky_pep_service_get_finish:
* @self: a #WockyPepService object
* @result: a #GAsyncResult
+ * @item: (out) (allow-none): on success, the first &lt;item&gt; element
+ * in the result, or %NULL if @self has no published items.
* @error: a location to store a #GError if an error occurs
*
* Finishes an asynchronous operation to get the PEP node,
@@ -411,17 +423,35 @@ wocky_pep_service_get_async (WockyPepService *self,
WockyStanza *
wocky_pep_service_get_finish (WockyPepService *self,
GAsyncResult *result,
+ WockyNode **item,
GError **error)
{
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+ WockyStanza *reply;
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
g_return_val_if_fail (g_simple_async_result_is_valid (result,
G_OBJECT (self), wocky_pep_service_get_async), NULL);
+ reply = WOCKY_STANZA (g_simple_async_result_get_op_res_gpointer (simple));
+
+ if (item != NULL)
+ {
+ WockyNode *pubsub_node = wocky_node_get_child_ns (
+ wocky_stanza_get_top_node (reply), "pubsub", WOCKY_XMPP_NS_PUBSUB);
+ WockyNode *items_node = NULL;
+
+ if (pubsub_node != NULL)
+ items_node = wocky_node_get_child (pubsub_node, "items");
+
+ if (items_node != NULL)
+ *item = wocky_node_get_child (items_node, "item");
+ else
+ *item = NULL;
+ }
- return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+ return g_object_ref (reply);
}
/**
diff --git a/wocky/wocky-pep-service.h b/wocky/wocky-pep-service.h
index 7812197..ff508b3 100644
--- a/wocky/wocky-pep-service.h
+++ b/wocky/wocky-pep-service.h
@@ -1,6 +1,6 @@
/*
* wocky-pep-service.h - Header of WockyPepService
- * Copyright (C) 2009 Collabora Ltd.
+ * Copyright © 2009, 2012 Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -74,7 +74,7 @@ GType wocky_pep_service_get_type (void);
WockyPepServiceClass))
WockyPepService * wocky_pep_service_new (const gchar *node,
- gboolean subscribe);
+ gboolean subscribe) G_GNUC_WARN_UNUSED_RESULT;
void wocky_pep_service_start (WockyPepService *self,
WockySession *session);
@@ -87,10 +87,11 @@ void wocky_pep_service_get_async (WockyPepService *self,
WockyStanza * wocky_pep_service_get_finish (WockyPepService *self,
GAsyncResult *result,
- GError **error);
+ WockyNode **item,
+ GError **error) G_GNUC_WARN_UNUSED_RESULT;
WockyStanza * wocky_pep_service_make_publish_stanza (WockyPepService *self,
- WockyNode **item);
+ WockyNode **item) G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS