diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2012-01-31 17:06:00 +0000 |
---|---|---|
committer | Will Thompson <will.thompson@collabora.co.uk> | 2012-01-31 17:06:00 +0000 |
commit | d1896284653c29577b3ecb037406a9ab84a810df (patch) | |
tree | c0832de4eebdec6c12544333ac19db0cd9b6d4c3 | |
parent | fef0ba21349c8f1434ed93766b6e35c787cbbbae (diff) | |
parent | f481ea91d5278178ca25abd9fd1f95283d2b0794 (diff) |
Merge branch '45400-pep-service-rummage-for-items'
-rw-r--r-- | tests/wocky-pep-service-test.c | 69 | ||||
-rw-r--r-- | wocky/wocky-pep-service.c | 40 | ||||
-rw-r--r-- | wocky/wocky-pep-service.h | 9 |
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—<item> 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 <item> 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 |