[evolution-data-server] I#295 - Calendar: Use ACKNOWLEDGED VALARM property



commit e4d70bcc918b0fbc735953608df671ccc1ab3940
Author: Milan Crha <mcrha redhat com>
Date:   Tue Feb 9 15:01:04 2021 +0100

    I#295 - Calendar: Use ACKNOWLEDGED VALARM property
    
    Touches the 'file' and the 'CalDAV' backends, storing the current time
    when the reminder had been dismissed. The reminder watcher ignores
    any reminders, which are scheduled before the acknowledged time.
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/295

 .../backends/caldav/e-cal-backend-caldav.c         | 58 +++++++++++++++
 src/calendar/backends/file/e-cal-backend-file.c    | 81 +++++++++++++++++++++
 src/calendar/libecal/e-cal-component-alarm.c       | 83 ++++++++++++++++++++++
 src/calendar/libecal/e-cal-component-alarm.h       |  8 +++
 src/calendar/libecal/e-cal-component.c             |  2 +-
 src/calendar/libecal/e-cal-util.c                  | 46 ++++++++++++
 src/calendar/libecal/e-cal-util.h                  |  4 ++
 src/calendar/libecal/e-reminder-watcher.c          | 41 ++++++++++-
 tests/libecal/test-cal-component.c                 | 41 ++++++++---
 9 files changed, 353 insertions(+), 11 deletions(-)
---
diff --git a/src/calendar/backends/caldav/e-cal-backend-caldav.c 
b/src/calendar/backends/caldav/e-cal-backend-caldav.c
index 0a1edca45..5f2c9bbad 100644
--- a/src/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/src/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -2233,6 +2233,63 @@ ecb_caldav_get_free_busy_sync (ECalBackendSync *sync_backend,
                users, start, end, out_freebusy, error);
 }
 
+static void
+ecb_caldav_discard_alarm_sync (ECalBackendSync *sync_backend,
+                              EDataCal *cal,
+                              GCancellable *cancellable,
+                              const gchar *uid,
+                              const gchar *rid,
+                              const gchar *auid,
+                              ECalOperationFlags opflags,
+                              GError **error)
+{
+       ECalComponent *comp = NULL;
+       ECalCache *cache;
+
+       g_return_if_fail (E_IS_CAL_BACKEND_CALDAV (sync_backend));
+       g_return_if_fail (uid != NULL);
+
+       cache = e_cal_meta_backend_ref_cache (E_CAL_META_BACKEND (sync_backend));
+
+       if (cache) {
+               GError *local_error = NULL;
+
+               if (!e_cal_cache_get_component (cache, uid, rid, &comp, cancellable, &local_error) && rid && 
*rid) {
+                       if (!e_cal_cache_get_component (cache, uid, NULL, &comp, cancellable, NULL)) {
+                               g_propagate_error (error, local_error);
+                               g_object_unref (cache);
+                               return;
+                       }
+
+                       rid = NULL;
+               }
+       }
+
+       if (comp) {
+               if (e_cal_util_set_alarm_acknowledged (comp, auid, 0)) {
+                       GSList *calobjs, *old_components = NULL, *new_components = NULL;
+
+                       calobjs = g_slist_prepend (NULL, e_cal_component_get_as_string (comp));
+
+                       e_cal_backend_sync_modify_objects (sync_backend, cal, cancellable, calobjs,
+                               (rid && *rid) ? E_CAL_OBJ_MOD_THIS : E_CAL_OBJ_MOD_ALL,
+                               opflags, &old_components, &new_components, error);
+
+                       e_util_free_nullable_object_slist (old_components);
+                       e_util_free_nullable_object_slist (new_components);
+                       g_slist_free_full (calobjs, g_free);
+               } else {
+                       g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND));
+               }
+
+               g_object_unref (comp);
+       } else {
+               g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND));
+       }
+
+       g_clear_object (&cache);
+}
+
 static gchar *
 ecb_caldav_get_backend_property (ECalBackend *backend,
                                 const gchar *prop_name)
