diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/chat_session.c | 294 | ||||
-rw-r--r-- | src/chat_session.h | 12 | ||||
-rw-r--r-- | src/command/command.c | 9 | ||||
-rw-r--r-- | src/command/commands.c | 49 | ||||
-rw-r--r-- | src/otr/otr.c | 3 | ||||
-rw-r--r-- | src/server_events.c | 6 | ||||
-rw-r--r-- | src/ui/core.c | 8 | ||||
-rw-r--r-- | src/ui/inputwin.c | 16 | ||||
-rw-r--r-- | src/xmpp/message.c | 27 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 5 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 2 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 11 | ||||
-rw-r--r-- | tests/helpers.c | 11 | ||||
-rw-r--r-- | tests/helpers.h | 3 | ||||
-rw-r--r-- | tests/test_chat_session.c | 125 | ||||
-rw-r--r-- | tests/test_chat_session.h | 11 | ||||
-rw-r--r-- | tests/test_cmd_otr.c | 2 | ||||
-rw-r--r-- | tests/test_server_events.c | 7 | ||||
-rw-r--r-- | tests/testsuite.c | 36 | ||||
-rw-r--r-- | tests/xmpp/stub_xmpp.c | 7 |
21 files changed, 466 insertions, 179 deletions
diff --git a/Makefile.am b/Makefile.am index 520e4c19..4639f8c8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,6 +88,7 @@ tests_sources = \ tests/test_roster_list.c tests/test_roster_list.h \ tests/test_server_events.c tests/test_server_events.h \ tests/test_autocomplete.c tests/test_autocomplete.h \ + tests/test_chat_session.c tests/test_chat_session.h \ tests/testsuite.c main_source = src/main.c diff --git a/src/chat_session.c b/src/chat_session.c index d27a3449..67104fa6 100644 --- a/src/chat_session.c +++ b/src/chat_session.c @@ -34,6 +34,7 @@ #include <stdlib.h> #include <string.h> +#include <assert.h> #include <glib.h> @@ -57,24 +58,30 @@ typedef enum { typedef struct chat_session_t { char *barejid; char *resource; - gboolean supported; + gboolean send_states; chat_state_t state; GTimer *active_timer; gboolean sent; + gboolean includes_message; } ChatSession; static GHashTable *sessions; static ChatSession* -_chat_session_new(const char * const barejid, gboolean supported) +_chat_session_new(const char * const barejid, const char * const resource, gboolean send_states) { ChatSession *new_session = malloc(sizeof(struct chat_session_t)); new_session->barejid = strdup(barejid); - new_session->resource = NULL; - new_session->supported = supported; + if (resource) { + new_session->resource = strdup(resource); + } else { + new_session->resource = NULL; + } + new_session->send_states = send_states; new_session->state = CHAT_STATE_STARTED; new_session->active_timer = g_timer_new(); new_session->sent = FALSE; + new_session->includes_message = FALSE; return new_session; } @@ -84,6 +91,7 @@ _chat_session_free(ChatSession *session) { if (session != NULL) { free(session->barejid); + free(session->resource); if (session->active_timer != NULL) { g_timer_destroy(session->active_timer); session->active_timer = NULL; @@ -107,137 +115,247 @@ chat_sessions_clear(void) } gboolean -chat_session_on_message_send(const char * const barejid) +chat_session_exists(const char * const barejid) { - gboolean send_state = FALSE; - if (prefs_get_boolean(PREF_STATES)) { - ChatSession *session = g_hash_table_lookup(sessions, barejid); - if (!session) { - session = _chat_session_new(barejid, TRUE); - g_hash_table_insert(sessions, strdup(barejid), session); + ChatSession *session = g_hash_table_lookup(sessions, barejid); - } - if (session->supported) { - session->state = CHAT_STATE_ACTIVE; - g_timer_start(session->active_timer); - session->sent = TRUE; - send_state = TRUE; - } - } + return (session != NULL); +} + +char* +chat_session_get_resource(const char * const barejid) +{ + ChatSession *session = g_hash_table_lookup(sessions, barejid); + assert(session != NULL); - return send_state; + return session->resource; +} + +gboolean +chat_session_send_states(const char * const barejid) +{ + ChatSession *session = g_hash_table_lookup(sessions, barejid); + assert(session != NULL); + + return session->send_states; } void -chat_session_on_incoming_message(const char * const barejid, gboolean supported) +chat_session_on_incoming_message(const char * const barejid, const char * const resource, gboolean send_states) { ChatSession *session = g_hash_table_lookup(sessions, barejid); + GString *log_msg = g_string_new(""); + + // no session exists, create one if (!session) { - session = _chat_session_new(barejid, supported); + g_string_append(log_msg, "Creating chat session for "); + g_string_append(log_msg, barejid); + if (resource) { + g_string_append(log_msg, "/"); + g_string_append(log_msg, resource); + } + session = _chat_session_new(barejid, resource, send_states); + g_hash_table_insert(sessions, strdup(barejid), session); + + // session exists for different resource, replace session + } else if (g_strcmp0(session->resource, resource) != 0) { + g_string_append(log_msg, "Replacing chat session for "); + g_string_append(log_msg, barejid); + if (session->resource) { + g_string_append(log_msg, "/"); + g_string_append(log_msg, session->resource); + } + g_string_append(log_msg, " with session for "); + g_string_append(log_msg, barejid); + if (resource) { + g_string_append(log_msg, "/"); + g_string_append(log_msg, resource); + } + g_hash_table_remove(sessions, session); + session = _chat_session_new(barejid, resource, send_states); + session->includes_message = TRUE; g_hash_table_insert(sessions, strdup(barejid), session); + + // session exists for resource, update state + } else { + g_string_append(log_msg, "Updating chat session for "); + g_string_append(log_msg, session->barejid); + if (session->resource) { + g_string_append(log_msg, "/"); + g_string_append(log_msg, session->resource); + } + session->send_states = send_states; + session->includes_message = TRUE; + } + if (send_states) { + g_string_append(log_msg, ", chat states supported"); } else { - session->supported = supported; + g_string_append(log_msg, ", chat states not supported"); } + + log_debug(log_msg->str); + g_string_free(log_msg, TRUE); } void -chat_session_on_window_open(const char * const barejid) +chat_session_on_message_send(const char * const barejid) { - if (prefs_get_boolean(PREF_STATES)) { - ChatSession *session = g_hash_table_lookup(sessions, barejid); - if (!session) { - session = _chat_session_new(barejid, TRUE); - g_hash_table_insert(sessions, strdup(barejid), session); - } + ChatSession *session = g_hash_table_lookup(sessions, barejid); + + // if no session exists, create one with no resource, and send states + if (!session) { + log_debug("Creating chat session for %s, chat states supported", barejid); + session = _chat_session_new(barejid, NULL, TRUE); + g_hash_table_insert(sessions, strdup(barejid), session); } + + session->state = CHAT_STATE_ACTIVE; + g_timer_start(session->active_timer); + session->sent = TRUE; + session->includes_message = TRUE; } void chat_session_on_window_close(const char * const barejid) { - if (prefs_get_boolean(PREF_STATES)) { - ChatSession *session = g_hash_table_lookup(sessions, barejid); - // send <gone/> chat state before closing - if (session->supported) { - session->state = CHAT_STATE_GONE; - message_send_gone(barejid); - session->sent = TRUE; - g_hash_table_remove(sessions, barejid); + ChatSession *session = g_hash_table_lookup(sessions, barejid); + + if (session) { + if (prefs_get_boolean(PREF_STATES) && session->send_states && session->includes_message) { + GString *jid = g_string_new(session->barejid); + if (session->resource) { + g_string_append(jid, "/"); + g_string_append(jid, session->resource); + } + message_send_gone(jid->str); + g_string_free(jid, TRUE); + } + GString *log_msg = g_string_new("Removing chat session for "); + g_string_append(log_msg, barejid); + if (session->resource) { + g_string_append(log_msg, "/"); + g_string_append(log_msg, session->resource); } + log_debug(log_msg->str); + g_string_free(log_msg, TRUE); + g_hash_table_remove(sessions, barejid); } } void -chat_session_on_cancel(const char * const jid) +chat_session_on_activity(const char * const barejid) { - if (prefs_get_boolean(PREF_STATES)) { - ChatSession *session = g_hash_table_lookup(sessions, jid); - if (session) { - session->supported = FALSE; + ChatSession *session = g_hash_table_lookup(sessions, barejid); + + if (!session) { + log_debug("Creating chat session for %s, chat states supported", barejid); + session = _chat_session_new(barejid, NULL, TRUE); + g_hash_table_insert(sessions, strdup(barejid), session); + } + + if (session->state != CHAT_STATE_COMPOSING) { + session->sent = FALSE; + } + + session->state = CHAT_STATE_COMPOSING; + g_timer_start(session->active_timer); + + if (!session->sent || session->state == CHAT_STATE_PAUSED) { + if (prefs_get_boolean(PREF_STATES) && prefs_get_boolean(PREF_OUTTYPE) && session->send_states) { + GString *jid = g_string_new(session->barejid); + if (session->resource) { + g_string_append(jid, "/"); + g_string_append(jid, session->resource); + } + message_send_composing(jid->str); + g_string_free(jid, TRUE); } + session->sent = TRUE; } } void -chat_session_on_activity(const char * const barejid) +chat_session_on_inactivity(const char * const barejid) { ChatSession *session = g_hash_table_lookup(sessions, barejid); - if (session) { - if (session->supported) { - if (session->state != CHAT_STATE_COMPOSING) { + if (!session) { + return; + } + + if (session->active_timer != NULL) { + gdouble elapsed = g_timer_elapsed(session->active_timer, NULL); + + if ((prefs_get_gone() != 0) && (elapsed > (prefs_get_gone() * 60.0))) { + if (session->state != CHAT_STATE_GONE) { + session->sent = FALSE; + } + session->state = CHAT_STATE_GONE; + + } else if (elapsed > INACTIVE_TIMOUT) { + if (session->state != CHAT_STATE_INACTIVE) { session->sent = FALSE; } + session->state = CHAT_STATE_INACTIVE; - session->state = CHAT_STATE_COMPOSING; - g_timer_start(session->active_timer); + } else if (elapsed > PAUSED_TIMOUT) { + if (session->state == CHAT_STATE_COMPOSING) { + session->sent = FALSE; + session->state = CHAT_STATE_PAUSED; + } + } + } - if (!session->sent || session->state == CHAT_STATE_PAUSED) { - message_send_composing(barejid); - session->sent = TRUE; + if (session->sent == FALSE) { + GString *jid = g_string_new(session->barejid); + if (session->resource) { + g_string_append(jid, "/"); + g_string_append(jid, session->resource); + } + if (session->state == CHAT_STATE_GONE) { + if (prefs_get_boolean(PREF_STATES) && session->send_states && session->includes_message) { + message_send_gone(jid->str); + } + session->sent = TRUE; + GString *log_msg = g_string_new("Removing chat session for "); + g_string_append(log_msg, barejid); + if (session->resource) { + g_string_append(log_msg, "/"); + g_string_append(log_msg, session->resource); + } + log_debug(log_msg->str); + g_string_free(log_msg, TRUE); + g_hash_table_remove(sessions, barejid); + } else if (session->state == CHAT_STATE_INACTIVE) { + if (prefs_get_boolean(PREF_STATES) && session->send_states) { + message_send_inactive(jid->str); } + session->sent = TRUE; + } else if (session->state == CHAT_STATE_PAUSED && prefs_get_boolean(PREF_OUTTYPE)) { + if (prefs_get_boolean(PREF_STATES) && session->send_states) { + message_send_paused(jid->str); + } + session->sent = TRUE; } + g_string_free(jid, TRUE); } } void -chat_session_on_inactivity(const char * const barejid) +chat_session_on_cancel(const char * const jid) { - ChatSession *session = g_hash_table_lookup(sessions, barejid); - if (session && session->supported) { - if (session->active_timer != NULL) { - gdouble elapsed = g_timer_elapsed(session->active_timer, NULL); - - if ((prefs_get_gone() != 0) && (elapsed > (prefs_get_gone() * 60.0))) { - if (session->state != CHAT_STATE_GONE) { - session->sent = FALSE; - } - session->state = CHAT_STATE_GONE; - - } else if (elapsed > INACTIVE_TIMOUT) { - if (session->state != CHAT_STATE_INACTIVE) { - session->sent = FALSE; - } - session->state = CHAT_STATE_INACTIVE; - - } else if (elapsed > PAUSED_TIMOUT) { - if (session->state == CHAT_STATE_COMPOSING) { - session->sent = FALSE; - session->state = CHAT_STATE_PAUSED; - } - } - } - - if (session->sent == FALSE) { - if (session->state == CHAT_STATE_GONE) { - message_send_gone(barejid); - session->sent = TRUE; - } else if (session->state == CHAT_STATE_INACTIVE) { - message_send_inactive(barejid); - session->sent = TRUE; - } else if (session->state == CHAT_STATE_PAUSED && prefs_get_boolean(PREF_OUTTYPE)) { - message_send_paused(barejid); - session->sent = TRUE; + Jid *jidp = jid_create(jid); + if (jidp) { + ChatSession *session = g_hash_table_lookup(sessions, jidp->barejid); + if (session) { + GString *log_msg = g_string_new("Removing chat session for "); + g_string_append(log_msg, jidp->barejid); + if (session->resource) { + g_string_append(log_msg, "/"); + g_string_append(log_msg, session->resource); } + log_debug(log_msg->str); + g_string_free(log_msg, TRUE); + g_hash_table_remove(sessions, jidp->barejid); } } } \ No newline at end of file diff --git a/src/chat_session.h b/src/chat_session.h index d1815f44..441f9096 100644 --- a/src/chat_session.h +++ b/src/chat_session.h @@ -40,12 +40,16 @@ void chat_sessions_init(void); void chat_sessions_clear(void); -gboolean chat_session_on_message_send(const char * const barejid); -void chat_session_on_window_open(const char * const barejid); +gboolean chat_session_exists(const char * const barejid); +char* chat_session_get_resource(const char * const barejid); +gboolean chat_session_send_states(const char * const barejid); + +void chat_session_on_message_send(const char * const barejid); void chat_session_on_window_close(const char * const barejid); -void chat_session_on_incoming_message(const char * const barejid, gboolean supported); +void chat_session_on_incoming_message(const char * const barejid, const char * const resource, gboolean send_states); void chat_session_on_cancel(const char * const jid); + void chat_session_on_activity(const char * const barejid); -void chat_session_on_inactivity(const char * const recipient); +void chat_session_on_inactivity(const char * const barejid); #endif diff --git a/src/command/command.c b/src/command/command.c index 5c1f858d..7fd1616e 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -1814,8 +1814,7 @@ cmd_execute_default(const char * inp) if (otr_is_secure(chatwin->barejid)) { char *encrypted = otr_encrypt_message(chatwin->barejid, inp); if (encrypted != NULL) { - gboolean send_state = chat_session_on_message_send(chatwin->barejid); - message_send_chat(chatwin->barejid, chatwin->resource, encrypted, send_state); + message_send_chat(chatwin->barejid, encrypted); otr_free_message(encrypted); if (prefs_get_boolean(PREF_CHLOG)) { const char *jid = jabber_get_fulljid(); @@ -1835,8 +1834,7 @@ cmd_execute_default(const char * inp) cons_show_error("Failed to send message."); } } else { - gboolean send_state = chat_session_on_message_send(chatwin->barejid); - message_send_chat(chatwin->barejid, chatwin->resource, inp, send_state); + message_send_chat(chatwin->barejid, inp); if (prefs_get_boolean(PREF_CHLOG)) { const char *jid = jabber_get_fulljid(); Jid *jidp = jid_create(jid); @@ -1847,8 +1845,7 @@ cmd_execute_default(const char * inp) ui_outgoing_chat_msg("me", chatwin->barejid, inp); } #else - gboolean send_state = chat_session_on_message_send(chatwin->barejid); - message_send_chat(chatwin->barejid, chatwin->resource, inp, send_state); + message_send_chat(chatwin->barejid, inp); if (prefs_get_boolean(PREF_CHLOG)) { const char *jid = jabber_get_fulljid(); Jid *jidp = jid_create(jid); diff --git a/src/command/commands.c b/src/command/commands.c index 5b5bd95e..049582c0 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -1203,24 +1203,23 @@ cmd_msg(gchar **args, struct cmd_help_t help) barejid = usr; } - // if msg to current recipient, and resource specified, set resource - char *resource = NULL; - ProfWin *current = wins_get_current(); - if (current->type == WIN_CHAT) { - ProfChatWin *chatwin = (ProfChatWin*)current; - assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); - if ((g_strcmp0(chatwin->barejid, barejid) == 0) && (chatwin->resource)) { - resource = chatwin->resource; - } - } + // TODO if msg to current recipient, and resource specified, set resource +// char *resource = NULL; +// ProfWin *current = wins_get_current(); +// if (current->type == WIN_CHAT) { +// ProfChatWin *chatwin = (ProfChatWin*)current; +// assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); +// if ((g_strcmp0(chatwin->barejid, barejid) == 0) && (chatwin->resource)) { +// resource = chatwin->resource; +// } +// } if (msg != NULL) { #ifdef HAVE_LIBOTR if (otr_is_secure(barejid)) { char *encrypted = otr_encrypt_message(barejid, msg); if (encrypted != NULL) { - gboolean send_state = chat_session_on_message_send(barejid); - message_send_chat(barejid, resource, encrypted, send_state); + message_send_chat(barejid, encrypted); otr_free_message(encrypted); ui_outgoing_chat_msg("me", barejid, msg); @@ -1249,13 +1248,11 @@ cmd_msg(gchar **args, struct cmd_help_t help) GString *otr_message = g_string_new(msg); g_string_append(otr_message, OTRL_MESSAGE_TAG_BASE); g_string_append(otr_message, OTRL_MESSAGE_TAG_V2); - gboolean send_state = chat_session_on_message_send(barejid); - message_send_chat(barejid, resource, otr_message->str, send_state); + message_send_chat(barejid, otr_message->str); g_string_free(otr_message, TRUE); } else { - gboolean send_state = chat_session_on_message_send(barejid); - message_send_chat(barejid, resource, msg, send_state); + message_send_chat(barejid, msg); } ui_outgoing_chat_msg("me", barejid, msg); @@ -1268,8 +1265,7 @@ cmd_msg(gchar **args, struct cmd_help_t help) } return TRUE; #else - gboolean send_state = chat_session_on_message_send(barejid); - message_send_chat(barejid, resource, msg, send_state); + message_send_chat(barejid, msg); ui_outgoing_chat_msg("me", barejid, msg); if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) && prefs_get_boolean(PREF_CHLOG)) { @@ -1282,7 +1278,6 @@ cmd_msg(gchar **args, struct cmd_help_t help) #endif } else { // msg == NULL - chat_session_on_window_open(barejid); ui_new_chat_win(barejid); #ifdef HAVE_LIBOTR if (otr_is_secure(barejid)) { @@ -3009,8 +3004,7 @@ cmd_tiny(gchar **args, struct cmd_help_t help) if (otr_is_secure(chatwin->barejid)) { char *encrypted = otr_encrypt_message(chatwin->barejid, tiny); if (encrypted != NULL) { - gboolean send_state = chat_session_on_message_send(chatwin->barejid); - message_send_chat(chatwin->barejid, chatwin->resource, encrypted, send_state); + message_send_chat(chatwin->barejid, encrypted); otr_free_message(encrypted); if (prefs_get_boolean(PREF_CHLOG)) { const char *jid = jabber_get_fulljid(); @@ -3030,8 +3024,7 @@ cmd_tiny(gchar **args, struct cmd_help_t help) cons_show_error("Failed to send message."); } } else { - gboolean send_state = chat_session_on_message_send(chatwin->barejid); - message_send_chat(chatwin->barejid, chatwin->resource, tiny, send_state); + message_send_chat(chatwin->barejid, tiny); if (prefs_get_boolean(PREF_CHLOG)) { const char *jid = jabber_get_fulljid(); Jid *jidp = jid_create(jid); @@ -3042,8 +3035,7 @@ cmd_tiny(gchar **args, struct cmd_help_t help) ui_outgoing_chat_msg("me", chatwin->barejid, tiny); } #else - gboolean send_state = chat_session_on_message_send(chatwin->barejid); - message_send_chat(chatwin->barejid, chatwin->resource, tiny, send_state); + message_send_chat(chatwin->barejid, tiny); if (prefs_get_boolean(PREF_CHLOG)) { const char *jid = jabber_get_fulljid(); Jid *jidp = jid_create(jid); @@ -3951,7 +3943,6 @@ cmd_otr(gchar **args, struct cmd_help_t help) barejid = contact; } - chat_session_on_window_open(barejid); ui_new_chat_win(barejid); if (ui_current_win_is_otr()) { @@ -3961,8 +3952,7 @@ cmd_otr(gchar **args, struct cmd_help_t help) ui_current_print_formatted_line('!', 0, "You have not generated or loaded a private key, use '/otr gen'"); } else if (!otr_is_secure(barejid)) { char *otr_query_message = otr_start_query(); - gboolean send_state = chat_session_on_message_send(barejid); - message_send_chat(barejid, NULL, otr_query_message, send_state); + message_send_chat(barejid, otr_query_message); } else { ui_gone_secure(barejid, otr_is_trusted(barejid)); } @@ -3980,8 +3970,7 @@ cmd_otr(gchar **args, struct cmd_help_t help) } else { ProfChatWin *chatwin = ui_get_current_chat(); char *otr_query_message = otr_start_query(); - gboolean send_state = chat_session_on_message_send(chatwin->barejid); - message_send_chat(chatwin->barejid, NULL, otr_query_message, send_state); + message_send_chat(chatwin->barejid, otr_query_message); } } } diff --git a/src/otr/otr.c b/src/otr/otr.c index 680c4c10..bd1c2ce3 100644 --- a/src/otr/otr.c +++ b/src/otr/otr.c @@ -110,8 +110,7 @@ static void cb_inject_message(void *opdata, const char *accountname, const char *protocol, const char *recipient, const char *message) { - gboolean send_state = chat_session_on_message_send(recipient); - message_send_chat(recipient, NULL, message, send_state); + message_send_chat(recipient, message); } static void diff --git a/src/server_events.c b/src/server_events.c index 9d7883d6..02522f98 100644 --- a/src/server_events.c +++ b/src/server_events.c @@ -318,8 +318,7 @@ handle_incoming_message(char *barejid, char *message) memmove(whitespace_base, whitespace_base+tag_length, tag_length); char *otr_query_message = otr_start_query(); cons_show("OTR Whitespace pattern detected. Attempting to start OTR session..."); - gboolean send_state = chat_session_on_message_send(barejid); - message_send_chat(barejid, NULL, otr_query_message, send_state); + message_send_chat(barejid, otr_query_message); } } } @@ -333,8 +332,7 @@ handle_incoming_message(char *barejid, char *message) if (policy == PROF_OTRPOLICY_ALWAYS && !was_decrypted && !whitespace_base) { char *otr_query_message = otr_start_query(); cons_show("Attempting to start OTR session..."); - gboolean send_state = chat_session_on_message_send(barejid); - message_send_chat(barejid, NULL, otr_query_message, send_state); + message_send_chat(barejid, otr_query_message); } ui_incoming_msg(barejid, newmessage, NULL); diff --git a/src/ui/core.c b/src/ui/core.c index 2e8ae9ff..d5e01d94 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -705,7 +705,9 @@ ui_close_connected_win(int index) otr_end_session(chatwin->barejid); } #endif - chat_session_on_window_close(chatwin->barejid); + if (chat_session_exists(chatwin->barejid)) { + chat_session_on_window_close(chatwin->barejid); + } } } } @@ -1162,7 +1164,9 @@ ui_prune_wins(void) if (window->type == WIN_CHAT) { if (conn_status == JABBER_CONNECTED) { ProfChatWin *chatwin = (ProfChatWin*)window; - chat_session_on_window_close(chatwin->barejid); + if (chat_session_exists(chatwin->barejid)) { + chat_session_on_window_close(chatwin->barejid); + } } } diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index 4165bd3f..19318745 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -151,17 +151,11 @@ inp_get_char(char *input, int *size, int *result) in_command = TRUE; } - if (prefs_get_boolean(PREF_STATES)) { - if (*result == ERR) { - prof_handle_idle(); - } - if (prefs_get_boolean(PREF_OUTTYPE) - && (*result != ERR) - && (*result != KEY_CODE_YES) - && !in_command - && _printable(ch)) { - prof_handle_activity(); - } + if (*result == ERR) { + prof_handle_idle(); + } + if ((*result != ERR) && (*result != KEY_CODE_YES) && !in_command && _printable(ch)) { + prof_handle_activity(); } // if it wasn't an arrow key etc diff --git a/src/xmpp/message.c b/src/xmpp/message.c index d87c5fb2..c3cbc14f 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -80,19 +80,23 @@ message_add_handlers(void) } void -message_send_chat(const char * const barejid, const char * const resource, const char * const msg, gboolean send_state) +message_send_chat(const char * const barejid, const char * const msg) { xmpp_stanza_t *message; xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); + chat_session_on_message_send(barejid); + char *resource = chat_session_get_resource(barejid); + gboolean send_state = chat_session_send_states(barejid); + GString *jid = g_string_new(barejid); if (resource) { g_string_append(jid, "/"); g_string_append(jid, resource); } - if (send_state) { + if (prefs_get_boolean(PREF_STATES) && send_state) { message = stanza_create_message(ctx, jid->str, STANZA_TYPE_CHAT, msg, STANZA_NAME_ACTIVE); } else { message = stanza_create_message(ctx, jid->str, STANZA_TYPE_CHAT, msg, NULL); @@ -149,23 +153,22 @@ message_send_invite(const char * const roomjid, const char * const contact, } void -message_send_composing(const char * const barejid) +message_send_composing(const char * const jid) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, barejid, - STANZA_NAME_COMPOSING); + xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_COMPOSING); xmpp_send(conn, stanza); xmpp_stanza_release(stanza); } void -message_send_paused(const char * const barejid) +message_send_paused(const char * const jid) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, barejid, + xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_PAUSED); xmpp_send(conn, stanza); @@ -173,11 +176,11 @@ message_send_paused(const char * const barejid) } void -message_send_inactive(const char * const barejid) +message_send_inactive(const char * const jid) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, barejid, + xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_INACTIVE); xmpp_send(conn, stanza); @@ -185,11 +188,11 @@ message_send_inactive(const char * const barejid) } void -message_send_gone(const char * const barejid) +message_send_gone(const char * const jid) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, barejid, + xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_GONE); xmpp_send(conn, stanza); @@ -469,7 +472,7 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, } // create or update chat session - chat_session_on_incoming_message(jid->barejid, recipient_supports); + chat_session_on_incoming_message(jid->barejid, jid->resourcepart, recipient_supports); // determine if the notifications happened whilst offline GTimeVal tv_stamp; diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 1766fe26..4f1d412d 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -199,15 +199,14 @@ stanza_create_bookmarks_pubsub_add(xmpp_ctx_t *ctx, const char * const jid, #endif xmpp_stanza_t * -stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const recipient, - const char * const state) +stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const fulljid, const char * const state) { xmpp_stanza_t *msg, *chat_state; msg = xmpp_stanza_new(ctx); xmpp_stanza_set_name(msg, STANZA_NAME_MESSAGE); xmpp_stanza_set_type(msg, STANZA_TYPE_CHAT); - xmpp_stanza_set_attribute(msg, STANZA_ATTR_TO, recipient); + xmpp_stanza_set_attribute(msg, STANZA_ATTR_TO, fulljid); char *id = create_unique_id(NULL); xmpp_stanza_set_id(msg, id); free(id); diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index e60e9fe1..84282401 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -179,7 +179,7 @@ typedef enum { xmpp_stanza_t* stanza_create_bookmarks_storage_request(xmpp_ctx_t *ctx); xmpp_stanza_t* stanza_create_chat_state(xmpp_ctx_t *ctx, - const char * const recipient, const char * const state); + const char * const fulljid, const char * const state); xmpp_stanza_t* stanza_create_message(xmpp_ctx_t *ctx, const char * const recipient, const char * const type, diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 2499d008..161eebdf 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -145,16 +145,15 @@ char* jabber_get_account_name(void); GList * jabber_get_available_resources(void); // message functions -void message_send_chat(const char * const barejid, const char * const resource, const char * const msg, - gboolean send_state); +void message_send_chat(const char * const barejid, const char * const msg); void message_send_private(const char * const fulljid, const char * const msg); void message_send_groupchat(const char * const roomjid, const char * const msg); void message_send_groupchat_subject(const char * const roomjid, const char * const subject); -void message_send_inactive(const char * const barejid); -void message_send_composing(const char * const barejid); -void message_send_paused(const char * const barejid); -void message_send_gone(const char * const barejid); +void message_send_inactive(const char * const jid); +void message_send_composing(const char * const jid); +void message_send_paused(const char * const jid); +void message_send_gone(const char * const jid); void message_send_invite(const char * const room, const char * const contact, const char * const reason); diff --git a/tests/helpers.c b/tests/helpers.c index a6a473e4..bc0b8009 100644 --- a/tests/helpers.c +++ b/tests/helpers.c @@ -10,6 +10,7 @@ #include "common.h" #include "helpers.h" #include "config/preferences.h" +#include "chat_session.h" void create_config_dir(void **state) { @@ -72,6 +73,16 @@ void close_preferences(void **state) rmdir("./tests/files"); } +void init_chat_sessions(void **state) +{ + chat_sessions_init(); +} + +void close_chat_sessions(void **state) +{ + chat_sessions_clear(); +} + static GCompareFunc cmp_func; void diff --git a/tests/helpers.h b/tests/helpers.h index 17d8329c..2d7af6e7 100644 --- a/tests/helpers.h +++ b/tests/helpers.h @@ -3,5 +3,8 @@ void load_preferences(void **state); void close_preferences(void **state); +void init_chat_sessions(void **state); +void close_chat_sessions(void **state); + void glist_set_cmp(GCompareFunc func); int glist_contents_equal(const void *actual, const void *expected); \ No newline at end of file diff --git a/tests/test_chat_session.c b/tests/test_chat_session.c new file mode 100644 index 00000000..a93c64b6 --- /dev/null +++ b/tests/test_chat_session.c @@ -0,0 +1,125 @@ +#include <stdarg.h> +#include <string.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> +#include <stdlib.h> + +#include "chat_session.h" + +void returns_false_when_chat_session_does_not_exist(void **state) +{ + gboolean result = chat_session_exists("somejid@server.org"); + assert_false(result); +} + +void creates_chat_session_on_message_send(void **state) +{ + char *barejid = "myjid@server.org"; + + chat_session_on_message_send(barejid); + gboolean exists = chat_session_exists(barejid); + + assert_true(exists); +} + +void creates_chat_session_on_activity(void **state) +{ + char *barejid = "myjid@server.org"; + + chat_session_on_activity(barejid); + gboolean exists = chat_session_exists(barejid); + + assert_true(exists); +} + +void returns_null_resource_for_new_session(void **state) +{ + char *barejid = "myjid@server.org"; + + chat_session_on_message_send(barejid); + char *resource = chat_session_get_resource(barejid); + + assert_null(resource); +} + +void returns_true_send_states_for_new_session(void **state) +{ + char *barejid = "myjid@server.org"; + + chat_session_on_message_send(barejid); + gboolean send_states = chat_session_send_states(barejid); + + assert_true(send_states); +} + +void sets_resource_on_incoming_message(void **state) +{ + char *barejid = "myjid@server.org"; + char *expected_resource = "laptop"; + + chat_session_on_message_send(barejid); + chat_session_on_incoming_message(barejid, expected_resource, FALSE); + char *actual_resource = chat_session_get_resource(barejid); + + assert_string_equal(expected_resource, actual_resource); +} + +void sets_send_states_on_incoming_message(void **state) +{ + char *barejid = "myjid@server.org"; + + chat_session_on_message_send(barejid); + chat_session_on_incoming_message(barejid, "resource", TRUE); + gboolean send_states = chat_session_send_states(barejid); + + assert_true(send_states); +} + +void replaces_chat_session_when_new_resource(void **state) +{ + char *barejid = "myjid@server.org"; + char *first_resource = "laptop"; + char *second_resource = "mobile"; + + chat_session_on_message_send(barejid); + chat_session_on_incoming_message(barejid, first_resource, TRUE); + chat_session_on_incoming_message(barejid, second_resource, TRUE); + char *actual_resource = chat_session_get_resource(barejid); + + assert_string_equal(second_resource, actual_resource); +} + +void removes_chat_session_on_window_close(void **state) +{ + char *barejid = "myjid@server.org"; + + chat_session_on_message_send(barejid); + chat_session_on_window_close(barejid); + gboolean exists = chat_session_exists(barejid); + + assert_false(exists); +} + +void removes_chat_session_on_cancel_for_barejid(void **state) +{ + char *barejid = "myjid@server.org"; + + chat_session_on_message_send(barejid); + chat_session_on_cancel(barejid); + gboolean exists = chat_session_exists(barejid); + + assert_false(exists); +} + +void removes_chat_session_on_cancel_for_fulljid(void **state) +{ + char *barejid = "myjid@server.org"; + char *fulljid = "myjid@server.org/desktop"; + + chat_session_on_message_send(barejid); + chat_session_on_cancel(fulljid); + gboolean exists = chat_session_exists(barejid); + + assert_false(exists); +} \ No newline at end of file diff --git a/tests/test_chat_session.h b/tests/test_chat_session.h new file mode 100644 index 00000000..8916f6b4 --- /dev/null +++ b/tests/test_chat_session.h @@ -0,0 +1,11 @@ +void returns_false_when_chat_session_does_not_exist(void **state); +void creates_chat_session_on_message_send(void **state); +void creates_chat_session_on_activity(void **state); +void returns_null_resource_for_new_session(void **state); +void returns_true_send_states_for_new_session(void **state); +void sets_resource_on_incoming_message(void **state); +void sets_send_states_on_incoming_message(void **state); +void replaces_chat_session_when_new_resource(void **state); +void removes_chat_session_on_window_close(void **state); +void removes_chat_session_on_cancel_for_barejid(void **state); +void removes_chat_session_on_cancel_for_fulljid(void **state); \ No newline at end of file diff --git a/tests/test_cmd_otr.c b/tests/test_cmd_otr.c index 3cd9dd59..7d0adc1a 100644 --- a/tests/test_cmd_otr.c +++ b/tests/test_cmd_otr.c @@ -552,9 +552,7 @@ cmd_otr_start_sends_otr_query_message_to_current_recipeint(void **state) will_return(otr_start_query, query_message); expect_string(message_send_chat, barejid, chatwin->barejid); - expect_value(message_send_chat, resource, NULL); expect_string(message_send_chat, msg, query_message); - expect_any(message_send_chat, send_state); gboolean result = cmd_otr(args, *help); assert_true(result); diff --git a/tests/test_server_events.c b/tests/test_server_events.c index 435493a2..0b5cfd09 100644 --- a/tests/test_server_events.c +++ b/tests/test_server_events.c @@ -130,19 +130,20 @@ void handle_message_error_when_recipient_cancel_disables_chat_session(void **sta { char *err_msg = "Some error."; char *from = "bob@server.com"; + char *resource = "resource"; char *type = "cancel"; prefs_set_boolean(PREF_STATES, TRUE); chat_sessions_init(); - chat_session_on_incoming_message(from, TRUE); + chat_session_on_incoming_message(from, resource, TRUE); expect_any(ui_handle_recipient_not_found, recipient); expect_any(ui_handle_recipient_not_found, err_msg); handle_message_error(from, type, err_msg); - gboolean chat_session_supported = chat_session_on_message_send(from); + gboolean session_exists = chat_session_exists(from); - assert_false(chat_session_supported); + assert_false(session_exists); chat_sessions_clear(); } diff --git a/tests/testsuite.c b/tests/testsuite.c index fb439331..db05639d 100644 --- a/tests/testsuite.c +++ b/tests/testsuite.c @@ -8,9 +8,11 @@ #include <sys/stat.h> #include "config.h" +#include "chat_session.h" #include "helpers.h" #include "test_autocomplete.h" +#include "test_chat_session.h" #include "test_common.h" #include "test_contact.h" #include "test_cmd_connect.h" @@ -204,6 +206,40 @@ int main(int argc, char* argv[]) { unit_test(find_five_times_finds_fifth), unit_test(find_twice_returns_first_when_two_match_and_reset), + unit_test_setup_teardown(returns_false_when_chat_session_does_not_exist, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(creates_chat_session_on_message_send, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(creates_chat_session_on_activity, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(returns_null_resource_for_new_session, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(returns_true_send_states_for_new_session, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(sets_resource_on_incoming_message, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(sets_send_states_on_incoming_message, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(replaces_chat_session_when_new_resource, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(removes_chat_session_on_window_close, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(removes_chat_session_on_cancel_for_barejid, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(removes_chat_session_on_cancel_for_fulljid, + init_chat_sessions, + close_chat_sessions), + unit_test_setup_teardown(cmd_connect_shows_message_when_disconnecting, load_preferences, close_preferences), diff --git a/tests/xmpp/stub_xmpp.c b/tests/xmpp/stub_xmpp.c index 580a6c61..a6058058 100644 --- a/tests/xmpp/stub_xmpp.c +++ b/tests/xmpp/stub_xmpp.c @@ -58,13 +58,10 @@ GList * jabber_get_available_resources(void) } // message functions -void message_send_chat(const char * const barejid, const char * const resource, const char * const msg, - gboolean send_state) +void message_send_chat(const char * const barejid, const char * const msg) { check_expected(barejid); - check_expected(resource); check_expected(msg); - check_expected(send_state); } void message_send_private(const char * const fulljid, const char * const msg) {} @@ -218,4 +215,4 @@ void roster_send_add_new(const char * const barejid, const char * const name) void roster_send_remove(const char * const barejid) { check_expected(barejid); -} \ No newline at end of file +} |