Add Purple.ProtocolConversation.refresh

Mon, 23 Dec 2024 20:39:36 -0600

author
Gary Kramlich <grim@reaperworld.com>
date
Mon, 23 Dec 2024 20:39:36 -0600
changeset 43104
f87ae4effec7
parent 43103
fac24c225f6e
child 43105
73562f3b9809

Add Purple.ProtocolConversation.refresh

This virtual function asks the protocol to update an existing conversation.
This could be to bring it back online, update the topic, whatever.

Testing Done:
Ran the unit tests under valgrind and called in the turtles for good measure.

Bugs closed: PIDGIN-17989

Reviewed at https://reviews.imfreedom.org/r/3699/

libpurple/purpleprotocolconversation.c file | annotate | diff | comparison | revisions
libpurple/purpleprotocolconversation.h file | annotate | diff | comparison | revisions
libpurple/tests/test_protocol_conversation.c file | annotate | diff | comparison | revisions
--- a/libpurple/purpleprotocolconversation.c	Fri Dec 06 15:18:29 2024 -0600
+++ b/libpurple/purpleprotocolconversation.c	Mon Dec 23 20:39:36 2024 -0600
@@ -499,3 +499,36 @@
 		          G_OBJECT_TYPE_NAME(protocol));
 	}
 }
+
+gboolean
+purple_protocol_conversation_implements_refresh(PurpleProtocolConversation *protocol)
+{
+	PurpleProtocolConversationInterface *iface = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_PROTOCOL_CONVERSATION(protocol), FALSE);
+
+	iface = PURPLE_PROTOCOL_CONVERSATION_GET_IFACE(protocol);
+	if(iface->refresh != NULL) {
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+void
+purple_protocol_conversation_refresh(PurpleProtocolConversation *protocol,
+                                     PurpleConversation *conversation)
+{
+	PurpleProtocolConversationInterface *iface = NULL;
+
+	g_return_if_fail(PURPLE_IS_PROTOCOL_CONVERSATION(protocol));
+	g_return_if_fail(PURPLE_IS_CONVERSATION(conversation));
+
+	iface = PURPLE_PROTOCOL_CONVERSATION_GET_IFACE(protocol);
+	if(iface->refresh != NULL) {
+		iface->refresh(protocol, conversation);
+	} else {
+		g_warning("%s does not implement refresh",
+		          G_OBJECT_TYPE_NAME(protocol));
+	}
+}
--- a/libpurple/purpleprotocolconversation.h	Fri Dec 06 15:18:29 2024 -0600
+++ b/libpurple/purpleprotocolconversation.h	Mon Dec 23 20:39:36 2024 -0600
@@ -95,6 +95,8 @@
 
 	void (*send_typing)(PurpleProtocolConversation *protocol, PurpleConversation *conversation, PurpleTypingState state);
 
+	void (*refresh)(PurpleProtocolConversation *protocol, PurpleConversation *conversation);
+
 	/*< private >*/
 	gpointer reserved[8];
 };
@@ -446,6 +448,36 @@
 PURPLE_AVAILABLE_IN_3_0
 void purple_protocol_conversation_send_typing(PurpleProtocolConversation *protocol, PurpleConversation *conversation, PurpleTypingState state);
 
+/**
+ * purple_protocol_conversation_implements_refresh:
+ *
+ * Checks if @protocol implements [vfunc@ProtocolConversation.refresh].
+ *
+ * Returns: true if everything is implemented; false otherwise.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+gboolean purple_protocol_conversation_implements_refresh(PurpleProtocolConversation *protocol);
+
+/**
+ * purple_protocol_conversation_refresh:
+ * @conversation: the conversation
+ *
+ * Asks the protocol to refresh a conversation.
+ *
+ * A conversation could need to be refreshed for any number of reasons, but the
+ * primary case is to help restore conversations when user interfaces restart.
+ *
+ * This allows the user interface to recreate a conversation and then have the
+ * protocol do whatever is necessary to bring the conversation back up to date
+ * and online.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+void purple_protocol_conversation_refresh(PurpleProtocolConversation *protocol, PurpleConversation *conversation);
+
 G_END_DECLS
 
 #endif /* PURPLE_PROTOCOL_CONVERSATION_H */
