/*
 *   Copyright (c) 2004-2006 NFG Net Facilities Group BV support@nfg.nl
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation; either
 *   version 2 of the License, or (at your option) any later
 *   version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 *   
 *
 *
 *  
 *
 *   Basic unit-test framework for dbmail (www.dbmail.org)
 *
 *   See http://check.sf.net for details and docs.
 *
 *
 *   Run 'make check' to see some action.
 *
 */ 

#include <check.h>
#include "check_dbmail.h"

extern char *configFile;
extern db_param_t _db_params;

extern char *multipart_message;
extern char *multipart_message_part;
extern char *raw_lmtp_data;

/*
 *
 * the test fixtures
 *
 */

	
void setup(void)
{
	configure_debug(5,0);
	config_read(configFile);
	GetDBParams(&_db_params);
	db_connect();
	auth_connect();
}

void teardown(void)
{
	db_disconnect();
	auth_disconnect();
	config_free();
}

//struct DbmailMessage * dbmail_message_new(void);
START_TEST(test_dbmail_message_new)
{
	struct DbmailMessage *m = dbmail_message_new();
	fail_unless(m->id==0,"dbmail_message_new failed");
	dbmail_message_free(m);
}
END_TEST
//void dbmail_message_set_class(struct DbmailMessage *self, int klass);
START_TEST(test_dbmail_message_set_class)
{
	int result;
	struct DbmailMessage *m = dbmail_message_new();
	result = dbmail_message_set_class(m,DBMAIL_MESSAGE);
	fail_unless(result==0,"dbmail_message_set_class failed");
	result = dbmail_message_set_class(m,DBMAIL_MESSAGE_PART);
	fail_unless(result==0,"dbmail_message_set_class failed");
	result = dbmail_message_set_class(m,10);
	fail_unless(result!=0,"dbmail_message_set_class failed");
	
	dbmail_message_free(m);
}
END_TEST
//int dbmail_message_get_class(struct DbmailMessage *self);
START_TEST(test_dbmail_message_get_class)
{
	int klass;
	struct DbmailMessage *m = dbmail_message_new();
	
	/* default */
	klass = dbmail_message_get_class(m);
	fail_unless(klass==DBMAIL_MESSAGE,"dbmail_message_get_class failed");
	
	/* set explicitely */
	dbmail_message_set_class(m,DBMAIL_MESSAGE_PART);
	klass = dbmail_message_get_class(m);
	fail_unless(klass==DBMAIL_MESSAGE_PART,"dbmail_message_get_class failed");
	
	dbmail_message_set_class(m,DBMAIL_MESSAGE);
	klass = dbmail_message_get_class(m);
	fail_unless(klass==DBMAIL_MESSAGE,"dbmail_message_get_class failed");

	dbmail_message_free(m);
}
END_TEST

//struct DbmailMessage * dbmail_message_retrieve(struct DbmailMessage *self, u64_t physid, int filter);
START_TEST(test_dbmail_message_retrieve)
{
	struct DbmailMessage *m, *n;
	GString *s;
	u64_t physid;

	s = g_string_new(multipart_message);
	m = dbmail_message_new();
	m = dbmail_message_init_with_string(m, s);
	fail_unless(m != NULL, "dbmail_message_init_with_string failed");

	dbmail_message_set_header(m, 
			"References", 
			"<20050326155326.1afb0377@ibook.linuks.mine.nu> <20050326181954.GB17389@khazad-dum.debian.net> <20050326193756.77747928@ibook.linuks.mine.nu> ");
	dbmail_message_store(m);

	physid = dbmail_message_get_physid(m);
	fail_unless(physid > 0, "dbmail_message_get_physid failed");
	
	n = dbmail_message_new();
	n = dbmail_message_retrieve(n,physid,DBMAIL_MESSAGE_FILTER_HEAD);	
	fail_unless(n != NULL, "dbmail_message_retrieve failed");
	fail_unless(n->content != NULL, "dbmail_message_retrieve failed");

	dbmail_message_free(m);
	dbmail_message_free(n);
	g_string_free(s,TRUE);

}
END_TEST
//struct DbmailMessage * dbmail_message_init_with_string(struct DbmailMessage *self, const GString *content);
START_TEST(test_dbmail_message_init_with_string)
{
	struct DbmailMessage *m;
	GTuples *t;
	GString *s;
	
	s = g_string_new(multipart_message);
	m = dbmail_message_new();
	m = dbmail_message_init_with_string(m,s);
	g_string_free(s,TRUE);
	
	t = g_relation_select(m->headers, "Received", 0);
	fail_unless(t->len==2,"Too few or too many headers in tuple");
	g_tuples_destroy(t);
	dbmail_message_free(m);
	
	s = g_string_new(simple_message_part);
	m = dbmail_message_new();
	m = dbmail_message_init_with_string(m, s);
	g_string_free(s,TRUE);
	
	fail_unless(dbmail_message_get_class(m)==DBMAIL_MESSAGE_PART, "init_with string failed");
	
	dbmail_message_free(m);
}
END_TEST

