diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b41432f8..78732f02 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,6 +29,7 @@ test: artifacts: paths: - testing/report.xml + - apache2_log/* reports: junit: testing/report.xml when: @@ -68,4 +69,5 @@ test: - apache2ctl start - useradd testrunner - cd testing && su testrunner -c 'IS_CI=yes ALLSUITES="regression-suite binding carddav scheduling" ./run_regressions.sh all x' - + after_script: + - cp -r /var/log/apache2 apache2_log diff --git a/dba/davical.sql b/dba/davical.sql index 50fb4907..fa8280cc 100644 --- a/dba/davical.sql +++ b/dba/davical.sql @@ -167,8 +167,8 @@ CREATE TABLE calendar_item ( completed TIMESTAMP WITH TIME ZONE, dav_id INT8 UNIQUE, collection_id INT8 REFERENCES collection(collection_id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, - first_instance_start TIMESTAMP WITHOUT TIME ZONE DEFAULT NULL, - last_instance_end TIMESTAMP WITHOUT TIME ZONE DEFAULT NULL, + first_instance_start TIMESTAMP WITH TIME ZONE DEFAULT NULL, + last_instance_end TIMESTAMP WITH TIME ZONE DEFAULT NULL, -- Cascade updates / deletes from the caldav_data table CONSTRAINT caldav_exists FOREIGN KEY ( user_no, dav_name ) @@ -489,4 +489,4 @@ CREATE SEQUENCE metrics_count_delticket; CREATE SEQUENCE metrics_count_bind; CREATE SEQUENCE metrics_count_unknown; -SELECT new_db_revision(1,3,2, 'Luty' ); +SELECT new_db_revision(1,3,3, 'Marzec' ); diff --git a/dba/patches/1.3.3.sql b/dba/patches/1.3.3.sql new file mode 100644 index 00000000..466743f7 --- /dev/null +++ b/dba/patches/1.3.3.sql @@ -0,0 +1,23 @@ + +-- Notable enhancement: change first_instance_start and last_instance_end to be timezone-aware + +BEGIN; +SELECT check_db_revision(1,3,2); + +ALTER TABLE calendar_item + ALTER COLUMN first_instance_start + TYPE TIMESTAMP WITH TIME ZONE + -- I don't believe the column has ever been populated, but if it has, we want + -- to throw away that data anyway because we don't know its timezone + USING NULL::timestamptz; + +ALTER TABLE calendar_item + ALTER COLUMN last_instance_end + TYPE TIMESTAMP WITH TIME ZONE + USING NULL::timestamptz; -- As above + +-- http://blogs.transparent.com/polish/names-of-the-months-and-their-meaning/ +SELECT new_db_revision(1,3,3, 'Marzec' ); + +COMMIT; +ROLLBACK; diff --git a/inc/DAVResource.php b/inc/DAVResource.php index 7b21c3d5..41e5209e 100644 --- a/inc/DAVResource.php +++ b/inc/DAVResource.php @@ -1295,6 +1295,15 @@ EOQRY; } + /** + * Returns the name of the timezone for this collection, or the collection containing this resource + */ + function timezone_name() { + if ( !isset($this->collection) ) $this->FetchCollection(); + return $this->collection->timezone; + } + + /** * Returns the database row for this resource */ diff --git a/inc/RRule.php b/inc/RRule.php index bf4dc9b8..7819a343 100644 --- a/inc/RRule.php +++ b/inc/RRule.php @@ -305,6 +305,18 @@ class RepeatRuleDateTime extends DateTime { return $this; } + public static function withFallbackTzid( $date, $fallback_tzid ) { + // Floating times or dates (either VALUE=DATE or with no TZID) can default to the collection's tzid, if one is set + + if ($date->GetParameterValue('VALUE') == 'DATE' && isset($fallback_tzid)) { + return new RepeatRuleDateTime($date->Value()."T000000", new RepeatRuleTimeZone($fallback_tzid)); + } else if ($date->GetParameterValue('TZID') === null && isset($fallback_tzid)) { + return new RepeatRuleDateTime($date->Value(), new RepeatRuleTimeZone($fallback_tzid)); + } else { + return new RepeatRuleDateTime($date); + } + } + public function __toString() { return (string)parent::format(self::$Format) . ' ' . parent::getTimeZone()->getName(); @@ -1144,7 +1156,7 @@ function rdate_expand( $dtstart, $property, $component, $range_end = null, $is_d * * @return array An array keyed on the UTC dates, referring to the component */ -function rrule_expand( $dtstart, $property, $component, $range_end, $is_date=null, $return_floating_times=false ) { +function rrule_expand( $dtstart, $property, $component, $range_end, $is_date=null, $return_floating_times=false, $fallback_tzid=null ) { $expansion = array(); $recur = $component->GetProperty($property); @@ -1153,7 +1165,7 @@ function rrule_expand( $dtstart, $property, $component, $range_end, $is_date=nul $this_start = $component->GetProperty('DTSTART'); if ( isset($this_start) ) { - $this_start = new RepeatRuleDateTime($this_start); + $this_start = RepeatRuleDateTime::withFallbackTzid($this_start, $fallback_tzid); } else { $this_start = clone($dtstart); @@ -1406,12 +1418,12 @@ function expand_event_instances( vComponent $vResource, $range_start = null, $ra * @throws Exception (1) When DTSTART is not present but the RFC says MUST and (2) when we get an unsupported component * @return RepeatRuleDateRange */ -function getComponentRange(vComponent $comp) { +function getComponentRange(vComponent $comp, string $fallback_tzid = null) { $dtstart_prop = $comp->GetProperty('DTSTART'); $duration_prop = $comp->GetProperty('DURATION'); if ( isset($duration_prop) ) { if ( !isset($dtstart_prop) ) throw new Exception('Invalid '.$comp->GetType().' containing DURATION without DTSTART', 0); - $dtstart = new RepeatRuleDateTime($dtstart_prop); + $dtstart = RepeatRuleDateTime::withFallbackTzid($dtstart_prop, $fallback_tzid); $dtend = clone($dtstart); $dtend->modify(new Rfc5545Duration($duration_prop->Value())); } @@ -1435,17 +1447,17 @@ function getComponentRange(vComponent $comp) { } if ( isset($dtstart_prop) ) - $dtstart = new RepeatRuleDateTime($dtstart_prop); + $dtstart = RepeatRuleDateTime::withFallbackTzid($dtstart_prop, $fallback_tzid); else $dtstart = null; if ( isset($dtend_prop) ) - $dtend = new RepeatRuleDateTime($dtend_prop); + $dtend = RepeatRuleDateTime::withFallbackTzid($dtend_prop, $fallback_tzid); else $dtend = null; if ( isset($completed_prop) ) { - $completed = new RepeatRuleDateTime($completed_prop); + $completed = RepeatRuleDateTime::withFallbackTzid($completed_prop, $fallback_tzid); if ( !isset($dtstart) || (isset($dtstart) && $completed < $dtstart) ) $dtstart = $completed; if ( !isset($dtend) || (isset($dtend) && $completed > $dtend) ) $dtend = $completed; } @@ -1461,7 +1473,7 @@ function getComponentRange(vComponent $comp) { * @param object $vResource A vComponent which is a VCALENDAR containing components needing expansion * @return RepeatRuleDateRange Representing the range of time covered by the event. */ -function getVCalendarRange( $vResource ) { +function getVCalendarRange( $vResource, string $fallback_tzid = null ) { $components = $vResource->GetComponents(); $dtstart = null; @@ -1471,7 +1483,7 @@ function getVCalendarRange( $vResource ) { $has_repeats = false; foreach( $components AS $k => $comp ) { if ( $comp->GetType() == 'VTIMEZONE' ) continue; - $range = getComponentRange($comp); + $range = getComponentRange($comp, $fallback_tzid); $dtstart = $range->from; if ( !isset($dtstart) ) continue; $duration = $range->getDuration(); @@ -1490,7 +1502,7 @@ function getVCalendarRange( $vResource ) { $range_end = new RepeatRuleDateTime(); $range_end->modify('+150 years'); } - $instances += rrule_expand($dtstart, 'RRULE', $comp, $range_end); + $instances += rrule_expand($dtstart, 'RRULE', $comp, $range_end, null, false, $fallback_tzid); $instances += rdate_expand($dtstart, 'RDATE', $comp, $range_end); foreach ( rdate_expand($dtstart, 'EXDATE', $comp, $range_end) AS $k => $v ) { unset($instances[$k]); diff --git a/inc/WritableCollection.php b/inc/WritableCollection.php index fc033784..112b073a 100644 --- a/inc/WritableCollection.php +++ b/inc/WritableCollection.php @@ -219,16 +219,23 @@ class WritableCollection extends DAVResource { $calitem_params[':due'] = $first->GetPValue('DUE'); $calitem_params[':percent_complete'] = $first->GetPValue('PERCENT-COMPLETE'); $calitem_params[':status'] = $first->GetPValue('STATUS'); + + $range = getVCalendarRange($vcal, $this->timezone_name()); + $calitem_params[':first_instance_start'] = isset($range->from) ? $range->from->UTC() : null; + $calitem_params[':last_instance_end'] = isset($range->until) ? $range->until->UTC() : null; + if ( $create_resource ) { $sql = <<GetPValue('PERCENT-COMPLETE'); $calitem_params[':status'] = $first->GetPValue('STATUS'); + // Intentionally not populating first_instance_start and last_instance_end + // here, As they may depend on the default tzid of the collection, which as + // I understand it hasn't yet been set + if ( $inserting ) { $created = $first->GetPValue('CREATED'); if ( $created == '00001231T000000Z' ) $created = '20001231T000000Z'; @@ -1596,7 +1600,11 @@ function write_resource( DAVResource $resource, $caldav_data, DAVResource $colle $calitem_params[':percent_complete'] = $first->GetPValue('PERCENT-COMPLETE'); $calitem_params[':status'] = $first->GetPValue('STATUS'); - // force re-render the object (to get the same representation for all attendiees) + $range = getVCalendarRange($vcal, $resource->timezone_name()); + $calitem_params[':first_instance_start'] = isset($range->from) ? $range->from->UTC() : null; + $calitem_params[':last_instance_end'] = isset($range->until) ? $range->until->UTC() : null; + + // force re-render the object (to get the same representation for all attendees) $vcal->Render(null, true); if ( !$collection->IsSchedulingCollection() ) { @@ -1632,11 +1640,13 @@ function write_resource( DAVResource $resource, $caldav_data, DAVResource $colle INSERT INTO calendar_item (user_no, dav_name, dav_id, dav_etag, uid, dtstamp, dtstart, dtend, summary, location, class, transp, description, rrule, tz_id, last_modified, url, priority, - created, due, percent_complete, status, collection_id ) + created, due, percent_complete, status, collection_id, + first_instance_start, last_instance_end ) VALUES ( :user_no, :dav_name, :dav_id, :etag, :uid, :dtstamp, :dtstart, $dtend, :summary, :location, :class, :transp, :description, :rrule, :tzid, :modified, :url, :priority, - :created, :due, :percent_complete, :status, :collection_id ) + :created, :due, :percent_complete, :status, $collection_id, + :first_instance_start, :last_instance_end) EOSQL; $sync_change = 201; $calitem_params[':collection_id'] = $collection_id; @@ -1650,7 +1660,8 @@ UPDATE calendar_item SET dav_etag=:etag, uid=:uid, dtstamp=:dtstamp, dtstart=:dtstart, dtend=$dtend, summary=:summary, location=:location, class=:class, transp=:transp, description=:description, rrule=:rrule, tz_id=:tzid, last_modified=:modified, url=:url, priority=:priority, - due=:due, percent_complete=:percent_complete, status=:status + due=:due, percent_complete=:percent_complete, status=:status, + first_instance_start=:first_instance_start, last_instance_end=:last_instance_end WHERE dav_id=:dav_id EOSQL; $sync_change = 200; diff --git a/inc/freebusy-functions.php b/inc/freebusy-functions.php index 888c6f1e..35225973 100644 --- a/inc/freebusy-functions.php +++ b/inc/freebusy-functions.php @@ -20,7 +20,10 @@ function get_freebusy( $path_match, $range_start, $range_end, $bin_privs = null } $params = array( ':path_match' => $path_match, ':start' => $range_start->UTC(), ':end' => $range_end->UTC() ); $where = ' WHERE caldav_data.dav_name ~ :path_match '; - $where .= 'AND rrule_event_overlaps( dtstart, dtend, rrule, :start, :end) '; + $where .= "AND ("; + $where .= " (calendar_item.first_instance_start <= :end AND (:start <= calendar_item.last_instance_end OR calendar_item.last_instance_end IS NULL)) "; + $where .= " OR (calendar_item.first_instance_start IS NULL AND rrule_event_overlaps( dtstart, dtend, rrule, :start, :end)) "; + $where .= ") "; $where .= "AND caldav_data.caldav_type IN ( 'VEVENT', 'VTODO' ) "; $where .= "AND (calendar_item.transp != 'TRANSPARENT' OR calendar_item.transp IS NULL) "; $where .= "AND (calendar_item.status != 'CANCELLED' OR calendar_item.status IS NULL) "; @@ -66,13 +69,7 @@ function get_freebusy( $path_match, $range_start, $range_end, $bin_privs = null } // Floating dtstarts (either VALUE=DATE or with no TZID) can default to the collection's tzid, if one is set - if ($start_date->GetParameterValue('VALUE') == 'DATE' && isset($collection_tzid)) { - $start_date = new RepeatRuleDateTime($start_date->Value()."T000000", new RepeatRuleTimeZone($collection_tzid)); - } else if ($start_date->GetParameterValue('TZID') === null && isset($collection_tzid)) { - $start_date = new RepeatRuleDateTime($start_date->Value(), new RepeatRuleTimeZone($collection_tzid)); - } else { - $start_date = new RepeatRuleDateTime($start_date); - } + $start_date = RepeatRuleDateTime::withFallbackTzid( $start_date, $collection_tzid ); $duration = $v->GetProperty('DURATION'); $duration = ( !isset($duration) ? 'P1D' : $duration->Value()); diff --git a/testing/phpunit/RangeTest.php b/testing/phpunit/RangeTest.php new file mode 100644 index 00000000..ac6d589c --- /dev/null +++ b/testing/phpunit/RangeTest.php @@ -0,0 +1,119 @@ +from->UTC()); + self::assertEquals("20190102T072000Z", (string) $range->until->UTC()); + + // TZ is specified in the event, so this should be unaffected by passing in a fallback timezone: + $range = getVCalendarRange($cal, "Asia/Baku"); + self::assertEquals("20181226T050000Z", (string) $range->from->UTC()); + self::assertEquals("20190102T072000Z", (string) $range->until->UTC()); + } + + public function testGetVCalendarRangeTwoDayAllDay() { + $cal = new vCalendar("BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VEVENT +CREATED:20181218T052603Z +LAST-MODIFIED:20181218T052734Z +DTSTAMP:20181218T052734Z +UID:7e76efc0-b1ed-4b68-b0ed-9e34889c30bd +SUMMARY:New Event +RRULE:FREQ=WEEKLY;COUNT=3;BYDAY=TU +DTSTART;VALUE=DATE:20181225 +DTEND;VALUE=DATE:20181227 +TRANSP:TRANSPARENT +END:VEVENT +END:VCALENDAR"); + + $range = getVCalendarRange($cal, "Asia/Baku"); + self::assertEquals("20181224T200000Z", (string) $range->from->UTC()); + self::assertEquals("20190109T200000Z", (string) $range->until->UTC()); + } + + public function testGetVCalendarRangeFloating() { + // When interpreted as being in Greece, this event crosses the daylight savings boundary! + // TODO deal with how that affects all-day events... + $cal = new vCalendar("BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VEVENT +CREATED:20181218T052603Z +LAST-MODIFIED:20181218T052734Z +DTSTAMP:20181218T052734Z +UID:7e76efc0-b1ed-4b68-b0ed-9e34889c30bd +SUMMARY:New Event +RRULE:FREQ=MONTHLY;COUNT=4;INTERVAL=2;BYMONTHDAY=10 +DTSTART:20180411T140000 +DTEND:20180411T150000 +TRANSP:TRANSPARENT +END:VEVENT +END:VCALENDAR"); + + $range = getVCalendarRange($cal, "Europe/Athens"); + self::assertEquals("20180411T110000Z", (string) $range->from->UTC()); + self::assertEquals("20181210T130000Z", (string) $range->until->UTC()); + } + + public function testGetVCalendarRangeAllDayAcrossDST() { + // When interpreted as being in Greece, this event crosses the daylight savings boundary! + + $cal = new vCalendar("BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VEVENT +CREATED:20181218T052603Z +LAST-MODIFIED:20181218T052734Z +DTSTAMP:20181218T052734Z +UID:7e76efc0-b1ed-4b68-b0ed-9e34889c30bd +SUMMARY:New Event +RRULE:FREQ=MONTHLY;COUNT=5;INTERVAL=2;BYMONTHDAY=10 +DTSTART;VALUE=DATE:20180410 +DTEND;VALUE=DATE:20180411 +TRANSP:TRANSPARENT +END:VEVENT +END:VCALENDAR"); + + $range = getVCalendarRange($cal, "Europe/Athens"); + self::assertEquals("20180409T210000Z", (string) $range->from->UTC()); + + // This is correctly at a different UTC time-of-day to the original, since DST has changed + self::assertEquals("20181210T220000Z", (string) $range->until->UTC()); + } +} diff --git a/testing/tests/regression-suite/0832-freebusy.result b/testing/tests/regression-suite/0832-freebusy.result index 7a2cbd7c..d5f5c52c 100644 --- a/testing/tests/regression-suite/0832-freebusy.result +++ b/testing/tests/regression-suite/0832-freebusy.result @@ -1,6 +1,6 @@ HTTP/1.1 200 OK Date: Dow, 01 Jan 2000 00:00:00 GMT -Content-Length: 14720 +Content-Length: 14764 Content-Type: text/calendar;charset=UTF-8 BEGIN:VCALENDAR @@ -11,6 +11,7 @@ BEGIN:VFREEBUSY DTSTAMP:yyyymmddThhmmssZ DTSTART:20060930T110000Z DTEND:correct +FREEBUSY:20031231T230000Z/20100217T000000Z FREEBUSY:20061001T210000Z/20061001T220000Z FREEBUSY:20061002T210000Z/20061002T220000Z FREEBUSY:20061003T210000Z/20061003T220000Z diff --git a/testing/tests/regression-suite/0836-freebusy.result b/testing/tests/regression-suite/0836-freebusy.result index 2417d3c2..d7ac2aa8 100644 --- a/testing/tests/regression-suite/0836-freebusy.result +++ b/testing/tests/regression-suite/0836-freebusy.result @@ -1,6 +1,6 @@ HTTP/1.1 200 OK Date: Dow, 01 Jan 2000 00:00:00 GMT -Content-Length: 14720 +Content-Length: 14764 Content-Type: text/calendar;charset=UTF-8 BEGIN:VCALENDAR @@ -11,6 +11,7 @@ BEGIN:VFREEBUSY DTSTAMP:yyyymmddThhmmssZ DTSTART:20060930T110000Z DTEND:20070630T115959Z +FREEBUSY:20031231T230000Z/20100217T000000Z FREEBUSY:20061001T210000Z/20061001T220000Z FREEBUSY:20061002T210000Z/20061002T220000Z FREEBUSY:20061003T210000Z/20061003T220000Z diff --git a/testing/tests/regression-suite/0837-freebusy.result b/testing/tests/regression-suite/0837-freebusy.result index 2417d3c2..d7ac2aa8 100644 --- a/testing/tests/regression-suite/0837-freebusy.result +++ b/testing/tests/regression-suite/0837-freebusy.result @@ -1,6 +1,6 @@ HTTP/1.1 200 OK Date: Dow, 01 Jan 2000 00:00:00 GMT -Content-Length: 14720 +Content-Length: 14764 Content-Type: text/calendar;charset=UTF-8 BEGIN:VCALENDAR @@ -11,6 +11,7 @@ BEGIN:VFREEBUSY DTSTAMP:yyyymmddThhmmssZ DTSTART:20060930T110000Z DTEND:20070630T115959Z +FREEBUSY:20031231T230000Z/20100217T000000Z FREEBUSY:20061001T210000Z/20061001T220000Z FREEBUSY:20061002T210000Z/20061002T220000Z FREEBUSY:20061003T210000Z/20061003T220000Z diff --git a/testing/tests/regression-suite/0880-Freebusy-POST.result b/testing/tests/regression-suite/0880-Freebusy-POST.result index 5d66cb38..18bc5305 100644 --- a/testing/tests/regression-suite/0880-Freebusy-POST.result +++ b/testing/tests/regression-suite/0880-Freebusy-POST.result @@ -14,6 +14,7 @@ BEGIN:VFREEBUSY DTSTAMP:yyyymmddThhmmssZ DTSTART:20081021T110000Z DTEND:20081106T110000Z +FREEBUSY:20031231T230000Z/20100217T000000Z FREEBUSY:20081021T180000Z/20081022T040000Z FREEBUSY:20081022T180000Z/20081023T040000Z FREEBUSY:20081022T184500Z/20081022T193000Z diff --git a/testing/tests/regression-suite/0885-GET-freebusy.result b/testing/tests/regression-suite/0885-GET-freebusy.result index 735a71d3..f111ffe4 100644 --- a/testing/tests/regression-suite/0885-GET-freebusy.result +++ b/testing/tests/regression-suite/0885-GET-freebusy.result @@ -1,6 +1,6 @@ HTTP/1.1 200 OK Date: Dow, 01 Jan 2000 00:00:00 GMT -Content-Length: 14720 +Content-Length: 14764 Content-Type: text/calendar;charset=UTF-8 BEGIN:VCALENDAR @@ -11,6 +11,7 @@ BEGIN:VFREEBUSY DTSTAMP:yyyymmddThhmmssZ DTSTART:20060930T110000Z DTEND:20070630T115959Z +FREEBUSY:20031231T230000Z/20100217T000000Z FREEBUSY:20061001T210000Z/20061001T220000Z FREEBUSY:20061002T210000Z/20061002T220000Z FREEBUSY:20061003T210000Z/20061003T220000Z diff --git a/testing/tests/regression-suite/0887-POST-freebusy.result b/testing/tests/regression-suite/0887-POST-freebusy.result index 264a1b93..1c7c65d0 100644 --- a/testing/tests/regression-suite/0887-POST-freebusy.result +++ b/testing/tests/regression-suite/0887-POST-freebusy.result @@ -14,6 +14,7 @@ BEGIN:VFREEBUSY DTSTAMP:yyyymmddThhmmssZ DTSTART:correct DTEND:correct +FREEBUSY:20031231T230000Z/20100217T000000Z FREEBUSY:20060930T210000Z/20060930T220000Z FREEBUSY:20061001T210000Z/20061001T220000Z FREEBUSY:20061002T210000Z/20061002T220000Z diff --git a/testing/tests/regression-suite/0888-GET-freebusy.result b/testing/tests/regression-suite/0888-GET-freebusy.result index 735a71d3..f111ffe4 100644 --- a/testing/tests/regression-suite/0888-GET-freebusy.result +++ b/testing/tests/regression-suite/0888-GET-freebusy.result @@ -1,6 +1,6 @@ HTTP/1.1 200 OK Date: Dow, 01 Jan 2000 00:00:00 GMT -Content-Length: 14720 +Content-Length: 14764 Content-Type: text/calendar;charset=UTF-8 BEGIN:VCALENDAR @@ -11,6 +11,7 @@ BEGIN:VFREEBUSY DTSTAMP:yyyymmddThhmmssZ DTSTART:20060930T110000Z DTEND:20070630T115959Z +FREEBUSY:20031231T230000Z/20100217T000000Z FREEBUSY:20061001T210000Z/20061001T220000Z FREEBUSY:20061002T210000Z/20061002T220000Z FREEBUSY:20061003T210000Z/20061003T220000Z diff --git a/testing/tests/regression-suite/0963-POST-freebusy-private.result b/testing/tests/regression-suite/0963-POST-freebusy-private.result index d38932b1..8a9c9edd 100644 --- a/testing/tests/regression-suite/0963-POST-freebusy-private.result +++ b/testing/tests/regression-suite/0963-POST-freebusy-private.result @@ -14,6 +14,7 @@ BEGIN:VFREEBUSY DTSTAMP:yyyymmddThhmmssZ DTSTART:20080730T110000Z DTEND:20080803T110000Z +FREEBUSY:20031231T230000Z/20100217T000000Z FREEBUSY:20080730T190000Z/20080731T050000Z FREEBUSY:20080730T194500Z/20080730T203000Z FREEBUSY:20080730T210000Z/20080730T220000Z diff --git a/testing/tests/regression-suite/Really-Upgrade-Database.result b/testing/tests/regression-suite/Really-Upgrade-Database.result index 379ba8dc..299acd5c 100644 --- a/testing/tests/regression-suite/Really-Upgrade-Database.result +++ b/testing/tests/regression-suite/Really-Upgrade-Database.result @@ -1,4 +1,4 @@ -The database is version XX currently at revision 1.3.2. +The database is version XX currently at revision 1.3.3. No patches were applied. Supported locales updated. Updated view: dav_principal.sql applied.