Thu, 07 Aug 2025 21:34:33 -0500
Replace Purple.Avatar with Purple.Image
Purple.Avatar was unnecessary and this just moves everything to Purple.Image
which should work just fine.
Testing Done:
Loaded a demo account and verified that the avatars were shown in the contact list properly. Also called in the turtles.
Reviewed at https://reviews.imfreedom.org/r/4084/
/* * Purple - Internet Messaging Library * Copyright (C) Pidgin Developers <devel@pidgin.im> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see <https://www.gnu.org/licenses/>. */ #include <glib.h> #include <birb.h> #include <purple.h> /****************************************************************************** * Tests *****************************************************************************/ static void test_purple_person_new(void) { PurplePerson *person = NULL; person = purple_person_new(); g_assert_true(PURPLE_IS_PERSON(person)); g_assert_finalize_object(person); } static void test_purple_person_properties(void) { PurpleImage *avatar = NULL; PurpleImage *avatar1 = NULL; PurpleImage *avatar_for_display = NULL; PurpleContact *person = NULL; PurpleTags *tags = NULL; char *id = NULL; char *alias = NULL; char *color = NULL; char *color_for_display = NULL; char *name_for_display = NULL; /* Create our avatar for testing. */ avatar = g_object_new(PURPLE_TYPE_IMAGE, NULL); /* Use g_object_new so we can test setting properties by name. All of them * call the setter methods, so by doing it this way we exercise more of the * code. */ person = g_object_new( PURPLE_TYPE_PERSON, "alias", "alias", "avatar", avatar, "color", "#794a85", NULL); /* Now use g_object_get to read all of the properties. */ g_object_get(person, "id", &id, "alias", &alias, "avatar", &avatar1, "avatar-for-display", &avatar_for_display, "color", &color, "color-for-display", &color_for_display, "name-for-display", &name_for_display, "tags", &tags, NULL); /* Test all the things. */ g_assert_nonnull(id); g_clear_pointer(&id, g_free); g_assert_cmpstr(alias, ==, "alias"); g_clear_pointer(&alias, g_free); g_assert_true(avatar1 == avatar); g_clear_object(&avatar1); g_assert_true(avatar_for_display == avatar); g_clear_object(&avatar_for_display); g_assert_cmpstr(color, ==, "#794a85"); g_clear_pointer(&color, g_free); g_assert_cmpstr(color_for_display, ==, "#794a85"); g_clear_pointer(&color_for_display, g_free); g_assert_cmpstr(name_for_display, ==, "alias"); g_clear_pointer(&name_for_display, g_free); g_assert_nonnull(tags); g_clear_object(&tags); /* Additional cleanup. */ g_assert_finalize_object(person); g_assert_finalize_object(avatar); } static void test_purple_person_avatar_for_display_person(void) { PurpleImage *avatar = NULL; PurpleContactInfo *info = NULL; PurplePerson *person = NULL; guint avatar_counter = 0; guint avatar_for_display_counter = 0; person = purple_person_new(); birb_count_property_changed(G_OBJECT(person), "avatar", &avatar_counter); birb_count_property_changed(G_OBJECT(person), "avatar-for-display", &avatar_for_display_counter); avatar = g_object_new(PURPLE_TYPE_IMAGE, NULL); purple_person_set_avatar(person, avatar); g_assert_cmpuint(avatar_counter, ==, 1); g_assert_cmpuint(avatar_for_display_counter, ==, 1); info = purple_contact_info_new("id"); purple_person_add_contact_info(person, info); /* Make sure the person's avatar is overriding the contact info. */ g_assert_true(purple_person_get_avatar_for_display(person) == avatar); /* Contact info's have a reference on the person, so the easiest way to * remove that is to remove them from the person. */ purple_person_remove_contact_info(person, info); g_assert_finalize_object(person); g_assert_finalize_object(info); g_assert_finalize_object(avatar); } static void test_purple_person_avatar_for_display_contact(void) { PurpleImage *avatar = NULL; PurpleContactInfo *info = NULL; PurplePerson *person = NULL; guint counter = 0; person = purple_person_new(); birb_count_property_changed(G_OBJECT(person), "avatar-for-display", &counter); info = purple_contact_info_new("id"); avatar = g_object_new(PURPLE_TYPE_IMAGE, NULL); purple_contact_info_set_avatar(info, avatar); purple_person_add_contact_info(person, info); g_assert_cmpuint(counter, ==, 1); /* Make sure the person's avatar is overriding the contact info. */ g_assert_true(purple_person_get_avatar_for_display(person) == avatar); g_clear_object(&avatar); /* Now change the avatar on the contact info an verify that we not notified * of the property changing. */ counter = 0; avatar = g_object_new(PURPLE_TYPE_IMAGE, NULL); purple_contact_info_set_avatar(info, avatar); g_assert_cmpuint(counter, ==, 1); /* Contact info's have a reference on the person, so the easiest way to * remove that is to remove them from the person. */ purple_person_remove_contact_info(person, info); g_assert_finalize_object(person); g_assert_finalize_object(info); g_assert_finalize_object(avatar); } static void test_purple_person_color_for_display_person(void) { PurpleContactInfo *info = NULL; PurplePerson *person = NULL; const char *color = NULL; guint color_counter = 0; guint color_for_display_counter = 0; person = purple_person_new(); birb_count_property_changed(G_OBJECT(person), "color", &color_counter); birb_count_property_changed(G_OBJECT(person), "color-for-display", &color_for_display_counter); purple_person_set_color(person, "#abcdef"); g_assert_cmpuint(color_counter, ==, 1); g_assert_cmpuint(color_for_display_counter, ==, 1); /* Make sure the person's color is overriding the contact info. */ color_counter = 0; color_for_display_counter = 0; info = purple_contact_info_new("id"); purple_person_add_contact_info(person, info); color = purple_person_get_color_for_display(person); g_assert_cmpstr(color, ==, "#abcdef"); g_assert_cmpuint(color_counter, ==, 0); g_assert_cmpuint(color_for_display_counter, ==, 0); /* Contact info's have a reference on the person, so the easiest way to * remove that is to remove them from the person. */ purple_person_remove_contact_info(person, info); /* Cleanup. */ g_assert_finalize_object(person); g_assert_finalize_object(info); } static void test_purple_person_color_for_display_contact(void) { PurpleContactInfo *info = NULL; PurplePerson *person = NULL; const char *color = NULL; guint counter = 0; person = purple_person_new(); birb_count_property_changed(G_OBJECT(person), "color-for-display", &counter); info = purple_contact_info_new("id"); purple_contact_info_set_color(info, "#012345"); purple_person_add_contact_info(person, info); g_assert_cmpuint(counter, ==, 1); /* Make sure the person's color is overriding the contact info. */ color = purple_person_get_color_for_display(person); g_assert_cmpstr(color, ==, "#012345"); /* Now change the color on the contact info and verify that we are notified * of the property changing. */ counter = 0; purple_contact_info_set_color(info, "#6789ab"); g_assert_cmpuint(counter, ==, 1); /* Contact info's have a reference on the person, so the easiest way to * remove that is to remove them from the person. */ purple_person_remove_contact_info(person, info); g_assert_finalize_object(person); g_assert_finalize_object(info); } static void test_purple_person_name_for_display_person(void) { PurpleContactInfo *info = NULL; PurplePerson *person = NULL; person = purple_person_new(); purple_person_set_alias(person, "person-alias"); info = purple_contact_info_new("id"); purple_person_add_contact_info(person, info); /* Make sure the person's alias is overriding the contact info. */ g_assert_cmpstr(purple_person_get_name_for_display(person), ==, "person-alias"); /* Contact info's have a reference on the person, so the easiest way to * remove that is to remove them from the person. */ purple_person_remove_contact_info(person, info); g_assert_finalize_object(person); g_assert_finalize_object(info); } static void test_purple_person_name_for_display_contact(void) { PurpleContactInfo *info = NULL; PurplePerson *person = NULL; guint counter = 0; person = purple_person_new(); birb_count_property_changed(G_OBJECT(person), "name-for-display", &counter); info = purple_contact_info_new("id"); purple_person_add_contact_info(person, info); g_assert_cmpuint(counter, ==, 1); /* Make sure the name for display matches the id of the contact. */ g_assert_cmpstr(purple_person_get_name_for_display(person), ==, "id"); /* Now set a username on the contact and verify that the name for display * matches and that the notify signal was emitted for the property. */ counter = 0; purple_contact_info_set_username(info, "clu"); g_assert_cmpstr(purple_person_get_name_for_display(person), ==, "clu"); g_assert_cmpuint(counter, ==, 1); /* Contact info's have a reference on the person, so the easiest way to * remove that is to remove them from the person. */ purple_person_remove_contact_info(person, info); g_assert_finalize_object(person); g_assert_finalize_object(info); } static void test_purple_person_contacts_single(void) { PurpleContactInfo *info = NULL; PurplePerson *person = NULL; PurplePerson *person1 = NULL; gboolean removed = FALSE; guint counter = 0; info = purple_contact_info_new("id"); person = purple_person_new(); birb_count_list_model_items_changed(G_LIST_MODEL(person), &counter); birb_assert_list_model_n_items(person, 0); purple_person_add_contact_info(person, info); birb_assert_list_model_n_items(person, 1); g_assert_cmpuint(counter, ==, 1); person1 = purple_contact_info_get_person(info); g_assert_true(person1 == person); counter = 0; removed = purple_person_remove_contact_info(person, info); g_assert_true(removed); g_assert_cmpuint(counter, ==, 1); birb_assert_list_model_n_items(person, 0); person1 = purple_contact_info_get_person(info); g_assert_null(person1); g_assert_finalize_object(person); g_assert_finalize_object(info); } static void test_purple_person_contacts_multiple(void) { PurplePerson *person = NULL; GPtrArray *infos = NULL; const int n_infos = 5; guint counter = 0; person = purple_person_new(); birb_count_list_model_items_changed(G_LIST_MODEL(person), &counter); infos = g_ptr_array_new_full(n_infos, g_object_unref); for(int i = 0; i < n_infos; i++) { PurpleContactInfo *info = NULL; char *username = NULL; counter = 0; birb_assert_list_model_n_items(person, i); username = g_strdup_printf("username%d", i); info = purple_contact_info_new(NULL); purple_contact_info_set_username(info, username); g_free(username); /* Add the contact info to the ptr array so we can remove it below. */ g_ptr_array_add(infos, info); /* Add the contact info to the person and make sure that all the magic * happened. */ purple_person_add_contact_info(person, info); birb_assert_list_model_n_items(person, i + 1); g_assert_cmpuint(counter, ==, 1); } for(int i = 0; i < n_infos; i++) { PurpleContactInfo *info = g_ptr_array_index(infos, i); gboolean removed = FALSE; counter = 0; birb_assert_list_model_n_items(person, n_infos - i); removed = purple_person_remove_contact_info(person, info); g_assert_true(removed); birb_assert_list_model_n_items(person, n_infos - (i + 1)); g_assert_cmpuint(counter, ==, 1); } /* Final sanity check that the person has no more contacts. */ birb_assert_list_model_n_items(person, 0); g_ptr_array_free(infos, TRUE); g_assert_finalize_object(person); } static void test_purple_person_priority_single(void) { PurpleContactInfo *info = NULL; PurpleContactInfo *priority = NULL; PurplePerson *person = NULL; PurplePresence *presence = NULL; guint counter = 0; person = purple_person_new(); birb_count_property_changed(G_OBJECT(person), "priority-contact-info", &counter); priority = purple_person_get_priority_contact_info(person); g_assert_null(priority); /* Now create a real contact. */ info = purple_contact_info_new(NULL); purple_person_add_contact_info(person, info); /* Set the presence of the contact. */ presence = purple_contact_info_get_presence(info); purple_presence_set_primitive(presence, PURPLE_PRESENCE_PRIMITIVE_AVAILABLE); g_assert_cmpuint(counter, ==, 1); priority = purple_person_get_priority_contact_info(person); g_assert_true(priority == info); /* Contact info's have a reference on the person, so the easiest way to * remove that is to remove them from the person. */ purple_person_remove_contact_info(person, info); g_assert_finalize_object(person); g_assert_finalize_object(info); } static void test_purple_person_priority_multiple_with_change(void) { PurpleContactInfo *priority = NULL; PurpleContactInfo *first = NULL; PurpleContactInfo *sorted_contact = NULL; PurplePerson *person = NULL; PurplePresence *sorted_presence = NULL; guint counter = 0; int n_infos = 5; /* This unit test is a bit complicated, but it adds 5 contact infos to a * person all whose presences are set to offline. After adding all the * contact infos, we verify that the first contact info we added is the * priority contact info. Then we flip the active status of the n_infos - 2 * infos to available. This should make it the priority contact info which * we then assert. */ /* Create the person and connected to the notify signal for the * priority-contact property. */ person = purple_person_new(); birb_count_property_changed(G_OBJECT(person), "priority-contact-info", &counter); priority = purple_person_get_priority_contact_info(person); g_assert_null(priority); /* Create and add all contact infos. */ for(int i = 0; i < n_infos; i++) { PurpleContactInfo *info = NULL; char *username = NULL; /* Set counter to 0 as it shouldn't be called as the priority contact * info shouldn't change except for the first index. */ counter = 0; /* Now create a real contact. */ username = g_strdup_printf("username%d", i + 1); info = purple_contact_info_new(NULL); purple_contact_info_set_username(info, username); g_free(username); purple_person_add_contact_info(person, info); if(i == 0) { first = g_object_ref(info); g_assert_cmpuint(counter, ==, 1); } else { g_assert_cmpuint(counter, ==, 0); if(i == n_infos - 2) { PurplePresence *presence = NULL; /* Add a reference to the presence of this specific contact * info, as we want to tweak it later. */ presence = purple_contact_info_get_presence(info); sorted_presence = g_object_ref(presence); sorted_contact = g_object_ref(info); } } g_clear_object(&info); } birb_assert_list_model_n_items(person, n_infos); priority = purple_person_get_priority_contact_info(person); g_assert_true(priority == first); g_clear_object(&first); /* Now set the second from the last contact info's status to available, and * verify that that contact info is now the priority contact info. */ counter = 0; purple_presence_set_primitive(sorted_presence, PURPLE_PRESENCE_PRIMITIVE_AVAILABLE); priority = purple_person_get_priority_contact_info(person); g_assert_true(priority == sorted_contact); g_assert_cmpuint(counter, ==, 1); /* Cleanup. */ purple_person_remove_all_contact_infos(person); g_clear_object(&sorted_contact); g_clear_object(&sorted_presence); g_assert_finalize_object(person); } /****************************************************************************** * Matches tests *****************************************************************************/ static void test_purple_person_matches_accepts_null(void) { PurplePerson *person = purple_person_new(); g_assert_true(purple_person_matches(person, NULL)); g_assert_finalize_object(person); } static void test_purple_person_matches_empty_string(void) { PurplePerson *person = purple_person_new(); g_assert_true(purple_person_matches(person, "")); g_assert_finalize_object(person); } static void test_purple_person_matches_alias(void) { PurplePerson *person = purple_person_new(); purple_person_set_alias(person, "this is the alias"); g_assert_true(purple_person_matches(person, "the")); g_assert_false(purple_person_matches(person, "what")); g_assert_finalize_object(person); } static void test_purple_person_matches_contact_info(void) { PurplePerson *person = purple_person_new(); PurpleContactInfo *info = purple_contact_info_new(NULL); purple_contact_info_set_username(info, "user1"); purple_person_add_contact_info(person, info); g_assert_true(purple_person_matches(person, "user1")); /* Contact info's have a reference on the person, so the easiest way to * remove that is to remove them from the person. */ purple_person_remove_contact_info(person, info); g_assert_finalize_object(person); } /****************************************************************************** * Main *****************************************************************************/ int main(int argc, char *argv[]) { g_test_init(&argc, &argv, NULL); g_test_set_nonfatal_assertions(); g_test_add_func("/person/new", test_purple_person_new); g_test_add_func("/person/properties", test_purple_person_properties); g_test_add_func("/person/avatar-for-display/person", test_purple_person_avatar_for_display_person); g_test_add_func("/person/avatar-for-display/contact", test_purple_person_avatar_for_display_contact); g_test_add_func("/person/color-for-display/person", test_purple_person_color_for_display_person); g_test_add_func("/person/color-for-display/contact", test_purple_person_color_for_display_contact); g_test_add_func("/person/name-for-display/person", test_purple_person_name_for_display_person); g_test_add_func("/person/name-for-display/contact", test_purple_person_name_for_display_contact); g_test_add_func("/person/contacts/single", test_purple_person_contacts_single); g_test_add_func("/person/contacts/multiple", test_purple_person_contacts_multiple); g_test_add_func("/person/priority/single", test_purple_person_priority_single); g_test_add_func("/person/priority/multiple-with-change", test_purple_person_priority_multiple_with_change); g_test_add_func("/person/matches/accepts_null", test_purple_person_matches_accepts_null); g_test_add_func("/person/matches/empty_string", test_purple_person_matches_empty_string); g_test_add_func("/person/matches/alias", test_purple_person_matches_alias); g_test_add_func("/person/matches/contact_info", test_purple_person_matches_contact_info); return g_test_run(); }