From 5b5f395feb19fd4cc456b5f20f36efc8c8bf2a56 Mon Sep 17 00:00:00 2001
From: Gunnar Wrobel
Date: Fri, 6 Aug 2010 22:41:54 +0200
Subject: [PATCH] Added testing and fixed some initial problems.
---
framework/Itip/lib/Horde/Itip/Event/Vevent.php | 42 ++--
framework/Itip/lib/Horde/Itip/Response.php | 48 ++--
framework/Itip/package.xml | 140 +++++++++++
framework/Itip/test/Horde/Itip/AllTests.php | 45 ++++
framework/Itip/test/Horde/Itip/Autoload.php | 29 +++
.../Itip/test/Horde/Itip/Integration/ItipTest.php | 256 +++++++++++++++++++++
framework/Itip/test/Horde/Itip/phpunit.xml | 8 +
7 files changed, 516 insertions(+), 52 deletions(-)
create mode 100644 framework/Itip/package.xml
create mode 100644 framework/Itip/test/Horde/Itip/AllTests.php
create mode 100644 framework/Itip/test/Horde/Itip/Autoload.php
create mode 100644 framework/Itip/test/Horde/Itip/Integration/ItipTest.php
create mode 100644 framework/Itip/test/Horde/Itip/phpunit.xml
diff --git a/framework/Itip/lib/Horde/Itip/Event/Vevent.php b/framework/Itip/lib/Horde/Itip/Event/Vevent.php
index f5741b081..fdf2fd33e 100644
--- a/framework/Itip/lib/Horde/Itip/Event/Vevent.php
+++ b/framework/Itip/lib/Horde/Itip/Event/Vevent.php
@@ -14,7 +14,8 @@
/**
* A wrapper for vEvent iCalender data.
*
- * Copyright 2010 Klarälvdalens Datakonsult AB
+ * Copyright 2002-2010 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2010 Klarälvdalens Datakonsult AB
*
* See the enclosed file COPYING for license information (LGPL). If you did not
* receive this file, see
@@ -388,7 +389,8 @@ implements Horde_Itip_Event
*/
public function getStartParameters()
{
- return array_pop($this->_vevent->getAttribute('DTSTART', true));
+ $parameters = $this->_vevent->getAttribute('DTSTART', true);
+ return array_pop($parameters);
}
/**
@@ -415,23 +417,14 @@ implements Horde_Itip_Event
}
/**
- * Does the event have an end?
- *
- * @return boolean True if it has an end, false otherwise.
- */
- private function hasEnd()
- {
- return !($this->_vevent->getAttribute('DTEND') instanceOf PEAR_Error);
- }
-
- /**
* Return the end parameters of the iTip event.
*
* @return array The end parameters of the event.
*/
private function getEndParameters()
{
- return array_pop($this->_vevent->getAttribute('DTEND', true));
+ $parameters = $this->_vevent->getAttribute('DTEND', true);
+ return array_pop($parameters);
}
/**
@@ -464,7 +457,8 @@ implements Horde_Itip_Event
*/
private function getDurationParameters()
{
- return array_pop($this->_vevent->getAttribute('DURATION', true));
+ $parameters = $this->_vevent->getAttribute('DURATION', true);
+ return array_pop($parameters);
}
/**
@@ -488,9 +482,9 @@ implements Horde_Itip_Event
*/
private function copyEndOrDuration(Horde_Itip_Event $itip)
{
- if ($this->hasEnd()) {
+ try {
$itip->setEnd($this->getEnd(), $this->getEndParameters());
- } else {
+ } catch (Horde_Icalendar_Exception $e) {
$itip->setDuration($this->getDuration(), $this->getDurationParameters());
}
}
@@ -527,16 +521,6 @@ implements Horde_Itip_Event
}
/**
- * Does the event have a location?
- *
- * @return boolean True if it has a location, false otherwise.
- */
- private function hasLocation()
- {
- return !($this->_vevent->getAttribute('LOCATION') instanceOf PEAR_Error);
- }
-
- /**
* Return the location for the event.
*
* @return string|PEAR_Error The location.
@@ -565,8 +549,9 @@ implements Horde_Itip_Event
*/
private function copyLocation(Horde_Itip_Event $itip)
{
- if ($this->hasLocation()) {
+ try {
$itip->setLocation($this->getLocation());
+ } catch (Horde_Icalendar_Exception $e) {
}
}
@@ -587,7 +572,8 @@ implements Horde_Itip_Event
*/
private function getOrganizerParameters()
{
- return array_pop($this->_vevent->getAttribute('ORGANIZER', true));
+ $parameters = $this->_vevent->getAttribute('ORGANIZER', true);
+ return array_pop($parameters);
}
/**
diff --git a/framework/Itip/lib/Horde/Itip/Response.php b/framework/Itip/lib/Horde/Itip/Response.php
index 3fea90c41..6827ecb3b 100644
--- a/framework/Itip/lib/Horde/Itip/Response.php
+++ b/framework/Itip/lib/Horde/Itip/Response.php
@@ -6,6 +6,8 @@
*
* @category Horde
* @package Itip
+ * @author Mike Cochrane
+ * @author Chuck Hagenbuch
* @author Steffen Hansen
* @author Gunnar Wrobel
* @license http://www.fsf.org/copyleft/lgpl.html LGPL
@@ -15,6 +17,7 @@
/**
* Handles Itip response data.
*
+ * Copyright 2002-2010 The Horde Project (http://www.horde.org/)
* Copyright 2004-2010 Klarälvdalens Datakonsult AB
*
* See the enclosed file COPYING for license information (LGPL). If you did not
@@ -23,6 +26,8 @@
*
* @category Horde
* @package Itip
+ * @author Mike Cochrane
+ * @author Chuck Hagenbuch
* @author Steffen Hansen
* @author Gunnar Wrobel
* @license http://www.fsf.org/copyleft/lgpl.html LGPL
@@ -54,11 +59,9 @@ class Horde_Itip_Response
/**
* Constructor.
*
- * @param Horde_Itip_Event $request The request this
- * instance will respond
- * to.
- * @param Horde_Itip_Resource $resource The requested
- * resource.
+ * @param Horde_Itip_Event $request The request this instance will
+ * respond to.
+ * @param Horde_Itip_Resource $resource The requested resource.
*/
public function __construct(
Horde_Itip_Event $request,
@@ -69,7 +72,7 @@ class Horde_Itip_Response
}
/**
- * Return the response as an iCalendar vveEnt object.
+ * Return the response as an iCalendar vEvent object.
*
* @param Horde_Itip_Response_Type $type The response type.
* @param Horde_iCalendar|boolean $vCal The parent container or false if not
@@ -99,12 +102,9 @@ class Horde_Itip_Response
/**
* Return the response as an iCalendar object.
*
- * @param Horde_Itip_Response_Type $type The response
- * type.
- * @param string $product_id The ID that
- * should be set
- * as the iCalendar
- * product id.
+ * @param Horde_Itip_Response_Type $type The response type.
+ * @param string $product_id The ID that should be set as
+ * the iCalendar product id.
*
* @return Horde_iCalendar The response object.
*/
@@ -122,13 +122,12 @@ class Horde_Itip_Response
/**
* Return the response as a MIME message.
*
- * @param Horde_Itip_Response_Type $type The response
- * type.
- * @param string $product_id The ID that
- * should be set
- * as the iCalendar
- * product id.
- * @param string $subject_comment An optional comment on the subject line.
+ * @param Horde_Itip_Response_Type $type The response type.
+ * @param string $product_id The ID that should be set
+ * as the iCalendar product
+ * id.
+ * @param string $subject_comment An optional comment on
+ * the subject line.
*
* @return array A list of two object: The mime headers and the mime
* message.
@@ -138,10 +137,11 @@ class Horde_Itip_Response
$product_id,
$subject_comment = null
) {
- $ics = new MIME_Part(
- 'text/calendar',
- $this->getIcalendar($type, $product_id)->exportvCalendar(),
- 'UTF-8'
+ $ics = new Horde_Mime_Part();
+ $ics->setType('text/calendar');
+ $ics->setCharset('UTF-8');
+ $ics->setContents(
+ $this->getIcalendar($type, $product_id)->exportvCalendar()
);
$ics->setContentTypeParameter('method', 'REPLY');
@@ -153,7 +153,7 @@ class Horde_Itip_Response
// is so that Outlook interprets the messages as it does Outlook-generated
// responses, i.e. double-clicking a reply will automatically update your
// meetings, showing different status icons in the UI, etc.
- $message = MIME_Message::convertMimePart($ics);
+ //$message = Horde_Mime_Message::convertMimePart($ics);
$message->setCharset('UTF-8');
$message->setTransferEncoding('quoted-printable');
$message->transferEncodeContents();
diff --git a/framework/Itip/package.xml b/framework/Itip/package.xml
new file mode 100644
index 000000000..e92eaa8ea
--- /dev/null
+++ b/framework/Itip/package.xml
@@ -0,0 +1,140 @@
+
+
+ Itip
+ pear.horde.org
+ iTip invitation response handling.
+ This package allows to generate MIME encapsuled
+ responses to iCalender invitations.
+
+ Gunnar Wrobel
+ wrobel
+ p@rdus.de
+ yes
+
+
+ Chuck Hagenbuch
+ chuck
+ chuck@horde.org
+ yes
+
+
+ Jan Schneider
+ jan
+ jan@horde.org
+ yes
+
+ 2010-08-06
+
+
+ 0.1.0
+ 0.1.0
+
+
+ alpha
+ alpha
+
+ LGPL
+
+* Extracted package from Kolab_Resource.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5.0.0
+
+
+ 1.4.0b1
+
+
+ Icalendar
+ pear.horde.org
+ 0.2.0
+
+
+ Mime
+ pear.horde.org
+ 0.1.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0.1.0
+ 0.1.0
+
+
+ alpha
+ alpha
+
+ 2010-08-06
+ LGPL
+
+* Extracted package from Kolab_Resource.
+
+
+
+
diff --git a/framework/Itip/test/Horde/Itip/AllTests.php b/framework/Itip/test/Horde/Itip/AllTests.php
new file mode 100644
index 000000000..93a708a7f
--- /dev/null
+++ b/framework/Itip/test/Horde/Itip/AllTests.php
@@ -0,0 +1,45 @@
+
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+/**
+ * Define the main method
+ */
+if (!defined('PHPUnit_MAIN_METHOD')) {
+ define('PHPUnit_MAIN_METHOD', 'Horde_Itip_AllTests::main');
+}
+
+/**
+ * Prepare the test setup.
+ */
+require_once 'Horde/Test/AllTests.php';
+
+/**
+ * All tests for the Itip:: package.
+ *
+ * @category Horde
+ * @package Itip
+ * @subpackage UnitTests
+ * @author Gunnar Wrobel
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+class Horde_Itip_AllTests extends Horde_Test_AllTests
+{
+}
+
+Horde_Itip_AllTests::init('Horde_Itip', __FILE__);
+
+if (PHPUnit_MAIN_METHOD == 'Horde_Itip_AllTests::main') {
+ Horde_Itip_AllTests::main();
+}
diff --git a/framework/Itip/test/Horde/Itip/Autoload.php b/framework/Itip/test/Horde/Itip/Autoload.php
new file mode 100644
index 000000000..bd9840f5d
--- /dev/null
+++ b/framework/Itip/test/Horde/Itip/Autoload.php
@@ -0,0 +1,29 @@
+
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+if (!spl_autoload_functions()) {
+ spl_autoload_register(
+ create_function(
+ '$class',
+ '$filename = str_replace(array(\'::\', \'_\'), \'/\', $class);'
+ . '$err_mask = E_ALL ^ E_WARNING;'
+ . '$oldErrorReporting = error_reporting($err_mask);'
+ . 'include "$filename.php";'
+ . 'error_reporting($oldErrorReporting);'
+ )
+ );
+}
+
+/** Catch strict standards */
+error_reporting(E_ALL | E_STRICT);
diff --git a/framework/Itip/test/Horde/Itip/Integration/ItipTest.php b/framework/Itip/test/Horde/Itip/Integration/ItipTest.php
new file mode 100644
index 000000000..5a025dd6d
--- /dev/null
+++ b/framework/Itip/test/Horde/Itip/Integration/ItipTest.php
@@ -0,0 +1,256 @@
+
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+/**
+ * Prepare the test setup.
+ */
+require_once dirname(__FILE__) . '/../Autoload.php';
+
+/**
+ * Test the itip response handling.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Horde
+ * @package Itip
+ * @subpackage UnitTests
+ * @author Gunnar Wrobel
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+class Horde_Itip_Integration_ItipTest
+extends PHPUnit_Framework_TestCase
+{
+ public function testMinimalItipHandlingSteps()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertEquals($reply->getAttribute('ATTENDEE'), 'MAILTO:test@example.org');
+ }
+
+ public function testDefaultSequenceIdSetToZero()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('SEQUENCE'), 0);
+ }
+
+ public function testForCopiedSequenceIdFromRequestToResponse()
+ {
+ $inv = $this->_getInvitation();
+ $inv->setAttribute('SEQUENCE', 555);
+ $iTip = $this->_getItip($inv);
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('SEQUENCE'), 555);
+ }
+
+ public function testForCopiedStartTimeFromRequestToResponse()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('DTSTART'), array('20080926T110000'));
+ }
+
+ public function testForCopiedEndTimeFromRequestToResponse()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('DTEND'), array('20080926T120000'));
+ }
+
+ public function testForCopiedDurationFromRequestToResponse()
+ {
+ $vCal = new Horde_iCalendar();
+ $inv = Horde_iCalendar::newComponent('VEVENT', $vCal);
+ $inv->setAttribute('METHOD', 'REQUEST');
+ $inv->setAttribute('UID', '1');
+ $inv->setAttribute('SUMMARY', 'Test Invitation');
+ $inv->setAttribute('DESCRIPTION', 'You are invited');
+ $inv->setAttribute('ORGANIZER', 'orga@example.org');
+ $inv->setAttribute('DTSTART', '20080926T110000');
+ $inv->setAttribute('DURATION', 3600);
+ $iTip = $this->_getItip($inv);
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('DURATION'), 3600);
+ }
+
+ public function testForCopiedOrganizerFromRequestToResponse()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('ORGANIZER'), 'orga@example.org');
+ }
+
+ public function testForCopiedUidFromRequestToResponse()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('UID'), '1');
+ }
+
+ public function testIcalendarResponseHasMethodReply()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getIcalendarResponse(
+ new Horde_Itip_Response_Type_Accept(), ''
+ );
+ $this->assertEquals($reply->getAttribute('METHOD'), 'REPLY');
+ }
+
+ public function testIcalendarResponseAllowsSettingTheProductId()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getIcalendarResponse(
+ new Horde_Itip_Response_Type_Accept(), 'My product'
+ );
+ $this->assertEquals($reply->getAttribute('PRODID'), 'My product');
+ }
+
+ public function testMessageResponseHasFromAddress()
+ {
+ $_SERVER['SERVER_NAME'] = 'localhost';
+ $iTip = $this->_getItip();
+ $reply = $iTip->getMessageResponse(
+ new Horde_Itip_Response_Type_Accept(), '', ''
+ );
+
+ $this->assertContains('From: Mister Test ', $reply[0]->toString());
+ }
+
+ public function testMessageResponseHasToAddress()
+ {
+ $_SERVER['SERVER_NAME'] = 'localhost';
+ $iTip = $this->_getItip();
+ $reply = $iTip->getMessageResponse(
+ new Horde_Itip_Response_Type_Accept(), '', ''
+ );
+
+ $this->assertContains('To: orga@example.org', $reply[0]->toString());
+ }
+
+ public function testMessageResponseHasSubjectAddress()
+ {
+ $_SERVER['SERVER_NAME'] = 'localhost';
+ $iTip = $this->_getItip();
+ $reply = $iTip->getMessageResponse(new Horde_Itip_Response_Type_Accept(), '');
+ $this->assertContains('Subject: Accepted: Test', $reply[0]->toString());
+ }
+
+ public function testMessageResponseAllowsAddingCommentsToTheSubject()
+ {
+ $_SERVER['SERVER_NAME'] = 'localhost';
+ $iTip = $this->_getItip();
+ $reply = $iTip->getMessageResponse(
+ new Horde_Itip_Response_Type_Accept(), '', 'info'
+ );
+ $this->assertContains('Subject: Accepted [info]: Test', $reply[0]->toString());
+ }
+
+ public function testAttendeeHoldsInformationAboutMailAddress()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept(), ''
+ );
+ $this->assertEquals($reply->getAttribute('ATTENDEE'), 'MAILTO:test@example.org');
+ }
+
+ public function testAttendeeHoldsInformationAboutCommonNameAndStatus()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept(), ''
+ );
+ $parameters = $reply->getAttribute('ATTENDEE', true);
+ $this->assertEquals(
+ array_pop($parameters),
+ array(
+ 'CN' => 'Mister Test',
+ 'PARTSTAT' => 'ACCEPTED'
+ )
+ );
+ }
+
+
+ /**
+ * Test the basic iTip handling method.
+ */
+ /* public function testBasic() */
+ /* { */
+ /* $iTip = new Horde_Itip( */
+ /* $request, $resource */
+ /* ); */
+ /* $reply = $itip->setResponseType($responseType) */
+ /* ->setSubjectComment('text') */
+ /* ->setMessageComment('text') */
+ /* ->setUpdate(true) */
+ /* ->getMimeMessage(); */
+ /* } */
+
+ private function _getItip($invitation = null)
+ {
+ if ($invitation === null) {
+ $invitation = $this->_getInvitation();
+ }
+ return Horde_Itip::factory(
+ $invitation,
+ $this->_getResource()
+ );
+ }
+
+ private function _getInvitation()
+ {
+ $vCal = new Horde_Icalendar();
+ $inv = Horde_Icalendar::newComponent('VEVENT', $vCal);
+ $inv->setAttribute('METHOD', 'REQUEST');
+ $inv->setAttribute('UID', '1');
+ $inv->setAttribute('SUMMARY', 'Test Invitation');
+ $inv->setAttribute('DESCRIPTION', 'You are invited');
+ $inv->setAttribute('ORGANIZER', 'orga@example.org');
+ $inv->setAttribute('DTSTART', array('20080926T110000'));
+ $inv->setAttribute('DTEND', array('20080926T120000'));
+ return $inv;
+ }
+
+ private function _getResource($mail = null, $cn = null)
+ {
+ if ($mail === null) {
+ $mail = 'test@example.org';
+ }
+ if ($cn === null) {
+ $cn = 'Mister Test';
+ }
+ return new Horde_Itip_Resource_Base($mail, $cn);
+ }
+}
diff --git a/framework/Itip/test/Horde/Itip/phpunit.xml b/framework/Itip/test/Horde/Itip/phpunit.xml
new file mode 100644
index 000000000..502d3c9b8
--- /dev/null
+++ b/framework/Itip/test/Horde/Itip/phpunit.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ ../../../lib
+
+
+
--
2.11.0