Complete unit testing for Horde_Itip.
authorGunnar Wrobel <p@rdus.de>
Tue, 17 Aug 2010 12:36:53 +0000 (14:36 +0200)
committerGunnar Wrobel <p@rdus.de>
Wed, 25 Aug 2010 17:21:42 +0000 (19:21 +0200)
framework/Itip/lib/Horde/Itip.php
framework/Itip/lib/Horde/Itip/Response.php
framework/Itip/test/Horde/Itip/Autoload.php
framework/Itip/test/Horde/Itip/Integration/ItipTest.php
framework/Itip/test/Horde/Itip/Stub/Identity.php [new file with mode: 0644]
framework/Itip/test/Horde/Itip/Unit/Response/Type/BaseTest.php [new file with mode: 0644]

index 79898a1..77e366f 100644 (file)
@@ -46,16 +46,6 @@ class Horde_Itip
     }
 
     /**
-     * Return the organizer mail address.
-     *
-     * @return string The mail address of the event organizer
-     */
-    public function getOrganizer()
-    {
-        return $this->_response->getRequest()->getOrganizer();
-    }
-
-    /**
      * Return the response as an iCalendar vEvent object.
      *
      * @param Horde_Itip_Response_Type $type The response type.
@@ -89,21 +79,27 @@ class Horde_Itip
     }
 
     /**
-     * Return the response as a MIME message.
+     * Send the response as a single part MIME message.
+     *
+     * @param Horde_Itip_Response_Type    $type      The response type.
+     * @param Horde_Itip_Response_Options $options   The options for the response.
+     * @param Horde_Mail_Transport        $transport The mail transport.
      *
-     * @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 array A list of two object: The mime headers and the mime
      *               message.
      */
-    public function getMessageResponse(
+    public function sendSinglepartResponse(
         Horde_Itip_Response_Type $type,
-        $product_id
+        Horde_Itip_Response_Options $options,
+        Horde_Mail_Transport $transport
     ) {
-        return $this->_response->getMessage(
-            $type, $product_id
+        list($headers, $body) = $this->_response->getMessage(
+            $type, $options
+        );
+        $body->send(
+            $this->_response->getRequest()->getOrganizer(),
+            $headers,
+            $transport
         );
     }
 
index c174707..940a3e1 100644 (file)
@@ -157,7 +157,7 @@ class Horde_Itip_Response
         $headers->addHeader('Date', date('r'));
         $headers->addHeader('From', $from);
         $headers->addHeader('To', $this->_request->getOrganizer());
-        if ($reply_to != $from) {
+        if (!empty($reply_to) && $reply_to != $from) {
             $headers->addHeader('Reply-to', $reply_to);
         }
         $headers->addHeader(
index bd9840f..6115b9f 100644 (file)
@@ -27,3 +27,6 @@ if (!spl_autoload_functions()) {
 
 /** Catch strict standards */
 error_reporting(E_ALL | E_STRICT);
+
+/** Load dependencies from the test suite */
+require_once dirname(__FILE__) . '/Stub/Identity.php';
\ No newline at end of file
index 2e36aa0..7f17f05 100644 (file)
@@ -36,22 +36,18 @@ require_once dirname(__FILE__) . '/../Autoload.php';
 class Horde_Itip_Integration_ItipTest
 extends PHPUnit_Framework_TestCase
 {
-    public function testMinimalItipHandlingSteps()
+    public function setUp()
     {
-        $iTip = $this->_getItip();
-        $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept()
-        );
-        $this->assertEquals($reply->getAttribute('ATTENDEE'), 'MAILTO:test@example.org');
+        $this->_transport = new Horde_Mail_Transport_Mock();
     }
 
-    public function testDefaultSequenceIdSetToZero()
+    public function testMinimalItipHandlingSteps()
     {
         $iTip = $this->_getItip();
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept()
+            new Horde_Itip_Response_Type_Accept($this->_getResource())
         );
-        $this->assertSame($reply->getAttribute('SEQUENCE'), 0);
+        $this->assertEquals($reply->getAttribute('ATTENDEE'), 'mailto:test@example.org');
     }
 
     public function testForCopiedSequenceIdFromRequestToResponse()
@@ -60,7 +56,7 @@ extends PHPUnit_Framework_TestCase
         $inv->setAttribute('SEQUENCE', 555);
         $iTip = $this->_getItip($inv);
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept()
+            new Horde_Itip_Response_Type_Accept($this->_getResource())
         );
         $this->assertSame($reply->getAttribute('SEQUENCE'), 555);
     }
@@ -69,7 +65,7 @@ extends PHPUnit_Framework_TestCase
     {
         $iTip = $this->_getItip();
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept()
+            new Horde_Itip_Response_Type_Accept($this->_getResource())
         );
         $this->assertEquals(1222419600, $reply->getAttribute('DTSTART'));
     }
@@ -78,7 +74,7 @@ extends PHPUnit_Framework_TestCase
     {
         $iTip = $this->_getItip();
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept()
+            new Horde_Itip_Response_Type_Accept($this->_getResource())
         );
         $this->assertEquals(1222423200, $reply->getAttribute('DTEND'));
     }
