This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,179 @@
<?php
namespace Sabre\VObject\Component;
use Sabre\VObject\Component;
use DateTime;
use Sabre\VObject\Reader;
class VAlarmTest extends \PHPUnit_Framework_TestCase {
/**
* @dataProvider timeRangeTestData
*/
public function testInTimeRange(VAlarm $valarm,$start,$end,$outcome) {
$this->assertEquals($outcome, $valarm->isInTimeRange($start, $end));
}
public function timeRangeTestData() {
$tests = array();
$calendar = new VCalendar();
// Hard date and time
$valarm1 = $calendar->createComponent('VALARM');
$valarm1->add(
$calendar->createProperty('TRIGGER', '20120312T130000Z', array('VALUE' => 'DATE-TIME'))
);
$tests[] = array($valarm1, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-04-01 01:00:00'), true);
$tests[] = array($valarm1, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-03-10 01:00:00'), false);
// Relation to start time of event
$valarm2 = $calendar->createComponent('VALARM');
$valarm2->add(
$calendar->createProperty('TRIGGER', '-P1D', array('VALUE' => 'DURATION'))
);
$vevent2 = $calendar->createComponent('VEVENT');
$vevent2->DTSTART = '20120313T130000Z';
$vevent2->add($valarm2);
$tests[] = array($valarm2, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-04-01 01:00:00'), true);
$tests[] = array($valarm2, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-03-10 01:00:00'), false);
// Relation to end time of event
$valarm3 = $calendar->createComponent('VALARM');
$valarm3->add( $calendar->createProperty('TRIGGER', '-P1D', array('VALUE'=>'DURATION', 'RELATED' => 'END')) );
$vevent3 = $calendar->createComponent('VEVENT');
$vevent3->DTSTART = '20120301T130000Z';
$vevent3->DTEND = '20120401T130000Z';
$vevent3->add($valarm3);
$tests[] = array($valarm3, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), false);
$tests[] = array($valarm3, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), true);
// Relation to end time of todo
$valarm4 = $calendar->createComponent('VALARM');
$valarm4->TRIGGER = '-P1D';
$valarm4->TRIGGER['VALUE'] = 'DURATION';
$valarm4->TRIGGER['RELATED']= 'END';
$vtodo4 = $calendar->createComponent('VTODO');
$vtodo4->DTSTART = '20120301T130000Z';
$vtodo4->DUE = '20120401T130000Z';
$vtodo4->add($valarm4);
$tests[] = array($valarm4, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), false);
$tests[] = array($valarm4, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), true);
// Relation to start time of event + repeat
$valarm5 = $calendar->createComponent('VALARM');
$valarm5->TRIGGER = '-P1D';
$valarm5->TRIGGER['VALUE'] = 'DURATION';
$valarm5->REPEAT = 10;
$valarm5->DURATION = 'P1D';
$vevent5 = $calendar->createComponent('VEVENT');
$vevent5->DTSTART = '20120301T130000Z';
$vevent5->add($valarm5);
$tests[] = array($valarm5, new DateTime('2012-03-09 01:00:00'), new DateTime('2012-03-10 01:00:00'), true);
// Relation to start time of event + duration, but no repeat
$valarm6 = $calendar->createComponent('VALARM');
$valarm6->TRIGGER = '-P1D';
$valarm6->TRIGGER['VALUE'] = 'DURATION';
$valarm6->DURATION = 'P1D';
$vevent6 = $calendar->createComponent('VEVENT');
$vevent6->DTSTART = '20120313T130000Z';
$vevent6->add($valarm6);
$tests[] = array($valarm6, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-04-01 01:00:00'), true);
$tests[] = array($valarm6, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-03-10 01:00:00'), false);
// Relation to end time of event (DURATION instead of DTEND)
$valarm7 = $calendar->createComponent('VALARM');
$valarm7->TRIGGER = '-P1D';
$valarm7->TRIGGER['VALUE'] = 'DURATION';
$valarm7->TRIGGER['RELATED']= 'END';
$vevent7 = $calendar->createComponent('VEVENT');
$vevent7->DTSTART = '20120301T130000Z';
$vevent7->DURATION = 'P30D';
$vevent7->add($valarm7);
$tests[] = array($valarm7, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), false);
$tests[] = array($valarm7, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), true);
// Relation to end time of event (No DTEND or DURATION)
$valarm7 = $calendar->createComponent('VALARM');
$valarm7->TRIGGER = '-P1D';
$valarm7->TRIGGER['VALUE'] = 'DURATION';
$valarm7->TRIGGER['RELATED']= 'END';
$vevent7 = $calendar->createComponent('VEVENT');
$vevent7->DTSTART = '20120301T130000Z';
$vevent7->add($valarm7);
$tests[] = array($valarm7, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), true);
$tests[] = array($valarm7, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), false);
return $tests;
}
/**
* @expectedException LogicException
*/
public function testInTimeRangeInvalidComponent() {
$calendar = new VCalendar();
$valarm = $calendar->createComponent('VALARM');
$valarm->TRIGGER = '-P1D';
$valarm->TRIGGER['RELATED'] = 'END';
$vjournal = $calendar->createComponent('VJOURNAL');
$vjournal->add($valarm);
$valarm->isInTimeRange(new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'));
}
/**
* This bug was found and reported on the mailing list.
*/
public function testInTimeRangeBuggy() {
$input = <<<BLA
BEGIN:VCALENDAR
BEGIN:VTODO
DTSTAMP:20121003T064931Z
UID:b848cb9a7bb16e464a06c222ca1f8102@examle.com
STATUS:NEEDS-ACTION
DUE:20121005T000000Z
SUMMARY:Task 1
CATEGORIES:AlarmCategory
BEGIN:VALARM
TRIGGER:-PT10M
ACTION:DISPLAY
DESCRIPTION:Task 1
END:VALARM
END:VTODO
END:VCALENDAR
BLA;
$vobj = Reader::read($input);
$this->assertTrue($vobj->VTODO->VALARM->isInTimeRange(new \DateTime('2012-10-01 00:00:00'), new \DateTime('2012-11-01 00:00:00')));
}
}

