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_set_uri (ECal *client,
341 /* The uri is set as part of create_client call. This method merely
342 * verifies it was done correctly.
345 gboolean compare = 0;
346 cal_uri = g_strconcat ("file://", uri, NULL);
347 compare = !strcmp (e_cal_get_uri (client), cal_uri);
350 mu_assert ("Test set_uri : uri was not set correctly\n", compare);
356 test_cal_loaded (ECal *client)
358 /* Test one loaded calendar and another that is not loaded. */
359 mu_assert ("Test get_cal_load_state : Failed \n",
360 (E_CAL_LOAD_LOADED == e_cal_get_load_state (client)) &&
361 (E_CAL_LOAD_NOT_LOADED == e_cal_get_load_state (NULL)));
367 test_get_source (ECal *client,
368 const gchar *expected)
373 gboolean compare = 0;
375 source = e_cal_get_source (client);
376 uri = e_source_get_uri (source);
377 cal_uri = g_strconcat ("file://", expected, NULL);
378 compare = !strcmp (expected, uri);
381 mu_assert ("Test get_source : Failed\n", compare);
387 test_query (ECal *client,
391 /* This uses pre-loaded data. Hence its results are valid only
392 * when called before any write operation is performed.
395 GList *objects = NULL;
397 if (!e_cal_get_object_list (client, query, &objects, NULL))
398 return "Could not get the list of objects";
399 i = g_list_length (objects);
400 e_cal_free_object_list (objects);
402 mu_assert ("Test get_object_list : Expected number of objects not found", i == expected);
409 test_e_cal_new (ECal **cal,
412 GError *error = NULL;
413 gchar *cal_uri, *cal_file;
414 gboolean created = 0;
416 cal_uri = g_strconcat ("file://", uri, NULL);
417 *cal = e_cal_new_from_uri (cal_uri, E_CAL_SOURCE_TYPE_EVENT);
419 g_message (G_STRLOC ": could not create the client");
421 return "Test Creation of new calendar : Failed";
423 g_object_weak_ref (G_OBJECT (*cal), client_destroy_cb, NULL);
425 cl_printf (*cal, "Calendar loading `%s'...\n", uri);
427 if (!e_cal_open (*cal, FALSE, &error)) {
428 cl_printf (*cal, "Load/create %s\n", error->message);
430 return "Test creation of new calendar : Failed";
433 cal_file = g_strconcat (uri, "/calendar.ics", NULL);
435 created = g_file_test (cal_file, G_FILE_TEST_EXISTS);
439 mu_assert ("Test creation of new calendar : Failed", created);
445 test_e_cal_remove (ECal *ecal,
449 GError *error = NULL;
450 gboolean removed = 0;
452 cal_uri = g_strconcat (uri, "/calendar.ics", NULL);
453 if (!e_cal_remove (ecal, &error)) {
454 cl_printf (ecal, "Test Calendar removal : Could not remove the Calendar : %s\n", error->message);
457 removed = !g_file_test (uri, G_FILE_TEST_EXISTS);
460 mu_assert ("Test Remove calendar : Failed ", removed);
467 test_new_system_calendar (void)
469 const gchar *user_data_dir;
473 e_cal_new_system_calendar ();
475 user_data_dir = e_get_user_data_dir ();
476 filename = g_build_filename (
477 user_data_dir, "calendar", "system", "calendar.ics", NULL);
478 created = g_file_test (filename, G_FILE_TEST_EXISTS);
481 mu_assert ("Test creation of default system calendar : Failed", created);
487 test_new_system_tasks (void)
489 const gchar *user_data_dir;
493 e_cal_new_system_tasks ();
495 user_data_dir = e_get_user_data_dir ();
496 filename = g_build_filename (
497 user_data_dir, "tasks", "system", "tasks.ics", NULL);
498 created = g_file_test (filename, G_FILE_TEST_EXISTS);
501 mu_assert ("Test creation of default system tasks : Failed", created);
507 test_new_system_memos (void)
509 const gchar *user_data_dir;
513 e_cal_new_system_memos ();
515 user_data_dir = e_get_user_data_dir ();
516 filename = g_build_filename (
517 user_data_dir, "memos", "system", "journal.ics", NULL);
518 created = g_file_test (filename, G_FILE_TEST_EXISTS);
521 mu_assert ("Test creation of default system memos : Failed", created);
527 test_get_free_busy (ECal *client)
529 /* TODO uses NULL for users and currently specific to file backend. */
530 GList *l, *freebusy = NULL;
531 GError *error = NULL;
535 utc = icaltimezone_get_utc_timezone ();
536 start = time_from_isodate ("20040212T000000Z");
537 end = time_add_day_with_zone (start, 2, utc);
539 if (!e_cal_get_free_busy (client, NULL, start, end, &freebusy, &error)) {
540 cl_printf (client, "Test free/busy : Could not retrieve free busy information : %s\n", error->message);
541 return error->message;
544 cl_printf (client, "Printing free busy information\n");
545 for (l = freebusy; l; l = l->next) {
547 ECalComponent *comp = E_CAL_COMPONENT (l->data);
549 comp_string = e_cal_component_get_as_string (comp);
550 cl_printf (client, "%s\n\n", comp_string);
551 g_object_unref (comp);
552 g_free (comp_string);
556 cl_printf (client, "free_busy was returned but NULL");
562 test_get_default_object (ECal *client)
564 icalcomponent *icalcomp;
565 GError *error = NULL;
567 if (e_cal_get_default_object (client, &icalcomp, &error)) {
568 ical_string = icalcomponent_as_ical_string_r (icalcomp);
569 cl_printf (client, "Obtained default object: %s\n", ical_string);
570 g_free (ical_string);
575 cl_printf (client, "Test Get default object : Could not get the default object: %s\n", error->message);
576 return error->message;
579 /* XXX The string pasted below is *really* ugly. Alternatively, it could be
580 * read from a file at run-time. Not sure if it is an elegant solution when
581 * multiple clients try to load the same file during stress testing.
582 * how can this be done better ?
586 UID : 20040213T055519Z - 15802 - 500 - 1 - 3@testcal\
587 DTSTAMP : 20040213T055519Z\
588 DTSTART; TZID=/softwarestudio.org / Olson_20011030_5 / Asia / Calcutta:\
590 DTEND; TZID=/softwarestudio.org / Olson_20011030_5 / Asia / Calcutta:\
594 SUMMARY : Test - Travel plans to Kansas\
595 LOCATION : Yellow Brick road\
597 ORGANIZER; CN = dorothy : MAILTO : dorothy@oz\
598 DESCRIPTION: Discuss way to home\
599 ATTENDEE; CUTYPE = INDIVIDUAL; ROLE = REQ - PARTICIPANT; PARTSTAT = ACCEPTED;\
600 RSVP = TRUE; CN = dorothy; LANGUAGE = en : MAILTO : dorothy@oz\
601 ATTENDEE; CUTYPE = INDIVIDUAL; ROLE = REQ - PARTICIPANT; PARTSTAT = NEEDS - ACTION;\
602 RSVP = TRUE; CN = tinman; LANGUAGE = en : MAILTO : tinman@oz\
603 ATTENDEE; CUTYPE = INDIVIDUAL; ROLE = REQ - PARTICIPANT; PARTSTAT = NEEDS - ACTION;\
604 RSVP = TRUE; CN = toto; LANGUAGE = en : MAILTO : toto@oz\
605 ATTENDEE; CUTYPE = INDIVIDUAL; ROLE = OPT - PARTICIPANT; PARTSTAT = NEEDS - ACTION;\
606 RSVP = TRUE; CN = scarecrow; LANGUAGE = en : MAILTO : scarecrow@oz\
607 LAST - MODIFIED : 20040213T055647Z\
611 test_get_object (ECal *client)
613 const gchar *uid = "20040213T055519Z-15802-500-1-3@testcal";
615 icalcomponent *icalcomp;
617 GError *error = NULL;
619 if (!e_cal_get_object (client, uid, NULL, &icalcomp, &error)) {
620 cl_printf (client, "Test Get object : Could not get the object: %s\n", error->message);
621 return error->message;
624 actual = icalcomponent_as_ical_string_r (icalcomp);
625 compare = !strcmp (actual, EXPECTED);
629 mu_assert ("Test : get_object does not match the expected output", compare);
634 test_timezones (ECal *client)
637 GError *error = NULL;
638 if (!e_cal_get_timezone (client, "UTC", &zone, &error))
640 cl_printf (client, "Could not get the timezone\n");
643 printf ("\n\nTime Zones : \n%s *** %s", icaltimezone_get_display_name (zone), icaltimezone_get_tzid (zone));
644 printf ("\n\nTime Zones : \n%s", icaltimezone_get_location (zone));
650 all_tests (ECal *client,
655 mu_run_test (test_new_system_calendar ());
656 mu_run_test (test_new_system_tasks ());
657 mu_run_test (test_new_system_memos ());
658 mu_run_test (test_set_uri (client, uri));
659 mu_run_test (test_get_source (client, uri));
660 mu_run_test (test_cal_loaded (client));
662 /* test_query acts on pre-loaded data. Hence it must executed before
663 * any writes are made */
664 mu_run_test (test_query (client, "(contains? \"any\" \"test\")", 2));
665 mu_run_test (test_query (client, "(contains? \"summary\" \"Kansas\")", 1));
666 mu_run_test (test_query (client, "(contains? \"any\" \"gibberish\")", 0));
668 mu_run_test (test_get_default_object (client));
669 mu_run_test (test_get_object (client));
670 mu_run_test (test_get_free_busy (client));
671 mu_run_test (test_object_creation (client, &uid));
672 mu_run_test (test_object_modification (client, uid));
673 /* mu_run_test (test_object_removal (client)); */
674 mu_run_test (test_get_alarms_in_range (client));
677 tmp = g_strconcat (uri, "_tmp", NULL);
678 mu_run_test (test_e_cal_new (&ecal, tmp));
679 mu_run_test (test_e_cal_remove (ecal, tmp));
683 test_timezones (client);
688 /* Creates a calendar client and tries to load the specified URI into it */
690 create_client (ECal **client,
693 gboolean only_if_exists)
695 const gchar *results;
698 GError *error = NULL;
700 cal_uri = g_strconcat ("file://", uri, NULL);
701 *client = e_cal_new_from_uri (cal_uri, type);
703 g_message (G_STRLOC ": could not create the client");
707 g_object_weak_ref (G_OBJECT (*client), client_destroy_cb, NULL);
709 cl_printf (*client, "Calendar loading `%s'...\n", uri);
711 if (!e_cal_open (*client, only_if_exists, &error)) {
712 cl_printf (*client, "Load/create %s\n", error->message);
715 g_clear_error (&error);
717 if (!e_cal_get_query (*client, "(contains? \"any\" \"Event\")", &query, NULL)) {
718 cl_printf (*client, G_STRLOC ": Unable to obtain query");
722 g_signal_connect (G_OBJECT (query), "objects_added",
723 G_CALLBACK (objects_added_cb), client);
724 g_signal_connect (G_OBJECT (query), "objects_modified",
725 G_CALLBACK (objects_modified_cb), client);
726 g_signal_connect (G_OBJECT (query), "objects_removed",
727 G_CALLBACK (objects_removed_cb), client);
728 g_signal_connect (G_OBJECT (query), "view_complete",
729 G_CALLBACK (view_complete_cb), client);
731 e_cal_view_start (query);
733 results = all_tests (*client, uri);
734 cl_printf (*client, "\n\n\n*************Tests run: %d****************\n\n", tests_run);
735 cl_printf (*client, "*************Tests passed: %d*************\n\n\n", tests_passed);
737 cl_printf (*client, "***Failures********%s\n", results);
739 cl_printf (*client, "dump of the test calendar data");
750 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
751 textdomain (GETTEXT_PACKAGE);
754 loop = g_main_loop_new (NULL, TRUE);
756 /* arg1- file name; arg2- client suffix */
757 uri = g_strconcat (argv[1], argv[2], NULL);
758 create_client (&client1, uri, E_CAL_SOURCE_TYPE_EVENT, FALSE);
761 g_main_loop_run (loop);