@@ -96,7 +92,7 @@ extends PHPUnit_Framework_TestCase
         $inv->setAttribute('DURATION', 3600);
         $iTip = $this->_getItip($inv);
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept()
+            new Horde_Itip_Response_Type_Accept($this->_getResource())
         );
         $this->assertSame($reply->getAttribute('DURATION'), 3600);
     }
@@ -105,7 +101,7 @@ extends PHPUnit_Framework_TestCase
     {
         $iTip = $this->_getItip();
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept()
+            new Horde_Itip_Response_Type_Accept($this->_getResource())
         );
         $this->assertSame($reply->getAttribute('ORGANIZER'), 'orga@example.org');
     }
@@ -114,7 +110,7 @@ extends PHPUnit_Framework_TestCase
     {
         $iTip = $this->_getItip();
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept()
+            new Horde_Itip_Response_Type_Accept($this->_getResource())
         );
         $this->assertSame($reply->getAttribute('LOCATION'), 'Somewhere');
     }
@@ -123,7 +119,7 @@ extends PHPUnit_Framework_TestCase
     {
         $iTip = $this->_getItip();
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept()
+            new Horde_Itip_Response_Type_Accept($this->_getResource())
         );
         $this->assertSame($reply->getAttribute('DESCRIPTION'), 'You are invited');
     }
@@ -132,7 +128,7 @@ extends PHPUnit_Framework_TestCase
     {
         $iTip = $this->_getItip();
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept()
+            new Horde_Itip_Response_Type_Accept($this->_getResource())
         );
         $this->assertSame($reply->getAttribute('UID'), '1');
     }
@@ -141,90 +137,170 @@ extends PHPUnit_Framework_TestCase
     {
         $iTip = $this->_getItip();
         $reply = $iTip->getIcalendarResponse(
-            new Horde_Itip_Response_Type_Accept(), ''
+            new Horde_Itip_Response_Type_Accept($this->_getResource()),
+            new Horde_Itip_Response_Options_Kolab()
         );
         $this->assertEquals($reply->getAttribute('METHOD'), 'REPLY');
     }
 