View File

@@ -0,0 +1,385 @@
<?php
namespace Sabre\VObject\Component;
use Sabre\VObject;
use Sabre\VObject\Reader;
use Sabre\VObject\Component;
use Sabre\VObject\Component\VAvailability;
/**
* We use `RFCxxx` has a placeholder for the
* https://tools.ietf.org/html/draft-daboo-calendar-availability-05 name.
*/
class VAvailabilityTest extends \PHPUnit_Framework_TestCase {
function testVAvailabilityComponent() {
$vcal = <<<VCAL
BEGIN:VCALENDAR
BEGIN:VAVAILABILITY
END:VAVAILABILITY
END:VCALENDAR
VCAL;
$document = Reader::read($vcal);
$this->assertInstanceOf(__NAMESPACE__ . '\VAvailability', $document->VAVAILABILITY);
}
function testRFCxxxSection3_1_availabilityprop_required() {
// UID and DTSTAMP are present.
$this->assertIsValid(Reader::read(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
UID:foo@test
DTSTAMP:20111005T133225Z
END:VAVAILABILITY
END:VCALENDAR
VCAL
));
// UID and DTSTAMP are missing.
$this->assertIsNotValid(Reader::read(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
END:VAVAILABILITY
END:VCALENDAR
VCAL
));
// DTSTAMP is missing.
$this->assertIsNotValid(Reader::read(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
UID:foo@test
END:VAVAILABILITY
END:VCALENDAR
VCAL
));
// UID is missing.
$this->assertIsNotValid(Reader::read(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
DTSTAMP:20111005T133225Z
END:VAVAILABILITY
END:VCALENDAR
VCAL
));
}
function testRFCxxxSection3_1_availabilityprop_optional_once() {
$properties = array(
'BUSYTYPE:BUSY',
'CLASS:PUBLIC',
'CREATED:20111005T135125Z',
'DESCRIPTION:Long bla bla',
'DTSTART:20111005T020000',
'LAST-MODIFIED:20111005T135325Z',
'ORGANIZER:mailto:foo@example.com',
'PRIORITY:1',
'SEQUENCE:0',
'SUMMARY:Bla bla',
'URL:http://example.org/'
);
// They are all present, only once.
$this->assertIsValid(Reader::read($this->template($properties)));
// We duplicate each one to see if it fails.
foreach ($properties as $property) {
$this->assertIsNotValid(Reader::read($this->template(array(
$property,
$property
))));
}
}
function testRFCxxxSection3_1_availabilityprop_dtend_duration() {
// Only DTEND.
$this->assertIsValid(Reader::read($this->template(array(
'DTEND:21111005T133225Z'
))));
// Only DURATION.
$this->assertIsValid(Reader::read($this->template(array(
'DURATION:PT1H'
))));
// Both (not allowed).
$this->assertIsNotValid(Reader::read($this->template(array(
'DTEND:21111005T133225Z',
'DURATION:PT1H'
))));
}
function testAvailableSubComponent() {
$vcal = <<<VCAL
BEGIN:VCALENDAR
BEGIN:VAVAILABILITY
BEGIN:AVAILABLE
END:AVAILABLE
END:VAVAILABILITY
END:VCALENDAR
VCAL;
$document = Reader::read($vcal);
$this->assertInstanceOf(__NAMESPACE__, $document->VAVAILABILITY->AVAILABLE);
}
function testRFCxxxSection3_1_availableprop_required() {
// UID, DTSTAMP and DTSTART are present.
$this->assertIsValid(Reader::read(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
UID:foo@test
DTSTAMP:20111005T133225Z
BEGIN:AVAILABLE
UID:foo@test
DTSTAMP:20111005T133225Z
DTSTART:20111005T133225Z
END:AVAILABLE
END:VAVAILABILITY
END:VCALENDAR
VCAL
));
// UID, DTSTAMP and DTSTART are missing.
$this->assertIsNotValid(Reader::read(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
UID:foo@test
DTSTAMP:20111005T133225Z
BEGIN:AVAILABLE
END:AVAILABLE
END:VAVAILABILITY
END:VCALENDAR
VCAL
));
// UID is missing.
$this->assertIsNotValid(Reader::read(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
UID:foo@test
DTSTAMP:20111005T133225Z
BEGIN:AVAILABLE
DTSTAMP:20111005T133225Z
DTSTART:20111005T133225Z
END:AVAILABLE
END:VAVAILABILITY
END:VCALENDAR
VCAL
));
// DTSTAMP is missing.
$this->assertIsNotValid(Reader::read(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
UID:foo@test
DTSTAMP:20111005T133225Z
BEGIN:AVAILABLE
UID:foo@test
DTSTART:20111005T133225Z
END:AVAILABLE
END:VAVAILABILITY
END:VCALENDAR
VCAL
));
// DTSTART is missing.
$this->assertIsNotValid(Reader::read(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
UID:foo@test
DTSTAMP:20111005T133225Z
BEGIN:AVAILABLE
UID:foo@test
DTSTAMP:20111005T133225Z
END:AVAILABLE
END:VAVAILABILITY
END:VCALENDAR
VCAL
));
}
function testRFCxxxSection3_1_available_dtend_duration() {
// Only DTEND.
$this->assertIsValid(Reader::read($this->templateAvailable(array(
'DTEND:21111005T133225Z'
))));
// Only DURATION.
$this->assertIsValid(Reader::read($this->templateAvailable(array(
'DURATION:PT1H'
))));
// Both (not allowed).
$this->assertIsNotValid(Reader::read($this->templateAvailable(array(
'DTEND:21111005T133225Z',
'DURATION:PT1H'
))));
}
function testRFCxxxSection3_1_available_optional_once() {
$properties = array(
'CREATED:20111005T135125Z',
'DESCRIPTION:Long bla bla',
'LAST-MODIFIED:20111005T135325Z',
'RECURRENCE-ID;RANGE=THISANDFUTURE:19980401T133000Z',
'RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR',
'SUMMARY:Bla bla'
);
// They are all present, only once.
$this->assertIsValid(Reader::read($this->templateAvailable($properties)));
// We duplicate each one to see if it fails.
foreach ($properties as $property) {
$this->assertIsNotValid(Reader::read($this->templateAvailable(array(
$property,
$property
))));
}
}
function testRFCxxxSection3_2() {
$this->assertEquals(
'BUSY',
Reader::read($this->templateAvailable(array(
'BUSYTYPE:BUSY'
)))
->VAVAILABILITY
->AVAILABLE
->BUSYTYPE
->getValue()
);
$this->assertEquals(
'BUSY-UNAVAILABLE',
Reader::read($this->templateAvailable(array(
'BUSYTYPE:BUSY-UNAVAILABLE'
)))
->VAVAILABILITY
->AVAILABLE
->BUSYTYPE
->getValue()
);
$this->assertEquals(
'BUSY-TENTATIVE',
Reader::read($this->templateAvailable(array(
'BUSYTYPE:BUSY-TENTATIVE'
)))
->VAVAILABILITY
->AVAILABLE
->BUSYTYPE
->getValue()
);
}
protected function assertIsValid(VObject\Document $document) {
$this->assertEmpty($document->validate());
}
protected function assertIsNotValid(VObject\Document $document) {
$this->assertNotEmpty($document->validate());
}
protected function template(array $properties) {
return $this->_template(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
UID:foo@test
DTSTAMP:20111005T133225Z
END:VAVAILABILITY
END:VCALENDAR
VCAL
,
$properties
);
}
protected function templateAvailable(array $properties) {
return $this->_template(
<<<VCAL
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id
BEGIN:VAVAILABILITY
UID:foo@test
DTSTAMP:20111005T133225Z
BEGIN:AVAILABLE
UID:foo@test
DTSTAMP:20111005T133225Z
DTSTART:20111005T133225Z
END:AVAILABLE
END:VAVAILABILITY
END:VCALENDAR
VCAL
,
$properties
);
}
protected function _template($template, array $properties) {
return str_replace('…', implode("\r\n", $properties), $template);
}
}

