fixes bad chars wbxml encoding
authorPhilipp Schüle <p.schuele@metaways.de>
Mon, 17 Nov 2014 15:31:31 +0000 (16:31 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Wed, 12 Aug 2015 17:20:46 +0000 (19:20 +0200)
* adds several test
* removes bad chars from email bodies

Change-Id: I44eca3323363fa44abaa212ecb6d8934a4137aa4
Reviewed-on: http://gerrit.tine20.com/customers/2054
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/ActiveSync/Command/SyncTests.php
tests/tine20/ActiveSync/Command/ibernard.xml [new file with mode: 0644]
tests/tine20/Felamimail/Frontend/ActiveSyncTest.php
tests/tine20/Felamimail/files/emoji.eml [new file with mode: 0644]
tests/tine20/Felamimail/files/invalid_body_chars.eml
tine20/Felamimail/Controller/Message.php

index 2a1c037..e9f86bb 100644 (file)
@@ -47,7 +47,7 @@ class ActiveSync_Command_SyncTests extends TestCase
     protected function setUp()
     {
         parent::setUp();
-        
+
         Syncroton_Registry::setDatabase(Tinebase_Core::getDb());
         Syncroton_Registry::setTransactionManager(Tinebase_TransactionManager::getInstance());
         
@@ -69,6 +69,18 @@ class ActiveSync_Command_SyncTests extends TestCase
     }
 
     /**
+     * tear down tests
+     */
+    protected function tearDown()
+    {
+        parent::tearDown();
+
+        if (! $this->_transactionId) {
+            Syncroton_Registry::getDeviceBackend()->delete($this->_device->id);
+        }
+    }
+
+    /**
      * test sync of existing contacts folder
      */
     public function testSyncOfContacts()
@@ -254,6 +266,20 @@ class ActiveSync_Command_SyncTests extends TestCase
         $this->assertEquals(1, $nodes->length, $syncDoc->saveXML());
         $this->assertEquals(Syncroton_Command_Sync::STATUS_SUCCESS, $nodes->item(0)->nodeValue, $syncDoc->saveXML());
     }
+
+    /**
+     * tests xml encoding/decoding
+     */
+    public function testWbXmlEncodeDecode()
+    {
+        $xmlFile = file_get_contents(dirname(__FILE__) . '/ibernard.xml');
+        $doc = new DOMDocument();
+        $doc->preserveWhiteSpace = false;
+        $doc->loadXML($xmlFile, LIBXML_NOWARNING);
+
+        $output = Felamimail_Frontend_ActiveSyncTest::encodeXml($doc);
+        $this->assertContains(' Mein Kopf ist gerade zu voll... 😃', $output);
+    }
     
     /**
      * test sync of existing events folder
@@ -280,9 +306,8 @@ class ActiveSync_Command_SyncTests extends TestCase
             ))
         ));
         
-        $event = Calendar_Controller_Event::getInstance()->create($event);
-        
-        
+        Calendar_Controller_Event::getInstance()->create($event);
+
         // first do a foldersync
         $doc = new DOMDocument();
         $doc->loadXML('<?xml version="1.0" encoding="utf-8"?>
@@ -361,8 +386,12 @@ class ActiveSync_Command_SyncTests extends TestCase
     
     /**
      * test sync of existing imap folder
+     *
+     * @param string $filename
+     * @param string $testHeaderValue
+     * @return string output
      */