@@ -2422,6 +2479,7 @@ e_cal_backend_caldav_class_init (ECalBackendCalDAVClass *klass)
        cal_backend_sync_class = E_CAL_BACKEND_SYNC_CLASS (klass);
        cal_backend_sync_class->refresh_sync = ecb_caldav_refresh_sync;
        cal_backend_sync_class->get_free_busy_sync = ecb_caldav_get_free_busy_sync;
+       cal_backend_sync_class->discard_alarm_sync = ecb_caldav_discard_alarm_sync;
 
        cal_backend_class = E_CAL_BACKEND_CLASS (klass);
        cal_backend_class->impl_get_backend_property = ecb_caldav_get_backend_property;
diff --git a/src/calendar/backends/file/e-cal-backend-file.c b/src/calendar/backends/file/e-cal-backend-file.c
index 9fbbc0a5b..617ac2975 100644
--- a/src/calendar/backends/file/e-cal-backend-file.c
+++ b/src/calendar/backends/file/e-cal-backend-file.c
@@ -2844,6 +2844,86 @@ e_cal_backend_file_modify_objects (ECalBackendSync *backend,
                *new_components = g_slist_reverse (*new_components);
 }
 
+static void
+e_cal_backend_file_discard_alarm_sync (ECalBackendSync *backend,
+                                      EDataCal *cal,
+                                      GCancellable *cancellable,
+                                      const gchar *uid,
+                                      const gchar *rid,
+                                      const gchar *auid,
+                                      ECalOperationFlags opflags,
+                                      GError **error)
+{
+       ECalBackendFile *cbfile;
+       ECalBackendFilePrivate *priv;
+       ECalBackendFileObject *obj_data;
+       ECalComponent *comp = NULL;
+
+       cbfile = E_CAL_BACKEND_FILE (backend);
+       priv = cbfile->priv;
+
+       if (priv->vcalendar == NULL) {
+               g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND));
+               return;
+       }
+
+       g_return_if_fail (uid != NULL);
+       g_return_if_fail (priv->comp_uid_hash != NULL);
+
+       g_rec_mutex_lock (&priv->idle_save_rmutex);
+
+       obj_data = g_hash_table_lookup (priv->comp_uid_hash, uid);
+       if (!obj_data) {
+               g_rec_mutex_unlock (&priv->idle_save_rmutex);
+               g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND));
+               return;
+       }
+
+       if (rid && *rid) {
+               comp = g_hash_table_lookup (obj_data->recurrences, rid);
+
+               if (comp) {
+                       g_object_ref (comp);
+               } else if (obj_data->full_object) {
+                       ICalComponent *icomp;
+                       ICalTime *itt;
+
+                       itt = i_cal_time_new_from_string (rid);
+                       icomp = e_cal_util_construct_instance (
+                               e_cal_component_get_icalcomponent (obj_data->full_object),
+                               itt);
+                       g_object_unref (itt);
+
+                       if (icomp)
+                               comp = e_cal_component_new_from_icalcomponent (icomp);
+               }
+       } else if (obj_data->full_object) {
+               comp = g_object_ref (obj_data->full_object);
+       }
+
+       if (comp) {
+               if (e_cal_util_set_alarm_acknowledged (comp, auid, 0)) {
+                       GSList *calobjs;
+
+                       calobjs = g_slist_prepend (NULL, e_cal_component_get_as_string (comp));
+
+                       e_cal_backend_file_modify_objects (backend, cal, cancellable, calobjs,
+                               (rid && *rid) ? E_CAL_OBJ_MOD_THIS : E_CAL_OBJ_MOD_ALL,
+                               opflags, NULL, NULL, error);
+
+                       g_slist_free_full (calobjs, g_free);
+               } else {
+                       g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND));
+               }
+
+               g_object_unref (comp);
+       } else {
+               g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND));
+       }
+
+       g_rec_mutex_unlock (&priv->idle_save_rmutex);
+}
+
 /**
  * Remove one and only one instance. The object may be empty
  * afterwards, in which case it will be removed completely.
@@ -3903,6 +3983,7 @@ e_cal_backend_file_class_init (ECalBackendFileClass *class)
        sync_class->get_attachment_uris_sync = e_cal_backend_file_get_attachment_uris;
        sync_class->add_timezone_sync = e_cal_backend_file_add_timezone;
        sync_class->get_free_busy_sync = e_cal_backend_file_get_free_busy;
+       sync_class->discard_alarm_sync = e_cal_backend_file_discard_alarm_sync;
 
        /* Register our ESource extension. */
        E_TYPE_SOURCE_LOCAL;
