diff options
author | Joas Schilling <nickvergessen@gmx.de> | 2016-05-20 15:38:20 +0200 |
---|---|---|
committer | Thomas Müller <DeepDiver1975@users.noreply.github.com> | 2016-05-20 15:38:20 +0200 |
commit | 94ad54ec9b96d41a614fbbad4a97b34c41a6901f (patch) | |
tree | f3eb7cdda2704aaf0cd59d58efe66bcbd34cb67d /tests/lib/Share20 | |
parent | 2ef751b1ec28f7b5c7113af60ec8c9fa0ae1cf87 (diff) | |
download | nextcloud-server-94ad54ec9b96d41a614fbbad4a97b34c41a6901f.tar.gz nextcloud-server-94ad54ec9b96d41a614fbbad4a97b34c41a6901f.zip |
Move tests/ to PSR-4 (#24731)
* Move a-b to PSR-4
* Move c-d to PSR-4
* Move e+g to PSR-4
* Move h-l to PSR-4
* Move m-r to PSR-4
* Move s-u to PSR-4
* Move files/ to PSR-4
* Move remaining tests to PSR-4
* Remove Test\ from old autoloader
Diffstat (limited to 'tests/lib/Share20')
-rw-r--r-- | tests/lib/Share20/DefaultShareProviderTest.php | 2154 | ||||
-rw-r--r-- | tests/lib/Share20/ManagerTest.php | 2570 | ||||
-rw-r--r-- | tests/lib/Share20/ShareTest.php | 93 |
3 files changed, 4817 insertions, 0 deletions
diff --git a/tests/lib/Share20/DefaultShareProviderTest.php b/tests/lib/Share20/DefaultShareProviderTest.php new file mode 100644 index 00000000000..44a48535b9b --- /dev/null +++ b/tests/lib/Share20/DefaultShareProviderTest.php @@ -0,0 +1,2154 @@ +<?php +/** + * @author Roeland Jago Douma <rullzer@owncloud.com> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ +namespace Test\Share20; + +use OC\Share20\Exception\ProviderException; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; +use OCP\IUserManager; +use OCP\IGroupManager; +use OCP\Files\IRootFolder; +use OC\Share20\DefaultShareProvider; + +/** + * Class DefaultShareProviderTest + * + * @package Test\Share20 + * @group DB + */ +class DefaultShareProviderTest extends \Test\TestCase { + + /** @var IDBConnection */ + protected $dbConn; + + /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject */ + protected $userManager; + + /** @var IGroupManager | \PHPUnit_Framework_MockObject_MockObject */ + protected $groupManager; + + /** @var IRootFolder | \PHPUnit_Framework_MockObject_MockObject */ + protected $rootFolder; + + /** @var DefaultShareProvider */ + protected $provider; + + public function setUp() { + $this->dbConn = \OC::$server->getDatabaseConnection(); + $this->userManager = $this->getMock('OCP\IUserManager'); + $this->groupManager = $this->getMock('OCP\IGroupManager'); + $this->rootFolder = $this->getMock('OCP\Files\IRootFolder'); + + //Empty share table + $this->dbConn->getQueryBuilder()->delete('share')->execute(); + + $this->provider = new DefaultShareProvider( + $this->dbConn, + $this->userManager, + $this->groupManager, + $this->rootFolder + ); + } + + public function tearDown() { + $this->dbConn->getQueryBuilder()->delete('share')->execute(); + } + + /** + * @param int $shareType + * @param string $sharedWith + * @param string $sharedBy + * @param string $shareOwner + * @param string $itemType + * @param int $fileSource + * @param string $fileTarget + * @param int $permissions + * @param $token + * @param $expiration + * @return int + */ + private function addShareToDB($shareType, $sharedWith, $sharedBy, $shareOwner, + $itemType, $fileSource, $fileTarget, $permissions, $token, $expiration, + $parent = null) { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share'); + + if ($shareType) $qb->setValue('share_type', $qb->expr()->literal($shareType)); + if ($sharedWith) $qb->setValue('share_with', $qb->expr()->literal($sharedWith)); + if ($sharedBy) $qb->setValue('uid_initiator', $qb->expr()->literal($sharedBy)); + if ($shareOwner) $qb->setValue('uid_owner', $qb->expr()->literal($shareOwner)); + if ($itemType) $qb->setValue('item_type', $qb->expr()->literal($itemType)); + if ($fileSource) $qb->setValue('file_source', $qb->expr()->literal($fileSource)); + if ($fileTarget) $qb->setValue('file_target', $qb->expr()->literal($fileTarget)); + if ($permissions) $qb->setValue('permissions', $qb->expr()->literal($permissions)); + if ($token) $qb->setValue('token', $qb->expr()->literal($token)); + if ($expiration) $qb->setValue('expiration', $qb->createNamedParameter($expiration, IQueryBuilder::PARAM_DATE)); + if ($parent) $qb->setValue('parent', $qb->expr()->literal($parent)); + + $this->assertEquals(1, $qb->execute()); + return$qb->getLastInsertId(); + } + + + + /** + * @expectedException \OCP\Share\Exceptions\ShareNotFound + */ + public function testGetShareByIdNotExist() { + $this->provider->getShareById(1); + } + + public function testGetShareByIdUserShare() { + $qb = $this->dbConn->getQueryBuilder(); + + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $qb->execute(); + + $id = $qb->getLastInsertId(); + + $sharedBy = $this->getMock('OCP\IUser'); + $sharedBy->method('getUID')->willReturn('sharedBy'); + $shareOwner = $this->getMock('OCP\IUser'); + $shareOwner->method('getUID')->willReturn('shareOwner'); + + $ownerPath = $this->getMock('\OCP\Files\File'); + $shareOwnerFolder = $this->getMock('\OCP\Files\Folder'); + $shareOwnerFolder->method('getById')->with(42)->willReturn([$ownerPath]); + + $this->rootFolder + ->method('getUserFolder') + ->will($this->returnValueMap([ + ['shareOwner', $shareOwnerFolder], + ])); + + $share = $this->provider->getShareById($id); + + $this->assertEquals($id, $share->getId()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + $this->assertEquals('sharedWith', $share->getSharedWith()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals($ownerPath, $share->getNode()); + $this->assertEquals(13, $share->getPermissions()); + $this->assertEquals(null, $share->getToken()); + $this->assertEquals(null, $share->getExpirationDate()); + $this->assertEquals('myTarget', $share->getTarget()); + } + + public function testGetShareByIdLazy() { + $qb = $this->dbConn->getQueryBuilder(); + + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $qb->execute(); + + $id = $qb->getLastInsertId(); + + $this->rootFolder->expects($this->never())->method('getUserFolder'); + + $share = $this->provider->getShareById($id); + + // We do not fetch the node so the rootfolder is never called. + + $this->assertEquals($id, $share->getId()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + $this->assertEquals('sharedWith', $share->getSharedWith()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals(13, $share->getPermissions()); + $this->assertEquals(null, $share->getToken()); + $this->assertEquals(null, $share->getExpirationDate()); + $this->assertEquals('myTarget', $share->getTarget()); + } + + public function testGetShareByIdLazy2() { + $qb = $this->dbConn->getQueryBuilder(); + + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $qb->execute(); + + $id = $qb->getLastInsertId(); + + $ownerPath = $this->getMock('\OCP\Files\File'); + + $shareOwnerFolder = $this->getMock('\OCP\Files\Folder'); + $shareOwnerFolder->method('getById')->with(42)->willReturn([$ownerPath]); + + $this->rootFolder + ->method('getUserFolder') + ->with('shareOwner') + ->willReturn($shareOwnerFolder); + + $share = $this->provider->getShareById($id); + + // We fetch the node so the root folder is eventually called + + $this->assertEquals($id, $share->getId()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + $this->assertEquals('sharedWith', $share->getSharedWith()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals($ownerPath, $share->getNode()); + $this->assertEquals(13, $share->getPermissions()); + $this->assertEquals(null, $share->getToken()); + $this->assertEquals(null, $share->getExpirationDate()); + $this->assertEquals('myTarget', $share->getTarget()); + } + + public function testGetShareByIdGroupShare() { + $qb = $this->dbConn->getQueryBuilder(); + + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + + // Get the id + $id = $qb->getLastInsertId(); + + $ownerPath = $this->getMock('\OCP\Files\Folder'); + $shareOwnerFolder = $this->getMock('\OCP\Files\Folder'); + $shareOwnerFolder->method('getById')->with(42)->willReturn([$ownerPath]); + + $this->rootFolder + ->method('getUserFolder') + ->will($this->returnValueMap([ + ['shareOwner', $shareOwnerFolder], + ])); + + $share = $this->provider->getShareById($id); + + $this->assertEquals($id, $share->getId()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType()); + $this->assertEquals('sharedWith', $share->getSharedWith()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals($ownerPath, $share->getNode()); + $this->assertEquals(13, $share->getPermissions()); + $this->assertEquals(null, $share->getToken()); + $this->assertEquals(null, $share->getExpirationDate()); + $this->assertEquals('myTarget', $share->getTarget()); + } + + public function testGetShareByIdUserGroupShare() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_GROUP, 'group0', 'user0', 'user0', 'file', 42, 'myTarget', 31, null, null); + $this->addShareToDB(2, 'user1', 'user0', 'user0', 'file', 42, 'userTarget', 0, null, null, $id); + + $user0 = $this->getMock('OCP\IUser'); + $user0->method('getUID')->willReturn('user0'); + $user1 = $this->getMock('OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + + $group0 = $this->getMock('OCP\IGroup'); + $group0->method('inGroup')->with($user1)->willReturn(true); + + $node = $this->getMock('\OCP\Files\Folder'); + $node->method('getId')->willReturn(42); + + $this->rootFolder->method('getUserFolder')->with('user0')->will($this->returnSelf()); + $this->rootFolder->method('getById')->willReturn([$node]); + + $this->userManager->method('get')->will($this->returnValueMap([ + ['user0', $user0], + ['user1', $user1], + ])); + $this->groupManager->method('get')->with('group0')->willReturn($group0); + + $share = $this->provider->getShareById($id, 'user1'); + + $this->assertEquals($id, $share->getId()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType()); + $this->assertSame('group0', $share->getSharedWith()); + $this->assertSame('user0', $share->getSharedBy()); + $this->assertSame('user0', $share->getShareOwner()); + $this->assertSame($node, $share->getNode()); + $this->assertEquals(0, $share->getPermissions()); + $this->assertEquals(null, $share->getToken()); + $this->assertEquals(null, $share->getExpirationDate()); + $this->assertEquals('userTarget', $share->getTarget()); + } + + public function testGetShareByIdLinkShare() { + $qb = $this->dbConn->getQueryBuilder(); + + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + 'token' => $qb->expr()->literal('token'), + 'expiration' => $qb->expr()->literal('2000-01-02 00:00:00'), + ]); + $this->assertEquals(1, $qb->execute()); + + $id = $qb->getLastInsertId(); + + $ownerPath = $this->getMock('\OCP\Files\Folder'); + $shareOwnerFolder = $this->getMock('\OCP\Files\Folder'); + $shareOwnerFolder->method('getById')->with(42)->willReturn([$ownerPath]); + + $this->rootFolder + ->method('getUserFolder') + ->will($this->returnValueMap([ + ['shareOwner', $shareOwnerFolder], + ])); + + $share = $this->provider->getShareById($id); + + $this->assertEquals($id, $share->getId()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_LINK, $share->getShareType()); + $this->assertEquals('sharedWith', $share->getPassword()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals($ownerPath, $share->getNode()); + $this->assertEquals(13, $share->getPermissions()); + $this->assertEquals('token', $share->getToken()); + $this->assertEquals(\DateTime::createFromFormat('Y-m-d H:i:s', '2000-01-02 00:00:00'), $share->getExpirationDate()); + $this->assertEquals('myTarget', $share->getTarget()); + } + + public function testDeleteSingleShare() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + + $id = $qb->getLastInsertId(); + + $share = $this->getMock('OCP\Share\IShare'); + $share->method('getId')->willReturn($id); + + $provider = $this->getMockBuilder('OC\Share20\DefaultShareProvider') + ->setConstructorArgs([ + $this->dbConn, + $this->userManager, + $this->groupManager, + $this->rootFolder, + ]) + ->setMethods(['getShareById']) + ->getMock(); + + $provider->delete($share); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->select('*') + ->from('share'); + + $cursor = $qb->execute(); + $result = $cursor->fetchAll(); + $cursor->closeCursor(); + + $this->assertEmpty($result); + } + + public function testDeleteSingleShareLazy() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + + $id = $qb->getLastInsertId(); + + $this->rootFolder->expects($this->never())->method($this->anything()); + + $share = $this->provider->getShareById($id); + $this->provider->delete($share); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->select('*') + ->from('share'); + + $cursor = $qb->execute(); + $result = $cursor->fetchAll(); + $cursor->closeCursor(); + + $this->assertEmpty($result); + } + + public function testDeleteGroupShareWithUserGroupShares() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + $id = $qb->getLastInsertId(); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(2), + 'share_with' => $qb->expr()->literal('sharedWithUser'), + 'uid_owner' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + 'parent' => $qb->expr()->literal($id), + ]); + $this->assertEquals(1, $qb->execute()); + + $share = $this->getMock('OCP\Share\IShare'); + $share->method('getId')->willReturn($id); + $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP); + + $provider = $this->getMockBuilder('OC\Share20\DefaultShareProvider') + ->setConstructorArgs([ + $this->dbConn, + $this->userManager, + $this->groupManager, + $this->rootFolder, + ]) + ->setMethods(['getShareById']) + ->getMock(); + + $provider->delete($share); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->select('*') + ->from('share'); + + $cursor = $qb->execute(); + $result = $cursor->fetchAll(); + $cursor->closeCursor(); + + $this->assertEmpty($result); + } + + public function testGetChildren() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $qb->execute(); + + // Get the id + $id = $qb->getLastInsertId(); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('user1'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('user2'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(1), + 'file_target' => $qb->expr()->literal('myTarget1'), + 'permissions' => $qb->expr()->literal(2), + 'parent' => $qb->expr()->literal($id), + ]); + $qb->execute(); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), + 'share_with' => $qb->expr()->literal('group1'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('user3'), + 'item_type' => $qb->expr()->literal('folder'), + 'file_source' => $qb->expr()->literal(3), + 'file_target' => $qb->expr()->literal('myTarget2'), + 'permissions' => $qb->expr()->literal(4), + 'parent' => $qb->expr()->literal($id), + ]); + $qb->execute(); + + $ownerPath = $this->getMock('\OCP\Files\Folder'); + $ownerFolder = $this->getMock('\OCP\Files\Folder'); + $ownerFolder->method('getById')->willReturn([$ownerPath]); + + $this->rootFolder + ->method('getUserFolder') + ->will($this->returnValueMap([ + ['shareOwner', $ownerFolder], + ])); + + $share = $this->getMock('\OCP\Share\IShare'); + $share->method('getId')->willReturn($id); + + $children = $this->provider->getChildren($share); + + $this->assertCount(2, $children); + + //Child1 + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $children[0]->getShareType()); + $this->assertEquals('user1', $children[0]->getSharedWith()); + $this->assertEquals('user2', $children[0]->getSharedBy()); + $this->assertEquals('shareOwner', $children[0]->getShareOwner()); + $this->assertEquals($ownerPath, $children[0]->getNode()); + $this->assertEquals(2, $children[0]->getPermissions()); + $this->assertEquals(null, $children[0]->getToken()); + $this->assertEquals(null, $children[0]->getExpirationDate()); + $this->assertEquals('myTarget1', $children[0]->getTarget()); + + //Child2 + $this->assertEquals(\OCP\Share::SHARE_TYPE_GROUP, $children[1]->getShareType()); + $this->assertEquals('group1', $children[1]->getSharedWith()); + $this->assertEquals('user3', $children[1]->getSharedBy()); + $this->assertEquals('shareOwner', $children[1]->getShareOwner()); + $this->assertEquals($ownerPath, $children[1]->getNode()); + $this->assertEquals(4, $children[1]->getPermissions()); + $this->assertEquals(null, $children[1]->getToken()); + $this->assertEquals(null, $children[1]->getExpirationDate()); + $this->assertEquals('myTarget2', $children[1]->getTarget()); + } + + public function testCreateUserShare() { + $share = new \OC\Share20\Share($this->rootFolder); + + $shareOwner = $this->getMock('OCP\IUser'); + $shareOwner->method('getUID')->WillReturn('shareOwner'); + + $path = $this->getMock('\OCP\Files\File'); + $path->method('getId')->willReturn(100); + $path->method('getOwner')->willReturn($shareOwner); + + $ownerFolder = $this->getMock('OCP\Files\Folder'); + $userFolder = $this->getMock('OCP\Files\Folder'); + $this->rootFolder + ->method('getUserFolder') + ->will($this->returnValueMap([ + ['sharedBy', $userFolder], + ['shareOwner', $ownerFolder], + ])); + + $userFolder->method('getById') + ->with(100) + ->willReturn([$path]); + $ownerFolder->method('getById') + ->with(100) + ->willReturn([$path]); + + $share->setShareType(\OCP\Share::SHARE_TYPE_USER); + $share->setSharedWith('sharedWith'); + $share->setSharedBy('sharedBy'); + $share->setShareOwner('shareOwner'); + $share->setNode($path); + $share->setPermissions(1); + $share->setTarget('/target'); + + $share2 = $this->provider->create($share); + + $this->assertNotNull($share2->getId()); + $this->assertSame('ocinternal:'.$share2->getId(), $share2->getFullId()); + $this->assertSame(\OCP\Share::SHARE_TYPE_USER, $share2->getShareType()); + $this->assertSame('sharedWith', $share2->getSharedWith()); + $this->assertSame('sharedBy', $share2->getSharedBy()); + $this->assertSame('shareOwner', $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + $this->assertSame('/target', $share2->getTarget()); + $this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime()); + $this->assertSame($path, $share2->getNode()); + } + + public function testCreateGroupShare() { + $share = new \OC\Share20\Share($this->rootFolder); + + $shareOwner = $this->getMock('\OCP\IUser'); + $shareOwner->method('getUID')->willReturn('shareOwner'); + + $path = $this->getMock('\OCP\Files\Folder'); + $path->method('getId')->willReturn(100); + $path->method('getOwner')->willReturn($shareOwner); + + $ownerFolder = $this->getMock('OCP\Files\Folder'); + $userFolder = $this->getMock('OCP\Files\Folder'); + $this->rootFolder + ->method('getUserFolder') + ->will($this->returnValueMap([ + ['sharedBy', $userFolder], + ['shareOwner', $ownerFolder], + ])); + + $userFolder->method('getById') + ->with(100) + ->willReturn([$path]); + $ownerFolder->method('getById') + ->with(100) + ->willReturn([$path]); + + $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP); + $share->setSharedWith('sharedWith'); + $share->setSharedBy('sharedBy'); + $share->setShareOwner('shareOwner'); + $share->setNode($path); + $share->setPermissions(1); + $share->setTarget('/target'); + + $share2 = $this->provider->create($share); + + $this->assertNotNull($share2->getId()); + $this->assertSame('ocinternal:'.$share2->getId(), $share2->getFullId()); + $this->assertSame(\OCP\Share::SHARE_TYPE_GROUP, $share2->getShareType()); + $this->assertSame('sharedWith', $share2->getSharedWith()); + $this->assertSame('sharedBy', $share2->getSharedBy()); + $this->assertSame('shareOwner', $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + $this->assertSame('/target', $share2->getTarget()); + $this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime()); + $this->assertSame($path, $share2->getNode()); + } + + public function testCreateLinkShare() { + $share = new \OC\Share20\Share($this->rootFolder); + + $shareOwner = $this->getMock('\OCP\IUser'); + $shareOwner->method('getUID')->willReturn('shareOwner'); + + $path = $this->getMock('\OCP\Files\Folder'); + $path->method('getId')->willReturn(100); + $path->method('getOwner')->willReturn($shareOwner); + + $ownerFolder = $this->getMock('OCP\Files\Folder'); + $userFolder = $this->getMock('OCP\Files\Folder'); + $this->rootFolder + ->method('getUserFolder') + ->will($this->returnValueMap([ + ['sharedBy', $userFolder], + ['shareOwner', $ownerFolder], + ])); + + $userFolder->method('getById') + ->with(100) + ->willReturn([$path]); + $ownerFolder->method('getById') + ->with(100) + ->willReturn([$path]); + + $share->setShareType(\OCP\Share::SHARE_TYPE_LINK); + $share->setSharedBy('sharedBy'); + $share->setShareOwner('shareOwner'); + $share->setNode($path); + $share->setPermissions(1); + $share->setPassword('password'); + $share->setToken('token'); + $expireDate = new \DateTime(); + $share->setExpirationDate($expireDate); + $share->setTarget('/target'); + + $share2 = $this->provider->create($share); + + $this->assertNotNull($share2->getId()); + $this->assertSame('ocinternal:'.$share2->getId(), $share2->getFullId()); + $this->assertSame(\OCP\Share::SHARE_TYPE_LINK, $share2->getShareType()); + $this->assertSame('sharedBy', $share2->getSharedBy()); + $this->assertSame('shareOwner', $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + $this->assertSame('/target', $share2->getTarget()); + $this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime()); + $this->assertSame($path, $share2->getNode()); + $this->assertSame('password', $share2->getPassword()); + $this->assertSame('token', $share2->getToken()); + $this->assertEquals($expireDate, $share2->getExpirationDate()); + } + + public function testGetShareByToken() { + $qb = $this->dbConn->getQueryBuilder(); + + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK), + 'share_with' => $qb->expr()->literal('password'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + 'token' => $qb->expr()->literal('secrettoken'), + ]); + $qb->execute(); + $id = $qb->getLastInsertId(); + + $file = $this->getMock('\OCP\Files\File'); + + $this->rootFolder->method('getUserFolder')->with('shareOwner')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(42)->willReturn([$file]); + + $share = $this->provider->getShareByToken('secrettoken'); + $this->assertEquals($id, $share->getId()); + $this->assertSame('shareOwner', $share->getShareOwner()); + $this->assertSame('sharedBy', $share->getSharedBy()); + $this->assertSame('secrettoken', $share->getToken()); + $this->assertSame('password', $share->getPassword()); + $this->assertSame(null, $share->getSharedWith()); + } + + /** + * @expectedException \OCP\Share\Exceptions\ShareNotFound + */ + public function testGetShareByTokenNotFound() { + $this->provider->getShareByToken('invalidtoken'); + } + + public function testGetSharedWithUser() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + $id = $qb->getLastInsertId(); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith2'), + 'uid_owner' => $qb->expr()->literal('shareOwner2'), + 'uid_initiator' => $qb->expr()->literal('sharedBy2'), + 'item_type' => $qb->expr()->literal('file2'), + 'file_source' => $qb->expr()->literal(43), + 'file_target' => $qb->expr()->literal('myTarget2'), + 'permissions' => $qb->expr()->literal(14), + ]); + $this->assertEquals(1, $qb->execute()); + + $file = $this->getMock('\OCP\Files\File'); + $this->rootFolder->method('getUserFolder')->with('shareOwner')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(42)->willReturn([$file]); + + $share = $this->provider->getSharedWith('sharedWith', \OCP\Share::SHARE_TYPE_USER, null, 1 , 0); + $this->assertCount(1, $share); + + $share = $share[0]; + $this->assertEquals($id, $share->getId()); + $this->assertEquals('sharedWith', $share->getSharedWith()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + } + + public function testGetSharedWithGroup() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner2'), + 'uid_initiator' => $qb->expr()->literal('sharedBy2'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(43), + 'file_target' => $qb->expr()->literal('myTarget2'), + 'permissions' => $qb->expr()->literal(14), + ]); + $this->assertEquals(1, $qb->execute()); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + $id = $qb->getLastInsertId(); + + $groups = []; + foreach(range(0, 100) as $i) { + $group = $this->getMock('\OCP\IGroup'); + $group->method('getGID')->willReturn('group'.$i); + $groups[] = $group; + } + + $group = $this->getMock('\OCP\IGroup'); + $group->method('getGID')->willReturn('sharedWith'); + $groups[] = $group; + + $user = $this->getMock('\OCP\IUser'); + $user->method('getUID')->willReturn('sharedWith'); + $owner = $this->getMock('\OCP\IUser'); + $owner->method('getUID')->willReturn('shareOwner'); + $initiator = $this->getMock('\OCP\IUser'); + $initiator->method('getUID')->willReturn('sharedBy'); + + $this->userManager->method('get')->willReturnMap([ + ['sharedWith', $user], + ['shareOwner', $owner], + ['sharedBy', $initiator], + ]); + $this->groupManager->method('getUserGroups')->with($user)->willReturn($groups); + $this->groupManager->method('get')->with('sharedWith')->willReturn($group); + + $file = $this->getMock('\OCP\Files\File'); + $this->rootFolder->method('getUserFolder')->with('shareOwner')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(42)->willReturn([$file]); + + $share = $this->provider->getSharedWith('sharedWith', \OCP\Share::SHARE_TYPE_GROUP, null, 20 , 1); + $this->assertCount(1, $share); + + $share = $share[0]; + $this->assertEquals($id, $share->getId()); + $this->assertEquals('sharedWith', $share->getSharedWith()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType()); + } + + public function testGetSharedWithGroupUserModified() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + $id = $qb->getLastInsertId(); + + /* + * Wrong share. Should not be taken by code. + */ + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(2), + 'share_with' => $qb->expr()->literal('user2'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('wrongTarget'), + 'permissions' => $qb->expr()->literal(31), + 'parent' => $qb->expr()->literal($id), + ]); + $this->assertEquals(1, $qb->execute()); + + /* + * Correct share. should be taken by code path. + */ + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(2), + 'share_with' => $qb->expr()->literal('user'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('userTarget'), + 'permissions' => $qb->expr()->literal(0), + 'parent' => $qb->expr()->literal($id), + ]); + $this->assertEquals(1, $qb->execute()); + + $group = $this->getMock('\OCP\IGroup'); + $group->method('getGID')->willReturn('sharedWith'); + $groups = [$group]; + + $user = $this->getMock('\OCP\IUser'); + $user->method('getUID')->willReturn('user'); + $owner = $this->getMock('\OCP\IUser'); + $owner->method('getUID')->willReturn('shareOwner'); + $initiator = $this->getMock('\OCP\IUser'); + $initiator->method('getUID')->willReturn('sharedBy'); + + $this->userManager->method('get')->willReturnMap([ + ['user', $user], + ['shareOwner', $owner], + ['sharedBy', $initiator], + ]); + $this->groupManager->method('getUserGroups')->with($user)->willReturn($groups); + $this->groupManager->method('get')->with('sharedWith')->willReturn($group); + + $file = $this->getMock('\OCP\Files\File'); + $this->rootFolder->method('getUserFolder')->with('shareOwner')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(42)->willReturn([$file]); + + $share = $this->provider->getSharedWith('user', \OCP\Share::SHARE_TYPE_GROUP, null, -1, 0); + $this->assertCount(1, $share); + + $share = $share[0]; + $this->assertSame((string)$id, $share->getId()); + $this->assertSame('sharedWith', $share->getSharedWith()); + $this->assertSame('shareOwner', $share->getShareOwner()); + $this->assertSame('sharedBy', $share->getSharedBy()); + $this->assertSame(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType()); + $this->assertSame(0, $share->getPermissions()); + $this->assertSame('userTarget', $share->getTarget()); + } + + public function testGetSharedWithUserWithNode() { + $this->addShareToDB(\OCP\Share::SHARE_TYPE_USER, 'user0', 'user1', 'user1', + 'file', 42, 'myTarget', 31, null, null, null); + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_USER, 'user0', 'user1', 'user1', + 'file', 43, 'myTarget', 31, null, null, null); + + $user0 = $this->getMock('\OCP\IUser'); + $user0->method('getUID')->willReturn('user0'); + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + + $this->userManager->method('get')->willReturnMap([ + ['user0', $user0], + ['user1', $user1], + ]); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(43); + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(43)->willReturn([$file]); + + $share = $this->provider->getSharedWith('user0', \OCP\Share::SHARE_TYPE_USER, $file, -1, 0); + $this->assertCount(1, $share); + + $share = $share[0]; + $this->assertEquals($id, $share->getId()); + $this->assertSame('user0', $share->getSharedWith()); + $this->assertSame('user1', $share->getShareOwner()); + $this->assertSame('user1', $share->getSharedBy()); + $this->assertSame($file, $share->getNode()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + } + + public function testGetSharedWithGroupWithNode() { + $this->addShareToDB(\OCP\Share::SHARE_TYPE_GROUP, 'group0', 'user1', 'user1', + 'file', 42, 'myTarget', 31, null, null, null); + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_GROUP, 'group0', 'user1', 'user1', + 'file', 43, 'myTarget', 31, null, null, null); + + $user0 = $this->getMock('\OCP\IUser'); + $user0->method('getUID')->willReturn('user0'); + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + + $this->userManager->method('get')->willReturnMap([ + ['user0', $user0], + ['user1', $user1], + ]); + + $group0 = $this->getMock('\OCP\IGroup'); + $group0->method('getGID')->willReturn('group0'); + + $this->groupManager->method('get')->with('group0')->willReturn($group0); + $this->groupManager->method('getUserGroups')->with($user0)->willReturn([$group0]); + + $node = $this->getMock('\OCP\Files\Folder'); + $node->method('getId')->willReturn(43); + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(43)->willReturn([$node]); + + $share = $this->provider->getSharedWith('user0', \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0); + $this->assertCount(1, $share); + + $share = $share[0]; + $this->assertEquals($id, $share->getId()); + $this->assertSame('group0', $share->getSharedWith()); + $this->assertSame('user1', $share->getShareOwner()); + $this->assertSame('user1', $share->getSharedBy()); + $this->assertSame($node, $share->getNode()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType()); + } + + public function testGetSharesBy() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + $id = $qb->getLastInsertId(); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy2'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('userTarget'), + 'permissions' => $qb->expr()->literal(0), + 'parent' => $qb->expr()->literal($id), + ]); + $this->assertEquals(1, $qb->execute()); + + $file = $this->getMock('\OCP\Files\File'); + $this->rootFolder->method('getUserFolder')->with('shareOwner')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(42)->willReturn([$file]); + + $share = $this->provider->getSharesBy('sharedBy', \OCP\Share::SHARE_TYPE_USER, null, false, 1, 0); + $this->assertCount(1, $share); + + $share = $share[0]; + $this->assertEquals($id, $share->getId()); + $this->assertEquals('sharedWith', $share->getSharedWith()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + $this->assertEquals(13, $share->getPermissions()); + $this->assertEquals('myTarget', $share->getTarget()); + } + + public function testGetSharesNode() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + $id = $qb->getLastInsertId(); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(43), + 'file_target' => $qb->expr()->literal('userTarget'), + 'permissions' => $qb->expr()->literal(0), + 'parent' => $qb->expr()->literal($id), + ]); + $this->assertEquals(1, $qb->execute()); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(42); + $this->rootFolder->method('getUserFolder')->with('shareOwner')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(42)->willReturn([$file]); + + $share = $this->provider->getSharesBy('sharedBy', \OCP\Share::SHARE_TYPE_USER, $file, false, 1, 0); + $this->assertCount(1, $share); + + $share = $share[0]; + $this->assertEquals($id, $share->getId()); + $this->assertEquals('sharedWith', $share->getSharedWith()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + $this->assertEquals(13, $share->getPermissions()); + $this->assertEquals('myTarget', $share->getTarget()); + } + + public function testGetSharesReshare() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('shareOwner'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + $id1 = $qb->getLastInsertId(); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('userTarget'), + 'permissions' => $qb->expr()->literal(0), + ]); + $this->assertEquals(1, $qb->execute()); + $id2 = $qb->getLastInsertId(); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(42); + $this->rootFolder->method('getUserFolder')->with('shareOwner')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(42)->willReturn([$file]); + + $shares = $this->provider->getSharesBy('shareOwner', \OCP\Share::SHARE_TYPE_USER, null, true, -1, 0); + $this->assertCount(2, $shares); + + $share = $shares[0]; + $this->assertEquals($id1, $share->getId()); + $this->assertSame('sharedWith', $share->getSharedWith()); + $this->assertSame('shareOwner', $share->getShareOwner()); + $this->assertSame('shareOwner', $share->getSharedBy()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + $this->assertEquals(13, $share->getPermissions()); + $this->assertEquals('myTarget', $share->getTarget()); + + $share = $shares[1]; + $this->assertEquals($id2, $share->getId()); + $this->assertSame('sharedWith', $share->getSharedWith()); + $this->assertSame('shareOwner', $share->getShareOwner()); + $this->assertSame('sharedBy', $share->getSharedBy()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + $this->assertEquals(0, $share->getPermissions()); + $this->assertEquals('userTarget', $share->getTarget()); + } + + public function testDeleteFromSelfGroupNoCustomShare() { + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), + 'share_with' => $qb->expr()->literal('group'), + 'uid_owner' => $qb->expr()->literal('user1'), + 'uid_initiator' => $qb->expr()->literal('user1'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(1), + 'file_target' => $qb->expr()->literal('myTarget1'), + 'permissions' => $qb->expr()->literal(2) + ])->execute(); + $this->assertEquals(1, $stmt); + $id = $qb->getLastInsertId(); + + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + $user2 = $this->getMock('\OCP\IUser'); + $user2->method('getUID')->willReturn('user2'); + $this->userManager->method('get')->will($this->returnValueMap([ + ['user1', $user1], + ['user2', $user2], + ])); + + $group = $this->getMock('\OCP\IGroup'); + $group->method('getGID')->willReturn('group'); + $group->method('inGroup')->with($user2)->willReturn(true); + $this->groupManager->method('get')->with('group')->willReturn($group); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(1); + + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(1)->willReturn([$file]); + + $share = $this->provider->getShareById($id); + + $this->provider->deleteFromSelf($share, 'user2'); + + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(2))) + ->execute(); + + $shares = $stmt->fetchAll(); + $stmt->closeCursor(); + + $this->assertCount(1, $shares); + $share2 = $shares[0]; + $this->assertEquals($id, $share2['parent']); + $this->assertEquals(0, $share2['permissions']); + $this->assertEquals('user2', $share2['share_with']); + } + + public function testDeleteFromSelfGroupAlreadyCustomShare() { + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), + 'share_with' => $qb->expr()->literal('group'), + 'uid_owner' => $qb->expr()->literal('user1'), + 'uid_initiator' => $qb->expr()->literal('user1'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(1), + 'file_target' => $qb->expr()->literal('myTarget1'), + 'permissions' => $qb->expr()->literal(2) + ])->execute(); + $this->assertEquals(1, $stmt); + $id = $qb->getLastInsertId(); + + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(2), + 'share_with' => $qb->expr()->literal('user2'), + 'uid_owner' => $qb->expr()->literal('user1'), + 'uid_initiator' => $qb->expr()->literal('user1'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(1), + 'file_target' => $qb->expr()->literal('myTarget1'), + 'permissions' => $qb->expr()->literal(2), + 'parent' => $qb->expr()->literal($id), + ])->execute(); + $this->assertEquals(1, $stmt); + + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + $user2 = $this->getMock('\OCP\IUser'); + $user2->method('getUID')->willReturn('user2'); + $this->userManager->method('get')->will($this->returnValueMap([ + ['user1', $user1], + ['user2', $user2], + ])); + + $group = $this->getMock('\OCP\IGroup'); + $group->method('getGID')->willReturn('group'); + $group->method('inGroup')->with($user2)->willReturn(true); + $this->groupManager->method('get')->with('group')->willReturn($group); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(1); + + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(1)->willReturn([$file]); + + $share = $this->provider->getShareById($id); + + $this->provider->deleteFromSelf($share, 'user2'); + + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(2))) + ->execute(); + + $shares = $stmt->fetchAll(); + $stmt->closeCursor(); + + $this->assertCount(1, $shares); + $share2 = $shares[0]; + $this->assertEquals($id, $share2['parent']); + $this->assertEquals(0, $share2['permissions']); + $this->assertEquals('user2', $share2['share_with']); + } + + /** + * @expectedException \OC\Share20\Exception\ProviderException + * @expectedExceptionMessage Recipient not in receiving group + */ + public function testDeleteFromSelfGroupUserNotInGroup() { + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), + 'share_with' => $qb->expr()->literal('group'), + 'uid_owner' => $qb->expr()->literal('user1'), + 'uid_initiator' => $qb->expr()->literal('user1'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(1), + 'file_target' => $qb->expr()->literal('myTarget1'), + 'permissions' => $qb->expr()->literal(2) + ])->execute(); + $this->assertEquals(1, $stmt); + $id = $qb->getLastInsertId(); + + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + $user2 = $this->getMock('\OCP\IUser'); + $user2->method('getUID')->willReturn('user2'); + $this->userManager->method('get')->will($this->returnValueMap([ + ['user1', $user1], + ['user2', $user2], + ])); + + $group = $this->getMock('\OCP\IGroup'); + $group->method('getGID')->willReturn('group'); + $group->method('inGroup')->with($user2)->willReturn(false); + $this->groupManager->method('get')->with('group')->willReturn($group); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(1); + + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(1)->willReturn([$file]); + + $share = $this->provider->getShareById($id); + + $this->provider->deleteFromSelf($share, 'user2'); + } + + public function testDeleteFromSelfUser() { + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('user2'), + 'uid_owner' => $qb->expr()->literal('user1'), + 'uid_initiator' => $qb->expr()->literal('user1'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(1), + 'file_target' => $qb->expr()->literal('myTarget1'), + 'permissions' => $qb->expr()->literal(2) + ])->execute(); + $this->assertEquals(1, $stmt); + $id = $qb->getLastInsertId(); + + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + $user2 = $this->getMock('\OCP\IUser'); + $user2->method('getUID')->willReturn('user2'); + $this->userManager->method('get')->will($this->returnValueMap([ + ['user1', $user1], + ['user2', $user2], + ])); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(1); + + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(1)->willReturn([$file]); + + $share = $this->provider->getShareById($id); + + $this->provider->deleteFromSelf($share, 'user2'); + + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) + ->execute(); + + $shares = $stmt->fetchAll(); + $stmt->closeCursor(); + + $this->assertCount(0, $shares); + } + + /** + * @expectedException \OC\Share20\Exception\ProviderException + * @expectedExceptionMessage Recipient does not match + */ + public function testDeleteFromSelfUserNotRecipient() { + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('user2'), + 'uid_owner' => $qb->expr()->literal('user1'), + 'uid_initiator' => $qb->expr()->literal('user1'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(1), + 'file_target' => $qb->expr()->literal('myTarget1'), + 'permissions' => $qb->expr()->literal(2) + ])->execute(); + $this->assertEquals(1, $stmt); + $id = $qb->getLastInsertId(); + + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + $user2 = $this->getMock('\OCP\IUser'); + $user2->method('getUID')->willReturn('user2'); + $user3 = $this->getMock('\OCP\IUser'); + $this->userManager->method('get')->will($this->returnValueMap([ + ['user1', $user1], + ['user2', $user2], + ])); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(1); + + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(1)->willReturn([$file]); + + $share = $this->provider->getShareById($id); + + $this->provider->deleteFromSelf($share, $user3); + } + + /** + * @expectedException \OC\Share20\Exception\ProviderException + * @expectedExceptionMessage Invalid shareType + */ + public function testDeleteFromSelfLink() { + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK), + 'uid_owner' => $qb->expr()->literal('user1'), + 'uid_initiator' => $qb->expr()->literal('user1'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(1), + 'file_target' => $qb->expr()->literal('myTarget1'), + 'permissions' => $qb->expr()->literal(2), + 'token' => $qb->expr()->literal('token'), + ])->execute(); + $this->assertEquals(1, $stmt); + $id = $qb->getLastInsertId(); + + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + $this->userManager->method('get')->will($this->returnValueMap([ + ['user1', $user1], + ])); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(1); + + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->with(1)->willReturn([$file]); + + $share = $this->provider->getShareById($id); + + $this->provider->deleteFromSelf($share, $user1); + } + + public function testUpdateUser() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_USER, 'user0', 'user1', 'user2', + 'file', 42, 'target', 31, null, null); + + $users = []; + for($i = 0; $i < 6; $i++) { + $user = $this->getMock('\OCP\IUser'); + $user->method('getUID')->willReturn('user'.$i); + $users['user'.$i] = $user; + } + + $this->userManager->method('get')->will( + $this->returnCallback(function($userId) use ($users) { + return $users[$userId]; + }) + ); + + $file1 = $this->getMock('\OCP\Files\File'); + $file1->method('getId')->willReturn(42); + $file2 = $this->getMock('\OCP\Files\File'); + $file2->method('getId')->willReturn(43); + + $folder1 = $this->getMock('\OCP\Files\Folder'); + $folder1->method('getById')->with(42)->willReturn([$file1]); + $folder2 = $this->getMock('\OCP\Files\Folder'); + $folder2->method('getById')->with(43)->willReturn([$file2]); + + $this->rootFolder->method('getUserFolder')->will($this->returnValueMap([ + ['user2', $folder1], + ['user5', $folder2], + ])); + + $share = $this->provider->getShareById($id); + + $share->setSharedWith('user3'); + $share->setSharedBy('user4'); + $share->setShareOwner('user5'); + $share->setNode($file2); + $share->setPermissions(1); + + $share2 = $this->provider->update($share); + + $this->assertEquals($id, $share2->getId()); + $this->assertSame('user3', $share2->getSharedWith()); + $this->assertSame('user4', $share2->getSharedBy()); + $this->assertSame('user5', $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + } + + public function testUpdateLink() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_LINK, null, 'user1', 'user2', + 'file', 42, 'target', 31, null, null); + + $users = []; + for($i = 0; $i < 6; $i++) { + $user = $this->getMock('\OCP\IUser'); + $user->method('getUID')->willReturn('user'.$i); + $users['user'.$i] = $user; + } + + $this->userManager->method('get')->will( + $this->returnCallback(function($userId) use ($users) { + return $users[$userId]; + }) + ); + + $file1 = $this->getMock('\OCP\Files\File'); + $file1->method('getId')->willReturn(42); + $file2 = $this->getMock('\OCP\Files\File'); + $file2->method('getId')->willReturn(43); + + $folder1 = $this->getMock('\OCP\Files\Folder'); + $folder1->method('getById')->with(42)->willReturn([$file1]); + $folder2 = $this->getMock('\OCP\Files\Folder'); + $folder2->method('getById')->with(43)->willReturn([$file2]); + + $this->rootFolder->method('getUserFolder')->will($this->returnValueMap([ + ['user2', $folder1], + ['user5', $folder2], + ])); + + $share = $this->provider->getShareById($id); + + $share->setPassword('password'); + $share->setSharedBy('user4'); + $share->setShareOwner('user5'); + $share->setNode($file2); + $share->setPermissions(1); + + $share2 = $this->provider->update($share); + + $this->assertEquals($id, $share2->getId()); + $this->assertEquals('password', $share->getPassword()); + $this->assertSame('user4', $share2->getSharedBy()); + $this->assertSame('user5', $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + } + + public function testUpdateLinkRemovePassword() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_LINK, 'foo', 'user1', 'user2', + 'file', 42, 'target', 31, null, null); + + $users = []; + for($i = 0; $i < 6; $i++) { + $user = $this->getMock('\OCP\IUser'); + $user->method('getUID')->willReturn('user'.$i); + $users['user'.$i] = $user; + } + + $this->userManager->method('get')->will( + $this->returnCallback(function($userId) use ($users) { + return $users[$userId]; + }) + ); + + $file1 = $this->getMock('\OCP\Files\File'); + $file1->method('getId')->willReturn(42); + $file2 = $this->getMock('\OCP\Files\File'); + $file2->method('getId')->willReturn(43); + + $folder1 = $this->getMock('\OCP\Files\Folder'); + $folder1->method('getById')->with(42)->willReturn([$file1]); + $folder2 = $this->getMock('\OCP\Files\Folder'); + $folder2->method('getById')->with(43)->willReturn([$file2]); + + $this->rootFolder->method('getUserFolder')->will($this->returnValueMap([ + ['user2', $folder1], + ['user5', $folder2], + ])); + + $share = $this->provider->getShareById($id); + + $share->setPassword(null); + $share->setSharedBy('user4'); + $share->setShareOwner('user5'); + $share->setNode($file2); + $share->setPermissions(1); + + $share2 = $this->provider->update($share); + + $this->assertEquals($id, $share2->getId()); + $this->assertEquals(null, $share->getPassword()); + $this->assertSame('user4', $share2->getSharedBy()); + $this->assertSame('user5', $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + } + + public function testUpdateGroupNoSub() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_GROUP, 'group0', 'user1', 'user2', + 'file', 42, 'target', 31, null, null); + + $users = []; + for($i = 0; $i < 6; $i++) { + $user = $this->getMock('\OCP\IUser'); + $user->method('getUID')->willReturn('user'.$i); + $users['user'.$i] = $user; + } + + $this->userManager->method('get')->will( + $this->returnCallback(function($userId) use ($users) { + return $users[$userId]; + }) + ); + + $groups = []; + for($i = 0; $i < 2; $i++) { + $group = $this->getMock('\OCP\IGroup'); + $group->method('getGID')->willReturn('group'.$i); + $groups['group'.$i] = $group; + } + + $this->groupManager->method('get')->will( + $this->returnCallback(function($groupId) use ($groups) { + return $groups[$groupId]; + }) + ); + + $file1 = $this->getMock('\OCP\Files\File'); + $file1->method('getId')->willReturn(42); + $file2 = $this->getMock('\OCP\Files\File'); + $file2->method('getId')->willReturn(43); + + $folder1 = $this->getMock('\OCP\Files\Folder'); + $folder1->method('getById')->with(42)->willReturn([$file1]); + $folder2 = $this->getMock('\OCP\Files\Folder'); + $folder2->method('getById')->with(43)->willReturn([$file2]); + + $this->rootFolder->method('getUserFolder')->will($this->returnValueMap([ + ['user2', $folder1], + ['user5', $folder2], + ])); + + $share = $this->provider->getShareById($id); + + $share->setSharedWith('group0'); + $share->setSharedBy('user4'); + $share->setShareOwner('user5'); + $share->setNode($file2); + $share->setPermissions(1); + + $share2 = $this->provider->update($share); + + $this->assertEquals($id, $share2->getId()); + // Group shares do not allow updating the recipient + $this->assertSame('group0', $share2->getSharedWith()); + $this->assertSame('user4', $share2->getSharedBy()); + $this->assertSame('user5', $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + } + + public function testUpdateGroupSubShares() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_GROUP, 'group0', 'user1', 'user2', + 'file', 42, 'target', 31, null, null); + + $id2 = $this->addShareToDB(2, 'user0', 'user1', 'user2', + 'file', 42, 'mytarget', 31, null, null, $id); + + $id3 = $this->addShareToDB(2, 'user3', 'user1', 'user2', + 'file', 42, 'mytarget2', 0, null, null, $id); + + $users = []; + for($i = 0; $i < 6; $i++) { + $user = $this->getMock('\OCP\IUser'); + $user->method('getUID')->willReturn('user'.$i); + $users['user'.$i] = $user; + } + + $this->userManager->method('get')->will( + $this->returnCallback(function($userId) use ($users) { + return $users[$userId]; + }) + ); + + $groups = []; + for($i = 0; $i < 2; $i++) { + $group = $this->getMock('\OCP\IGroup'); + $group->method('getGID')->willReturn('group'.$i); + $groups['group'.$i] = $group; + } + + $this->groupManager->method('get')->will( + $this->returnCallback(function($groupId) use ($groups) { + return $groups[$groupId]; + }) + ); + + $file1 = $this->getMock('\OCP\Files\File'); + $file1->method('getId')->willReturn(42); + $file2 = $this->getMock('\OCP\Files\File'); + $file2->method('getId')->willReturn(43); + + $folder1 = $this->getMock('\OCP\Files\Folder'); + $folder1->method('getById')->with(42)->willReturn([$file1]); + $folder2 = $this->getMock('\OCP\Files\Folder'); + $folder2->method('getById')->with(43)->willReturn([$file2]); + + $this->rootFolder->method('getUserFolder')->will($this->returnValueMap([ + ['user2', $folder1], + ['user5', $folder2], + ])); + + $share = $this->provider->getShareById($id); + + $share->setSharedWith('group0'); + $share->setSharedBy('user4'); + $share->setShareOwner('user5'); + $share->setNode($file2); + $share->setPermissions(1); + + $share2 = $this->provider->update($share); + + $this->assertEquals($id, $share2->getId()); + // Group shares do not allow updating the recipient + $this->assertSame('group0', $share2->getSharedWith()); + $this->assertSame('user4', $share2->getSharedBy()); + $this->assertSame('user5', $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('parent', $qb->createNamedParameter($id))) + ->orderBy('id') + ->execute(); + + $shares = $stmt->fetchAll(); + + $this->assertSame('user0', $shares[0]['share_with']); + $this->assertSame('user4', $shares[0]['uid_initiator']); + $this->assertSame('user5', $shares[0]['uid_owner']); + $this->assertSame(1, (int)$shares[0]['permissions']); + + $this->assertSame('user3', $shares[1]['share_with']); + $this->assertSame('user4', $shares[1]['uid_initiator']); + $this->assertSame('user5', $shares[1]['uid_owner']); + $this->assertSame(0, (int)$shares[1]['permissions']); + + + $stmt->closeCursor(); + } + + public function testMoveUserShare() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_USER, 'user0', 'user1', 'user1', 'file', + 42, 'mytaret', 31, null, null); + + $user0 = $this->getMock('\OCP\IUser'); + $user0->method('getUID')->willReturn('user0'); + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + + $this->userManager->method('get')->will($this->returnValueMap([ + ['user0', $user0], + ['user1', $user1], + ])); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(42); + + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->willReturn([$file]); + + $share = $this->provider->getShareById($id, null); + + $share->setTarget('/newTarget'); + $this->provider->move($share, $user0); + + $share = $this->provider->getShareById($id, null); + $this->assertSame('/newTarget', $share->getTarget()); + } + + public function testMoveGroupShare() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_GROUP, 'group0', 'user1', 'user1', 'file', + 42, 'mytaret', 31, null, null); + + $user0 = $this->getMock('\OCP\IUser'); + $user0->method('getUID')->willReturn('user0'); + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + + $group0 = $this->getMock('\OCP\IGroup'); + $group0->method('getGID')->willReturn('group0'); + $group0->method('inGroup')->with($user0)->willReturn(true); + + $this->groupManager->method('get')->with('group0')->willReturn($group0); + + $this->userManager->method('get')->will($this->returnValueMap([ + ['user0', $user0], + ['user1', $user1], + ])); + + $folder = $this->getMock('\OCP\Files\Folder'); + $folder->method('getId')->willReturn(42); + + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->willReturn([$folder]); + + $share = $this->provider->getShareById($id, 'user0'); + + $share->setTarget('/newTarget'); + $this->provider->move($share, 'user0'); + + $share = $this->provider->getShareById($id, 'user0'); + $this->assertSame('/newTarget', $share->getTarget()); + + $share->setTarget('/ultraNewTarget'); + $this->provider->move($share, 'user0'); + + $share = $this->provider->getShareById($id, 'user0'); + $this->assertSame('/ultraNewTarget', $share->getTarget()); + } + + public function dataDeleteUser() { + return [ + [\OCP\Share::SHARE_TYPE_USER, 'a', 'b', 'c', 'a', true], + [\OCP\Share::SHARE_TYPE_USER, 'a', 'b', 'c', 'b', false], + [\OCP\Share::SHARE_TYPE_USER, 'a', 'b', 'c', 'c', true], + [\OCP\Share::SHARE_TYPE_USER, 'a', 'b', 'c', 'd', false], + [\OCP\Share::SHARE_TYPE_GROUP, 'a', 'b', 'c', 'a', true], + [\OCP\Share::SHARE_TYPE_GROUP, 'a', 'b', 'c', 'b', false], + // The group c is still valid but user c is deleted so group share stays + [\OCP\Share::SHARE_TYPE_GROUP, 'a', 'b', 'c', 'c', false], + [\OCP\Share::SHARE_TYPE_GROUP, 'a', 'b', 'c', 'd', false], + [\OCP\Share::SHARE_TYPE_LINK, 'a', 'b', 'c', 'a', true], + // To avoid invisible link shares delete initiated link shares as well (see #22327) + [\OCP\Share::SHARE_TYPE_LINK, 'a', 'b', 'c', 'b', true], + [\OCP\Share::SHARE_TYPE_LINK, 'a', 'b', 'c', 'c', false], + [\OCP\Share::SHARE_TYPE_LINK, 'a', 'b', 'c', 'd', false], + ]; + } + + /** + * @dataProvider dataDeleteUser + * + * @param int $type The shareType (user/group/link) + * @param string $owner The owner of the share (uid) + * @param string $initiator The initiator of the share (uid) + * @param string $recipient The recipient of the share (uid/gid/pass) + * @param string $deletedUser The user that is deleted + * @param bool $rowDeleted Is the row deleted in this setup + */ + public function testDeleteUser($type, $owner, $initiator, $recipient, $deletedUser, $rowDeleted) { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->setValue('share_type', $qb->createNamedParameter($type)) + ->setValue('uid_owner', $qb->createNamedParameter($owner)) + ->setValue('uid_initiator', $qb->createNamedParameter($initiator)) + ->setValue('share_with', $qb->createNamedParameter($recipient)) + ->setValue('item_type', $qb->createNamedParameter('file')) + ->setValue('item_source', $qb->createNamedParameter(42)) + ->setValue('file_source', $qb->createNamedParameter(42)) + ->execute(); + + $id = $qb->getLastInsertId(); + + $this->provider->userDeleted($deletedUser, $type); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->select('*') + ->from('share') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id)) + ); + $cursor = $qb->execute(); + $data = $cursor->fetchAll(); + $cursor->closeCursor(); + + $this->assertCount($rowDeleted ? 0 : 1, $data); + } + + public function dataDeleteUserGroup() { + return [ + ['a', 'b', 'c', 'a', true, true], + ['a', 'b', 'c', 'b', false, false], + ['a', 'b', 'c', 'c', false, true], + ['a', 'b', 'c', 'd', false, false], + ]; + } + + /** + * @dataProvider dataDeleteUserGroup + * + * @param string $owner The owner of the share (uid) + * @param string $initiator The initiator of the share (uid) + * @param string $recipient The recipient of the usergroup share (uid) + * @param string $deletedUser The user that is deleted + * @param bool $groupShareDeleted + * @param bool $userGroupShareDeleted + */ + public function testDeleteUserGroup($owner, $initiator, $recipient, $deletedUser, $groupShareDeleted, $userGroupShareDeleted) { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)) + ->setValue('uid_owner', $qb->createNamedParameter($owner)) + ->setValue('uid_initiator', $qb->createNamedParameter($initiator)) + ->setValue('share_with', $qb->createNamedParameter('group')) + ->setValue('item_type', $qb->createNamedParameter('file')) + ->setValue('item_source', $qb->createNamedParameter(42)) + ->setValue('file_source', $qb->createNamedParameter(42)) + ->execute(); + $groupId = $qb->getLastInsertId(); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->setValue('share_type', $qb->createNamedParameter(2)) + ->setValue('uid_owner', $qb->createNamedParameter($owner)) + ->setValue('uid_initiator', $qb->createNamedParameter($initiator)) + ->setValue('share_with', $qb->createNamedParameter($recipient)) + ->setValue('item_type', $qb->createNamedParameter('file')) + ->setValue('item_source', $qb->createNamedParameter(42)) + ->setValue('file_source', $qb->createNamedParameter(42)) + ->execute(); + $userGroupId = $qb->getLastInsertId(); + + $this->provider->userDeleted($deletedUser, \OCP\Share::SHARE_TYPE_GROUP); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->select('*') + ->from('share') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($userGroupId)) + ); + $cursor = $qb->execute(); + $data = $cursor->fetchAll(); + $cursor->closeCursor(); + $this->assertCount($userGroupShareDeleted ? 0 : 1, $data); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->select('*') + ->from('share') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($groupId)) + ); + $cursor = $qb->execute(); + $data = $cursor->fetchAll(); + $cursor->closeCursor(); + $this->assertCount($groupShareDeleted ? 0 : 1, $data); + } + + public function dataGroupDeleted() { + return [ + [ + [ + 'type' => \OCP\Share::SHARE_TYPE_USER, + 'recipient' => 'user', + 'children' => [] + ], 'group', false + ], + [ + [ + 'type' => \OCP\Share::SHARE_TYPE_USER, + 'recipient' => 'user', + 'children' => [] + ], 'user', false + ], + [ + [ + 'type' => \OCP\Share::SHARE_TYPE_LINK, + 'recipient' => 'user', + 'children' => [] + ], 'group', false + ], + [ + [ + 'type' => \OCP\Share::SHARE_TYPE_GROUP, + 'recipient' => 'group1', + 'children' => [ + 'foo', + 'bar' + ] + ], 'group2', false + ], + [ + [ + 'type' => \OCP\Share::SHARE_TYPE_GROUP, + 'recipient' => 'group1', + 'children' => [ + 'foo', + 'bar' + ] + ], 'group1', true + ], + ]; + } + + /** + * @dataProvider dataGroupDeleted + * + * @param $shares + * @param $groupToDelete + * @param $shouldBeDeleted + */ + public function testGroupDeleted($shares, $groupToDelete, $shouldBeDeleted) { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->setValue('share_type', $qb->createNamedParameter($shares['type'])) + ->setValue('uid_owner', $qb->createNamedParameter('owner')) + ->setValue('uid_initiator', $qb->createNamedParameter('initiator')) + ->setValue('share_with', $qb->createNamedParameter($shares['recipient'])) + ->setValue('item_type', $qb->createNamedParameter('file')) + ->setValue('item_source', $qb->createNamedParameter(42)) + ->setValue('file_source', $qb->createNamedParameter(42)) + ->execute(); + $ids = [$qb->getLastInsertId()]; + + foreach ($shares['children'] as $child) { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->setValue('share_type', $qb->createNamedParameter(2)) + ->setValue('uid_owner', $qb->createNamedParameter('owner')) + ->setValue('uid_initiator', $qb->createNamedParameter('initiator')) + ->setValue('share_with', $qb->createNamedParameter($child)) + ->setValue('item_type', $qb->createNamedParameter('file')) + ->setValue('item_source', $qb->createNamedParameter(42)) + ->setValue('file_source', $qb->createNamedParameter(42)) + ->setValue('parent', $qb->createNamedParameter($ids[0])) + ->execute(); + $ids[] = $qb->getLastInsertId(); + } + + $this->provider->groupDeleted($groupToDelete); + + $qb = $this->dbConn->getQueryBuilder(); + $cursor = $qb->select('*') + ->from('share') + ->where($qb->expr()->in('id', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY))) + ->execute(); + $data = $cursor->fetchAll(); + $cursor->closeCursor(); + + $this->assertCount($shouldBeDeleted ? 0 : count($ids), $data); + } + + public function dataUserDeletedFromGroup() { + return [ + ['group1', 'user1', true], + ['group1', 'user2', false], + ['group2', 'user1', false], + ]; + } + + /** + * Given a group share with 'group1' + * And a user specific group share with 'user1'. + * User $user is deleted from group $gid. + * + * @dataProvider dataUserDeletedFromGroup + * + * @param string $group + * @param string $user + * @param bool $toDelete + */ + public function testUserDeletedFromGroup($group, $user, $toDelete) { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)) + ->setValue('uid_owner', $qb->createNamedParameter('owner')) + ->setValue('uid_initiator', $qb->createNamedParameter('initiator')) + ->setValue('share_with', $qb->createNamedParameter('group1')) + ->setValue('item_type', $qb->createNamedParameter('file')) + ->setValue('item_source', $qb->createNamedParameter(42)) + ->setValue('file_source', $qb->createNamedParameter(42)); + $qb->execute(); + $id1 = $qb->getLastInsertId(); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->setValue('share_type', $qb->createNamedParameter(2)) + ->setValue('uid_owner', $qb->createNamedParameter('owner')) + ->setValue('uid_initiator', $qb->createNamedParameter('initiator')) + ->setValue('share_with', $qb->createNamedParameter('user1')) + ->setValue('item_type', $qb->createNamedParameter('file')) + ->setValue('item_source', $qb->createNamedParameter(42)) + ->setValue('file_source', $qb->createNamedParameter(42)) + ->setValue('parent', $qb->createNamedParameter($id1)); + $qb->execute(); + $id2 = $qb->getLastInsertId(); + + $this->provider->userDeletedFromGroup($user, $group); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id2))); + $cursor = $qb->execute(); + $data = $cursor->fetchAll(); + $cursor->closeCursor(); + + $this->assertCount($toDelete ? 0 : 1, $data); + } +} diff --git a/tests/lib/Share20/ManagerTest.php b/tests/lib/Share20/ManagerTest.php new file mode 100644 index 00000000000..7d79150449c --- /dev/null +++ b/tests/lib/Share20/ManagerTest.php @@ -0,0 +1,2570 @@ +<?php +/** + * @author Roeland Jago Douma <rullzer@owncloud.com> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ +namespace Test\Share20; + +use OCP\Files\IRootFolder; +use OCP\IUserManager; +use OCP\Share\Exceptions\ShareNotFound; +use OCP\Share\IProviderFactory; +use OCP\Share\IShare; +use OC\Share20\Manager; +use OC\Share20\Exception; + +use OC\Share20\Share; +use OCP\IL10N; +use OCP\ILogger; +use OCP\IConfig; +use OCP\Share\IShareProvider; +use OCP\Security\ISecureRandom; +use OCP\Security\IHasher; +use OCP\Files\Mount\IMountManager; +use OCP\IGroupManager; + +/** + * Class ManagerTest + * + * @package Test\Share20 + * @group DB + */ +class ManagerTest extends \Test\TestCase { + + /** @var Manager */ + protected $manager; + /** @var ILogger */ + protected $logger; + /** @var IConfig */ + protected $config; + /** @var ISecureRandom */ + protected $secureRandom; + /** @var IHasher */ + protected $hasher; + /** @var IShareProvider | \PHPUnit_Framework_MockObject_MockObject */ + protected $defaultProvider; + /** @var IMountManager */ + protected $mountManager; + /** @var IGroupManager */ + protected $groupManager; + /** @var IL10N */ + protected $l; + /** @var DummyFactory */ + protected $factory; + /** @var IUserManager */ + protected $userManager; + /** @var IRootFolder | \PHPUnit_Framework_MockObject_MockObject */ + protected $rootFolder; + + public function setUp() { + + $this->logger = $this->getMock('\OCP\ILogger'); + $this->config = $this->getMock('\OCP\IConfig'); + $this->secureRandom = $this->getMock('\OCP\Security\ISecureRandom'); + $this->hasher = $this->getMock('\OCP\Security\IHasher'); + $this->mountManager = $this->getMock('\OCP\Files\Mount\IMountManager'); + $this->groupManager = $this->getMock('\OCP\IGroupManager'); + $this->userManager = $this->getMock('\OCP\IUserManager'); + $this->rootFolder = $this->getMock('\OCP\Files\IRootFolder'); + + $this->l = $this->getMock('\OCP\IL10N'); + $this->l->method('t') + ->will($this->returnCallback(function($text, $parameters = []) { + return vsprintf($text, $parameters); + })); + + $this->factory = new DummyFactory(\OC::$server); + + $this->manager = new Manager( + $this->logger, + $this->config, + $this->secureRandom, + $this->hasher, + $this->mountManager, + $this->groupManager, + $this->l, + $this->factory, + $this->userManager, + $this->rootFolder + ); + + $this->defaultProvider = $this->getMockBuilder('\OC\Share20\DefaultShareProvider') + ->disableOriginalConstructor() + ->getMock(); + $this->defaultProvider->method('identifier')->willReturn('default'); + $this->factory->setProvider($this->defaultProvider); + + + } + + /** + * @return \PHPUnit_Framework_MockObject_MockBuilder + */ + private function createManagerMock() { + return $this->getMockBuilder('\OC\Share20\Manager') + ->setConstructorArgs([ + $this->logger, + $this->config, + $this->secureRandom, + $this->hasher, + $this->mountManager, + $this->groupManager, + $this->l, + $this->factory, + $this->userManager, + $this->rootFolder + ]); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testDeleteNoShareId() { + $share = $this->manager->newShare(); + + $this->manager->deleteShare($share); + } + + public function dataTestDelete() { + $user = $this->getMock('\OCP\IUser'); + $user->method('getUID')->willReturn('sharedWithUser'); + + $group = $this->getMock('\OCP\IGroup'); + $group->method('getGID')->willReturn('sharedWithGroup'); + + return [ + [\OCP\Share::SHARE_TYPE_USER, 'sharedWithUser'], + [\OCP\Share::SHARE_TYPE_GROUP, 'sharedWithGroup'], + [\OCP\Share::SHARE_TYPE_LINK, ''], + [\OCP\Share::SHARE_TYPE_REMOTE, 'foo@bar.com'], + ]; + } + + /** + * @dataProvider dataTestDelete + */ + public function testDelete($shareType, $sharedWith) { + $manager = $this->createManagerMock() + ->setMethods(['getShareById', 'deleteChildren']) + ->getMock(); + + $path = $this->getMock('\OCP\Files\File'); + $path->method('getId')->willReturn(1); + + $share = $this->manager->newShare(); + $share->setId(42) + ->setProviderId('prov') + ->setShareType($shareType) + ->setSharedWith($sharedWith) + ->setSharedBy('sharedBy') + ->setNode($path) + ->setTarget('myTarget'); + + $manager->expects($this->once())->method('deleteChildren')->with($share); + + $this->defaultProvider + ->expects($this->once()) + ->method('delete') + ->with($share); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['pre', 'post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'pre_unshare', $hookListner, 'pre'); + \OCP\Util::connectHook('OCP\Share', 'post_unshare', $hookListner, 'post'); + + $hookListnerExpectsPre = [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => $shareType, + 'shareWith' => $sharedWith, + 'itemparent' => null, + 'uidOwner' => 'sharedBy', + 'fileSource' => 1, + 'fileTarget' => 'myTarget', + ]; + + $hookListnerExpectsPost = [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => $shareType, + 'shareWith' => $sharedWith, + 'itemparent' => null, + 'uidOwner' => 'sharedBy', + 'fileSource' => 1, + 'fileTarget' => 'myTarget', + 'deletedShares' => [ + [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => $shareType, + 'shareWith' => $sharedWith, + 'itemparent' => null, + 'uidOwner' => 'sharedBy', + 'fileSource' => 1, + 'fileTarget' => 'myTarget', + ], + ], + ]; + + + $hookListner + ->expects($this->exactly(1)) + ->method('pre') + ->with($hookListnerExpectsPre); + $hookListner + ->expects($this->exactly(1)) + ->method('post') + ->with($hookListnerExpectsPost); + + $manager->deleteShare($share); + } + + public function testDeleteLazyShare() { + $manager = $this->createManagerMock() + ->setMethods(['getShareById', 'deleteChildren']) + ->getMock(); + + $share = $this->manager->newShare(); + $share->setId(42) + ->setProviderId('prov') + ->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setSharedWith('sharedWith') + ->setSharedBy('sharedBy') + ->setShareOwner('shareOwner') + ->setTarget('myTarget') + ->setNodeId(1) + ->setNodeType('file'); + + $this->rootFolder->expects($this->never())->method($this->anything()); + + $manager->expects($this->once())->method('deleteChildren')->with($share); + + $this->defaultProvider + ->expects($this->once()) + ->method('delete') + ->with($share); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['pre', 'post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'pre_unshare', $hookListner, 'pre'); + \OCP\Util::connectHook('OCP\Share', 'post_unshare', $hookListner, 'post'); + + $hookListnerExpectsPre = [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_USER, + 'shareWith' => 'sharedWith', + 'itemparent' => null, + 'uidOwner' => 'sharedBy', + 'fileSource' => 1, + 'fileTarget' => 'myTarget', + ]; + + $hookListnerExpectsPost = [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_USER, + 'shareWith' => 'sharedWith', + 'itemparent' => null, + 'uidOwner' => 'sharedBy', + 'fileSource' => 1, + 'fileTarget' => 'myTarget', + 'deletedShares' => [ + [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_USER, + 'shareWith' => 'sharedWith', + 'itemparent' => null, + 'uidOwner' => 'sharedBy', + 'fileSource' => 1, + 'fileTarget' => 'myTarget', + ], + ], + ]; + + + $hookListner + ->expects($this->exactly(1)) + ->method('pre') + ->with($hookListnerExpectsPre); + $hookListner + ->expects($this->exactly(1)) + ->method('post') + ->with($hookListnerExpectsPost); + + $manager->deleteShare($share); + } + + public function testDeleteNested() { + $manager = $this->createManagerMock() + ->setMethods(['getShareById']) + ->getMock(); + + $path = $this->getMock('\OCP\Files\File'); + $path->method('getId')->willReturn(1); + + $share1 = $this->manager->newShare(); + $share1->setId(42) + ->setProviderId('prov') + ->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setSharedWith('sharedWith1') + ->setSharedBy('sharedBy1') + ->setNode($path) + ->setTarget('myTarget1'); + + $share2 = $this->manager->newShare(); + $share2->setId(43) + ->setProviderId('prov') + ->setShareType(\OCP\Share::SHARE_TYPE_GROUP) + ->setSharedWith('sharedWith2') + ->setSharedBy('sharedBy2') + ->setNode($path) + ->setTarget('myTarget2') + ->setParent(42); + + $share3 = $this->manager->newShare(); + $share3->setId(44) + ->setProviderId('prov') + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setSharedBy('sharedBy3') + ->setNode($path) + ->setTarget('myTarget3') + ->setParent(43); + + $this->defaultProvider + ->method('getChildren') + ->will($this->returnValueMap([ + [$share1, [$share2]], + [$share2, [$share3]], + [$share3, []], + ])); + + $this->defaultProvider + ->method('delete') + ->withConsecutive($share3, $share2, $share1); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['pre', 'post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'pre_unshare', $hookListner, 'pre'); + \OCP\Util::connectHook('OCP\Share', 'post_unshare', $hookListner, 'post'); + + $hookListnerExpectsPre = [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_USER, + 'shareWith' => 'sharedWith1', + 'itemparent' => null, + 'uidOwner' => 'sharedBy1', + 'fileSource' => 1, + 'fileTarget' => 'myTarget1', + ]; + + $hookListnerExpectsPost = [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_USER, + 'shareWith' => 'sharedWith1', + 'itemparent' => null, + 'uidOwner' => 'sharedBy1', + 'fileSource' => 1, + 'fileTarget' => 'myTarget1', + 'deletedShares' => [ + [ + 'id' => 44, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_LINK, + 'shareWith' => '', + 'itemparent' => 43, + 'uidOwner' => 'sharedBy3', + 'fileSource' => 1, + 'fileTarget' => 'myTarget3', + ], + [ + 'id' => 43, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_GROUP, + 'shareWith' => 'sharedWith2', + 'itemparent' => 42, + 'uidOwner' => 'sharedBy2', + 'fileSource' => 1, + 'fileTarget' => 'myTarget2', + ], + [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_USER, + 'shareWith' => 'sharedWith1', + 'itemparent' => null, + 'uidOwner' => 'sharedBy1', + 'fileSource' => 1, + 'fileTarget' => 'myTarget1', + ], + ], + ]; + + $hookListner + ->expects($this->exactly(1)) + ->method('pre') + ->with($hookListnerExpectsPre); + $hookListner + ->expects($this->exactly(1)) + ->method('post') + ->with($hookListnerExpectsPost); + + $manager->deleteShare($share1); + } + + public function testDeleteChildren() { + $manager = $this->createManagerMock() + ->setMethods(['deleteShare']) + ->getMock(); + + $share = $this->getMock('\OCP\Share\IShare'); + $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); + + $child1 = $this->getMock('\OCP\Share\IShare'); + $child1->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); + $child2 = $this->getMock('\OCP\Share\IShare'); + $child2->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); + $child3 = $this->getMock('\OCP\Share\IShare'); + $child3->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); + + $shares = [ + $child1, + $child2, + $child3, + ]; + + $this->defaultProvider + ->expects($this->exactly(4)) + ->method('getChildren') + ->will($this->returnCallback(function($_share) use ($share, $shares) { + if ($_share === $share) { + return $shares; + } + return []; + })); + + $this->defaultProvider + ->expects($this->exactly(3)) + ->method('delete') + ->withConsecutive($child1, $child2, $child3); + + $result = $this->invokePrivate($manager, 'deleteChildren', [$share]); + $this->assertSame($shares, $result); + } + + public function testGetShareById() { + $share = $this->getMock('\OCP\Share\IShare'); + + $this->defaultProvider + ->expects($this->once()) + ->method('getShareById') + ->with(42) + ->willReturn($share); + + $this->assertEquals($share, $this->manager->getShareById('default:42')); + } + + /** + * @expectedException \OCP\Share\Exceptions\ShareNotFound + */ + public function testGetExpiredShareById() { + $manager = $this->createManagerMock() + ->setMethods(['deleteShare']) + ->getMock(); + + $date = new \DateTime(); + $date->setTime(0,0,0); + + $share = $this->manager->newShare(); + $share->setExpirationDate($date) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK); + + $this->defaultProvider->expects($this->once()) + ->method('getShareById') + ->with('42') + ->willReturn($share); + + $manager->expects($this->once()) + ->method('deleteShare') + ->with($share); + + $manager->getShareById('default:42'); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage Passwords are enforced for link shares + */ + public function testVerifyPasswordNullButEnforced() { + $this->config->method('getAppValue')->will($this->returnValueMap([ + ['core', 'shareapi_enforce_links_password', 'no', 'yes'], + ])); + + $this->invokePrivate($this->manager, 'verifyPassword', [null]); + } + + public function testVerifyPasswordNull() { + $this->config->method('getAppValue')->will($this->returnValueMap([ + ['core', 'shareapi_enforce_links_password', 'no', 'no'], + ])); + + $result = $this->invokePrivate($this->manager, 'verifyPassword', [null]); + $this->assertNull($result); + } + + public function testVerifyPasswordHook() { + $this->config->method('getAppValue')->will($this->returnValueMap([ + ['core', 'shareapi_enforce_links_password', 'no', 'no'], + ])); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['listner'])->getMock(); + \OCP\Util::connectHook('\OC\Share', 'verifyPassword', $hookListner, 'listner'); + + $hookListner->expects($this->once()) + ->method('listner') + ->with([ + 'password' => 'password', + 'accepted' => true, + 'message' => '' + ]); + + $result = $this->invokePrivate($this->manager, 'verifyPassword', ['password']); + $this->assertNull($result); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage password not accepted + */ + public function testVerifyPasswordHookFails() { + $this->config->method('getAppValue')->will($this->returnValueMap([ + ['core', 'shareapi_enforce_links_password', 'no', 'no'], + ])); + + $dummy = new DummyPassword(); + \OCP\Util::connectHook('\OC\Share', 'verifyPassword', $dummy, 'listner'); + $this->invokePrivate($this->manager, 'verifyPassword', ['password']); + } + + public function createShare($id, $type, $path, $sharedWith, $sharedBy, $shareOwner, + $permissions, $expireDate = null, $password = null) { + $share = $this->getMock('\OCP\Share\IShare'); + + $share->method('getShareType')->willReturn($type); + $share->method('getSharedWith')->willReturn($sharedWith); + $share->method('getSharedBy')->willReturn($sharedBy); + $share->method('getShareOwner')->willReturn($shareOwner); + $share->method('getNode')->willReturn($path); + $share->method('getPermissions')->willReturn($permissions); + $share->method('getExpirationDate')->willReturn($expireDate); + $share->method('getPassword')->willReturn($password); + + return $share; + } + + public function dataGeneralChecks() { + $user0 = 'user0'; + $user2 = 'user1'; + $group0 = 'group0'; + + $file = $this->getMock('\OCP\Files\File'); + $node = $this->getMock('\OCP\Files\Node'); + + $data = [ + [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $file, null, $user0, $user0, 31, null, null), 'SharedWith is not a valid user', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $file, $group0, $user0, $user0, 31, null, null), 'SharedWith is not a valid user', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $file, 'foo@bar.com', $user0, $user0, 31, null, null), 'SharedWith is not a valid user', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $file, null, $user0, $user0, 31, null, null), 'SharedWith is not a valid group', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $file, $user2, $user0, $user0, 31, null, null), 'SharedWith is not a valid group', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $file, 'foo@bar.com', $user0, $user0, 31, null, null), 'SharedWith is not a valid group', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $file, $user2, $user0, $user0, 31, null, null), 'SharedWith should be empty', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $file, $group0, $user0, $user0, 31, null, null), 'SharedWith should be empty', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $file, 'foo@bar.com', $user0, $user0, 31, null, null), 'SharedWith should be empty', true], + [$this->createShare(null, -1, $file, null, $user0, $user0, 31, null, null), 'unkown share type', true], + + [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $file, $user2, null, $user0, 31, null, null), 'SharedBy should be set', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $file, $group0, null, $user0, 31, null, null), 'SharedBy should be set', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $file, null, null, $user0, 31, null, null), 'SharedBy should be set', true], + + [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $file, $user0, $user0, $user0, 31, null, null), 'Can\'t share with yourself', true], + + [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, null, $user2, $user0, $user0, 31, null, null), 'Path should be set', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, null, $group0, $user0, $user0, 31, null, null), 'Path should be set', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, null, null, $user0, $user0, 31, null, null), 'Path should be set', true], + + [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $node, $user2, $user0, $user0, 31, null, null), 'Path should be either a file or a folder', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $node, $group0, $user0, $user0, 31, null, null), 'Path should be either a file or a folder', true], + [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $node, null, $user0, $user0, 31, null, null), 'Path should be either a file or a folder', true], + ]; + + $nonShareAble = $this->getMock('\OCP\Files\Folder'); + $nonShareAble->method('isShareable')->willReturn(false); + $nonShareAble->method('getPath')->willReturn('path'); + + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $nonShareAble, $user2, $user0, $user0, 31, null, null), 'You are not allowed to share path', true]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $nonShareAble, $group0, $user0, $user0, 31, null, null), 'You are not allowed to share path', true]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $nonShareAble, null, $user0, $user0, 31, null, null), 'You are not allowed to share path', true]; + + $limitedPermssions = $this->getMock('\OCP\Files\File'); + $limitedPermssions->method('isShareable')->willReturn(true); + $limitedPermssions->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_READ); + $limitedPermssions->method('getPath')->willReturn('path'); + + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $limitedPermssions, $user2, $user0, $user0, null, null, null), 'A share requires permissions', true]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $limitedPermssions, $group0, $user0, $user0, null, null, null), 'A share requires permissions', true]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $limitedPermssions, null, $user0, $user0, null, null, null), 'A share requires permissions', true]; + + $mount = $this->getMock('OC\Files\Mount\MoveableMount'); + $limitedPermssions->method('getMountPoint')->willReturn($mount); + + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $limitedPermssions, $user2, $user0, $user0, 31, null, null), 'Cannot increase permissions of path', true]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $limitedPermssions, $group0, $user0, $user0, 17, null, null), 'Cannot increase permissions of path', true]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $limitedPermssions, null, $user0, $user0, 3, null, null), 'Cannot increase permissions of path', true]; + + $nonMoveableMountPermssions = $this->getMock('\OCP\Files\Folder'); + $nonMoveableMountPermssions->method('isShareable')->willReturn(true); + $nonMoveableMountPermssions->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_READ); + $nonMoveableMountPermssions->method('getPath')->willReturn('path'); + + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $nonMoveableMountPermssions, $user2, $user0, $user0, 11, null, null), 'Cannot increase permissions of path', false]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $nonMoveableMountPermssions, $group0, $user0, $user0, 11, null, null), 'Cannot increase permissions of path', false]; + + $rootFolder = $this->getMock('\OCP\Files\Folder'); + $rootFolder->method('isShareable')->willReturn(true); + $rootFolder->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_ALL); + $rootFolder->method('getPath')->willReturn('myrootfolder'); + + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $rootFolder, $user2, $user0, $user0, 30, null, null), 'You can\'t share your root folder', true]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $rootFolder, $group0, $user0, $user0, 2, null, null), 'You can\'t share your root folder', true]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $rootFolder, null, $user0, $user0, 16, null, null), 'You can\'t share your root folder', true]; + + $allPermssions = $this->getMock('\OCP\Files\Folder'); + $allPermssions->method('isShareable')->willReturn(true); + $allPermssions->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_ALL); + + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $allPermssions, $user2, $user0, $user0, 30, null, null), 'Shares need at least read permissions', true]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 2, null, null), 'Shares need at least read permissions', true]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $allPermssions, null, $user0, $user0, 16, null, null), 'Shares need at least read permissions', true]; + + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $allPermssions, $user2, $user0, $user0, 31, null, null), null, false]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 3, null, null), null, false]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $allPermssions, null, $user0, $user0, 17, null, null), null, false]; + + return $data; + } + + /** + * @dataProvider dataGeneralChecks + * + * @param $share + * @param $exceptionMessage + */ + public function testGeneralChecks($share, $exceptionMessage, $exception) { + $thrown = null; + + $this->userManager->method('userExists')->will($this->returnValueMap([ + ['user0', true], + ['user1', true], + ])); + + $this->groupManager->method('groupExists')->will($this->returnValueMap([ + ['group0', true], + ])); + + $userFolder = $this->getMock('\OCP\Files\Folder'); + $userFolder->method('getPath')->willReturn('myrootfolder'); + $this->rootFolder->method('getUserFolder')->willReturn($userFolder); + + + try { + $this->invokePrivate($this->manager, 'generalCreateChecks', [$share]); + $thrown = false; + } catch (\OCP\Share\Exceptions\GenericShareException $e) { + $this->assertEquals($exceptionMessage, $e->getHint()); + $thrown = true; + } catch(\InvalidArgumentException $e) { + $this->assertEquals($exceptionMessage, $e->getMessage()); + $thrown = true; + } + + $this->assertSame($exception, $thrown); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage You can't share your root folder + */ + public function testGeneralCheckShareRoot() { + $thrown = null; + + $this->userManager->method('userExists')->will($this->returnValueMap([ + ['user0', true], + ['user1', true], + ])); + + $userFolder = $this->getMock('\OCP\Files\Folder'); + $userFolder->method('isSubNode')->with($userFolder)->willReturn(false); + $this->rootFolder->method('getUserFolder')->willReturn($userFolder); + + $share = $this->manager->newShare(); + + $share->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setSharedWith('user0') + ->setSharedBy('user1') + ->setNode($userFolder); + + $this->invokePrivate($this->manager, 'generalCreateChecks', [$share]); + } + + /** + * @expectedException \OCP\Share\Exceptions\GenericShareException + * @expectedExceptionMessage Expiration date is in the past + */ + public function testvalidateExpirationDateInPast() { + + // Expire date in the past + $past = new \DateTime(); + $past->sub(new \DateInterval('P1D')); + + $share = $this->manager->newShare(); + $share->setExpirationDate($past); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage Expiration date is enforced + */ + public function testvalidateExpirationDateEnforceButNotSet() { + $share = $this->manager->newShare(); + $share->setProviderId('foo')->setId('bar'); + + $this->config->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_default_expire_date', 'no', 'yes'], + ['core', 'shareapi_enforce_expire_date', 'no', 'yes'], + ])); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + } + + public function testvalidateExpirationDateEnforceButNotEnabledAndNotSet() { + $share = $this->manager->newShare(); + $share->setProviderId('foo')->setId('bar'); + + $this->config->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_enforce_expire_date', 'no', 'yes'], + ])); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + + $this->assertNull($share->getExpirationDate()); + } + + public function testvalidateExpirationDateEnforceButNotSetNewShare() { + $share = $this->manager->newShare(); + + $this->config->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_enforce_expire_date', 'no', 'yes'], + ['core', 'shareapi_expire_after_n_days', '7', '3'], + ['core', 'shareapi_default_expire_date', 'no', 'yes'], + ])); + + $expected = new \DateTime(); + $expected->setTime(0,0,0); + $expected->add(new \DateInterval('P3D')); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + + $this->assertNotNull($share->getExpirationDate()); + $this->assertEquals($expected, $share->getExpirationDate()); + } + + public function testvalidateExpirationDateEnforceToFarIntoFuture() { + // Expire date in the past + $future = new \DateTime(); + $future->add(new \DateInterval('P7D')); + + $share = $this->manager->newShare(); + $share->setExpirationDate($future); + + $this->config->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_enforce_expire_date', 'no', 'yes'], + ['core', 'shareapi_expire_after_n_days', '7', '3'], + ])); + + try { + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + } catch (\OCP\Share\Exceptions\GenericShareException $e) { + $this->assertEquals('Cannot set expiration date more than 3 days in the future', $e->getMessage()); + $this->assertEquals('Cannot set expiration date more than 3 days in the future', $e->getHint()); + $this->assertEquals(404, $e->getCode()); + } + } + + public function testvalidateExpirationDateEnforceValid() { + // Expire date in the past + $future = new \DateTime(); + $future->add(new \DateInterval('P2D')); + $future->setTime(0,0,0); + + $expected = clone $future; + $future->setTime(1,2,3); + + $share = $this->manager->newShare(); + $share->setExpirationDate($future); + + $this->config->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_enforce_expire_date', 'no', 'yes'], + ['core', 'shareapi_expire_after_n_days', '7', '3'], + ])); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock(); + \OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener'); + $hookListner->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($future) { + return $data['expirationDate'] == $future; + })); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + + $this->assertEquals($expected, $share->getExpirationDate()); + } + + public function testvalidateExpirationDateNoDateNoDefaultNull() { + $date = new \DateTime(); + $date->add(new \DateInterval('P5D')); + + $expected = clone $date; + $expected->setTime(0,0,0); + + $share = $this->manager->newShare(); + $share->setExpirationDate($date); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock(); + \OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener'); + $hookListner->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) { + return $data['expirationDate'] == $expected && $data['passwordSet'] === false; + })); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + + $this->assertEquals($expected, $share->getExpirationDate()); + } + + public function testvalidateExpirationDateNoDateNoDefault() { + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock(); + \OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener'); + $hookListner->expects($this->once())->method('listener')->with($this->callback(function ($data) { + return $data['expirationDate'] === null && $data['passwordSet'] === true; + })); + + $share = $this->manager->newShare(); + $share->setPassword('password'); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + + $this->assertNull($share->getExpirationDate()); + } + + public function testvalidateExpirationDateNoDateDefault() { + $future = new \DateTime(); + $future->add(new \DateInterval('P3D')); + $future->setTime(0,0,0); + + $expected = clone $future; + + $share = $this->manager->newShare(); + $share->setExpirationDate($future); + + $this->config->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_default_expire_date', 'no', 'yes'], + ['core', 'shareapi_expire_after_n_days', '7', '3'], + ])); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock(); + \OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener'); + $hookListner->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) { + return $data['expirationDate'] == $expected; + })); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + + $this->assertEquals($expected, $share->getExpirationDate()); + } + + public function testValidateExpirationDateHookModification() { + $nextWeek = new \DateTime(); + $nextWeek->add(new \DateInterval('P7D')); + $nextWeek->setTime(0,0,0); + + $save = clone $nextWeek; + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock(); + \OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener'); + $hookListner->expects($this->once())->method('listener')->will($this->returnCallback(function ($data) { + $data['expirationDate']->sub(new \DateInterval('P2D')); + })); + + $share = $this->manager->newShare(); + $share->setExpirationDate($nextWeek); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + + $save->sub(new \DateInterval('P2D')); + $this->assertEquals($save, $share->getExpirationDate()); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Invalid date! + */ + public function testValidateExpirationDateHookException() { + $nextWeek = new \DateTime(); + $nextWeek->add(new \DateInterval('P7D')); + $nextWeek->setTime(0,0,0); + + $share = $this->manager->newShare(); + $share->setExpirationDate($nextWeek); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock(); + \OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener'); + $hookListner->expects($this->once())->method('listener')->will($this->returnCallback(function ($data) { + $data['accepted'] = false; + $data['message'] = 'Invalid date!'; + })); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + } + + public function testValidateExpirationDateExistingShareNoDefault() { + $share = $this->manager->newShare(); + + $share->setId('42')->setProviderId('foo'); + + $this->config->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_default_expire_date', 'no', 'yes'], + ['core', 'shareapi_expire_after_n_days', '7', '6'], + ])); + + $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]); + + $this->assertEquals(null, $share->getExpirationDate()); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Only sharing with group members is allowed + */ + public function testUserCreateChecksShareWithGroupMembersOnlyDifferentGroups() { + $share = $this->manager->newShare(); + + $sharedBy = $this->getMock('\OCP\IUser'); + $sharedWith = $this->getMock('\OCP\IUser'); + $share->setSharedBy('sharedBy')->setSharedWith('sharedWith'); + + $this->groupManager + ->method('getUserGroupIds') + ->will( + $this->returnValueMap([ + [$sharedBy, ['group1']], + [$sharedWith, ['group2']], + ]) + ); + + $this->userManager->method('get')->will($this->returnValueMap([ + ['sharedBy', $sharedBy], + ['sharedWith', $sharedWith], + ])); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], + ])); + + $this->invokePrivate($this->manager, 'userCreateChecks', [$share]); + } + + public function testUserCreateChecksShareWithGroupMembersOnlySharedGroup() { + $share = $this->manager->newShare(); + + $sharedBy = $this->getMock('\OCP\IUser'); + $sharedWith = $this->getMock('\OCP\IUser'); + $share->setSharedBy('sharedBy')->setSharedWith('sharedWith'); + + $path = $this->getMock('\OCP\Files\Node'); + $share->setNode($path); + + $this->groupManager + ->method('getUserGroupIds') + ->will( + $this->returnValueMap([ + [$sharedBy, ['group1', 'group3']], + [$sharedWith, ['group2', 'group3']], + ]) + ); + + $this->userManager->method('get')->will($this->returnValueMap([ + ['sharedBy', $sharedBy], + ['sharedWith', $sharedWith], + ])); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], + ])); + + $this->defaultProvider + ->method('getSharesByPath') + ->with($path) + ->willReturn([]); + + $this->invokePrivate($this->manager, 'userCreateChecks', [$share]); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Path already shared with this user + */ + public function testUserCreateChecksIdenticalShareExists() { + $share = $this->manager->newShare(); + $share2 = $this->manager->newShare(); + + $sharedWith = $this->getMock('\OCP\IUser'); + $path = $this->getMock('\OCP\Files\Node'); + + $share->setSharedWith('sharedWith')->setNode($path) + ->setProviderId('foo')->setId('bar'); + + $share2->setSharedWith('sharedWith')->setNode($path) + ->setProviderId('foo')->setId('baz'); + + $this->defaultProvider + ->method('getSharesByPath') + ->with($path) + ->willReturn([$share2]); + + $this->invokePrivate($this->manager, 'userCreateChecks', [$share]); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Path already shared with this user + */ + public function testUserCreateChecksIdenticalPathSharedViaGroup() { + $share = $this->manager->newShare(); + + $sharedWith = $this->getMock('\OCP\IUser'); + $sharedWith->method('getUID')->willReturn('sharedWith'); + + $this->userManager->method('get')->with('sharedWith')->willReturn($sharedWith); + + $path = $this->getMock('\OCP\Files\Node'); + + $share->setSharedWith('sharedWith') + ->setNode($path) + ->setShareOwner('shareOwner') + ->setProviderId('foo') + ->setId('bar'); + + $share2 = $this->manager->newShare(); + $share2->setShareType(\OCP\Share::SHARE_TYPE_GROUP) + ->setShareOwner('shareOwner2') + ->setProviderId('foo') + ->setId('baz') + ->setSharedWith('group'); + + $group = $this->getMock('\OCP\IGroup'); + $group->method('inGroup') + ->with($sharedWith) + ->willReturn(true); + + $this->groupManager->method('get')->with('group')->willReturn($group); + + $this->defaultProvider + ->method('getSharesByPath') + ->with($path) + ->willReturn([$share2]); + + $this->invokePrivate($this->manager, 'userCreateChecks', [$share]); + } + + public function testUserCreateChecksIdenticalPathNotSharedWithUser() { + $share = $this->manager->newShare(); + $sharedWith = $this->getMock('\OCP\IUser'); + $path = $this->getMock('\OCP\Files\Node'); + $share->setSharedWith('sharedWith') + ->setNode($path) + ->setShareOwner('shareOwner') + ->setProviderId('foo') + ->setId('bar'); + + $this->userManager->method('get')->with('sharedWith')->willReturn($sharedWith); + + $share2 = $this->manager->newShare(); + $share2->setShareType(\OCP\Share::SHARE_TYPE_GROUP) + ->setShareOwner('shareOwner2') + ->setProviderId('foo') + ->setId('baz'); + + $group = $this->getMock('\OCP\IGroup'); + $group->method('inGroup') + ->with($sharedWith) + ->willReturn(false); + + $this->groupManager->method('get')->with('group')->willReturn($group); + + $share2->setSharedWith('group'); + + $this->defaultProvider + ->method('getSharesByPath') + ->with($path) + ->willReturn([$share2]); + + $this->invokePrivate($this->manager, 'userCreateChecks', [$share]); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Group sharing is now allowed + */ + public function testGroupCreateChecksShareWithGroupMembersGroupSharingNotAllowed() { + $share = $this->manager->newShare(); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_group_sharing', 'yes', 'no'], + ])); + + $this->invokePrivate($this->manager, 'groupCreateChecks', [$share]); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Only sharing within your own groups is allowed + */ + public function testGroupCreateChecksShareWithGroupMembersOnlyNotInGroup() { + $share = $this->manager->newShare(); + + $user = $this->getMock('\OCP\IUser'); + $group = $this->getMock('\OCP\IGroup'); + $share->setSharedBy('user')->setSharedWith('group'); + + $group->method('inGroup')->with($user)->willReturn(false); + + $this->groupManager->method('get')->with('group')->willReturn($group); + $this->userManager->method('get')->with('user')->willReturn($user); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], + ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'], + ])); + + $this->invokePrivate($this->manager, 'groupCreateChecks', [$share]); + } + + public function testGroupCreateChecksShareWithGroupMembersOnlyInGroup() { + $share = $this->manager->newShare(); + + $user = $this->getMock('\OCP\IUser'); + $group = $this->getMock('\OCP\IGroup'); + $share->setSharedBy('user')->setSharedWith('group'); + + $this->userManager->method('get')->with('user')->willReturn($user); + $this->groupManager->method('get')->with('group')->willReturn($group); + + $group->method('inGroup')->with($user)->willReturn(true); + + $path = $this->getMock('\OCP\Files\Node'); + $share->setNode($path); + + $this->defaultProvider->method('getSharesByPath') + ->with($path) + ->willReturn([]); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], + ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'], + ])); + + $this->invokePrivate($this->manager, 'groupCreateChecks', [$share]); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Path already shared with this group + */ + public function testGroupCreateChecksPathAlreadySharedWithSameGroup() { + $share = $this->manager->newShare(); + + $path = $this->getMock('\OCP\Files\Node'); + $share->setSharedWith('sharedWith') + ->setNode($path) + ->setProviderId('foo') + ->setId('bar'); + + $share2 = $this->manager->newShare(); + $share2->setSharedWith('sharedWith') + ->setProviderId('foo') + ->setId('baz'); + + $this->defaultProvider->method('getSharesByPath') + ->with($path) + ->willReturn([$share2]); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'], + ])); + + $this->invokePrivate($this->manager, 'groupCreateChecks', [$share]); + } + + public function testGroupCreateChecksPathAlreadySharedWithDifferentGroup() { + $share = $this->manager->newShare(); + + $share->setSharedWith('sharedWith'); + + $path = $this->getMock('\OCP\Files\Node'); + $share->setNode($path); + + $share2 = $this->manager->newShare(); + $share2->setSharedWith('sharedWith2'); + + $this->defaultProvider->method('getSharesByPath') + ->with($path) + ->willReturn([$share2]); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'], + ])); + + $this->invokePrivate($this->manager, 'groupCreateChecks', [$share]); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Link sharing not allowed + */ + public function testLinkCreateChecksNoLinkSharesAllowed() { + $share = $this->manager->newShare(); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_links', 'yes', 'no'], + ])); + + $this->invokePrivate($this->manager, 'linkCreateChecks', [$share]); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Link shares can't have reshare permissions + */ + public function testLinkCreateChecksSharePermissions() { + $share = $this->manager->newShare(); + + $share->setPermissions(\OCP\Constants::PERMISSION_SHARE); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_links', 'yes', 'yes'], + ])); + + $this->invokePrivate($this->manager, 'linkCreateChecks', [$share]); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Link shares can't have delete permissions + */ + public function testLinkCreateChecksDeletePermissions() { + $share = $this->manager->newShare(); + + $share->setPermissions(\OCP\Constants::PERMISSION_DELETE); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_links', 'yes', 'yes'], + ])); + + $this->invokePrivate($this->manager, 'linkCreateChecks', [$share]); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Public upload not allowed + */ + public function testLinkCreateChecksNoPublicUpload() { + $share = $this->manager->newShare(); + + $share->setPermissions(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_links', 'yes', 'yes'], + ['core', 'shareapi_allow_public_upload', 'yes', 'no'] + ])); + + $this->invokePrivate($this->manager, 'linkCreateChecks', [$share]); + } + + public function testLinkCreateChecksPublicUpload() { + $share = $this->manager->newShare(); + + $share->setPermissions(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_links', 'yes', 'yes'], + ['core', 'shareapi_allow_public_upload', 'yes', 'yes'] + ])); + + $this->invokePrivate($this->manager, 'linkCreateChecks', [$share]); + } + + public function testLinkCreateChecksReadOnly() { + $share = $this->manager->newShare(); + + $share->setPermissions(\OCP\Constants::PERMISSION_READ); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_links', 'yes', 'yes'], + ['core', 'shareapi_allow_public_upload', 'yes', 'no'] + ])); + + $this->invokePrivate($this->manager, 'linkCreateChecks', [$share]); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Path contains files shared with you + */ + public function testPathCreateChecksContainsSharedMount() { + $path = $this->getMock('\OCP\Files\Folder'); + $path->method('getPath')->willReturn('path'); + + $mount = $this->getMock('\OCP\Files\Mount\IMountPoint'); + $storage = $this->getMock('\OCP\Files\Storage'); + $mount->method('getStorage')->willReturn($storage); + $storage->method('instanceOfStorage')->with('\OCA\Files_Sharing\ISharedStorage')->willReturn(true); + + $this->mountManager->method('findIn')->with('path')->willReturn([$mount]); + + $this->invokePrivate($this->manager, 'pathCreateChecks', [$path]); + } + + public function testPathCreateChecksContainsNoSharedMount() { + $path = $this->getMock('\OCP\Files\Folder'); + $path->method('getPath')->willReturn('path'); + + $mount = $this->getMock('\OCP\Files\Mount\IMountPoint'); + $storage = $this->getMock('\OCP\Files\Storage'); + $mount->method('getStorage')->willReturn($storage); + $storage->method('instanceOfStorage')->with('\OCA\Files_Sharing\ISharedStorage')->willReturn(false); + + $this->mountManager->method('findIn')->with('path')->willReturn([$mount]); + + $this->invokePrivate($this->manager, 'pathCreateChecks', [$path]); + } + + public function testPathCreateChecksContainsNoFolder() { + $path = $this->getMock('\OCP\Files\File'); + + $this->invokePrivate($this->manager, 'pathCreateChecks', [$path]); + } + + public function dataIsSharingDisabledForUser() { + $data = []; + + // No exclude groups + $data[] = ['no', null, null, null, false]; + + // empty exclude list, user no groups + $data[] = ['yes', '', json_encode(['']), [], false]; + + // empty exclude list, user groups + $data[] = ['yes', '', json_encode(['']), ['group1', 'group2'], false]; + + // Convert old list to json + $data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), [], false]; + + // Old list partly groups in common + $data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), ['group1', 'group3'], false]; + + // Old list only groups in common + $data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), ['group1'], true]; + + // New list partly in common + $data[] = ['yes', json_encode(['group1', 'group2']), null, ['group1', 'group3'], false]; + + // New list only groups in common + $data[] = ['yes', json_encode(['group1', 'group2']), null, ['group2'], true]; + + return $data; + } + + /** + * @dataProvider dataIsSharingDisabledForUser + * + * @param string $excludeGroups + * @param string $groupList + * @param string $setList + * @param string[] $groupIds + * @param bool $expected + */ + public function testIsSharingDisabledForUser($excludeGroups, $groupList, $setList, $groupIds, $expected) { + $user = $this->getMock('\OCP\IUser'); + + $this->config->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_exclude_groups', 'no', $excludeGroups], + ['core', 'shareapi_exclude_groups_list', '', $groupList], + ])); + + if ($setList !== null) { + $this->config->expects($this->once()) + ->method('setAppValue') + ->with('core', 'shareapi_exclude_groups_list', $setList); + } else { + $this->config->expects($this->never()) + ->method('setAppValue'); + } + + $this->groupManager->method('getUserGroupIds') + ->with($user) + ->willReturn($groupIds); + + $this->userManager->method('get')->with('user')->willReturn($user); + + $res = $this->manager->sharingDisabledForUser('user'); + $this->assertEquals($expected, $res); + } + + public function dataCanShare() { + $data = []; + + /* + * [expected, sharing enabled, disabled for user] + */ + + $data[] = [false, 'no', false]; + $data[] = [false, 'no', true]; + $data[] = [true, 'yes', false]; + $data[] = [false, 'yes', true]; + + return $data; + } + + /** + * @dataProvider dataCanShare + * + * @param bool $expected + * @param string $sharingEnabled + * @param bool $disabledForUser + */ + public function testCanShare($expected, $sharingEnabled, $disabledForUser) { + $this->config->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_enabled', 'yes', $sharingEnabled], + ])); + + $manager = $this->createManagerMock() + ->setMethods(['sharingDisabledForUser']) + ->getMock(); + + $manager->method('sharingDisabledForUser') + ->with('user') + ->willReturn($disabledForUser); + + $share = $this->manager->newShare(); + $share->setSharedBy('user'); + + $exception = false; + try { + $res = $this->invokePrivate($manager, 'canShare', [$share]); + } catch (\Exception $e) { + $exception = true; + } + + $this->assertEquals($expected, !$exception); + } + + public function testCreateShareUser() { + $manager = $this->createManagerMock() + ->setMethods(['canShare', 'generalCreateChecks', 'userCreateChecks', 'pathCreateChecks']) + ->getMock(); + + $shareOwner = $this->getMock('\OCP\IUser'); + $shareOwner->method('getUID')->willReturn('shareOwner'); + + $storage = $this->getMock('\OCP\Files\Storage'); + $path = $this->getMock('\OCP\Files\File'); + $path->method('getOwner')->willReturn($shareOwner); + $path->method('getName')->willReturn('target'); + $path->method('getStorage')->willReturn($storage); + + $share = $this->createShare( + null, + \OCP\Share::SHARE_TYPE_USER, + $path, + 'sharedWith', + 'sharedBy', + null, + \OCP\Constants::PERMISSION_ALL); + + $manager->expects($this->once()) + ->method('canShare') + ->with($share) + ->willReturn(true); + $manager->expects($this->once()) + ->method('generalCreateChecks') + ->with($share);; + $manager->expects($this->once()) + ->method('userCreateChecks') + ->with($share);; + $manager->expects($this->once()) + ->method('pathCreateChecks') + ->with($path); + + $this->defaultProvider + ->expects($this->once()) + ->method('create') + ->with($share) + ->will($this->returnArgument(0)); + + $share->expects($this->once()) + ->method('setShareOwner') + ->with('shareOwner'); + $share->expects($this->once()) + ->method('setTarget') + ->with('/target'); + + $manager->createShare($share); + } + + public function testCreateShareGroup() { + $manager = $this->createManagerMock() + ->setMethods(['canShare', 'generalCreateChecks', 'groupCreateChecks', 'pathCreateChecks']) + ->getMock(); + + $shareOwner = $this->getMock('\OCP\IUser'); + $shareOwner->method('getUID')->willReturn('shareOwner'); + + $storage = $this->getMock('\OCP\Files\Storage'); + $path = $this->getMock('\OCP\Files\File'); + $path->method('getOwner')->willReturn($shareOwner); + $path->method('getName')->willReturn('target'); + $path->method('getStorage')->willReturn($storage); + + $share = $this->createShare( + null, + \OCP\Share::SHARE_TYPE_GROUP, + $path, + 'sharedWith', + 'sharedBy', + null, + \OCP\Constants::PERMISSION_ALL); + + $manager->expects($this->once()) + ->method('canShare') + ->with($share) + ->willReturn(true); + $manager->expects($this->once()) + ->method('generalCreateChecks') + ->with($share);; + $manager->expects($this->once()) + ->method('groupCreateChecks') + ->with($share);; + $manager->expects($this->once()) + ->method('pathCreateChecks') + ->with($path); + + $this->defaultProvider + ->expects($this->once()) + ->method('create') + ->with($share) + ->will($this->returnArgument(0)); + + $share->expects($this->once()) + ->method('setShareOwner') + ->with('shareOwner'); + $share->expects($this->once()) + ->method('setTarget') + ->with('/target'); + + $manager->createShare($share); + } + + public function testCreateShareLink() { + $manager = $this->createManagerMock() + ->setMethods([ + 'canShare', + 'generalCreateChecks', + 'linkCreateChecks', + 'pathCreateChecks', + 'validateExpirationDate', + 'verifyPassword', + 'setLinkParent', + ]) + ->getMock(); + + $shareOwner = $this->getMock('\OCP\IUser'); + $shareOwner->method('getUID')->willReturn('shareOwner'); + + $storage = $this->getMock('\OCP\Files\Storage'); + $path = $this->getMock('\OCP\Files\File'); + $path->method('getOwner')->willReturn($shareOwner); + $path->method('getName')->willReturn('target'); + $path->method('getId')->willReturn(1); + $path->method('getStorage')->willReturn($storage); + + $date = new \DateTime(); + + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setNode($path) + ->setSharedBy('sharedBy') + ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setExpirationDate($date) + ->setPassword('password'); + + $manager->expects($this->once()) + ->method('canShare') + ->with($share) + ->willReturn(true); + $manager->expects($this->once()) + ->method('generalCreateChecks') + ->with($share);; + $manager->expects($this->once()) + ->method('linkCreateChecks') + ->with($share);; + $manager->expects($this->once()) + ->method('pathCreateChecks') + ->with($path); + $manager->expects($this->once()) + ->method('validateExpirationDate') + ->with($share); + $manager->expects($this->once()) + ->method('verifyPassword') + ->with('password'); + $manager->expects($this->once()) + ->method('setLinkParent') + ->with($share); + + $this->hasher->expects($this->once()) + ->method('hash') + ->with('password') + ->willReturn('hashed'); + + $this->secureRandom->method('getMediumStrengthGenerator') + ->will($this->returnSelf()); + $this->secureRandom->method('generate') + ->willReturn('token'); + + $this->defaultProvider + ->expects($this->once()) + ->method('create') + ->with($share) + ->will($this->returnCallback(function(Share $share) { + return $share->setId(42); + })); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['pre', 'post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'pre_shared', $hookListner, 'pre'); + \OCP\Util::connectHook('OCP\Share', 'post_shared', $hookListner, 'post'); + + $hookListnerExpectsPre = [ + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_LINK, + 'uidOwner' => 'sharedBy', + 'permissions' => 31, + 'fileSource' => 1, + 'expiration' => $date, + 'token' => 'token', + 'run' => true, + 'error' => '', + 'itemTarget' => '/target', + 'shareWith' => null, + ]; + + $hookListnerExpectsPost = [ + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_LINK, + 'uidOwner' => 'sharedBy', + 'permissions' => 31, + 'fileSource' => 1, + 'expiration' => $date, + 'token' => 'token', + 'id' => 42, + 'itemTarget' => '/target', + 'fileTarget' => '/target', + 'shareWith' => null, + ]; + + $hookListner->expects($this->once()) + ->method('pre') + ->with($this->equalTo($hookListnerExpectsPre)); + $hookListner->expects($this->once()) + ->method('post') + ->with($this->equalTo($hookListnerExpectsPost)); + + /** @var IShare $share */ + $share = $manager->createShare($share); + + $this->assertSame('shareOwner', $share->getShareOwner()); + $this->assertEquals('/target', $share->getTarget()); + $this->assertSame($date, $share->getExpirationDate()); + $this->assertEquals('token', $share->getToken()); + $this->assertEquals('hashed', $share->getPassword()); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage I won't let you share + */ + public function testCreateShareHookError() { + $manager = $this->createManagerMock() + ->setMethods([ + 'canShare', + 'generalCreateChecks', + 'userCreateChecks', + 'pathCreateChecks', + ]) + ->getMock(); + + $shareOwner = $this->getMock('\OCP\IUser'); + $shareOwner->method('getUID')->willReturn('shareOwner'); + + $storage = $this->getMock('\OCP\Files\Storage'); + $path = $this->getMock('\OCP\Files\File'); + $path->method('getOwner')->willReturn($shareOwner); + $path->method('getName')->willReturn('target'); + $path->method('getStorage')->willReturn($storage); + + $share = $this->createShare( + null, + \OCP\Share::SHARE_TYPE_USER, + $path, + 'sharedWith', + 'sharedBy', + null, + \OCP\Constants::PERMISSION_ALL); + + $manager->expects($this->once()) + ->method('canShare') + ->with($share) + ->willReturn(true); + $manager->expects($this->once()) + ->method('generalCreateChecks') + ->with($share);; + $manager->expects($this->once()) + ->method('userCreateChecks') + ->with($share);; + $manager->expects($this->once()) + ->method('pathCreateChecks') + ->with($path); + + $share->expects($this->once()) + ->method('setShareOwner') + ->with('shareOwner'); + $share->expects($this->once()) + ->method('setTarget') + ->with('/target'); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['pre'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'pre_shared', $hookListner, 'pre'); + $hookListner->expects($this->once()) + ->method('pre') + ->will($this->returnCallback(function (array $data) { + $data['run'] = false; + $data['error'] = 'I won\'t let you share!'; + })); + + $manager->createShare($share); + } + + public function testCreateShareOfIncommingFederatedShare() { + $manager = $this->createManagerMock() + ->setMethods(['canShare', 'generalCreateChecks', 'userCreateChecks', 'pathCreateChecks']) + ->getMock(); + + $shareOwner = $this->getMock('\OCP\IUser'); + $shareOwner->method('getUID')->willReturn('shareOwner'); + + $storage = $this->getMock('\OCP\Files\Storage'); + $storage->method('instanceOfStorage') + ->with('OCA\Files_Sharing\External\Storage') + ->willReturn(true); + + $storage2 = $this->getMock('\OCP\Files\Storage'); + $storage2->method('instanceOfStorage') + ->with('OCA\Files_Sharing\External\Storage') + ->willReturn(false); + + $path = $this->getMock('\OCP\Files\File'); + $path->expects($this->never())->method('getOwner'); + $path->method('getName')->willReturn('target'); + $path->method('getStorage')->willReturn($storage); + + $parent = $this->getMock('\OCP\Files\Folder'); + $parent->method('getStorage')->willReturn($storage); + + $parentParent = $this->getMock('\OCP\Files\Folder'); + $parentParent->method('getStorage')->willReturn($storage2); + $parentParent->method('getOwner')->willReturn($shareOwner); + + $path->method('getParent')->willReturn($parent); + $parent->method('getParent')->willReturn($parentParent); + + $share = $this->createShare( + null, + \OCP\Share::SHARE_TYPE_USER, + $path, + 'sharedWith', + 'sharedBy', + null, + \OCP\Constants::PERMISSION_ALL); + + $manager->expects($this->once()) + ->method('canShare') + ->with($share) + ->willReturn(true); + $manager->expects($this->once()) + ->method('generalCreateChecks') + ->with($share);; + $manager->expects($this->once()) + ->method('userCreateChecks') + ->with($share);; + $manager->expects($this->once()) + ->method('pathCreateChecks') + ->with($path); + + $this->defaultProvider + ->expects($this->once()) + ->method('create') + ->with($share) + ->will($this->returnArgument(0)); + + $share->expects($this->once()) + ->method('setShareOwner') + ->with('shareOwner'); + $share->expects($this->once()) + ->method('setTarget') + ->with('/target'); + + $manager->createShare($share); + } + + public function testGetSharesBy() { + $share = $this->manager->newShare(); + + $node = $this->getMock('OCP\Files\Folder'); + + $this->defaultProvider->expects($this->once()) + ->method('getSharesBy') + ->with( + $this->equalTo('user'), + $this->equalTo(\OCP\Share::SHARE_TYPE_USER), + $this->equalTo($node), + $this->equalTo(true), + $this->equalTo(1), + $this->equalTo(1) + )->willReturn([$share]); + + $shares = $this->manager->getSharesBy('user', \OCP\Share::SHARE_TYPE_USER, $node, true, 1, 1); + + $this->assertCount(1, $shares); + $this->assertSame($share, $shares[0]); + } + + /** + * Test to ensure we correctly remove expired link shares + * + * We have 8 Shares and we want the 3 first valid shares. + * share 3-6 and 8 are expired. Thus at the end of this test we should + * have received share 1,2 and 7. And from the manager. Share 3-6 should be + * deleted (as they are evaluated). but share 8 should still be there. + */ + public function testGetSharesByExpiredLinkShares() { + $manager = $this->createManagerMock() + ->setMethods(['deleteShare']) + ->getMock(); + + /** @var \OCP\Share\IShare[] $shares */ + $shares = []; + + /* + * This results in an array of 8 IShare elements + */ + for ($i = 0; $i < 8; $i++) { + $share = $this->manager->newShare(); + $share->setId($i); + $shares[] = $share; + } + + $today = new \DateTime(); + $today->setTime(0,0,0); + + /* + * Set the expiration date to today for some shares + */ + $shares[2]->setExpirationDate($today); + $shares[3]->setExpirationDate($today); + $shares[4]->setExpirationDate($today); + $shares[5]->setExpirationDate($today); + + /** @var \OCP\Share\IShare[] $i */ + $shares2 = []; + for ($i = 0; $i < 8; $i++) { + $shares2[] = clone $shares[$i]; + } + + $node = $this->getMock('OCP\Files\File'); + + /* + * Simulate the getSharesBy call. + */ + $this->defaultProvider + ->method('getSharesBy') + ->will($this->returnCallback(function($uid, $type, $node, $reshares, $limit, $offset) use (&$shares2) { + return array_slice($shares2, $offset, $limit); + })); + + /* + * Simulate the deleteShare call. + */ + $manager->method('deleteShare') + ->will($this->returnCallback(function($share) use (&$shares2) { + for($i = 0; $i < count($shares2); $i++) { + if ($shares2[$i]->getId() === $share->getId()) { + array_splice($shares2, $i, 1); + break; + } + } + })); + + $res = $manager->getSharesBy('user', \OCP\Share::SHARE_TYPE_LINK, $node, true, 3, 0); + + $this->assertCount(3, $res); + $this->assertEquals($shares[0]->getId(), $res[0]->getId()); + $this->assertEquals($shares[1]->getId(), $res[1]->getId()); + $this->assertEquals($shares[6]->getId(), $res[2]->getId()); + + $this->assertCount(4, $shares2); + $this->assertEquals(0, $shares2[0]->getId()); + $this->assertEquals(1, $shares2[1]->getId()); + $this->assertEquals(6, $shares2[2]->getId()); + $this->assertEquals(7, $shares2[3]->getId()); + $this->assertSame($today, $shares[3]->getExpirationDate()); + } + + public function testGetShareByToken() { + $factory = $this->getMock('\OCP\Share\IProviderFactory'); + + $manager = new Manager( + $this->logger, + $this->config, + $this->secureRandom, + $this->hasher, + $this->mountManager, + $this->groupManager, + $this->l, + $factory, + $this->userManager, + $this->rootFolder + ); + + $share = $this->getMock('\OCP\Share\IShare'); + + $factory->expects($this->once()) + ->method('getProviderForType') + ->with(\OCP\Share::SHARE_TYPE_LINK) + ->willReturn($this->defaultProvider); + + $this->defaultProvider->expects($this->once()) + ->method('getShareByToken') + ->with('token') + ->willReturn($share); + + $ret = $manager->getShareByToken('token'); + $this->assertSame($share, $ret); + } + + public function testGetShareByTokenWithException() { + $factory = $this->getMock('\OCP\Share\IProviderFactory'); + + $manager = new Manager( + $this->logger, + $this->config, + $this->secureRandom, + $this->hasher, + $this->mountManager, + $this->groupManager, + $this->l, + $factory, + $this->userManager, + $this->rootFolder + ); + + $share = $this->getMock('\OCP\Share\IShare'); + + $factory->expects($this->at(0)) + ->method('getProviderForType') + ->with(\OCP\Share::SHARE_TYPE_LINK) + ->willReturn($this->defaultProvider); + $factory->expects($this->at(1)) + ->method('getProviderForType') + ->with(\OCP\Share::SHARE_TYPE_REMOTE) + ->willReturn($this->defaultProvider); + + $this->defaultProvider->expects($this->at(0)) + ->method('getShareByToken') + ->with('token') + ->will($this->throwException(new ShareNotFound())); + $this->defaultProvider->expects($this->at(1)) + ->method('getShareByToken') + ->with('token') + ->willReturn($share); + + $ret = $manager->getShareByToken('token'); + $this->assertSame($share, $ret); + } + + /** + * @expectedException \OCP\Share\Exceptions\ShareNotFound + */ + public function testGetShareByTokenExpired() { + $manager = $this->createManagerMock() + ->setMethods(['deleteShare']) + ->getMock(); + + $date = new \DateTime(); + $date->setTime(0,0,0); + $share = $this->manager->newShare(); + $share->setExpirationDate($date); + + $this->defaultProvider->expects($this->once()) + ->method('getShareByToken') + ->with('expiredToken') + ->willReturn($share); + + $manager->expects($this->once()) + ->method('deleteShare') + ->with($this->equalTo($share)); + + $manager->getShareByToken('expiredToken'); + } + + public function testGetShareByTokenNotExpired() { + $date = new \DateTime(); + $date->setTime(0,0,0); + $date->add(new \DateInterval('P2D')); + $share = $this->manager->newShare(); + $share->setExpirationDate($date); + + $this->defaultProvider->expects($this->once()) + ->method('getShareByToken') + ->with('expiredToken') + ->willReturn($share); + + $res = $this->manager->getShareByToken('expiredToken'); + + $this->assertSame($share, $res); + } + + public function testGetShareByTokenPublicSharingDisabled() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPermissions(\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); + + $this->config->method('getAppValue')->will($this->returnValueMap([ + ['core', 'shareapi_allow_public_upload', 'yes', 'no'], + ])); + + $this->defaultProvider->expects($this->once()) + ->method('getShareByToken') + ->willReturn('validToken') + ->willReturn($share); + + $res = $this->manager->getShareByToken('validToken'); + + $this->assertSame(\OCP\Constants::PERMISSION_READ, $res->getPermissions()); + } + + public function testCheckPasswordNoLinkShare() { + $share = $this->getMock('\OCP\Share\IShare'); + $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); + $this->assertFalse($this->manager->checkPassword($share, 'password')); + } + + public function testCheckPasswordNoPassword() { + $share = $this->getMock('\OCP\Share\IShare'); + $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK); + $this->assertFalse($this->manager->checkPassword($share, 'password')); + + $share->method('getPassword')->willReturn('password'); + $this->assertFalse($this->manager->checkPassword($share, null)); + } + + public function testCheckPasswordInvalidPassword() { + $share = $this->getMock('\OCP\Share\IShare'); + $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK); + $share->method('getPassword')->willReturn('password'); + + $this->hasher->method('verify')->with('invalidpassword', 'password', '')->willReturn(false); + + $this->assertFalse($this->manager->checkPassword($share, 'invalidpassword')); + } + + public function testCheckPasswordValidPassword() { + $share = $this->getMock('\OCP\Share\IShare'); + $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK); + $share->method('getPassword')->willReturn('passwordHash'); + + $this->hasher->method('verify')->with('password', 'passwordHash', '')->willReturn(true); + + $this->assertTrue($this->manager->checkPassword($share, 'password')); + } + + public function testCheckPasswordUpdateShare() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPassword('passwordHash'); + + $this->hasher->method('verify')->with('password', 'passwordHash', '') + ->will($this->returnCallback(function($pass, $hash, &$newHash) { + $newHash = 'newHash'; + + return true; + })); + + $this->defaultProvider->expects($this->once()) + ->method('update') + ->with($this->callback(function (\OCP\Share\IShare $share) { + return $share->getPassword() === 'newHash'; + })); + + $this->assertTrue($this->manager->checkPassword($share, 'password')); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Can't change share type + */ + public function testUpdateShareCantChangeShareType() { + $manager = $this->createManagerMock() + ->setMethods([ + 'canShare', + 'getShareById' + ]) + ->getMock(); + + $originalShare = $this->manager->newShare(); + $originalShare->setShareType(\OCP\Share::SHARE_TYPE_GROUP); + + $manager->expects($this->once())->method('canShare')->willReturn(true); + $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); + + $share = $this->manager->newShare(); + $share->setProviderId('foo') + ->setId('42') + ->setShareType(\OCP\Share::SHARE_TYPE_USER); + + $manager->updateShare($share); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Can only update recipient on user shares + */ + public function testUpdateShareCantChangeRecipientForGroupShare() { + $manager = $this->createManagerMock() + ->setMethods([ + 'canShare', + 'getShareById' + ]) + ->getMock(); + + $originalShare = $this->manager->newShare(); + $originalShare->setShareType(\OCP\Share::SHARE_TYPE_GROUP) + ->setSharedWith('origGroup'); + + $manager->expects($this->once())->method('canShare')->willReturn(true); + $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); + + $share = $this->manager->newShare(); + $share->setProviderId('foo') + ->setId('42') + ->setShareType(\OCP\Share::SHARE_TYPE_GROUP) + ->setSharedWith('newGroup'); + + $manager->updateShare($share); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Can't share with the share owner + */ + public function testUpdateShareCantShareWithOwner() { + $manager = $this->createManagerMock() + ->setMethods([ + 'canShare', + 'getShareById' + ]) + ->getMock(); + + $originalShare = $this->manager->newShare(); + $originalShare->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setSharedWith('sharedWith'); + + $manager->expects($this->once())->method('canShare')->willReturn(true); + $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); + + $share = $this->manager->newShare(); + $share->setProviderId('foo') + ->setId('42') + ->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setSharedWith('newUser') + ->setShareOwner('newUser'); + + $manager->updateShare($share); + } + + public function testUpdateShareUser() { + $manager = $this->createManagerMock() + ->setMethods([ + 'canShare', + 'getShareById', + 'generalCreateChecks', + 'userCreateChecks', + 'pathCreateChecks', + ]) + ->getMock(); + + $originalShare = $this->manager->newShare(); + $originalShare->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setSharedWith('origUser') + ->setPermissions(1); + + $node = $this->getMock('\OCP\Files\File'); + $node->method('getId')->willReturn(100); + $node->method('getPath')->willReturn('/newUser/files/myPath'); + + $manager->expects($this->once())->method('canShare')->willReturn(true); + $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); + + $share = $this->manager->newShare(); + $share->setProviderId('foo') + ->setId('42') + ->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setSharedWith('origUser') + ->setShareOwner('newUser') + ->setSharedBy('sharer') + ->setPermissions(31) + ->setNode($node); + + $this->defaultProvider->expects($this->once()) + ->method('update') + ->with($share) + ->willReturn($share); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListner, 'post'); + $hookListner->expects($this->never())->method('post'); + + $this->rootFolder->method('getUserFolder')->with('newUser')->will($this->returnSelf()); + $this->rootFolder->method('getRelativePath')->with('/newUser/files/myPath')->willReturn('/myPath'); + + $hookListner2 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'post_update_permissions', $hookListner2, 'post'); + $hookListner2->expects($this->once())->method('post')->with([ + 'itemType' => 'file', + 'itemSource' => 100, + 'shareType' => \OCP\Share::SHARE_TYPE_USER, + 'shareWith' => 'origUser', + 'uidOwner' => 'sharer', + 'permissions' => 31, + 'path' => '/myPath', + ]); + + $manager->updateShare($share); + } + + public function testUpdateShareGroup() { + $manager = $this->createManagerMock() + ->setMethods([ + 'canShare', + 'getShareById', + 'generalCreateChecks', + 'groupCreateChecks', + 'pathCreateChecks', + ]) + ->getMock(); + + $originalShare = $this->manager->newShare(); + $originalShare->setShareType(\OCP\Share::SHARE_TYPE_GROUP) + ->setSharedWith('origUser') + ->setPermissions(31); + + $manager->expects($this->once())->method('canShare')->willReturn(true); + $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); + + $node = $this->getMock('\OCP\Files\File'); + + $share = $this->manager->newShare(); + $share->setProviderId('foo') + ->setId('42') + ->setShareType(\OCP\Share::SHARE_TYPE_GROUP) + ->setSharedWith('origUser') + ->setShareOwner('owner') + ->setNode($node) + ->setPermissions(31); + + $this->defaultProvider->expects($this->once()) + ->method('update') + ->with($share) + ->willReturn($share); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListner, 'post'); + $hookListner->expects($this->never())->method('post'); + + $hookListner2 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'post_update_permissions', $hookListner2, 'post'); + $hookListner2->expects($this->never())->method('post'); + + $manager->updateShare($share); + } + + public function testUpdateShareLink() { + $manager = $this->createManagerMock() + ->setMethods([ + 'canShare', + 'getShareById', + 'generalCreateChecks', + 'linkCreateChecks', + 'pathCreateChecks', + 'verifyPassword', + 'validateExpirationDate', + ]) + ->getMock(); + + $originalShare = $this->manager->newShare(); + $originalShare->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPermissions(15); + + $tomorrow = new \DateTime(); + $tomorrow->setTime(0,0,0); + $tomorrow->add(new \DateInterval('P1D')); + + $file = $this->getMock('OCP\Files\File', [], [], 'File'); + $file->method('getId')->willReturn(100); + + $share = $this->manager->newShare(); + $share->setProviderId('foo') + ->setId('42') + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setSharedBy('owner') + ->setShareOwner('owner') + ->setPassword('password') + ->setExpirationDate($tomorrow) + ->setNode($file) + ->setPermissions(15); + + $manager->expects($this->once())->method('canShare')->willReturn(true); + $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); + $manager->expects($this->once())->method('validateExpirationDate')->with($share); + + $this->defaultProvider->expects($this->once()) + ->method('update') + ->with($share) + ->willReturn($share); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListner, 'post'); + $hookListner->expects($this->once())->method('post')->with([ + 'itemType' => 'file', + 'itemSource' => 100, + 'date' => $tomorrow, + 'uidOwner' => 'owner', + ]); + + $hookListner2 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'post_update_permissions', $hookListner2, 'post'); + $hookListner2->expects($this->never())->method('post'); + + + $manager->updateShare($share); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Can't change target of link share + */ + public function testMoveShareLink() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_LINK); + + $recipient = $this->getMock('\OCP\IUser'); + + $this->manager->moveShare($share, $recipient); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid recipient + */ + public function testMoveShareUserNotRecipient() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_USER); + + $share->setSharedWith('sharedWith'); + + $this->manager->moveShare($share, 'recipient'); + } + + public function testMoveShareUser() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setId('42') + ->setProviderId('foo'); + + $share->setSharedWith('recipient'); + + $this->defaultProvider->method('move')->with($share, 'recipient')->will($this->returnArgument(0)); + + $this->manager->moveShare($share, 'recipient'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid recipient + */ + public function testMoveShareGroupNotRecipient() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP); + + $sharedWith = $this->getMock('\OCP\IGroup'); + $share->setSharedWith('shareWith'); + + $recipient = $this->getMock('\OCP\IUser'); + $sharedWith->method('inGroup')->with($recipient)->willReturn(false); + + $this->groupManager->method('get')->with('shareWith')->willReturn($sharedWith); + $this->userManager->method('get')->with('recipient')->willReturn($recipient); + + $this->manager->moveShare($share, 'recipient'); + } + + public function testMoveShareGroup() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP) + ->setId('42') + ->setProviderId('foo'); + + $group = $this->getMock('\OCP\IGroup'); + $share->setSharedWith('group'); + + $recipient = $this->getMock('\OCP\IUser'); + $group->method('inGroup')->with($recipient)->willReturn(true); + + $this->groupManager->method('get')->with('group')->willReturn($group); + $this->userManager->method('get')->with('recipient')->willReturn($recipient); + + $this->defaultProvider->method('move')->with($share, 'recipient')->will($this->returnArgument(0)); + + $this->manager->moveShare($share, 'recipient'); + } +} + +class DummyPassword { + public function listner($array) { + $array['accepted'] = false; + $array['message'] = 'password not accepted'; + } +} + +class DummyFactory implements IProviderFactory { + + /** @var IShareProvider */ + private $provider; + + public function __construct(\OCP\IServerContainer $serverContainer) { + + } + + /** + * @param IShareProvider $provider + */ + public function setProvider($provider) { + $this->provider = $provider; + } + + /** + * @param string $id + * @return IShareProvider + */ + public function getProvider($id) { + return $this->provider; + } + + /** + * @param int $shareType + * @return IShareProvider + */ + public function getProviderForType($shareType) { + return $this->provider; + } +}
\ No newline at end of file diff --git a/tests/lib/Share20/ShareTest.php b/tests/lib/Share20/ShareTest.php new file mode 100644 index 00000000000..fdfc69f6577 --- /dev/null +++ b/tests/lib/Share20/ShareTest.php @@ -0,0 +1,93 @@ +<?php +/** + * @author Roeland Jago Douma <rullzer@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ +namespace Test\Share20; + +use OCP\Files\IRootFolder; + +/** + * Class ShareTest + * + * @package Test\Share20 + */ +class ShareTest extends \Test\TestCase { + + /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */ + protected $rootFolder; + /** @var \OCP\Share\IShare */ + protected $share; + + public function setUp() { + $this->rootFolder = $this->getMock('\OCP\Files\IRootFolder'); + $this->share = new \OC\Share20\Share($this->rootFolder); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage String expected. + */ + public function testSetIdInvalid() { + $this->share->setId(1.2); + } + + public function testSetIdInt() { + $this->share->setId(42); + $this->assertEquals('42', $this->share->getId()); + } + + + public function testSetIdString() { + $this->share->setId('foo'); + $this->assertEquals('foo', $this->share->getId()); + } + + /** + * @expectedException \OCP\Share\Exceptions\IllegalIDChangeException + * @expectedExceptionMessage Not allowed to assign a new internal id to a share + */ + public function testSetIdOnce() { + $this->share->setId('foo'); + $this->share->setId('bar'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage String expected. + */ + public function testSetProviderIdInt() { + $this->share->setProviderId(42); + } + + + public function testSetProviderIdString() { + $this->share->setProviderId('foo'); + $this->share->setId('bar'); + $this->assertEquals('foo:bar', $this->share->getFullId()); + } + + /** + * @expectedException \OCP\Share\Exceptions\IllegalIDChangeException + * @expectedExceptionMessage Not allowed to assign a new provider id to a share + */ + public function testSetProviderIdOnce() { + $this->share->setProviderId('foo'); + $this->share->setProviderId('bar'); + } +} |