diff --git a/.gitignore b/.gitignore index f6f9621d..8c582aa3 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,10 @@ m4/ *.so *.lo src/gitversion.c +TAGS +.libs/ +_configs.sed +libprofanity.la +libtool +runvalgrind.sh +src/prof_config.h diff --git a/Makefile.am b/Makefile.am index 39306300..49a7acff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -78,6 +78,7 @@ test_sources = \ tests/log/mock_log.c \ tests/test_autocomplete.c \ tests/test_common.c \ + tests/test_contact.c \ tests/test_cmd_connect.c \ tests/test_cmd_account.c \ tests/test_cmd_rooms.c \ diff --git a/src/contact.c b/src/contact.c index 0b955548..f2f74349 100644 --- a/src/contact.c +++ b/src/contact.c @@ -172,11 +172,8 @@ p_contact_create_display_string(const PContact contact, const char * const resou GString *result_str = g_string_new(""); // use nickname if exists - if (contact->name != NULL) { - g_string_append(result_str, contact->name); - } else { - g_string_append(result_str, contact->barejid); - } + const char *display_name = p_contact_name_or_jid(contact); + g_string_append(result_str, display_name); // add resource if not default provided by profanity if (strcmp(resource, "__prof_default") != 0) { diff --git a/src/log.c b/src/log.c index 4442dcfd..b82905cf 100644 --- a/src/log.c +++ b/src/log.c @@ -131,13 +131,15 @@ void log_close(void) { g_time_zone_unref(tz); - fclose(logp); + if (logp != NULL) { + fclose(logp); + } } void log_msg(log_level_t level, const char * const area, const char * const msg) { - if (level >= level_filter) { + if (level >= level_filter && logp != NULL) { long result; dt = g_date_time_new_now(tz); @@ -238,25 +240,26 @@ chat_log_chat(const gchar * const login, gchar *other, date_fmt = g_date_time_format(dt, "%H:%M:%S"); FILE *logp = fopen(dated_log->filename, "a"); - - if (direction == PROF_IN_LOG) { - if (strncmp(msg, "/me ", 4) == 0) { - fprintf(logp, "%s - *%s %s\n", date_fmt, other, msg + 4); + if (logp != NULL) { + if (direction == PROF_IN_LOG) { + if (strncmp(msg, "/me ", 4) == 0) { + fprintf(logp, "%s - *%s %s\n", date_fmt, other, msg + 4); + } else { + fprintf(logp, "%s - %s: %s\n", date_fmt, other, msg); + } } else { - fprintf(logp, "%s - %s: %s\n", date_fmt, other, msg); + if (strncmp(msg, "/me ", 4) == 0) { + fprintf(logp, "%s - *me %s\n", date_fmt, msg + 4); + } else { + fprintf(logp, "%s - me: %s\n", date_fmt, msg); + } } - } else { - if (strncmp(msg, "/me ", 4) == 0) { - fprintf(logp, "%s - *me %s\n", date_fmt, msg + 4); - } else { - fprintf(logp, "%s - me: %s\n", date_fmt, msg); + fflush(logp); + int result = fclose(logp); + if (result == EOF) { + log_error("Error closing file %s, errno = %d", dated_log->filename, errno); } } - fflush(logp); - int result = fclose(logp); - if (result == EOF) { - log_error("Error closing file %s, errno = %d", dated_log->filename, errno); - } g_free(date_fmt); g_date_time_unref(dt); @@ -285,17 +288,18 @@ groupchat_log_chat(const gchar * const login, const gchar * const room, gchar *date_fmt = g_date_time_format(dt, "%H:%M:%S"); FILE *logp = fopen(dated_log->filename, "a"); + if (logp != NULL) { + if (strncmp(msg, "/me ", 4) == 0) { + fprintf(logp, "%s - *%s %s\n", date_fmt, nick, msg + 4); + } else { + fprintf(logp, "%s - %s: %s\n", date_fmt, nick, msg); + } - if (strncmp(msg, "/me ", 4) == 0) { - fprintf(logp, "%s - *%s %s\n", date_fmt, nick, msg + 4); - } else { - fprintf(logp, "%s - %s: %s\n", date_fmt, nick, msg); - } - - fflush(logp); - int result = fclose(logp); - if (result == EOF) { - log_error("Error closing file %s, errno = %d", dated_log->filename, errno); + fflush(logp); + int result = fclose(logp); + if (result == EOF) { + log_error("Error closing file %s, errno = %d", dated_log->filename, errno); + } } g_free(date_fmt); diff --git a/tests/test_contact.c b/tests/test_contact.c new file mode 100644 index 00000000..5bc84a38 --- /dev/null +++ b/tests/test_contact.c @@ -0,0 +1,407 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "contact.h" + +void contact_in_group(void **state) +{ + GSList *groups = NULL; + groups = g_slist_append(groups, strdup("somegroup")); + PContact contact = p_contact_new("bob@server.com", "bob", groups, "both", + "is offline", FALSE); + + gboolean result = p_contact_in_group(contact, "somegroup"); + + assert_true(result); + + p_contact_free(contact); + g_slist_free(groups); +} + +void contact_not_in_group(void **state) +{ + GSList *groups = NULL; + groups = g_slist_append(groups, strdup("somegroup")); + PContact contact = p_contact_new("bob@server.com", "bob", groups, "both", + "is offline", FALSE); + + gboolean result = p_contact_in_group(contact, "othergroup"); + + assert_false(result); + + p_contact_free(contact); + g_slist_free(groups); +} + +void contact_name_when_name_exists(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + const char *name = p_contact_name_or_jid(contact); + + assert_string_equal("bob", name); + + p_contact_free(contact); +} + +void contact_jid_when_name_not_exists(void **state) +{ + PContact contact = p_contact_new("bob@server.com", NULL, NULL, "both", + "is offline", FALSE); + + const char *jid = p_contact_name_or_jid(contact); + + assert_string_equal("bob@server.com", jid); + + p_contact_free(contact); +} + +void contact_string_when_name_exists(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + char *str = p_contact_create_display_string(contact, "laptop"); + + assert_string_equal("bob (laptop)", str); + + p_contact_free(contact); + free(str); +} + +void contact_string_when_name_not_exists(void **state) +{ + PContact contact = p_contact_new("bob@server.com", NULL, NULL, "both", + "is offline", FALSE); + + char *str = p_contact_create_display_string(contact, "laptop"); + + assert_string_equal("bob@server.com (laptop)", str); + + p_contact_free(contact); + free(str); +} + +void contact_string_when_default_resource(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + char *str = p_contact_create_display_string(contact, "__prof_default"); + + assert_string_equal("bob", str); + + p_contact_free(contact); + free(str); +} + +void contact_presence_offline(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + const char *presence = p_contact_presence(contact); + + assert_string_equal("offline", presence); + + p_contact_free(contact); +} + +void contact_presence_uses_highest_priority(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + Resource *resource10 = resource_new("resource10", RESOURCE_ONLINE, NULL, 10, NULL); + Resource *resource20 = resource_new("resource20", RESOURCE_CHAT, NULL, 20, NULL); + Resource *resource30 = resource_new("resource30", RESOURCE_AWAY, NULL, 30, NULL); + Resource *resource1 = resource_new("resource1", RESOURCE_XA, NULL, 1, NULL); + Resource *resource2 = resource_new("resource2", RESOURCE_DND, NULL, 2, NULL); + p_contact_set_presence(contact, resource10); + p_contact_set_presence(contact, resource20); + p_contact_set_presence(contact, resource30); + p_contact_set_presence(contact, resource1); + p_contact_set_presence(contact, resource2); + + const char *presence = p_contact_presence(contact); + + assert_string_equal("away", presence); + + p_contact_free(contact); +} + +void contact_presence_chat_when_same_prioroty(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10, NULL); + Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10, NULL); + Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10, NULL); + Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10, NULL); + Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10, NULL); + p_contact_set_presence(contact, resource_online); + p_contact_set_presence(contact, resource_chat); + p_contact_set_presence(contact, resource_away); + p_contact_set_presence(contact, resource_xa); + p_contact_set_presence(contact, resource_dnd); + + const char *presence = p_contact_presence(contact); + + assert_string_equal("chat", presence); + + p_contact_free(contact); +} + +void contact_presence_online_when_same_prioroty(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10, NULL); + Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10, NULL); + Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10, NULL); + Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10, NULL); + p_contact_set_presence(contact, resource_online); + p_contact_set_presence(contact, resource_away); + p_contact_set_presence(contact, resource_xa); + p_contact_set_presence(contact, resource_dnd); + + const char *presence = p_contact_presence(contact); + + assert_string_equal("online", presence); + + p_contact_free(contact); +} + +void contact_presence_away_when_same_prioroty(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10, NULL); + Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10, NULL); + Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10, NULL); + p_contact_set_presence(contact, resource_away); + p_contact_set_presence(contact, resource_xa); + p_contact_set_presence(contact, resource_dnd); + + const char *presence = p_contact_presence(contact); + + assert_string_equal("away", presence); + + p_contact_free(contact); +} + +void contact_presence_xa_when_same_prioroty(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10, NULL); + Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10, NULL); + p_contact_set_presence(contact, resource_xa); + p_contact_set_presence(contact, resource_dnd); + + const char *presence = p_contact_presence(contact); + + assert_string_equal("xa", presence); + + p_contact_free(contact); +} + +void contact_presence_dnd(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10, NULL); + p_contact_set_presence(contact, resource_dnd); + + const char *presence = p_contact_presence(contact); + + assert_string_equal("dnd", presence); + + p_contact_free(contact); +} + +void contact_subscribed_when_to(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "to", + "is offline", FALSE); + + gboolean result = p_contact_subscribed(contact); + + assert_true(result); + + p_contact_free(contact); +} + +void contact_subscribed_when_both(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both", + "is offline", FALSE); + + gboolean result = p_contact_subscribed(contact); + + assert_true(result); + + p_contact_free(contact); +} + +void contact_not_subscribed_when_from(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, "from", + "is offline", FALSE); + + gboolean result = p_contact_subscribed(contact); + + assert_false(result); + + p_contact_free(contact); +} + +void contact_not_subscribed_when_no_subscription_value(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL, + "is offline", FALSE); + + gboolean result = p_contact_subscribed(contact); + + assert_false(result); + + p_contact_free(contact); +} + +void contact_not_available(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL, + "is offline", FALSE); + + gboolean result = p_contact_is_available(contact); + + assert_false(result); + + p_contact_free(contact); +} + +void contact_not_available_when_highest_priority_away(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL, + "is offline", FALSE); + + Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10, NULL); + Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10, NULL); + Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 20, NULL); + Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10, NULL); + Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10, NULL); + p_contact_set_presence(contact, resource_online); + p_contact_set_presence(contact, resource_chat); + p_contact_set_presence(contact, resource_away); + p_contact_set_presence(contact, resource_xa); + p_contact_set_presence(contact, resource_dnd); + + gboolean result = p_contact_is_available(contact); + + assert_false(result); + + p_contact_free(contact); +} + +void contact_not_available_when_highest_priority_xa(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL, + "is offline", FALSE); + + Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10, NULL); + Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10, NULL); + Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10, NULL); + Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 20, NULL); + Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10, NULL); + p_contact_set_presence(contact, resource_online); + p_contact_set_presence(contact, resource_chat); + p_contact_set_presence(contact, resource_away); + p_contact_set_presence(contact, resource_xa); + p_contact_set_presence(contact, resource_dnd); + + gboolean result = p_contact_is_available(contact); + + assert_false(result); + + p_contact_free(contact); +} + +void contact_not_available_when_highest_priority_dnd(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL, + "is offline", FALSE); + + Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10, NULL); + Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10, NULL); + Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10, NULL); + Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10, NULL); + Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 20, NULL); + p_contact_set_presence(contact, resource_online); + p_contact_set_presence(contact, resource_chat); + p_contact_set_presence(contact, resource_away); + p_contact_set_presence(contact, resource_xa); + p_contact_set_presence(contact, resource_dnd); + + gboolean result = p_contact_is_available(contact); + + assert_false(result); + + p_contact_free(contact); +} + +void contact_available_when_highest_priority_online(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL, + "is offline", FALSE); + + Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 20, NULL); + Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10, NULL); + Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10, NULL); + Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10, NULL); + Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10, NULL); + p_contact_set_presence(contact, resource_online); + p_contact_set_presence(contact, resource_chat); + p_contact_set_presence(contact, resource_away); + p_contact_set_presence(contact, resource_xa); + p_contact_set_presence(contact, resource_dnd); + + gboolean result = p_contact_is_available(contact); + + assert_true(result); + + p_contact_free(contact); +} + +void contact_available_when_highest_priority_chat(void **state) +{ + PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL, + "is offline", FALSE); + + Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10, NULL); + Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 20, NULL); + Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10, NULL); + Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10, NULL); + Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10, NULL); + p_contact_set_presence(contact, resource_online); + p_contact_set_presence(contact, resource_chat); + p_contact_set_presence(contact, resource_away); + p_contact_set_presence(contact, resource_xa); + p_contact_set_presence(contact, resource_dnd); + + gboolean result = p_contact_is_available(contact); + + assert_true(result); + + p_contact_free(contact); +} diff --git a/tests/test_contact.h b/tests/test_contact.h new file mode 100644 index 00000000..c9d8c1fd --- /dev/null +++ b/tests/test_contact.h @@ -0,0 +1,24 @@ +void contact_in_group(void **state); +void contact_not_in_group(void **state); +void contact_name_when_name_exists(void **state); +void contact_jid_when_name_not_exists(void **state); +void contact_string_when_name_exists(void **state); +void contact_string_when_name_not_exists(void **state); +void contact_string_when_default_resource(void **state); +void contact_presence_offline(void **state); +void contact_presence_uses_highest_priority(void **state); +void contact_presence_chat_when_same_prioroty(void **state); +void contact_presence_online_when_same_prioroty(void **state); +void contact_presence_away_when_same_prioroty(void **state); +void contact_presence_xa_when_same_prioroty(void **state); +void contact_presence_dnd(void **state); +void contact_subscribed_when_to(void **state); +void contact_subscribed_when_both(void **state); +void contact_not_subscribed_when_from(void **state); +void contact_not_subscribed_when_no_subscription_value(void **state); +void contact_not_available(void **state); +void contact_not_available_when_highest_priority_away(void **state); +void contact_not_available_when_highest_priority_xa(void **state); +void contact_not_available_when_highest_priority_dnd(void **state); +void contact_available_when_highest_priority_online(void **state); +void contact_available_when_highest_priority_chat(void **state); diff --git a/tests/testsuite.c b/tests/testsuite.c index c0e98b23..c4606a49 100644 --- a/tests/testsuite.c +++ b/tests/testsuite.c @@ -5,6 +5,7 @@ #include "test_autocomplete.h" #include "test_common.h" +#include "test_contact.h" #include "test_cmd_connect.h" #include "test_cmd_account.h" #include "test_cmd_rooms.h" @@ -257,6 +258,31 @@ int main(int argc, char* argv[]) { unit_test(cmd_sub_shows_message_when_not_connected), unit_test(cmd_sub_shows_usage_when_no_arg), + unit_test(contact_in_group), + unit_test(contact_not_in_group), + unit_test(contact_name_when_name_exists), + unit_test(contact_jid_when_name_not_exists), + unit_test(contact_string_when_name_exists), + unit_test(contact_string_when_name_not_exists), + unit_test(contact_string_when_default_resource), + unit_test(contact_presence_offline), + unit_test(contact_presence_uses_highest_priority), + unit_test(contact_presence_chat_when_same_prioroty), + unit_test(contact_presence_online_when_same_prioroty), + unit_test(contact_presence_away_when_same_prioroty), + unit_test(contact_presence_xa_when_same_prioroty), + unit_test(contact_presence_dnd), + unit_test(contact_subscribed_when_to), + unit_test(contact_subscribed_when_both), + unit_test(contact_not_subscribed_when_from), + unit_test(contact_not_subscribed_when_no_subscription_value), + unit_test(contact_not_available), + unit_test(contact_not_available_when_highest_priority_away), + unit_test(contact_not_available_when_highest_priority_xa), + unit_test(contact_not_available_when_highest_priority_dnd), + unit_test(contact_available_when_highest_priority_online), + unit_test(contact_available_when_highest_priority_chat), + }; return run_tests(tests); }