START_TEST(test_dbmail_message_get_internal_date)
{
	struct DbmailMessage *m;
	GString *s;

	s = g_string_new(rfc822);

	m = dbmail_message_new();
	m = dbmail_message_init_with_string(m, s);
	// From_ contains: Wed Sep 14 16:47:48 2005
	const char *expect = "2005-09-14 16:47:48";
	const char *expect03 = "2003-09-14 16:47:48";
	const char *expect75 = "1975-09-14 16:47:48";
	char *result;

	/* baseline */
	result = dbmail_message_get_internal_date(m, 0);
	fail_unless(MATCH(expect,result),"dbmail_message_get_internal_date failed exp [%s] got [%s]", expect, result);
	g_free(result);

	/* should be the same */
	result = dbmail_message_get_internal_date(m, 2007);
	fail_unless(MATCH(expect,result),"dbmail_message_get_internal_date failed exp [%s] got [%s]", expect, result);
	g_free(result);

	/* capped to 2004, which should also be the same  */
	result = dbmail_message_get_internal_date(m, 2004);
	fail_unless(MATCH(expect,result),"dbmail_message_get_internal_date failed exp [%s] got [%s]", expect, result);
	g_free(result);

	/* capped to 2003, should be different */
	result = dbmail_message_get_internal_date(m, 2003);
	fail_unless(MATCH(expect03,result),"dbmail_message_get_internal_date failed exp [%s] got [%s]", expect03, result);
	g_free(result);

	/* capped to 1975, should be way different */
	result = dbmail_message_get_internal_date(m, 1975);
	fail_unless(MATCH(expect75,result),"dbmail_message_get_internal_date failed exp [%s] got [%s]", expect75, result);
	g_free(result);

	g_string_free(s,TRUE);
	dbmail_message_free(m);
	
}
END_TEST

START_TEST(test_dbmail_message_to_string)
{
        char *result;
	GString *s;
	struct DbmailMessage *m;
        
	s = g_string_new(multipart_message);
	
	m = dbmail_message_new();
	m = dbmail_message_init_with_string(m, s);
	
        result = dbmail_message_to_string(m);
	fail_unless(strlen(result)==s->len, "dbmail_message_to_string failed");
	
        g_string_free(s,TRUE);
	g_free(result);
	dbmail_message_free(m);

	//
	s = g_string_new(simple_with_from);
	m = dbmail_message_new();
	m = dbmail_message_init_with_string(m,s);
	result = dbmail_message_to_string(m);
	fail_unless(MATCH(s->str,result), "[%s] =! [%s]\n", s->str, result);
	g_string_free(s,TRUE);
	g_free(result);
	dbmail_message_free(m);

}
END_TEST
    
//struct DbmailMessage * dbmail_message_init_with_stream(struct DbmailMessage *self, GMimeStream *stream, int type);
/*
START_TEST(test_dbmail_message_init_with_stream)
{
}
END_TEST
*/
//gchar * dbmail_message_hdrs_to_string(struct DbmailMessage *self);

START_TEST(test_dbmail_message_hdrs_to_string)
{
	char *result;
	GString *s;
	struct DbmailMessage *m;
	
	s = g_string_new(multipart_message);
	m = dbmail_message_new();
        m = dbmail_message_init_with_string(m, s);

	result = dbmail_message_hdrs_to_string(m);
	fail_unless(strlen(result)==634, "dbmail_message_hdrs_to_string failed [%d] != [634]\n[%s]\n", strlen(result), result);
	
	g_string_free(s,TRUE);
        dbmail_message_free(m);
	g_free(result);
}
END_TEST

//gchar * dbmail_message_body_to_string(struct DbmailMessage *self);

