#9800: unselectable folder with subfolders disappears
authorPhilipp Schüle <p.schuele@metaways.de>
Wed, 9 Apr 2014 16:54:41 +0000 (18:54 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 10 Apr 2014 10:51:18 +0000 (12:51 +0200)
-> don't remove folder from cache if it isn't selectable
-> set is_selectable = 0 and skip update of folder
-> splits test testUpdateFolderCache

https://forge.tine20.org/mantisbt/view.php?id=9800

Change-Id: I732d94e8ce554b4cb1faf3a1542b3c529bde4da9
Reviewed-on: http://gerrit.tine20.com/customers/465
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Felamimail/JsonTest.php
tine20/Felamimail/Controller/Cache/Folder.php
tine20/Felamimail/Controller/Cache/Message.php

index bf34632..e0d275a 100644 (file)
@@ -171,6 +171,9 @@ class Felamimail_JsonTest extends PHPUnit_Framework_TestCase
      */
     protected function tearDown()
     {
+        if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+            . ' Tearing down ...');
+        
         if (count($this->_createdFolders) > 0) {
             foreach ($this->_createdFolders as $folderName) {
                 //echo "delete $folderName\n";
@@ -320,31 +323,56 @@ class Felamimail_JsonTest extends PHPUnit_Framework_TestCase
         $this->_createdFolders[] = $this->_testFolderName . $this->_account->delimiter . 'test' . $this->_account->delimiter . 'testsub';
         $this->_createdFolders[] = $this->_testFolderName . $this->_account->delimiter . 'test';
         
-        // update cache and check if folder is found
+        if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+            . ' Update cache and check if folder is found');
+        
         $result = $this->_json->updateFolderCache($this->_account->getId(), $this->_testFolderName);
         $testfolder = $result[0];
-        //print_r($testfolder);
         $this->assertGreaterThan(0, count($result));
         $this->assertEquals($this->_testFolderName . $this->_account->delimiter . 'test', $testfolder['globalname']);
         $this->assertEquals(TRUE, (bool)$testfolder['has_children'], 'should have children');
         
-        // delete subfolder directly on imap server
+        if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+            . ' Delete subfolder directly on imap server');
+        
         $this->_imap->removeFolder($this->_testFolderName . $this->_account->delimiter . 'test' . $this->_account->delimiter . 'testsub');
         array_shift($this->_createdFolders);
         
-        // check if has_children got updated and folder is removed from cache
+        if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+            . ' Check if has_children got updated and folder is removed from cache');
+        
         $this->_json->updateFolderCache($this->_account->getId(), '');
         $testfolder = $this->_getFolder($this->_testFolderName . $this->_account->delimiter . 'test');
         $this->assertEquals(FALSE, (bool)$testfolder['has_children'], 'should have no children');
-        $this->setExpectedException('Tinebase_Exception_NotFound');
-        $testfoldersub = $this->_getFolder($this->_testFolderName . $this->_account->delimiter . 'test' . $this->_account->delimiter . 'testsub');
 
+        return $testfolder;
+    }
+    
+    /**
+     * testUpdateFolderCacheOfNonexistantFolder
+     * 
+     * @see 0009800: unselectable folder with subfolders disappears
+     */
+    public function testUpdateFolderCacheOfNonexistantFolder()
+    {
+        $testfolder = $this->testUpdateFolderCache();
+        
+        try {
+            $folderName = $this->_testFolderName . $this->_account->delimiter . 'test' . $this->_account->delimiter . 'testsub';
+            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+                . ' Trying to fetch deleted folder ' . $folderName);
+            
+            $testfoldersub = Felamimail_Controller_Folder::getInstance()->getByBackendAndGlobalName($this->_account->getId(), $folderName);
+            $this->fail('Tinebase_Exception_NotFound expected when looking for folder ' . $folderName);
+        } catch (Tinebase_Exception_NotFound $tenf) {
+        }
+        
         $this->_imap->removeFolder($this->_testFolderName . $this->_account->delimiter . 'test');
         array_shift($this->_createdFolders);
         
         // try to update message cache of nonexistant folder
-        $this->setExpectedException('Felamimail_Exception_IMAPFolderNotFound');
         $removedTestfolder = $this->_json->updateMessageCache($testfolder['id'], 1);
+        $this->assertEquals(0, $removedTestfolder['is_selectable'], 'Folder should not be selectable');
         
         // update cache and check if folder is deleted
         $result = $this->_json->updateFolderCache($this->_account->getId(), $this->_testFolderName);
index a7aba05..c55efd9 100644 (file)
@@ -253,7 +253,7 @@ class Felamimail_Controller_Cache_Folder extends Tinebase_Controller_Abstract
         $counter = $imap->examineFolder(Felamimail_Model_Folder::encodeFolderName($folder->globalname));
         
         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ .  ' ' . print_r($counter, TRUE));
-            
+        
         // check validity
         $folder->cache_uidvalidity = $folder->imap_uidvalidity;
         $folder->imap_uidvalidity  = $counter['uidvalidity'];
@@ -482,7 +482,8 @@ class Felamimail_Controller_Cache_Folder extends Tinebase_Controller_Abstract
         if (count($cachedFolderIds) > count($_imapFolderIds)) {
             // remove folders from cache
             $idsToRemove = array_diff($cachedFolderIds, $_imapFolderIds);
-            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Removing ' . count($idsToRemove) . ' folders from cache.');
+            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ 
+                . ' Removing ' . count($idsToRemove) . ' folders from cache.');
             $this->delete($idsToRemove);
         }
     }
index e5de051..e9482ad 100644 (file)
@@ -263,8 +263,13 @@ class Felamimail_Controller_Cache_Message extends Felamimail_Controller_Message
         $imap = Felamimail_Backend_ImapFactory::factory($folder->account_id);
         
         $this->_availableUpdateTime = $_time;
+       
+        try { 
+            $this->_expungeCacheFolder($folder, $imap);
+        } catch (Felamimail_Exception_IMAPFolderNotFound $feifnf) {
+            return $folder;
+        }
         
-        $this->_expungeCacheFolder($folder, $imap);
         $this->_initUpdate($folder);
         $this->_updateMessageSequence($folder, $imap);
         $this->_deleteMessagesInCache($folder, $imap);
@@ -320,10 +325,19 @@ class Felamimail_Controller_Cache_Message extends Felamimail_Controller_Message
             $_imap->expunge(Felamimail_Model_Folder::encodeFolderName($_folder->globalname));
         } catch (Zend_Mail_Storage_Exception $zmse) {
             Tinebase_Exception::log($zmse);
-            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
-                . ' Removing no longer existing folder ' . $_folder->globalname . ' from cache. ' .$zmse->getMessage() );
-            Felamimail_Controller_Cache_Folder::getInstance()->delete($_folder->getId());
-            throw new Felamimail_Exception_IMAPFolderNotFound('Folder not found: ' . $_folder->globalname);
+            
+            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+                . ' Marking folder as not selectable: ' . print_r($_folder->toArray(), true));
+            
+            // mark folder as not selectable + finish cache update
+            $_folder->is_selectable = 0;
+            $_folder->cache_status = Felamimail_Model_Folder::CACHE_STATUS_COMPLETE;
+            $_folder = Felamimail_Controller_Folder::getInstance()->update($_folder);
+            
+            // @todo check if folder is really deleted?
+            //Felamimail_Controller_Cache_Folder::getInstance()->delete($_folder->getId());
+            
+            throw new Felamimail_Exception_IMAPFolderNotFound('Folder not found / is not selectable: ' . $_folder->globalname);
         }
     }