696 lines
25 KiB
C
696 lines
25 KiB
C
/* test-event.c
|
|
*
|
|
* Copyright © 2018 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <glib.h>
|
|
#include <string.h>
|
|
|
|
#include "gcal-event-attendee.h"
|
|
#include "gcal-event-organizer.h"
|
|
#include "gcal-event.h"
|
|
#include "gcal-recurrence.h"
|
|
#include "gcal-stub-calendar.h"
|
|
#include "gcal-utils.h"
|
|
#include "libecal/libecal.h"
|
|
|
|
#define STUB_EVENT "BEGIN:VEVENT\n" \
|
|
"SUMMARY:Stub event\n" \
|
|
"UID:example@uid\n" \
|
|
"DTSTAMP:19970114T170000Z\n" \
|
|
"DTSTART:20180714T170000Z\n" \
|
|
"DTEND:20180715T035959Z\n" \
|
|
"END:VEVENT\n"
|
|
|
|
#define STUB_EVENT_DTEND "BEGIN:VEVENT\n" \
|
|
"SUMMARY:Stub all day\n" \
|
|
"UID:example@uid\n" \
|
|
"DTSTART;VALUE=DATE:20231108\n" \
|
|
"DTEND;VALUE=DATE:20231109\n" \
|
|
"END:VEVENT\n"
|
|
|
|
#define STUB_EVENT_NODTEND "BEGIN:VEVENT\n" \
|
|
"SUMMARY:Stub all day\n" \
|
|
"UID:example@uid\n" \
|
|
"DTSTART;VALUE=DATE:20231108\n" \
|
|
"END:VEVENT\n"
|
|
|
|
#define EVENT_STRING_FOR_DATE(dtstart,dtend) \
|
|
"BEGIN:VEVENT\n" \
|
|
"SUMMARY:Stub event\n" \
|
|
"UID:example@uid\n" \
|
|
"DTSTAMP:19970114T170000Z\n" \
|
|
"DTSTART"dtstart"\n" \
|
|
"DTEND"dtend"\n" \
|
|
"END:VEVENT\n"
|
|
|
|
#define EVENT_STRING_FOR_DATE_START(dtstart) \
|
|
EVENT_STRING_FOR_DATE(dtstart, ":20180715T035959Z")
|
|
|
|
#define EVENT_STRING_FOR_DATE_END(dtend) \
|
|
EVENT_STRING_FOR_DATE(":19970101T170000Z", dtend)
|
|
|
|
|
|
#define STUB_EVENT_WITH_ATTENDEES "BEGIN:VEVENT\n" \
|
|
"UID:123456789@example.com\n" \
|
|
"DTSTAMP:20240210T120000Z\n" \
|
|
"DTSTART:20240215T150000Z\n" \
|
|
"DTEND:20240215T160000Z\n" \
|
|
"SUMMARY:Project Meeting\n" \
|
|
"DESCRIPTION:Discuss project updates and next steps.\n" \
|
|
"ORGANIZER;CN=Alice Smith;SENT-BY=\"MAILTO:jane_doe@host.com\":mailto:alice@example.com\n" \
|
|
"ATTENDEE;CN=Bob Johnson;RSVP=TRUE;ROLE=REQ-PARTICIPANT:mailto:bob@example.com\n" \
|
|
"ATTENDEE;CN=Carol Lee;RSVP=FALSE;ROLE=OPT-PARTICIPANT:mailto:carol@example.com\n" \
|
|
"END:VEVENT\n"
|
|
|
|
#define STUB_EVENT_WITH_RECURRENCE "BEGIN:VEVENT\n" \
|
|
"SUMMARY:Stub event\n" \
|
|
"UID:example@uid\n" \
|
|
"DTSTAMP:19970114T000000Z\n" \
|
|
"DTSTART:20180714T000000Z\n" \
|
|
"DTEND:20180714T235959Z\n" \
|
|
"RRULE;FREQ=DAILY;COUNT=3\n" \
|
|
"RECURRENCE-ID:20180714T000000Z\n" \
|
|
"END:VEVENT\n"
|
|
|
|
/*
|
|
* Auxiliary methods
|
|
*/
|
|
|
|
static GcalEvent*
|
|
create_event_for_string (const gchar *string,
|
|
GError **error)
|
|
{
|
|
g_autoptr (ECalComponent) component = NULL;
|
|
g_autoptr (GcalCalendar) calendar = NULL;
|
|
|
|
component = e_cal_component_new_from_string (string);
|
|
calendar = gcal_stub_calendar_new (NULL, error);
|
|
|
|
return component ? gcal_event_new (calendar, component, error) : NULL;
|
|
}
|
|
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_new (void)
|
|
{
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
event = create_event_for_string (STUB_EVENT, &error);
|
|
|
|
g_assert_no_error (error);
|
|
g_assert_nonnull (event);
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_clone (void)
|
|
{
|
|
g_autoptr (GcalEvent) clone1 = NULL;
|
|
g_autoptr (GcalEvent) clone2 = NULL;
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
event = create_event_for_string (STUB_EVENT, &error);
|
|
|
|
g_assert_no_error (error);
|
|
g_assert_nonnull (event);
|
|
|
|
clone1 = gcal_event_new_from_event (event);
|
|
g_assert_nonnull (clone1);
|
|
|
|
gcal_event_set_summary (event, "Another summary");
|
|
|
|
clone2 = gcal_event_new_from_event (event);
|
|
g_assert_nonnull (clone2);
|
|
}
|
|
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_uid (void)
|
|
{
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
|
|
event = create_event_for_string (STUB_EVENT, NULL);
|
|
|
|
g_assert_cmpstr (gcal_event_get_uid (event), ==, "stub:example@uid");
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_summary (void)
|
|
{
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
|
|
event = create_event_for_string (STUB_EVENT, NULL);
|
|
|
|
g_assert_cmpstr (gcal_event_get_summary (event), ==, "Stub event");
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_no_dtend (void)
|
|
{
|
|
g_autoptr (GcalEvent) event_dtend = NULL;
|
|
g_autoptr (GcalEvent) event_nodtend = NULL;
|
|
GDateTime *end_dtend = NULL;
|
|
GDateTime *end_nodtend = NULL;
|
|
|
|
g_test_bug ("327");
|
|
|
|
event_dtend = create_event_for_string (STUB_EVENT_DTEND, NULL);
|
|
event_nodtend = create_event_for_string (STUB_EVENT_NODTEND, NULL);
|
|
end_dtend = gcal_event_get_date_end (event_dtend);
|
|
end_nodtend = gcal_event_get_date_end (event_nodtend);
|
|
|
|
// assert event with DTEND is working correctly
|
|
g_assert_true (gcal_event_get_all_day (event_dtend));
|
|
g_assert_true (end_dtend != NULL);
|
|
|
|
// assert event without DTEND is working correctly, has a date_end assigned
|
|
// for all day
|
|
g_assert_true (gcal_event_get_all_day (event_nodtend));
|
|
g_assert_true (end_nodtend != NULL);
|
|
|
|
// The event without dtend should be all day and should have the same
|
|
// date_end than the event that explicitly specified it.
|
|
g_assert_true (g_date_time_equal (end_dtend, end_nodtend));
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_date_start (void)
|
|
{
|
|
struct
|
|
{
|
|
const gchar *string;
|
|
GDateTime *datetime;
|
|
}
|
|
start_dates[] = {
|
|
{ EVENT_STRING_FOR_DATE_START (":20160229T000000Z"), g_date_time_new_utc (2016, 2, 29, 00, 00, 00.) },
|
|
{ EVENT_STRING_FOR_DATE_START (":20180228T170000Z"), g_date_time_new_utc (2018, 2, 28, 17, 00, 00.) },
|
|
{ EVENT_STRING_FOR_DATE_START (":20180714T170000Z"), g_date_time_new_utc (2018, 7, 14, 17, 00, 00.) },
|
|
};
|
|
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (start_dates); i++)
|
|
{
|
|
g_autoptr (GDateTime) dtstart = NULL;
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
event = create_event_for_string (start_dates[i].string, &error);
|
|
dtstart = start_dates[i].datetime;
|
|
|
|
g_assert_no_error (error);
|
|
g_assert_true (g_date_time_equal (gcal_event_get_date_start (event), dtstart));
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_date_end (void)
|
|
{
|
|
struct
|
|
{
|
|
const gchar *string;
|
|
GDateTime *datetime;
|
|
}
|
|
end_dates[] = {
|
|
{ EVENT_STRING_FOR_DATE_END (":20160229T000000Z"), g_date_time_new_utc (2016, 2, 29, 00, 00, 00.) },
|
|
{ EVENT_STRING_FOR_DATE_END (":20180228T170000Z"), g_date_time_new_utc (2018, 2, 28, 17, 00, 00.) },
|
|
{ EVENT_STRING_FOR_DATE_END (":20180714T170000Z"), g_date_time_new_utc (2018, 7, 14, 17, 00, 00.) },
|
|
};
|
|
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (end_dates); i++)
|
|
{
|
|
g_autoptr (GDateTime) dtend = NULL;
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
event = create_event_for_string (end_dates[i].string, &error);
|
|
dtend = end_dates[i].datetime;
|
|
|
|
g_assert_no_error (error);
|
|
g_assert_true (g_date_time_equal (gcal_event_get_date_end (event), dtend));
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_date_singleday (void)
|
|
{
|
|
const gchar * const events[] = {
|
|
EVENT_STRING_FOR_DATE (":20160229T000000Z", ":20160229T030000Z"),
|
|
EVENT_STRING_FOR_DATE (":20160229T000000Z", ":20160301T000000Z"),
|
|
EVENT_STRING_FOR_DATE (":20160229T000000Z", ":20160229T235959Z"),
|
|
};
|
|
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (events); i++)
|
|
{
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
event = create_event_for_string (events[i], &error);
|
|
|
|
g_assert_no_error (error);
|
|
g_assert_false (gcal_event_is_multiday (event));
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_date_multiday (void)
|
|
{
|
|
const gchar * const events[] = {
|
|
EVENT_STRING_FOR_DATE (":20160229T000000Z", ":20160302T000001Z"),
|
|
EVENT_STRING_FOR_DATE (":20160229T020000Z", ":20160310T004500Z"),
|
|
};
|
|
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (events); i++)
|
|
{
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
event = create_event_for_string (events[i], &error);
|
|
|
|
g_assert_no_error (error);
|
|
g_assert_true (gcal_event_is_multiday (event));
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_date_create_tzid (void)
|
|
{
|
|
const gchar *event_str = EVENT_STRING_FOR_DATE (";TZID=Europe/London:20170818T010000", ";TZID=Europe/London:20170818T020000");
|
|
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
g_autoptr (GDateTime) datetime = NULL;
|
|
g_autoptr (GTimeZone) tz = NULL;
|
|
g_autofree gchar *ical_string = NULL;
|
|
|
|
ECalComponent *comp = NULL;
|
|
ICalComponent *ical_comp = NULL;
|
|
ECalComponentDateTime *dt_end = NULL;
|
|
|
|
g_test_bug ("172");
|
|
|
|
event = create_event_for_string (event_str, &error);
|
|
g_assert_no_error (error);
|
|
|
|
comp = gcal_event_get_component (event);
|
|
dt_end = e_cal_component_get_dtend (comp);
|
|
g_assert_cmpstr (e_cal_component_datetime_get_tzid (dt_end), ==, "Europe/London");
|
|
e_cal_component_datetime_free (dt_end);
|
|
|
|
ical_comp = e_cal_component_get_icalcomponent (comp);
|
|
|
|
ical_string = i_cal_component_as_ical_string (ical_comp);
|
|
g_assert_true (strstr (ical_string, "DTSTART;TZID=Europe/London:20170818T010000\r\n") != NULL);
|
|
g_assert_true (strstr (ical_string, "DTEND;TZID=Europe/London:20170818T020000\r\n") != NULL);
|
|
g_clear_pointer (&ical_string, g_free);
|
|
|
|
// Edit the event to check that the modification is stored correctly
|
|
g_setenv ("TZ", "Europe/London", TRUE);
|
|
|
|
tz = g_time_zone_new_identifier ("Europe/London");
|
|
datetime = g_date_time_new (tz, 2017, 8, 18, 3, 00, 00.);
|
|
gcal_event_set_date_end (event, datetime);
|
|
|
|
ical_string = i_cal_component_as_ical_string (ical_comp);
|
|
g_assert_true (strstr (ical_string, "DTSTART;TZID=Europe/London:20170818T010000\r\n") != NULL);
|
|
g_assert_true (strstr (ical_string, "DTEND;TZID=/freeassociation.sourceforge.net/Europe/London:\r\n 20170818T030000\r\n") != NULL);
|
|
g_clear_pointer (&ical_string, g_free);
|
|
|
|
g_setenv ("TZ", "UTC", TRUE);
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_date_check_tz (void)
|
|
{
|
|
struct
|
|
{
|
|
const gchar *string;
|
|
const gchar *tz;
|
|
}
|
|
timezones[] = {
|
|
{
|
|
STUB_EVENT_DTEND, "UTC"
|
|
},
|
|
{
|
|
EVENT_STRING_FOR_DATE (";TZID=America/New_York:20240709T170000", ";TZID=America/New_York:20240709T180000"),
|
|
"America/New_York"
|
|
},
|
|
{
|
|
EVENT_STRING_FOR_DATE (";TZID=Australia/Melbourne:20240709T170000", ";TZID=Australia/Melbourne:20240709T180000"),
|
|
"Australia/Melbourne"
|
|
},
|
|
{
|
|
EVENT_STRING_FOR_DATE (":20240709T170000", ":20240709T180000"), "Europe/London"
|
|
},
|
|
{
|
|
EVENT_STRING_FOR_DATE (":20240709T180000Z", ":20240709T190000Z"), "UTC"
|
|
},
|
|
};
|
|
|
|
g_test_bug ("171");
|
|
|
|
for (gsize i = 0; i < G_N_ELEMENTS (timezones); i++)
|
|
{
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
GTimeZone *date_start = NULL;
|
|
GTimeZone *date_end = NULL;
|
|
|
|
/* Change environment variable to test local timezone, when it's the case. */
|
|
g_setenv ("TZ", "Europe/London", TRUE);
|
|
|
|
event = create_event_for_string (timezones[i].string, &error);
|
|
|
|
g_setenv ("TZ", "UTC", TRUE);
|
|
g_assert_no_error (error);
|
|
|
|
date_start = g_date_time_get_timezone (gcal_event_get_date_start (event));
|
|
date_end = g_date_time_get_timezone (gcal_event_get_date_end (event));
|
|
|
|
g_assert_cmpstr (g_time_zone_get_identifier (date_start), ==, timezones[i].tz);
|
|
g_assert_cmpstr (g_time_zone_get_identifier (date_end), ==, timezones[i].tz);
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_get_attendees (void)
|
|
{
|
|
/* "ATTENDEE;CN=Bob Johnson;RSVP=TRUE;ROLE=REQ-PARTICIPANT:mailto:bob@example.com\n" \ */
|
|
/* "ATTENDEE;CN=Carol Lee;RSVP=FALSE;ROLE=OPT-PARTICIPANT:mailto:carol@example.com\n" \ */
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
GListModel *attendees = NULL;
|
|
|
|
event = create_event_for_string (STUB_EVENT_WITH_ATTENDEES, &error);
|
|
|
|
attendees = gcal_event_get_attendees (event);
|
|
|
|
g_assert_nonnull (attendees);
|
|
|
|
for (guint i = 0; i < g_list_model_get_n_items (attendees); ++i)
|
|
{
|
|
g_autoptr (GcalEventAttendee) at = (GcalEventAttendee *) g_list_model_get_item (attendees, i);
|
|
|
|
g_assert_cmpstr (NULL, !=, gcal_event_attendee_get_name (at));
|
|
g_assert_cmpstr (NULL, !=, gcal_event_attendee_get_uri (at));
|
|
g_assert_cmpuint (GCAL_EVENT_ATTENDEE_TYPE_NONE, !=, gcal_event_attendee_get_attendee_type (at));
|
|
}
|
|
|
|
/* organizer should be set */
|
|
/* "ORGANIZER;CN=Alice Smith;SENT-BY=\"MAILTO:jane_doe@host.com\":mailto:alice@example.com\n" \ */
|
|
GcalEventOrganizer *organizer = gcal_event_get_organizer (event);
|
|
g_assert_nonnull (organizer);
|
|
g_assert_cmpstr ("Alice Smith", ==, gcal_event_organizer_get_name (organizer));
|
|
g_assert_cmpstr ("MAILTO:jane_doe@host.com", ==, gcal_event_organizer_get_sent_by (organizer));
|
|
g_assert_cmpstr ("mailto:alice@example.com", ==, gcal_event_organizer_get_uri (organizer));
|
|
|
|
g_autofree const gchar *uri_trimmed = gcal_util_get_email_from_mailto_uri (gcal_event_organizer_get_uri (organizer));
|
|
g_assert_cmpstr ("alice@example.com", ==, uri_trimmed);
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static void
|
|
event_invite_attendees (void)
|
|
{
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GcalEvent) clone = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
g_autofree gchar *ical = NULL;
|
|
GcalEventOrganizer *organizer;
|
|
GListModel *attendees;
|
|
|
|
event = create_event_for_string (STUB_EVENT, &error);
|
|
g_assert_no_error (error);
|
|
|
|
attendees = gcal_event_get_attendees (event);
|
|
g_assert_cmpuint (g_list_model_get_n_items (attendees), ==, 0);
|
|
g_assert_null (gcal_event_get_organizer (event));
|
|
|
|
clone = gcal_event_new_from_event (event);
|
|
g_assert_true (gcal_event_attendees_equal (event, clone));
|
|
|
|
gcal_event_set_organizer (clone, "me@example.com", "Me Myself");
|
|
organizer = gcal_event_get_organizer (clone);
|
|
g_assert_nonnull (organizer);
|
|
g_assert_cmpstr (gcal_event_organizer_get_uri (organizer), ==, "mailto:me@example.com");
|
|
g_assert_cmpstr (gcal_event_organizer_get_name (organizer), ==, "Me Myself");
|
|
g_assert_false (gcal_event_attendees_equal (event, clone));
|
|
|
|
g_assert_true (gcal_event_add_attendee (clone, "ana@example.com", "Ana Lima"));
|
|
g_assert_true (gcal_event_add_attendee (clone, "bo@example.com", NULL));
|
|
g_assert_false (gcal_event_add_attendee (clone, "ANA@example.com", NULL));
|
|
|
|
attendees = gcal_event_get_attendees (clone);
|
|
g_assert_cmpuint (g_list_model_get_n_items (attendees), ==, 2);
|
|
g_assert_true (gcal_event_has_attendee (clone, "mailto:Ana@Example.com"));
|
|
g_assert_false (gcal_event_has_attendee (clone, "carl@example.com"));
|
|
|
|
{
|
|
g_autoptr (GcalEventAttendee) attendee = g_list_model_get_item (attendees, 0);
|
|
|
|
g_assert_cmpstr (gcal_event_attendee_get_uri (attendee), ==, "mailto:ana@example.com");
|
|
g_assert_cmpstr (gcal_event_attendee_get_name (attendee), ==, "Ana Lima");
|
|
g_assert_cmpint (gcal_event_attendee_get_attendee_type (attendee), ==, GCAL_EVENT_ATTENDEE_TYPE_INDIVIDUAL);
|
|
g_assert_cmpint (gcal_event_attendee_get_role (attendee), ==, GCAL_EVENT_ATTENDEE_ROLE_REQUIRED);
|
|
g_assert_cmpint (gcal_event_attendee_get_part_status (attendee), ==, GCAL_EVENT_ATTENDEE_PART_NEEDS_ACTION);
|
|
g_assert_true (gcal_event_attendee_get_requires_rsvp (attendee));
|
|
}
|
|
|
|
/* What the server sees */
|
|
ical = e_cal_component_get_as_string (gcal_event_get_component (clone));
|
|
g_assert_nonnull (strstr (ical, "ORGANIZER;CN=Me Myself:mailto:me@example.com"));
|
|
g_assert_nonnull (strstr (ical, "mailto:ana@example.com"));
|
|
g_assert_nonnull (strstr (ical, "mailto:bo@example.com"));
|
|
|
|
gcal_event_remove_attendee (clone, "mailto:ANA@example.com");
|
|
g_assert_cmpuint (g_list_model_get_n_items (attendees), ==, 1);
|
|
g_assert_false (gcal_event_has_attendee (clone, "ana@example.com"));
|
|
|
|
/* Removing someone who isn't invited does nothing */
|
|
gcal_event_remove_attendee (clone, "carl@example.com");
|
|
g_assert_cmpuint (g_list_model_get_n_items (attendees), ==, 1);
|
|
|
|
gcal_event_remove_attendee (clone, "bo@example.com");
|
|
gcal_event_set_organizer (clone, NULL, NULL);
|
|
g_assert_null (gcal_event_get_organizer (clone));
|
|
g_assert_true (gcal_event_attendees_equal (event, clone));
|
|
}
|
|
|
|
static void
|
|
event_copy_attendees (void)
|
|
{
|
|
g_autoptr (GcalEvent) with_attendees = NULL;
|
|
g_autoptr (GcalEvent) event = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
with_attendees = create_event_for_string (STUB_EVENT_WITH_ATTENDEES, &error);
|
|
g_assert_no_error (error);
|
|
|
|
event = create_event_for_string (STUB_EVENT, &error);
|
|
g_assert_no_error (error);
|
|
|
|
g_assert_false (gcal_event_attendees_equal (event, with_attendees));
|
|
|
|
gcal_event_copy_attendees (event, with_attendees);
|
|
|
|
g_assert_true (gcal_event_attendees_equal (event, with_attendees));
|
|
g_assert_cmpuint (g_list_model_get_n_items (gcal_event_get_attendees (event)), ==, 2);
|
|
g_assert_cmpstr (gcal_event_organizer_get_uri (gcal_event_get_organizer (event)), ==, "mailto:alice@example.com");
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
static GDateTime *
|
|
dt_add_second_random (GDateTime *dt)
|
|
{
|
|
gint32 seconds = 0;
|
|
do
|
|
{
|
|
// numbers chosen to cover a fair amount of years
|
|
seconds = g_test_rand_int_range (-1000000000, 1000000000);
|
|
}
|
|
while (seconds == 0);
|
|
|
|
return g_date_time_add_seconds (dt, seconds);
|
|
};
|
|
|
|
static void
|
|
event_schedule_equal (void)
|
|
{
|
|
g_test_bug ("1612");
|
|
|
|
const gchar *const events[] = {
|
|
EVENT_STRING_FOR_DATE (":20160229T000000Z", ":20160229T030000Z"),
|
|
EVENT_STRING_FOR_DATE (":20160229T000000Z", ":20160301T000000Z"),
|
|
EVENT_STRING_FOR_DATE (":20160229T000000Z", ":20160229T235959Z"),
|
|
EVENT_STRING_FOR_DATE (":20160229T000000Z", ":20160302T000001Z"),
|
|
EVENT_STRING_FOR_DATE (":20160229T020000Z", ":20160310T004500Z"),
|
|
STUB_EVENT_WITH_RECURRENCE,
|
|
};
|
|
|
|
for (guint i = 0; i < G_N_ELEMENTS (events); i++)
|
|
{
|
|
g_autoptr (GcalEvent) event_orig = NULL;
|
|
g_autoptr (GcalEvent) event_mod = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
event_orig = create_event_for_string (events[i], &error);
|
|
g_assert_no_error (error);
|
|
|
|
event_mod = create_event_for_string (events[i], &error);
|
|
g_assert_no_error (error);
|
|
|
|
g_assert_true (gcal_event_schedule_equal (event_orig, event_mod));
|
|
|
|
g_autoptr (GDateTime) dt_start = g_date_time_ref (gcal_event_get_date_start (event_mod));
|
|
g_autoptr (GDateTime) dt_end = g_date_time_ref (gcal_event_get_date_end (event_mod));
|
|
|
|
/* == type changed == */
|
|
|
|
/* use a separate event instance in case flipping the type also changes the stored date time */
|
|
{
|
|
g_autoptr (GcalEvent) event_mod_mod = gcal_event_new_from_event (event_mod);
|
|
|
|
gcal_event_set_all_day (event_mod_mod, !gcal_event_get_all_day (event_mod_mod));
|
|
|
|
g_assert_false (gcal_event_schedule_equal (event_orig, event_mod_mod));
|
|
}
|
|
|
|
/* == start and/or end date time changed == */
|
|
|
|
/* poor person's fuzz test I suppose */
|
|
for (guint j = 0; j < 10; j++)
|
|
{
|
|
g_autoptr (GDateTime) dt_start_mod = dt_add_second_random (dt_start);
|
|
g_autoptr (GDateTime) dt_end_mod = dt_add_second_random (dt_end);
|
|
|
|
gcal_event_set_date_start (event_mod, dt_start_mod);
|
|
g_assert_false (gcal_event_schedule_equal (event_orig, event_mod));
|
|
|
|
gcal_event_set_date_start (event_mod, dt_start);
|
|
g_assert_true (gcal_event_schedule_equal (event_orig, event_mod));
|
|
|
|
gcal_event_set_date_end (event_mod, dt_end_mod);
|
|
g_assert_false (gcal_event_schedule_equal (event_orig, event_mod));
|
|
|
|
gcal_event_set_date_end (event_mod, dt_end);
|
|
g_assert_true (gcal_event_schedule_equal (event_orig, event_mod));
|
|
}
|
|
|
|
/* == start and/or end timezone changed == */
|
|
|
|
{
|
|
g_autoptr (GDateTime) dt_start_mod = g_date_time_to_timezone (dt_start, g_time_zone_new_identifier ("Australia/Melbourne"));
|
|
g_autoptr (GDateTime) dt_end_mod = g_date_time_to_timezone (dt_end, g_time_zone_new_identifier ("Australia/Melbourne"));
|
|
|
|
gcal_event_set_date_start (event_mod, dt_start_mod);
|
|
g_assert_false (gcal_event_schedule_equal (event_orig, event_mod));
|
|
|
|
gcal_event_set_date_start (event_mod, dt_start);
|
|
g_assert_true (gcal_event_schedule_equal (event_orig, event_mod));
|
|
|
|
gcal_event_set_date_end (event_mod, dt_end_mod);
|
|
g_assert_false (gcal_event_schedule_equal (event_orig, event_mod));
|
|
|
|
gcal_event_set_date_end (event_mod, dt_end);
|
|
g_assert_true (gcal_event_schedule_equal (event_orig, event_mod));
|
|
}
|
|
|
|
/* == recurrence changed == */
|
|
|
|
if (gcal_event_has_recurrence (event_mod))
|
|
{
|
|
g_autoptr (GcalRecurrence) no_rec = gcal_recurrence_new ();
|
|
|
|
gcal_event_set_recurrence (event_mod, no_rec);
|
|
}
|
|
else
|
|
{
|
|
g_autoptr (ECalComponent) comp = e_cal_component_new_from_string (STUB_EVENT_WITH_RECURRENCE);
|
|
g_autoptr (GcalRecurrence) some_rec = gcal_recurrence_parse_recurrence_rules (comp);
|
|
|
|
gcal_event_set_recurrence (event_mod, some_rec);
|
|
}
|
|
|
|
g_assert_false (gcal_event_schedule_equal (event_orig, event_mod));
|
|
|
|
/* event_mod uses different recurrence now, don't add additional tests below */
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
|
|
gint
|
|
main (gint argc,
|
|
gchar *argv[])
|
|
{
|
|
g_setenv ("TZ", "UTC", TRUE);
|
|
|
|
g_test_init (&argc, &argv, NULL);
|
|
g_test_bug_base ("https://gitlab.gnome.org/GNOME/gnome-calendar/-/issues/");
|
|
|
|
g_test_add_func ("/event/new", event_new);
|
|
g_test_add_func ("/event/clone", event_clone);
|
|
g_test_add_func ("/event/uid", event_uid);
|
|
g_test_add_func ("/event/summary", event_summary);
|
|
g_test_add_func ("/event/nodtend", event_no_dtend);
|
|
g_test_add_func ("/event/date/start", event_date_start);
|
|
g_test_add_func ("/event/date/end", event_date_end);
|
|
g_test_add_func ("/event/date/singleday", event_date_singleday);
|
|
g_test_add_func ("/event/date/multiday", event_date_multiday);
|
|
g_test_add_func ("/event/date/create-tzid", event_date_create_tzid);
|
|
g_test_add_func ("/event/date/check-tz", event_date_check_tz);
|
|
g_test_add_func ("/event/date/get-attendees", event_get_attendees);
|
|
g_test_add_func ("/event/attendees/invite", event_invite_attendees);
|
|
g_test_add_func ("/event/attendees/copy", event_copy_attendees);
|
|
g_test_add_func ("/event/equal/schedule", event_schedule_equal);
|
|
|
|
return g_test_run ();
|
|
}
|