START_TEST(test_dbmail_message_body_to_string)
{
	char *result;
	GString *s;
	struct DbmailMessage *m;
	
	s = g_string_new(multipart_message);
	m = dbmail_message_new();
        m = dbmail_message_init_with_string(m,s);
	result = dbmail_message_body_to_string(m);
	fail_unless(strlen(result)==1045, "dbmail_message_body_to_string failed [%d] != [1045]\n[%s]\n", strlen(result),result);
	
        dbmail_message_free(m);
	g_string_free(s,TRUE);
	g_free(result);

	s = g_string_new(outlook_multipart);
	m = dbmail_message_new();
        m = dbmail_message_init_with_string(m,s);
	result = dbmail_message_body_to_string(m);
//	printf("{%d} [%s]\n", strlen(result), result);
	fail_unless(strlen(result)==329, "dbmail_message_body_to_string failed [%s]", result);
	
        dbmail_message_free(m);
	g_string_free(s,TRUE);
	g_free(result);

	
}
END_TEST

//size_t dbmail_message_get_rfcsize(struct DbmailMessage *self);

START_TEST(test_dbmail_message_get_rfcsize)
{
	unsigned result;
	GString *s;
	struct DbmailMessage *m;
	
	s = g_string_new(multipart_message);
	m = dbmail_message_new();
        m = dbmail_message_init_with_string(m,s);
	result = dbmail_message_get_rfcsize(m);
	
	fail_unless(result==1724, "dbmail_message_get_rfcsize failed [%d]", result);
	
	g_string_free(s,TRUE);
        dbmail_message_free(m);
}
END_TEST

//void dbmail_message_free(struct DbmailMessage *self);
START_TEST(test_dbmail_message_free)
{
	struct DbmailMessage *m = dbmail_message_new();
	dbmail_message_free(m);
}
END_TEST

START_TEST(test_dbmail_message_new_from_stream)
{
	FILE *fd;
	struct DbmailMessage *m;
	u64_t whole_message_size = 0;
	fd = tmpfile();
	fprintf(fd, "%s", multipart_message);
	fseek(fd,0,0);
	m = dbmail_message_new_from_stream(fd, DBMAIL_STREAM_PIPE);
	whole_message_size = dbmail_message_get_size(m, FALSE);
	fail_unless(whole_message_size == strlen(multipart_message), 
			"read_whole_message_stream returned wrong message_size");
	dbmail_message_free(m);
	
	fseek(fd,0,0);
	fprintf(fd, "%s", raw_lmtp_data);
	
	
	m = dbmail_message_new_from_stream(fd, DBMAIL_STREAM_LMTP);
	whole_message_size = dbmail_message_get_size(m, FALSE);
	// note: we're comparing with multipart_message not raw_lmtp_data because
	// multipart_message == raw_lmtp_data - crlf - end-dot
	fail_unless(whole_message_size == strlen(multipart_message), 
			"read_whole_message_network returned wrong message_size");
	dbmail_message_free(m);
}
END_TEST

START_TEST(test_dbmail_message_set_header)
{
	struct DbmailMessage *m;
	GString *s;
	s =  g_string_new(multipart_message);
	m = dbmail_message_new();
	m = dbmail_message_init_with_string(m,s);
	dbmail_message_set_header(m, "X-Foobar","Foo Bar");
	fail_unless(dbmail_message_get_header(m, "X-Foobar")!=NULL, "set_header failed");
	dbmail_message_free(m);
	g_string_free(s,TRUE);
}
END_TEST

START_TEST(test_dbmail_message_get_header)
{
	char *t;
	struct DbmailMessage *h = dbmail_message_new();
	struct DbmailMessage *m = dbmail_message_new();
	GString *s, *j;
	
	s = g_string_new(multipart_message);
	m = dbmail_message_init_with_string(m, s);
	t = dbmail_message_hdrs_to_string(m);
	j = g_string_new(t);
	h = dbmail_message_init_with_string(h, j);
	g_free(t);
	
	fail_unless(dbmail_message_get_header(m, "X-Foobar")==NULL, "get_header failed on full message");
	fail_unless(strcmp(dbmail_message_get_header(m,"Subject"),"multipart/mixed")==0,"get_header failed on full message");

	fail_unless(dbmail_message_get_header(h, "X-Foobar")==NULL, "get_header failed on headers-only message");
	fail_unless(strcmp(dbmail_message_get_header(h,"Subject"),"multipart/mixed")==0,"get_header failed on headers-only message");
	
	dbmail_message_free(m);
	dbmail_message_free(h);
	g_string_free(s,TRUE);
	g_string_free(j,TRUE);

}
END_TEST

