about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore7
-rw-r--r--Makefile.am1
-rw-r--r--src/contact.c7
-rw-r--r--src/log.c58
-rw-r--r--tests/test_contact.c407
-rw-r--r--tests/test_contact.h24
-rw-r--r--tests/testsuite.c26
7 files changed, 498 insertions, 32 deletions
diff --git a/.gitignore b/.gitignore
index 5c7b7553..f5e02c37 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,10 @@ plugins/
 src/gitversion.c
 *_key.txt
 *_fingerprints.txt
+TAGS
+.libs/
+_configs.sed
+libprofanity.la
+libtool
+runvalgrind.sh
+src/prof_config.h
diff --git a/Makefile.am b/Makefile.am
index 61c824b5..e1905ad8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -68,6 +68,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 <glib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <stdlib.h>
+
+#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);
 }