diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2012-02-02 17:31:10 -0500 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2012-02-02 17:41:40 -0500 |
commit | c7e35a522f01a3474f3e4271e4a2d287c9b9f61e (patch) | |
tree | d5480f1273f4ae510b45ff3186f4a386b872a319 | |
parent | be46c968599e46578a94dea13a10e6dcce8b69e8 (diff) |
text-channel test: add test for chat state stuff
Hot off the press.
Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
-rw-r--r-- | examples/cm/echo-message-parts/chan.c | 61 | ||||
-rw-r--r-- | tests/dbus/channel-introspect.c | 12 | ||||
-rw-r--r-- | tests/dbus/text-channel.c | 123 |
3 files changed, 190 insertions, 6 deletions
diff --git a/examples/cm/echo-message-parts/chan.c b/examples/cm/echo-message-parts/chan.c index d900555cf..4b2f79b2f 100644 --- a/examples/cm/echo-message-parts/chan.c +++ b/examples/cm/echo-message-parts/chan.c @@ -22,6 +22,7 @@ static void destroyable_iface_init (gpointer iface, gpointer data); static void sms_iface_init (gpointer iface, gpointer data); +static void chat_state_iface_init (gpointer iface, gpointer data); G_DEFINE_TYPE_WITH_CODE (ExampleEcho2Channel, example_echo_2_channel, @@ -31,6 +32,8 @@ G_DEFINE_TYPE_WITH_CODE (ExampleEcho2Channel, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_DESTROYABLE, destroyable_iface_init) G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_SMS, sms_iface_init) + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CHAT_STATE, + chat_state_iface_init) ) /* type definition stuff */ @@ -38,12 +41,14 @@ G_DEFINE_TYPE_WITH_CODE (ExampleEcho2Channel, static const char * example_echo_2_channel_interfaces[] = { TP_IFACE_CHANNEL_INTERFACE_DESTROYABLE, TP_IFACE_CHANNEL_INTERFACE_SMS, + TP_IFACE_CHANNEL_INTERFACE_CHAT_STATE, NULL }; enum { PROP_SMS = 1, PROP_SMS_FLASH, + PROP_CHAT_STATES, N_PROPS }; @@ -285,6 +290,21 @@ get_property (GObject *object, case PROP_SMS_FLASH: g_value_set_boolean (value, TRUE); break; + case PROP_CHAT_STATES: + { + GHashTable *states = g_hash_table_new ( + g_direct_hash, g_direct_equal); + TpHandle handle = tp_base_channel_get_target_handle ( + TP_BASE_CHANNEL (self)); + + /* the target handle is always Composing; give it a break? */ + + g_hash_table_insert (states, GUINT_TO_POINTER (handle), + GUINT_TO_POINTER (TP_CHANNEL_CHAT_STATE_COMPOSING)); + + g_value_take_boxed (value, states); + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -302,6 +322,10 @@ example_echo_2_channel_class_init (ExampleEcho2ChannelClass *klass) { "Flash", "sms-flash", NULL }, { NULL } }; + static TpDBusPropertiesMixinPropImpl chat_state_props[] = { + { "ChatStates", "chat-states", NULL }, + { NULL } + }; g_type_class_add_private (klass, sizeof (ExampleEcho2ChannelPrivate)); @@ -329,11 +353,22 @@ example_echo_2_channel_class_init (ExampleEcho2ChannelClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_SMS_FLASH, param_spec); + param_spec = g_param_spec_boxed ("chat-states", "Chat states", + "ChatState.ChatStates", + TP_HASH_TYPE_CHAT_STATE_MAP, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_CHAT_STATES, param_spec); + tp_dbus_properties_mixin_implement_interface (object_class, TP_IFACE_QUARK_CHANNEL_INTERFACE_SMS, tp_dbus_properties_mixin_getter_gobject_properties, NULL, sms_props); + tp_dbus_properties_mixin_implement_interface (object_class, + TP_IFACE_QUARK_CHANNEL_INTERFACE_CHAT_STATE, + tp_dbus_properties_mixin_getter_gobject_properties, NULL, + chat_state_props); + tp_message_mixin_init_dbus_properties (object_class); } @@ -416,3 +451,29 @@ sms_iface_init (gpointer iface, IMPLEMENT (get_sms_length); #undef IMPLEMENT } + +static void +chat_state_set_chat_state (TpSvcChannelInterfaceChatState *self, + guint state, + DBusGMethodInvocation *context) +{ + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + + tp_svc_channel_interface_chat_state_emit_chat_state_changed (self, + base_conn->self_handle, state); + + tp_svc_channel_interface_chat_state_return_from_set_chat_state (context); +} + +static void +chat_state_iface_init (gpointer iface, + gpointer data) +{ + TpSvcChannelInterfaceChatStateClass *klass = iface; + +#define IMPLEMENT(x) \ + tp_svc_channel_interface_chat_state_implement_##x (klass, chat_state_##x) + IMPLEMENT (set_chat_state); +#undef IMPLEMENT +} diff --git a/tests/dbus/channel-introspect.c b/tests/dbus/channel-introspect.c index 81550fe2b..4520e21aa 100644 --- a/tests/dbus/channel-introspect.c +++ b/tests/dbus/channel-introspect.c @@ -129,7 +129,7 @@ main (int argc, GHashTable *asv; GAsyncResult *prepare_result; GQuark some_features[] = { TP_CHANNEL_FEATURE_CORE, - TP_CHANNEL_FEATURE_CHAT_STATES, 0 }; + TP_CHANNEL_FEATURE_CONTACTS, 0 }; g_type_init (); tp_tests_abort_after (10); @@ -200,7 +200,7 @@ main (int argc, g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CORE), ==, FALSE); - g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CHAT_STATES), + g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CONTACTS), ==, FALSE); MYASSERT (tp_channel_run_until_ready (chan, &error, NULL), ""); @@ -208,7 +208,7 @@ main (int argc, g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CORE), ==, TRUE); - g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CHAT_STATES), + g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CONTACTS), ==, FALSE); if (prepare_result == NULL) @@ -461,8 +461,8 @@ main (int argc, g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CORE), ==, TRUE); - g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CHAT_STATES), - ==, FALSE); + g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CONTACTS), + ==, TRUE); tp_tests_connection_assert_disconnect_succeeds (conn); @@ -479,7 +479,7 @@ main (int argc, /* is_prepared becomes FALSE because the channel broke */ g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CORE), ==, FALSE); - g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CHAT_STATES), + g_assert_cmpint (tp_proxy_is_prepared (chan, TP_CHANNEL_FEATURE_CONTACTS), ==, FALSE); g_assert_error (invalidated, tp_proxy_get_invalidated (chan)->domain, tp_proxy_get_invalidated (chan)->code); diff --git a/tests/dbus/text-channel.c b/tests/dbus/text-channel.c index 673cff430..6754c189a 100644 --- a/tests/dbus/text-channel.c +++ b/tests/dbus/text-channel.c @@ -40,6 +40,9 @@ typedef struct { gchar *sent_token; TpMessageSendingFlags sending_flags; + TpHandle chat_state_contact; + TpChannelChatState chat_state; + GError *error /* initialized where needed */; gint wait; } Test; @@ -962,6 +965,124 @@ test_receive_muc_delivery (Test *test, g_ptr_array_unref (parts); } +static void +chat_state_changed_cb (TpChannel *chan, + TpHandle contact, + TpChannelChatState state, + gpointer user_data) +{ + Test *test = user_data; + + test->chat_state_contact = contact; + test->chat_state = state; + + test->wait--; + if (test->wait <= 0) + g_main_loop_quit (test->mainloop); +} + +static void +set_chat_state_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpTextChannel *channel = TP_TEXT_CHANNEL (source_object); + Test *test = user_data; + + g_assert (tp_text_channel_set_chat_state_finish ( + channel, result, &test->error)); + + test->wait--; + if (test->wait <= 0) + g_main_loop_quit (test->mainloop); +} + +static void +test_chat_states (Test *test, + gconstpointer data G_GNUC_UNUSED) +{ + GQuark features[] = { TP_TEXT_CHANNEL_FEATURE_CHAT_STATES, 0 }; + TpHandle comeau; /* he knows everyone */ + TpHandle self_handle = test->base_connection->self_handle; + + g_assert (!tp_proxy_is_prepared (test->channel, + TP_TEXT_CHANNEL_FEATURE_CHAT_STATES)); + + /* so we won't know bob's chat state */ + g_assert_cmpuint (tp_text_channel_get_chat_state (test->channel, + test->bob), ==, TP_CHANNEL_CHAT_STATE_INACTIVE); + + /* but we also won't know anyone else's */ + comeau = tp_handle_ensure (test->contact_repo, "comeau", NULL, &test->error); + g_assert_no_error (test->error); + g_assert (comeau != 0); + + g_assert_cmpuint (tp_text_channel_get_chat_state (test->channel, + comeau), ==, TP_CHANNEL_CHAT_STATE_INACTIVE); + + /* finally get some hot hot chat states */ + tp_proxy_prepare_async (test->channel, features, + proxy_prepare_cb, test); + + g_main_loop_run (test->mainloop); + g_assert_no_error (test->error); + + g_assert (tp_proxy_is_prepared (test->channel, + TP_TEXT_CHANNEL_FEATURE_CHAT_STATES)); + + /* now we're ready; let's check to see if bob and comeu come out + * with sensible results */ + + g_assert_cmpuint (tp_text_channel_get_chat_state (test->channel, + test->bob), ==, TP_CHANNEL_CHAT_STATE_COMPOSING); + g_assert_cmpuint (tp_text_channel_get_chat_state (test->channel, + comeau), ==, TP_CHANNEL_CHAT_STATE_INACTIVE); + + /* make sure change notification works */ + g_assert_cmpuint (test->chat_state_contact, ==, 0); + g_assert_cmpuint (test->chat_state, ==, 0); + g_signal_connect (test->channel, "chat-state-changed", + G_CALLBACK (chat_state_changed_cb), test); + + tp_svc_channel_interface_chat_state_emit_chat_state_changed ( + test->chan_service, test->bob, TP_CHANNEL_CHAT_STATE_ACTIVE); + + test->wait = 1; + g_main_loop_run (test->mainloop); + g_assert_no_error (test->error); + + g_assert_cmpuint (test->chat_state_contact, ==, test->bob); + g_assert_cmpuint (test->chat_state, ==, TP_CHANNEL_CHAT_STATE_ACTIVE); + test->chat_state_contact = test->chat_state = 0; + + /* this signal should have updated the text channel's hash table */ + g_assert_cmpuint (tp_text_channel_get_chat_state (test->channel, + test->bob), ==, TP_CHANNEL_CHAT_STATE_ACTIVE); + g_assert_cmpuint (tp_text_channel_get_chat_state (test->channel, + comeau), ==, TP_CHANNEL_CHAT_STATE_INACTIVE); + + /* now set our own chat state */ + tp_text_channel_set_chat_state_async (test->channel, + TP_CHANNEL_CHAT_STATE_PAUSED, set_chat_state_cb, test); + + test->wait = 2; /* the method return and the signal */ + g_main_loop_run (test->mainloop); + g_assert_no_error (test->error); + + g_assert_cmpuint (test->chat_state_contact, ==, self_handle); + g_assert_cmpuint (test->chat_state, ==, TP_CHANNEL_CHAT_STATE_PAUSED); + + /* now we'll know about bob *and* the self handle */ + g_assert_cmpuint (tp_text_channel_get_chat_state (test->channel, + test->bob), ==, TP_CHANNEL_CHAT_STATE_ACTIVE); + g_assert_cmpuint (tp_text_channel_get_chat_state (test->channel, + comeau), ==, TP_CHANNEL_CHAT_STATE_INACTIVE); + g_assert_cmpuint (tp_text_channel_get_chat_state (test->channel, + self_handle), ==, TP_CHANNEL_CHAT_STATE_PAUSED); + + /* hot */ +} + int main (int argc, char **argv) @@ -997,6 +1118,8 @@ main (int argc, test_sent_with_no_sender, teardown); g_test_add ("/text-channel/receive-muc-delivery", Test, NULL, setup, test_receive_muc_delivery, teardown); + g_test_add ("/text-channel/chat-states", Test, NULL, setup, + test_chat_states, teardown); return g_test_run (); } |