-    public function testIcalendarResponseAllowsSettingTheProductId()
+    public function testMessageResponseHasFromAddress()
     {
+        $_SERVER['SERVER_NAME'] = 'localhost';
         $iTip = $this->_getItip();
-        $reply = $iTip->getIcalendarResponse(
-            new Horde_Itip_Response_Type_Accept(), 'My product'
+        $reply = $iTip->sendSinglepartResponse(
+            new Horde_Itip_Response_Type_Accept($this->_getResource()),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
+        );
+        
+        $this->assertContains(
+            'From: Mister Test <test@example.org>',
+            $this->_transport->sentMessages[0]['header_text']
         );
-        $this->assertEquals($reply->getAttribute('PRODID'), 'My product');
     }
 
-    public function testMessageResponseHasFromAddress()
+    public function testMessageResponseWithIdentityResourceHasFromAddress()
     {
         $_SERVER['SERVER_NAME'] = 'localhost';
-        $iTip = $this->_getItip();
-        $reply = $iTip->getMessageResponse(
-            new Horde_Itip_Response_Type_Accept(), '', ''
+        $invitation = $this->_getInvitation();
+        $resource = new Horde_Itip_Resource_Identity(
+            new Horde_Itip_Stub_Identity(),
+            'mailto:test@example.org',
+            'test'
+        );
+        $iTip = Horde_Itip::factory(
+            $invitation,
+            $resource
+        );
+        $reply = $iTip->sendSinglepartResponse(
+            new Horde_Itip_Response_Type_Accept($resource),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
+        );
+
+        $this->assertContains(
+            'From: "Mr. Test" <test@example.org>',
+            $this->_transport->sentMessages[0]['header_text']
+        );
+    }
+
+    public function testMessageResponseWithDefaultIdentityResourceHasDefaultFromAddress()
+    {
+        $_SERVER['SERVER_NAME'] = 'localhost';
+        $invitation = $this->_getInvitation();
+        $resource = new Horde_Itip_Resource_Identity(
+            new Horde_Itip_Stub_Identity(),
+            'mailto:default@example.org',
+            'default'
+        );
+        $iTip = Horde_Itip::factory(
+            $invitation,
+            $resource
+        );
+        $reply = $iTip->sendSinglepartResponse(
+            new Horde_Itip_Response_Type_Accept($resource),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
+        );
+
+        $this->assertContains(
+            'From: default@example.org',
+            $this->_transport->sentMessages[0]['header_text']
         );
-        
-        $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(), '', ''
+        $reply = $iTip->sendSinglepartResponse(
+            new Horde_Itip_Response_Type_Accept($this->_getResource()),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
         );
         
-        $this->assertContains('To: orga@example.org', $reply[0]->toString());
+        $this->assertContains(
+            'To: orga@example.org', 
+            $this->_transport->sentMessages[0]['header_text']
+        );
     }
 
     public function testMessageAcceptResponseHasAcceptSubject()
     {
         $_SERVER['SERVER_NAME'] = 'localhost';
         $iTip = $this->_getItip();
-        $reply = $iTip->getMessageResponse(new Horde_Itip_Response_Type_Accept(), '');
-        $this->assertContains('Subject: Accepted: Test', $reply[0]->toString());
+        $reply = $iTip->sendSinglepartResponse(
+            new Horde_Itip_Response_Type_Accept($this->_getResource()),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
+        );
+        $this->assertContains(
+            'Subject: Accepted: Test',
+            $this->_transport->sentMessages[0]['header_text']
+        );
     }
 
     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());
+        $reply = $iTip->sendSinglepartResponse(
+            new Horde_Itip_Response_Type_Decline($this->_getResource()),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
+        );
+        $this->assertContains(
+            'Subject: Declined: Test',
+            $this->_transport->sentMessages[0]['header_text']
+        );
     }
 
     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());
+        $reply = $iTip->sendSinglepartResponse(
+            new Horde_Itip_Response_Type_Tentative($this->_getResource()),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
+        );
+        $this->assertContains(
+            'Subject: Tentative: Test',
+            $this->_transport->sentMessages[0]['header_text']
+        );
     }
 
     public function testMessageResponseAllowsAddingCommentsToTheSubject()
     {
         $_SERVER['SERVER_NAME'] = 'localhost';
         $iTip = $this->_getItip();
-        $reply = $iTip->getMessageResponse(
-            new Horde_Itip_Response_Type_Accept(), '', 'info'
+        $reply = $iTip->sendSinglepartResponse(
+            new Horde_Itip_Response_Type_Accept($this->_getResource(), 'info'),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
+        );
+        $this->assertContains(
+            'Subject: Accepted [info]: Test',
+            $this->_transport->sentMessages[0]['header_text']
         );
-        $this->assertContains('Subject: Accepted [info]: Test', $reply[0]->toString());
     }
 
     public function testAttendeeHoldsInformationAboutMailAddress()
     {
         $iTip = $this->_getItip();
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept(), ''
+            new Horde_Itip_Response_Type_Accept($this->_getResource()),
+            new Horde_Itip_Response_Options_Kolab()
         );
-        $this->assertEquals($reply->getAttribute('ATTENDEE'), 'MAILTO:test@example.org');
+        $this->assertEquals($reply->getAttribute('ATTENDEE'), 'mailto:test@example.org');
     }
 
     public function testAttendeeHoldsInformationAboutCommonNameAndStatus()
     {
         $iTip = $this->_getItip();
         $reply = $iTip->getVeventResponse(
-            new Horde_Itip_Response_Type_Accept(), ''
+            new Horde_Itip_Response_Type_Accept($this->_getResource()),
+            new Horde_Itip_Response_Options_Kolab()
         );
         $parameters = $reply->getAttribute('ATTENDEE', true);
         $this->assertEquals(
@@ -236,6 +312,70 @@ extends PHPUnit_Framework_TestCase
         );
     }
 