diff --git a/src/calendar/libecal/e-cal-component-alarm.c b/src/calendar/libecal/e-cal-component-alarm.c
index 52ecc2a8e..52f00def5 100644
--- a/src/calendar/libecal/e-cal-component-alarm.c
+++ b/src/calendar/libecal/e-cal-component-alarm.c
@@ -49,6 +49,7 @@ struct _ECalComponentAlarm {
        GSList *attendees; /* ECalComponentAttendee * */
        GSList *attachments; /* ICalAttach * */
        ECalComponentPropertyBag *property_bag;
+       ICalTime *acknowledged;
 };
 
 /**
@@ -185,6 +186,9 @@ e_cal_component_alarm_copy (const ECalComponentAlarm *alarm)
                alrm->attachments = g_slist_reverse (alrm->attachments);
        }
 
+       if (alarm->acknowledged)
+               e_cal_component_alarm_set_acknowledged (alrm, alarm->acknowledged);
+
        e_cal_component_property_bag_assign (alrm->property_bag, alarm->property_bag);
 
        return alrm;
@@ -215,6 +219,7 @@ e_cal_component_alarm_free (gpointer alarm)
                e_cal_component_property_bag_free (alrm->property_bag);
                g_slist_free_full (alrm->attendees, e_cal_component_attendee_free);
                g_slist_free_full (alrm->attachments, g_object_unref);
+               g_clear_object (&alrm->acknowledged);
                g_slice_free (ECalComponentAlarm, alrm);
        }
 }
@@ -248,6 +253,7 @@ e_cal_component_alarm_set_from_component (ECalComponentAlarm *alarm,
        e_cal_component_alarm_trigger_free (alarm->trigger);
        g_slist_free_full (alarm->attendees, e_cal_component_attendee_free);
        g_slist_free_full (alarm->attachments, g_object_unref);
+       g_clear_object (&alarm->acknowledged);
 
        alarm->uid = NULL;
        alarm->action = E_CAL_COMPONENT_ALARM_NONE;
@@ -346,6 +352,11 @@ e_cal_component_alarm_set_from_component (ECalComponentAlarm *alarm,
                                alarm->attendees = g_slist_prepend (alarm->attendees, attendee);
                        break;
 
+               case I_CAL_ACKNOWLEDGED_PROPERTY:
+                       g_clear_object (&alarm->acknowledged);
+                       alarm->acknowledged = i_cal_property_get_acknowledged (prop);
+                       break;
+
                case I_CAL_X_PROPERTY:
                        xname = i_cal_property_get_x_name (prop);
                        if (g_strcmp0 (xname, E_CAL_EVOLUTION_ALARM_UID_PROPERTY) == 0) {
@@ -586,6 +597,11 @@ e_cal_component_alarm_fill_component (ECalComponentAlarm *alarm,
                        i_cal_component_take_property (component, prop);
        }
 
+       if (alarm->acknowledged) {
+               prop = i_cal_property_new_acknowledged (alarm->acknowledged);
+               i_cal_component_take_property (component, prop);
+       }
+
        e_cal_component_property_bag_fill_component (alarm->property_bag, component);
 }
 
@@ -1119,3 +1135,70 @@ e_cal_component_alarm_get_property_bag (const ECalComponentAlarm *alarm)
 
        return alarm->property_bag;
 }
+
+/**
+ * e_cal_component_alarm_get_acknowledged:
+ * @alarm: an #ECalComponentAlarm
+ *
+ * Get the last time the alarm had been acknowledged, that is, when its
+ * reminder had been triggered.
+ * The returned #ICalTime is owned by @alarm and should not be modified,
+ * neither its content.
+ *
+ * Returns: (transfer none) (nullable): the @alarm acknowledged time,
+ *    or %NULL, when none is set
+ *
+ * Since: 3.40
+ **/
+ICalTime *
+e_cal_component_alarm_get_acknowledged (const ECalComponentAlarm *alarm)
+{
+       g_return_val_if_fail (alarm != NULL, NULL);
+
+       return alarm->acknowledged;
+}
+
+/**
+ * e_cal_component_alarm_set_acknowledged:
+ * @alarm: an #ECalComponentAlarm
+ * @when: (transfer none) (nullable): an #ICalTime when the @alarm
+ *    had been acknowledged, or %NULL to unset
+ *
+ * Set the acknowledged time of the @alarm. Use %NULL to unset it.
+ *
+ * Since: 3.40
+ **/
+void
+e_cal_component_alarm_set_acknowledged (ECalComponentAlarm *alarm,
+                                       const ICalTime *when)
+{
+       g_return_if_fail (alarm != NULL);
+
+       if (when != alarm->acknowledged)
+               e_cal_component_alarm_take_acknowledged (alarm, when ? i_cal_time_clone (when) : NULL);
+}
+
+/**
+ * e_cal_component_alarm_take_acknowledged:
+ * @alarm: an #ECalComponentAlarm
+ * @when: (transfer full) (nullable): an #ICalTime when the @alarm
+ *    had been acknowledged, or %NULL to unset
+ *
+ * Set the acknowledged time of the @alarm. Use %NULL to unset it.
+ * The function assumes ownership of the @when.
+ *
+ * Since: 3.40
+ **/
+void
+e_cal_component_alarm_take_acknowledged (ECalComponentAlarm *alarm,
+                                        ICalTime *when)
+{
+       g_return_if_fail (alarm != NULL);
+
+       if (when != alarm->acknowledged) {
+               g_clear_object (&alarm->acknowledged);
+               alarm->acknowledged = when;
+       } else {
+               g_clear_object (&when);
+       }
+}
diff --git a/src/calendar/libecal/e-cal-component-alarm.h b/src/calendar/libecal/e-cal-component-alarm.h
index a2a4fbe06..cb2cf021d 100644
--- a/src/calendar/libecal/e-cal-component-alarm.h
+++ b/src/calendar/libecal/e-cal-component-alarm.h
@@ -133,6 +133,14 @@ void               e_cal_component_alarm_take_attachments
 ECalComponentPropertyBag *
                e_cal_component_alarm_get_property_bag
                                                (const ECalComponentAlarm *alarm);
