1 /* Evolution calendar client - test program
3 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU Lesser General Public
7 * License as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include <glib/gi18n.h>
26 #include <libecal/e-cal.h>
27 #include <libecal/e-cal-component.h>
28 #include <libecal/e-cal-time-util.h>
29 #include <libedataserver/e-data-server-util.h>
30 #include <libical/ical.h>
32 /* start_testing_scaffold */
33 #define mu_assert(message, test) do { if (!(test)) return message; else { tests_passed++; return NULL;}} while (0)
34 #define mu_run_test(test) do { const gchar *message = test; tests_run++; \
35 if (message) { cl_printf (client, "***Error***\n%s\n", message); break;} } while (0)
37 static gint tests_run = 0;
38 static gint tests_passed = 0;
39 /* end_testing_scaffold */
44 static GMainLoop *loop;
46 /* Prints a message with a client identifier */
48 cl_printf (ECal *client,
54 if (client != client1)
57 va_start (args, format);
58 printf ("Client %s: ", "Test");
59 vprintf (format, args);
64 objects_added_cb (GObject *object,
70 for (l = objects; l; l = l->next)
71 cl_printf (data, "Object added %s\n", icalcomponent_get_uid (l->data));
75 objects_modified_cb (GObject *object,
81 for (l = objects; l; l = l->next)
82 cl_printf (data, "Object modified %s\n", icalcomponent_get_uid (l->data));
86 objects_removed_cb (GObject *object,
92 for (l = objects; l; l = l->next)
93 cl_printf (data, "Object removed %s\n", icalcomponent_get_uid (l->data));
97 view_complete_cb (GObject *object,
98 ECalendarStatus status,
99 const gchar *error_msg,
102 cl_printf (data, "View complete (status:%d, error_msg:%s)\n", status, error_msg ? error_msg : "NULL");
106 list_uids (ECal *client)
108 GList *objects = NULL;
111 if (!e_cal_get_object_list (client, "(contains? \"any\" \"test\")", &objects, NULL))
114 cl_printf (client, "UIDS: ");
116 cl_printf (client, "\nGot %d objects\n", g_list_length (objects));
120 for (l = objects; l; l = l->next) {
123 uid = icalcomponent_get_uid (l->data);
124 printf ("`%s' ", uid);
129 for (l = objects; l; l = l->next) {
130 gchar *obj = icalcomponent_as_ical_string_r (l->data);
131 printf ("------------------------------\n");
133 printf ("------------------------------\n");
138 e_cal_free_object_list (objects);
143 /* Callback used when a client is destroyed */
145 client_destroy_cb (gpointer data,
148 if (E_CAL (object) == client1)
150 else if (E_CAL (object) == client2)
153 if (!client1 && !client2)
154 g_main_loop_quit (loop);
158 test_object_creation (ECal *client,
161 ECalComponent *comp, *comp_retrieved;
162 icalcomponent *icalcomp, *icalcomp_retrieved;
163 struct icaltimetype tt;
164 ECalComponentText text;
165 ECalComponentDateTime dt;
166 ECalComponentTransparency transp;
168 GError *error = NULL;
170 comp = e_cal_component_new ();
172 e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT);
173 text.value = "Creation of new test event";
175 e_cal_component_set_summary (comp, &text);
176 tt = icaltime_from_string ("20040109T090000Z");
179 e_cal_component_set_dtstart (comp, &dt);
180 tt = icaltime_from_string ("20040109T103000");
183 e_cal_component_set_dtend (comp, &dt);
184 e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_OPAQUE);
186 e_cal_component_commit_sequence (comp);
187 icalcomp = e_cal_component_get_icalcomponent (comp);
188 if (!e_cal_create_object (client, icalcomp, uid, &error)) {
189 cl_printf (client, "Object creation: %s\n", error->message);
192 return "Test Object Creation failed";
194 e_cal_component_commit_sequence (comp);
195 if (!e_cal_get_object (client, *uid, NULL, &icalcomp_retrieved, &error)) {
196 cl_printf (client, "Object retrieval: %s\n", error->message);
200 return "Test Object Creation failed";
204 comp_retrieved = e_cal_component_new ();
205 if (!e_cal_component_set_icalcomponent (comp_retrieved, icalcomp_retrieved)) {
206 cl_printf (client, "Could not set icalcomponent\n");
210 g_free (icalcomp_retrieved);
211 return "Test Object Creation failed";
214 /* Dumping icalcomp into a string is not useful as the retrieved object
215 * has some generated information like timestamps. We compare
216 * member values we set during creation*/
217 compare = e_cal_component_event_dates_match (comp, comp_retrieved);
220 e_cal_component_get_transparency (comp_retrieved, &transp);
221 compare = (transp == E_CAL_COMPONENT_TRANSP_OPAQUE);
224 g_free (comp_retrieved);
227 g_free (icalcomp_retrieved);
229 mu_assert ("Test Object creation : Created object does not match retrieved data\n", compare);
234 test_object_modification (ECal *client,
237 const gchar *summary = "This summary was modified";
238 icalcomponent *icalcomp, *icalcomp_modified;
240 GError *error = NULL;
242 if (!e_cal_get_object (client, uid, NULL, &icalcomp, &error)) {
243 cl_printf (client, "Test Modify object : Could not get the object: %s\n", error->message);
245 return error->message;
248 /* Modify one property of the icalcomp and save it.
249 * Now retrieve it and check the field. */
250 icalcomponent_set_summary (icalcomp, summary);
251 if (!e_cal_modify_object (client, icalcomp, CALOBJ_MOD_THIS, &error)) {
252 cl_printf (client, "Test Modify object : Could not modify the object: %s\n", error->message);
255 return error->message;
258 if (!e_cal_get_object (client, uid, NULL, &icalcomp_modified, &error)) {
259 cl_printf (client, "Test Modify object : Could not get the modified object: %s\n", error->message);
262 return "Test Object Creation failed";
265 compare = !strcmp ( icalcomponent_get_summary (icalcomp_modified), summary);
269 g_free (icalcomp_modified);
271 mu_assert ("Test Modify object : Modification failed\n", compare);
277 test_object_removal (ECal *client)
282 icalcomponent *icalcomp;
283 gboolean compare = 1;
284 GError *error = NULL;
286 comp = e_cal_component_new ();
287 e_cal_component_commit_sequence (comp);
288 icalcomp = e_cal_component_get_icalcomponent (comp);
289 if (!e_cal_create_object (client, icalcomp, &uid, &error)) {
290 cl_printf (client, "Test object removal - Object creation: %s\n", error->message);
291 g_object_unref (comp);
292 g_object_unref (icalcomp);
293 return "Test Object Removal failed\n";
296 if (!e_cal_remove_object (client, uid, &error)) {
297 cl_printf (client, "Test object removal - Could not remove the object\n");
299 g_object_unref (comp);
300 g_object_unref (icalcomp);
301 return "Test Object Removal failed\n";
305 compare = e_cal_get_object (client, uid, NULL, &icalcomp, &error);
308 g_object_unref (comp);
309 g_object_unref (icalcomp);
311 mu_assert ("Test object removal - Failed\n", compare);
317 test_get_alarms_in_range (ECal *client)
324 utc = icaltimezone_get_utc_timezone ();
325 start = time_from_isodate ("20040212T000000Z");
326 end = time_add_day_with_zone (start, 2, utc);
328 alarms = e_cal_get_alarms_in_range (client, start, end);
329 compare = (g_slist_length (alarms) == 3);
331 e_cal_free_alarms (alarms);
332 mu_assert ("Test getting alarms in range\n", compare);
338 test_cal_loaded (ECal *client)
340 /* Test one loaded calendar and another that is not loaded. */
341 mu_assert ("Test get_cal_load_state : Failed \n",
342 (E_CAL_LOAD_LOADED == e_cal_get_load_state (client)) &&
343 (E_CAL_LOAD_NOT_LOADED == e_cal_get_load_state (NULL)));
349 test_get_source (ECal *client,
350 const gchar *expected)
354 gboolean compare = 0;
356 /* FIXME ESources no longer have built-in URIs. */
357 /* uri = e_source_get_uri (source); */
359 cal_uri = g_strconcat ("file://", expected, NULL);
360 compare = !strcmp (expected, uri);
363 mu_assert ("Test get_source : Failed\n", compare);
369 test_query (ECal *client,
373 /* This uses pre-loaded data. Hence its results are valid only
374 * when called before any write operation is performed.
377 GList *objects = NULL;
379 if (!e_cal_get_object_list (client, query, &objects, NULL))
380 return "Could not get the list of objects";
381 i = g_list_length (objects);
382 e_cal_free_object_list (objects);
384 mu_assert ("Test get_object_list : Expected number of objects not found", i == expected);
391 test_e_cal_new (ECal **cal,
394 GError *error = NULL;
395 gchar *cal_uri, *cal_file;
396 gboolean created = 0;
398 cal_uri = g_strconcat ("file://", uri, NULL);
399 *cal = e_cal_new_from_uri (cal_uri, E_CAL_SOURCE_TYPE_EVENT);
401 g_message (G_STRLOC ": could not create the client");
403 return "Test Creation of new calendar : Failed";
405 g_object_weak_ref (G_OBJECT (*cal), client_destroy_cb, NULL);
407 cl_printf (*cal, "Calendar loading `%s'...\n", uri);
409 if (!e_cal_open (*cal, FALSE, &error)) {
410 cl_printf (*cal, "Load/create %s\n", error->message);
412 return "Test creation of new calendar : Failed";
415 cal_file = g_strconcat (uri, "/calendar.ics", NULL);
417 created = g_file_test (cal_file, G_FILE_TEST_EXISTS);
421 mu_assert ("Test creation of new calendar : Failed", created);
427 test_e_cal_remove (ECal *ecal,
431 GError *error = NULL;
432 gboolean removed = 0;
434 cal_uri = g_strconcat (uri, "/calendar.ics", NULL);
435 if (!e_cal_remove (ecal, &error)) {
436 cl_printf (ecal, "Test Calendar removal : Could not remove the Calendar : %s\n", error->message);
439 removed = !g_file_test (uri, G_FILE_TEST_EXISTS);
442 mu_assert ("Test Remove calendar : Failed ", removed);
449 test_new_system_calendar (void)
451 #if 0 /* ACCOUNT_MGMT */
452 const gchar *user_data_dir;
456 e_cal_new_system_calendar ();
458 user_data_dir = e_get_user_data_dir ();
459 filename = g_build_filename (
460 user_data_dir, "calendar", "system", "calendar.ics", NULL);
461 created = g_file_test (filename, G_FILE_TEST_EXISTS);
464 mu_assert ("Test creation of default system calendar : Failed", created);
465 #endif /* ACCOUNT_MGMT */
471 test_new_system_tasks (void)
473 #if 0 /* ACCOUNT_MGMT */
474 const gchar *user_data_dir;
478 e_cal_new_system_tasks ();
480 user_data_dir = e_get_user_data_dir ();
481 filename = g_build_filename (
482 user_data_dir, "tasks", "system", "tasks.ics", NULL);
483 created = g_file_test (filename, G_FILE_TEST_EXISTS);
486 mu_assert ("Test creation of default system tasks : Failed", created);
487 #endif /* ACCOUNT_MGMT */
493 test_new_system_memos (void)
495 #if 0 /* ACCOUNT_MGMT */
496 const gchar *user_data_dir;
500 e_cal_new_system_memos ();
502 user_data_dir = e_get_user_data_dir ();
503 filename = g_build_filename (
504 user_data_dir, "memos", "system", "journal.ics", NULL);
505 created = g_file_test (filename, G_FILE_TEST_EXISTS);
508 mu_assert ("Test creation of default system memos : Failed", created);
509 #endif /* ACCOUNT_MGMT */
515 test_get_free_busy (ECal *client)
517 /* TODO uses NULL for users and currently specific to file backend. */
518 GList *l, *freebusy = NULL;
519 GError *error = NULL;
523 utc = icaltimezone_get_utc_timezone ();
524 start = time_from_isodate ("20040212T000000Z");
525 end = time_add_day_with_zone (start, 2, utc);
527 if (!e_cal_get_free_busy (client, NULL, start, end, &freebusy, &error)) {
528 cl_printf (client, "Test free/busy : Could not retrieve free busy information : %s\n", error->message);
529 return error->message;
532 cl_printf (client, "Printing free busy information\n");
533 for (l = freebusy; l; l = l->next) {
535 ECalComponent *comp = E_CAL_COMPONENT (l->data);
537 comp_string = e_cal_component_get_as_string (comp);
538 cl_printf (client, "%s\n\n", comp_string);
539 g_object_unref (comp);
540 g_free (comp_string);
544 cl_printf (client, "free_busy was returned but NULL");
550 test_get_default_object (ECal *client)
552 icalcomponent *icalcomp;
553 GError *error = NULL;
555 if (e_cal_get_default_object (client, &icalcomp, &error)) {
556 ical_string = icalcomponent_as_ical_string_r (icalcomp);
557 cl_printf (client, "Obtained default object: %s\n", ical_string);
558 g_free (ical_string);
563 cl_printf (client, "Test Get default object : Could not get the default object: %s\n", error->message);
564 return error->message;
567 /* XXX The string pasted below is *really* ugly. Alternatively, it could be
568 * read from a file at run-time. Not sure if it is an elegant solution when
569 * multiple clients try to load the same file during stress testing.
570 * how can this be done better ?
574 UID : 20040213T055519Z - 15802 - 500 - 1 - 3@testcal\
575 DTSTAMP : 20040213T055519Z\
576 DTSTART; TZID=/softwarestudio.org / Olson_20011030_5 / Asia / Calcutta:\
578 DTEND; TZID=/softwarestudio.org / Olson_20011030_5 / Asia / Calcutta:\
582 SUMMARY : Test - Travel plans to Kansas\
583 LOCATION : Yellow Brick road\
585 ORGANIZER; CN = dorothy : MAILTO : dorothy@oz\
586 DESCRIPTION: Discuss way to home\
587 ATTENDEE; CUTYPE = INDIVIDUAL; ROLE = REQ - PARTICIPANT; PARTSTAT = ACCEPTED;\
588 RSVP = TRUE; CN = dorothy; LANGUAGE = en : MAILTO : dorothy@oz\
589 ATTENDEE; CUTYPE = INDIVIDUAL; ROLE = REQ - PARTICIPANT; PARTSTAT = NEEDS - ACTION;\
590 RSVP = TRUE; CN = tinman; LANGUAGE = en : MAILTO : tinman@oz\
591 ATTENDEE; CUTYPE = INDIVIDUAL; ROLE = REQ - PARTICIPANT; PARTSTAT = NEEDS - ACTION;\
592 RSVP = TRUE; CN = toto; LANGUAGE = en : MAILTO : toto@oz\
593 ATTENDEE; CUTYPE = INDIVIDUAL; ROLE = OPT - PARTICIPANT; PARTSTAT = NEEDS - ACTION;\
594 RSVP = TRUE; CN = scarecrow; LANGUAGE = en : MAILTO : scarecrow@oz\
595 LAST - MODIFIED : 20040213T055647Z\
599 test_get_object (ECal *client)
601 const gchar *uid = "20040213T055519Z-15802-500-1-3@testcal";
603 icalcomponent *icalcomp;
605 GError *error = NULL;
607 if (!e_cal_get_object (client, uid, NULL, &icalcomp, &error)) {
608 cl_printf (client, "Test Get object : Could not get the object: %s\n", error->message);
609 return error->message;
612 actual = icalcomponent_as_ical_string_r (icalcomp);
613 compare = !strcmp (actual, EXPECTED);
617 mu_assert ("Test : get_object does not match the expected output", compare);
622 test_timezones (ECal *client)
625 GError *error = NULL;
626 if (!e_cal_get_timezone (client, "UTC", &zone, &error))
628 cl_printf (client, "Could not get the timezone\n");
631 printf ("\n\nTime Zones : \n%s *** %s", icaltimezone_get_display_name (zone), icaltimezone_get_tzid (zone));
632 printf ("\n\nTime Zones : \n%s", icaltimezone_get_location (zone));
638 all_tests (ECal *client,
643 mu_run_test (test_new_system_calendar ());
644 mu_run_test (test_new_system_tasks ());
645 mu_run_test (test_new_system_memos ());
646 mu_run_test (test_get_source (client, uri));
647 mu_run_test (test_cal_loaded (client));
649 /* test_query acts on pre-loaded data. Hence it must executed before
650 * any writes are made */
651 mu_run_test (test_query (client, "(contains? \"any\" \"test\")", 2));
652 mu_run_test (test_query (client, "(contains? \"summary\" \"Kansas\")", 1));
653 mu_run_test (test_query (client, "(contains? \"any\" \"gibberish\")", 0));
655 mu_run_test (test_get_default_object (client));
656 mu_run_test (test_get_object (client));
657 mu_run_test (test_get_free_busy (client));
658 mu_run_test (test_object_creation (client, &uid));
659 mu_run_test (test_object_modification (client, uid));
660 /* mu_run_test (test_object_removal (client)); */
661 mu_run_test (test_get_alarms_in_range (client));
664 tmp = g_strconcat (uri, "_tmp", NULL);
665 mu_run_test (test_e_cal_new (&ecal, tmp));
666 mu_run_test (test_e_cal_remove (ecal, tmp));
670 test_timezones (client);
675 /* Creates a calendar client and tries to load the specified URI into it */
677 create_client (ECal **client,
680 gboolean only_if_exists)
682 const gchar *results;
685 GError *error = NULL;
687 cal_uri = g_strconcat ("file://", uri, NULL);
688 /* FIXME We don't build ECals from URIs anymore. */
689 /* *client = e_cal_new_from_uri (cal_uri, type); */
692 g_message (G_STRLOC ": could not create the client");
696 g_object_weak_ref (G_OBJECT (*client), client_destroy_cb, NULL);
698 cl_printf (*client, "Calendar loading `%s'...\n", uri);
700 if (!e_cal_open (*client, only_if_exists, &error)) {
701 cl_printf (*client, "Load/create %s\n", error->message);
704 g_clear_error (&error);
706 if (!e_cal_get_query (*client, "(contains? \"any\" \"Event\")", &query, NULL)) {
707 cl_printf (*client, G_STRLOC ": Unable to obtain query");
711 g_signal_connect (G_OBJECT (query), "objects_added",
712 G_CALLBACK (objects_added_cb), client);
713 g_signal_connect (G_OBJECT (query), "objects_modified",
714 G_CALLBACK (objects_modified_cb), client);
715 g_signal_connect (G_OBJECT (query), "objects_removed",
716 G_CALLBACK (objects_removed_cb), client);
717 g_signal_connect (G_OBJECT (query), "view_complete",
718 G_CALLBACK (view_complete_cb), client);
720 e_cal_view_start (query);
722 results = all_tests (*client, uri);
723 cl_printf (*client, "\n\n\n*************Tests run: %d****************\n\n", tests_run);
724 cl_printf (*client, "*************Tests passed: %d*************\n\n\n", tests_passed);
726 cl_printf (*client, "***Failures********%s\n", results);
728 cl_printf (*client, "dump of the test calendar data");
739 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
740 textdomain (GETTEXT_PACKAGE);
743 loop = g_main_loop_new (NULL, TRUE);
745 /* arg1- file name; arg2- client suffix */
746 uri = g_strconcat (argv[1], argv[2], NULL);
747 create_client (&client1, uri, E_CAL_SOURCE_TYPE_EVENT, FALSE);
750 g_main_loop_run (loop);