START_TEST(test_dbmail_message_encoded)
{
	struct DbmailMessage *m = dbmail_message_new();
	GString *s = g_string_new(encoded_message_koi);
	const char *exp = ":: [ Arrty ] :: [ Roy (L) Stèphanie ]  <over.there@hotmail.com>";
	u64_t id = 0;

	m = dbmail_message_init_with_string(m, s);

	fail_unless(strcmp(dbmail_message_get_header(m,"From"),"=?koi8-r?Q?=E1=CE=D4=CF=CE=20=EE=C5=C8=CF=D2=CF=DB=C9=C8=20?=<bad@foo.ru>")==0, 
			"dbmail_message_get_header failed for koi-8 encoded header");
	dbmail_message_free(m);


	m = dbmail_message_new();
	g_string_printf(s, "%s", utf7_header);
	m = dbmail_message_init_with_string(m, s);
	g_string_free(s, TRUE);

	dbmail_message_store(m);
	id = dbmail_message_get_physid(m);
	dbmail_message_free(m);

	m = dbmail_message_new();
	m = dbmail_message_retrieve(m, id, DBMAIL_MESSAGE_FILTER_FULL);
	dbmail_message_free(m);


}
END_TEST
START_TEST(test_dbmail_message_8bit)
{
	struct DbmailMessage *m = dbmail_message_new();
	GString *s = g_string_new(raw_message_koi);

	m = dbmail_message_init_with_string(m, s);
	g_string_free(s,TRUE);

	dbmail_message_store(m);
	dbmail_message_free(m);

	/* */
	m = dbmail_message_new();
	s = g_string_new(encoded_message_utf8);
	m = dbmail_message_init_with_string(m, s);
	g_string_free(s, TRUE);

	dbmail_message_store(m);
	dbmail_message_free(m);
}
END_TEST

START_TEST(test_dbmail_message_cache_headers)
{
	struct DbmailMessage *m = dbmail_message_new();
	char *s = g_new0(char,20);
	GString *j =  g_string_new(multipart_message);
	m = dbmail_message_init_with_string(m,j);
	dbmail_message_set_header(m, 
			"References", 
			"<20050326155326.1afb0377@ibook.linuks.mine.nu> <20050326181954.GB17389@khazad-dum.debian.net> <20050326193756.77747928@ibook.linuks.mine.nu> ");
	dbmail_message_store(m);
	dbmail_message_free(m);
	g_string_free(j,TRUE);

	sprintf(s,"%.*s",10,"abcdefghijklmnopqrstuvwxyz");
	fail_unless(MATCH(s,"abcdefghij"),"string truncate failed");
	g_free(s);
}
END_TEST

START_TEST(test_dbmail_message_get_header_addresses)
{
	GList * result;
	GString *s;
	struct DbmailMessage *m;

	s = g_string_new(multipart_message);
	m = dbmail_message_new();
	m = dbmail_message_init_with_string(m,s);
	
	result = dbmail_message_get_header_addresses(m, "Cc");
	result = g_list_first(result);

	fail_unless(result != NULL, "dbmail_message_get_header_addresses failed");
	fail_unless(g_list_length(result)==2,"dbmail_message_get_header_addresses failed");
	fail_unless(strcmp((char *)result->data,"vol@inter7.com")==0, "dbmail_message_get_header_addresses failed");

	g_list_destroy(result);
	dbmail_message_free(m);
	g_string_free(s,TRUE);
}
END_TEST

START_TEST(test_dbmail_message_get_header_repeated)
{
	GTuples *headers;
	GString *s;
	struct DbmailMessage *m;

	s = g_string_new(multipart_message);
	m = dbmail_message_new();
	m = dbmail_message_init_with_string(m,s);
	
	headers = dbmail_message_get_header_repeated(m, "Received");

	fail_unless(headers != NULL, "dbmail_message_get_header_repeated failed");
	fail_unless(headers->len==2, "dbmail_message_get_header_repeated failed");
	
	g_tuples_destroy(headers);

	headers = dbmail_message_get_header_repeated(m, "received");

	fail_unless(headers != NULL, "dbmail_message_get_header_repeated failed");
	fail_unless(headers->len==2, "dbmail_message_get_header_repeated failed");
	
	g_tuples_destroy(headers);

	dbmail_message_free(m);
	g_string_free(s,TRUE);
}
END_TEST


