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