--- a/libpurple/tests/test_protocol_conversation.c	Fri Dec 06 15:18:29 2024 -0600
+++ b/libpurple/tests/test_protocol_conversation.c	Mon Dec 23 20:39:36 2024 -0600
@@ -458,6 +458,45 @@
 	g_test_trap_assert_stderr("*Purple-WARNING*TestPurpleProtocolConversationEmpty*send_typing*");
 }
 
+static void
+test_purple_protocol_conversation_empty_implements_refresh(void) {
+	PurpleProtocolConversation *protocol = NULL;
+
+	protocol = g_object_new(test_purple_protocol_conversation_empty_get_type(),
+	                        NULL);
+
+	g_assert_false(purple_protocol_conversation_implements_refresh(protocol));
+
+	g_assert_finalize_object(protocol);
+}
+
+static void
+test_purple_protocol_conversation_empty_refresh(void) {
+	if(g_test_subprocess()) {
+		PurpleAccount *account = NULL;
+		PurpleConversation *conversation = NULL;
+		PurpleProtocolConversation *protocol = NULL;
+
+		protocol = g_object_new(test_purple_protocol_conversation_empty_get_type(),
+		                        NULL);
+		account = purple_account_new("test", "test");
+		conversation = g_object_new(
+			PURPLE_TYPE_CONVERSATION,
+			"account", account,
+			"type", PURPLE_CONVERSATION_TYPE_DM,
+			NULL);
+
+		purple_protocol_conversation_refresh(protocol, conversation);
+
+		g_clear_object(&account);
+		g_clear_object(&conversation);
+		g_clear_object(&protocol);
+	}
+
+	g_test_trap_subprocess(NULL, 0, 0);
+	g_test_trap_assert_stderr("*Purple-WARNING*TestPurpleProtocolConversationEmpty*refresh*");
+}
+
 /******************************************************************************
  * TestProtocolConversation Implementation
  *****************************************************************************/
@@ -491,6 +530,7 @@
 	guint set_avatar_finish;
 
 	guint send_typing;
+	guint refresh;
 };
 
 static PurpleCreateConversationDetails *
@@ -796,6 +836,18 @@
 }
 
 static void
+test_purple_protocol_conversation_refresh(PurpleProtocolConversation *protocol,
+                                          PurpleConversation *conversation)
+{
+	TestPurpleProtocolConversation *test_protocol = NULL;
+
+	test_protocol = TEST_PURPLE_PROTOCOL_CONVERSATION(protocol);
+	test_protocol->refresh += 1;
+
+	g_assert_true(PURPLE_IS_CONVERSATION(conversation));
+}
+
+static void
 test_purple_protocol_conversation_iface_init(PurpleProtocolConversationInterface *iface) {
 	iface->get_create_conversation_details = test_purple_protocol_conversation_get_create_conversation_details;
 	iface->create_conversation_async = test_purple_protocol_conversation_create_conversation_async;
@@ -818,6 +870,7 @@
 	iface->set_avatar_finish = test_purple_protocol_conversation_set_avatar_finish;
 
 	iface->send_typing = test_purple_protocol_conversation_send_typing;
+	iface->refresh = test_purple_protocol_conversation_refresh;
 }
 
 G_DEFINE_FINAL_TYPE_WITH_CODE(TestPurpleProtocolConversation,
@@ -850,6 +903,7 @@
 	protocol->set_avatar_finish = 0;
 
 	protocol->send_typing = 0;
+	protocol->refresh = 0;
 }
 
 static void
