Adapt to Icalendar H4 changes. Complete testing.
authorGunnar Wrobel <wrobel@temple.(none)>
Sun, 8 Aug 2010 09:15:14 +0000 (11:15 +0200)
committerGunnar Wrobel <p@rdus.de>
Wed, 25 Aug 2010 17:21:39 +0000 (19:21 +0200)
framework/Itip/lib/Horde/Itip.php
framework/Itip/lib/Horde/Itip/Event.php
framework/Itip/lib/Horde/Itip/Event/Vevent.php
framework/Itip/lib/Horde/Itip/Response.php
framework/Itip/test/Horde/Itip/Integration/ItipTest.php
framework/Itip/test/Horde/Itip/Unit/Event/VeventTest.php [new file with mode: 0644]

index 2e13a4d..229d3dc 100644 (file)
@@ -51,7 +51,7 @@ class Horde_Itip
      *
      * @param Horde_Itip_Response_Type $type The response type.
      *
-     * @return Horde_iCalendar_vevent The response object.
+     * @return Horde_Icalendar_Vevent The response object.
      */
     public function getVeventResponse(
         Horde_Itip_Response_Type $type
@@ -105,13 +105,13 @@ class Horde_Itip
     /**
      * Factory for generating a response object for an iCalendar invitation.
      *
-     * @param Horde_iCalendar_vevent $vevent   The iCalendar request.
+     * @param Horde_Icalendar_Vevent $vevent   The iCalendar request.
      * @param Horde_Itip_Resource    $resource The invited resource.
      *
      * @return Horde_Itip_Response The prepared response.
      */
     static public function prepareResponse(
-        Horde_iCalendar_vevent $vevent,
+        Horde_Icalendar_Vevent $vevent,
         Horde_Itip_Resource $resource
     ) {
         return new Horde_Itip_Response(
@@ -125,13 +125,13 @@ class Horde_Itip
     /**
      * Factory for generating an iTip handler for an iCalendar invitation.
      *
-     * @param Horde_iCalendar_vevent $vevent   The iCalendar request.
+     * @param Horde_Icalendar_Vevent $vevent   The iCalendar request.
      * @param Horde_Itip_Resource    $resource The invited resource.
      *
      * @return Horde_Itip The iTip handler.
      */
     static public function factory(
-        Horde_iCalendar_vevent $vevent,
+        Horde_Icalendar_Vevent $vevent,
         Horde_Itip_Resource $resource
     ) {
         return new Horde_Itip(
index c11b61d..b18d844 100644 (file)
@@ -96,8 +96,4 @@ interface Horde_Itip_Event
      * @return NULL
      */
     public function setAttendee($attendee, $common_name, $status);
-
-    public function getKolabObject();
-
-    public function setAccepted($resource);
 }
\ No newline at end of file
index fdf2fd3..204e243 100644 (file)
@@ -33,17 +33,17 @@ implements Horde_Itip_Event
     /**
      * The wrapped vEvent.
      *
-     * @var Horde_iCalendar_vevent
+     * @var Horde_Icalendar_Vevent
      */
     private $_vevent;
 
     /**
      * Constructor.
      *
-     * @param Horde_iCalendar_vevent $vevent The iCalendar object that will be
+     * @param Horde_Icalendar_Vevent $vevent The iCalendar object that will be
      *                                       wrapped by this instance.
      */
-    public function __construct(Horde_iCalendar_vevent $vevent)
+    public function __construct(Horde_Icalendar_Vevent $vevent)
     {
         $this->_vevent = $vevent;
     }
@@ -51,7 +51,7 @@ implements Horde_Itip_Event
     /**
      * Returns the wrapped vEvent.
      *
-     * @return Horde_iCalendar_vevent The wrapped event.
+     * @return Horde_Icalendar_Vevent The wrapped event.
      */
     public function getVevent()
     {
@@ -81,7 +81,7 @@ implements Horde_Itip_Event
     /**
      * Return the summary for the event.
      *
-     * @return string|PEAR_Error The summary.
+     * @return string The summary.
      */
     public function getSummary()
     {
@@ -158,142 +158,6 @@ implements Horde_Itip_Event
         );
     }
 
-    public function getKolabObject()
-    {
-        $object = array();
-        $object['uid'] = $this->getUid();
-
-        $org_params = $this->_vevent->getAttribute('ORGANIZER', true);
-        if (!is_a( $org_params, 'PEAR_Error')) {
-            if (!empty($org_params[0]['CN'])) {
-                $object['organizer']['display-name'] = $org_params[0]['CN'];
-            }
-            $orgemail = $this->_vevent->getAttributeDefault('ORGANIZER', '');
-            if (preg_match('/mailto:(.*)/i', $orgemail, $regs )) {
-                $orgemail = $regs[1];
-            }
-            $object['organizer']['smtp-address'] = $orgemail;
-        }
-        $object['summary'] = $this->_vevent->getAttributeDefault('SUMMARY', '');
-        $object['location'] = $this->_vevent->getAttributeDefault('LOCATION', '');
-        $object['body'] = $this->_vevent->getAttributeDefault('DESCRIPTION', '');
-        $dtend = $this->_vevent->getAttributeDefault('DTEND', '');
-        if (is_array($dtend)) {
-            $object['_is_all_day'] = true;
-        }
-        $start = new Horde_Kolab_Resource_Epoch($this->getStart());
-        $object['start-date'] = $start->getEpoch();
-        $end = new Horde_Kolab_Resource_Epoch($dtend);
-        $object['end-date'] = $end->getEpoch();
-
-        $attendees = $this->_vevent->getAttribute('ATTENDEE');
-        if (!is_a( $attendees, 'PEAR_Error')) {
-            $attendees_params = $this->_vevent->getAttribute('ATTENDEE', true);
-            if (!is_array($attendees)) {
-                $attendees = array($attendees);
-            }
-            if (!is_array($attendees_params)) {
-                $attendees_params = array($attendees_params);
-            }
-
-            $object['attendee'] = array();
-            for ($i = 0; $i < count($attendees); $i++) {
-                $attendee = array();
-                if (isset($attendees_params[$i]['CN'])) {
-                    $attendee['display-name'] = $attendees_params[$i]['CN'];
-                }
-
-                $attendeeemail = $attendees[$i];
-                if (preg_match('/mailto:(.*)/i', $attendeeemail, $regs)) {
-                    $attendeeemail = $regs[1];
-                }
-                $attendee['smtp-address'] = $attendeeemail;
-
-                if (!isset($attendees_params[$i]['RSVP'])
-                    || $attendees_params[$i]['RSVP'] == 'FALSE') {
-                    $attendee['request-response'] = false;
-                } else {
-                    $attendee['request-response'] = true;
-                }
-
-                if (isset($attendees_params[$i]['ROLE'])) {
-                    $attendee['role'] = $attendees_params[$i]['ROLE'];
-                }
-
-                if (isset($attendees_params[$i]['PARTSTAT'])) {
-                    $status = strtolower($attendees_params[$i]['PARTSTAT']);
-                    switch ($status) {
-                    case 'needs-action':
-                    case 'delegated':
-                        $attendee['status'] = 'none';
-                        break;
-                    default:
-                        $attendee['status'] = $status;
-                        break;
-                    }
-                }
-
-                $object['attendee'][] = $attendee;
-            }
-        }
-
-        // Alarm
-        $valarm = $this->_vevent->findComponent('VALARM');
-        if ($valarm) {
-            $trigger = $valarm->getAttribute('TRIGGER');
-            if (!is_a($trigger, 'PEAR_Error')) {
-                $p = $valarm->getAttribute('TRIGGER', true);
-                if ($trigger < 0) {
-                    // All OK, enter the alarm into the XML
-                    // NOTE: The Kolab XML format seems underspecified
-                    // wrt. alarms currently...
-                    $object['alarm'] = -$trigger / 60;
-                }
-            }
-        }
-
-        // Recurrence
-        $rrule_str = $this->_vevent->getAttribute('RRULE');
-        if (!is_a($rrule_str, 'PEAR_Error')) {
-            require_once 'Horde/Date/Recurrence.php';
-            $recurrence = new Horde_Date_Recurrence(time());
-            $recurrence->fromRRule20($rrule_str);
-            $object['recurrence'] = $recurrence->toHash();
-        }
-
-        return $object;
-    }
-
-    public function setAccepted($resource)
-    {
-        // Update our status within the iTip request and send the reply
-        $this->_vevent->setAttribute('STATUS', 'CONFIRMED', array(), false);
-        $attendees = $this->_vevent->getAttribute('ATTENDEE');
-        if (!is_array($attendees)) {
-            $attendees = array($attendees);
-        }
-        $attparams = $this->_vevent->getAttribute('ATTENDEE', true);
-        foreach ($attendees as $i => $attendee) {
-            $attendee = preg_replace('/^mailto:\s*/i', '', $attendee);
-            if ($attendee != $resource) {
-                continue;
-            }
-
-            $attparams[$i]['PARTSTAT'] = 'ACCEPTED';
-            if (array_key_exists('RSVP', $attparams[$i])) {
-                unset($attparams[$i]['RSVP']);
-            }
-        }
-
-        // Re-add all the attendees to the event, using our updates status info
-        $firstatt = array_pop($attendees);
-        $firstattparams = array_pop($attparams);
-        $this->_vevent->setAttribute('ATTENDEE', $firstatt, $firstattparams, false);
-        foreach ($attendees as $i => $attendee) {
-            $this->_vevent->setAttribute('ATTENDEE', $attendee, $attparams[$i]);
-        }
-    }
-
     /**
      * Set the uid of the iTip event.
      *
@@ -339,19 +203,9 @@ implements Horde_Itip_Event
     }
 
     /**
-     * Does the event have a description?
-     *
-     * @return boolean True if it has a description, false otherwise.
-     */
-    private function hasDescription()
-    {
-        return !($this->_vevent->getAttribute('DESCRIPTION') instanceOf PEAR_Error);
-    }
-
-    /**
      * Return the description for the event.
      *
-     * @return string|PEAR_Error The description.
+     * @return string The description.
      */
     private function getDescription()
     {
@@ -377,8 +231,9 @@ implements Horde_Itip_Event
      */
     private function copyDescription(Horde_Itip_Event $itip)
     {
-        if ($this->hasDescription()) {
+        try {
             $itip->setDescription($this->getDescription());
+        } catch (Horde_Icalendar_Exception $e) {
         }
     }
 
@@ -443,7 +298,7 @@ implements Horde_Itip_Event
     /**
      * Return the duration for the event.
      *
-     * @return string|PEAR_Error The duration of the event.
+     * @return string The duration of the event.
      */
     private function getDuration()
     {
@@ -492,7 +347,7 @@ implements Horde_Itip_Event
     /**
      * Return the sequence for the event.
      *
-     * @return string|PEAR_Error The sequence.
+     * @return string The sequence.
      */
     private function getSequence()
     {
@@ -523,7 +378,7 @@ implements Horde_Itip_Event
     /**
      * Return the location for the event.
      *
-     * @return string|PEAR_Error The location.
+     * @return string The location.
      */
     private function getLocation()
     {
@@ -558,7 +413,7 @@ implements Horde_Itip_Event
     /**
      * Return the organizer for the event.
      *
-     * @return string|PEAR_Error The organizer of the event.
+     * @return string The organizer of the event.
      */
     private function getRawOrganizer()
     {
index 6827ecb..63a2625 100644 (file)
@@ -78,7 +78,7 @@ class Horde_Itip_Response
      * @param Horde_iCalendar|boolean  $vCal The parent container or false if not
      *                                       provided.
      *
-     * @return Horde_iCalendar_vevent The response object.
+     * @return Horde_Icalendar_Vevent The response object.
      */
     public function getVevent(
         Horde_Itip_Response_Type $type,
@@ -154,19 +154,20 @@ class Horde_Itip_Response
         // responses, i.e. double-clicking a reply will automatically update your
         // meetings, showing different status icons in the UI, etc.
         //$message = Horde_Mime_Message::convertMimePart($ics);
+        $message = new Horde_Mime_Part();
         $message->setCharset('UTF-8');
         $message->setTransferEncoding('quoted-printable');
-        $message->transferEncodeContents();
+        //$message->transferEncodeContents();
 
         // Build the reply headers.
-        $headers = new MIME_Headers();
+        $headers = new Horde_Mime_Headers();
         $headers->addHeader('Date', date('r'));
         $headers->addHeader('From', $this->_resource->getFrom());
         $headers->addHeader('To', $this->_request->getOrganizer());
         $headers->addHeader(
             'Subject', $type->getSubject($subject_comment)
         );
-        $headers->addMIMEHeaders($message);
+        //$headers->addMimeHeaders($message);
         return array($headers, $message);
     }
 }
\ No newline at end of file
index 5a025dd..bccf7b5 100644 (file)
@@ -71,7 +71,7 @@ extends PHPUnit_Framework_TestCase
         $reply = $iTip->getVeventResponse(
             new Horde_Itip_Response_Type_Accept()
         );
-        $this->assertSame($reply->getAttribute('DTSTART'), array('20080926T110000'));
+        $this->assertEquals(1222419600, $reply->getAttribute('DTSTART'));
     }
 
     public function testForCopiedEndTimeFromRequestToResponse()
@@ -80,7 +80,7 @@ extends PHPUnit_Framework_TestCase
         $reply = $iTip->getVeventResponse(
             new Horde_Itip_Response_Type_Accept()
         );
-        $this->assertSame($reply->getAttribute('DTEND'), array('20080926T120000'));
+        $this->assertEquals(1222423200, $reply->getAttribute('DTEND'));
     }
 
     public function testForCopiedDurationFromRequestToResponse()
@@ -110,6 +110,24 @@ extends PHPUnit_Framework_TestCase
         $this->assertSame($reply->getAttribute('ORGANIZER'), 'orga@example.org');
     }
 
+    public function testForCopiedLocationFromRequestToResponse()
+    {
+        $iTip = $this->_getItip();
+        $reply = $iTip->getVeventResponse(
+            new Horde_Itip_Response_Type_Accept()
+        );
+        $this->assertSame($reply->getAttribute('LOCATION'), 'Somewhere');
+    }
+
+    public function testForCopiedDescriptionFromRequestToResponse()
+    {
+        $iTip = $this->_getItip();
+        $reply = $iTip->getVeventResponse(
+            new Horde_Itip_Response_Type_Accept()
+        );
+        $this->assertSame($reply->getAttribute('DESCRIPTION'), 'You are invited');
+    }
+
     public function testForCopiedUidFromRequestToResponse()
     {
         $iTip = $this->_getItip();
@@ -159,7 +177,7 @@ extends PHPUnit_Framework_TestCase
         $this->assertContains('To: orga@example.org', $reply[0]->toString());
     }
 
-    public function testMessageResponseHasSubjectAddress()
+    public function testMessageAcceptResponseHasAcceptSubject()
     {
         $_SERVER['SERVER_NAME'] = 'localhost';
         $iTip = $this->_getItip();
@@ -167,6 +185,22 @@ extends PHPUnit_Framework_TestCase
         $this->assertContains('Subject: Accepted: Test', $reply[0]->toString());
     }
 
+    public function testMessageDeclineResponseHasDeclineSubject()
+    {
+        $_SERVER['SERVER_NAME'] = 'localhost';
+        $iTip = $this->_getItip();
+        $reply = $iTip->getMessageResponse(new Horde_Itip_Response_Type_Decline(), '');
+        $this->assertContains('Subject: Declined: Test', $reply[0]->toString());
+    }
+
+    public function testMessageTentativeResponseHasTentativeSubject()
+    {
+        $_SERVER['SERVER_NAME'] = 'localhost';
+        $iTip = $this->_getItip();
+        $reply = $iTip->getMessageResponse(new Horde_Itip_Response_Type_Tentative(), '');
+        $this->assertContains('Subject: Tentative: Test', $reply[0]->toString());
+    }
+
     public function testMessageResponseAllowsAddingCommentsToTheSubject()
     {
         $_SERVER['SERVER_NAME'] = 'localhost';
@@ -203,21 +237,6 @@ extends PHPUnit_Framework_TestCase
     }
 
 
-    /**
-     * 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) {
@@ -231,15 +250,18 @@ extends PHPUnit_Framework_TestCase
 
     private function _getInvitation()
     {
+        $start = new Horde_Date('20080926T110000');
+        $end = new Horde_Date('20080926T120000');
         $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('LOCATION', 'Somewhere');
         $inv->setAttribute('ORGANIZER', 'orga@example.org');
-        $inv->setAttribute('DTSTART', array('20080926T110000'));
-        $inv->setAttribute('DTEND', array('20080926T120000'));
+        $inv->setAttribute('DTSTART', $start->timestamp());
+        $inv->setAttribute('DTEND', $end->timestamp());
         return $inv;
     }
 
diff --git a/framework/Itip/test/Horde/Itip/Unit/Event/VeventTest.php b/framework/Itip/test/Horde/Itip/Unit/Event/VeventTest.php
new file mode 100644 (file)
index 0000000..4e9944e
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Test the vEvent iCal 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 vEvent iCal 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_Unit_Event_VeventTest
+extends PHPUnit_Framework_TestCase
+{
+    public function testGetMethodReturnsMethod()
+    {
+        $inv = Horde_Icalendar::newComponent('VEVENT', false);
+        $inv->setAttribute('METHOD', 'TEST');
+        $vevent = new Horde_Itip_Event_Vevent($inv);
+        $this->assertEquals('TEST', $vevent->getMethod());
+    }
+
+    public function testGetMethodReturnsDefaultMethod()
+    {
+        $inv = Horde_Icalendar::newComponent('VEVENT', false);
+        $vevent = new Horde_Itip_Event_Vevent($inv);
+        $this->assertEquals('REQUEST', $vevent->getMethod());
+    }
+
+}