diff -r 86e0a26348a1 -r 393c2ea6b399 libpurple/tests/test_conversation_member.c --- a/libpurple/tests/test_conversation_member.c Fri Mar 03 01:22:08 2023 -0600 +++ b/libpurple/tests/test_conversation_member.c Fri Mar 03 01:23:31 2023 -0600 @@ -44,6 +44,7 @@ PurpleContactInfo *info1 = NULL; PurpleConversationMember *member = NULL; PurpleTags *tags = NULL; + PurpleTypingState typing_state = PURPLE_TYPING_STATE_NONE; info = purple_contact_info_new("abc123"); @@ -54,17 +55,20 @@ member = g_object_new( PURPLE_TYPE_CONVERSATION_MEMBER, "contact-info", info, + "typing-state", PURPLE_TYPING_STATE_TYPING, NULL); /* Now use g_object_get to read all of the properties. */ g_object_get(member, "contact-info", &info1, "tags", &tags, + "typing-state", &typing_state, NULL); /* Compare all the things. */ g_assert_true(info1 == info); g_assert_true(PURPLE_IS_TAGS(tags)); + g_assert_cmpint(typing_state, ==, PURPLE_TYPING_STATE_TYPING); /* Free/unref all the things. */ g_clear_object(&info1); @@ -75,6 +79,79 @@ } /****************************************************************************** + * Typing State Timeout + *****************************************************************************/ +static void +test_purple_conversation_manager_timeout_notify(G_GNUC_UNUSED GObject *obj, + G_GNUC_UNUSED GParamSpec *pspec, + gpointer data) +{ + GMainLoop *loop = data; + static guint count = 0; + + /* Increment count each time we're called. We're expecting to be called + * twice, so after that quit the main loop. + */ + count++; + if(count >= 2) { + g_main_loop_quit(loop); + } +} + +static gboolean +test_purple_conversation_manager_timeout_fail_safe(gpointer data) { + GMainLoop *loop = data; + + g_warning("fail safe triggered"); + + g_main_loop_quit(loop); + + return G_SOURCE_REMOVE; +} + +static void +test_purple_conversation_member_typing_state_timeout(void) { + PurpleContactInfo *info = NULL; + PurpleConversationMember *member = NULL; + PurpleTypingState typing_state = PURPLE_TYPING_STATE_TYPING; + GMainLoop *loop = NULL; + + /* Create the main loop as we'll need it to let the timeout fire. */ + loop = g_main_loop_new(NULL, FALSE); + + /* Create the member and add a notify callback on the typing-state property + * so we can check it and exit the main loop. + */ + info = purple_contact_info_new(NULL); + member = purple_conversation_member_new(info); + g_signal_connect(member, "notify::typing-state", + G_CALLBACK(test_purple_conversation_manager_timeout_notify), + loop); + + /* Set the state to typing with a timeout of 1 second. */ + purple_conversation_member_set_typing_state(member, + PURPLE_TYPING_STATE_TYPING, 1); + + /* Add a fail safe timeout at 2 seconds to make sure the test won't get + * stuck waiting forever. + */ + g_timeout_add_seconds(2, + test_purple_conversation_manager_timeout_fail_safe, + loop); + + /* Run the main loop and let the timeouts fire. */ + g_main_loop_run(loop); + + /* Verify that our state got reset back to PURPLE_TYPING_STATE_NONE. */ + typing_state = purple_conversation_member_get_typing_state(member); + g_assert_cmpint(typing_state, ==, PURPLE_TYPING_STATE_NONE); + + /* Clean everything up. */ + g_clear_object(&info); + g_clear_object(&member); +} + +/****************************************************************************** * Main *****************************************************************************/ gint @@ -86,5 +163,8 @@ g_test_add_func("/conversation-member/properties", test_purple_conversation_member_properties); + g_test_add_func("/conversation-member/typing-state/timeout", + test_purple_conversation_member_typing_state_timeout); + return g_test_run(); }