0011398: add own_id index to relations table
[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         
1002         $node = $this->_json->getNode($result['results'][0]['id']);
1003         $this->assertEquals('file', $node['type']);
1004         
1005         $node['description'] = 'UNITTEST';
1006         $node = $this->_json->saveNode($node);
1007         
1008         $this->assertEquals('UNITTEST', $node['description']);
1009         
1010         return $node;
1011     }
1012     
1013     /**
1014      * testSetRelation
1015      * 
1016      * @see 0006736: Create File (Edit)InfoDialog
1017      */
1018     public function testSetRelation()
1019     {
1020         $node = $this->testGetUpdate();
1021         $node['relations'] = array($this->_getRelationData($node));
1022         $node = $this->_json->saveNode($node);
1023         
1024         $this->assertEquals(1, count($node['relations']));
1025         $this->assertEquals('PHPUNIT, ali', $node['relations'][0]['related_record']['n_fileas']);
1026         
1027         $adbJson = new Addressbook_Frontend_Json();
1028         $contact = $adbJson->getContact($node['relations'][0]['related_id']);
1029         $this->assertEquals(1, count($contact['relations']), 'relations are missing');
1030         $this->assertEquals($node['name'], $contact['relations'][0]['related_record']['name']);
1031     }
1032     
1033     /**
1034      * get contact relation data
1035      * 
1036      * @param array $node
1037      * @return array
1038      */
1039     protected function _getRelationData($node)
1040     {
1041         return array(
1042             'own_model'              => 'Filemanager_Model_Node',
1043             'own_backend'            => 'Sql',
1044             'own_id'                 => $node['id'],
1045             'own_degree'             => Tinebase_Model_Relation::DEGREE_SIBLING,
1046             'type'                   => 'FILE',
1047             'related_backend'        => 'Sql',
1048             'related_model'          => 'Addressbook_Model_Contact',
1049             'remark'                 => NULL,
1050             'related_record'         => array(
1051                 'n_given'           => 'ali',
1052                 'n_family'          => 'PHPUNIT',
1053                 'org_name'          => Tinebase_Record_Abstract::generateUID(),
1054                 'tel_cell_private'  => '+49TELCELLPRIVATE',
1055             )
1056         );
1057     }
1058
1059     /**
1060      * testSetRelationToFileInPersonalFolder
1061      * 
1062      * @see 0006736: Create File (Edit)InfoDialog
1063      */
1064     public function testSetRelationToFileInPersonalFolder()
1065     {
1066         $node = $this->testCreateFileNodeWithUTF8Filenames();
1067         $node['relations'] = array($this->_getRelationData($node));
1068         $node = $this->_json->saveNode($node);
1069         
1070         $adbJson = new Addressbook_Frontend_Json();
1071         $contact = $adbJson->getContact($node['relations'][0]['related_id']);
1072         $this->assertEquals(1, count($contact['relations']));
1073         $relatedNode = $contact['relations'][0]['related_record'];
1074         $this->assertEquals($node['name'], $relatedNode['name']);
1075         $pathRegEx = '@^/personal/[a-f0-9-]+/[0-9]+/' . preg_quote($relatedNode['name']) . '$@';
1076         $this->assertTrue(preg_match($pathRegEx, $relatedNode['path']) === 1, 'path mismatch: ' . print_r($relatedNode, TRUE) . ' regex: ' . $pathRegEx);
1077     }
1078     
1079     /**
1080      * test renaming a folder in a folder containing a folder with the same name
1081      *
1082      * @see: https://forge.tine20.org/mantisbt/view.php?id=10132
1083      */
1084      public function testRenameFolderInFolderContainingFolderAlready()
1085      {
1086         $path = '/personal/' .Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name;
1087      
1088         $this->_json->createNode($path . '/Test1', 'folder', NULL, FALSE);
1089         $this->_json->createNode($path . '/Test1/Test2', 'folder', NULL, FALSE);
1090         $this->_json->createNode($path . '/Test1/Test3', 'folder', NULL, FALSE);
1091         
1092         $this->setExpectedException('Filemanager_Exception_NodeExists');
1093         
1094         $this->_json->moveNodes(array($path . '/Test1/Test3'), array($path . '/Test1/Test2'), FALSE);
1095      }
1096     
1097     /**
1098      * tests the recursive filter
1099      */
1100     public function testSearchRecursiveFilter()
1101     {
1102         $fixtures = array(
1103             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testa', 'color-red.gif'),
1104             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testb', 'color-green.gif'),
1105             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testc', 'color-blue.gif'));
1106
1107         $tempFileBackend = new Tinebase_TempFile();
1108         
1109         foreach($fixtures as $path) {
1110             $node = $this->_json->createNode($path[0], Tinebase_Model_Tree_Node::TYPE_FOLDER, NULL, FALSE);
1111             
1112             $this->_objects['containerids'][] = $node['name']['id'];
1113             
1114             $this->assertTrue(is_array($node['name']));
1115             $this->assertEquals(str_replace('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/', '', $path[0]), $node['name']['name']);
1116             $this->assertEquals($path[0], $node['path']);
1117             
1118             $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($node['path']);
1119     
1120             $filepath = $node['path'] . '/' . $path[1];
1121             // create empty file first (like the js frontend does)
1122             $result = $this->_json->createNode($filepath, Tinebase_Model_Tree_Node::TYPE_FILE, array(), FALSE);
1123             $tempFile = $tempFileBackend->createTempFile(dirname(dirname(__FILE__)) . '/files/' . $path[1]);
1124             $result = $this->_json->createNode($filepath, Tinebase_Model_Tree_Node::TYPE_FILE, $tempFile->getId(), TRUE);
1125         }
1126         
1127         $filter = array(
1128             array('field' => 'recursive', 'operator' => 'equals',   'value' => 1),
1129             array('field' => 'path',      'operator' => 'equals',   'value' => '/'),
1130             array('field' => 'query',     'operator' => 'contains', 'value' => 'color'),
1131         'AND');
1132         
1133         $result = $this->_json->searchNodes($filter, array('sort' => 'name', 'start' => 0, 'limit' => 0));
1134         $this->assertEquals(3, count($result), '3 files should have been found!');
1135     }
1136     
1137     /**
1138      * test cleanup of deleted files (filesystem)
1139      */
1140     public function testDeletedFileCleanupFromFilesystem()
1141     {
1142         // remove all files with size 0 first
1143         $size0Nodes = Tinebase_FileSystem::getInstance()->searchNodes(new Tinebase_Model_Tree_Node_Filter(array(
1144             array('field' => 'type', 'operator' => 'equals', 'value' => Tinebase_Model_Tree_FileObject::TYPE_FILE),
1145             array('field' => 'size', 'operator' => 'equals', 'value' => 0)
1146         )));
1147         foreach ($size0Nodes as $node) {
1148             Tinebase_FileSystem::getInstance()->deleteFileNode($node);
1149         }
1150         
1151         $this->testDeleteFileNodes();
1152         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromFilesystem();
1153         $this->assertGreaterThan(0, $result, 'should cleanup one file or more');
1154         $this->tearDown();
1155         
1156         Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
1157         $this->testDeleteFileNodes();
1158         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromFilesystem();
1159         $this->assertEquals(1, $result, 'should cleanup one file');
1160     }
1161     
1162     /**
1163      * test preventing to copy a folder in its subfolder
1164      * 
1165      * @see: https://forge.tine20.org/mantisbt/view.php?id=9990
1166      */
1167     public function testMoveFolderIntoChildFolder()
1168     {
1169         $this->_json->createNode('/shared/Parent', 'folder', NULL, FALSE);
1170         $this->_json->createNode('/shared/Parent/Child', 'folder', NULL, FALSE);
1171         
1172         $this->setExpectedException('Filemanager_Exception_DestinationIsOwnChild');
1173         
1174         // this must not work
1175         $this->_json->moveNodes(array('/shared/Parent'), array('/shared/Parent/Child/Parent'), FALSE);
1176     }
1177     
1178     /**
1179      * test exception on moving to the same position
1180      * 
1181      * @see: https://forge.tine20.org/mantisbt/view.php?id=9990
1182      */
1183     public function testMoveFolderToSamePosition()
1184     {
1185         $this->_json->createNode('/shared/Parent', 'folder', NULL, FALSE);
1186         $this->_json->createNode('/shared/Parent/Child', 'folder', NULL, FALSE);
1187     
1188         $this->setExpectedException('Filemanager_Exception_DestinationIsSameNode');
1189     
1190         // this must not work
1191         $this->_json->moveNodes(array('/shared/Parent/Child'), array('/shared/Parent/Child'), FALSE);
1192     }
1193
1194     /**
1195      * test to move a folder containing another folder
1196      *
1197      * @see: https://forge.tine20.org/mantisbt/view.php?id=9990
1198      */
1199     public function testMove2FoldersOnToplevel()
1200     {
1201         $path = '/personal/' .Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name;
1202     
1203         $this->_json->createNode($path . '/Parent', 'folder', NULL, FALSE);
1204         $this->_json->createNode($path . '/Parent/Child', 'folder', NULL, FALSE);
1205         $this->_json->createNode('/shared/Another', 'folder', NULL, FALSE);
1206     
1207         // move forth and back, no exception should occur
1208         $this->_json->moveNodes(array($path . '/Parent'), array('/shared/Parent'), FALSE);
1209         $this->_json->moveNodes(array('/shared/Parent'), array($path . '/Parent'), FALSE);
1210     
1211         try {
1212             $c = Tinebase_Container::getInstance()->getContainerByName('Filemanager', 'Parent', Tinebase_Model_Container::TYPE_SHARED);
1213             $this->fail('Container doesn\'t get deleted');
1214         } catch (Tinebase_Exception_NotFound $e) {
1215         }
1216         
1217         // may be any exception
1218         $e = new Tinebase_Exception('Dog eats cat');
1219     
1220         try {
1221             $this->_json->moveNodes(array($path . '/Parent'), array('/shared/Parent'), FALSE);
1222         } catch (Filemanager_Exception_NodeExists $e) {
1223         }
1224     
1225         // if $e gets overridden, an error occured (the exception Filemanager_Exception_NodeExists must not be thrown)
1226         $this->assertEquals('Tinebase_Exception', get_class($e));
1227     }
1228     
1229     /**
1230      * test creating a folder in a folder with the same name (below personal folders)
1231      *
1232      * @see: https://forge.tine20.org/mantisbt/view.php?id=10132
1233      */
1234     public function testCreateFolderInFolderWithSameName()
1235     {
1236         $path = '/personal/' .Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name;
1237         
1238         $this->_json->createNode($path . '/Test1', 'folder', NULL, FALSE);
1239         $this->_json->createNode($path . '/Test1/Test1', 'folder', NULL, FALSE);
1240         $e = new Tinebase_Exception('nothing');
1241         try {
1242             $this->_json->createNode($path . '/Test1/Test1/Test2', 'folder', NULL, FALSE);
1243         } catch(Exception $e) {
1244             $this->fail('The folder couldn\'t be found, so it hasn\'t ben created');
1245         }
1246         
1247         $this->assertEquals('nothing', $e->getMessage());
1248     }
1249     
1250     /**
1251      * get other users container
1252      * 
1253      * @return Tinebase_Model_Container
1254      */
1255     protected function _getOtherUserContainer()
1256     {
1257         if (!$this->_otherUserContainer) {
1258             $sclever = Tinebase_Helper::array_value('sclever', Zend_Registry::get('personas'));
1259             
1260             $this->_otherUserContainer = Tinebase_Container::getInstance()->getDefaultContainer('Filemanager', $sclever->getId());
1261             Tinebase_Container::getInstance()->addGrants(
1262                 $this->_otherUserContainer->getId(), 
1263                 Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE, 
1264                 NULL, 
1265                 array(Tinebase_Model_Grants::GRANT_READ), 
1266                 TRUE
1267             );
1268         }
1269         
1270         return $this->_otherUserContainer;
1271     }
1272     
1273     /**
1274      * get personal container
1275      * 
1276      * @return Tinebase_Model_Container
1277      */
1278     protected function _getPersonalFilemanagerContainer()
1279     {
1280         if (!$this->_personalContainer) {
1281             $this->_personalContainer = $this->_getPersonalContainer('Filemanager');
1282         }
1283         
1284         return $this->_personalContainer;
1285     }
1286     
1287     /**
1288      * get shared container
1289      * 
1290      * @return Tinebase_Model_Container
1291      */
1292     protected function _getSharedContainer()
1293     {
1294         if (!$this->_sharedContainer) {
1295             $search = Tinebase_Container::getInstance()->search(new Tinebase_Model_ContainerFilter(array(
1296                 'application_id' => $this->_application->getId(),
1297                 'name'           => 'shared',
1298                 'type'           => Tinebase_Model_Container::TYPE_SHARED,
1299             )));
1300             $this->_sharedContainer = (count($search) > 0) 
1301                 ? $search->getFirstRecord()
1302                 : Tinebase_Container::getInstance()->addContainer(new Tinebase_Model_Container(array(
1303                     'name'           => 'shared',
1304                     'type'           => Tinebase_Model_Container::TYPE_SHARED,
1305                     'backend'        => 'sql',
1306                     'application_id' => $this->_application->getId(),
1307                 ))
1308             );
1309         }
1310         
1311         return $this->_sharedContainer;
1312     }
1313     
1314     /**
1315      * setup the test paths
1316      * 
1317      * @param string|array $_types
1318      */
1319     protected function _setupTestPath($_types)
1320     {
1321         $testPaths = array();
1322         $types = (array) $_types;
1323         
1324         foreach ($types as $type) {
1325             switch ($type) {
1326                 case Tinebase_Model_Container::TYPE_PERSONAL:
1327                     $testPaths[] = Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->getId() . '/' 
1328                         . $this->_getPersonalFilemanagerContainer()->getId() . '/unittestdir_personal';
1329                     break;
1330                 case Tinebase_Model_Container::TYPE_SHARED:
1331                     $testPaths[] = Tinebase_Model_Container::TYPE_SHARED . '/' . $this->_getSharedContainer()->getId();
1332                     $testPaths[] = Tinebase_Model_Container::TYPE_SHARED . '/' . $this->_getSharedContainer()->getId() . '/unittestdir_shared';
1333                     break;
1334                 case Tinebase_Model_Container::TYPE_OTHERUSERS:
1335                     $personas = Zend_Registry::get('personas');
1336                     $testPaths[] = Tinebase_Model_Container::TYPE_PERSONAL . '/' . $personas['sclever']->getId() . '/' 
1337                         . $this->_getOtherUserContainer()->getId() . '/unittestdir_other';
1338                     break;
1339             }
1340         }
1341         
1342         foreach ($testPaths as $path) {
1343             $path = Filemanager_Controller_Node::getInstance()->addBasePath($path);
1344             $this->_objects['paths'][] = $path;
1345             $this->_fsController->mkdir($path);
1346         }
1347     }
1348     
1349     /**
1350      * testSaveDownloadLinkFile
1351      * 
1352      * @return array Filemanager_Model_DownloadLink
1353      */
1354     public function testSaveDownloadLinkFile()
1355     {
1356         $downloadLinkData = $this->_getDownloadLinkData();
1357         $result = $this->_json->saveDownloadLink($downloadLinkData);
1358         
1359         $this->assertTrue(! empty($result['url']));
1360         $this->assertEquals(Tinebase_Core::getHostname() . '/download/show/' . $result['id'], $result['url']);
1361         $this->assertEquals(0, $result['access_count']);
1362         
1363         return $result;
1364     }
1365     
1366     /**
1367      * testSaveDownloadLinkDirectory
1368      *
1369      * @return array Filemanager_Model_DownloadLink
1370      */
1371     public function testSaveDownloadLinkDirectory()
1372     {
1373         $downloadLinkData = $this->_getDownloadLinkData();
1374         $result = $this->_json->saveDownloadLink($downloadLinkData);
1375         
1376         $this->assertTrue(! empty($result['url']));
1377         $this->assertEquals(Tinebase_Core::getHostname() . '/download/show/' . $result['id'], $result['url']);
1378         
1379         return $result;
1380     }
1381     
1382     /**
1383      * get download link data
1384      * 
1385      * @param string $nodeType
1386      * @return array
1387      * @throws Tinebase_Exception_InvalidArgument
1388      */
1389     protected function _getDownloadLinkData($nodeType = Tinebase_Model_Tree_Node::TYPE_FILE)
1390     {
1391         // create node first
1392         if ($nodeType === Tinebase_Model_Tree_Node::TYPE_FILE) {
1393             $node = $this->testCreateFileNodeWithTempfile();
1394         } else if ($nodeType === Tinebase_Model_Tree_Node::TYPE_FOLDER) {
1395             $node = $this->testCreateContainerNodeInPersonalFolder();
1396         } else {
1397             throw new Tinebase_Exception_InvalidArgument('only file and folder nodes are supported');
1398         }
1399         
1400         return array(
1401             'node_id'       => $node['id'],
1402             'expiry_date'   => Tinebase_DateTime::now()->addDay(1)->toString(),
1403             'access_count'  => 7,
1404         );
1405     }
1406     
1407     /**
1408      * testGetDownloadLink
1409      */
1410     public function testGetDownloadLink()
1411     {
1412         $downloadLink = $this->testSaveDownloadLinkFile();
1413         
1414         $this->assertEquals($downloadLink, $this->_json->getDownloadLink($downloadLink['id']));
1415     }
1416     
1417     /**
1418      * testSearchDownloadLinks
1419      */
1420     public function testSearchDownloadLinks()
1421     {
1422         $downloadLink = $this->testSaveDownloadLinkFile();
1423         $filter = array(array(
1424             'field'     => 'id',
1425             'operator'  => 'equals',
1426             'value'     => $downloadLink['id']
1427         ));
1428         $result = $this->_json->searchDownloadLinks($filter, array());
1429         
1430         $this->assertEquals(1, $result['totalcount']);
1431     }
1432     
1433     /**
1434      * testDeleteDownloadLinks
1435      */
1436     public function testDeleteDownloadLinks()
1437     {
1438         $downloadLink = $this->testSaveDownloadLinkFile();
1439         
1440         $result = $this->_json->deleteDownloadLinks(array($downloadLink['id']));
1441         try {
1442             Filemanager_Controller_DownloadLink::getInstance()->get($downloadLink['id']);
1443             $this->fail('link should have been deleted');
1444         } catch (Exception $e) {
1445             $this->assertTrue($e instanceof Tinebase_Exception_NotFound);
1446         }
1447     }
1448 }