Index: tests/Makefile
===================================================================
--- tests/Makefile	(revision 7bee5af91e56f1e58232b895fd40c367aec67e8a)
+++ tests/Makefile	(revision ed5df815732d311b228993627f5d8b8c8e3eb4e0)
@@ -11,5 +11,5 @@
 main_objs = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o storage_text.o user.o 
 
-test_objs = check.o check_util.o check_nick.o check_md5.o check_irc.o check_help.o
+test_objs = check.o check_util.o check_nick.o check_md5.o check_irc.o check_help.o check_user.o
 
 check: $(test_objs) $(addprefix ../, $(main_objs)) ../protocols/protocols.o ../lib/lib.o
Index: tests/check.c
===================================================================
--- tests/check.c	(revision 7bee5af91e56f1e58232b895fd40c367aec67e8a)
+++ tests/check.c	(revision ed5df815732d311b228993627f5d8b8c8e3eb4e0)
@@ -19,4 +19,14 @@
 	*ch2 = g_io_channel_unix_new(sock[1]);
 	return TRUE;
+}
+
+irc_t *torture_irc(void)
+{
+	irc_t *irc;
+	GIOChannel *ch1, *ch2;
+	if (!g_io_channel_pair(&ch1, &ch2))
+		return NULL;
+	irc = irc_new(g_io_channel_unix_get_fd(ch1));
+	return irc;
 }
 
@@ -43,4 +53,7 @@
 /* From check_help.c */
 Suite *help_suite(void);
+
+/* From check_user.c */
+Suite *user_suite(void);
 
 int main (int argc, char **argv)
@@ -85,4 +98,5 @@
 	srunner_add_suite(sr, irc_suite());
 	srunner_add_suite(sr, help_suite());
+	srunner_add_suite(sr, user_suite());
 	if (no_fork)
 		srunner_set_fork_status(sr, CK_NOFORK);
Index: tests/check_user.c
===================================================================
--- tests/check_user.c	(revision ed5df815732d311b228993627f5d8b8c8e3eb4e0)
+++ tests/check_user.c	(revision ed5df815732d311b228993627f5d8b8c8e3eb4e0)
@@ -0,0 +1,75 @@
+#include <stdlib.h>
+#include <glib.h>
+#include <gmodule.h>
+#include <check.h>
+#include <string.h>
+#include "bitlbee.h"
+#include "user.h"
+#include "testsuite.h"
+
+START_TEST(test_user_add)
+	irc_t *irc = torture_irc();
+	user_t *user;
+	user = user_add(irc, "foo");
+	fail_if(user == NULL);
+	fail_if(strcmp(user->nick, "foo") != 0);
+	fail_unless(user_find(irc, "foo") == user);
+END_TEST
+
+START_TEST(test_user_add_exists)
+	irc_t *irc = torture_irc();
+	user_t *user;
+	user = user_add(irc, "foo");
+	fail_if(user == NULL);
+	user = user_add(irc, "foo");
+	fail_unless(user == NULL);
+END_TEST
+
+START_TEST(test_user_add_invalid)
+	irc_t *irc = torture_irc();
+	user_t *user;
+	user = user_add(irc, ":foo");
+	fail_unless(user == NULL);
+END_TEST
+
+START_TEST(test_user_del_invalid)
+	irc_t *irc = torture_irc();
+	fail_unless(user_del(irc, ":foo") == 0);
+END_TEST
+
+START_TEST(test_user_del)
+	irc_t *irc = torture_irc();
+	user_t *user;
+	user = user_add(irc, "foo");
+	fail_unless(user_del(irc, "foo") == 1);
+	fail_unless(user_find(irc, "foo") == NULL);
+END_TEST
+
+START_TEST(test_user_del_nonexistant)
+	irc_t *irc = torture_irc();
+	fail_unless(user_del(irc, "foo") == 0);
+END_TEST
+
+START_TEST(test_user_rename)
+	irc_t *irc = torture_irc();
+	user_t *user;
+	user = user_add(irc, "foo");
+	user_rename(irc, "foo", "bar");
+	fail_unless(user_find(irc, "foo") == NULL);
+	fail_if(user_find(irc, "bar") == NULL);
+END_TEST
+
+Suite *user_suite (void)
+{
+	Suite *s = suite_create("User");
+	TCase *tc_core = tcase_create("Core");
+	suite_add_tcase (s, tc_core);
+	tcase_add_test (tc_core, test_user_add);
+	tcase_add_test (tc_core, test_user_add_invalid);
+	tcase_add_test (tc_core, test_user_add_exists);
+	tcase_add_test (tc_core, test_user_del_invalid);
+	tcase_add_test (tc_core, test_user_del_nonexistant);
+	tcase_add_test (tc_core, test_user_del);
+	tcase_add_test (tc_core, test_user_rename);
+	return s;
+}
Index: tests/testsuite.h
===================================================================
--- tests/testsuite.h	(revision 7bee5af91e56f1e58232b895fd40c367aec67e8a)
+++ tests/testsuite.h	(revision ed5df815732d311b228993627f5d8b8c8e3eb4e0)
@@ -2,4 +2,5 @@
 #define __BITLBEE_CHECK_H__ 
 
+irc_t *torture_irc(void);
 gboolean g_io_channel_pair(GIOChannel **ch1, GIOChannel **ch2);
 
Index: user.h
===================================================================
--- user.h	(revision 7bee5af91e56f1e58232b895fd40c367aec67e8a)
+++ user.h	(revision ed5df815732d311b228993627f5d8b8c8e3eb4e0)
@@ -23,4 +23,6 @@
   Suite 330, Boston, MA  02111-1307  USA
 */
+#ifndef __USER_H__
+#define __USER_H__
 
 typedef struct __USER
@@ -56,2 +58,4 @@
 G_MODULE_EXPORT user_t *user_findhandle( struct gaim_connection *gc, char *handle );
 void user_rename( irc_t *irc, char *oldnick, char *newnick );
+
+#endif /* __USER_H__ */
