summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonny Lamb <jonny.lamb@collabora.co.uk>2012-02-02 17:31:10 -0500
committerJonny Lamb <jonny.lamb@collabora.co.uk>2012-02-02 17:41:40 -0500
commitc7e35a522f01a3474f3e4271e4a2d287c9b9f61e (patch)
treed5480f1273f4ae510b45ff3186f4a386b872a319
parentbe46c968599e46578a94dea13a10e6dcce8b69e8 (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.c61
-rw-r--r--tests/dbus/channel-introspect.c12
-rw-r--r--tests/dbus/text-channel.c123
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 ();
}