-    public function testSyncOfEmails()
+    public function testSyncOfEmails($filename = 'multipart_mixed.eml', $testHeaderValue = 'multipart/mixed')
     {
         $imapConfig = Tinebase_Config::getInstance()->get(Tinebase_Config::IMAP);
         if (! $imapConfig || ! isset($imapConfig->useSystemAccount) || $imapConfig->useSystemAccount != TRUE) {
@@ -373,18 +402,23 @@ class ActiveSync_Command_SyncTests extends TestCase
         $emailTest = new Felamimail_Controller_MessageTest();
         $emailTest->setUp();
         $inbox = $emailTest->getFolder('INBOX');
-        $emailTest->messageTestHelper('multipart_mixed.eml', 'multipart/mixed', $inbox);
+        $emailTest->messageTestHelper($filename, $testHeaderValue, $inbox);
         
         $emailController = new Felamimail_Frontend_ActiveSync($this->_device, new Tinebase_DateTime(null, null, 'de_DE'));
 
         $folders = $emailController->getAllFolders();
-        
+
+
         foreach ($folders as $folder) {
             if (strtoupper($folder->displayName) == 'INBOX') {
                 break;
             }
         }
-        
+
+        if (! isset($folder)) {
+            $this->fail('should have an INBOX');
+        }
+
         // first do a foldersync
         $doc = new DOMDocument();
         $doc->loadXML('<?xml version="1.0" encoding="utf-8"?>
@@ -452,6 +486,8 @@ class ActiveSync_Command_SyncTests extends TestCase
         $sync->handle();
         
         $syncDoc = $sync->getResponse();
+
+        // activate for xml output
         #$syncDoc->formatOutput = true; echo $syncDoc->saveXML();
         
         $xpath = new DomXPath($syncDoc);
@@ -473,10 +509,22 @@ class ActiveSync_Command_SyncTests extends TestCase
         $this->assertEquals(1, $nodes->length, $syncDoc->saveXML());
         
         $this->assertEquals("uri:Email", $syncDoc->lookupNamespaceURI('Email'), $syncDoc->saveXML());
-        
+
+        $output = Felamimail_Frontend_ActiveSyncTest::encodeXml($syncDoc);
+
         $emailTest->tearDown();
+
+        return $output;
     }
 
+    public function testSyncOfGarbledEmail()
+    {
+        $this->_testNeedsTransaction();
+
+        $output = $this->testSyncOfEmails('emoji.eml', 'emoji.eml');
+
+        $this->assertContains('Mein Kopf ist gerade zu voll...?', $output, 'emoji should be replaced with "?"');
+    }
     
     /**
      * testResetSync
@@ -499,8 +547,8 @@ class ActiveSync_Command_SyncTests extends TestCase
         
         foreach ($folderState as $folder) {
             try {
-               $syncState = Syncroton_Registry::getSyncStateBackend()->getSyncState($this->_device->id, $folder->id);
-               $this->fail('should not find sync state for folder');
+                Syncroton_Registry::getSyncStateBackend()->getSyncState($this->_device->id, $folder->id);
+                $this->fail('should not find sync state for folder');
             } catch (Exception $e) {
                 $this->assertEquals('id not found', $e->getMessage());
             }
diff --git a/tests/tine20/ActiveSync/Command/ibernard.xml b/tests/tine20/ActiveSync/Command/ibernard.xml
new file mode 100644 (file)
index 0000000..3b0b3a5
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
+<Sync xmlns="uri:AirSync" xmlns:Syncroton="uri:Syncroton" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Email="uri:Email" xmlns:Email2="uri:Email2" xmlns:Tasks="uri:Tasks">
+  <Collections>
+    <Collection xmlns:default="uri:Email" xmlns:default1="uri:AirSyncBase" xmlns:default2="uri:Email2" xmlns:Syncroton="uri:Syncroton">
+      <Class>Email</Class>
+      <SyncKey>4</SyncKey>
+      <CollectionId>45898fd75f3990586f7f7c16fb1b53bf3a5128c8</CollectionId>
+      <Status>1</Status>
+      <MoreAvailable/>
+      <Commands xmlns:default="uri:Email" xmlns:default1="uri:AirSyncBase" xmlns:default2="uri:Email2" xmlns:Syncroton="uri:Syncroton">
+        <Add xmlns:default="uri:Email" xmlns:default1="uri:AirSyncBase" xmlns:default2="uri:Email2" xmlns:Syncroton="uri:Syncroton">
+          <ServerId>c48dfe5e1ccf22afbcf11aff2b9d1438020affb8</ServerId>
+          <ApplicationData>
+            <Email:DateReceived xmlns="uri:Email">2014-10-21T07:18:51.000Z</Email:DateReceived>
+            <Email:From xmlns="uri:Email">"Heinz Erhard Herno" &lt;heinz@erhard.de&gt;</Email:From>
+            <Email:Subject xmlns="uri:Email">Re-2: Frage</Email:Subject>
+            <Email:To xmlns="uri:Email">erhard@erhard.de</Email:To>
+            <AirSyncBase:Body xmlns="uri:AirSyncBase">
+              <AirSyncBase:Type>1</AirSyncBase:Type>
+              <AirSyncBase:EstimatedDataSize>9458</AirSyncBase:EstimatedDataSize>
+              <AirSyncBase:Data>ok!&#13;
+&#13;
+&#13;
+ Original Message processed by David.fx12  &#13;
+Re: Frage (21-Okt-2014 6:47)&#13;
+From:   Heinz Erhard&#13;
+To:Fritz Meister&#13;
+&#13;
+&#13;
+Guten Morgen Fritz,&#13;
+&#13;
+&#13;
+ich bin gerade nicht sicher, weil ich so viele Entwürfe und das momentane Formular nicht vor Augen habe. Es gibt ja Rechnungen und Erinnerungen usw. Mein Kopf ist gerade zu voll... 😃.&#13;
+Ich bin heute in hummel - wenn ich morgen wieder in himmel bin, schaue ich in den Unterlagen nach.&#13;
+&#13;
+&#13;
+Viele Grüße&#13;
+&#13;
+&#13;
+Heinz&#13;
+&#13;
+Von meinem iPa</AirSyncBase:Data>
+              <AirSyncBase:Truncated>1</AirSyncBase:Truncated>
+            </AirSyncBase:Body>
+            <AirSyncBase:NativeBodyType xmlns="uri:AirSyncBase">1</AirSyncBase:NativeBodyType>
+            <Email:MessageClass xmlns="uri:Email">IPM.Note</Email:MessageClass>
+            <Email:ContentClass xmlns="uri:Email">urn:content-classes:message</Email:ContentClass>
+            <Email:Read xmlns="uri:Email">1</Email:Read>
+            <Email:Flag xmlns="uri:Email">
+              <Email:Status>0</Email:Status>
+            </Email:Flag>
+            <Email2:ConversationId xmlns="uri:Email2" xmlns:Syncroton="uri:Syncroton" Syncroton:encoding="opaque"><![CDATA[YzQ4ZGZlNWUxY2NmMjJhZmJjZjExYWZmMmI5ZDE0MzgwMjBhZmZiOA==]]></Email2:ConversationId>
+            <Email2:ConversationIndex xmlns="uri:Email2" xmlns:Syncroton="uri:Syncroton" Syncroton:encoding="opaque"><![CDATA[AAECAwQ=]]></Email2:ConversationIndex>
+          </ApplicationData>
+        </Add>
+      </Commands>
+    </Collection>
+  </Collections>
+</Sync>
index a71aa82..772042c 100644 (file)
@@ -131,7 +131,23 @@ class Felamimail_Frontend_ActiveSyncTest extends TestCase
         );
         
         $this->assertEquals('9631', $syncrotonModelEmail->body->estimatedDataSize);
-        #$this->assertEquals(2787, strlen(stream_get_contents($syncrotonFileReference->data)));
+    }
+
+    /**
+     * validate getEntry with an Emoji
+     */
+    public function testGetEntryWithEmoji()
+    {
+        $controller = $this->_getController($this->_getDevice(Syncroton_Model_Device::TYPE_ANDROID_40));
+    
+        $message = $this->_createTestMessage('emoji.eml', 'emoji.eml');
+    
+        $syncrotonModelEmail = $controller->getEntry(
+                new Syncroton_Model_SyncCollection(array('collectionId' => 'foobar', 'options' => array('bodyPreferences' => array('2' => array('type' => '2'))))),
+                $message->getId()
+        );
+        
+        $this->assertEquals('1744', $syncrotonModelEmail->body->estimatedDataSize);
     }
     
     /**
@@ -156,15 +172,15 @@ class Felamimail_Frontend_ActiveSyncTest extends TestCase
      * 
      * @return Felamimail_Model_Message
      */
-    protected function _createTestMessage()
+    protected function _createTestMessage($emailFile = 'multipart_mixed.eml', $headerToReplace = 'multipart/mixed')
     {
         $testMessageId = Tinebase_Record_Abstract::generateUID();
         
         $message = $this->_emailTestClass->messageTestHelper(
-            'multipart_mixed.eml',
+            $emailFile,
             $testMessageId,
             null,
-            array('X-Tine20TestMessage: multipart/mixed', 'X-Tine20TestMessage: ' . $testMessageId)
+            array('X-Tine20TestMessage: ' . $headerToReplace, 'X-Tine20TestMessage: ' . $testMessageId)
         );
         
         return $message;
@@ -215,10 +231,26 @@ class Felamimail_Frontend_ActiveSyncTest extends TestCase
         
         $this->assertEquals(preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F]/', null, $xml), $xml);
         
-        // try to encode XML until we have wbxml tests
+        self::encodeXml($testDoc);
+    }
+
+    /**
+     * try to encode XML until we have wbxml tests
+     *
+     * @param $testDoc
+     * @return string returns encoded/decoded xml string
+     */
+    public static function encodeXml($testDoc)
+    {
         $outputStream = fopen("php://temp", 'r+');
         $encoder = new Syncroton_Wbxml_Encoder($outputStream, 'UTF-8', 3);
         $encoder->encode($testDoc);
+
+        rewind($outputStream);
+        $decoder = new Syncroton_Wbxml_Decoder($outputStream);
+        $xml = $decoder->decode();
+
+        return $xml->saveXML();
     }
     
     /**
@@ -320,7 +352,8 @@ class Felamimail_Frontend_ActiveSyncTest extends TestCase
      * 
      * @see 0008572: email reply text garbled
      */
-    public function testSendBase64DecodedMessage () {
+    public function testSendBase64DecodedMessage ()
+    {
         $controller = $this->_getController($this->_getDevice(Syncroton_Model_Device::TYPE_ANDROID_40));
         
         $messageId = '<j4wxaho1t8ggvk5cef7kqc6i.1373048280847@email.android.com>';
diff --git a/tests/tine20/Felamimail/files/emoji.eml b/tests/tine20/Felamimail/files/emoji.eml
new file mode 100644 (file)
index 0000000..8a0900b
--- /dev/null
@@ -0,0 +1,33 @@
+Return-Path: <unittest@tine20.org>
+Delivered-To: <lkneschke@metaways.de>
+Received: from mail01.metaways.net ([10.129.3.233])
+    by mail02.metaways.net (Dovecot) with LMTP id Ju5vArVo0VGbZQAAk4785w
+    for <lkneschke@metaways.de>; Mon, 01 Jul 2013 13:38:32 +0200
+Received: from mx01.metaways.net ([127.0.0.1])
+    by mail01.metaways.net (Dovecot) with LMTP id /GdiAE1p0VEcZgAAiWCYmA
+    ; Mon, 01 Jul 2013 13:38:32 +0200
+Received: from [10.100.11.79] (unknown [194.12.218.135])
+    by mx01.metaways.net (Postfix) with ESMTPSA id 67562C08D
+    for <l.kneschke@metaways.de>; Mon,  1 Jul 2013 13:38:32 +0200 (CEST)
+Message-ID: <51D16A37.7090508@metaways.de>
+Date: Mon, 01 Jul 2013 13:38:31 +0200
+From: Unittest <unittest@tine20.org>
+User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130518 Icedove/17.0.5
+MIME-Version: 1.0
+To: Lars Kneschke <l.kneschke@metaways.de>
+Subject: Re: Tine Suche Speicherplatz mit Vertrag
+X-Tine20TestMessage: emoji.eml
+References: <51CB142C.4000900@metaways.de> <f70f00b0285201337bfccca6581d796a6b7eac18@metaways.de>
+In-Reply-To: <f70f00b0285201337bfccca6581d796a6b7eac18@metaways.de>
+Content-Type: text/plain; charset=UTF-8; format=flowed
+Content-Transfer-Encoding: 8bit
+
+ Original Message processed by David.fx12  &#13;
+Re: Frage (21-Okt-2014 6:47)&#13;
+From:   Heinz Erhard&#13;
+To:Fritz Meister&#13;
+Guten Morgen Fritz,&#13;
+ich bin gerade nicht sicher, weil ich so viele Entwürfe und das momentane Formular nicht vor Augen habe. Es gibt ja Rechnungen und Erinnerungen usw. Mein Kopf ist gerade zu voll...😃?�
+Ich bin heute in hummel - wenn ich morgen wieder in Büttel bin, schaue ich in den Unterlagen nach.&#13;
+Viele Grüße
+Heinz
index e96fcf5..ca23f2b 100644 (file)
@@ -46,3 +46,4 @@ If you are interested , please reply this email and we will send to you our=
 Thank you=17
 
 
+ . 😊
\ No newline at end of file
index b47d996..8aa5b3c 100644 (file)
@@ -636,7 +636,7 @@ class Felamimail_Controller_Message extends Tinebase_Controller_Record_Abstract
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
                 . ' Adding part ' . $partId . ' to message body.');
             
-            $messageBody .= $body;
+            $messageBody .= Tinebase_Core::filterInputForDatabase($body);
         }
         
         return $messageBody;