+    public function testMultipartMessageResponseHoldsMultipleParts()
+    {
+        $_SERVER['SERVER_NAME'] = 'localhost';
+        $iTip = $this->_getItip();
+        $reply = $iTip->sendMultipartResponse(
+            new Horde_Itip_Response_Type_Accept($this->_getResource(), 'info'),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
+        );
+        $mail = '';
+        $mail .= $this->_transport->sentMessages[0]['header_text'] . "\n\n";
+        $body = $this->_transport->sentMessages[0]['body'];
+        while (!feof($body)) {
+            $mail .= fread($body, 8192);
+        }
+        $part = Horde_Mime_Part::parseMessage($mail);
+        $this->assertEquals(2, count($part->getParts()));
+    }
+
+    public function testMultipartMessageDeclineResponseHasDeclineSubject()
+    {
+        $_SERVER['SERVER_NAME'] = 'localhost';
+        $iTip = $this->_getItip();
+        $reply = $iTip->sendMultipartResponse(
+            new Horde_Itip_Response_Type_Decline($this->_getResource()),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
+        );
+        $this->assertContains(
+            'Subject: Declined: Test',
+            $this->_transport->sentMessages[0]['header_text']
+        );
+    }
+
+    public function testMultipartMessageTentativeResponseHasTentativeSubject()
+    {
+        $_SERVER['SERVER_NAME'] = 'localhost';
+        $iTip = $this->_getItip();
+        $reply = $iTip->sendMultipartResponse(
+            new Horde_Itip_Response_Type_Tentative($this->_getResource()),
+            new Horde_Itip_Response_Options_Kolab(),
+            $this->_transport
+        );
+        $this->assertContains(
+            'Subject: Tentative: Test',
+            $this->_transport->sentMessages[0]['header_text']
+        );
+    }
+
+    public function testMultipartMessageWithHordeOptionsHasMessageId()
+    {
+        $_SERVER['REMOTE_ADDR'] = 'none';
+        $_SERVER['SERVER_NAME'] = 'localhost';
+        $iTip = $this->_getItip();
+        $reply = $iTip->sendMultipartResponse(
+            new Horde_Itip_Response_Type_Accept($this->_getResource(), 'info'),
+            new Horde_Itip_Response_Options_Horde('UTF-8', array()),
+            $this->_transport
+        );
+        $this->assertContains(
+            'Message-ID:',
+            $this->_transport->sentMessages[0]['header_text']
+        );
+    }
 
     private function _getItip($invitation = null)
     {
diff --git a/framework/Itip/test/Horde/Itip/Stub/Identity.php b/framework/Itip/test/Horde/Itip/Stub/Identity.php
new file mode 100644 (file)
index 0000000..ce283de
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Dummy IMP_Prefs_Identity stub.
+ *
+ * PHP version 5
+ *
+ * @category   Horde
+ * @package    IMP
+ * @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=Imp
+ */
+
+/**
+ * Dummy IMP_Prefs_Identity stub.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @category   Horde
+ * @package    IMP
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @license    http://www.fsf.org/copyleft/gpl.html GPL
+ * @link       http://pear.horde.org/index.php?package=Imp
+ */
+class Horde_Itip_Stub_Identity
+{
+    private $_id = 'default';
+
+    public function getMatchingIdentity($mail)
+    {
+        if ($mail == 'test@example.org') {
+            return 'test';
+        }
+    }
+
+    public function setDefault($id)
+    {
+        if ($id != 'test' && $id != 'other' && $id != 'default') {
+            throw new Exception("Unexpected default $id!");
+        }
+        $this->_id = $id;
+    }
+
+    public function getDefault()
+    {
+        return $this->_id;
+    }
+
+    public function getFromAddress()
+    {
+        if ($this->_id == 'test') {
+            return 'test@example.org';
+        }
+        if ($this->_id == 'default') {
+            return 'default@example.org';
+        }
+    }
+
+    public function getValue($value)
+    {
+        switch ($value) {
+        case 'fullname':
+            if ($this->_id == 'test') {
+                return 'Mr. Test';
+            } else {
+                return '';
+            }
+        case 'replyto_addr':
+            switch ($this->_id) {
+            case 'test':
+                return 'test@example.org';
+            case 'other':
+                return 'reply@example.org';
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/framework/Itip/test/Horde/Itip/Unit/Response/Type/BaseTest.php b/framework/Itip/test/Horde/Itip/Unit/Response/Type/BaseTest.php
new file mode 100644 (file)
index 0000000..17bb47c
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Test the base response definition.
+ *
+ * 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 base response definition.
+ *
+ * Copyright 2010 Kolab Systems AG
+ *
+ * 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_Response_Type_BaseTest
+extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @expectedException Horde_Itip_Exception
+     */
+    public function testExceptionOnUndefinedRequest()
+    {
+        $type = new Horde_Itip_Response_Type_Accept(
+            new Horde_Itip_Resource_Base('', '')
+        );
+        $type->getRequest();
+    }
+}