Fixes a crash when saving attachments fails
[modest] / tests / check_text-utils.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <check.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <modest-text-utils.h>
35 #include <modest-init.h>
36
37 typedef struct {
38         const gchar *original;
39         const gchar *expected;
40 } StringPair;
41
42 static void
43 fx_setup_i18n ()
44 {
45         fail_unless (gtk_init_check (NULL, NULL));
46         fail_unless (modest_init (0, NULL), "Failed running modest_init");
47 }
48
49 /* ----------------- display address tests -------------- */
50
51 /**
52  * Test regular usage of modest_text_utils_get_display_address
53  *  - Test 1: Check "<...>" deletion
54  *  - Test 2: Check "(...)" deletion
55  *  - Test 3: Check address left and right trim, also non ASCII chars
56  *  - Test 4: Check issues in tests 1, 2 and 3 together
57  *  - Test 5: Check with an empty address
58  */
59 START_TEST (test_get_display_address_regular)
60 {
61         gint i;
62         const StringPair tests[] = {
63                 { "John Doe <foo@bar>", "John Doe" },
64                 { "Rupert Griffin (test)", "Rupert Griffin (test)"},
65                 { "    Hyvää päivää    ", "Hyvää päivää"},
66                 { "  John Doe  <foo@bar>  (test)  ", "John Doe" },
67                 { "", "" },
68         };
69
70         /* Tests 1, 2, 3, 4 */
71         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
72                 gchar *str = g_strdup (tests[i].original);
73                 modest_text_utils_get_display_address (str);
74                 fail_unless (str && strcmp(str, tests[i].expected) == 0,
75                         "modest_text_utils_get_display_address failed for '%s': "
76                              "expected '%s' but got '%s'",
77                              tests[i].original, tests[i].expected, str);
78                 g_free (str);
79         }
80 }
81 END_TEST
82
83
84 /**
85  * Test invalid usage of modest_text_utils_get_display_address
86  *  - Test 1: Check with NULL address (should return NULL)
87  */
88 START_TEST (test_get_display_address_invalid)
89 {
90         /* Test 1 */
91         modest_text_utils_get_display_address (NULL);
92 }
93 END_TEST
94
95 /* ----------------- derived address tests -------------- */
96
97 /**
98  * Test regular usage of modest_text_utils_derived_subject
99  *  - Test 1: Check with a normal subject
100  *  - Test 2: Test with NULL subject
101  *  - Test 3: Test with non ASCII chars
102  *  - Test 4: Test with an empty subject
103  */
104 START_TEST (test_derived_subject_regular)
105 {
106         gint i;
107         const gchar *prefix="Re:";
108         const StringPair tests[] = {
109                 { "subject", "Re: subject" },
110                 { NULL,      "Re: (no subject)"},
111                 { "Hyvää päivää", "Re: Hyvää päivää"},
112                 { "", "Re: (no subject)"},
113         };
114
115         /* Tests 1, 2, 3, 4 */
116         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
117                 gchar *orig = g_strdup (tests[i].original);
118                 gchar *str = modest_text_utils_derived_subject (orig, prefix);
119                 fail_unless (str && strcmp(str, tests[i].expected) == 0,
120                         "modest_text_utils_derived_subject failed for '%s': "
121                              "expected '%s' but got '%s'",
122                              tests[i].original, tests[i].expected, str);
123                 g_free (orig);
124                 g_free (str);
125         }
126 }
127 END_TEST
128
129 /**
130  * Test invalid usage of modest_text_utils_derived_subject
131  *  - Test 1: Check with NULL prefix (should return NULL)
132  */
133 START_TEST (test_derived_subject_invalid)
134 {
135         /* Test 1 */
136         fail_unless (modest_text_utils_derived_subject (NULL, NULL) == NULL,
137                      "modest_text_utils_derived_subject (*,NULL) should be NULL");
138 }
139 END_TEST
140
141 /* --------------------- quote tests -------------------- */
142
143 /**
144  * Test regular usage of modest_text_utils_quote
145  *  - Test 1: Quote empty text
146  *  - Test 2: Quote 1 line of plain text 
147  *  - Test 3: Quote several lines of plain text 
148  *  - Test 4: Quote non ASCII chars
149  *  - Test 5: Quote with a limit lower than the any word in the text
150  *  - TODO: Test HTML quotation once its implementation if finished
151  */
152 START_TEST (test_quote_regular)
153 {
154         gint i;
155         gchar *text = NULL;
156         gchar *expected_quoted_text = NULL;
157         gchar *quoted_text = NULL;
158
159         /* Tests 1, 2, 3 */
160         const StringPair tests[] = {
161                 { "", 
162                   "\n----- Original message -----\n> \n" },
163                 { "This text should be quoted", 
164                   "\n----- Original message -----\n> This text\n> should be quoted\n> \n" },
165                 { "These are several\nlines\nof plain text", 
166                   "\n----- Original message -----\n> These are\n> several lines\n> of plain text\n" },
167                 { "áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš", 
168                   "\n----- Original message -----\n> áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš\n" },
169         };
170
171         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
172                 text = g_strdup (tests[i].original);
173                 expected_quoted_text = g_strdup (tests[i].expected);
174                 quoted_text = modest_text_utils_quote (text, "text/plain", NULL /*signature*/,
175                                                        "foo@bar",  0 /* date */, NULL /*attachments*/, 15 /*limit*/);
176                 fail_unless (quoted_text && strcmp(expected_quoted_text, quoted_text)==0,
177                              "modest_text_utils_quote failed:\nOriginal text:\n\"%s\"\n" \
178                              "Expected quotation:\n\"%s\"\nQuoted text:\n\"%s\"",
179                              text, expected_quoted_text, quoted_text);
180                 g_free (text);
181                 g_free (expected_quoted_text);
182                 g_free (quoted_text);
183         }
184
185         /* Test 5 */
186         text = g_strdup ("Quotation test example");
187         expected_quoted_text = 
188                 g_strdup ("\n----- Original message -----\n> Quotation\n> test\n> example\n> \n");
189         quoted_text = modest_text_utils_quote (text, "text/plain", NULL /*signature */,
190                                                "foo@bar",  0 /*date*/, NULL /*attachments*/, 1 /*limit*/);
191         fail_unless (quoted_text && !strcmp (expected_quoted_text, quoted_text),
192                      "modest_text_utils_quote failed:\nOriginal text:\n\"%s\"\n" \
193                      "Expected quotation:\n\"%s\"\nQuoted text:\n\"%s\"",
194                      text, expected_quoted_text, quoted_text);
195         g_free (text);
196         g_free (expected_quoted_text);
197         g_free (quoted_text);
198 }
199 END_TEST
200
201 /**
202  * Test invalid usage of modest_text_utils_quote
203  *  - Test 1: Check NULL text (should return NULL)
204  *  - Test 2: Check NULL content_type (should quote as text/plain)
205  *  - Test 3: Check NULL address (should cite address as "(null)")
206  *  - Test 4: Check negative limit (should write each word in its own line)
207  *  - TODO: Repeat tests for HTML quotation when its implementation is finished
208  */
209 START_TEST (test_quote_invalid)
210 {
211         gchar *text = NULL;
212         gchar *expected_quoted_text = NULL;
213         gchar *quoted_text = NULL;
214
215         /* Test 1 (Fault) */
216         text = NULL;
217         quoted_text = modest_text_utils_quote (NULL, "text/plain", NULL, "foo@bar",  0, NULL, 15);
218         fail_unless (quoted_text == NULL,
219                      "modest_text_utils_quote failed:\nOriginal text: NULL\n" \
220                      "Expected quotation: NULL\nQuoted text: \"%s\"",
221                      quoted_text);
222         g_free (quoted_text);
223         
224         
225         /* Test 2 (Fault) */
226         text = g_strdup ("Text");
227         quoted_text = modest_text_utils_quote (text, NULL, NULL, "foo@bar",  0, NULL, 15);
228         fail_unless (quoted_text == NULL,
229                      "modest_text_utils_quote failed:\nOriginal text: NULL\n" \
230                      "Expected quotation: NULL\nQuoted text: \"%s\"",
231                      quoted_text);
232         g_free (text);
233         g_free (quoted_text);
234
235         /* Test 3 */
236         text = g_strdup ("Text");
237         expected_quoted_text = g_strdup ("\n----- Original message -----\n> Text\n");
238         quoted_text = modest_text_utils_quote (text, "text/plain", NULL, NULL,  0, NULL, 15);
239         fail_unless (quoted_text && strcmp (quoted_text, expected_quoted_text) == 0,
240                      "modest_text_utils_quote failed:\nOriginal text: NULL\n" \
241                      "Expected quotation: %s\nQuoted text: \"%s\"",
242                      expected_quoted_text, quoted_text);
243         g_free (text);
244         g_free (expected_quoted_text);
245         g_free (quoted_text);
246
247         /* Test 4 */
248         text = g_strdup ("This is a text");
249         expected_quoted_text = g_strdup ("\n----- Original message -----\n> This\n> is\n> a\n> text\n> \n");
250         quoted_text = modest_text_utils_quote (text, "text/plain", NULL, "foo@bar",  0, NULL, 0);
251         fail_unless (quoted_text && !strcmp (expected_quoted_text, quoted_text),
252                      "modest_text_utils_quote failed:\nOriginal text:\n\"%s\"\n" \
253                      "Expected quotation:\n\"%s\"\nQuoted text:\n\"%s\"",
254                      text, expected_quoted_text, quoted_text);
255         g_free (text);
256         g_free (expected_quoted_text);
257         g_free (quoted_text);
258 }
259 END_TEST
260
261 /* ---------------------- cite tests -------------------- */
262
263 /**
264  * Test regular usage of modest_text_utils_cite
265  *  - Test 1: Check cite of an empty text
266  *  - Test 2: Check cite of a line of text
267  *  - Test 3: Check cite of several lines of text
268  *  - Test 4: Check with non ASCII chars
269  */
270 START_TEST (test_cite_regular)
271 {
272         gint i;
273         gchar *cited_text = NULL;
274         const StringPair tests[] = {
275                 { "", 
276                   "\n--\nSIGNATURE" },
277                 { "This is some text", 
278                   "This is some text\n--\nSIGNATURE" },
279                 { "This\nis some\ntext", 
280                   "This\nis some\ntext\n--\nSIGNATURE" },
281                 { "áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš",
282                   "áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš\n--\nSIGNATURE" },
283         };
284
285         /* Tests 1, 2, 3, 4 */
286         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
287                 cited_text = modest_text_utils_cite (tests[i].original, "text/plain", "SIGNATURE", "foo@bar", 0);
288                 fail_unless (cited_text && !strcmp (tests[i].expected, cited_text),
289                              "modest_text_utils_cite failed:\nOriginal text:\n\"%s\"\n" \
290                              "Expected cite:\n\"%s\"\nCite obtained:\n\"%s\"",
291                              tests[i].original, tests[i].expected, cited_text);
292                 g_free (cited_text);
293         }
294 }
295 END_TEST
296
297 /**
298  * Test invalid usage of modest_text_utils_cite
299  *  - Test 1: Check NULL text (should cite text as (null))
300  *  - Test 2: Check NULL address (should cite address as (null)
301  *  TODO: add tests for content_type once it is used in the implementation
302  */
303 START_TEST (test_cite_invalid)
304 {
305         gchar *text = NULL;
306         gchar *cited_text = NULL;
307         gchar *expected_cite = NULL;
308
309         /* Test 1 */
310         text = NULL;
311         cited_text = modest_text_utils_cite (text, "text/plain", "SIGNATURE", "foo@bar", 0);
312         fail_unless (cited_text == NULL,
313                      "modest_text_utils_cite failed:\nOriginal text:\nNULL\n" \
314                      "Expected cite:\nNULL\nCite obtained:\n\"%s\"",
315                      cited_text);
316         g_free (expected_cite);
317         g_free (cited_text);
318
319         /* Test 2 */
320         text = g_strdup ("This is some text");
321         expected_cite = g_strdup ("This is some text\n--\nSIGNATURE");
322         cited_text = modest_text_utils_cite (text, "text/plain", "SIGNATURE", NULL, 0);
323         fail_unless (cited_text && !strcmp (expected_cite, cited_text),
324                      "modest_text_utils_cite failed:\nOriginal text:\n\"%s\"\n" \
325                      "Expected cite:\n\"%s\"\nCite obtained:\n\"%s\"",
326                      text, expected_cite, cited_text);
327         g_free (text);
328         g_free (expected_cite);
329         g_free (cited_text);
330
331         /* Test 3 */
332         text = g_strdup ("This is some text");
333         expected_cite = g_strdup ("This is some text");
334         cited_text = modest_text_utils_cite (text, "text/plain", NULL, "foo@bar", 0);
335         fail_unless (cited_text && !strcmp (expected_cite, cited_text),
336                      "modest_text_utils_cite failed:\nOriginal text:\n\"%s\"\n" \
337                      "Expected cite:\n\"%s\"\nCite obtained:\n\"%s\"",
338                      text, expected_cite, cited_text);
339         g_free (text);
340         g_free (expected_cite);
341         g_free (cited_text);
342 }
343 END_TEST
344
345 /* -------------------- inline tests -------------------- */
346
347 /**
348  * Test regular usage of modest_text_utils_inline
349  *  - Test 1: Check inline of an empty text
350  *  - Test 2: Check inline of a regular text
351  *  - Test 3: Check with non ASCII chars
352  *  TODO: add tests for HTML when implementation is finished
353  */
354 START_TEST (test_inline_regular)
355 {
356         gint i;
357         gchar *inlined_text = NULL;
358         const StringPair tests[] = {
359                 { "", 
360                   "\n----- Original message -----\n" \
361                   "From: foo@bar\n" \
362                   "Sent:  Thu,  1 Jan 1970, 01:00:00 CET\n" \
363                   "To: bar@foo\n" \
364                   "Subject: Any subject\n\n> \n" },
365                 { "Some text\nto inline", 
366                   "\n----- Original message -----\n" \
367                   "From: foo@bar\n" \
368                   "Sent:  Thu,  1 Jan 1970, 01:00:00 CET\n" \
369                   "To: bar@foo\n" \
370                   "Subject: Any subject\n\n" \
371                   "> Some text\n> to inline\n" },
372                 { "áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš", 
373                   "\n----- Original message -----\n" \
374                   "From: foo@bar\n" \
375                   "Sent:  Thu,  1 Jan 1970, 01:00:00 CET\n" \
376                   "To: bar@foo\n" \
377                   "Subject: Any subject\n\n" \
378                   "> áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš\n" },
379         };
380
381         /* Tests 1, 2, 3 */
382         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
383                 inlined_text =  modest_text_utils_inline (tests[i].original, 
384                                                           "text/plain", 
385                                                           NULL, 
386                                                           "foo@bar", 
387                                                           0, 
388                                                           "bar@foo", 
389                                                           "Any subject");
390                 fail_unless (inlined_text && !strcmp (tests[i].expected, inlined_text),
391                              "modest_text_utils_inline failed:\nOriginal text:\n\"%s\"\n" \
392                              "Expected inline:\n\"%s\"\nInline obtained:\n\"%s\"",
393                              tests[i].original, tests[i].expected, inlined_text);               
394                 g_free (inlined_text);
395         }
396 }
397 END_TEST
398
399 /**
400  * Test invalid usage of modest_text_utils_inline
401  *  - Test 1: Check NULL text (should inline text as (null))
402  *  - Test 2: Check NULL content_type (should assume text/plain)
403  *  - Test 3: Check NULL from (should write "(null)")
404  *  - Test 4: Check NULL to (should write ("null"))
405  *  - Test 5: Check NULL subject (should write ("null"))
406  * TODO: repeat tests from HTML when implemented
407  */
408 START_TEST (test_inline_invalid)
409 {
410         gchar *text = NULL;
411         gchar *expected_inline = NULL;
412         gchar *inlined_text = NULL;
413
414         /* Test 1 */
415         expected_inline = g_strdup("-----Forwarded Message-----\n" \
416                                    "From: foo@bar\n" \
417                                    "Sent: Thu Jan  1 01:00:00 1970\n" \
418                                    "To: bar@foo\n" \
419                                    "Subject: Any subject\n\n" \
420                                    "(null)");
421         inlined_text =  modest_text_utils_inline (NULL, 
422                                                   "text/plain", 
423                                                   NULL,
424                                                   "foo@bar", 
425                                                   0, 
426                                                   "bar@foo", 
427                                                   "Any subject");
428         fail_unless (inlined_text == NULL, 
429                      "modest_text_utils_inline failed: it should return NULL");
430         g_free (expected_inline);
431         g_free (inlined_text);
432
433         /* Test 2 (Fault) */
434         text = g_strdup ("Some text");
435         expected_inline = g_strdup("-----Forwarded Message-----\n" \
436                                    "From: foo@bar\n" \
437                                    "Sent: Thu Jan  1 01:00:00 1970\n" \
438                                    "To: bar@foo\n" \
439                                    "Subject: Any subject\n\n" \
440                                    "Some text");
441         inlined_text =  modest_text_utils_inline (text,
442                                                   NULL,
443                                                   NULL,
444                                                   "foo@bar",
445                                                   0,
446                                                   "bar@foo",
447                                                   "Any subject");
448         fail_unless (inlined_text == NULL, 
449                      "modest_text_utils_inline failed: it should return NULL");
450         g_free (expected_inline);
451         g_free (inlined_text);
452
453         /* Test 3 */
454         text = g_strdup ("Some text");
455         expected_inline = g_strdup("\n----- Original message -----\n"   \
456                                    "From: \n" \
457                                    "Sent:  Thu,  1 Jan 1970, 01:00:00 CET\n" \
458                                    "To: bar@foo\n" \
459                                    "Subject: Any subject\n\n" \
460                                    "> Some text\n");
461         inlined_text =  modest_text_utils_inline (text, 
462                                                   "text/plain", 
463                                                   NULL, 
464                                                   NULL, 
465                                                   0, 
466                                                   "bar@foo", 
467                                                   "Any subject");
468         fail_unless (inlined_text && strcmp (inlined_text, expected_inline) == 0, 
469                      "modest_text_utils_inline failed: it should return %s and returned %s",
470                      expected_inline, inlined_text);
471
472         g_free (expected_inline);
473         g_free (inlined_text);
474
475         /* Test 4 */
476         text = g_strdup ("Some text");
477         expected_inline = g_strdup("\n----- Original message -----\n"   \
478                                    "From: foo@bar\n" \
479                                    "Sent:  Thu,  1 Jan 1970, 01:00:00 CET\n" \
480                                    "To: \n" \
481                                    "Subject: Any subject\n\n" \
482                                    "> Some text\n");
483         inlined_text =  modest_text_utils_inline (text, 
484                                                   "text/plain", 
485                                                   NULL,
486                                                   "foo@bar", 
487                                                   0, 
488                                                   NULL, 
489                                                   "Any subject");
490         fail_unless (inlined_text && strcmp (inlined_text, expected_inline) == 0, 
491                      "modest_text_utils_inline failed: it should return %s and returned %s",
492                      expected_inline, inlined_text);
493         g_free (expected_inline);
494         g_free (inlined_text);
495         
496         /* Test 5 */
497         text = g_strdup ("Some text");
498         expected_inline = g_strdup("\n----- Original message -----\n" \
499                                    "From: foo@bar\n" \
500                                    "Sent:  Thu,  1 Jan 1970, 01:00:00 CET\n" \
501                                    "To: bar@foo\n" \
502                                    "Subject: \n\n" \
503                                    "> Some text\n");
504         inlined_text =  modest_text_utils_inline (text, 
505                                                   "text/plain", 
506                                                   NULL, 
507                                                   "foo@bar", 
508                                                   0, 
509                                                   "bar@foo", 
510                                                   NULL);
511         fail_unless (inlined_text && strcmp (inlined_text, expected_inline) == 0, 
512                      "modest_text_utils_inline failed: it should return %s and returned %s",
513                      expected_inline, inlined_text);
514
515         g_free (expected_inline);
516         g_free (inlined_text);
517 }
518 END_TEST
519
520 /* ---------------- remove address tests ---------------- */
521
522 /**
523  * Test regular usage of modest_text_utils_remove_address
524  *  - Test 1: Remove a single address in the middle of a list
525  *  - Test 2: Remove an extended address in the middle of a list
526  *  - Test 3: Remove an address that appears more than once in the list
527  *  - Test 4: Remove address from an empty list
528  *  - Test 5: Check with non ASCII characters
529  */
530 START_TEST (test_remove_address_regular)
531 {
532         gchar *list = NULL;
533         gchar *new_list = NULL;
534         gchar *address = NULL;
535
536         /* Test 1 */
537         list = g_strdup ("foo@bar <foo>, myname@mycompany.com (myname), " \
538                          "xxx@yyy.zzz (xxx yyy zzz), bar@foo");
539         address = g_strdup ("xxx@yyy.zzz");
540         new_list = modest_text_utils_remove_address (list, address);
541
542         fail_unless (new_list && strstr (new_list, "foo@bar <foo>") != NULL,
543                      "modest_text_utils_remove_address failed: "\
544                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
545                      address, list, new_list);
546         fail_unless (new_list && strstr (new_list, "myname@mycompany.com (myname)") != NULL,
547                      "modest_text_utils_remove_address failed: " \
548                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
549                      address, list, new_list);
550         fail_unless (new_list && strstr (new_list, "bar@foo") != NULL,
551                      "modest_text_utils_remove_address failed: " \
552                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
553                      address, list, new_list);
554         fail_unless (new_list && strstr (new_list, "xxx@yyy.zzz") == NULL,
555                      "modest_text_utils_remove_address failed: " \
556                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
557                      address, list, new_list);
558         fail_unless (new_list && strstr (new_list, "(xxx yyy zzz)") == NULL,
559                      "modest_text_utils_remove_address failed: " \
560                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
561                      address, list, new_list);
562
563         g_free (list);
564         g_free (new_list);
565         g_free (address);
566
567         /* Test 2 */
568         list = g_strdup ("foo@bar <foo>, xxx@yyy.zzz (xxx yyy zzz), bar@foo");
569         address = g_strdup ("xxx@yyy.zzz (xxx yyy zzz)");
570         new_list = modest_text_utils_remove_address (list, address);
571
572         fail_unless (new_list && strstr (new_list, "foo@bar <foo>") != NULL,
573                      "modest_text_utils_remove_address failed: " \
574                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
575                      address, list, new_list);
576         fail_unless (new_list && strstr (new_list, "bar@foo") != NULL,
577                      "modest_text_utils_remove_address failed: " \
578                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
579                      address, list, new_list);
580         fail_unless (new_list && strstr (new_list, "xxx@yyy.zzz") == NULL,
581                      "modest_text_utils_remove_address failed: " \
582                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
583                      address, list, new_list);
584         fail_unless (new_list && strstr (new_list, "(xxx yyy zzz)") == NULL,
585                      "modest_text_utils_remove_address failed: " \
586                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
587                      address, list, new_list);
588
589         g_free (list);
590         g_free (new_list);
591         g_free (address);
592
593         /* Test 3 */
594         list = g_strdup ("foo@bar <foo>, bar@foo (BAR), xxx@yyy.zzz (xxx yyy zzz), bar@foo");
595         address = g_strdup ("bar@foo");
596         new_list = modest_text_utils_remove_address (list, address);
597
598         fail_unless (new_list && strstr (new_list, "foo@bar <foo>") != NULL,
599                      "modest_text_utils_remove_address failed: " \
600                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
601                      address, list, new_list);
602         fail_unless (new_list && strstr (new_list, "xxx@yyy.zzz (xxx yyy zzz)") != NULL,
603                      "modest_text_utils_remove_address failed: " \
604                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
605                      address, list, new_list);
606         fail_unless (new_list && strstr (new_list, "bar@foo") == NULL,
607                      "modest_text_utils_remove_address failed: " \
608                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
609                      address, list, new_list);
610         fail_unless (new_list && strstr (new_list, "(BAR)") == NULL,
611                      "modest_text_utils_remove_address failed: " \
612                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
613                      address, list, new_list);
614
615         g_free (list);
616         g_free (new_list);
617         g_free (address);
618
619         /* Test 4 */
620         list = g_strdup ("");
621         address = g_strdup ("bar@foo");
622         new_list = modest_text_utils_remove_address (list, address);
623
624         fail_unless (new_list && !strcmp (new_list, list),
625                      "modest_text_utils_remove_address failed: " \
626                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
627                      address, list, new_list);
628
629         g_free (list);
630         g_free (new_list);
631         g_free (address);
632
633         /* Test 5 */
634         list = g_strdup ("foo@bar, áñï@Èž.com (Àç ÑŸž), bar@foo");
635         address = g_strdup ("áñï@Èž.com");
636         new_list = modest_text_utils_remove_address (list, address);
637
638         fail_unless (new_list && strstr (new_list, "foo@bar") != NULL,
639                      "modest_text_utils_remove_address failed: " \
640                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
641                      address, list, new_list);
642         fail_unless (new_list && strstr (new_list, "bar@foo") != NULL,
643                      "modest_text_utils_remove_address failed: " \
644                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
645                      address, list, new_list);
646         fail_unless (new_list && strstr (new_list, "áñï@Èž.com") == NULL,
647                      "modest_text_utils_remove_address failed: " \
648                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
649                      address, list, new_list);
650         fail_unless (new_list && strstr (new_list, "(Àç ÑŸž)") == NULL,
651                      "modest_text_utils_remove_address failed: " \
652                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
653                      address, list, new_list);
654
655         g_free (list);
656         g_free (new_list);
657         g_free (address);
658 }
659 END_TEST
660
661 /**
662  * Test limits usage of modest_text_utils_remove_address
663  *  - Test 1: Remove address at the beginning of the list
664  *  - Test 2: Remove address at the end  of the list
665  *  - Test 3: Remove the address of a one-element-size list
666  */
667 START_TEST (test_remove_address_limits)
668 {
669         gchar *list = NULL;
670         gchar *new_list = NULL;
671         gchar *expected_list = NULL;
672         //gchar *address = NULL;
673         gint i;
674
675         const StringPair tests[] = {
676                 { "foo@bar <FOO BAR>, bar@foo (BAR FOO)", "bar@foo (BAR FOO)" },
677                 { "foo@bar <FOO BAR>, bar@foo (BAR FOO)", "foo@bar <FOO BAR>" },
678                 { "foo@bar <FOO BAR>", "" },
679         };
680         const gchar *remove[] = { "foo@bar", "bar@foo", "foo@bar" };
681
682         /* Tests 1, 2, 3 */
683         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
684                 list = g_strdup (tests[i].original);
685                 expected_list = g_strdup (tests[i].expected);
686                 new_list = modest_text_utils_remove_address (list, remove[i]);
687                 fail_unless (new_list && !strcmp (expected_list, new_list),
688                              "modest_text_utils_remove_address failed: " \
689                              "Removing \"%s\" from address list \"%s\" returns \"%s\" instead of \"%s\"",
690                              remove[i], list, new_list, expected_list);
691                 g_free (list);
692                 g_free (expected_list);
693                 g_free (new_list);
694         }
695 }
696 END_TEST
697
698 /**
699  * Test invalid usage of modest_text_utils_remove_address
700  *  - Test 1: Remove a NULL address (should return the same list)
701  *  - Test 2: Remove an address form a NULL list (should return NULL)
702  */
703 START_TEST (test_remove_address_invalid)
704 {
705         gchar *list = NULL;
706         gchar *new_list = NULL;
707
708         /* Test 1 (Fault) */
709         list = g_strdup ("foo@bar, bar@foo");
710         new_list = modest_text_utils_remove_address (list, NULL);
711         fail_unless (new_list && !strcmp (list, new_list),
712                      "modest_text_utils_remove_address failed: " \
713                      "Removing a NULL address from \"%s\" returns \"%s\"",
714                      list, new_list);
715         g_free (list);
716         g_free (new_list);
717
718         /* Test 2 */
719         new_list = modest_text_utils_remove_address (NULL, "foo@bar");
720         fail_unless (new_list == NULL,
721                      "modest_text_utils_remove_address failed: " \
722                      "Removing an address from a NULL list does not return NULL");
723         g_free (new_list);
724 }
725 END_TEST
726
727 /* --------------- convert to html tests ---------------- */
728
729 /**
730  * Test regular usage of modest_text_utils_convert_to_html
731  *  - Test 1: Check conversion of a regular text
732  *  - Test 2: Check conversion of a regular text with links
733  *  - Test 3: Check conversion of a regular text with special html chars
734  */
735 START_TEST (test_convert_to_html_regular)
736 {
737         gchar *text_in_html;
738         gchar *html_start = NULL;
739         gchar *html_end = NULL;
740         gchar *html = NULL;
741         gint bytes;
742         int i;
743
744         const StringPair tests[] = {
745                 { "This is some text.", 
746                   "<body>This is some text.</body>" },
747                 { "http://xxx.yyy.zzz/myfile", 
748                   "<body><a href=\"http://xxx.yyy.zzz/myfile\">http://xxx.yyy.zzz/myfile</a></body>" },
749                 { "<a  &  b>\n\tx", 
750                   "<body>&lt;a&nbsp; &amp;&nbsp; b&gt;<br>\n&nbsp;&nbsp;&nbsp; x</body>" },
751         };
752
753         /* Tests 1, 2, 3 */
754         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
755                 html = modest_text_utils_convert_to_html (tests[i].original);
756                 fail_unless (html != NULL,
757                              "modest_text_utils_convert_to_html failed:" \
758                              "Original text:\n\"%s\"\nExpected html:\n\"%s\"\nObtained html:\nNULL",
759                              tests[i].original, tests[i].expected);
760                 html_start = strstr (html, "<body>");
761                 html_end = strstr (html, "</body>");
762                 if (html_end != NULL)
763                         html_end += strlen ("</body>");
764                 bytes = html_end - html_start;
765                 text_in_html = g_strndup (html_start, bytes);
766                 
767                 fail_unless (strstr (html, tests[i].expected) != NULL,
768                              "modest_text_utils_convert_to_html failed:" \
769                              "Original text:\n\"%s\"\nExpected html:\n\"%s\"\n\nObtained string:\n\"%s\"\nObtained html:\n\"%s\"",
770                              tests[i].original, tests[i].expected, html, text_in_html);
771 //              g_free (html_start);
772 //              g_free (text_in_html);
773 //              g_free (html);
774         }
775 }
776 END_TEST
777
778 /**
779  * Test invalid usage of modest_text_utils_convert_to_html
780  *  - Test 1: Check with NULL data
781  */
782 START_TEST (test_convert_to_html_invalid)
783 {
784         gchar *html = NULL;
785
786         /* Test 1 */
787         html = modest_text_utils_convert_to_html (NULL);
788         fail_unless (html == NULL,
789                      "modest_text_utils_convert_to_html failed:" \
790                      "Does not return NULL when passed NULL data");
791 }
792 END_TEST
793
794
795 /* ------------------- Suite creation ------------------- */
796
797 static Suite*
798 text_utils_suite (void)
799 {
800         Suite *suite = suite_create ("ModestTextUtils");
801         TCase *tc = NULL;
802
803         /* Tests case for "display adress" */
804         tc = tcase_create ("display_adress");
805         tcase_add_checked_fixture (tc,
806                                    fx_setup_i18n,
807                                    NULL);
808         tcase_add_test (tc, test_get_display_address_regular);
809         tcase_add_test (tc, test_get_display_address_invalid);
810         suite_add_tcase (suite, tc);
811
812         /* Test case for "derived subject" */
813         tc = tcase_create ("derived_subject");
814         tcase_add_checked_fixture (tc,
815                                    fx_setup_i18n,
816                                    NULL);
817         tcase_add_test (tc, test_derived_subject_regular);
818         tcase_add_test (tc, test_derived_subject_invalid);
819         suite_add_tcase (suite, tc);
820
821         /* Test case for "quote" */
822         tc = tcase_create ("quote");
823         tcase_add_checked_fixture (tc,
824                                    fx_setup_i18n,
825                                    NULL);
826         tcase_add_test (tc, test_quote_regular);
827         tcase_add_test (tc, test_quote_invalid);
828         suite_add_tcase (suite, tc);
829
830         /* Test case for "cite" */
831         tc = tcase_create ("cite");
832         tcase_add_checked_fixture (tc,
833                                    fx_setup_i18n,
834                                    NULL);
835         tcase_add_test (tc, test_cite_regular);
836         tcase_add_test (tc, test_cite_invalid);
837         suite_add_tcase (suite, tc);
838
839         /* Test case for "inline" */
840         tc = tcase_create ("inline");
841         tcase_add_checked_fixture (tc,
842                                    fx_setup_i18n,
843                                    NULL);
844         tcase_add_test (tc, test_inline_regular);
845         tcase_add_test (tc, test_inline_invalid);
846         suite_add_tcase (suite, tc);
847
848         /* Test case for "remove address" */
849         tc = tcase_create ("remove_address");
850         tcase_add_checked_fixture (tc,
851                                    fx_setup_i18n,
852                                    NULL);
853         tcase_add_test (tc, test_remove_address_regular);
854         tcase_add_test (tc, test_remove_address_limits);
855         tcase_add_test (tc, test_remove_address_invalid);
856         suite_add_tcase (suite, tc);
857
858         /* Test case for "convert to html" */
859         tc = tcase_create ("convert_to_html");
860         tcase_add_checked_fixture (tc,
861                                    fx_setup_i18n,
862                                    NULL);
863         tcase_add_test (tc, test_convert_to_html_regular);
864         tcase_add_test (tc, test_convert_to_html_invalid);
865         suite_add_tcase (suite, tc);
866
867         return suite;
868 }
869
870 /* --------------------- Main program ------------------- */
871
872 gint
873 main ()
874 {
875         SRunner *srunner;
876         Suite   *suite;
877         int     failures;
878
879         setenv ("TZ", "Europe/Paris", 1);
880         setenv ("LANG", "en_GB", 1);
881         setenv ("LC_MESSAGES", "en_GB", 1);
882         
883         suite   = text_utils_suite ();
884         srunner = srunner_create (suite);
885                 
886         srunner_run_all (srunner, CK_ENV);
887         failures = srunner_ntests_failed (srunner);
888         srunner_free (srunner);
889         
890         return failures;
891 }