View File

@@ -0,0 +1,697 @@
<?php
namespace Sabre\VObject\Component;
use DateTimeZone;
use Sabre\VObject;
class VCalendarTest extends \PHPUnit_Framework_TestCase {
/**
* @dataProvider expandData
*/
public function testExpand($input, $output, $timeZone = 'UTC', $start = '2011-12-01', $end = '2011-12-31') {
$vcal = VObject\Reader::read($input);
$timeZone = new DateTimeZone($timeZone);
$vcal->expand(
new \DateTime($start),
new \DateTime($end),
$timeZone
);
// This will normalize the output
$output = VObject\Reader::read($output)->serialize();
$this->assertEquals($output, $vcal->serialize());
}
public function expandData() {
$tests = array();
// No data
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
END:VCALENDAR
';
$output = $input;
$tests[] = array($input,$output);
// Simple events
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla
SUMMARY:InExpand
DTSTART;VALUE=DATE:20111202
END:VEVENT
BEGIN:VEVENT
UID:bla2
SUMMARY:NotInExpand
DTSTART;VALUE=DATE:20120101
END:VEVENT
END:VCALENDAR
';
$output = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla
SUMMARY:InExpand
DTSTART;VALUE=DATE:20111202
END:VEVENT
END:VCALENDAR
';
$tests[] = array($input, $output);
// Removing timezone info
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Europe/Paris
END:VTIMEZONE
BEGIN:VEVENT
UID:bla4
SUMMARY:RemoveTZ info
DTSTART;TZID=Europe/Paris:20111203T130102
END:VEVENT
END:VCALENDAR
';
$output = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla4
SUMMARY:RemoveTZ info
DTSTART:20111203T120102Z
END:VEVENT
END:VCALENDAR
';
$tests[] = array($input, $output);
// Recurrence rule
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART:20111125T120000Z
DTEND:20111125T130000Z
RRULE:FREQ=WEEKLY
END:VEVENT
END:VCALENDAR
';
$output = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART:20111202T120000Z
DTEND:20111202T130000Z
RECURRENCE-ID:20111202T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART:20111209T120000Z
DTEND:20111209T130000Z
RECURRENCE-ID:20111209T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART:20111216T120000Z
DTEND:20111216T130000Z
RECURRENCE-ID:20111216T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART:20111223T120000Z
DTEND:20111223T130000Z
RECURRENCE-ID:20111223T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART:20111230T120000Z
DTEND:20111230T130000Z
RECURRENCE-ID:20111230T120000Z
END:VEVENT
END:VCALENDAR
';
$tests[] = array($input, $output);
// Recurrence rule + override
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule2
DTSTART:20111125T120000Z
DTEND:20111125T130000Z
RRULE:FREQ=WEEKLY
END:VEVENT
BEGIN:VEVENT
UID:bla6
RECURRENCE-ID:20111209T120000Z
DTSTART:20111209T140000Z
DTEND:20111209T150000Z
SUMMARY:Override!
END:VEVENT
END:VCALENDAR
';
$output = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule2
DTSTART:20111202T120000Z
DTEND:20111202T130000Z
RECURRENCE-ID:20111202T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
RECURRENCE-ID:20111209T120000Z
DTSTART:20111209T140000Z
DTEND:20111209T150000Z
SUMMARY:Override!
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule2
DTSTART:20111216T120000Z
DTEND:20111216T130000Z
RECURRENCE-ID:20111216T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule2
DTSTART:20111223T120000Z
DTEND:20111223T130000Z
RECURRENCE-ID:20111223T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule2
DTSTART:20111230T120000Z
DTEND:20111230T130000Z
RECURRENCE-ID:20111230T120000Z
END:VEVENT
END:VCALENDAR
';
$tests[] = array($input, $output);
// Floating dates and times.
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:bla1
DTSTART:20141112T195000
END:VEVENT
BEGIN:VEVENT
UID:bla2
DTSTART;VALUE=DATE:20141112
END:VEVENT
BEGIN:VEVENT
UID:bla3
DTSTART;VALUE=DATE:20141112
RRULE:FREQ=DAILY;COUNT=2
END:VEVENT
END:VCALENDAR
ICS;
$output = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:bla1
DTSTART:20141112T225000Z
END:VEVENT
BEGIN:VEVENT
UID:bla2
DTSTART;VALUE=DATE:20141112
END:VEVENT
BEGIN:VEVENT
UID:bla3
DTSTART;VALUE=DATE:20141112
RECURRENCE-ID;VALUE=DATE:20141112
END:VEVENT
BEGIN:VEVENT
UID:bla3
DTSTART;VALUE=DATE:20141113
RECURRENCE-ID;VALUE=DATE:20141113
END:VEVENT
END:VCALENDAR
ICS;
$tests[] = array($input, $output, 'America/Argentina/Buenos_Aires', '2014-01-01', '2015-01-01');
// Recurrence rule with no valid instances
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule3
DTSTART:20111125T120000Z
DTEND:20111125T130000Z
RRULE:FREQ=WEEKLY;COUNT=1
EXDATE:20111125T120000Z
END:VEVENT
END:VCALENDAR
';
$output = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
END:VCALENDAR
';
$tests[] = array($input, $output);
return $tests;
}
/**
* @expectedException LogicException
*/
public function testBrokenEventExpand() {
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
RRULE:FREQ=WEEKLY
DTSTART;VALUE=DATE:20111202
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$vcal->expand(
new \DateTime('2011-12-01'),
new \DateTime('2011-12-31')
);
}
function testGetDocumentType() {
$vcard = new VCalendar();
$vcard->VERSION = '2.0';
$this->assertEquals(VCalendar::ICALENDAR20, $vcard->getDocumentType());
}
function testValidateCorrect() {
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
PRODID:foo
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
DTSTAMP:20140122T233226Z
UID:foo
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$this->assertEquals(array(), $vcal->validate(), 'Got an error');
}
function testValidateNoVersion() {
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
PRODID:foo
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$this->assertEquals(1, count($vcal->validate()));
}
function testValidateWrongVersion() {
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:3.0
PRODID:foo
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$this->assertEquals(1, count($vcal->validate()));
}
function testValidateNoProdId() {
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$this->assertEquals(1, count($vcal->validate()));
}
function testValidateDoubleCalScale() {
$input = 'BEGIN:VCALENDAR
VERSION:2.0
PRODID:foo
CALSCALE:GREGORIAN
CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$this->assertEquals(1, count($vcal->validate()));
}
function testValidateDoubleMethod() {
$input = 'BEGIN:VCALENDAR
VERSION:2.0
PRODID:foo
METHOD:REQUEST
METHOD:REQUEST
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$this->assertEquals(1, count($vcal->validate()));
}
function testValidateTwoMasterEvents() {
$input = 'BEGIN:VCALENDAR
VERSION:2.0
PRODID:foo
METHOD:REQUEST
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$this->assertEquals(1, count($vcal->validate()));
}
function testValidateOneMasterEvent() {
$input = 'BEGIN:VCALENDAR
VERSION:2.0
PRODID:foo
METHOD:REQUEST
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
RECURRENCE-ID;VALUE=DATE:20111202
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$this->assertEquals(0, count($vcal->validate()));
}
function testGetBaseComponent() {
$input = 'BEGIN:VCALENDAR
VERSION:2.0
PRODID:foo
METHOD:REQUEST
BEGIN:VEVENT
SUMMARY:test
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
RECURRENCE-ID;VALUE=DATE:20111202
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$result = $vcal->getBaseComponent();
$this->assertEquals('test', $result->SUMMARY->getValue());
}
function testGetBaseComponentNoResult() {
$input = 'BEGIN:VCALENDAR
VERSION:2.0
PRODID:foo
METHOD:REQUEST
BEGIN:VEVENT
SUMMARY:test
RECURRENCE-ID;VALUE=DATE:20111202
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20111202
UID:foo
DTSTAMP:20140122T234434Z
RECURRENCE-ID;VALUE=DATE:20111202
END:VEVENT
END:VCALENDAR
';
$vcal = VObject\Reader::read($input);
$result = $vcal->getBaseComponent();
$this->assertNull($result);
}
function testNoComponents() {
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:vobject
END:VCALENDAR
ICS;
$this->assertValidate(
$input,
0,
3,
"An iCalendar object must have at least 1 component."
);
}
function testCalDAVNoComponents() {
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:vobject
BEGIN:VTIMEZONE
TZID:America/Toronto
END:VTIMEZONE
END:VCALENDAR
ICS;
$this->assertValidate(
$input,
VCalendar::PROFILE_CALDAV,
3,
"A calendar object on a CalDAV server must have at least 1 component (VTODO, VEVENT, VJOURNAL)."
);
}
function testCalDAVMultiUID() {
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:vobject
BEGIN:VEVENT
UID:foo
DTSTAMP:20150109T184500Z
DTSTART:20150109T184500Z
END:VEVENT
BEGIN:VEVENT
UID:bar
DTSTAMP:20150109T184500Z
DTSTART:20150109T184500Z
END:VEVENT
END:VCALENDAR
ICS;
$this->assertValidate(
$input,
VCalendar::PROFILE_CALDAV,
3,
"A calendar object on a CalDAV server may only have components with the same UID."
);
}
function testCalDAVMultiComponent() {
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:vobject
BEGIN:VEVENT
UID:foo
RECURRENCE-ID:20150109T185200Z
DTSTAMP:20150109T184500Z
DTSTART:20150109T184500Z
END:VEVENT
BEGIN:VTODO
UID:foo
DTSTAMP:20150109T184500Z
DTSTART:20150109T184500Z
END:VTODO
END:VCALENDAR
ICS;
$this->assertValidate(
$input,
VCalendar::PROFILE_CALDAV,
3,
"A calendar object on a CalDAV server may only have 1 type of component (VEVENT, VTODO or VJOURNAL)."
);
}
function testCalDAVMETHOD() {
$input = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
PRODID:vobject
BEGIN:VEVENT
UID:foo
RECURRENCE-ID:20150109T185200Z
DTSTAMP:20150109T184500Z
DTSTART:20150109T184500Z
END:VEVENT
END:VCALENDAR
ICS;
$this->assertValidate(
$input,
VCalendar::PROFILE_CALDAV,
3,
"A calendar object on a CalDAV server MUST NOT have a METHOD property."
);
}
function assertValidate($ics, $options, $expectedLevel, $expectedMessage = null) {
$vcal = VObject\Reader::read($ics);
$result = $vcal->validate($options);
$this->assertValidateResult($result, $expectedLevel, $expectedMessage);
}
function assertValidateResult($input, $expectedLevel, $expectedMessage = null) {
$messages = array();
foreach($input as $warning) {
$messages[] = $warning['message'];
}
if ($expectedLevel === 0) {
$this->assertEquals(0, count($input), 'No validation messages were expected. We got: ' . implode(', ', $messages));
} else {
$this->assertEquals(1, count($input), 'We expected exactly 1 validation message, We got: ' . implode(', ', $messages));
$this->assertEquals($expectedMessage, $input[0]['message']);
$this->assertEquals($expectedLevel, $input[0]['level']);
}
}
}

