Merge branch '2013.10' into 2014.11
[tine20] / tests / tine20 / Filemanager / Frontend / JsonTests.php
1 <?php
2 /**
3  * Tine 2.0 - http://www.tine20.org
4  * 
5  * @package     Filemanager
6  * @license     http://www.gnu.org/licenses/agpl.html
7  * @copyright   Copyright (c) 2011-2014 Metaways Infosystems GmbH (http://www.metaways.de)
8  * @author      Philipp Schüle <p.schuele@metaways.de>
9  * 
10  */
11
12 /**
13  * Test class for Filemanager_Frontend_Json
14  * 
15  * @package     Filemanager
16  */
17 class Filemanager_Frontend_JsonTests extends TestCase
18 {
19     /**
20      * @var array test objects
21      */
22     protected $_objects = array();
23     
24     /**
25      * uit
26      *
27      * @var Filemanager_Frontend_Json
28      */
29     protected $_json;
30     
31     /**
32      * fs controller
33      *
34      * @var Tinebase_FileSystem
35      */
36     protected $_fsController;
37     
38     /**
39      * filemanager app
40      *
41      * @var Tinebase_Model_Application
42      */
43     protected $_application;
44     
45     /**
46      * personal container
47      *
48      * @var Tinebase_Model_Container
49      */
50     protected $_personalContainer;
51     
52     /**
53      * shared container
54      *
55      * @var Tinebase_Model_Container
56      */
57     protected $_sharedContainer;
58     
59     /**
60      * other user container
61      *
62      * @var Tinebase_Model_Container
63      */
64     protected $_otherUserContainer;
65     
66     /**
67      * Sets up the fixture.
68      * This method is called before a test is executed.
69      *
70      * @access protected
71      */
72     protected function setUp()
73     {
74         parent::setUp();
75         
76         $this->_json = new Filemanager_Frontend_Json();
77         $this->_fsController = Tinebase_FileSystem::getInstance();
78         $this->_application = Tinebase_Application::getInstance()->getApplicationByName('Filemanager');
79     }
80     
81     /**
82      * Tears down the fixture
83      * This method is called after a test is executed.
84      *
85      * @access protected
86      */
87     protected function tearDown()
88     {
89         parent::tearDown();
90         
91         Tinebase_FileSystem::getInstance()->clearStatCache();
92         Tinebase_FileSystem::getInstance()->clearDeletedFilesFromFilesystem();
93         
94         $this->_personalContainer  = null;
95         $this->_sharedContainer    = null;
96         $this->_otherUserContainer = null;
97     }
98     
99     /**
100      * test search nodes (personal)
101      */
102     public function testSearchRoot()
103     {
104         $filter = array(array(
105             'field'    => 'path', 
106             'operator' => 'equals', 
107             'value'    => '/'
108         ));
109         $result = $this->_json->searchNodes($filter, array());
110         $this->_assertRootNodes($result);
111     }
112     
113     /**
114      * assert 3 root nodes
115      * 
116      * @param array $searchResult
117      */
118     protected function _assertRootNodes($searchResult)
119     {
120         $this->assertEquals(3, $searchResult['totalcount'], 'did not get root nodes: ' . print_r($searchResult, TRUE));
121         $this->assertEquals('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName, $searchResult['results'][0]['path']);
122     }
123     
124     /**
125      * test search nodes (personal)
126      */
127     public function testSearchPersonalNodes()
128     {
129         $this->_setupTestPath(Tinebase_Model_Container::TYPE_PERSONAL);
130         
131         $filter = array(array(
132             'field'    => 'path', 
133             'operator' => 'equals', 
134             'value'    => '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name
135         ));
136         $this->_searchHelper($filter, 'unittestdir_personal');
137     }
138     
139     /**
140      * search node helper
141      * 
142      * @param array $_filter
143      * @param string $_expectedName
144      * @return array search result
145      */
146     protected function _searchHelper($_filter, $_expectedName, $_toplevel = FALSE, $_checkAccountGrants = TRUE)
147     {
148         $result = $this->_json->searchNodes($_filter, array('sort' => 'size'));
149         
150         $this->assertGreaterThanOrEqual(1, $result['totalcount'], 'expected at least one entry');
151         if ($_toplevel) {
152             $found = FALSE;
153             foreach ($result['results'] as $container) {
154                 // toplevel containers are resolved (array structure below [name])
155                 if ($_expectedName == $container['name']['name']) {
156                     $found = TRUE;
157                     if ($_checkAccountGrants) {
158                         $this->assertTrue(isset($container['name']['account_grants']));
159                         $this->assertEquals(Tinebase_Core::getUser()->getId(), $container['name']['account_grants']['account_id']);
160                     }
161                 }
162             }
163             $this->assertTrue($found, 'container not found: ' . print_r($result['results'], TRUE));
164         } else {
165             $this->assertEquals($_expectedName, $result['results'][0]['name']);
166         }
167         
168         if ($_checkAccountGrants) {
169             $this->assertTrue(isset($result['results'][0]['account_grants']));
170             $this->assertEquals(Tinebase_Core::getUser()->getId(), $result['results'][0]['account_grants']['account_id']);
171         }
172         
173         return $result;
174     }
175     
176     /**
177      * test search nodes (shared)
178      */
179     public function testSearchSharedNodes()
180     {
181         $this->_setupTestPath(Tinebase_Model_Container::TYPE_SHARED);
182         
183         $filter = array(array(
184             'field'    => 'path', 
185             'operator' => 'equals', 
186             'value'    => '/' . Tinebase_Model_Container::TYPE_SHARED . '/' . $this->_getSharedContainer()->name
187         ));
188         $this->_searchHelper($filter, 'unittestdir_shared');
189     }
190     
191     /**
192      * test search nodes (other)
193      */
194     public function testSearchOtherUsersNodes()
195     {
196         $this->_setupTestPath(Tinebase_Model_Container::TYPE_OTHERUSERS);
197         
198         $filter = array(array(
199             'field'    => 'path', 
200             'operator' => 'equals', 
201             'value'    => '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/sclever/' . $this->_getOtherUserContainer()->name
202         ));
203         $this->_searchHelper($filter, 'unittestdir_other');
204     }
205     
206     /**
207      * search top level containers of user
208      * 
209      * @see 0007400: Newly created directories disappear
210      */
211     public function testSearchTopLevelContainersOfUser()
212     {
213         $filter = array(array(
214             'field'    => 'path', 
215             'operator' => 'equals', 
216             'value'    => '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName
217         ));
218         $this->_searchHelper($filter, $this->_getPersonalFilemanagerContainer()->name, TRUE);
219         
220         $another = $this->testCreateContainerNodeInPersonalFolder();
221         $this->_searchHelper($filter, $another['name']['name'], TRUE);
222     }
223
224     /**
225      * search shared top level containers 
226      */
227     public function testSearchSharedTopLevelContainers()
228     {
229         $this->_setupTestPath(Tinebase_Model_Container::TYPE_SHARED);
230         
231         $filter = array(array(
232             'field'    => 'path', 
233             'operator' => 'equals', 
234             'value'    => '/' . Tinebase_Model_Container::TYPE_SHARED
235         ));
236         $result = $this->_searchHelper($filter, $this->_getSharedContainer()->name, TRUE);
237     }
238
239     /**
240      * search top level containers of other users
241      */
242     public function testSearchTopLevelContainersOfOtherUsers()
243     {
244         $this->_getOtherUserContainer();
245         
246         $filter = array(
247             array(
248                 'field'    => 'path', 
249                 'operator' => 'equals', 
250                 'value'    => '/' . Tinebase_Model_Container::TYPE_PERSONAL
251             )
252         );
253         $this->_searchHelper($filter, 'Clever, Susan', FALSE, FALSE);
254     }
255
256     /**
257      * search containers of other user
258      */
259     public function testSearchContainersOfOtherUser()
260     {
261         $this->_setupTestPath(Tinebase_Model_Container::TYPE_OTHERUSERS);
262         
263         $filter = array(array(
264             'field'    => 'path', 
265             'operator' => 'equals', 
266             'value'    => '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/sclever'
267         ), array(
268             'field'    => 'creation_time', 
269             'operator' => 'within', 
270             'value'    => 'weekThis',
271         ));
272         $result = $this->_searchHelper($filter, $this->_getOtherUserContainer()->name, TRUE);
273         
274         $expectedPath = $filter[0]['value'] . '/' . $this->_getOtherUserContainer()->name;
275         $this->assertEquals($expectedPath, $result['results'][0]['path'], 'node path mismatch');
276         $this->assertEquals($filter[0]['value'], $result['filter'][0]['value']['path'], 'filter path mismatch');
277     }
278     /**
279      * testSearchWithInvalidPath
280      * 
281      * @see 0007110: don't show exception for invalid path filters
282      */
283     public function testSearchWithInvalidPath()
284     {
285         // wrong user
286         $filter = array(array(
287             'field'    => 'path', 
288             'operator' => 'equals', 
289             'value'    => '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/xyz'
290         ));
291         
292         $result = $this->_json->searchNodes($filter, array());
293         $this->_assertRootNodes($result);
294         
295         // wrong type
296         $filter[0]['value'] = '/lala';
297         $result = $this->_json->searchNodes($filter, array());
298         $this->_assertRootNodes($result);
299
300         // no path filter
301         $result = $this->_json->searchNodes(array(), array());
302         $this->_assertRootNodes($result);
303     }
304     
305     /**
306      * create container in personal folder
307      * 
308      * @return array created node
309      */
310     public function testCreateContainerNodeInPersonalFolder($containerName = 'testcontainer')
311     {
312         $testPath = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/' . $containerName;
313         $result = $this->_json->createNodes($testPath, Tinebase_Model_Tree_Node::TYPE_FOLDER, array(), FALSE);
314         $createdNode = $result[0];
315         
316         $this->_objects['containerids'][] = $createdNode['name']['id'];
317         
318         $this->assertTrue(is_array($createdNode['name']));
319         $this->assertEquals($containerName, $createdNode['name']['name']);
320         $this->assertEquals(Tinebase_Core::getUser()->getId(), $createdNode['created_by']['accountId']);
321         
322         return $createdNode;
323     }
324
325     /**
326      * create container with bad name
327      * 
328      * @see 0006524: Access Problems via Webdav
329      */
330     public function testCreateContainerNodeWithBadName()
331     {
332         $testPath = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testcon/tainer';
333         
334         $this->setExpectedException('Tinebase_Exception_NotFound');
335         $result = $this->_json->createNodes($testPath, Tinebase_Model_Tree_Node::TYPE_FOLDER, array(), FALSE);
336     }
337
338     /**
339      * create container in shared folder
340      * 
341      * @return array created node
342      */
343     public function testCreateContainerNodeInSharedFolder()
344     {
345         $testPath = '/' . Tinebase_Model_Container::TYPE_SHARED . '/testcontainer';
346         $result = $this->_json->createNode($testPath, Tinebase_Model_Tree_Node::TYPE_FOLDER, NULL, FALSE);
347         $createdNode = $result;
348         
349         $this->_objects['containerids'][] = $createdNode['name']['id'];
350         
351         $this->assertTrue(is_array($createdNode['name']));
352         $this->assertEquals('testcontainer', $createdNode['name']['name']);
353         $this->assertEquals($testPath, $createdNode['path']);
354         
355         return $createdNode;
356     }
357
358     /**
359      * testCreateFileNodes
360      * 
361      * @return array file paths
362      */
363     public function testCreateFileNodes()
364     {
365         $sharedContainerNode = $this->testCreateContainerNodeInSharedFolder();
366         
367         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($sharedContainerNode['path']);
368         
369         $filepaths = array(
370             $sharedContainerNode['path'] . '/file1',
371             $sharedContainerNode['path'] . '/file2',
372         );
373         $result = $this->_json->createNodes($filepaths, Tinebase_Model_Tree_Node::TYPE_FILE, array(), FALSE);
374         
375         $this->assertEquals(2, count($result));
376         $this->assertEquals('file1', $result[0]['name']);
377         $this->assertEquals(Tinebase_Model_Tree_Node::TYPE_FILE, $result[0]['type']);
378         $this->assertEquals('file2', $result[1]['name']);
379         $this->assertEquals(Tinebase_Model_Tree_Node::TYPE_FILE, $result[1]['type']);
380         
381         return $filepaths;
382     }
383
384     /**
385     * testCreateFileNodeWithUTF8Filenames
386     * 
387     * @see 0006068: No umlauts at beginning of file names / https://forge.tine20.org/mantisbt/view.php?id=6068
388     * @see 0006150: Problem loading files with russian file names / https://forge.tine20.org/mantisbt/view.php?id=6150
389     * 
390     * @return array first created node
391     */
392     public function testCreateFileNodeWithUTF8Filenames()
393     {
394         $personalContainerNode = $this->testCreateContainerNodeInPersonalFolder();
395         
396         $testPaths = array($personalContainerNode['path'] . '/ütest.eml', $personalContainerNode['path'] . '/Безимени.txt');
397         $result = $this->_json->createNodes($testPaths, Tinebase_Model_Tree_Node::TYPE_FILE, array(), FALSE);
398     
399         $this->assertEquals(2, count($result));
400         $this->assertEquals('ütest.eml', $result[0]['name']);
401         $this->assertEquals('Безимени.txt', $result[1]['name']);
402         $this->assertEquals(Tinebase_Model_Tree_Node::TYPE_FILE, $result[0]['type']);
403         
404         return $result[0];
405     }
406     
407     /**
408      * testCreateFileNodeWithTempfile
409      * 
410      * @return array node
411      */
412     public function testCreateFileNodeWithTempfile()
413     {
414         $sharedContainerNode = $this->testCreateContainerNodeInSharedFolder();
415         
416         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($sharedContainerNode['path']);
417         
418         $filepath = $sharedContainerNode['path'] . '/test.txt';
419         // create empty file first (like the js frontend does)
420         $result = $this->_json->createNode($filepath, Tinebase_Model_Tree_Node::TYPE_FILE, array(), FALSE);
421
422         $tempFileBackend = new Tinebase_TempFile();
423         $tempFile = $tempFileBackend->createTempFile(dirname(dirname(__FILE__)) . '/files/test.txt');
424         $result = $this->_json->createNode($filepath, Tinebase_Model_Tree_Node::TYPE_FILE, $tempFile->getId(), TRUE);
425         
426         $this->assertEquals('text/plain', $result['contenttype'], print_r($result, TRUE));
427         $this->assertEquals(17, $result['size']);
428         
429         return $result;
430     }
431     
432     /**
433      * testCreateFileCountTempDir
434      * 
435      * @see 0007370: Unable to upload files
436      */
437     public function testCreateFileCountTempDir()
438     {
439         $tmp = Tinebase_Core::getTempDir();
440         $filecountInTmpBefore = count(scandir($tmp));
441         
442         $this->testCreateFileNodeWithTempfile();
443         
444         // check if tempfile has been created in tine20 tempdir
445         $filecountInTmpAfter = count(scandir($tmp));
446         
447         $this->assertEquals($filecountInTmpBefore + 2, $filecountInTmpAfter, '2 tempfiles should have been created');
448     }
449
450     /**
451      * testCreateDirectoryNodesInShared
452      * 
453      * @return array dir paths
454      */
455     public function testCreateDirectoryNodesInShared()
456     {
457         $sharedContainerNode = $this->testCreateContainerNodeInSharedFolder();
458         
459         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($sharedContainerNode['path']);
460         
461         $dirpaths = array(
462             $sharedContainerNode['path'] . '/dir1',
463             $sharedContainerNode['path'] . '/dir2',
464         );
465         $result = $this->_json->createNodes($dirpaths, Tinebase_Model_Tree_Node::TYPE_FOLDER, array(), FALSE);
466         
467         $this->assertEquals(2, count($result));
468         $this->assertEquals('dir1', $result[0]['name']);
469         $this->assertEquals('dir2', $result[1]['name']);
470         
471         $filter = array(array(
472             'field'    => 'path', 
473             'operator' => 'equals', 
474             'value'    => $sharedContainerNode['path']
475         ), array(
476             'field'    => 'type', 
477             'operator' => 'equals', 
478             'value'    => Tinebase_Model_Tree_Node::TYPE_FOLDER,
479         ));
480         $result = $this->_json->searchNodes($filter, array('sort' => 'creation_time'));
481         $this->assertEquals(2, $result['totalcount']);
482         
483         return $dirpaths;
484     }
485
486     /**
487      * testCreateDirectoryNodesInPersonal
488      * 
489      * @return array dir paths
490      */
491     public function testCreateDirectoryNodesInPersonal()
492     {
493         $personalContainerNode = $this->testCreateContainerNodeInPersonalFolder();
494         
495         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($personalContainerNode['path']);
496         
497         $dirpaths = array(
498             $personalContainerNode['path'] . '/dir1',
499             $personalContainerNode['path'] . '/dir2',
500         );
501         $result = $this->_json->createNodes($dirpaths, Tinebase_Model_Tree_Node::TYPE_FOLDER, array(), FALSE);
502         
503         $this->assertEquals(2, count($result));
504         $this->assertEquals('dir1', $result[0]['name']);
505         $this->assertEquals('dir2', $result[1]['name']);
506         
507         $filter = array(array(
508             'field'    => 'path', 
509             'operator' => 'equals', 
510             'value'    => $personalContainerNode['path']
511         ), array(
512             'field'    => 'type', 
513             'operator' => 'equals', 
514             'value'    => Tinebase_Model_Tree_Node::TYPE_FOLDER,
515         ));
516         $result = $this->_json->searchNodes($filter, array('sort' => 'contenttype'));
517         $this->assertEquals(2, $result['totalcount']);
518         
519         return $dirpaths;
520     }
521     
522     /**
523      * testCreateDirectoryNodeInPersonalWithSameNameAsOtherUsersDir
524      * 
525      * @see 0008044: could not create a personal folder with the name of a folder of another user
526      */
527     public function testCreateDirectoryNodeInPersonalWithSameNameAsOtherUsersDir()
528     {
529         $personalContainerNode = $this->testCreateContainerNodeInPersonalFolder();
530         
531         $personas = Zend_Registry::get('personas');
532         Tinebase_Core::set(Tinebase_Core::USER, $personas['sclever']);
533         $personalContainerNodeOfsclever = $this->testCreateContainerNodeInPersonalFolder();
534         
535         $this->assertEquals('/personal/sclever/testcontainer', $personalContainerNodeOfsclever['path']);
536     }
537     
538     /**
539      * testRenameDirectoryNodeInPersonalToSameNameAsOtherUsersDir
540      * 
541      * @see 0008046: Rename personal folder to personal folder of another user
542      */
543     public function testRenameDirectoryNodeInPersonalToSameNameAsOtherUsersDir()
544     {
545         $personalContainerNode = $this->testCreateContainerNodeInPersonalFolder();
546         
547         $personas = Zend_Registry::get('personas');
548         Tinebase_Core::set(Tinebase_Core::USER, $personas['sclever']);
549         $personalContainerNodeOfsclever = $this->testCreateContainerNodeInPersonalFolder('testcontainer2');
550         
551         $this->assertEquals('/personal/sclever/testcontainer2', $personalContainerNodeOfsclever['path']);
552         
553         // rename
554         $newPath = '/personal/sclever/testcontainer';
555         $result = $this->_json->moveNodes(array($personalContainerNodeOfsclever['path']), array($newPath), FALSE);
556         $this->assertEquals(1, count($result));
557         $this->assertEquals($newPath, $result[0]['path']);
558     }
559     
560     /**
561      * testCopyFolderNodes
562      */
563     public function testCopyFolderNodesToFolder()
564     {
565         $dirsToCopy = $this->testCreateDirectoryNodesInShared();
566         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
567         
568         $result = $this->_json->copyNodes($dirsToCopy, $targetNode['path'], FALSE);
569         $this->assertEquals(2, count($result));
570         $this->assertEquals($targetNode['path'] . '/dir1', $result[0]['path']);
571     }
572
573     /**
574      * testCopyContainerNode
575      */
576     public function testCopyContainerNode()
577     {
578         $sharedContainerNode = $this->testCreateContainerNodeInSharedFolder();
579         $target = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName;
580         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($target . '/testcontainer');
581         $result = $this->_json->copyNodes($sharedContainerNode['path'], $target, FALSE);
582         $this->assertEquals(1, count($result));
583         $this->assertTrue(is_array($result[0]['name']));
584         $this->_objects['containerids'][] = $result[0]['name']['id'];
585     }
586     
587     /**
588      * testCopyFileNodesToFolder
589      * 
590      * @return array target node
591      */
592     public function testCopyFileNodesToFolder()
593     {
594         $filesToCopy = $this->testCreateFileNodes();
595         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
596         
597         $result = $this->_json->copyNodes($filesToCopy, $targetNode['path'], FALSE);
598         $this->assertEquals(2, count($result));
599         $this->assertEquals($targetNode['path'] . '/file1', $result[0]['path']);
600         
601         return $targetNode;
602     }
603
604     /**
605      * testCopyFolderWithNodes
606      */
607     public function testCopyFolderWithNodes()
608     {
609         $filesToCopy = $this->testCreateFileNodes();
610         $target = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName;
611         
612         $result = $this->_json->copyNodes(
613             '/' . Tinebase_Model_Container::TYPE_SHARED . '/testcontainer',
614             $target, 
615             FALSE
616         );
617         
618         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($target . '/testcontainer');
619         $this->assertEquals(1, count($result));
620         $this->_objects['containerids'][] = $result[0]['name']['id'];
621         
622         $filter = array(array(
623             'field'    => 'path', 
624             'operator' => 'equals', 
625             'value'    => '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testcontainer',
626         ), array(
627             'field'    => 'type', 
628             'operator' => 'equals', 
629             'value'    => Tinebase_Model_Tree_Node::TYPE_FILE,
630         ));
631         $result = $this->_json->searchNodes($filter, array());
632         $this->assertEquals(2, $result['totalcount']);
633     }
634     
635     /**
636      * testCopyFileWithContentToFolder
637      */
638     public function testCopyFileWithContentToFolder()
639     {
640         $fileToCopy = $this->testCreateFileNodeWithTempfile();
641         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
642         
643         $result = $this->_json->copyNodes($fileToCopy['path'], $targetNode['path'], FALSE);
644         $this->assertEquals(1, count($result));
645         $this->assertEquals($targetNode['path'] . '/test.txt', $result[0]['path']);
646         $this->assertEquals('text/plain', $result[0]['contenttype']);
647     }
648     
649     /**
650      * testCopyFileNodeToFileExisting
651      */
652     public function testCopyFileNodeToFileExisting()
653     {
654         $filesToCopy = $this->testCreateFileNodes();
655         $file1 = $filesToCopy[0];
656         $file2 = $filesToCopy[1];
657         
658         $this->setExpectedException('Filemanager_Exception_NodeExists');
659         $result = $this->_json->copyNodes(array($file1), array($file2), FALSE);
660     }
661     
662     /**
663      * testCopyFileNodeToFileExistingCatchException
664      */
665     public function testCopyFileNodeToFileExistingCatchException()
666     {
667         $filesToCopy = $this->testCreateFileNodes();
668         $file1 = $filesToCopy[0];
669         $file2 = $filesToCopy[1];
670         
671         try {
672             $result = $this->_json->copyNodes(array($file1), array($file2), FALSE);
673         } catch (Filemanager_Exception_NodeExists $fene) {
674             $info = $fene->toArray();
675             $this->assertEquals(1, count($info['existingnodesinfo']));
676             return;
677         }
678         
679         $this->fail('An expected exception has not been raised.');
680     }
681     
682     /**
683      * testMoveFolderNodesToFolder
684      */
685     public function testMoveFolderNodesToFolder()
686     {
687         $dirsToMove = $this->testCreateDirectoryNodesInShared();
688         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
689         
690         $result = $this->_json->moveNodes($dirsToMove, $targetNode['path'], FALSE);
691         $this->assertEquals(2, count($result));
692         $this->assertEquals($targetNode['path'] . '/dir1', $result[0]['path'], 'no new path: ' . print_r($result, TRUE));
693         
694         $filter = array(array(
695             'field'    => 'path', 
696             'operator' => 'equals', 
697             'value'    => '/' . Tinebase_Model_Container::TYPE_SHARED . '/testcontainer'
698         ), array(
699             'field'    => 'type', 
700             'operator' => 'equals', 
701             'value'    => Tinebase_Model_Tree_Node::TYPE_FOLDER,
702         ));
703         $result = $this->_json->searchNodes($filter, array());
704         $this->assertEquals(0, $result['totalcount']);
705     }
706     
707     /**
708      * testMoveFolderNodesToFolderExisting
709      * 
710      * @see 0007028: moving a folder to another folder with a folder with the same name
711      */
712     public function testMoveFolderNodesToFolderExisting()
713     {
714         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
715         $testPath = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/dir1';
716         $result = $this->_json->moveNodes(array($targetNode['path']), array($testPath), FALSE);
717         $dirs = $this->testCreateDirectoryNodesInShared();
718         try {
719             $result = $this->_json->moveNodes(array($testPath), '/shared/testcontainer', FALSE);
720             $this->fail('Expected Filemanager_Exception_NodeExists!');
721         } catch (Filemanager_Exception_NodeExists $fene) {
722             $result = $this->_json->moveNodes(array($testPath), '/shared/testcontainer', TRUE);
723             $this->assertEquals(1, count($result));
724             $this->assertEquals('/shared/testcontainer/dir1', $result[0]['path']);
725         }
726     }
727
728     /**
729      * testMoveContainerFolderNodeToExistingContainer
730      * 
731      * @see 0007028: moving a folder to another folder with a folder with the same name
732      */
733     public function testMoveContainerFolderNodeToExistingContainer()
734     {
735         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
736         
737         $testPath = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testcontainer2';
738         $result = $this->_json->createNodes($testPath, Tinebase_Model_Tree_Node::TYPE_FOLDER, array(), FALSE);
739         $createdNode = $result[0];
740         $this->_objects['containerids'][] = $createdNode['name']['id'];
741         
742         try {
743             $result = $this->_json->moveNodes(array($targetNode['path']), array($createdNode['path']), FALSE);
744             $this->fail('Expected Filemanager_Exception_NodeExists!');
745         } catch (Filemanager_Exception_NodeExists $fene) {
746             $result = $this->_json->moveNodes(array($targetNode['path']), array($createdNode['path']), TRUE);
747             $this->assertEquals(1, count($result));
748             $this->assertEquals($testPath, $result[0]['path']);
749         }
750     }
751     
752     /**
753     * testMoveFolderNodesToTopLevel
754     */
755     public function testMoveFolderNodesToTopLevel()
756     {
757         // we need the personal folder for the test user
758         $this->_setupTestPath(Tinebase_Model_Container::TYPE_PERSONAL);
759         
760         $dirsToMove = $this->testCreateDirectoryNodesInShared();
761         $targetPath = '/personal/' . Tinebase_Core::getUser()->accountLoginName;
762         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($targetPath . '/dir1');
763         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($targetPath . '/dir2');
764         
765         $result = $this->_json->moveNodes($dirsToMove, $targetPath, FALSE);
766         $this->assertEquals(2, count($result));
767         $this->assertEquals($targetPath . '/dir1', $result[0]['path']);
768     }
769     
770     /**
771      * testMoveContainerFolderNodesToContainerFolder
772      */
773     public function testMoveContainerFolderNodesToContainerFolder()
774     {
775         $sourceNode = $this->testCreateContainerNodeInPersonalFolder();
776         
777         $newPath = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testcontainermoved';
778         $result = $this->_json->moveNodes($sourceNode['path'], array($newPath), FALSE);
779         $this->assertEquals(1, count($result));
780         $this->assertEquals($newPath, $result[0]['path'], 'no new path: ' . print_r($result, TRUE));
781         $this->_objects['containerids'][] = $result[0]['name']['id'];
782         
783         $filter = array(array(
784             'field'    => 'path', 
785             'operator' => 'equals', 
786             'value'    => '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName
787         ), array(
788             'field'    => 'type', 
789             'operator' => 'equals', 
790             'value'    => Tinebase_Model_Tree_Node::TYPE_FOLDER,
791         ));
792         $result = $this->_json->searchNodes($filter, array());
793         foreach ($result['results'] as $node) {
794             $this->assertNotEquals($sourceNode['path'], $node['path']);
795         }
796     }
797     
798     /**
799      * testMoveContainerFolderNodesToContainerFolderWithChildNodes
800      */
801     public function testMoveContainerFolderNodesToContainerFolderWithChildNodes()
802     {
803         $children = $this->testCreateDirectoryNodesInPersonal();
804         
805         $oldPath = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testcontainer';
806         $newPath = $oldPath . 'moved';
807         $result = $this->_json->moveNodes(array($oldPath), array($newPath), FALSE);
808         $this->assertEquals(1, count($result));
809         $this->assertEquals($newPath, $result[0]['path']);
810         $this->_objects['containerids'][] = $result[0]['name']['id'];
811         
812         $filter = array(array(
813             'field'    => 'path', 
814             'operator' => 'equals', 
815             'value'    => $newPath
816         ), array(
817             'field'    => 'type', 
818             'operator' => 'equals', 
819             'value'    => Tinebase_Model_Tree_Node::TYPE_FOLDER,
820         ));
821         $result = $this->_json->searchNodes($filter, array());
822         $this->assertEquals(2, $result['totalcount']);
823     }
824     
825     /**
826      * testMoveFileNodesToFolder
827      * 
828      * @return array target node
829      */
830     public function testMoveFileNodesToFolder()
831     {
832         $filesToMove = $this->testCreateFileNodes();
833         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
834         
835         $result = $this->_json->moveNodes($filesToMove, $targetNode['path'], FALSE);
836         $this->assertEquals(2, count($result));
837         $this->assertEquals($targetNode['path'] . '/file1', $result[0]['path']);
838
839         $filter = array(array(
840             'field'    => 'path', 
841             'operator' => 'equals', 
842             'value'    => '/' . Tinebase_Model_Container::TYPE_SHARED . '/testcontainer'
843         ), array(
844             'field'    => 'type', 
845             'operator' => 'equals', 
846             'value'    => Tinebase_Model_Tree_Node::TYPE_FILE,
847         ));
848         $result = $this->_json->searchNodes($filter, array());
849         $this->assertEquals(0, $result['totalcount']);
850         
851         return $targetNode;
852     }
853
854     /**
855      * testMoveFileNodesOverwrite
856      */
857     public function testMoveFileNodesOverwrite()
858     {
859         $targetNode = $this->testCopyFileNodesToFolder();
860         
861         $sharedContainerPath = '/' . Tinebase_Model_Container::TYPE_SHARED . '/testcontainer/';
862         $filesToMove = array($sharedContainerPath . 'file1', $sharedContainerPath . 'file2');
863         $result = $this->_json->moveNodes($filesToMove, $targetNode['path'], TRUE);
864         
865         $this->assertEquals(2, count($result));
866     }
867     
868     /**
869      * testMoveFolderNodeToRoot
870      */
871     public function testMoveFolderNodeToRoot()
872     {
873         $children = $this->testCreateDirectoryNodesInPersonal();
874         
875         $target = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName;
876         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($target . '/testcontainer');
877         $result = $this->_json->moveNodes($children[0], $target, FALSE);
878         $this->assertEquals(1, count($result));
879         $this->assertTrue(is_array($result[0]['name']), 'array with container data expected: ' . print_r($result[0], TRUE));
880         $this->_objects['containerids'][] = $result[0]['name']['id'];
881     }
882     
883     /**
884      * testDeleteContainerNode
885      */
886     public function testDeleteContainerNode()
887     {
888         $sharedContainerNode = $this->testCreateContainerNodeInSharedFolder();
889         
890         $result = $this->_json->deleteNodes($sharedContainerNode['path']);
891         
892         // check if container is deleted
893         $search = Tinebase_Container::getInstance()->search(new Tinebase_Model_ContainerFilter(array(
894             'id' => $sharedContainerNode['name']['id'],
895         )));
896         $this->assertEquals(0, count($search));
897         $this->_objects['containerids'] = array();
898         
899         // check if node is deleted
900         $this->setExpectedException('Tinebase_Exception_NotFound');
901         $this->_fsController->stat($sharedContainerNode['path']);
902     }
903
904     /**
905      * testDeleteFileNodes
906      */
907     public function testDeleteFileNodes()
908     {
909         $filepaths = $this->testCreateFileNodes();
910         
911         $result = $this->_json->deleteNodes($filepaths);
912
913         // check if node is deleted
914         try {
915             $this->_fsController->stat(Filemanager_Controller_Node::getInstance()->addBasePath($filepaths[0]));
916             $this->assertTrue(FALSE);
917         } catch (Tinebase_Exception_NotFound $tenf) {
918             $this->assertTrue(TRUE);
919         }
920     }
921     
922     /**
923      * test cleanup of deleted files (database)
924      * 
925      * @see 0008062: add cleanup script for deleted files
926      */
927     public function testDeletedFileCleanupFromDatabase()
928     {
929         $fileNode = $this->testCreateFileNodeWithTempfile();
930         
931         // get "real" filesystem path + unlink
932         $fileObjectBackend = new Tinebase_Tree_FileObject();
933         $fileObject = $fileObjectBackend->get($fileNode['object_id']);
934         unlink($fileObject->getFilesystemPath());
935         
936         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromDatabase();
937         $this->assertEquals(1, $result, 'should cleanup one file');
938
939         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromDatabase();
940         $this->assertEquals(0, $result, 'should cleanup no file');
941         
942         // node should no longer be found
943         try {
944             $this->_json->getNode($fileNode['id']);
945             $this->fail('tree node still exists: ' . print_r($fileNode, TRUE));
946         } catch (Tinebase_Exception_NotFound $tenf) {
947             $this->assertEquals('Tinebase_Model_Tree_Node record with id = ' . $fileNode['id'] . ' not found!', $tenf->getMessage());
948         }
949     }
950     
951     /**
952      * testDeleteDirectoryNodes
953      */
954     public function testDeleteDirectoryNodes()
955     {
956         $dirpaths = $this->testCreateDirectoryNodesInShared();
957         
958         $result = $this->_json->deleteNodes($dirpaths);
959
960         // check if node is deleted
961         $this->setExpectedException('Tinebase_Exception_NotFound');
962         $node = $this->_fsController->stat(Filemanager_Controller_Node::getInstance()->addBasePath($dirpaths[0]));
963     }
964     
965     /**
966      * testSetContainerInPathRecord
967      * 
968      * @todo move this to Tinebase?
969      */
970     public function testSetContainerInPathRecord()
971     {
972         $flatpath = Filemanager_Controller_Node::getInstance()->addBasePath(
973             '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name);
974         $path = Tinebase_Model_Tree_Node_Path::createFromPath($flatpath);
975         $path->setContainer($this->_getSharedContainer());
976         $this->assertEquals('/' . $this->_application->getId() . '/folders/shared/' . $this->_getSharedContainer()->getId(), $path->statpath);
977         
978         // move it back
979         $path->setContainer($this->_getPersonalFilemanagerContainer());
980         $this->assertEquals('/' . $this->_application->getId() . '/folders/personal/' 
981             . Tinebase_Core::getUser()->getId() . '/' . $this->_getPersonalFilemanagerContainer()->getId(), $path->statpath, 'wrong statpath: ' . print_r($path->toArray(), TRUE));
982     }
983
984     /**
985      * testGetUpdate
986      * 
987      * @see 0006736: Create File (Edit)InfoDialog
988      * @return array
989      */
990     public function testGetUpdate()
991     {
992         $this->testCreateFileNodes();
993         $filter = array(array(
994             'field'    => 'path', 
995             'operator' => 'equals', 
996             'value'    => '/' . Tinebase_Model_Container::TYPE_SHARED . '/testcontainer'
997         ));
998         $result = $this->_json->searchNodes($filter, array());
999         
1000         $this->assertEquals(2, $result['totalcount']);
1001         $initialNode = $result['results'][0];
1002         
1003         $node = $this->_json->getNode($initialNode['id']);
1004         $this->assertEquals('file', $node['type']);
1005         
1006         $node['description'] = 'UNITTEST';
1007         $node = $this->_json->saveNode($node);
1008         
1009         $this->assertEquals('UNITTEST', $node['description']);
1010         $this->assertEquals($initialNode['contenttype'], $node['contenttype'], 'contenttype  not preserved');
1011
1012         
1013         return $node;
1014     }
1015     
1016     /**
1017      * testSetRelation
1018      * 
1019      * @see 0006736: Create File (Edit)InfoDialog
1020      */
1021     public function testSetRelation()
1022     {
1023         $node = $this->testGetUpdate();
1024         $node['relations'] = array($this->_getRelationData($node));
1025         $node = $this->_json->saveNode($node);
1026         
1027         $this->assertEquals(1, count($node['relations']));
1028         $this->assertEquals('PHPUNIT, ali', $node['relations'][0]['related_record']['n_fileas']);
1029         
1030         $adbJson = new Addressbook_Frontend_Json();
1031         $contact = $adbJson->getContact($node['relations'][0]['related_id']);
1032         $this->assertEquals(1, count($contact['relations']), 'relations are missing');
1033         $this->assertEquals($node['name'], $contact['relations'][0]['related_record']['name']);
1034     }
1035     
1036     /**
1037      * get contact relation data
1038      * 
1039      * @param array $node
1040      * @return array
1041      */
1042     protected function _getRelationData($node)
1043     {
1044         return array(
1045             'own_model'              => 'Filemanager_Model_Node',
1046             'own_backend'            => 'Sql',
1047             'own_id'                 => $node['id'],
1048             'own_degree'             => Tinebase_Model_Relation::DEGREE_SIBLING,
1049             'type'                   => 'FILE',
1050             'related_backend'        => 'Sql',
1051             'related_model'          => 'Addressbook_Model_Contact',
1052             'remark'                 => NULL,
1053             'related_record'         => array(
1054                 'n_given'           => 'ali',
1055                 'n_family'          => 'PHPUNIT',
1056                 'org_name'          => Tinebase_Record_Abstract::generateUID(),
1057                 'tel_cell_private'  => '+49TELCELLPRIVATE',
1058             )
1059         );
1060     }
1061
1062     /**
1063      * testSetRelationToFileInPersonalFolder
1064      * 
1065      * @see 0006736: Create File (Edit)InfoDialog
1066      */
1067     public function testSetRelationToFileInPersonalFolder()
1068     {
1069         $node = $this->testCreateFileNodeWithUTF8Filenames();
1070         $node['relations'] = array($this->_getRelationData($node));
1071         $node = $this->_json->saveNode($node);
1072         
1073         $adbJson = new Addressbook_Frontend_Json();
1074         $contact = $adbJson->getContact($node['relations'][0]['related_id']);
1075         $this->assertEquals(1, count($contact['relations']));
1076         $relatedNode = $contact['relations'][0]['related_record'];
1077         $this->assertEquals($node['name'], $relatedNode['name']);
1078         $pathRegEx = '@^/personal/[a-f0-9-]+/[0-9]+/' . preg_quote($relatedNode['name']) . '$@';
1079         $this->assertTrue(preg_match($pathRegEx, $relatedNode['path']) === 1, 'path mismatch: ' . print_r($relatedNode, TRUE) . ' regex: ' . $pathRegEx);
1080     }
1081     
1082     /**
1083      * test renaming a folder in a folder containing a folder with the same name
1084      *
1085      * @see: https://forge.tine20.org/mantisbt/view.php?id=10132
1086      */
1087      public function testRenameFolderInFolderContainingFolderAlready()
1088      {
1089         $path = '/personal/' .Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name;
1090      
1091         $this->_json->createNode($path . '/Test1', 'folder', NULL, FALSE);
1092         $this->_json->createNode($path . '/Test1/Test2', 'folder', NULL, FALSE);
1093         $this->_json->createNode($path . '/Test1/Test3', 'folder', NULL, FALSE);
1094         
1095         $this->setExpectedException('Filemanager_Exception_NodeExists');
1096         
1097         $this->_json->moveNodes(array($path . '/Test1/Test3'), array($path . '/Test1/Test2'), FALSE);
1098      }
1099     
1100     /**
1101      * tests the recursive filter
1102      */
1103     public function testSearchRecursiveFilter()
1104     {
1105         $fixtures = array(
1106             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testa', 'color-red.gif'),
1107             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testb', 'color-green.gif'),
1108             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testc', 'color-blue.gif'));
1109
1110         $tempFileBackend = new Tinebase_TempFile();
1111         
1112         foreach($fixtures as $path) {
1113             $node = $this->_json->createNode($path[0], Tinebase_Model_Tree_Node::TYPE_FOLDER, NULL, FALSE);
1114             
1115             $this->_objects['containerids'][] = $node['name']['id'];
1116             
1117             $this->assertTrue(is_array($node['name']));
1118             $this->assertEquals(str_replace('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/', '', $path[0]), $node['name']['name']);
1119             $this->assertEquals($path[0], $node['path']);
1120             
1121             $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($node['path']);
1122     
1123             $filepath = $node['path'] . '/' . $path[1];
1124             // create empty file first (like the js frontend does)
1125             $result = $this->_json->createNode($filepath, Tinebase_Model_Tree_Node::TYPE_FILE, array(), FALSE);
1126             $tempFile = $tempFileBackend->createTempFile(dirname(dirname(__FILE__)) . '/files/' . $path[1]);
1127             $result = $this->_json->createNode($filepath, Tinebase_Model_Tree_Node::TYPE_FILE, $tempFile->getId(), TRUE);
1128         }
1129         
1130         $filter = array(
1131             array('field' => 'recursive', 'operator' => 'equals',   'value' => 1),
1132             array('field' => 'path',      'operator' => 'equals',   'value' => '/'),
1133             array('field' => 'query',     'operator' => 'contains', 'value' => 'color'),
1134         'AND');
1135         
1136         $result = $this->_json->searchNodes($filter, array('sort' => 'name', 'start' => 0, 'limit' => 0));
1137         $this->assertEquals(3, count($result), '3 files should have been found!');
1138     }
1139     
1140     /**
1141      * test cleanup of deleted files (filesystem)
1142      */
1143     public function testDeletedFileCleanupFromFilesystem()
1144     {
1145         // remove all files with size 0 first
1146         $size0Nodes = Tinebase_FileSystem::getInstance()->searchNodes(new Tinebase_Model_Tree_Node_Filter(array(
1147             array('field' => 'type', 'operator' => 'equals', 'value' => Tinebase_Model_Tree_FileObject::TYPE_FILE),
1148             array('field' => 'size', 'operator' => 'equals', 'value' => 0)
1149         )));
1150         foreach ($size0Nodes as $node) {
1151             Tinebase_FileSystem::getInstance()->deleteFileNode($node);
1152         }
1153         
1154         $this->testDeleteFileNodes();
1155         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromFilesystem();
1156         $this->assertGreaterThan(0, $result, 'should cleanup one file or more');
1157         $this->tearDown();
1158         
1159         Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
1160         $this->testDeleteFileNodes();
1161         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromFilesystem();
1162         $this->assertEquals(1, $result, 'should cleanup one file');
1163     }
1164     
1165     /**
1166      * test preventing to copy a folder in its subfolder
1167      * 
1168      * @see: https://forge.tine20.org/mantisbt/view.php?id=9990
1169      */
1170     public function testMoveFolderIntoChildFolder()
1171     {
1172         $this->_json->createNode('/shared/Parent', 'folder', NULL, FALSE);
1173         $this->_json->createNode('/shared/Parent/Child', 'folder', NULL, FALSE);
1174         
1175         $this->setExpectedException('Filemanager_Exception_DestinationIsOwnChild');
1176         
1177         // this must not work
1178         $this->_json->moveNodes(array('/shared/Parent'), array('/shared/Parent/Child/Parent'), FALSE);
1179     }
1180     
1181     /**
1182      * test exception on moving to the same position
1183      * 
1184      * @see: https://forge.tine20.org/mantisbt/view.php?id=9990
1185      */
1186     public function testMoveFolderToSamePosition()
1187     {
1188         $this->_json->createNode('/shared/Parent', 'folder', NULL, FALSE);
1189         $this->_json->createNode('/shared/Parent/Child', 'folder', NULL, FALSE);
1190     
1191         $this->setExpectedException('Filemanager_Exception_DestinationIsSameNode');
1192     
1193         // this must not work
1194         $this->_json->moveNodes(array('/shared/Parent/Child'), array('/shared/Parent/Child'), FALSE);
1195     }
1196
1197     /**
1198      * test to move a folder containing another folder
1199      *
1200      * @see: https://forge.tine20.org/mantisbt/view.php?id=9990
1201      */
1202     public function testMove2FoldersOnToplevel()
1203     {
1204         $path = '/personal/' .Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name;
1205     
1206         $this->_json->createNode($path . '/Parent', 'folder', NULL, FALSE);
1207         $this->_json->createNode($path . '/Parent/Child', 'folder', NULL, FALSE);
1208         $this->_json->createNode('/shared/Another', 'folder', NULL, FALSE);
1209     
1210         // move forth and back, no exception should occur
1211         $this->_json->moveNodes(array($path . '/Parent'), array('/shared/Parent'), FALSE);
1212         $this->_json->moveNodes(array('/shared/Parent'), array($path . '/Parent'), FALSE);
1213     
1214         try {
1215             $c = Tinebase_Container::getInstance()->getContainerByName('Filemanager', 'Parent', Tinebase_Model_Container::TYPE_SHARED);
1216             $this->fail('Container doesn\'t get deleted');
1217         } catch (Tinebase_Exception_NotFound $e) {
1218         }
1219         
1220         // may be any exception
1221         $e = new Tinebase_Exception('Dog eats cat');
1222     
1223         try {
1224             $this->_json->moveNodes(array($path . '/Parent'), array('/shared/Parent'), FALSE);
1225         } catch (Filemanager_Exception_NodeExists $e) {
1226         }
1227     
1228         // if $e gets overridden, an error occured (the exception Filemanager_Exception_NodeExists must not be thrown)
1229         $this->assertEquals('Tinebase_Exception', get_class($e));
1230     }
1231     
1232     /**
1233      * test creating a folder in a folder with the same name (below personal folders)
1234      *
1235      * @see: https://forge.tine20.org/mantisbt/view.php?id=10132
1236      */
1237     public function testCreateFolderInFolderWithSameName()
1238     {
1239         $path = '/personal/' .Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name;
1240         
1241         $this->_json->createNode($path . '/Test1', 'folder', NULL, FALSE);
1242         $this->_json->createNode($path . '/Test1/Test1', 'folder', NULL, FALSE);
1243         $e = new Tinebase_Exception('nothing');
1244         try {
1245             $this->_json->createNode($path . '/Test1/Test1/Test2', 'folder', NULL, FALSE);
1246         } catch(Exception $e) {
1247             $this->fail('The folder couldn\'t be found, so it hasn\'t ben created');
1248         }
1249         
1250         $this->assertEquals('nothing', $e->getMessage());
1251     }
1252     
1253     /**
1254      * get other users container
1255      * 
1256      * @return Tinebase_Model_Container
1257      */
1258     protected function _getOtherUserContainer()
1259     {
1260         if (!$this->_otherUserContainer) {
1261             $sclever = Tinebase_Helper::array_value('sclever', Zend_Registry::get('personas'));
1262             
1263             $this->_otherUserContainer = Tinebase_Container::getInstance()->getDefaultContainer('Filemanager', $sclever->getId());
1264             Tinebase_Container::getInstance()->addGrants(
1265                 $this->_otherUserContainer->getId(), 
1266                 Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE, 
1267                 NULL, 
1268                 array(Tinebase_Model_Grants::GRANT_READ), 
1269                 TRUE
1270             );
1271         }
1272         
1273         return $this->_otherUserContainer;
1274     }
1275     
1276     /**
1277      * get personal container
1278      * 
1279      * @return Tinebase_Model_Container
1280      */
1281     protected function _getPersonalFilemanagerContainer()
1282     {
1283         if (!$this->_personalContainer) {
1284             $this->_personalContainer = $this->_getPersonalContainer('Filemanager');
1285         }
1286         
1287         return $this->_personalContainer;
1288     }
1289     
1290     /**
1291      * get shared container
1292      * 
1293      * @return Tinebase_Model_Container
1294      */
1295     protected function _getSharedContainer()
1296     {
1297         if (!$this->_sharedContainer) {
1298             $search = Tinebase_Container::getInstance()->search(new Tinebase_Model_ContainerFilter(array(
1299                 'application_id' => $this->_application->getId(),
1300                 'name'           => 'shared',
1301                 'type'           => Tinebase_Model_Container::TYPE_SHARED,
1302             )));
1303             $this->_sharedContainer = (count($search) > 0) 
1304                 ? $search->getFirstRecord()
1305                 : Tinebase_Container::getInstance()->addContainer(new Tinebase_Model_Container(array(
1306                     'name'           => 'shared',
1307                     'type'           => Tinebase_Model_Container::TYPE_SHARED,
1308                     'backend'        => 'sql',
1309                     'application_id' => $this->_application->getId(),
1310                 ))
1311             );
1312         }
1313         
1314         return $this->_sharedContainer;
1315     }
1316     
1317     /**
1318      * setup the test paths
1319      * 
1320      * @param string|array $_types
1321      */
1322     protected function _setupTestPath($_types)
1323     {
1324         $testPaths = array();
1325         $types = (array) $_types;
1326         
1327         foreach ($types as $type) {
1328             switch ($type) {
1329                 case Tinebase_Model_Container::TYPE_PERSONAL:
1330                     $testPaths[] = Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->getId() . '/' 
1331                         . $this->_getPersonalFilemanagerContainer()->getId() . '/unittestdir_personal';
1332                     break;
1333                 case Tinebase_Model_Container::TYPE_SHARED:
1334                     $testPaths[] = Tinebase_Model_Container::TYPE_SHARED . '/' . $this->_getSharedContainer()->getId();
1335                     $testPaths[] = Tinebase_Model_Container::TYPE_SHARED . '/' . $this->_getSharedContainer()->getId() . '/unittestdir_shared';
1336                     break;
1337                 case Tinebase_Model_Container::TYPE_OTHERUSERS:
1338                     $personas = Zend_Registry::get('personas');
1339                     $testPaths[] = Tinebase_Model_Container::TYPE_PERSONAL . '/' . $personas['sclever']->getId() . '/' 
1340                         . $this->_getOtherUserContainer()->getId() . '/unittestdir_other';
1341                     break;
1342             }
1343         }
1344         
1345         foreach ($testPaths as $path) {
1346             $path = Filemanager_Controller_Node::getInstance()->addBasePath($path);
1347             $this->_objects['paths'][] = $path;
1348             $this->_fsController->mkdir($path);
1349         }
1350     }
1351     
1352     /**
1353      * testSaveDownloadLinkFile
1354      * 
1355      * @return array Filemanager_Model_DownloadLink
1356      */
1357     public function testSaveDownloadLinkFile()
1358     {
1359         $downloadLinkData = $this->_getDownloadLinkData();
1360         $result = $this->_json->saveDownloadLink($downloadLinkData);
1361         
1362         $this->assertTrue(! empty($result['url']));
1363         $this->assertEquals(Tinebase_Core::getHostname() . '/download/show/' . $result['id'], $result['url']);
1364         $this->assertEquals(0, $result['access_count']);
1365         
1366         return $result;
1367     }
1368     
1369     /**
1370      * testSaveDownloadLinkDirectory
1371      *
1372      * @return array Filemanager_Model_DownloadLink
1373      */
1374     public function testSaveDownloadLinkDirectory()
1375     {
1376         $downloadLinkData = $this->_getDownloadLinkData();
1377         $result = $this->_json->saveDownloadLink($downloadLinkData);
1378         
1379         $this->assertTrue(! empty($result['url']));
1380         $this->assertEquals(Tinebase_Core::getHostname() . '/download/show/' . $result['id'], $result['url']);
1381         
1382         return $result;
1383     }
1384     
1385     /**
1386      * get download link data
1387      * 
1388      * @param string $nodeType
1389      * @return array
1390      * @throws Tinebase_Exception_InvalidArgument
1391      */
1392     protected function _getDownloadLinkData($nodeType = Tinebase_Model_Tree_Node::TYPE_FILE)
1393     {
1394         // create node first
1395         if ($nodeType === Tinebase_Model_Tree_Node::TYPE_FILE) {
1396             $node = $this->testCreateFileNodeWithTempfile();
1397         } else if ($nodeType === Tinebase_Model_Tree_Node::TYPE_FOLDER) {
1398             $node = $this->testCreateContainerNodeInPersonalFolder();
1399         } else {
1400             throw new Tinebase_Exception_InvalidArgument('only file and folder nodes are supported');
1401         }
1402         
1403         return array(
1404             'node_id'       => $node['id'],
1405             'expiry_date'   => Tinebase_DateTime::now()->addDay(1)->toString(),
1406             'access_count'  => 7,
1407         );
1408     }
1409     
1410     /**
1411      * testGetDownloadLink
1412      */
1413     public function testGetDownloadLink()
1414     {
1415         $downloadLink = $this->testSaveDownloadLinkFile();
1416         
1417         $this->assertEquals($downloadLink, $this->_json->getDownloadLink($downloadLink['id']));
1418     }
1419     
1420     /**
1421      * testSearchDownloadLinks
1422      */
1423     public function testSearchDownloadLinks()
1424     {
1425         $downloadLink = $this->testSaveDownloadLinkFile();
1426         $filter = array(array(
1427             'field'     => 'id',
1428             'operator'  => 'equals',
1429             'value'     => $downloadLink['id']
1430         ));
1431         $result = $this->_json->searchDownloadLinks($filter, array());
1432         
1433         $this->assertEquals(1, $result['totalcount']);
1434     }
1435     
1436     /**
1437      * testDeleteDownloadLinks
1438      */
1439     public function testDeleteDownloadLinks()
1440     {
1441         $downloadLink = $this->testSaveDownloadLinkFile();
1442         
1443         $result = $this->_json->deleteDownloadLinks(array($downloadLink['id']));
1444         try {
1445             Filemanager_Controller_DownloadLink::getInstance()->get($downloadLink['id']);
1446             $this->fail('link should have been deleted');
1447         } catch (Exception $e) {
1448             $this->assertTrue($e instanceof Tinebase_Exception_NotFound);
1449         }
1450     }
1451 }