@@ -1094,7 +1148,6 @@
 	conversation = g_object_new(
 		PURPLE_TYPE_CONVERSATION,
 		"account", account,
-		"name", "this is required at the moment",
 		"type", PURPLE_CONVERSATION_TYPE_DM,
 		NULL);
 
@@ -1158,7 +1211,6 @@
 	conversation = g_object_new(
 		PURPLE_TYPE_CONVERSATION,
 		"account", account,
-		"name", "this is required at the moment",
 		"type", PURPLE_CONVERSATION_TYPE_DM,
 		NULL);
 
@@ -1302,7 +1354,6 @@
 	conversation = g_object_new(
 		PURPLE_TYPE_CONVERSATION,
 		"account", account,
-		"name", "this is required at the moment",
 		"type", PURPLE_CONVERSATION_TYPE_DM,
 		NULL);
 
@@ -1352,7 +1403,6 @@
 	conversation = g_object_new(
 		PURPLE_TYPE_CONVERSATION,
 		"account", account,
-		"name", "this is required at the moment",
 		"type", PURPLE_CONVERSATION_TYPE_DM,
 		NULL);
 
@@ -1367,6 +1417,49 @@
 }
 
 /******************************************************************************
+ * TestProtocolConversation Refresh Tests
+ ****************************************************************************/
+static void
+test_purple_protocol_conversation_implements_refresh(void) {
+	PurpleProtocolConversation *protocol = NULL;
+
+	protocol = g_object_new(test_purple_protocol_conversation_get_type(),
+	                        NULL);
+
+	g_assert_true(purple_protocol_conversation_implements_refresh(protocol));
+
+	g_assert_finalize_object(protocol);
+}
+
+static void
+test_purple_protocol_conversation_refresh_normal(void) {
+	TestPurpleProtocolConversation *test_protocol = NULL;
+	PurpleAccount *account = NULL;
+	PurpleConversation *conversation = NULL;
+	PurpleProtocolConversation *protocol = NULL;
+
+	protocol = g_object_new(test_purple_protocol_conversation_get_type(),
+	                        NULL);
+	test_protocol = TEST_PURPLE_PROTOCOL_CONVERSATION(protocol);
+
+	account = purple_account_new("test", "test");
+
+	conversation = g_object_new(
+		PURPLE_TYPE_CONVERSATION,
+		"account", account,
+		"type", PURPLE_CONVERSATION_TYPE_DM,
+		NULL);
+
+	test_purple_protocol_conversation_refresh(protocol, conversation);
+
+	g_assert_cmpuint(test_protocol->refresh, ==, 1);
+
+	g_clear_object(&conversation);
+	g_clear_object(&account);
+	g_clear_object(&protocol);
+}
+
+/******************************************************************************
  * Main
  *****************************************************************************/
 gint
@@ -1412,6 +1505,12 @@
 	g_test_add_func("/protocol-conversation/empty/send-typing",
 	                test_purple_protocol_conversation_empty_send_typing);
 
+	/* Empty refresh tests. */
+	g_test_add_func("/protocol-conversation/empty/implements-refresh",
+	                test_purple_protocol_conversation_empty_implements_refresh);
+	g_test_add_func("/protocol-conversation/empty/refresh",
+	                test_purple_protocol_conversation_empty_refresh);
+
 	/* Normal create conversation tests. */
 	g_test_add_func("/protocol-conversation/normal/implements-create-conversation",
 	                test_purple_protocol_conversation_implements_create_conversation);
@@ -1476,5 +1575,11 @@
 	g_test_add_func("/protocol-conversation/normal/send-typing",
 	                test_purple_protocol_conversation_send_typing_normal);
 
+	/* Normal refresh tests. */
+	g_test_add_func("/protocol-conversation/normal/implements-refresh",
+	                test_purple_protocol_conversation_implements_refresh);
+	g_test_add_func("/protocol-conversation/normal/refresh",
+	                test_purple_protocol_conversation_refresh_normal);
+
 	return g_test_run();
 }

mercurial