+ICalTime *     e_cal_component_alarm_get_acknowledged
+                                               (const ECalComponentAlarm *alarm);
+void           e_cal_component_alarm_set_acknowledged
+                                               (ECalComponentAlarm *alarm,
+                                                const ICalTime *when);
+void           e_cal_component_alarm_take_acknowledged
+                                               (ECalComponentAlarm *alarm,
+                                                ICalTime *when);
 
 G_END_DECLS
 
diff --git a/src/calendar/libecal/e-cal-component.c b/src/calendar/libecal/e-cal-component.c
index edff43f94..dafefb3bb 100644
--- a/src/calendar/libecal/e-cal-component.c
+++ b/src/calendar/libecal/e-cal-component.c
@@ -4155,7 +4155,7 @@ get_all_alarms_cb (ICalComponent *icalcomp,
  * @comp: A calendar component.
  *
  * Queries all alarm subcomponents of a calendar component.
- * Free the returned #GSList with g_slist_free_full (slist, e_cal_component_alarm_free));,
+ * Free the returned #GSList with g_slist_free_full (slist, e_cal_component_alarm_free);,
  * when no longer needed.
  *
  * Returns: (transfer full) (nullable) (element-type ECalComponentAlarm): the alarm subcomponents
diff --git a/src/calendar/libecal/e-cal-util.c b/src/calendar/libecal/e-cal-util.c
index 64c3bb54a..09121eeba 100644
--- a/src/calendar/libecal/e-cal-util.c
+++ b/src/calendar/libecal/e-cal-util.c
@@ -2950,3 +2950,49 @@ e_cal_util_inline_local_attachments_sync (ICalComponent *component,
 
        return success;
 }
+
+/**
+ * e_cal_util_set_alarm_acknowledged:
+ * @component: an #ECalComponent
+ * @auid: an alarm UID to modify
+ * @when: a time, in UTC, when to set the acknowledged property, or 0 for the current time
+ *
+ * Sets the ACKNOWLEDGED property on the @component's alarm with UID @auid
+ * to the time @when (in UTC), or to the current time, when the @when is 0.
+ *
+ * Returns: Whether succeeded.
+ *
+ * Since: 3.40
+ **/
+gboolean
+e_cal_util_set_alarm_acknowledged (ECalComponent *component,
+                                  const gchar *auid,
+                                  gint64 when)
+{
+       ECalComponentAlarm *alarm, *copy;
+       ICalTime *tt;
+
+       g_return_val_if_fail (E_IS_CAL_COMPONENT (component), FALSE);
+       g_return_val_if_fail (auid != NULL, FALSE);
+
+       alarm = e_cal_component_get_alarm (component, auid);
+
+       if (!alarm)
+               return FALSE;
+
+       if (when)
+               tt = i_cal_time_new_from_timet_with_zone (when, 0, i_cal_timezone_get_utc_timezone ());
+       else
+               tt = i_cal_time_new_current_with_zone (i_cal_timezone_get_utc_timezone ());
+
+       copy = e_cal_component_alarm_copy (alarm);
+
+       e_cal_component_alarm_take_acknowledged (copy, tt);
+       e_cal_component_remove_alarm (component, auid);
+       e_cal_component_add_alarm (component, copy);
+
+       e_cal_component_alarm_free (copy);
+       e_cal_component_alarm_free (alarm);
+
+       return TRUE;
+}
diff --git a/src/calendar/libecal/e-cal-util.h b/src/calendar/libecal/e-cal-util.h
index ece7f9419..e9bb1a65a 100644
--- a/src/calendar/libecal/e-cal-util.h
+++ b/src/calendar/libecal/e-cal-util.h
@@ -347,6 +347,10 @@ gboolean   e_cal_util_inline_local_attachments_sync
                                                (ICalComponent *component,
                                                 GCancellable *cancellable,
                                                 GError **error);
+gboolean       e_cal_util_set_alarm_acknowledged
+                                               (ECalComponent *component,
+                                                const gchar *auid,
+                                                gint64 when); /* as time_t in UTC */
 
 G_END_DECLS
 
diff --git a/src/calendar/libecal/e-reminder-watcher.c b/src/calendar/libecal/e-reminder-watcher.c
index 91b55bae0..e98972af5 100644
--- a/src/calendar/libecal/e-reminder-watcher.c
+++ b/src/calendar/libecal/e-reminder-watcher.c
@@ -881,7 +881,21 @@ e_reminder_watcher_objects_changed_thread (GTask *task,
 
                                if (alarms && e_cal_component_alarms_get_instances (alarms)) {
                                        ECalComponent *alarms_comp = e_cal_component_alarms_get_component 
(alarms);
-                                       GSList *alink, *instances;
+                                       GHashTable *acknowledged_alarms; /* alarm uid ~> ICalTime * */
+                                       GSList *alink, *instances, *all_alarms;
+
+                                       acknowledged_alarms = g_hash_table_new (g_str_hash, g_str_equal);
+                                       all_alarms = e_cal_component_get_all_alarms (alarms_comp);
+
+                                       for (alink = all_alarms; alink; alink = g_slist_next (alink)) {
+                                               ECalComponentAlarm *alarm = alink->data;
+
+                                               if (e_cal_component_alarm_get_acknowledged (alarm)) {
+                                                       g_hash_table_insert (acknowledged_alarms,
+                                                               (gpointer) e_cal_component_alarm_get_uid 
(alarm),
+                                                               e_cal_component_alarm_get_acknowledged 
(alarm));
+                                               }
+                                       }
 
                                        instances = e_cal_component_alarms_get_instances (alarms);
 
@@ -894,11 +908,36 @@ e_reminder_watcher_objects_changed_thread (GTask *task,
                                        for (alink = instances; alink; alink = g_slist_next (alink)) {
                                                const ECalComponentAlarmInstance *instance = alink->data;
 
+                                               if (instance && e_cal_component_alarm_instance_get_uid 
(instance)) {
+                                                       ICalTime *acknowledged;
+
+                                                       acknowledged = g_hash_table_lookup 
(acknowledged_alarms, e_cal_component_alarm_instance_get_uid (instance));
+                                                       if (acknowledged) {
+                                                               gint64 ack_time, instance_time;
+
+                                                               ack_time = i_cal_time_as_timet (acknowledged);
+                                                               instance_time = 
e_cal_component_alarm_instance_get_time (instance);
+
+                                                               if (instance_time <= ack_time) {
+                                                                       e_reminder_watcher_debug_print ("   
Skipping alarm '%s' at '%s', because had been acknowledged at '%s'\n",
+                                                                               
e_cal_component_alarm_instance_get_uid (instance),
+                                                                               
e_reminder_watcher_timet_as_string (instance_time),
+                                                                               
e_reminder_watcher_timet_as_string (ack_time));
+
+                                                                       instance = NULL;
+                                                               }
+                                                       }
+                                               }
+
                                                if (instance) {
                                                        reminders = g_slist_prepend (reminders, 
e_reminder_data_new_take_component (
                                                                source_uid, g_object_ref (alarms_comp), 
instance));
                                                }
                                        }
+
+                                       g_hash_table_destroy (acknowledged_alarms);
+                                       /* Free all_alarms after the acknowledged_alarms, because it uses 
data from it */
+                                       g_slist_free_full (all_alarms, e_cal_component_alarm_free);
                                } else {
                                        e_reminder_watcher_debug_print ("Source %s: Got no alarms for object 
'%s':'%s' at interval %s .. %s\n",
                                                source_uid, e_cal_component_id_get_uid (id),
diff --git a/tests/libecal/test-cal-component.c b/tests/libecal/test-cal-component.c
index 28b8737fd..3af1c2e96 100644
--- a/tests/libecal/test-cal-component.c
+++ b/tests/libecal/test-cal-component.c
@@ -442,6 +442,9 @@ verify_struct_alarm_equal (const ECalComponentAlarm *expected,
 
        verify_struct_property_bag_equal (e_cal_component_alarm_get_property_bag (expected),
                                          e_cal_component_alarm_get_property_bag (received));
+
+       verify_ical_timetype_equal (e_cal_component_alarm_get_acknowledged (expected),
+                                   e_cal_component_alarm_get_acknowledged (received));
 }
 
 static void
@@ -511,17 +514,18 @@ test_component_struct_alarm (void)
                gboolean with_attendees;
                gboolean with_attachments;
                gboolean with_properties;
+               gboolean with_acknowledged;
        } values[] = {
-               { "1", E_CAL_COMPONENT_ALARM_AUDIO, NULL, NULL, FALSE, FALSE, FALSE, FALSE, FALSE },
-               { "2", E_CAL_COMPONENT_ALARM_DISPLAY, NULL, "display text", FALSE, FALSE, FALSE, FALSE, FALSE 
},
-               { "3", E_CAL_COMPONENT_ALARM_EMAIL, "summary text", NULL, TRUE, FALSE, FALSE, FALSE, FALSE },
-               { "4", E_CAL_COMPONENT_ALARM_PROCEDURE, NULL, "procedure", FALSE, TRUE, FALSE, FALSE, TRUE },
-               { "5", E_CAL_COMPONENT_ALARM_AUDIO, NULL, NULL, FALSE, FALSE, TRUE, FALSE, TRUE },
-               { "6", E_CAL_COMPONENT_ALARM_DISPLAY, NULL, "display text", FALSE, FALSE, FALSE, TRUE, TRUE },
-               { "7", E_CAL_COMPONENT_ALARM_EMAIL, "summary", "description", TRUE, FALSE, TRUE, FALSE, TRUE 
},
-               { "8", E_CAL_COMPONENT_ALARM_PROCEDURE, NULL, "procedure", TRUE, TRUE, TRUE, TRUE, TRUE }
+               { "1", E_CAL_COMPONENT_ALARM_AUDIO, NULL, NULL, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
+               { "2", E_CAL_COMPONENT_ALARM_DISPLAY, NULL, "display text", FALSE, FALSE, FALSE, FALSE, 
FALSE, TRUE },
+               { "3", E_CAL_COMPONENT_ALARM_EMAIL, "summary text", NULL, TRUE, FALSE, FALSE, FALSE, FALSE, 
FALSE },
+               { "4", E_CAL_COMPONENT_ALARM_PROCEDURE, NULL, "procedure", FALSE, TRUE, FALSE, FALSE, TRUE, 
TRUE },
+               { "5", E_CAL_COMPONENT_ALARM_AUDIO, NULL, NULL, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE },
+               { "6", E_CAL_COMPONENT_ALARM_DISPLAY, NULL, "display text", FALSE, FALSE, FALSE, TRUE, TRUE, 
TRUE },
+               { "7", E_CAL_COMPONENT_ALARM_EMAIL, "summary", "description", TRUE, FALSE, TRUE, FALSE, TRUE, 
FALSE },
+               { "8", E_CAL_COMPONENT_ALARM_PROCEDURE, NULL, "procedure", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE 
}
        };
-       gint ii, nth_summary = 0, nth_description = 0, nth_repeat = 0, nth_trigger = 0, nth_attendees = 0, 
nth_attachments = 0, nth_properties = 0;
+       gint ii, nth_summary = 0, nth_description = 0, nth_repeat = 0, nth_trigger = 0, nth_attendees = 0, 
nth_attachments = 0, nth_properties = 0, nth_acknowledged = 0;
 
        for (ii = 0; ii < G_N_ELEMENTS (values); ii++) {
                ECalComponentAlarm *expected, *received;
@@ -693,6 +697,24 @@ test_component_struct_alarm (void)
                        g_assert_cmpint (e_cal_component_property_bag_get_count (bag), ==, nth_properties);
                }
 
+               if (values[ii].with_acknowledged) {
+                       ICalTime *tt;
+
+                       nth_acknowledged++;
+
+                       tt = i_cal_time_new_current_with_zone (i_cal_timezone_get_utc_timezone ());
+
+                       if ((nth_acknowledged & 1) != 0) {
+                               e_cal_component_alarm_set_acknowledged (expected, tt);
+                               g_object_unref (tt);
+                       } else {
+                               e_cal_component_alarm_take_acknowledged (expected, tt);
+                       }
+
+                       if (nth_acknowledged == 3)
+                               e_cal_component_alarm_set_acknowledged (expected, NULL);
+               }
+
                received = e_cal_component_alarm_copy (expected);
                verify_struct_alarm_equal (expected, received);
                e_cal_component_alarm_free (received);
@@ -723,6 +745,7 @@ test_component_struct_alarm (void)
        g_assert_cmpint (nth_attendees, >, 1);
        g_assert_cmpint (nth_attachments, >, 1);
        g_assert_cmpint (nth_properties, >, 1);
+       g_assert_cmpint (nth_acknowledged, >, 3);
 }
 
 static void


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