eed72b43af6540ed5896f4e285943024f070bb70
[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         
999         $node = $this->_json->getNode($result['results'][0]['id']);
1000         $this->assertEquals('file', $node['type']);
1001         
1002         $node['description'] = 'UNITTEST';
1003         $node = $this->_json->saveNode($node);
1004         
1005         $this->assertEquals('UNITTEST', $node['description']);
1006         
1007         return $node;
1008     }
1009     
1010     /**
1011      * testSetRelation
1012      * 
1013      * @see 0006736: Create File (Edit)InfoDialog
1014      */
1015     public function testSetRelation()
1016     {
1017         $node = $this->testGetUpdate();
1018         $node['relations'] = array($this->_getRelationData($node));
1019         $node = $this->_json->saveNode($node);
1020         
1021         $this->assertEquals(1, count($node['relations']));
1022         $this->assertEquals('PHPUNIT, ali', $node['relations'][0]['related_record']['n_fileas']);
1023         
1024         $adbJson = new Addressbook_Frontend_Json();
1025         $contact = $adbJson->getContact($node['relations'][0]['related_id']);
1026         $this->assertEquals(1, count($contact['relations']), 'relations are missing');
1027         $this->assertEquals($node['name'], $contact['relations'][0]['related_record']['name']);
1028     }
1029     
1030     /**
1031      * get contact relation data
1032      * 
1033      * @param array $node
1034      * @return array
1035      */
1036     protected function _getRelationData($node)
1037     {
1038         return array(
1039             'own_model'              => 'Filemanager_Model_Node',
1040             'own_backend'            => 'Sql',
1041             'own_id'                 => $node['id'],
1042             'own_degree'             => Tinebase_Model_Relation::DEGREE_SIBLING,
1043             'type'                   => 'FILE',
1044             'related_backend'        => 'Sql',
1045             'related_model'          => 'Addressbook_Model_Contact',
1046             'remark'                 => NULL,
1047             'related_record'         => array(
1048                 'n_given'           => 'ali',
1049                 'n_family'          => 'PHPUNIT',
1050                 'org_name'          => Tinebase_Record_Abstract::generateUID(),
1051                 'tel_cell_private'  => '+49TELCELLPRIVATE',
1052             )
1053         );
1054     }
1055
1056     /**
1057      * testSetRelationToFileInPersonalFolder
1058      * 
1059      * @see 0006736: Create File (Edit)InfoDialog
1060      */
1061     public function testSetRelationToFileInPersonalFolder()
1062     {
1063         $node = $this->testCreateFileNodeWithUTF8Filenames();
1064         $node['relations'] = array($this->_getRelationData($node));
1065         $node = $this->_json->saveNode($node);
1066         
1067         $adbJson = new Addressbook_Frontend_Json();
1068         $contact = $adbJson->getContact($node['relations'][0]['related_id']);
1069         $this->assertEquals(1, count($contact['relations']));
1070         $relatedNode = $contact['relations'][0]['related_record'];
1071         $this->assertEquals($node['name'], $relatedNode['name']);
1072         $pathRegEx = '@^/personal/[a-f0-9-]+/[0-9]+/' . preg_quote($relatedNode['name']) . '$@';
1073         $this->assertTrue(preg_match($pathRegEx, $relatedNode['path']) === 1, 'path mismatch: ' . print_r($relatedNode, TRUE) . ' regex: ' . $pathRegEx);
1074     }
1075     
1076     /**
1077      * tests the recursive filter
1078      */
1079     public function testSearchRecursiveFilter()
1080     {
1081         $fixtures = array(
1082             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testa', 'color-red.gif'),
1083             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testb', 'color-green.gif'),
1084             array('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/testc', 'color-blue.gif'));
1085
1086         $tempFileBackend = new Tinebase_TempFile();
1087         
1088         foreach($fixtures as $path) {
1089             $node = $this->_json->createNode($path[0], Tinebase_Model_Tree_Node::TYPE_FOLDER, NULL, FALSE);
1090             
1091             $this->_objects['containerids'][] = $node['name']['id'];
1092             
1093             $this->assertTrue(is_array($node['name']));
1094             $this->assertEquals(str_replace('/' . Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->accountLoginName . '/', '', $path[0]), $node['name']['name']);
1095             $this->assertEquals($path[0], $node['path']);
1096             
1097             $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($node['path']);
1098     
1099             $filepath = $node['path'] . '/' . $path[1];
1100             // create empty file first (like the js frontend does)
1101             $result = $this->_json->createNode($filepath, Tinebase_Model_Tree_Node::TYPE_FILE, array(), FALSE);
1102             $tempFile = $tempFileBackend->createTempFile(dirname(dirname(__FILE__)) . '/files/' . $path[1]);
1103             $result = $this->_json->createNode($filepath, Tinebase_Model_Tree_Node::TYPE_FILE, $tempFile->getId(), TRUE);
1104         }
1105         
1106         $filter = array(
1107             array('field' => 'recursive', 'operator' => 'equals',   'value' => 1),
1108             array('field' => 'path',      'operator' => 'equals',   'value' => '/'),
1109             array('field' => 'query',     'operator' => 'contains', 'value' => 'color'),
1110         'AND');
1111         
1112         $result = $this->_json->searchNodes($filter, array('sort' => 'name', 'start' => 0, 'limit' => 0));
1113         $this->assertEquals(3, count($result), '3 files should have been found!');
1114     }
1115     
1116     /**
1117      * test cleanup of deleted files (filesystem)
1118      */
1119     public function testDeletedFileCleanupFromFilesystem()
1120     {
1121         // remove all files with size 0 first
1122         $size0Nodes = Tinebase_FileSystem::getInstance()->searchNodes(new Tinebase_Model_Tree_Node_Filter(array(
1123             array('field' => 'type', 'operator' => 'equals', 'value' => Tinebase_Model_Tree_FileObject::TYPE_FILE),
1124             array('field' => 'size', 'operator' => 'equals', 'value' => 0)
1125         )));
1126         foreach ($size0Nodes as $node) {
1127             Tinebase_FileSystem::getInstance()->deleteFileNode($node);
1128         }
1129         
1130         $this->testDeleteFileNodes();
1131         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromFilesystem();
1132         $this->assertGreaterThan(0, $result, 'should cleanup one file or more');
1133         $this->tearDown();
1134         
1135         Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
1136         $this->testDeleteFileNodes();
1137         $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromFilesystem();
1138         $this->assertEquals(1, $result, 'should cleanup one file');
1139     }
1140     
1141     /**
1142      * get other users container
1143      * 
1144      * @return Tinebase_Model_Container
1145      */
1146     protected function _getOtherUserContainer()
1147     {
1148         if (!$this->_otherUserContainer) {
1149             $sclever = array_value('sclever', Zend_Registry::get('personas'));
1150             
1151             $this->_otherUserContainer = Tinebase_Container::getInstance()->getDefaultContainer('Filemanager', $sclever->getId());
1152             Tinebase_Container::getInstance()->addGrants(
1153                 $this->_otherUserContainer->getId(), 
1154                 Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE, 
1155                 NULL, 
1156                 array(Tinebase_Model_Grants::GRANT_READ), 
1157                 TRUE
1158             );
1159         }
1160         
1161         return $this->_otherUserContainer;
1162     }
1163     
1164     /**
1165      * get personal container
1166      * 
1167      * @return Tinebase_Model_Container
1168      */
1169     protected function _getPersonalFilemanagerContainer()
1170     {
1171         if (!$this->_personalContainer) {
1172             $this->_personalContainer = $this->_getPersonalContainer('Filemanager');
1173         }
1174         
1175         return $this->_personalContainer;
1176     }
1177     
1178     /**
1179      * get shared container
1180      * 
1181      * @return Tinebase_Model_Container
1182      */
1183     protected function _getSharedContainer()
1184     {
1185         if (!$this->_sharedContainer) {
1186             $search = Tinebase_Container::getInstance()->search(new Tinebase_Model_ContainerFilter(array(
1187                 'application_id' => $this->_application->getId(),
1188                 'name'           => 'shared',
1189                 'type'           => Tinebase_Model_Container::TYPE_SHARED,
1190             )));
1191             $this->_sharedContainer = (count($search) > 0) 
1192                 ? $search->getFirstRecord()
1193                 : Tinebase_Container::getInstance()->addContainer(new Tinebase_Model_Container(array(
1194                     'name'           => 'shared',
1195                     'type'           => Tinebase_Model_Container::TYPE_SHARED,
1196                     'backend'        => 'sql',
1197                     'application_id' => $this->_application->getId(),
1198                 ))
1199             );
1200         }
1201         
1202         return $this->_sharedContainer;
1203     }
1204     
1205     /**
1206      * setup the test paths
1207      * 
1208      * @param string|array $_types
1209      */
1210     protected function _setupTestPath($_types)
1211     {
1212         $testPaths = array();
1213         $types = (array) $_types;
1214         
1215         foreach ($types as $type) {
1216             switch ($type) {
1217                 case Tinebase_Model_Container::TYPE_PERSONAL:
1218                     $testPaths[] = Tinebase_Model_Container::TYPE_PERSONAL . '/' . Tinebase_Core::getUser()->getId() . '/' 
1219                         . $this->_getPersonalFilemanagerContainer()->getId() . '/unittestdir_personal';
1220                     break;
1221                 case Tinebase_Model_Container::TYPE_SHARED:
1222                     $testPaths[] = Tinebase_Model_Container::TYPE_SHARED . '/' . $this->_getSharedContainer()->getId();
1223                     $testPaths[] = Tinebase_Model_Container::TYPE_SHARED . '/' . $this->_getSharedContainer()->getId() . '/unittestdir_shared';
1224                     break;
1225                 case Tinebase_Model_Container::TYPE_OTHERUSERS:
1226                     $personas = Zend_Registry::get('personas');
1227                     $testPaths[] = Tinebase_Model_Container::TYPE_PERSONAL . '/' . $personas['sclever']->getId() . '/' 
1228                         . $this->_getOtherUserContainer()->getId() . '/unittestdir_other';
1229                     break;
1230             }
1231         }
1232         
1233         foreach ($testPaths as $path) {
1234             $path = Filemanager_Controller_Node::getInstance()->addBasePath($path);
1235             $this->_objects['paths'][] = $path;
1236             $this->_fsController->mkdir($path);
1237         }
1238     }
1239     
1240     /**
1241      * testSaveDownloadLinkFile
1242      * 
1243      * @return array Filemanager_Model_DownloadLink
1244      */
1245     public function testSaveDownloadLinkFile()
1246     {
1247         $downloadLinkData = $this->_getDownloadLinkData();
1248         $result = $this->_json->saveDownloadLink($downloadLinkData);
1249         
1250         $this->assertTrue(! empty($result['url']));
1251         $this->assertEquals(Tinebase_Core::getHostname() . '/download/show/' . $result['id'], $result['url']);
1252         $this->assertEquals(0, $result['access_count']);
1253         
1254         return $result;
1255     }
1256     
1257     /**
1258      * testSaveDownloadLinkDirectory
1259      *
1260      * @return array Filemanager_Model_DownloadLink
1261      */
1262     public function testSaveDownloadLinkDirectory()
1263     {
1264         $downloadLinkData = $this->_getDownloadLinkData();
1265         $result = $this->_json->saveDownloadLink($downloadLinkData);
1266         
1267         $this->assertTrue(! empty($result['url']));
1268         $this->assertEquals(Tinebase_Core::getHostname() . '/download/show/' . $result['id'], $result['url']);
1269         
1270         return $result;
1271     }
1272     
1273     /**
1274      * get download link data
1275      * 
1276      * @param string $nodeType
1277      * @return array
1278      * @throws Tinebase_Exception_InvalidArgument
1279      */
1280     protected function _getDownloadLinkData($nodeType = Tinebase_Model_Tree_Node::TYPE_FILE)
1281     {
1282         // create node first
1283         if ($nodeType === Tinebase_Model_Tree_Node::TYPE_FILE) {
1284             $node = $this->testCreateFileNodeWithTempfile();
1285         } else if ($nodeType === Tinebase_Model_Tree_Node::TYPE_FOLDER) {
1286             $node = $this->testCreateContainerNodeInPersonalFolder();
1287         } else {
1288             throw new Tinebase_Exception_InvalidArgument('only file and folder nodes are supported');
1289         }
1290         
1291         return array(
1292             'node_id'       => $node['id'],
1293             'expiry_date'   => Tinebase_DateTime::now()->addDay(1)->toString(),
1294             'access_count'  => 7,
1295         );
1296     }
1297     
1298     /**
1299      * testGetDownloadLink
1300      */
1301     public function testGetDownloadLink()
1302     {
1303         $downloadLink = $this->testSaveDownloadLinkFile();
1304         
1305         $this->assertEquals($downloadLink, $this->_json->getDownloadLink($downloadLink['id']));
1306     }
1307     
1308     /**
1309      * testSearchDownloadLinks
1310      */
1311     public function testSearchDownloadLinks()
1312     {
1313         $downloadLink = $this->testSaveDownloadLinkFile();
1314         $filter = array(array(
1315             'field'     => 'id',
1316             'operator'  => 'equals',
1317             'value'     => $downloadLink['id']
1318         ));
1319         $result = $this->_json->searchDownloadLinks($filter, array());
1320         
1321         $this->assertEquals(1, $result['totalcount']);
1322     }
1323     
1324     /**
1325      * testDeleteDownloadLinks
1326      */
1327     public function testDeleteDownloadLinks()
1328     {
1329         $downloadLink = $this->testSaveDownloadLinkFile();
1330         
1331         $result = $this->_json->deleteDownloadLinks(array($downloadLink['id']));
1332         try {
1333             Filemanager_Controller_DownloadLink::getInstance()->get($downloadLink['id']);
1334             $this->fail('link should have been deleted');
1335         } catch (Exception $e) {
1336             $this->assertTrue($e instanceof Tinebase_Exception_NotFound);
1337         }
1338     }
1339 }