forked from extern/egroupware
Calendar - All tests passing for daily recurring events, all day and otherwise
This commit is contained in:
parent
2d90927e53
commit
423caf7be2
@ -915,6 +915,9 @@ class calendar_bo
|
|||||||
$start = $this->date2ts($event['start'],true);
|
$start = $this->date2ts($event['start'],true);
|
||||||
if ($event['whole_day'])
|
if ($event['whole_day'])
|
||||||
{
|
{
|
||||||
|
$start = new Api\DateTime($event['start'], Api\DateTime::$server_timezone);
|
||||||
|
$start->setTime(0,0,0);
|
||||||
|
$start = $start->format('ts');
|
||||||
$time = $this->so->startOfDay(new Api\DateTime($event['end'], Api\DateTime::$user_timezone));
|
$time = $this->so->startOfDay(new Api\DateTime($event['end'], Api\DateTime::$user_timezone));
|
||||||
$time->setTime(23, 59, 59);
|
$time->setTime(23, 59, 59);
|
||||||
$end = $this->date2ts($time,true);
|
$end = $this->date2ts($time,true);
|
||||||
@ -1127,10 +1130,16 @@ class calendar_bo
|
|||||||
// unset exceptions, as we need to add them as recurrence too, but marked as exception
|
// unset exceptions, as we need to add them as recurrence too, but marked as exception
|
||||||
unset($event['recur_exception']);
|
unset($event['recur_exception']);
|
||||||
// loop over all recurrences and insert them, if they are after $start
|
// loop over all recurrences and insert them, if they are after $start
|
||||||
$rrule = calendar_rrule::event2rrule($event, true); // true = we operate in usertime, like the rest of calendar_bo
|
$rrule = calendar_rrule::event2rrule($event, !$event['whole_day'], Api\DateTime::$user_timezone->getName()); // true = we operate in usertime, like the rest of calendar_bo
|
||||||
foreach($rrule as $time)
|
foreach($rrule as $time)
|
||||||
{
|
{
|
||||||
$time->setUser(); // $time is in timezone of event, convert it to usertime used here
|
$time->setUser(); // $time is in timezone of event, convert it to usertime used here
|
||||||
|
if($event['whole_day'])
|
||||||
|
{
|
||||||
|
// All day events are processed in server timezone
|
||||||
|
$time->setServer();
|
||||||
|
$time->setTime(0,0,0);
|
||||||
|
}
|
||||||
if (($ts = $this->date2ts($time)) < $start-$event_length)
|
if (($ts = $this->date2ts($time)) < $start-$event_length)
|
||||||
{
|
{
|
||||||
//echo "<p>".$time." --> ignored as $ts < $start-$event_length</p>\n";
|
//echo "<p>".$time." --> ignored as $ts < $start-$event_length</p>\n";
|
||||||
|
@ -1211,6 +1211,13 @@ class calendar_boupdate extends calendar_bo
|
|||||||
if (!empty($event['end']))
|
if (!empty($event['end']))
|
||||||
{
|
{
|
||||||
$time = new Api\DateTime($event['end'], Api\DateTime::$user_timezone);
|
$time = new Api\DateTime($event['end'], Api\DateTime::$user_timezone);
|
||||||
|
|
||||||
|
// Check to see if switching timezones changes the date, we'll need to adjust for that
|
||||||
|
$end_event_timezone = clone $time;
|
||||||
|
$time->setServer();
|
||||||
|
$delta = (int)$end_event_timezone->format('z') - (int)$time->format('z');
|
||||||
|
$time->add("$delta days");
|
||||||
|
|
||||||
$time->setTime(23, 59, 59);
|
$time->setTime(23, 59, 59);
|
||||||
$event['end'] = Api\DateTime::to($time, 'ts');
|
$event['end'] = Api\DateTime::to($time, 'ts');
|
||||||
$save_event['end'] = $time;
|
$save_event['end'] = $time;
|
||||||
@ -1222,13 +1229,18 @@ class calendar_boupdate extends calendar_bo
|
|||||||
}
|
}
|
||||||
if (!empty($event['recur_enddate']))
|
if (!empty($event['recur_enddate']))
|
||||||
{
|
{
|
||||||
// all-day events are handled in server time
|
// all-day events are handled in server time, but here (BO) it's in user time
|
||||||
$time = $this->so->startOfDay(
|
$time = new Api\DateTime($event['recur_enddate'], Api\DateTime::$user_timezone);
|
||||||
new Api\DateTime($event['recur_enddate'], Api\DateTime::$server_timezone),
|
$time->setTime(23, 59, 59);
|
||||||
Api\DateTime::$server_timezone->getName()
|
// Check to see if switching timezones changes the date, we'll need to adjust for that
|
||||||
);
|
$enddate_event_timezone = clone $time;
|
||||||
$time->modify(($event['end'] - $event['start']).' seconds');
|
$time->setServer();
|
||||||
//$event['recur_enddate'] = $save_event['recur_enddate'] = Api\DateTime::to($time, 'ts');
|
$delta = (int)$enddate_event_timezone->format('z') - (int)$time->format('z');
|
||||||
|
$time->add("$delta days");
|
||||||
|
|
||||||
|
//$time->setServer();
|
||||||
|
$time->setTime(23, 59, 59);
|
||||||
|
|
||||||
$event['recur_enddate'] = $save_event['recur_enddate'] = $time;
|
$event['recur_enddate'] = $save_event['recur_enddate'] = $time;
|
||||||
}
|
}
|
||||||
$timestamps = array('modified','created');
|
$timestamps = array('modified','created');
|
||||||
|
@ -756,7 +756,7 @@ class calendar_rrule implements Iterator
|
|||||||
self::rrule2tz($event, $time, $to_tz);
|
self::rrule2tz($event, $time, $to_tz);
|
||||||
|
|
||||||
$time->setTimezone(self::$tz_cache[$to_tz]);
|
$time->setTimezone(self::$tz_cache[$to_tz]);
|
||||||
|
|
||||||
if ($event['recur_enddate'])
|
if ($event['recur_enddate'])
|
||||||
{
|
{
|
||||||
$enddate = is_a($event['recur_enddate'],'DateTime') ? clone $event['recur_enddate'] : new Api\DateTime($event['recur_enddate'],$timestamp_tz);
|
$enddate = is_a($event['recur_enddate'],'DateTime') ? clone $event['recur_enddate'] : new Api\DateTime($event['recur_enddate'],$timestamp_tz);
|
||||||
|
@ -21,9 +21,6 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
|
|||||||
|
|
||||||
protected $bo;
|
protected $bo;
|
||||||
|
|
||||||
// TODO: Do this at different times, at least 12 hours apart
|
|
||||||
const START_TIME = 9;
|
|
||||||
const END_TIME = 10;
|
|
||||||
const RECUR_DAYS = 5;
|
const RECUR_DAYS = 5;
|
||||||
|
|
||||||
protected $recur_end;
|
protected $recur_end;
|
||||||
@ -45,7 +42,6 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
|
|||||||
//$this->mockTracking($this->bo, 'calendar_tracking');
|
//$this->mockTracking($this->bo, 'calendar_tracking');
|
||||||
|
|
||||||
$this->recur_end = new Api\DateTime(mktime(0,0,0,date('m'), date('d') + static::RECUR_DAYS, date('Y')));
|
$this->recur_end = new Api\DateTime(mktime(0,0,0,date('m'), date('d') + static::RECUR_DAYS, date('Y')));
|
||||||
echo "End date: " . $this->recur_end->format('Y-m-d') . '(Event time)';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown()
|
public function tearDown()
|
||||||
@ -66,25 +62,22 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
|
|||||||
* event to make sure it has the correct number of days, and its timezone
|
* event to make sure it has the correct number of days, and its timezone
|
||||||
* stays as set.
|
* stays as set.
|
||||||
*
|
*
|
||||||
* @param type $timezones
|
* @param Array $timezones Timezone settings for event, client & server
|
||||||
|
* @param Array $times Start & end hours
|
||||||
*
|
*
|
||||||
* @dataProvider eventProvider
|
* @dataProvider eventProvider
|
||||||
*/
|
*/
|
||||||
public function testTimezones($timezones)
|
public function testTimezones($timezones, $times)
|
||||||
{
|
{
|
||||||
|
|
||||||
echo $this->tzString($timezones)."\n";
|
|
||||||
|
|
||||||
$this->setTimezones($timezones);
|
$this->setTimezones($timezones);
|
||||||
|
|
||||||
$event = $this->makeEvent($timezones);
|
$event = $this->makeEvent($timezones, $times);
|
||||||
|
|
||||||
|
|
||||||
// Save the event
|
// Save the event
|
||||||
$this->cal_id = $this->bo->save($event);
|
$this->cal_id = $this->bo->save($event);
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
$this->checkEvent($timezones, $this->cal_id);
|
$this->checkEvent($timezones, $this->cal_id, $times);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,38 +85,45 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
|
|||||||
* all day event to make sure it has the correct number of days, and its timezone
|
* all day event to make sure it has the correct number of days, and its timezone
|
||||||
* stays as set.
|
* stays as set.
|
||||||
*
|
*
|
||||||
* @param type $timezones
|
* @param Array $timezones Timezone settings for event, client & server
|
||||||
|
* @param Array $times Start & end hours
|
||||||
*
|
*
|
||||||
* @dataProvider eventProvider
|
* @dataProvider eventProvider
|
||||||
*/
|
*/
|
||||||
public function notestTimezonesAllDay($timezones)
|
public function testTimezonesAllDay($timezones, $times)
|
||||||
{
|
{
|
||||||
echo $this->tzString($timezones)."\n";
|
|
||||||
|
|
||||||
$this->setTimezones($timezones);
|
$this->setTimezones($timezones);
|
||||||
|
|
||||||
$event = $this->makeEvent($timezones, true);
|
$event = $this->makeEvent($timezones, $times, true);
|
||||||
|
|
||||||
|
|
||||||
// Save the event
|
// Save the event
|
||||||
$this->cal_id = $this->bo->save($event);
|
$this->cal_id = $this->bo->save($event);
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
$this->checkEvent($timezones, $this->cal_id);
|
$this->checkEvent($timezones, $this->cal_id, $times);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function checkEvent($timezones, $cal_id)
|
/**
|
||||||
|
* Load the event and check that it matches expectations
|
||||||
|
*
|
||||||
|
* @param Array $timezones List of timezones (event, client, server)
|
||||||
|
* @param int $cal_id
|
||||||
|
* @param Array $times start and end times (just hours)
|
||||||
|
*/
|
||||||
|
protected function checkEvent($timezones, $cal_id, $times)
|
||||||
{
|
{
|
||||||
// Load the event
|
// Load the event
|
||||||
// BO does caching, need array to avoid it
|
// BO does caching, pass ID as array to avoid it
|
||||||
$loaded = $this->bo->read(Array($cal_id));
|
$loaded = $this->bo->read(Array($cal_id));
|
||||||
$loaded = $loaded[$cal_id];
|
$loaded = $loaded[$cal_id];
|
||||||
|
|
||||||
$message = $this->makeMessage($timezones, $loaded);
|
$message = $this->makeMessage($timezones, $loaded);
|
||||||
|
|
||||||
|
$start_time = \mktime($loaded['whole_day'] ? 0 : $times['start'], 0, 0, date('m'), date('d')+1, date('Y'));
|
||||||
|
|
||||||
// Check that the start date is the same (user time)
|
// Check that the start date is the same (user time)
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
Api\DateTime::to(\mktime($loaded['whole_day'] ? 0 : static::START_TIME, 0, 0, date('m'), date('d')+1, date('Y')), Api\DateTime::DATABASE),
|
Api\DateTime::to($start_time, Api\DateTime::DATABASE),
|
||||||
Api\DateTime::to($loaded['start'], Api\DateTime::DATABASE),
|
Api\DateTime::to($loaded['start'], Api\DateTime::DATABASE),
|
||||||
'Start date'. $message
|
'Start date'. $message
|
||||||
);
|
);
|
||||||
@ -132,7 +132,7 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
|
|||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
Api\DateTime::to(
|
Api\DateTime::to(
|
||||||
$loaded['whole_day'] ? \mktime(0, 0, 0, date('m'), date('d')+2, date('Y'))-1 :
|
$loaded['whole_day'] ? \mktime(0, 0, 0, date('m'), date('d')+2, date('Y'))-1 :
|
||||||
\mktime(static::END_TIME, 0, 0, date('m'), date('d')+1, date('Y')
|
\mktime($times['end'], 0, 0, date('m'), date('d')+1, date('Y')
|
||||||
), Api\DateTime::DATABASE),
|
), Api\DateTime::DATABASE),
|
||||||
Api\DateTime::to($loaded['end'], Api\DateTime::DATABASE),
|
Api\DateTime::to($loaded['end'], Api\DateTime::DATABASE),
|
||||||
'End date'. $message
|
'End date'. $message
|
||||||
@ -148,7 +148,16 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
|
|||||||
// Recurrences
|
// Recurrences
|
||||||
$so = new \calendar_so();
|
$so = new \calendar_so();
|
||||||
$recurrences = $so->get_recurrences($cal_id);
|
$recurrences = $so->get_recurrences($cal_id);
|
||||||
$this->assertEquals(static::RECUR_DAYS, count($recurrences)-1, 'Recurrence count' . $message);
|
unset($recurrences[0]);
|
||||||
|
$this->assertEquals(static::RECUR_DAYS, count($recurrences), 'Recurrence count' . $message);
|
||||||
|
foreach($recurrences as $recur_start_time => $participant)
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
Api\DateTime::to($start_time, 'H:i:s'),
|
||||||
|
$loaded['whole_day'] ? '00:00:00' : Api\DateTime::to(Api\DateTime::server2user($recur_start_time), 'H:i:s'),
|
||||||
|
'Recurrence start time' . $message
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,11 +166,22 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
|
|||||||
public function eventProvider()
|
public function eventProvider()
|
||||||
{
|
{
|
||||||
$tests = array();
|
$tests = array();
|
||||||
$tz_combos = $this->makeCombos();
|
$tz_combos = $this->makeTZCombos();
|
||||||
|
|
||||||
|
// Start times to test, 1 chosen to cross days
|
||||||
|
$times = array(1, 9);
|
||||||
|
|
||||||
foreach($tz_combos as $timezones)
|
foreach($tz_combos as $timezones)
|
||||||
{
|
{
|
||||||
$tests[] = Array($timezones);
|
foreach($times as $start_time)
|
||||||
|
{
|
||||||
|
$tests[] = Array($timezones,
|
||||||
|
Array(
|
||||||
|
'start' => $start_time,
|
||||||
|
'end' => $start_time + 1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tests;
|
return $tests;
|
||||||
@ -171,15 +191,16 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
|
|||||||
* Make a map of all the different client / server / event combinations
|
* Make a map of all the different client / server / event combinations
|
||||||
* that we'll use.
|
* that we'll use.
|
||||||
*/
|
*/
|
||||||
protected function makeCombos()
|
protected function makeTZCombos()
|
||||||
{
|
{
|
||||||
// Timezone list
|
// Timezone list
|
||||||
$tz_list = Array(
|
$tz_list = Array(
|
||||||
'Pacific/Tahiti', // -10
|
'Pacific/Tahiti', // -10
|
||||||
'America/Edmonton', // -8
|
|
||||||
'Europe/Berlin', // +2
|
'Europe/Berlin', // +2
|
||||||
'Pacific/Auckland', // +12
|
// The first 2 are usually sufficient
|
||||||
'UTC'
|
//'America/Edmonton', // -8
|
||||||
|
//'Pacific/Auckland', // +12
|
||||||
|
//'UTC'
|
||||||
);
|
);
|
||||||
$tz_combos = Array();
|
$tz_combos = Array();
|
||||||
|
|
||||||
@ -218,16 +239,16 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
|
|||||||
* Make the array of event information
|
* Make the array of event information
|
||||||
*
|
*
|
||||||
* @param Array $timezones
|
* @param Array $timezones
|
||||||
* @param boolean $whole_day
|
|
||||||
* @return Array Event array, unsaved.
|
* @return Array Event array, unsaved.
|
||||||
|
* @param boolean $whole_day
|
||||||
*/
|
*/
|
||||||
protected function makeEvent($timezones, $whole_day = false)
|
protected function makeEvent($timezones, $times, $whole_day = false)
|
||||||
{
|
{
|
||||||
$event = array(
|
$event = array(
|
||||||
'title' => ($whole_day ? 'Whole day ' : '')."Test for " . $this->tzString($timezones),
|
'title' => ($whole_day ? 'Whole day ' : '')."Test for " . $this->tzString($timezones),
|
||||||
'des' => ($whole_day ? 'Whole day ' : '').'Test for test ' . $this->getName() . ' ' . $this->tzString($timezones),
|
'des' => ($whole_day ? 'Whole day ' : '').'Test for test ' . $this->getName() . ' ' . $this->tzString($timezones),
|
||||||
'start' => \mktime(static::START_TIME, 0, 0, date('m'), date('d')+1, date('Y')),
|
'start' => \mktime($whole_day ? 0 : $times['start'], 0, 0, date('m'), date('d')+1, date('Y')),
|
||||||
'end' => \mktime(static::END_TIME, 0, 0, date('m'), date('d')+1, date('Y')),
|
'end' => $whole_day ? \mktime(23, 59, 59, date('m'), date('d')+1, date('Y')) : \mktime($times['end'], 0, 0, date('m'), date('d')+1, date('Y')),
|
||||||
'tzid' => $timezones['event'],
|
'tzid' => $timezones['event'],
|
||||||
'recur_type' => 1, // MCAL_RECUR_DAILY
|
'recur_type' => 1, // MCAL_RECUR_DAILY
|
||||||
'recur_enddate' => $this->recur_end->format('ts'),
|
'recur_enddate' => $this->recur_end->format('ts'),
|
||||||
@ -241,7 +262,7 @@ class TimezoneTest extends \EGroupware\Api\AppTest {
|
|||||||
|
|
||||||
protected function makeMessage($timezones, $event)
|
protected function makeMessage($timezones, $event)
|
||||||
{
|
{
|
||||||
return ' ' . Api\DateTime::to($event['recur_enddate'], Api\DateTime::DATABASE) . ' '.
|
return ' ' . ($event['id'] ? '[#'.$event['id'] .'] ' : '') . Api\DateTime::to($event['recur_enddate'], Api\DateTime::DATABASE) . ' '.
|
||||||
($event['whole_day'] ? '(whole day) ' : '') . $this->tzString($timezones);
|
($event['whole_day'] ? '(whole day) ' : '') . $this->tzString($timezones);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user