0011362: mime-type lost after detail update
[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         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($target . '/testcontainer');
618         $this->assertEquals(1, count($result));
619         $this->_objects['containerids'][] = $result[0]['name']['id'];
620         
621         $filter = array(array(
622             'field'    => 'path', 
623             'operator' => 'equals', 
624             'value'    => '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testcontainer',
625         ), array(
626             'field'    => 'type', 
627             'operator' => 'equals', 
628             'value'    => Tinebase_Model_Tree_Node::TYPE_FILE,
629         ));
630         $result = $this->_json->searchNodes($filter, array());
631         $this->assertEquals(2, $result['totalcount']);
632     }
633     
634     /**
635      * testCopyFileWithContentToFolder
636      */
637     public function testCopyFileWithContentToFolder()
638     {
639         $fileToCopy = $this->testCreateFileNodeWithTempfile();
640         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
641         
642         $result = $this->_json->copyNodes($fileToCopy['path'], $targetNode['path'], FALSE);
643         $this->assertEquals(1, count($result));
644         $this->assertEquals($targetNode['path'] . '/test.txt', $result[0]['path']);
645         $this->assertEquals('text/plain', $result[0]['contenttype']);
646     }
647     
648     /**
649      * testCopyFileNodeToFileExisting
650      */
651     public function testCopyFileNodeToFileExisting()
652     {
653         $filesToCopy = $this->testCreateFileNodes();
654         $file1 = $filesToCopy[0];
655         
656         $this->setExpectedException('Filemanager_Exception_NodeExists');
657         $result = $this->_json->copyNodes(array($file1), array($file1), FALSE);
658     }
659     
660     /**
661      * testCopyFileNodeToFileExistingCatchException
662      */
663     public function testCopyFileNodeToFileExistingCatchException()
664     {
665         $filesToCopy = $this->testCreateFileNodes();
666         $file1 = $filesToCopy[0];
667         
668         try {
669             $result = $this->_json->copyNodes(array($file1), array($file1), FALSE);
670         } catch (Filemanager_Exception_NodeExists $fene) {
671             $info = $fene->toArray();
672             $this->assertEquals(1, count($info['existingnodesinfo']));
673             return;
674         }
675         
676         $this->fail('An expected exception has not been raised.');
677     }
678     
679     /**
680      * testMoveFolderNodesToFolder
681      */
682     public function testMoveFolderNodesToFolder()
683     {
684         $dirsToMove = $this->testCreateDirectoryNodesInShared();
685         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
686         
687         $result = $this->_json->moveNodes($dirsToMove, $targetNode['path'], FALSE);
688         $this->assertEquals(2, count($result));
689         $this->assertEquals($targetNode['path'] . '/dir1', $result[0]['path'], 'no new path: ' . print_r($result, TRUE));
690         
691         $filter = array(array(
692             'field'    => 'path', 
693             'operator' => 'equals', 
694             'value'    => '/' . Tinebase_Model_Container::TYPE_SHARED . '/testcontainer'
695         ), array(
696             'field'    => 'type', 
697             'operator' => 'equals', 
698             'value'    => Tinebase_Model_Tree_Node::TYPE_FOLDER,
699         ));
700         $result = $this->_json->searchNodes($filter, array());
701         $this->assertEquals(0, $result['totalcount']);
702     }
703     
704     /**
705      * testMoveFolderNodesToFolderExisting
706      * 
707      * @see 0007028: moving a folder to another folder with a folder with the same name
708      */
709     public function testMoveFolderNodesToFolderExisting()
710     {
711         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
712         $testPath = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/dir1';
713         $result = $this->_json->moveNodes(array($targetNode['path']), array($testPath), FALSE);
714         $dirs = $this->testCreateDirectoryNodesInShared();
715         try {
716             $result = $this->_json->moveNodes(array($testPath), '/shared/testcontainer', FALSE);
717             $this->fail('Expected Filemanager_Exception_NodeExists!');
718         } catch (Filemanager_Exception_NodeExists $fene) {
719             $result = $this->_json->moveNodes(array($testPath), '/shared/testcontainer', TRUE);
720             $this->assertEquals(1, count($result));
721             $this->assertEquals('/shared/testcontainer/dir1', $result[0]['path']);
722         }
723     }
724
725     /**
726      * testMoveContainerFolderNodeToExistingContainer
727      * 
728      * @see 0007028: moving a folder to another folder with a folder with the same name
729      */
730     public function testMoveContainerFolderNodeToExistingContainer()
731     {
732         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
733         
734         $testPath = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testcontainer2';
735         $result = $this->_json->createNodes($testPath, Tinebase_Model_Tree_Node::TYPE_FOLDER, array(), FALSE);
736         $createdNode = $result[0];
737         $this->_objects['containerids'][] = $createdNode['name']['id'];
738         
739         try {
740             $result = $this->_json->moveNodes(array($targetNode['path']), array($createdNode['path']), FALSE);
741             $this->fail('Expected Filemanager_Exception_NodeExists!');
742         } catch (Filemanager_Exception_NodeExists $fene) {
743             $result = $this->_json->moveNodes(array($targetNode['path']), array($createdNode['path']), TRUE);
744             $this->assertEquals(1, count($result));
745             $this->assertEquals($testPath, $result[0]['path']);
746         }
747     }
748     
749     /**
750     * testMoveFolderNodesToTopLevel
751     */
752     public function testMoveFolderNodesToTopLevel()
753     {
754         // we need the personal folder for the test user
755         $this->_setupTestPath(Tinebase_Model_Container::TYPE_PERSONAL);
756         
757         $dirsToMove = $this->testCreateDirectoryNodesInShared();
758         $targetPath = '/personal/' . Tinebase_Core::getUser()->accountLoginName;
759         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($targetPath . '/dir1');
760         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($targetPath . '/dir2');
761         
762         $result = $this->_json->moveNodes($dirsToMove, $targetPath, FALSE);
763         $this->assertEquals(2, count($result));
764         $this->assertEquals($targetPath . '/dir1', $result[0]['path']);
765     }
766     
767     /**
768      * testMoveContainerFolderNodesToContainerFolder
769      */
770     public function testMoveContainerFolderNodesToContainerFolder()
771     {
772         $sourceNode = $this->testCreateContainerNodeInPersonalFolder();
773         
774         $newPath = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testcontainermoved';
775         $result = $this->_json->moveNodes($sourceNode['path'], array($newPath), FALSE);
776         $this->assertEquals(1, count($result));
777         $this->assertEquals($newPath, $result[0]['path'], 'no new path: ' . print_r($result, TRUE));
778         $this->_objects['containerids'][] = $result[0]['name']['id'];
779         
780         $filter = array(array(
781             'field'    => 'path', 
782             'operator' => 'equals', 
783             'value'    => '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName
784         ), array(
785             'field'    => 'type', 
786             'operator' => 'equals', 
787             'value'    => Tinebase_Model_Tree_Node::TYPE_FOLDER,
788         ));
789         $result = $this->_json->searchNodes($filter, array());
790         foreach ($result['results'] as $node) {
791             $this->assertNotEquals($sourceNode['path'], $node['path']);
792         }
793     }
794     
795     /**
796      * testMoveContainerFolderNodesToContainerFolderWithChildNodes
797      */
798     public function testMoveContainerFolderNodesToContainerFolderWithChildNodes()
799     {
800         $children = $this->testCreateDirectoryNodesInPersonal();
801         
802         $oldPath = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testcontainer';
803         $newPath = $oldPath . 'moved';
804         $result = $this->_json->moveNodes(array($oldPath), array($newPath), FALSE);
805         $this->assertEquals(1, count($result));
806         $this->assertEquals($newPath, $result[0]['path']);
807         $this->_objects['containerids'][] = $result[0]['name']['id'];
808         
809         $filter = array(array(
810             'field'    => 'path', 
811             'operator' => 'equals', 
812             'value'    => $newPath
813         ), array(
814             'field'    => 'type', 
815             'operator' => 'equals', 
816             'value'    => Tinebase_Model_Tree_Node::TYPE_FOLDER,
817         ));
818         $result = $this->_json->searchNodes($filter, array());
819         $this->assertEquals(2, $result['totalcount']);
820     }
821     
822     /**
823      * testMoveFileNodesToFolder
824      * 
825      * @return array target node
826      */
827     public function testMoveFileNodesToFolder()
828     {
829         $filesToMove = $this->testCreateFileNodes();
830         $targetNode = $this->testCreateContainerNodeInPersonalFolder();
831         
832         $result = $this->_json->moveNodes($filesToMove, $targetNode['path'], FALSE);
833         $this->assertEquals(2, count($result));
834         $this->assertEquals($targetNode['path'] . '/file1', $result[0]['path']);
835
836         $filter = array(array(
837             'field'    => 'path', 
838             'operator' => 'equals', 
839             'value'    => '/' . Tinebase_Model_Container::TYPE_SHARED . '/testcontainer'
840         ), array(
841             'field'    => 'type', 
842             'operator' => 'equals', 
843             'value'    => Tinebase_Model_Tree_Node::TYPE_FILE,
844         ));
845         $result = $this->_json->searchNodes($filter, array());
846         $this->assertEquals(0, $result['totalcount']);
847         
848         return $targetNode;
849     }
850
851     /**
852      * testMoveFileNodesOverwrite
853      */
854     public function testMoveFileNodesOverwrite()
855     {
856         $targetNode = $this->testCopyFileNodesToFolder();
857         
858         $sharedContainerPath = '/' . Tinebase_Model_Container::TYPE_SHARED . '/testcontainer/';
859         $filesToMove = array($sharedContainerPath . 'file1', $sharedContainerPath . 'file2');
860         $result = $this->_json->moveNodes($filesToMove, $targetNode['path'], TRUE);
861         
862         $this->assertEquals(2, count($result));
863     }
864     
865     /**
866      * testMoveFolderNodeToRoot
867      */
868     public function testMoveFolderNodeToRoot()
869     {
870         $children = $this->testCreateDirectoryNodesInPersonal();
871         
872         $target = '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName;
873         $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($target . '/testcontainer');
874         $result = $this->_json->moveNodes($children[0], $target, FALSE);
875         $this->assertEquals(1, count($result));
876         $this->assertTrue(is_array($result[0]['name']), 'array with container data expected: ' . print_r($result[0], TRUE));
877         $this->_objects['containerids'][] = $result[0]['name']['id'];
878     }
879     
880     /**
881      * testDeleteContainerNode
882      */
883     public function testDeleteContainerNode()
884     {
885         $sharedContainerNode = $this->testCreateContainerNodeInSharedFolder();
886         
887         $result = $this->_json->deleteNodes($sharedContainerNode['path']);
888         
889         // check if container is deleted
890         $search = Tinebase_Container::getInstance()->search(new Tinebase_Model_ContainerFilter(array(
891             'id' => $sharedContainerNode['name']['id'],
892         )));
893         $this->assertEquals(0, count($search));
894         $this->_objects['containerids'] = array();
895         
896         // check if node is deleted
897         $this->setExpectedException('Tinebase_Exception_NotFound');
898         $this->_fsController->stat($sharedContainerNode['path']);
899     }
900
901     /**
902      * testDeleteFileNodes
903      */
904     public function testDeleteFileNodes()
905     {
906         $filepaths = $this->testCreateFileNodes();
907         
908         $result = $this->_json->deleteNodes($filepaths);
909
910         // check if node is deleted
911         try {
912             $this->_fsController->stat(Filemanager_Controller_Node::getInstance()->addBasePath($filepaths[0]));
913             $this->assertTrue(FALSE);
914         } catch (Tinebase_Exception_NotFound $tenf) {
915             $this->assertTrue(TRUE);
916         }
917     }
918     
919     /**
920      * test cleanup of deleted files (database)
921      * 
922      * @see 0008062: add cleanup script for deleted files
923      */
924     public function testDeletedFileCleanupFromDatabase()
925     {
926         $fileNode = $this->testCreateFileNodeWithTempfile();
927         
928         // get "real" filesystem path + unlink
929         $fileObjectBackend = new Tinebase_Tree_FileObject();
930         $fileObject = $fileObjectBackend->get($fileNode['object_id']);
931         unlink($fileObject->getFilesystemPath());
932         
933         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromDatabase();
934         $this->assertEquals(1, $result, 'should cleanup one file');
935
936         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromDatabase();
937         $this->assertEquals(0, $result, 'should cleanup no file');
938         
939         // node should no longer be found
940         try {
941             $this->_json->getNode($fileNode['id']);
942             $this->fail('tree node still exists: ' . print_r($fileNode, TRUE));
943         } catch (Tinebase_Exception_NotFound $tenf) {
944             $this->assertEquals('Tinebase_Model_Tree_Node record with id = ' . $fileNode['id'] . ' not found!', $tenf->getMessage());
945         }
946     }
947     
948     /**
949      * testDeleteDirectoryNodes
950      */
951     public function testDeleteDirectoryNodes()
952     {
953         $dirpaths = $this->testCreateDirectoryNodesInShared();
954         
955         $result = $this->_json->deleteNodes($dirpaths);
956
957         // check if node is deleted
958         $this->setExpectedException('Tinebase_Exception_NotFound');
959         $node = $this->_fsController->stat(Filemanager_Controller_Node::getInstance()->addBasePath($dirpaths[0]));
960     }
961     
962     /**
963      * testSetContainerInPathRecord
964      * 
965      * @todo move this to Tinebase?
966      */
967     public function testSetContainerInPathRecord()
968     {
969         $flatpath = Filemanager_Controller_Node::getInstance()->addBasePath(
970             '/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name);
971         $path = Tinebase_Model_Tree_Node_Path::createFromPath($flatpath);
972         $path->setContainer($this->_getSharedContainer());
973         $this->assertEquals('/' . $this->_application->getId() . '/folders/shared/' . $this->_getSharedContainer()->getId(), $path->statpath);
974         
975         // move it back
976         $path->setContainer($this->_getPersonalFilemanagerContainer());
977         $this->assertEquals('/' . $this->_application->getId() . '/folders/personal/' 
978             . Tinebase_Core::getUser()->getId() . '/' . $this->_getPersonalFilemanagerContainer()->getId(), $path->statpath, 'wrong statpath: ' . print_r($path->toArray(), TRUE));
979     }
980
981     /**
982      * testGetUpdate
983      * 
984      * @see 0006736: Create File (Edit)InfoDialog
985      * @return array
986      */
987     public function testGetUpdate()
988     {
989         $this->testCreateFileNodes();
990         $filter = array(array(
991             'field'    => 'path', 
992             'operator' => 'equals', 
993             'value'    => '/' . Tinebase_Model_Container::TYPE_SHARED . '/testcontainer'
994         ));
995         $result = $this->_json->searchNodes($filter, array());
996         
997         $this->assertEquals(2, $result['totalcount']);
998         $initialNode = $result['results'][0];
999         
1000         $node = $this->_json->getNode($initialNode['id']);
1001         $this->assertEquals('file', $node['type']);
1002         
1003         $node['description'] = 'UNITTEST';
1004         $node = $this->_json->saveNode($node);
1005         
1006         $this->assertEquals('UNITTEST', $node['description']);
1007         $this->assertEquals($initialNode['contenttype'], $node['contenttype'], 'contenttype  not preserved');
1008
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      * tests the recursive filter
1081      */
1082     public function testSearchRecursiveFilter()
1083     {
1084         $fixtures = array(
1085             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testa', 'color-red.gif'),
1086             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testb', 'color-green.gif'),
1087             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testc', 'color-blue.gif'));
1088
1089         $tempFileBackend = new Tinebase_TempFile();
1090         
1091         foreach($fixtures as $path) {
1092             $node = $this->_json->createNode($path[0], Tinebase_Model_Tree_Node::TYPE_FOLDER, NULL, FALSE);
1093             
1094             $this->_objects['containerids'][] = $node['name']['id'];
1095             
1096             $this->assertTrue(is_array($node['name']));
1097             $this->assertEquals(str_replace('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/', '', $path[0]), $node['name']['name']);
1098             $this->assertEquals($path[0], $node['path']);
1099             
1100             $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($node['path']);
1101     
1102             $filepath = $node['path'] . '/' . $path[1];
1103             // create empty file first (like the js frontend does)
1104             $result = $this->_json->createNode($filepath, Tinebase_Model_Tree_Node::TYPE_FILE, array(), FALSE);
1105             $tempFile = $tempFileBackend->createTempFile(dirname(dirname(__FILE__)) . '/files/' . $path[1]);
1106             $result = $this->_json->createNode($filepath, Tinebase_Model_Tree_Node::TYPE_FILE, $tempFile->getId(), TRUE);
1107         }
1108         
1109         $filter = array(
1110             array('field' => 'recursive', 'operator' => 'equals',   'value' => 1),
1111             array('field' => 'path',      'operator' => 'equals',   'value' => '/'),
1112             array('field' => 'query',     'operator' => 'contains', 'value' => 'color'),
1113         'AND');
1114         
1115         $result = $this->_json->searchNodes($filter, array('sort' => 'name', 'start' => 0, 'limit' => 0));
1116         $this->assertEquals(3, count($result), '3 files should have been found!');
1117     }
1118     
1119     /**
1120      * test cleanup of deleted files (filesystem)
1121      */
1122     public function testDeletedFileCleanupFromFilesystem()
1123     {
1124         // remove all files with size 0 first
1125         $size0Nodes = Tinebase_FileSystem::getInstance()->searchNodes(new Tinebase_Model_Tree_Node_Filter(array(
1126             array('field' => 'type', 'operator' => 'equals', 'value' => Tinebase_Model_Tree_FileObject::TYPE_FILE),
1127             array('field' => 'size', 'operator' => 'equals', 'value' => 0)
1128         )));
1129         foreach ($size0Nodes as $node) {
1130             Tinebase_FileSystem::getInstance()->deleteFileNode($node);
1131         }
1132         
1133         $this->testDeleteFileNodes();
1134         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromFilesystem();
1135         $this->assertGreaterThan(0, $result, 'should cleanup one file or more');
1136         $this->tearDown();
1137         
1138         Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
1139         $this->testDeleteFileNodes();
1140         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromFilesystem();
1141         $this->assertEquals(1, $result, 'should cleanup one file');
1142     }
1143     
1144     /**
1145      * get other users container
1146      * 
1147      * @return Tinebase_Model_Container
1148      */
1149     protected function _getOtherUserContainer()
1150     {
1151         if (!$this->_otherUserContainer) {
1152             $sclever = array_value('sclever', Zend_Registry::get('personas'));
1153             
1154             $this->_otherUserContainer = Tinebase_Container::getInstance()->getDefaultContainer('Filemanager', $sclever->getId());
1155             Tinebase_Container::getInstance()->addGrants(
1156                 $this->_otherUserContainer->getId(), 
1157                 Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE, 
1158                 NULL, 
1159                 array(Tinebase_Model_Grants::GRANT_READ), 
1160                 TRUE
1161             );
1162         }
1163         
1164         return $this->_otherUserContainer;
1165     }
1166     
1167     /**
1168      * get personal container
1169      * 
1170      * @return Tinebase_Model_Container
1171      */
1172     protected function _getPersonalFilemanagerContainer()
1173     {
1174         if (!$this->_personalContainer) {
1175             $this->_personalContainer = $this->_getPersonalContainer('Filemanager');
1176         }
1177         
1178         return $this->_personalContainer;
1179     }
1180     
1181     /**
1182      * get shared container
1183      * 
1184      * @return Tinebase_Model_Container
1185      */
1186     protected function _getSharedContainer()
1187     {
1188         if (!$this->_sharedContainer) {
1189             $search = Tinebase_Container::getInstance()->search(new Tinebase_Model_ContainerFilter(array(
1190                 'application_id' => $this->_application->getId(),
1191                 'name'           => 'shared',
1192                 'type'           => Tinebase_Model_Container::TYPE_SHARED,
1193             )));
1194             $this->_sharedContainer = (count($search) > 0) 
1195                 ? $search->getFirstRecord()
1196                 : Tinebase_Container::getInstance()->addContainer(new Tinebase_Model_Container(array(
1197                     'name'           => 'shared',
1198                     'type'           => Tinebase_Model_Container::TYPE_SHARED,
1199                     'backend'        => 'sql',
1200                     'application_id' => $this->_application->getId(),
1201                 ))
1202             );
1203         }
1204         
1205         return $this->_sharedContainer;
1206     }
1207     
1208     /**
1209      * setup the test paths
1210      * 
1211      * @param string|array $_types
1212      */
1213     protected function _setupTestPath($_types)
1214     {
1215         $testPaths = array();
1216         $types = (array) $_types;
1217         
1218         foreach ($types as $type) {
1219             switch ($type) {
1220                 case Tinebase_Model_Container::TYPE_PERSONAL:
1221                     $testPaths[] = Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->getId() . '/' 
1222                         . $this->_getPersonalFilemanagerContainer()->getId() . '/unittestdir_personal';
1223                     break;
1224                 case Tinebase_Model_Container::TYPE_SHARED:
1225                     $testPaths[] = Tinebase_Model_Container::TYPE_SHARED . '/' . $this->_getSharedContainer()->getId();
1226                     $testPaths[] = Tinebase_Model_Container::TYPE_SHARED . '/' . $this->_getSharedContainer()->getId() . '/unittestdir_shared';
1227                     break;
1228                 case Tinebase_Model_Container::TYPE_OTHERUSERS:
1229                     $personas = Zend_Registry::get('personas');
1230                     $testPaths[] = Tinebase_Model_Container::TYPE_PERSONAL . '/' . $personas['sclever']->getId() . '/' 
1231                         . $this->_getOtherUserContainer()->getId() . '/unittestdir_other';
1232                     break;
1233             }
1234         }
1235         
1236         foreach ($testPaths as $path) {
1237             $path = Filemanager_Controller_Node::getInstance()->addBasePath($path);
1238             $this->_objects['paths'][] = $path;
1239             $this->_fsController->mkdir($path);
1240         }
1241     }
1242     
1243     /**
1244      * testSaveDownloadLinkFile
1245      * 
1246      * @return array Filemanager_Model_DownloadLink
1247      */
1248     public function testSaveDownloadLinkFile()
1249     {
1250         $downloadLinkData = $this->_getDownloadLinkData();
1251         $result = $this->_json->saveDownloadLink($downloadLinkData);
1252         
1253         $this->assertTrue(! empty($result['url']));
1254         $this->assertEquals(Tinebase_Core::getHostname() . '/download/show/' . $result['id'], $result['url']);
1255         $this->assertEquals(0, $result['access_count']);
1256         
1257         return $result;
1258     }
1259     
1260     /**
1261      * testSaveDownloadLinkDirectory
1262      *
1263      * @return array Filemanager_Model_DownloadLink
1264      */
1265     public function testSaveDownloadLinkDirectory()
1266     {
1267         $downloadLinkData = $this->_getDownloadLinkData();
1268         $result = $this->_json->saveDownloadLink($downloadLinkData);
1269         
1270         $this->assertTrue(! empty($result['url']));
1271         $this->assertEquals(Tinebase_Core::getHostname() . '/download/show/' . $result['id'], $result['url']);
1272         
1273         return $result;
1274     }
1275     
1276     /**
1277      * get download link data
1278      * 
1279      * @param string $nodeType
1280      * @return array
1281      * @throws Tinebase_Exception_InvalidArgument
1282      */
1283     protected function _getDownloadLinkData($nodeType = Tinebase_Model_Tree_Node::TYPE_FILE)
1284     {
1285         // create node first
1286         if ($nodeType === Tinebase_Model_Tree_Node::TYPE_FILE) {
1287             $node = $this->testCreateFileNodeWithTempfile();
1288         } else if ($nodeType === Tinebase_Model_Tree_Node::TYPE_FOLDER) {
1289             $node = $this->testCreateContainerNodeInPersonalFolder();
1290         } else {
1291             throw new Tinebase_Exception_InvalidArgument('only file and folder nodes are supported');
1292         }
1293         
1294         return array(
1295             'node_id'       => $node['id'],
1296             'expiry_date'   => Tinebase_DateTime::now()->addDay(1)->toString(),
1297             'access_count'  => 7,
1298         );
1299     }
1300     
1301     /**
1302      * testGetDownloadLink
1303      */
1304     public function testGetDownloadLink()
1305     {
1306         $downloadLink = $this->testSaveDownloadLinkFile();
1307         
1308         $this->assertEquals($downloadLink, $this->_json->getDownloadLink($downloadLink['id']));
1309     }
1310     
1311     /**
1312      * testSearchDownloadLinks
1313      */
1314     public function testSearchDownloadLinks()
1315     {
1316         $downloadLink = $this->testSaveDownloadLinkFile();
1317         $filter = array(array(
1318             'field'     => 'id',
1319             'operator'  => 'equals',
1320             'value'     => $downloadLink['id']
1321         ));
1322         $result = $this->_json->searchDownloadLinks($filter, array());
1323         
1324         $this->assertEquals(1, $result['totalcount']);
1325     }
1326     
1327     /**
1328      * testDeleteDownloadLinks
1329      */
1330     public function testDeleteDownloadLinks()
1331     {
1332         $downloadLink = $this->testSaveDownloadLinkFile();
1333         
1334         $result = $this->_json->deleteDownloadLinks(array($downloadLink['id']));
1335         try {
1336             Filemanager_Controller_DownloadLink::getInstance()->get($downloadLink['id']);
1337             $this->fail('link should have been deleted');
1338         } catch (Exception $e) {
1339             $this->assertTrue($e instanceof Tinebase_Exception_NotFound);
1340         }
1341     }
1342 }