[evolution-data-server] I#194 - e-cal-recur: Incorrect timezone used for DTEND from DURATION



commit 80072aea88235e1cfe2223d8d5c7d9605700a71f
Author: Milan Crha <mcrha redhat com>
Date:   Tue Feb 25 11:40:26 2020 +0100

    I#194 - e-cal-recur: Incorrect timezone used for DTEND from DURATION
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/194

 src/calendar/libecal/e-cal-recur.c |   6 ++
 tests/libecal/test-cal-recur.c     | 115 +++++++++++++++++++++++++++++++++++++
 2 files changed, 121 insertions(+)
---
diff --git a/src/calendar/libecal/e-cal-recur.c b/src/calendar/libecal/e-cal-recur.c
index 52613cb18..98a5715e6 100644
--- a/src/calendar/libecal/e-cal-recur.c
+++ b/src/calendar/libecal/e-cal-recur.c
@@ -227,6 +227,12 @@ ensure_timezone (ICalComponent *comp,
                prop = i_cal_component_get_first_property (comp, prop_kind);
        else
                g_object_ref (prop);
+
+       /* DTEND can be computed from DTSTART and DURATION, thus use TZID from DTSTART,
+          in case DTEND is not present. */
+       if (!prop && prop_kind == I_CAL_DTEND_PROPERTY)
+               prop = i_cal_component_get_first_property (comp, I_CAL_DTSTART_PROPERTY);
+
        if (!prop)
                return TRUE;
 
diff --git a/tests/libecal/test-cal-recur.c b/tests/libecal/test-cal-recur.c
index ec951e065..6948ac064 100644
--- a/tests/libecal/test-cal-recur.c
+++ b/tests/libecal/test-cal-recur.c
@@ -480,6 +480,114 @@ test_recur_exdate (ETestServerFixture *fixture,
        );
 }
 
+typedef struct _DurationData {
+       gint n_found;
+       gint expected_duration;
+} DurationData;
+
+static gboolean
+duration_got_instance_cb (ICalComponent *icomp,
+                         ICalTime *instance_start,
+                         ICalTime *instance_end,
+                         gpointer user_data,
+                         GCancellable *cancellable,
+                         GError **error)
+{
+       DurationData *dd = user_data;
+       ICalDuration *dur;
+
+       dd->n_found++;
+
+       dur = i_cal_component_get_duration (icomp);
+       g_assert_nonnull (dur);
+       g_assert_cmpint (i_cal_duration_as_int (dur), ==, dd->expected_duration);
+       g_assert_cmpint (i_cal_time_as_timet (instance_end) - i_cal_time_as_timet (instance_start), ==, 
dd->expected_duration);
+
+       g_object_unref (dur);
+
+       return TRUE;
+}
+
+static void
+test_recur_duration (ETestServerFixture *fixture,
+                    gconstpointer user_data)
+{
+       ICalComponent *comp;
+       ICalDuration *dur;
+       ICalTime *start, *end;
+       DurationData dd;
+       gboolean success;
+       GError *error = NULL;
+
+       comp = i_cal_component_new_from_string (
+               "BEGIN:VEVENT\n"
+               "UID:1\n"
+               "DTSTART;TZID=Australia/Melbourne:20200212T100000\n"
+               "DURATION:PT30M\n"
+               "CREATED:20200212T111400Z\n"
+               "DTSTAMP:20200212T111400Z\n"
+               "SUMMARY:With duration\n"
+               "RRULE:FREQ=WEEKLY\n"
+               "END:VEVENT\n"
+       );
+
+       g_assert_nonnull (comp);
+
+       start = i_cal_time_new_from_string ("20200201T000000Z");
+       end = i_cal_time_new_from_string ("20200331T235959Z");
+
+       g_assert_nonnull (start);
+       g_assert_nonnull (end);
+
+       dur = i_cal_component_get_duration (comp);
+       g_assert_nonnull (dur);
+
+       dd.expected_duration = i_cal_duration_as_int (dur);
+       g_object_unref (dur);
+
+       g_assert_cmpint (dd.expected_duration, ==, 30 * 60);
+
+       dd.n_found = 0;
+
+       success = e_cal_recur_generate_instances_sync (comp, start, end,
+               duration_got_instance_cb, &dd,
+               lookup_tzid_cb, NULL,
+               i_cal_timezone_get_builtin_timezone ("Australia/Melbourne"),
+               NULL, &error);
+
+       g_assert_no_error (error);
+       g_assert (success);
+       g_assert_cmpint (dd.n_found, ==, 8);
+
+       dd.n_found = 0;
+
+       success = e_cal_recur_generate_instances_sync (comp, start, end,
+               duration_got_instance_cb, &dd,
+               lookup_tzid_cb, NULL,
+               i_cal_timezone_get_builtin_timezone ("Europe/Berlin"),
+               NULL, &error);
+
+       g_assert_no_error (error);
+       g_assert (success);
+       g_assert_cmpint (dd.n_found, ==, 8);
+
+       dd.n_found = 0;
+
+       success = e_cal_recur_generate_instances_sync (comp, start, end,
+               duration_got_instance_cb, &dd,
+               lookup_tzid_cb, NULL,
+               i_cal_timezone_get_builtin_timezone ("America/New_York"),
+               NULL, &error);
+
+       g_assert_no_error (error);
+       g_assert (success);
+       g_assert_cmpint (dd.n_found, ==, 8);
+
+       g_object_unref (start);
+       g_object_unref (end);
+       g_object_unref (comp);
+}
+
 gint
 main (gint argc,
       gchar **argv)
@@ -508,6 +616,13 @@ main (gint argc,
                e_test_server_utils_setup,
                test_recur_exdate,
                e_test_server_utils_teardown);
+       g_test_add (
+               "/ECalRecur/Duration",
+               ETestServerFixture,
+               &test_closure,
+               e_test_server_utils_setup,
+               test_recur_duration,
+               e_test_server_utils_teardown);
 
        return e_test_server_utils_run ();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]