START_TEST(test_dbmail_message_construct)
{
	const gchar *sender = "foo@bar.org";
	const gchar *subject = "Some test";
	const gchar *recipient = "<bar@foo.org> Bar";
	gchar *body = g_strdup("\ntesting\n\nááááä\n\n");
	gchar *expect = g_strdup("From: foo@bar.org\n"
	"Subject: Some test\n"
	"To: bar@foo.org\n"
	"MIME-Version: 1.0\n"
	"Content-Type: text/plain; charset=utf-8\n"
	"Content-Transfer-Encoding: base64\n"
	"\n"
	"CnRlc3RpbmcKCuHh4eHk");
	gchar *result;

	struct DbmailMessage *message = dbmail_message_new();
	message = dbmail_message_construct(message,recipient,sender,subject,body);
	result = dbmail_message_to_string(message);
	fail_unless(MATCH(expect,result),"dbmail_message_construct failed\n%s\n%s", expect, result);
	dbmail_message_free(message);
	g_free(body);
	g_free(result);
	g_free(expect);

	body = g_strdup("Mit freundlichen Gr=C3=BC=C3=9Fen");
	message = dbmail_message_new();
	message = dbmail_message_construct(message,recipient,sender,subject,body);
	//printf ("%s\n", dbmail_message_to_string(message));
	dbmail_message_free(message);
	g_free(body);
}
END_TEST

START_TEST(test_encoding)
{
	char *raw, *enc, *dec;

	raw = g_strdup( "Kristoffer Br�nemyr");
	enc = g_mime_utils_header_encode_phrase((unsigned char *)raw);
	dec = g_mime_utils_header_decode_phrase((unsigned char *)enc);
	fail_unless(MATCH(raw,dec),"decode/encode failed");
	g_free(raw);
	g_free(dec);
	g_free(enc);
}
END_TEST

Suite *dbmail_message_suite(void)
{
	Suite *s = suite_create("Dbmail Message");
	TCase *tc_message = tcase_create("Message");
	
	suite_add_tcase(s, tc_message);
	tcase_add_checked_fixture(tc_message, setup, teardown);
	
	tcase_add_test(tc_message, test_dbmail_message_new);
	tcase_add_test(tc_message, test_dbmail_message_new_from_stream);
	tcase_add_test(tc_message, test_dbmail_message_set_class);
	tcase_add_test(tc_message, test_dbmail_message_get_class);
	tcase_add_test(tc_message, test_dbmail_message_get_internal_date);
	tcase_add_test(tc_message, test_dbmail_message_retrieve);
//	tcase_add_test(tc_message, test_dbmail_message_init_with_string);
	tcase_add_test(tc_message, test_dbmail_message_to_string);
//	tcase_add_test(tc_message, test_dbmail_message_init_with_stream);
	tcase_add_test(tc_message, test_dbmail_message_hdrs_to_string);
	tcase_add_test(tc_message, test_dbmail_message_body_to_string);
	tcase_add_test(tc_message, test_dbmail_message_get_rfcsize);
	tcase_add_test(tc_message, test_dbmail_message_set_header);
	tcase_add_test(tc_message, test_dbmail_message_set_header);
	tcase_add_test(tc_message, test_dbmail_message_get_header);
	tcase_add_test(tc_message, test_dbmail_message_cache_headers);
	tcase_add_test(tc_message, test_dbmail_message_free);
	tcase_add_test(tc_message, test_dbmail_message_encoded);
	tcase_add_test(tc_message, test_dbmail_message_8bit);
	tcase_add_test(tc_message, test_dbmail_message_get_header_addresses);
	tcase_add_test(tc_message, test_dbmail_message_get_header_repeated);
	tcase_add_test(tc_message, test_dbmail_message_construct);
	tcase_add_test(tc_message, test_encoding);

	return s;
}

int main(void)
{
	int nf;
	g_mime_init(0);
	Suite *s = dbmail_message_suite();
	SRunner *sr = srunner_create(s);
	srunner_run_all(sr, CK_NORMAL);
	nf = srunner_ntests_failed(sr);
	srunner_free(sr);
	g_mime_shutdown();
	return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
	



syntax highlighted by Code2HTML, v. 0.9.1