Added testing and fixed some initial problems.
authorGunnar Wrobel <p@rdus.de>
Fri, 6 Aug 2010 20:41:54 +0000 (22:41 +0200)
committerGunnar Wrobel <p@rdus.de>
Wed, 25 Aug 2010 17:21:39 +0000 (19:21 +0200)
framework/Itip/lib/Horde/Itip/Event/Vevent.php
framework/Itip/lib/Horde/Itip/Response.php
framework/Itip/package.xml [new file with mode: 0644]
framework/Itip/test/Horde/Itip/AllTests.php [new file with mode: 0644]
framework/Itip/test/Horde/Itip/Autoload.php [new file with mode: 0644]
framework/Itip/test/Horde/Itip/Integration/ItipTest.php [new file with mode: 0644]
framework/Itip/test/Horde/Itip/phpunit.xml [new file with mode: 0644]

index f5741b0..fdf2fd3 100644 (file)
@@ -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);
     }
 
     /**
index 3fea90c..6827ecb 100644 (file)
@@ -6,6 +6,8 @@
  *
  * @category Horde
  * @package  Itip
+ * @author   Mike Cochrane <mike@graftonhall.co.nz>
+ * @author   Chuck Hagenbuch <chuck@horde.org>
  * @author   Steffen Hansen <steffen@klaralvdalens-datakonsult.se>
  * @author   Gunnar Wrobel <wrobel@pardus.de>
  * @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 <mike@graftonhall.co.nz>
+ * @author   Chuck Hagenbuch <chuck@horde.org>
  * @author   Steffen Hansen <steffen@klaralvdalens-datakonsult.se>
  * @author   Gunnar Wrobel <wrobel@pardus.de>
  * @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 (file)
index 0000000..e92eaa8
--- /dev/null
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.9.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Itip</name>
+ <channel>pear.horde.org</channel>
+ <summary>iTip invitation response handling.</summary>
+ <description>This package allows to generate MIME encapsuled
+ responses to iCalender invitations.</description>
+ <lead>
+  <name>Gunnar Wrobel</name>
+  <user>wrobel</user>
+  <email>p@rdus.de</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>Chuck Hagenbuch</name>
+  <user>chuck</user>
+  <email>chuck@horde.org</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>Jan Schneider</name>
+  <user>jan</user>
+  <email>jan@horde.org</email>
+  <active>yes</active>
+ </lead>
+ <date>2010-08-06</date>
+ <time>21:15:38</time>
+ <version>
+  <release>0.1.0</release>
+  <api>0.1.0</api>
+ </version>
+ <stability>
+  <release>alpha</release>
+  <api>alpha</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">LGPL</license>
+ <notes>
+* Extracted package from Kolab_Resource.
+ </notes>
+ <contents>
+  <dir baseinstalldir="/" name="/">
+   <dir name="lib">
+    <dir name="Horde">
+     <dir name="Itip">
+      <dir name="Event">
+       <file name="Vevent.php" role="php" />
+      </dir> <!-- /lib/Horde/Itip/Event -->
+      <dir name="Resource">
+       <file name="Base.php" role="php" />
+      </dir> <!-- /lib/Horde/Itip/Resource -->
+      <dir name="Response">
+       <dir name="Type">
+        <file name="Accept.php" role="php" />
+        <file name="Base.php" role="php" />
+        <file name="Decline.php" role="php" />
+        <file name="Tentative.php" role="php" />
+       </dir> <!-- /lib/Horde/Itip/Response/Type -->
+       <file name="Type.php" role="php" />
+      </dir> <!-- /lib/Horde/Itip/Response -->
+      <file name="Event.php" role="php" />
+      <file name="Exception.php" role="php" />
+      <file name="Resource.php" role="php" />
+      <file name="Response.php" role="php" />
+     </dir> <!-- /lib/Horde/Itip -->
+     <file name="Itip.php" role="php" />
+    </dir> <!-- /lib/Horde -->
+   </dir> <!-- /lib -->
+   <dir name="test">
+    <dir name="Horde">
+     <dir name="Itip">
+      <dir name="Integration">
+       <file name="ItipTest.php" role="test" />
+      </dir> <!-- /test/Horde/Itip/Integration -->
+      <file name="AllTests.php" role="test" />
+      <file name="Autoload.php" role="test" />
+      <file name="phpunit.xml" role="test" />
+     </dir> <!-- /test/Horde/Itip -->
+    </dir> <!-- /test/Horde -->
+   </dir> <!-- /test -->
+   <file name="TODO" role="data" />
+  </dir> <!-- / -->
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.0.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.0b1</min>
+   </pearinstaller>
+   <package>
+    <name>Icalendar</name>
+    <channel>pear.horde.org</channel>
+    <min>0.2.0</min>
+   </package>
+   <package>
+    <name>Mime</name>
+    <channel>pear.horde.org</channel>
+    <min>0.1.0</min>
+   </package>
+  </required>
+ </dependencies>
+ <phprelease>
+  <filelist>
+   <install as="Horde/Itip.php" name="lib/Horde/Itip.php" />
+   <install as="Horde/Itip/Event.php" name="lib/Horde/Itip/Event.php" />
+   <install as="Horde/Itip/Exception.php" name="lib/Horde/Itip/Exception.php" />
+   <install as="Horde/Itip/Resource.php" name="lib/Horde/Itip/Resource.php" />
+   <install as="Horde/Itip/Response.php" name="lib/Horde/Itip/Response.php" />
+   <install as="Horde/Itip/Event/Vevent.php" name="lib/Horde/Itip/Event/Vevent.php" />
+   <install as="Horde/Itip/Resource/Base.php" name="lib/Horde/Itip/Resource/Base.php" />
+   <install as="Horde/Itip/Response/Type.php" name="lib/Horde/Itip/Response/Type.php" />
+   <install as="Horde/Itip/Response/Type/Accept.php" name="lib/Horde/Itip/Response/Type/Accept.php" />
+   <install as="Horde/Itip/Response/Type/Base.php" name="lib/Horde/Itip/Response/Type/Base.php" />
+   <install as="Horde/Itip/Response/Type/Decline.php" name="lib/Horde/Itip/Response/Type/Decline.php" />
+   <install as="Horde/Itip/Response/Type/Tentative.php" name="lib/Horde/Itip/Response/Type/Tentative.php" />
+   <install as="Horde/Itip/AllTests.php" name="test/Horde/Itip/AllTests.php" />
+   <install as="Horde/Itip/Autoload.php" name="test/Horde/Itip/Autoload.php" />
+   <install as="Horde/Itip/phpunit.xml" name="test/Horde/Itip/phpunit.xml" />
+   <install as="Horde/Itip/Integration/ItipTest.php" name="test/Horde/Itip/Integration/ItipTest.php" />
+  </filelist>
+ </phprelease>
+ <changelog>
+  <release>
+   <version>
+    <release>0.1.0</release>
+    <api>0.1.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2010-08-06</date>
+   <license uri="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">LGPL</license>
+   <notes>
+* Extracted package from Kolab_Resource.
+   </notes>
+  </release>
+ </changelog>
+</package>
diff --git a/framework/Itip/test/Horde/Itip/AllTests.php b/framework/Itip/test/Horde/Itip/AllTests.php
new file mode 100644 (file)
index 0000000..93a708a
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * All tests for the Itip:: package.
+ *
+ * PHP version 5
+ *
+ * @category   Horde
+ * @package    Itip
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @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 <wrobel@pardus.de>
+ * @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 (file)
index 0000000..bd9840f
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Setup autoloading for the tests.
+ *
+ * PHP version 5
+ *
+ * @category   Horde
+ * @package    Itip
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @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 (file)
index 0000000..5a025dd
--- /dev/null
@@ -0,0 +1,256 @@
+<?php
+/**
+ * Test the itip response handling.
+ *
+ * PHP version 5
+ *
+ * @category   Horde
+ * @package    Itip
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @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 <wrobel@pardus.de>
+ * @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 <test@example.org>', $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 (file)
index 0000000..502d3c9
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit>
+  <filter>
+    <whitelist>
+      <directory suffix=".php">../../../lib</directory>
+    </whitelist>
+  </filter>
+</phpunit>