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, const gchar *format, ...)
52 va_start (args, format);
53 if ( client != client1)
55 printf ("Client %s: ", "Test");
56 vprintf (format, args);
61 objects_added_cb (GObject *object, GList *objects, gpointer data)
65 for (l = objects; l; l = l->next)
66 cl_printf (data, "Object added %s\n", icalcomponent_get_uid (l->data));
70 objects_modified_cb (GObject *object, GList *objects, gpointer data)
74 for (l = objects; l; l = l->next)
75 cl_printf (data, "Object modified %s\n", icalcomponent_get_uid (l->data));
79 objects_removed_cb (GObject *object, GList *objects, gpointer data)
83 for (l = objects; l; l = l->next)
84 cl_printf (data, "Object removed %s\n", icalcomponent_get_uid (l->data));
88 view_complete_cb (GObject *object, ECalendarStatus status, const gchar *error_msg, gpointer data)
90 cl_printf (data, "View complete (status:%d, error_msg:%s)\n", status, error_msg ? error_msg : "NULL");
94 list_uids (ECal *client)
96 GList *objects = NULL;
99 if (!e_cal_get_object_list (client, "(contains? \"any\" \"test\")", &objects, NULL))
102 cl_printf (client, "UIDS: ");
104 cl_printf (client, "\nGot %d objects\n", g_list_length (objects));
108 for (l = objects; l; l = l->next) {
111 uid = icalcomponent_get_uid (l->data);
112 printf ("`%s' ", uid);
117 for (l = objects; l; l = l->next) {
118 gchar *obj = icalcomponent_as_ical_string_r (l->data);
119 printf ("------------------------------\n");
121 printf ("------------------------------\n");
126 e_cal_free_object_list (objects);
131 /* Callback used when a client is destroyed */
133 client_destroy_cb (gpointer data, GObject *object)
135 if (E_CAL (object) == client1)
137 else if (E_CAL (object) == client2)
140 if (!client1 && !client2)
141 g_main_loop_quit (loop);
145 test_object_creation (ECal *client, gchar **uid)
147 ECalComponent *comp, *comp_retrieved;
148 icalcomponent *icalcomp, *icalcomp_retrieved;
149 struct icaltimetype tt;
150 ECalComponentText text;
151 ECalComponentDateTime dt;
152 ECalComponentTransparency transp;
154 GError *error = NULL;
156 comp = e_cal_component_new ();
158 e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT);
159 text.value = "Creation of new test event";
161 e_cal_component_set_summary (comp, &text);
162 tt = icaltime_from_string ("20040109T090000Z");
165 e_cal_component_set_dtstart (comp, &dt);
166 tt = icaltime_from_string ("20040109T103000");
169 e_cal_component_set_dtend (comp, &dt);
170 e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_OPAQUE);
172 e_cal_component_commit_sequence (comp);
173 icalcomp = e_cal_component_get_icalcomponent (comp);
174 if (!e_cal_create_object (client, icalcomp, uid, &error)) {
175 cl_printf (client, "Object creation: %s\n", error->message);
178 return "Test Object Creation failed";
180 e_cal_component_commit_sequence (comp);
181 if (!e_cal_get_object (client, *uid, NULL, &icalcomp_retrieved, &error)) {
182 cl_printf (client, "Object retrieval: %s\n", error->message);
186 return "Test Object Creation failed";
190 comp_retrieved = e_cal_component_new ();
191 if (!e_cal_component_set_icalcomponent (comp_retrieved, icalcomp_retrieved)) {
192 cl_printf (client, "Could not set icalcomponent\n");
196 g_free (icalcomp_retrieved);
197 return "Test Object Creation failed";
200 /* Dumping icalcomp into a string is not useful as the retrieved object
201 * has some generated information like timestamps. We compare
202 * member values we set during creation*/
203 compare = e_cal_component_event_dates_match (comp, comp_retrieved);
206 e_cal_component_get_transparency (comp_retrieved, &transp);
207 compare = (transp == E_CAL_COMPONENT_TRANSP_OPAQUE);
210 g_free (comp_retrieved);
213 g_free (icalcomp_retrieved);
215 mu_assert ("Test Object creation : Created object does not match retrieved data\n", compare);
220 test_object_modification (ECal *client, gchar *uid)
222 const gchar *summary = "This summary was modified";
223 icalcomponent *icalcomp, *icalcomp_modified;
225 GError *error = NULL;
227 if (!e_cal_get_object (client, uid, NULL, &icalcomp, &error)) {
228 cl_printf (client, "Test Modify object : Could not get the object: %s\n", error->message);
230 return error->message;
233 /* Modify one property of the icalcomp and save it.
234 * Now retrieve it and check the field. */
235 icalcomponent_set_summary (icalcomp, summary);
236 if (!e_cal_modify_object (client, icalcomp, CALOBJ_MOD_THIS, &error)) {
237 cl_printf (client, "Test Modify object : Could not modify the object: %s\n", error->message);
240 return error->message;
243 if (!e_cal_get_object (client, uid, NULL, &icalcomp_modified, &error)) {
244 cl_printf (client, "Test Modify object : Could not get the modified object: %s\n", error->message);
247 return "Test Object Creation failed";
250 compare = !strcmp ( icalcomponent_get_summary (icalcomp_modified), summary);
254 g_free (icalcomp_modified);
256 mu_assert ("Test Modify object : Modification failed\n", compare);
262 test_object_removal (ECal *client)
267 icalcomponent *icalcomp;
268 gboolean compare = 1;
269 GError *error = NULL;
271 comp = e_cal_component_new ();
272 e_cal_component_commit_sequence (comp);
273 icalcomp = e_cal_component_get_icalcomponent (comp);
274 if (!e_cal_create_object (client, icalcomp, &uid, &error)) {
275 cl_printf (client, "Test object removal - Object creation: %s\n", error->message);
276 g_object_unref (comp);
277 g_object_unref (icalcomp);
278 return "Test Object Removal failed\n";
281 if (!e_cal_remove_object (client, uid, &error)) {
282 cl_printf (client, "Test object removal - Could not remove the object\n");
284 g_object_unref (comp);
285 g_object_unref (icalcomp);
286 return "Test Object Removal failed\n";
290 compare = e_cal_get_object (client, uid, NULL, &icalcomp, &error);
293 g_object_unref (comp);
294 g_object_unref (icalcomp);
296 mu_assert ("Test object removal - Failed\n", compare);
302 test_get_alarms_in_range (ECal *client)
309 utc = icaltimezone_get_utc_timezone ();
310 start = time_from_isodate ("20040212T000000Z");
311 end = time_add_day_with_zone (start, 2, utc);
313 alarms = e_cal_get_alarms_in_range (client, start, end);
314 compare = (g_slist_length (alarms) == 3);
316 e_cal_free_alarms (alarms);
317 mu_assert ("Test getting alarms in range\n", compare);
323 test_set_uri (ECal *client, const gchar *uri)
325 /* The uri is set as part of create_client call. This method merely
326 * verifies it was done correctly.
329 gboolean compare = 0;
330 cal_uri = g_strconcat ("file://", uri, NULL);
331 compare = !strcmp (e_cal_get_uri (client), cal_uri);
334 mu_assert ("Test set_uri : uri was not set correctly\n", compare);
340 test_cal_loaded (ECal *client)
342 /* Test one loaded calendar and another that is not loaded. */
343 mu_assert ("Test get_cal_load_state : Failed \n",
344 (E_CAL_LOAD_LOADED == e_cal_get_load_state (client)) &&
345 (E_CAL_LOAD_NOT_LOADED == e_cal_get_load_state (NULL)));
351 test_get_source (ECal *client, const gchar *expected)
356 gboolean compare = 0;
358 source = e_cal_get_source (client);
359 uri = e_source_get_uri (source);
360 cal_uri = g_strconcat ("file://", expected, NULL);
361 compare = !strcmp (expected, uri);
364 mu_assert ("Test get_source : Failed\n", compare);
370 test_query (ECal *client, const gchar *query, gint expected)
372 /* This uses pre-loaded data. Hence its results are valid only
373 * when called before any write operation is performed.
376 GList *objects = NULL;
378 if (!e_cal_get_object_list (client, query, &objects, NULL))
379 return "Could not get the list of objects";
380 i = g_list_length (objects);
381 e_cal_free_object_list (objects);
383 mu_assert ("Test get_object_list : Expected number of objects not found", i == expected);
390 test_e_cal_new (ECal **cal, const gchar *uri)
392 GError *error = NULL;
393 gchar *cal_uri, *cal_file;
394 gboolean created = 0;
396 cal_uri = g_strconcat ("file://", uri, NULL);
397 *cal = e_cal_new_from_uri (cal_uri, E_CAL_SOURCE_TYPE_EVENT);
399 g_message (G_STRLOC ": could not create the client");
401 return "Test Creation of new calendar : Failed";
403 g_object_weak_ref (G_OBJECT (*cal), client_destroy_cb, NULL);
405 cl_printf (*cal, "Calendar loading `%s'...\n", uri);
407 if (!e_cal_open (*cal, FALSE, &error)) {
408 cl_printf (*cal, "Load/create %s\n", error->message);
410 return "Test creation of new calendar : Failed";
413 cal_file = g_strconcat (uri, "/calendar.ics", NULL);
415 created = g_file_test (cal_file, G_FILE_TEST_EXISTS);
419 mu_assert ("Test creation of new calendar : Failed", created);
425 test_e_cal_remove (ECal *ecal, const gchar *uri)
428 GError *error = NULL;
429 gboolean removed = 0;
431 cal_uri = g_strconcat (uri, "/calendar.ics", NULL);
432 if (!e_cal_remove (ecal, &error)) {
433 cl_printf (ecal, "Test Calendar removal : Could not remove the Calendar : %s\n", error->message);
436 removed = !g_file_test (uri, G_FILE_TEST_EXISTS);
439 mu_assert ("Test Remove calendar : Failed ", removed);
446 test_new_system_calendar (void)
448 const gchar *user_data_dir;
452 e_cal_new_system_calendar ();
454 user_data_dir = e_get_user_data_dir ();
455 filename = g_build_filename (
456 user_data_dir, "calendar", "system", "calendar.ics", NULL);
457 created = g_file_test (filename, G_FILE_TEST_EXISTS);
460 mu_assert ("Test creation of default system calendar : Failed", created);
466 test_new_system_tasks (void)
468 const gchar *user_data_dir;
472 e_cal_new_system_tasks ();
474 user_data_dir = e_get_user_data_dir ();
475 filename = g_build_filename (
476 user_data_dir, "tasks", "system", "tasks.ics", NULL);
477 created = g_file_test (filename, G_FILE_TEST_EXISTS);
480 mu_assert ("Test creation of default system tasks : Failed", created);
486 test_new_system_memos (void)
488 const gchar *user_data_dir;
492 e_cal_new_system_memos ();
494 user_data_dir = e_get_user_data_dir ();
495 filename = g_build_filename (
496 user_data_dir, "memos", "system", "journal.ics", NULL);
497 created = g_file_test (filename, G_FILE_TEST_EXISTS);
500 mu_assert ("Test creation of default system memos : Failed", created);
506 test_get_free_busy (ECal *client)
508 /* TODO uses NULL for users and currently specific to file backend. */
509 GList *l, *freebusy = NULL;
510 GError *error = NULL;
514 utc = icaltimezone_get_utc_timezone ();
515 start = time_from_isodate ("20040212T000000Z");
516 end = time_add_day_with_zone (start, 2, utc);
518 if (!e_cal_get_free_busy (client, NULL, start, end, &freebusy, &error)) {
519 cl_printf (client, "Test free/busy : Could not retrieve free busy information : %s\n", error->message);
520 return error->message;
523 cl_printf (client, "Printing free busy information\n");
524 for (l = freebusy; l; l = l->next) {
526 ECalComponent *comp = E_CAL_COMPONENT (l->data);
528 comp_string = e_cal_component_get_as_string (comp);
529 cl_printf (client, "%s\n\n", comp_string);
530 g_object_unref (comp);
531 g_free (comp_string);
535 cl_printf (client, "free_busy was returned but NULL");
541 test_get_default_object (ECal *client)
543 icalcomponent *icalcomp;
544 GError *error = NULL;
546 if (e_cal_get_default_object (client, &icalcomp, &error)) {
547 ical_string = icalcomponent_as_ical_string_r (icalcomp);
548 cl_printf (client, "Obtained default object: %s\n", ical_string);
549 g_free (ical_string);
554 cl_printf (client, "Test Get default object : Could not get the default object: %s\n", error->message);
555 return error->message;
558 /* XXX The string pasted below is *really* ugly. Alternatively, it could be
559 * read from a file at run-time. Not sure if it is an elegant solution when
560 * multiple clients try to load the same file during stress testing.
561 * how can this be done better ?
565 UID:20040213T055519Z-15802-500-1-3@testcal\
566 DTSTAMP:20040213T055519Z\
567 DTSTART;TZID=/softwarestudio.org/Olson_20011030_5/Asia/Calcutta:\
569 DTEND;TZID=/softwarestudio.org/Olson_20011030_5/Asia/Calcutta:\
573 SUMMARY:Test - Travel plans to Kansas\
574 LOCATION:Yellow Brick road\
576 ORGANIZER;CN=dorothy:MAILTO:dorothy@oz\
577 DESCRIPTION: Discuss way to home\
578 ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;\
579 RSVP=TRUE;CN=dorothy;LANGUAGE=en:MAILTO:dorothy@oz\
580 ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;\
581 RSVP=TRUE;CN=tinman;LANGUAGE=en:MAILTO:tinman@oz\
582 ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;\
583 RSVP=TRUE;CN=toto;LANGUAGE=en:MAILTO:toto@oz\
584 ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=OPT-PARTICIPANT;PARTSTAT=NEEDS-ACTION;\
585 RSVP=TRUE;CN=scarecrow;LANGUAGE=en:MAILTO:scarecrow@oz\
586 LAST-MODIFIED:20040213T055647Z\
590 test_get_object (ECal *client)
592 const gchar *uid = "20040213T055519Z-15802-500-1-3@testcal";
594 icalcomponent *icalcomp;
596 GError *error = NULL;
598 if (!e_cal_get_object (client, uid, NULL, &icalcomp, &error)) {
599 cl_printf (client, "Test Get object : Could not get the object: %s\n", error->message);
600 return error->message;
603 actual = icalcomponent_as_ical_string_r (icalcomp);
604 compare = !strcmp (actual, EXPECTED);
608 mu_assert ("Test : get_object does not match the expected output", compare);
613 test_timezones (ECal *client)
616 GError *error = NULL;
617 if (!e_cal_get_timezone (client, "UTC", &zone, &error))
619 cl_printf (client, "Could not get the timezone\n");
622 printf ("\n\nTime Zones : \n%s *** %s", icaltimezone_get_display_name (zone), icaltimezone_get_tzid (zone));
623 printf ("\n\nTime Zones : \n%s", icaltimezone_get_location (zone));
629 all_tests (ECal *client, const gchar *uri)
633 mu_run_test (test_new_system_calendar ());
634 mu_run_test (test_new_system_tasks ());
635 mu_run_test (test_new_system_memos ());
636 mu_run_test (test_set_uri (client, uri));
637 mu_run_test (test_get_source (client, uri));
638 mu_run_test (test_cal_loaded (client));
640 /* test_query acts on pre-loaded data. Hence it must executed before
641 * any writes are made */
642 mu_run_test (test_query (client, "(contains? \"any\" \"test\")", 2));
643 mu_run_test (test_query (client, "(contains? \"summary\" \"Kansas\")", 1));
644 mu_run_test (test_query (client, "(contains? \"any\" \"gibberish\")", 0));
646 mu_run_test (test_get_default_object (client));
647 mu_run_test (test_get_object (client));
648 mu_run_test (test_get_free_busy (client));
649 mu_run_test (test_object_creation (client, &uid));
650 mu_run_test (test_object_modification (client, uid));
651 /* mu_run_test (test_object_removal (client)); */
652 mu_run_test (test_get_alarms_in_range (client));
655 tmp = g_strconcat (uri, "_tmp", NULL);
656 mu_run_test (test_e_cal_new (&ecal, tmp));
657 mu_run_test (test_e_cal_remove (ecal, tmp));
661 test_timezones (client);
666 /* Creates a calendar client and tries to load the specified URI into it */
668 create_client (ECal **client, const gchar *uri, ECalSourceType type, gboolean only_if_exists)
670 const gchar *results;
673 GError *error = NULL;
675 cal_uri = g_strconcat ("file://", uri, NULL);
676 *client = e_cal_new_from_uri (cal_uri, type);
678 g_message (G_STRLOC ": could not create the client");
682 g_object_weak_ref (G_OBJECT (*client), client_destroy_cb, NULL);
684 cl_printf (*client, "Calendar loading `%s'...\n", uri);
686 if (!e_cal_open (*client, only_if_exists, &error)) {
687 cl_printf (*client, "Load/create %s\n", error->message);
690 g_clear_error (&error);
692 if (!e_cal_get_query (*client, "(contains? \"any\" \"Event\")", &query, NULL)) {
693 cl_printf (*client, G_STRLOC ": Unable to obtain query");
697 g_signal_connect (G_OBJECT (query), "objects_added",
698 G_CALLBACK (objects_added_cb), client);
699 g_signal_connect (G_OBJECT (query), "objects_modified",
700 G_CALLBACK (objects_modified_cb), client);
701 g_signal_connect (G_OBJECT (query), "objects_removed",
702 G_CALLBACK (objects_removed_cb), client);
703 g_signal_connect (G_OBJECT (query), "view_complete",
704 G_CALLBACK (view_complete_cb), client);
706 e_cal_view_start (query);
708 results = all_tests (*client, uri);
709 cl_printf (*client, "\n\n\n*************Tests run: %d****************\n\n", tests_run);
710 cl_printf (*client, "*************Tests passed: %d*************\n\n\n", tests_passed);
712 cl_printf (*client, "***Failures********%s\n", results);
714 cl_printf (*client, "dump of the test calendar data");
721 main (gint argc, gchar **argv)
724 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
725 textdomain (GETTEXT_PACKAGE);
728 loop = g_main_loop_new (NULL, TRUE);
730 /* arg1- file name; arg2- client suffix */
731 uri = g_strconcat (argv[1], argv[2], NULL);
732 create_client (&client1, uri, E_CAL_SOURCE_TYPE_EVENT, FALSE);
735 g_main_loop_run (loop);