* @copyright 2007-2022 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link https://kigkonsult.se
* @license Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* iCalcreator 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with iCalcreator. If not, see .
*/
declare( strict_types = 1 );
namespace Kigkonsult\Icalcreator;
use DateTime;
use DateTimeZone;
use Exception;
use PHPUnit\Framework\TestCase;
/**
* class SelectComponentsTest
*
* Testing exceptions in DateIntervalFactory
*
* @since 2.27.18 - 2019-04-09
*/
class SelectComponentsTest extends TestCase
{
/**
* Vevent calendar sub-provider
*
* demoUsage.md calendar
*
* @throws Exception
*/
public static function veventCalendarSubProvider() : Vcalendar
{
// create a new calendar
$vcalendar = Vcalendar::factory( [ IcalInterface::UNIQUE_ID => "kigkonsult.se", ] )
// with calendaring info
->setMethod( IcalInterface::PUBLISH )
->setXprop(
IcalInterface::X_WR_CALNAME,
"Calendar Sample"
)
->setXprop(
IcalInterface::X_WR_CALDESC,
"The calendar Description"
)
->setXprop(
IcalInterface::X_WR_RELCALID,
"3E26604A-50F4-4449-8B3E-E4F4932D05B5"
)
->setXprop(
IcalInterface::X_WR_TIMEZONE,
"Europe/Stockholm"
);
// create a new event with dtstart, dtend and summary
$event1 = $vcalendar->newVevent(
new DateTime( '20190421T090000', new DateTimeZone( 'Europe/Stockholm' )),
new DateTime( '20190421T100000', new DateTimeZone( 'Europe/Stockholm' )),
null.
'Scheduled meeting with six occurrences'
)
->setTransp( IcalInterface::OPAQUE )
->setClass( IcalInterface::P_BLIC )
->setSequence( 1 )
->setDescription(
'Agenda for the the meeting...',
[ IcalInterface::ALTREP => 'CID:' ]
)
->setComment( 'It\'s going to be fun..' )
->setLocation( 'Kafé Ekorren Stockholm' )
->setGeo( '59.32206', '18.12485' )
// with recurrence rule
->setRrule(
[
IcalInterface::FREQ => IcalInterface::WEEKLY,
IcalInterface::COUNT => 5,
]
)
// and a another using a recurrence date
->setRdate(
[
new DateTime(
'20190609T090000',
new DateTimeZone( 'Europe/Stockholm' )
),
new DateTime(
'20190609T110000',
new DateTimeZone( 'Europe/Stockholm' )
),
],
[ IcalInterface::VALUE => IcalInterface::PERIOD ]
)
// and revoke a recurrence date
->setExdate(
new DateTime(
'2019-05-12 09:00:00',
new DateTimeZone( 'Europe/Stockholm' )
)
)
// organizer, chair and some participants
->setContact(
'Head Office, coffeebean Corp, Acme city',
[ IcalInterface::ALTREP => "http://coffeebean.com/contacts.vcf" ]
)
->setContact(
'+12 34 56 78 90, coffeebean Corp, Acme city',
[ IcalInterface::ALTREP => "http://coffeebean.com/contacts.vcf" ]
)
->setContact(
'Head.Office@coffeebean.com, coffeebean Corp, Acme city',
[ IcalInterface::ALTREP => "http://coffeebean.com/contacts.vcf" ]
)
->setOrganizer(
'secretary@coffeebean.com',
[ IcalInterface::SENT_BY => 'sent_by.Secretary.staff@CoffeeBean.com' ]
)
->setAttendee(
'president@coffeebean.com',
[
IcalInterface::ROLE => IcalInterface::CHAIR,
IcalInterface::PARTSTAT => IcalInterface::ACCEPTED,
IcalInterface::RSVP => IcalInterface::FALSE,
IcalInterface::CN => 'President CoffeeBean',
IcalInterface::SENT_BY => 'president.sent_by.secretary@coffeebean.com'
]
)
->setAttendee(
'participant1.staff@coffeebean.com',
[
IcalInterface::ROLE => IcalInterface::REQ_PARTICIPANT,
IcalInterface::PARTSTAT => IcalInterface::NEEDS_ACTION,
IcalInterface::RSVP => IcalInterface::TRUE,
IcalInterface::CN => 'Participant1 CoffeeBean',
IcalInterface::MEMBER => [
'member.3@coffeebean.com',
'member.4@coffeebean.com'
],
]
)
->setAttendee(
'participant2@coffeebean.com',
[
IcalInterface::ROLE => IcalInterface::REQ_PARTICIPANT,
IcalInterface::PARTSTAT => IcalInterface::NEEDS_ACTION,
IcalInterface::RSVP => IcalInterface::TRUE,
IcalInterface::CN => 'Participant2 CoffeeBean',
IcalInterface::DELEGATED_FROM => 'delegated_from.2@coffeebean.com',
]
);
// add an alarm for the event
// fire off the alarm one day before
$alarm = $event1->newValarm(IcalInterface::DISPLAY, '-P1D' )
->setDescription( $event1->getDescription());
// alter day and time for one event in recurrence set
// the altered day and time with duration
$event2 = $vcalendar->newVevent(
new DateTime( '20190504T100000', new DateTimeZone( 'Europe/Stockholm' )),
null,
'PT2H'
)
->setTransp( IcalInterface::OPAQUE )
->setClass( IcalInterface::P_BLIC )
// reference to one event in recurrence set
->setUid( $event1->getUid() )
->setSequence( 2 )
// pointer to event in the recurrence set
->setRecurrenceid( '20190505T090000 Europe/Stockholm' )
// reason text
->setDescription(
'Altered day and time for event 2019-05-05',
[ IcalInterface::ALTREP => 'CID:' ]
)
->setComment( 'Now we are working hard for two hours' )
// add alarm (i.e. same as event1)
->setComponent( $event1->getComponent( IcalInterface::VALARM ) );
// apply appropriate Vtimezone with Standard/DayLight components
$vcalendar->vtimezonePopulate();
return $vcalendar;
}
/**
* Vtodo calendar sub-provider
* @throws Exception
*/
public static function vtodoCalendarSubProvider() : Vcalendar
{
// create a new calendar
$vcalendar = Vcalendar::factory( [ IcalInterface::UNIQUE_ID => "kigkonsult.se", ] )
// with calendaring info
->setMethod( IcalInterface::PUBLISH )
->setXprop(
IcalInterface::X_WR_CALNAME,
"Calendar Sample"
)
->setXprop(
IcalInterface::X_WR_CALDESC,
"The calendar Description"
)
->setXprop(
IcalInterface::X_WR_RELCALID,
"3E26604A-50F4-4449-8B3E-E4F4932D05B5"
)
->setXprop(
IcalInterface::X_WR_TIMEZONE,
"Europe/Stockholm"
);
// create a new todo
$todo1 = $vcalendar->newVtodo(
new DateTime( '20190421T090000', new DateTimeZone( 'Europe/Stockholm' )),
new DateTime( '20190421T100000', new DateTimeZone( 'Europe/Stockholm' )),
null,
'Scheduled meeting with six occurrences'
)
->setClass( IcalInterface::P_BLIC )
->setSequence( 1 )
// describe the event
->setDescription(
'Agenda for the the meeting...',
[ IcalInterface::ALTREP => 'CID:' ]
)
->setComment( 'It\'s going to be fun..' )
->setLocation( 'Kafé Ekorren Stockholm' )
->setGeo( '59.32206', '18.12485' )
// with recurrence rule
->setRrule(
[
IcalInterface::FREQ => IcalInterface::WEEKLY,
IcalInterface::COUNT => 5,
]
)
// and a another using a recurrence date
->setRdate(
[
new DateTime(
'20190609T090000',
new DateTimeZone( 'Europe/Stockholm' )
),
new DateTime(
'20190609T110000',
new DateTimeZone( 'Europe/Stockholm' )
),
],
[ IcalInterface::VALUE => IcalInterface::PERIOD ]
)
// and revoke recurrence dates
->setExdate(
new DateTime(
'2019-05-12 09:00:00',
new DateTimeZone( 'Europe/Stockholm' )
)
)
// organizer, chair and some participants
->setContact(
'Head Office, coffeebean Corp, Acme city',
[ IcalInterface::ALTREP => "http://coffeebean.com/contacts.vcf" ]
)
->setOrganizer(
'secretary2@coffeebean.com',
[ IcalInterface::SENT_BY => 'sent_by.Secretary.staff@CoffeeBean.com' ]
)
->setAttendee(
'VicePresident@coffeebean.com',
[
IcalInterface::ROLE => IcalInterface::CHAIR,
IcalInterface::PARTSTAT => IcalInterface::ACCEPTED,
IcalInterface::RSVP => IcalInterface::FALSE,
IcalInterface::CN => 'President CoffeeBean',
IcalInterface::SENT_BY => 'sent_by.VicePresident@coffeebean.com',
]
)
->setAttendee(
'participant1.team1@coffeebean.com',
[
IcalInterface::ROLE => IcalInterface::REQ_PARTICIPANT,
IcalInterface::PARTSTAT => IcalInterface::NEEDS_ACTION,
IcalInterface::RSVP => IcalInterface::TRUE,
IcalInterface::CN => 'Participant1 CoffeeBean',
IcalInterface::MEMBER => [
'member1@coffeebean.com',
'member2@coffeebean.com'
],
IcalInterface::DELEGATED_TO => [
'delegated_to.1@coffeebean.com',
'delegated_to.2@coffeebean.com'
],
]
)
->setAttendee(
'participant2@coffeebean.com',
[
IcalInterface::ROLE => IcalInterface::REQ_PARTICIPANT,
IcalInterface::PARTSTAT => IcalInterface::NEEDS_ACTION,
IcalInterface::RSVP => IcalInterface::TRUE,
IcalInterface::CN => 'Participant2 CoffeeBean',
]
);
// add an alarm for the todo
// fire off the alarm one day before
$alarm = $todo1->newValarm( IcalInterface::DISPLAY, '-P1D' )
->setDescription( $todo1->getDescription());
// alter day and time for one todo in recurrence set
// the altered day and time with duration
$event2 = $vcalendar->newVtodo(
new DateTime( '20190504T100000', new DateTimeZone( 'Europe/Stockholm' )),
null,
'PT2H'
)
->setClass( IcalInterface::P_BLIC )
// reference to one event in recurrence set
->setUid( $todo1->getUid() )
->setSequence( 2 )
// pointer to event in the recurrence set
->setRecurrenceid( '20190505T090000 Europe/Stockholm' )
// reason text
->setDescription(
'Altered day and time for event 2019-05-05',
[ IcalInterface::ALTREP => 'CID:' ]
)
->setComment( 'Now we are working hard for two hours' )
// add alarm (i.e. same as event1)
->setComponent( $todo1->getComponent( IcalInterface::VALARM ) );
// apply appropriate Vtimezone with Standard/DayLight components
$vcalendar->vtimezonePopulate();
return $vcalendar;
}
/**
* SelectComponentsTest provider
*
* @return mixed[]
* @throws Exception
*/
public function SelectCompTestProvider() : array
{
$veventCalendar = self::veventCalendarSubProvider();
$todoCalendar = self::vtodoCalendarSubProvider();
$dataArr = [];
$dataArr[] = [
11,
clone $veventCalendar,
null
];
$dataArr[] = [
12,
clone $veventCalendar,
strtolower( IcalInterface::VEVENT )
];
$dataArr[] = [
13,
clone $veventCalendar,
[ strtolower( IcalInterface::VEVENT ), strtolower( IcalInterface::VTODO ) ]
];
$dataArr[] = [
21,
clone $todoCalendar,
null
];
$dataArr[] = [
22,
clone $todoCalendar,
strtolower( IcalInterface::VTODO )
];
$dataArr[] = [
23,
clone $todoCalendar,
[ strtolower( IcalInterface::VEVENT ), strtolower( IcalInterface::VTODO ) ]
];
return $dataArr;
}
/**
* Testing Vcalendar::selectComponents
*
* @test
* @dataProvider SelectCompTestProvider
* @param int $case
* @param Vcalendar $vcalendar
* @param mixed[]|string|null $compType
* @throws Exception
*/
public function SelectCompTest( int $case, Vcalendar $vcalendar, array | string $compType = null ) : void
{
static $FMTerr = 'error in case#%d-%d, date %d-%d-%d';
$selectComponents = $vcalendar->selectComponents(
new DateTime( '20190421T000000', new DateTimeZone( 'Europe/Stockholm' )),
new DateTime( '20190630T000000', new DateTimeZone( 'Europe/Stockholm' ))
,null, null, null, null,
$compType
);
/*
foreach( $selectComponents[2019] as $month => $monthArr ) {
foreach( $monthArr as $day => $dayArr ) {
foreach( $dayArr as $no => $comp ) {
echo 'keys found 2019-' . $month . '-' . $day . ' #' . $no . PHP_EOL; // test ###
}
}
}
*/
// 2019-04-21
$this->assertTrue(
isset( $selectComponents[2019][4][21][0] ),
sprintf( $FMTerr, $case, 10, 2019, 4, 21 )
);
$this->assertEquals(
'2019-04-21 09:00:00 Europe/Stockholm',
$selectComponents[2019][4][21][0]->getXprop( IcalInterface::X_CURRENT_DTSTART )[1],
sprintf( $FMTerr, $case, 11, 2019, 4, 21 )
);
if( false === ( $value = $selectComponents[2019][4][21][0]->getXprop( IcalInterface::X_CURRENT_DTEND ))) {
$value = $selectComponents[2019][4][21][0]->getXprop( IcalInterface::X_CURRENT_DUE );
}
$this->assertEquals(
'2019-04-21 10:00:00 Europe/Stockholm',
$value[1],
sprintf( $FMTerr, $case, 12, 2019, 4, 21 )
);
// 2019-04-28
$this->assertTrue( isset( $selectComponents[2019][4][28][0] ));
$this->assertEquals(
2,
$selectComponents[2019][4][28][0]->getXprop( IcalInterface::X_RECURRENCE )[1],
sprintf( $FMTerr, $case, 13, 2019, 4, 28 )
);
$this->assertEquals(
'2019-04-28 09:00:00 Europe/Stockholm',
$selectComponents[2019][4][28][0]->getXprop( IcalInterface::X_CURRENT_DTSTART )[1],
sprintf( $FMTerr, $case, 14, 2019, 4, 28 )
);
if( false === ( $value = $selectComponents[2019][4][28][0]->getXprop( IcalInterface::X_CURRENT_DTEND ))) {
$value = $selectComponents[2019][4][28][0]->getXprop( IcalInterface::X_CURRENT_DUE );
}
$this->assertEquals(
'2019-04-28 10:00:00 Europe/Stockholm',
$value[1],
sprintf( $FMTerr, $case, 15, 2019, 4, 28 )
);
// 2019-05-04
$this->assertTrue( isset( $selectComponents[2019][5][4][0] ));
$this->assertEquals(
3,
$selectComponents[2019][5][4][0]->getXprop( IcalInterface::X_RECURRENCE )[1],
sprintf( $FMTerr, $case, 16, 2019, 5, 4 )
);
$this->assertEquals(
'2019-05-04 10:00:00 Europe/Stockholm',
$selectComponents[2019][5][4][0]->getXprop( IcalInterface::X_CURRENT_DTSTART )[1],
sprintf( $FMTerr, $case, 17, 2019, 5, 4 )
);
if( false === ( $value = $selectComponents[2019][5][4][0]->getXprop( IcalInterface::X_CURRENT_DTEND ))) {
$value = $selectComponents[2019][5][4][0]->getXprop( IcalInterface::X_CURRENT_DUE );
}
$this->assertEquals(
'2019-05-04 12:00:00 Europe/Stockholm',
$value[1],
sprintf( $FMTerr, $case, 18, 2019, 5, 4 )
);
// 2019-05-19
$this->assertTrue( isset( $selectComponents[2019][5][19][0] ));
$this->assertEquals(
4,
$selectComponents[2019][5][19][0]->getXprop( IcalInterface::X_RECURRENCE )[1],
sprintf( $FMTerr, $case, 19, 2019, 5, 19 )
);
$this->assertEquals(
'2019-05-19 09:00:00 Europe/Stockholm',
$selectComponents[2019][5][19][0]->getXprop( IcalInterface::X_CURRENT_DTSTART )[1],
sprintf( $FMTerr, $case, 20, 2019, 5, 19 )
);
if( false === ( $value = $selectComponents[2019][5][19][0]->getXprop( IcalInterface::X_CURRENT_DTEND ))) {
$value = $selectComponents[2019][5][19][0]->getXprop( IcalInterface::X_CURRENT_DUE );
}
$this->assertEquals(
'2019-05-19 10:00:00 Europe/Stockholm',
$value[1],
sprintf( $FMTerr, $case, 21, 2019, 5, 19 )
);
// 2019-06-09
$this->assertTrue( isset( $selectComponents[2019][6][9][0] ));
$this->assertEquals(
5,
$selectComponents[2019][6][9][0]->getXprop( IcalInterface::X_RECURRENCE )[1],
sprintf( $FMTerr, $case, 22, 2019, 6, 9 )
);
$this->assertEquals(
'2019-06-09 09:00:00 Europe/Stockholm',
$selectComponents[2019][6][9][0]->getXprop( IcalInterface::X_CURRENT_DTSTART )[1],
sprintf( $FMTerr, $case, 23, 2019, 6, 9 )
);
if( false === ( $value = $selectComponents[2019][6][9][0]->getXprop( IcalInterface::X_CURRENT_DTEND ))) {
$value = $selectComponents[2019][6][9][0]->getXprop( IcalInterface::X_CURRENT_DUE );
}
$this->assertEquals(
'2019-06-09 11:00:00 Europe/Stockholm',
$value[1],
sprintf( $FMTerr, $case, 24, 2019, 6, 9 )
);
}
}