View File

@@ -0,0 +1,288 @@
<?php
namespace Sabre\VObject\Component;
use Sabre\VObject;
class VCardTest extends \PHPUnit_Framework_TestCase {
/**
* @dataProvider validateData
*/
function testValidate($input, $expectedWarnings, $expectedRepairedOutput) {
$vcard = VObject\Reader::read($input);
$warnings = $vcard->validate();
$warnMsg = array();
foreach($warnings as $warning) {
$warnMsg[] = $warning['message'];
}
$this->assertEquals($expectedWarnings, $warnMsg);
$vcard->validate(VObject\Component::REPAIR);
$this->assertEquals(
$expectedRepairedOutput,
$vcard->serialize()
);
}
public function validateData() {
$tests = array();
// Correct
$tests[] = array(
"BEGIN:VCARD\r\nVERSION:4.0\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
array(),
"BEGIN:VCARD\r\nVERSION:4.0\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
);
// No VERSION
$tests[] = array(
"BEGIN:VCARD\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
array(
'VERSION MUST appear exactly once in a VCARD component',
),
"BEGIN:VCARD\r\nVERSION:3.0\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
);
// Unknown version
$tests[] = array(
"BEGIN:VCARD\r\nVERSION:2.2\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
array(
'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.',
),
"BEGIN:VCARD\r\nVERSION:2.1\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
);
// No FN
$tests[] = array(
"BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nEND:VCARD\r\n",
array(
'The FN property must appear in the VCARD component exactly 1 time',
),
"BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nEND:VCARD\r\n",
);
// No FN, N fallback
$tests[] = array(
"BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nN:Doe;John;;;;;\r\nEND:VCARD\r\n",
array(
'The FN property must appear in the VCARD component exactly 1 time',
),
"BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nN:Doe;John;;;;;\r\nFN:John Doe\r\nEND:VCARD\r\n",
);
// No FN, N fallback, no first name
$tests[] = array(
"BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nN:Doe;;;;;;\r\nEND:VCARD\r\n",
array(
'The FN property must appear in the VCARD component exactly 1 time',
),
"BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nN:Doe;;;;;;\r\nFN:Doe\r\nEND:VCARD\r\n",
);
// No FN, ORG fallback
$tests[] = array(
"BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nORG:Acme Co.\r\nEND:VCARD\r\n",
array(
'The FN property must appear in the VCARD component exactly 1 time',
),
"BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nORG:Acme Co.\r\nFN:Acme Co.\r\nEND:VCARD\r\n",
);
return $tests;
}
function testGetDocumentType() {
$vcard = new VCard(array(), false);
$vcard->VERSION = '2.1';
$this->assertEquals(VCard::VCARD21, $vcard->getDocumentType());
$vcard = new VCard(array(), false);
$vcard->VERSION = '3.0';
$this->assertEquals(VCard::VCARD30, $vcard->getDocumentType());
$vcard = new VCard(array(), false);
$vcard->VERSION = '4.0';
$this->assertEquals(VCard::VCARD40, $vcard->getDocumentType());
$vcard = new VCard(array(), false);
$this->assertEquals(VCard::UNKNOWN, $vcard->getDocumentType());
}
function testPreferredNoPref() {
$vcard = <<<VCF
BEGIN:VCARD
VERSION:3.0
EMAIL:1@example.org
EMAIL:2@example.org
END:VCARD
VCF;
$vcard = VObject\Reader::read($vcard);
$this->assertEquals('1@example.org', $vcard->preferred('EMAIL')->getValue());
}
function testPreferredWithPref() {
$vcard = <<<VCF
BEGIN:VCARD
VERSION:3.0
EMAIL:1@example.org
EMAIL;TYPE=PREF:2@example.org
END:VCARD
VCF;
$vcard = VObject\Reader::read($vcard);
$this->assertEquals('2@example.org', $vcard->preferred('EMAIL')->getValue());
}
function testPreferredWith40Pref() {
$vcard = <<<VCF
BEGIN:VCARD
VERSION:4.0
EMAIL:1@example.org
EMAIL;PREF=3:2@example.org
EMAIL;PREF=2:3@example.org
END:VCARD
VCF;
$vcard = VObject\Reader::read($vcard);
$this->assertEquals('3@example.org', $vcard->preferred('EMAIL')->getValue());
}
function testPreferredNotFound() {
$vcard = <<<VCF
BEGIN:VCARD
VERSION:4.0
END:VCARD
VCF;
$vcard = VObject\Reader::read($vcard);
$this->assertNull($vcard->preferred('EMAIL'));
}
function testNoUIDCardDAV() {
$vcard = <<<VCF
BEGIN:VCARD
VERSION:4.0
FN:John Doe
END:VCARD
VCF;
$this->assertValidate(
$vcard,
VCARD::PROFILE_CARDDAV,
3,
'vCards on CardDAV servers MUST have a UID property.'
);
}
function testNoUIDNoCardDAV() {
$vcard = <<<VCF
BEGIN:VCARD
VERSION:4.0
FN:John Doe
END:VCARD
VCF;
$this->assertValidate(
$vcard,
0,
2,
'Adding a UID to a vCard property is recommended.'
);
}
function testNoUIDNoCardDAVRepair() {
$vcard = <<<VCF
BEGIN:VCARD
VERSION:4.0
FN:John Doe
END:VCARD
VCF;
$this->assertValidate(
$vcard,
VCARD::REPAIR,
1,
'Adding a UID to a vCard property is recommended.'
);
}
function testVCard21CardDAV() {
$vcard = <<<VCF
BEGIN:VCARD
VERSION:2.1
FN:John Doe
UID:foo
END:VCARD
VCF;
$this->assertValidate(
$vcard,
VCARD::PROFILE_CARDDAV,
3,
'CardDAV servers are not allowed to accept vCard 2.1.'
);
}
function testVCard21NoCardDAV() {
$vcard = <<<VCF
BEGIN:VCARD
VERSION:2.1
FN:John Doe
UID:foo
END:VCARD
VCF;
$this->assertValidate(
$vcard,
0,
0
);
}
function assertValidate($vcf, $options, $expectedLevel, $expectedMessage = null) {
$vcal = VObject\Reader::read($vcf);
$result = $vcal->validate($options);
$this->assertValidateResult($result, $expectedLevel, $expectedMessage);
}
function assertValidateResult($input, $expectedLevel, $expectedMessage = null) {
$messages = array();
foreach($input as $warning) {
$messages[] = $warning['message'];
}
if ($expectedLevel === 0) {
$this->assertEquals(0, count($input), 'No validation messages were expected. We got: ' . implode(', ', $messages));
} else {
$this->assertEquals(1, count($input), 'We expected exactly 1 validation message, We got: ' . implode(', ', $messages));
$this->assertEquals($expectedMessage, $input[0]['message']);
$this->assertEquals($expectedLevel, $input[0]['level']);
}
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace Sabre\VObject\Component;
use Sabre\VObject;
class VEventTest extends \PHPUnit_Framework_TestCase {
/**
* @dataProvider timeRangeTestData
*/
public function testInTimeRange(VEvent $vevent,$start,$end,$outcome) {
$this->assertEquals($outcome, $vevent->isInTimeRange($start, $end));
}
public function timeRangeTestData() {
$tests = array();
$calendar = new VCalendar();
$vevent = $calendar->createComponent('VEVENT');
$vevent->DTSTART = '20111223T120000Z';
$tests[] = array($vevent, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vevent, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vevent2 = clone $vevent;
$vevent2->DTEND = '20111225T120000Z';
$tests[] = array($vevent2, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vevent2, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vevent3 = clone $vevent;
$vevent3->DURATION = 'P1D';
$tests[] = array($vevent3, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vevent3, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vevent4 = clone $vevent;
$vevent4->DTSTART = '20111225';
$vevent4->DTSTART['VALUE'] = 'DATE';
$tests[] = array($vevent4, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vevent4, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
// Event with no end date should be treated as lasting the entire day.
$tests[] = array($vevent4, new \DateTime('2011-12-25 16:00:00'), new \DateTime('2011-12-25 17:00:00'), true);
// DTEND is non inclusive so all day events should not be returned on the next day.
$tests[] = array($vevent4, new \DateTime('2011-12-26 00:00:00'), new \DateTime('2011-12-26 17:00:00'), false);
// The timezone of timerange in question also needs to be considered.
$tests[] = array($vevent4, new \DateTime('2011-12-26 00:00:00', new \DateTimeZone('Europe/Berlin')), new \DateTime('2011-12-26 17:00:00', new \DateTimeZone('Europe/Berlin')), false);
$vevent5 = clone $vevent;
$vevent5->DURATION = 'P1D';
$vevent5->RRULE = 'FREQ=YEARLY';
$tests[] = array($vevent5, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vevent5, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$tests[] = array($vevent5, new \DateTime('2013-12-01'), new \DateTime('2013-12-31'), true);
$vevent6 = clone $vevent;
$vevent6->DTSTART = '20111225';
$vevent6->DTSTART['VALUE'] = 'DATE';
$vevent6->DTEND = '20111225';
$vevent6->DTEND['VALUE'] = 'DATE';
$tests[] = array($vevent6, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vevent6, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
// Added this test to ensure that recurrence rules with no DTEND also
// get checked for the entire day.
$vevent7 = clone $vevent;
$vevent7->DTSTART = '20120101';
$vevent7->DTSTART['VALUE'] = 'DATE';
$vevent7->RRULE = 'FREQ=MONTHLY';
$tests[] = array($vevent7, new \DateTime('2012-02-01 15:00:00'), new \DateTime('2012-02-02'), true);
// The timezone of timerange in question should also be considered.
// Added this test to check recurring events that have no instances.
$vevent8 = clone $vevent;
$vevent8->DTSTART = '20130329T140000';
$vevent8->DTEND = '20130329T153000';
$vevent8->RRULE = array('FREQ' => 'WEEKLY', 'BYDAY' => array('FR'), 'UNTIL' => '20130412T115959Z');
$vevent8->add('EXDATE', '20130405T140000');
$vevent8->add('EXDATE', '20130329T140000');
$tests[] = array($vevent8, new \DateTime('2013-03-01'), new \DateTime('2013-04-01'), false);
return $tests;
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace Sabre\VObject\Component;
use Sabre\VObject;
use Sabre\VObject\Reader;
class VFreeBusyTest extends \PHPUnit_Framework_TestCase {
function testIsFree() {
$input = <<<BLA
BEGIN:VCALENDAR
BEGIN:VFREEBUSY
FREEBUSY;FBTYPE=FREE:20120912T000500Z/PT1H
FREEBUSY;FBTYPE=BUSY:20120912T010000Z/20120912T020000Z
FREEBUSY;FBTYPE=BUSY-TENTATIVE:20120912T020000Z/20120912T030000Z
FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:20120912T030000Z/20120912T040000Z
FREEBUSY;FBTYPE=BUSY:20120912T050000Z/20120912T060000Z,20120912T080000Z/20120912T090000Z
FREEBUSY;FBTYPE=BUSY:20120912T100000Z/PT1H
END:VFREEBUSY
END:VCALENDAR
BLA;
$obj = VObject\Reader::read($input);
$vfb = $obj->VFREEBUSY;
$tz = new \DateTimeZone('UTC');
$this->assertFalse($vfb->isFree(new \DateTime('2012-09-12 01:15:00', $tz), new \DateTime('2012-09-12 01:45:00', $tz)));
$this->assertFalse($vfb->isFree(new \DateTime('2012-09-12 08:05:00', $tz), new \DateTime('2012-09-12 08:10:00', $tz)));
$this->assertFalse($vfb->isFree(new \DateTime('2012-09-12 10:15:00', $tz), new \DateTime('2012-09-12 10:45:00', $tz)));
// Checking whether the end time is treated as non-inclusive
$this->assertTrue($vfb->isFree(new \DateTime('2012-09-12 09:00:00', $tz), new \DateTime('2012-09-12 09:15:00', $tz)));
$this->assertTrue($vfb->isFree(new \DateTime('2012-09-12 09:45:00', $tz), new \DateTime('2012-09-12 10:00:00', $tz)));
$this->assertTrue($vfb->isFree(new \DateTime('2012-09-12 11:00:00', $tz), new \DateTime('2012-09-12 12:00:00', $tz)));
}
public function testValidate() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
PRODID:YoYo
BEGIN:VFREEBUSY
UID:some-random-id
DTSTAMP:20140402T180200Z
END:VFREEBUSY
END:VCALENDAR
HI;
$obj = Reader::read($input);
$warnings = $obj->validate();
$messages = array();
foreach($warnings as $warning) {
$messages[] = $warning['message'];
}
$this->assertEquals(array(), $messages);
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace Sabre\VObject\Component;
use Sabre\VObject\Component;
use Sabre\VObject\Reader;
class VJournalTest extends \PHPUnit_Framework_TestCase {
/**
* @dataProvider timeRangeTestData
*/
public function testInTimeRange(VJournal $vtodo,$start,$end,$outcome) {
$this->assertEquals($outcome, $vtodo->isInTimeRange($start, $end));
}
public function testValidate() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
PRODID:YoYo
BEGIN:VJOURNAL
UID:12345678
DTSTAMP:20140402T174100Z
END:VJOURNAL
END:VCALENDAR
HI;
$obj = Reader::read($input);
$warnings = $obj->validate();
$messages = array();
foreach($warnings as $warning) {
$messages[] = $warning['message'];
}
$this->assertEquals(array(), $messages);
}
public function testValidateBroken() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
PRODID:YoYo
BEGIN:VJOURNAL
UID:12345678
DTSTAMP:20140402T174100Z
URL:http://example.org/
URL:http://example.com/
END:VJOURNAL
END:VCALENDAR
HI;
$obj = Reader::read($input);
$warnings = $obj->validate();
$messages = array();
foreach($warnings as $warning) {
$messages[] = $warning['message'];
}
$this->assertEquals(
array("URL MUST NOT appear more than once in a VJOURNAL component"),
$messages
);
}
public function timeRangeTestData() {
$calendar = new VCalendar();
$tests = array();
$vjournal = $calendar->createComponent('VJOURNAL');
$vjournal->DTSTART = '20111223T120000Z';
$tests[] = array($vjournal, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vjournal, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vjournal2 = $calendar->createComponent('VJOURNAL');
$vjournal2->DTSTART = '20111223';
$vjournal2->DTSTART['VALUE'] = 'DATE';
$tests[] = array($vjournal2, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vjournal2, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vjournal3 = $calendar->createComponent('VJOURNAL');
$tests[] = array($vjournal3, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), false);
$tests[] = array($vjournal3, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
return $tests;
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Sabre\VObject\Component;
use Sabre\VObject;
use Sabre\VObject\Reader;
class VTimeZoneTest extends \PHPUnit_Framework_TestCase {
function testValidate() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
PRODID:YoYo
BEGIN:VTIMEZONE
TZID:America/Toronto
END:VTIMEZONE
END:VCALENDAR
HI;
$obj = Reader::read($input);
$warnings = $obj->validate();
$messages = array();
foreach($warnings as $warning) {
$messages[] = $warning['message'];
}
$this->assertEquals(array(), $messages);
}
function testGetTimeZone() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
PRODID:YoYo
BEGIN:VTIMEZONE
TZID:America/Toronto
END:VTIMEZONE
END:VCALENDAR
HI;
$obj = Reader::read($input);
$tz = new \DateTimeZone('America/Toronto');
$this->assertEquals(
$tz,
$obj->VTIMEZONE->getTimeZone()
);
}
}

View File

@@ -0,0 +1,180 @@
<?php
namespace Sabre\VObject\Component;
use
Sabre\VObject\Component,
Sabre\VObject\Reader;
class VTodoTest extends \PHPUnit_Framework_TestCase {
/**
* @dataProvider timeRangeTestData
*/
public function testInTimeRange(VTodo $vtodo,$start,$end,$outcome) {
$this->assertEquals($outcome, $vtodo->isInTimeRange($start, $end));
}
public function timeRangeTestData() {
$tests = array();
$calendar = new VCalendar();
$vtodo = $calendar->createComponent('VTODO');
$vtodo->DTSTART = '20111223T120000Z';
$tests[] = array($vtodo, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vtodo, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vtodo2 = clone $vtodo;
$vtodo2->DURATION = 'P1D';
$tests[] = array($vtodo2, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vtodo2, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vtodo3 = clone $vtodo;
$vtodo3->DUE = '20111225';
$tests[] = array($vtodo3, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vtodo3, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vtodo4 = $calendar->createComponent('VTODO');
$vtodo4->DUE = '20111225';
$tests[] = array($vtodo4, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vtodo4, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vtodo5 = $calendar->createComponent('VTODO');
$vtodo5->COMPLETED = '20111225';
$tests[] = array($vtodo5, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vtodo5, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vtodo6 = $calendar->createComponent('VTODO');
$vtodo6->CREATED = '20111225';
$tests[] = array($vtodo6, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vtodo6, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vtodo7 = $calendar->createComponent('VTODO');
$vtodo7->CREATED = '20111225';
$vtodo7->COMPLETED = '20111226';
$tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
$vtodo7 = $calendar->createComponent('VTODO');
$tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
$tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), true);
return $tests;
}
public function testValidate() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
PRODID:YoYo
BEGIN:VTODO
UID:1234-21355-123156
DTSTAMP:20140402T183400Z
END:VTODO
END:VCALENDAR
HI;
$obj = Reader::read($input);
$warnings = $obj->validate();
$messages = array();
foreach($warnings as $warning) {
$messages[] = $warning['message'];
}
$this->assertEquals(array(), $messages);
}
public function testValidateInvalid() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
PRODID:YoYo
BEGIN:VTODO
END:VTODO
END:VCALENDAR
HI;
$obj = Reader::read($input);
$warnings = $obj->validate();
$messages = array();
foreach($warnings as $warning) {
$messages[] = $warning['message'];
}
$this->assertEquals(array(
"UID MUST appear exactly once in a VTODO component",
"DTSTAMP MUST appear exactly once in a VTODO component",
), $messages);
}
public function testValidateDUEDTSTARTMisMatch() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
PRODID:YoYo
BEGIN:VTODO
UID:FOO
DTSTART;VALUE=DATE-TIME:20140520T131600Z
DUE;VALUE=DATE:20140520
DTSTAMP;VALUE=DATE-TIME:20140520T131600Z
END:VTODO
END:VCALENDAR
HI;
$obj = Reader::read($input);
$warnings = $obj->validate();
$messages = array();
foreach($warnings as $warning) {
$messages[] = $warning['message'];
}
$this->assertEquals(array(
"The value type (DATE or DATE-TIME) must be identical for DUE and DTSTART",
), $messages);
}
public function testValidateDUEbeforeDTSTART() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
PRODID:YoYo
BEGIN:VTODO
UID:FOO
DTSTART;VALUE=DATE:20140520
DUE;VALUE=DATE:20140518
DTSTAMP;VALUE=DATE-TIME:20140520T131600Z
END:VTODO
END:VCALENDAR
HI;
$obj = Reader::read($input);
$warnings = $obj->validate();
$messages = array();
foreach($warnings as $warning) {
$messages[] = $warning['message'];
}
$this->assertEquals(array(
"DUE must occur after DTSTART",
), $messages);
}
}