Calendar - fix bug in recurring event exception edit across timezones causing events to move or get lost

This commit is contained in:
nathangray 2017-07-31 12:39:15 -06:00
parent fe7e240321
commit 64a12f1ddd
2 changed files with 64 additions and 2 deletions

View File

@ -1206,7 +1206,7 @@ class calendar_boupdate extends calendar_bo
if (!isset($event['whole_day'])) $event['whole_day'] = $this->isWholeDay($event); if (!isset($event['whole_day'])) $event['whole_day'] = $this->isWholeDay($event);
// set recur-enddate/range-end to real end-date of last recurrence // set recur-enddate/range-end to real end-date of last recurrence
if ($event['recur_type'] != MCAL_RECUR_NONE && $event['recur_enddate']) if ($event['recur_type'] != MCAL_RECUR_NONE && $event['recur_enddate'] && $event['start'])
{ {
$event['recur_enddate'] = new Api\DateTime($event['recur_enddate'], calendar_timezones::DateTimeZone($event['tzid'])); $event['recur_enddate'] = new Api\DateTime($event['recur_enddate'], calendar_timezones::DateTimeZone($event['tzid']));
$event['recur_enddate']->setTime(23,59,59); $event['recur_enddate']->setTime(23,59,59);

View File

@ -46,7 +46,8 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
public function tearDown() public function tearDown()
{ {
//$this->bo->delete($this->cal_id); $this->bo->delete($this->cal_id);
$this->bo->delete($this->cal_id);
$this->bo = null; $this->bo = null;
// need to call preferences constructor and read_repository, to set user timezone again // need to call preferences constructor and read_repository, to set user timezone again
@ -103,6 +104,67 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
$this->checkEvent($timezones, $this->cal_id, $times); $this->checkEvent($timezones, $this->cal_id, $times);
} }
/**
* Test that making an exception works correctly, and does not modify the
* original series
*
* @param \EGroupware\calendar\Array $timezones
* @param \EGroupware\calendar\Array $times
*
* @dataProvider eventProvider
*/
public function testException($timezones, $times)
{
$this->setTimezones($timezones);
$event = $this->makeEvent($timezones, $times);
// Save the event
$this->cal_id = $this->bo->save($event);
// Make an exception for the second day
$start = new Api\DateTime($event['start']);
$start->modify('+1 day');
$exception = $event;
$preserve = array('actual_date', $start->format('ts'));
$ui = new \calendar_uiforms();
$ui->_create_exception($exception, $preserve);
// Move exception 1 hour later
$exception_start = new Api\DateTime($exception['start']);
$exception_start->modify('+1 hour');
$exception['start'] = $exception_start->format('ts');
$exception['end'] += 3600;
$exception_id = $this->bo->save($exception);
// now we need to add the original start as recur-execption to the series
$recur_event = $this->bo->read($event['reference']);
$recur_event['recur_exception'][] = $content['edit_single'];
unset($recur_event['start']); unset($recur_event['end']); // no update necessary
unset($recur_event['alarm']); // unsetting alarms too, as they cant be updated without start!
$this->bo->update($recur_event,true); // no conflict check here
// Load the event
// BO does caching, pass ID as array to avoid it
$loaded = $this->bo->read(Array($exception_id));
$loaded = $loaded[$exception_id];
$message = $this->makeMessage($timezones, $loaded);
// Check exception times
$this->assertEquals(
Api\DateTime::to($exception_start, Api\DateTime::DATABASE),
Api\DateTime::to($loaded['start'], Api\DateTime::DATABASE),
'Start date'. $message
);
// Check original event
$this->checkEvent($timezones, $this->cal_id, $times);
}
/** /**
* Load the event and check that it matches expectations * Load the event and check that it matches expectations
* *