diff options
Diffstat (limited to 'apps/files/tests')
33 files changed, 1610 insertions, 7255 deletions
diff --git a/apps/files/tests/Activity/Filter/GenericTest.php b/apps/files/tests/Activity/Filter/GenericTest.php new file mode 100644 index 00000000000..40e2f9848b5 --- /dev/null +++ b/apps/files/tests/Activity/Filter/GenericTest.php @@ -0,0 +1,81 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\Files\Tests\Activity\Filter; + +use OCA\Files\Activity\Filter\Favorites; +use OCA\Files\Activity\Filter\FileChanges; +use OCP\Activity\IFilter; +use OCP\Server; +use Test\TestCase; + +/** + * Class GenericTest + * + * @package OCA\Files\Tests\Activity\Filter + * @group DB + */ +class GenericTest extends TestCase { + public static function dataFilters(): array { + return [ + [Favorites::class], + [FileChanges::class], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataFilters')] + public function testImplementsInterface(string $filterClass): void { + $filter = Server::get($filterClass); + $this->assertInstanceOf(IFilter::class, $filter); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataFilters')] + public function testGetIdentifier(string $filterClass): void { + /** @var IFilter $filter */ + $filter = Server::get($filterClass); + $this->assertIsString($filter->getIdentifier()); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataFilters')] + public function testGetName(string $filterClass): void { + /** @var IFilter $filter */ + $filter = Server::get($filterClass); + $this->assertIsString($filter->getName()); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataFilters')] + public function testGetPriority(string $filterClass): void { + /** @var IFilter $filter */ + $filter = Server::get($filterClass); + $priority = $filter->getPriority(); + $this->assertIsInt($filter->getPriority()); + $this->assertGreaterThanOrEqual(0, $priority); + $this->assertLessThanOrEqual(100, $priority); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataFilters')] + public function testGetIcon(string $filterClass): void { + /** @var IFilter $filter */ + $filter = Server::get($filterClass); + $this->assertIsString($filter->getIcon()); + $this->assertStringStartsWith('http', $filter->getIcon()); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataFilters')] + public function testFilterTypes(string $filterClass): void { + /** @var IFilter $filter */ + $filter = Server::get($filterClass); + $this->assertIsArray($filter->filterTypes([])); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataFilters')] + public function testAllowedApps(string $filterClass): void { + /** @var IFilter $filter */ + $filter = Server::get($filterClass); + $this->assertIsArray($filter->allowedApps()); + } +} diff --git a/apps/files/tests/Activity/ProviderTest.php b/apps/files/tests/Activity/ProviderTest.php new file mode 100644 index 00000000000..b6ba095ecfe --- /dev/null +++ b/apps/files/tests/Activity/ProviderTest.php @@ -0,0 +1,189 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\Files\Tests\Activity; + +use OCA\Files\Activity\Provider; +use OCP\Activity\Exceptions\UnknownActivityException; +use OCP\Activity\IEvent; +use OCP\Activity\IEventMerger; +use OCP\Activity\IManager; +use OCP\Contacts\IManager as IContactsManager; +use OCP\Federation\ICloudId; +use OCP\Federation\ICloudIdManager; +use OCP\Files\IRootFolder; +use OCP\IURLGenerator; +use OCP\IUserManager; +use OCP\L10N\IFactory; +use PHPUnit\Framework\MockObject\MockObject; +use Test\TestCase; + +/** + * Class ProviderTest + * + * @package OCA\Files\Tests\Activity + */ +class ProviderTest extends TestCase { + protected IFactory&MockObject $l10nFactory; + protected IURLGenerator&MockObject $url; + protected IManager&MockObject $activityManager; + protected IUserManager&MockObject $userManager; + protected IRootFolder&MockObject $rootFolder; + protected ICloudIdManager&MockObject $cloudIdManager; + protected IContactsManager&MockObject $contactsManager; + protected IEventMerger&MockObject $eventMerger; + + protected function setUp(): void { + parent::setUp(); + + $this->l10nFactory = $this->createMock(IFactory::class); + $this->url = $this->createMock(IURLGenerator::class); + $this->activityManager = $this->createMock(IManager::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->rootFolder = $this->createMock(IRootFolder::class); + $this->cloudIdManager = $this->createMock(ICloudIdManager::class); + $this->contactsManager = $this->createMock(IContactsManager::class); + $this->eventMerger = $this->createMock(IEventMerger::class); + } + + /** + * @param string[] $methods + * @return Provider|MockObject + */ + protected function getProvider(array $methods = []) { + if (!empty($methods)) { + return $this->getMockBuilder(Provider::class) + ->setConstructorArgs([ + $this->l10nFactory, + $this->url, + $this->activityManager, + $this->userManager, + $this->rootFolder, + $this->cloudIdManager, + $this->contactsManager, + $this->eventMerger, + ]) + ->onlyMethods($methods) + ->getMock(); + } + return new Provider( + $this->l10nFactory, + $this->url, + $this->activityManager, + $this->userManager, + $this->rootFolder, + $this->cloudIdManager, + $this->contactsManager, + $this->eventMerger + ); + } + + public static function dataGetFile(): array { + return [ + [[42 => '/FortyTwo.txt'], null, '42', 'FortyTwo.txt', 'FortyTwo.txt'], + [['23' => '/Twenty/Three.txt'], null, '23', 'Three.txt', 'Twenty/Three.txt'], + ['/Foo/Bar.txt', 128, '128', 'Bar.txt', 'Foo/Bar.txt'], // Legacy from ownCloud 8.2 and before + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetFile')] + public function testGetFile(array|string $parameter, ?int $eventId, string $id, string $name, string $path): void { + $provider = $this->getProvider(); + + if ($eventId !== null) { + $event = $this->createMock(IEvent::class); + $event->expects($this->once()) + ->method('getObjectId') + ->willReturn($eventId); + } else { + $event = null; + } + + $this->url->expects($this->once()) + ->method('linkToRouteAbsolute') + ->with('files.viewcontroller.showFile', ['fileid' => $id]) + ->willReturn('link-' . $id); + + $result = self::invokePrivate($provider, 'getFile', [$parameter, $event]); + + $this->assertSame('file', $result['type']); + $this->assertSame($id, $result['id']); + $this->assertSame($name, $result['name']); + $this->assertSame($path, $result['path']); + $this->assertSame('link-' . $id, $result['link']); + } + + + public function testGetFileThrows(): void { + $this->expectException(UnknownActivityException::class); + + $provider = $this->getProvider(); + self::invokePrivate($provider, 'getFile', ['/Foo/Bar.txt', null]); + } + + public static function dataGetUser(): array { + return [ + ['test', 'Test user', null, ['type' => 'user', 'id' => 'test', 'name' => 'Test user']], + ['test@http://localhost', null, ['user' => 'test', 'displayId' => 'test@localhost', 'remote' => 'localhost', 'name' => null], ['type' => 'user', 'id' => 'test', 'name' => 'test@localhost', 'server' => 'localhost']], + ['test@http://localhost', null, ['user' => 'test', 'displayId' => 'test@localhost', 'remote' => 'localhost', 'name' => 'Remote user'], ['type' => 'user', 'id' => 'test', 'name' => 'Remote user (test@localhost)', 'server' => 'localhost']], + ['test', null, null, ['type' => 'user', 'id' => 'test', 'name' => 'test']], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetUser')] + public function testGetUser(string $uid, ?string $userDisplayName, ?array $cloudIdData, array $expected): void { + $provider = $this->getProvider(); + + if ($userDisplayName !== null) { + $this->userManager->expects($this->once()) + ->method('getDisplayName') + ->with($uid) + ->willReturn($userDisplayName); + } + if ($cloudIdData !== null) { + $this->cloudIdManager->expects($this->once()) + ->method('isValidCloudId') + ->willReturn(true); + + $cloudId = $this->createMock(ICloudId::class); + $cloudId->expects($this->once()) + ->method('getUser') + ->willReturn($cloudIdData['user']); + $cloudId->expects($this->once()) + ->method('getDisplayId') + ->willReturn($cloudIdData['displayId']); + $cloudId->expects($this->once()) + ->method('getRemote') + ->willReturn($cloudIdData['remote']); + + $this->cloudIdManager->expects($this->once()) + ->method('resolveCloudId') + ->with($uid) + ->willReturn($cloudId); + + if ($cloudIdData['name'] !== null) { + $this->contactsManager->expects($this->once()) + ->method('search') + ->with($cloudIdData['displayId'], ['CLOUD']) + ->willReturn([ + [ + 'CLOUD' => $cloudIdData['displayId'], + 'FN' => $cloudIdData['name'], + ] + ]); + } else { + $this->contactsManager->expects($this->once()) + ->method('search') + ->with($cloudIdData['displayId'], ['CLOUD']) + ->willReturn([]); + } + } + + $result = self::invokePrivate($provider, 'getUser', [$uid]); + $this->assertEquals($expected, $result); + } +} diff --git a/apps/files/tests/Activity/Setting/GenericTest.php b/apps/files/tests/Activity/Setting/GenericTest.php new file mode 100644 index 00000000000..df6b1e0f6d4 --- /dev/null +++ b/apps/files/tests/Activity/Setting/GenericTest.php @@ -0,0 +1,82 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\Files\Tests\Activity\Setting; + +use OCA\Files\Activity\Settings\FavoriteAction; +use OCA\Files\Activity\Settings\FileChanged; +use OCP\Activity\ISetting; +use OCP\Server; +use Test\TestCase; + +class GenericTest extends TestCase { + public static function dataSettings(): array { + return [ + [FavoriteAction::class], + [FileChanged::class], + [FileChanged::class], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataSettings')] + public function testImplementsInterface(string $settingClass): void { + $setting = Server::get($settingClass); + $this->assertInstanceOf(ISetting::class, $setting); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataSettings')] + public function testGetIdentifier(string $settingClass): void { + /** @var ISetting $setting */ + $setting = Server::get($settingClass); + $this->assertIsString($setting->getIdentifier()); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataSettings')] + public function testGetName(string $settingClass): void { + /** @var ISetting $setting */ + $setting = Server::get($settingClass); + $this->assertIsString($setting->getName()); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataSettings')] + public function testGetPriority(string $settingClass): void { + /** @var ISetting $setting */ + $setting = Server::get($settingClass); + $priority = $setting->getPriority(); + $this->assertIsInt($setting->getPriority()); + $this->assertGreaterThanOrEqual(0, $priority); + $this->assertLessThanOrEqual(100, $priority); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataSettings')] + public function testCanChangeStream(string $settingClass): void { + /** @var ISetting $setting */ + $setting = Server::get($settingClass); + $this->assertIsBool($setting->canChangeStream()); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataSettings')] + public function testIsDefaultEnabledStream(string $settingClass): void { + /** @var ISetting $setting */ + $setting = Server::get($settingClass); + $this->assertIsBool($setting->isDefaultEnabledStream()); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataSettings')] + public function testCanChangeMail(string $settingClass): void { + /** @var ISetting $setting */ + $setting = Server::get($settingClass); + $this->assertIsBool($setting->canChangeMail()); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataSettings')] + public function testIsDefaultEnabledMail(string $settingClass): void { + /** @var ISetting $setting */ + $setting = Server::get($settingClass); + $this->assertIsBool($setting->isDefaultEnabledMail()); + } +} diff --git a/apps/files/tests/AdvancedCapabilitiesTest.php b/apps/files/tests/AdvancedCapabilitiesTest.php new file mode 100644 index 00000000000..f39ac1c873f --- /dev/null +++ b/apps/files/tests/AdvancedCapabilitiesTest.php @@ -0,0 +1,46 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\Files; + +use OCA\Files\Service\SettingsService; +use PHPUnit\Framework\MockObject\MockObject; +use Test\TestCase; + +class AdvancedCapabilitiesTest extends TestCase { + + protected SettingsService&MockObject $service; + protected AdvancedCapabilities $capabilities; + + protected function setUp(): void { + parent::setUp(); + $this->service = $this->createMock(SettingsService::class); + $this->capabilities = new AdvancedCapabilities($this->service); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetCapabilities')] + public function testGetCapabilities(bool $wcf): void { + $this->service + ->expects(self::once()) + ->method('hasFilesWindowsSupport') + ->willReturn($wcf); + + self::assertEqualsCanonicalizing(['files' => [ 'windows_compatible_filenames' => $wcf ]], $this->capabilities->getCapabilities()); + } + + public static function dataGetCapabilities(): array { + return [ + 'WCF enabled' => [ + true, + ], + 'WCF disabled' => [ + false, + ], + ]; + } +} diff --git a/apps/files/tests/backgroundjob/DeleteOrphanedItemsJobTest.php b/apps/files/tests/BackgroundJob/DeleteOrphanedItemsJobTest.php index e802a248a9b..3f811fca407 100644 --- a/apps/files/tests/backgroundjob/DeleteOrphanedItemsJobTest.php +++ b/apps/files/tests/BackgroundJob/DeleteOrphanedItemsJobTest.php @@ -1,29 +1,19 @@ <?php + +declare(strict_types=1); /** - * @author Arthur Schiwon <blizzz@owncloud.com> - * @author Vincent Petry <pvince81@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/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ - namespace OCA\Files\Tests\BackgroundJob; use OCA\Files\BackgroundJob\DeleteOrphanedItems; +use OCP\AppFramework\Utility\ITimeFactory; use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; +use OCP\Server; +use Psr\Log\LoggerInterface; /** * Class DeleteOrphanedItemsJobTest @@ -33,25 +23,27 @@ use OCP\DB\QueryBuilder\IQueryBuilder; * @package Test\BackgroundJob */ class DeleteOrphanedItemsJobTest extends \Test\TestCase { + protected IDBConnection $connection; + protected LoggerInterface $logger; + protected ITimeFactory $timeFactory; - /** @var \OCP\IDBConnection */ - protected $connection; - - protected function setup() { + protected function setUp(): void { parent::setUp(); - $this->connection = \OC::$server->getDatabaseConnection(); + $this->connection = Server::get(IDBConnection::class); + $this->timeFactory = $this->createMock(ITimeFactory::class); + $this->logger = Server::get(LoggerInterface::class); } - protected function cleanMapping($table) { + protected function cleanMapping(string $table): void { $query = $this->connection->getQueryBuilder(); - $query->delete($table)->execute(); + $query->delete($table)->executeStatement(); } - protected function getMappings($table) { + protected function getMappings(string $table): array { $query = $this->connection->getQueryBuilder(); $query->select('*') ->from($table); - $result = $query->execute(); + $result = $query->executeQuery(); $mapping = $result->fetchAll(); $result->closeCursor(); @@ -61,7 +53,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { /** * Test clearing orphaned system tag mappings */ - public function testClearSystemTagMappings() { + public function testClearSystemTagMappings(): void { $this->cleanMapping('systemtag_object_mapping'); $query = $this->connection->getQueryBuilder(); @@ -70,7 +62,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'storage' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), 'path' => $query->createNamedParameter('apps/files/tests/deleteorphanedtagsjobtest.php'), 'path_hash' => $query->createNamedParameter(md5('apps/files/tests/deleteorphanedtagsjobtest.php')), - ])->execute(); + ])->executeStatement(); $fileId = $query->getLastInsertId(); // Existing file @@ -80,7 +72,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'objectid' => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT), 'objecttype' => $query->createNamedParameter('files'), 'systemtagid' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); // Non-existing file $query = $this->connection->getQueryBuilder(); @@ -89,13 +81,13 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'objectid' => $query->createNamedParameter($fileId + 1, IQueryBuilder::PARAM_INT), 'objecttype' => $query->createNamedParameter('files'), 'systemtagid' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); $mapping = $this->getMappings('systemtag_object_mapping'); $this->assertCount(2, $mapping); - $job = new DeleteOrphanedItems(); - $this->invokePrivate($job, 'cleanSystemTags'); + $job = new DeleteOrphanedItems($this->timeFactory, $this->connection, $this->logger); + self::invokePrivate($job, 'cleanSystemTags'); $mapping = $this->getMappings('systemtag_object_mapping'); $this->assertCount(1, $mapping); @@ -103,14 +95,14 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { $query = $this->connection->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))) - ->execute(); + ->executeStatement(); $this->cleanMapping('systemtag_object_mapping'); } /** * Test clearing orphaned system tag mappings */ - public function testClearUserTagMappings() { + public function testClearUserTagMappings(): void { $this->cleanMapping('vcategory_to_object'); $query = $this->connection->getQueryBuilder(); @@ -119,7 +111,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'storage' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), 'path' => $query->createNamedParameter('apps/files/tests/deleteorphanedtagsjobtest.php'), 'path_hash' => $query->createNamedParameter(md5('apps/files/tests/deleteorphanedtagsjobtest.php')), - ])->execute(); + ])->executeStatement(); $fileId = $query->getLastInsertId(); // Existing file @@ -129,7 +121,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'objid' => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT), 'type' => $query->createNamedParameter('files'), 'categoryid' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); // Non-existing file $query = $this->connection->getQueryBuilder(); @@ -138,13 +130,13 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'objid' => $query->createNamedParameter($fileId + 1, IQueryBuilder::PARAM_INT), 'type' => $query->createNamedParameter('files'), 'categoryid' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); $mapping = $this->getMappings('vcategory_to_object'); $this->assertCount(2, $mapping); - $job = new DeleteOrphanedItems(); - $this->invokePrivate($job, 'cleanUserTags'); + $job = new DeleteOrphanedItems($this->timeFactory, $this->connection, $this->logger); + self::invokePrivate($job, 'cleanUserTags'); $mapping = $this->getMappings('vcategory_to_object'); $this->assertCount(1, $mapping); @@ -152,14 +144,14 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { $query = $this->connection->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))) - ->execute(); + ->executeStatement(); $this->cleanMapping('vcategory_to_object'); } /** * Test clearing orphaned system tag mappings */ - public function testClearComments() { + public function testClearComments(): void { $this->cleanMapping('comments'); $query = $this->connection->getQueryBuilder(); @@ -168,7 +160,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'storage' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), 'path' => $query->createNamedParameter('apps/files/tests/deleteorphanedtagsjobtest.php'), 'path_hash' => $query->createNamedParameter(md5('apps/files/tests/deleteorphanedtagsjobtest.php')), - ])->execute(); + ])->executeStatement(); $fileId = $query->getLastInsertId(); // Existing file @@ -179,7 +171,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'object_type' => $query->createNamedParameter('files'), 'actor_id' => $query->createNamedParameter('Alice', IQueryBuilder::PARAM_INT), 'actor_type' => $query->createNamedParameter('users'), - ])->execute(); + ])->executeStatement(); // Non-existing file $query = $this->connection->getQueryBuilder(); @@ -189,13 +181,13 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'object_type' => $query->createNamedParameter('files'), 'actor_id' => $query->createNamedParameter('Alice', IQueryBuilder::PARAM_INT), 'actor_type' => $query->createNamedParameter('users'), - ])->execute(); + ])->executeStatement(); $mapping = $this->getMappings('comments'); $this->assertCount(2, $mapping); - $job = new DeleteOrphanedItems(); - $this->invokePrivate($job, 'cleanComments'); + $job = new DeleteOrphanedItems($this->timeFactory, $this->connection, $this->logger); + self::invokePrivate($job, 'cleanComments'); $mapping = $this->getMappings('comments'); $this->assertCount(1, $mapping); @@ -203,14 +195,14 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { $query = $this->connection->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))) - ->execute(); + ->executeStatement(); $this->cleanMapping('comments'); } /** * Test clearing orphaned system tag mappings */ - public function testClearCommentReadMarks() { + public function testClearCommentReadMarks(): void { $this->cleanMapping('comments_read_markers'); $query = $this->connection->getQueryBuilder(); @@ -219,7 +211,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'storage' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), 'path' => $query->createNamedParameter('apps/files/tests/deleteorphanedtagsjobtest.php'), 'path_hash' => $query->createNamedParameter(md5('apps/files/tests/deleteorphanedtagsjobtest.php')), - ])->execute(); + ])->executeStatement(); $fileId = $query->getLastInsertId(); // Existing file @@ -229,7 +221,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'object_id' => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT), 'object_type' => $query->createNamedParameter('files'), 'user_id' => $query->createNamedParameter('Alice', IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); // Non-existing file $query = $this->connection->getQueryBuilder(); @@ -238,13 +230,13 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'object_id' => $query->createNamedParameter($fileId + 1, IQueryBuilder::PARAM_INT), 'object_type' => $query->createNamedParameter('files'), 'user_id' => $query->createNamedParameter('Alice', IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); $mapping = $this->getMappings('comments_read_markers'); $this->assertCount(2, $mapping); - $job = new DeleteOrphanedItems(); - $this->invokePrivate($job, 'cleanCommentMarkers'); + $job = new DeleteOrphanedItems($this->timeFactory, $this->connection, $this->logger); + self::invokePrivate($job, 'cleanCommentMarkers'); $mapping = $this->getMappings('comments_read_markers'); $this->assertCount(1, $mapping); @@ -252,8 +244,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { $query = $this->connection->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))) - ->execute(); + ->executeStatement(); $this->cleanMapping('comments_read_markers'); } - } diff --git a/apps/files/tests/BackgroundJob/ScanFilesTest.php b/apps/files/tests/BackgroundJob/ScanFilesTest.php new file mode 100644 index 00000000000..00d9ed823f9 --- /dev/null +++ b/apps/files/tests/BackgroundJob/ScanFilesTest.php @@ -0,0 +1,101 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ +namespace OCA\Files\Tests\BackgroundJob; + +use OC\Files\Mount\MountPoint; +use OC\Files\Storage\Temporary; +use OCA\Files\BackgroundJob\ScanFiles; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Config\IUserMountCache; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\IUser; +use OCP\Server; +use Psr\Log\LoggerInterface; +use Test\TestCase; +use Test\Traits\MountProviderTrait; +use Test\Traits\UserTrait; + +/** + * Class ScanFilesTest + * + * @package OCA\Files\Tests\BackgroundJob + * @group DB + */ +class ScanFilesTest extends TestCase { + use UserTrait; + use MountProviderTrait; + + private ScanFiles $scanFiles; + private IUserMountCache $mountCache; + + protected function setUp(): void { + parent::setUp(); + + $config = $this->createMock(IConfig::class); + $dispatcher = $this->createMock(IEventDispatcher::class); + $logger = $this->createMock(LoggerInterface::class); + $connection = Server::get(IDBConnection::class); + $this->mountCache = Server::get(IUserMountCache::class); + + $this->scanFiles = $this->getMockBuilder(ScanFiles::class) + ->setConstructorArgs([ + $config, + $dispatcher, + $logger, + $connection, + $this->createMock(ITimeFactory::class) + ]) + ->onlyMethods(['runScanner']) + ->getMock(); + } + + private function runJob(): void { + self::invokePrivate($this->scanFiles, 'run', [[]]); + } + + private function getUser(string $userId): IUser { + $user = $this->createMock(IUser::class); + $user->method('getUID') + ->willReturn($userId); + return $user; + } + + private function setupStorage(string $user, string $mountPoint) { + $storage = new Temporary([]); + $storage->mkdir('foo'); + $storage->getScanner()->scan(''); + + $this->createUser($user, ''); + $this->mountCache->registerMounts($this->getUser($user), [ + new MountPoint($storage, $mountPoint) + ]); + + return $storage; + } + + public function testAllScanned(): void { + $this->setupStorage('foouser', '/foousers/files/foo'); + + $this->scanFiles->expects($this->never()) + ->method('runScanner'); + $this->runJob(); + } + + public function testUnscanned(): void { + $storage = $this->setupStorage('foouser', '/foousers/files/foo'); + $storage->getCache()->put('foo', ['size' => -1]); + + $this->scanFiles->expects($this->once()) + ->method('runScanner') + ->with('foouser'); + $this->runJob(); + } +} diff --git a/apps/files/tests/Command/DeleteOrphanedFilesTest.php b/apps/files/tests/Command/DeleteOrphanedFilesTest.php new file mode 100644 index 00000000000..a488915e0cb --- /dev/null +++ b/apps/files/tests/Command/DeleteOrphanedFilesTest.php @@ -0,0 +1,138 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ +namespace OCA\Files\Tests\Command; + +use OC\Files\View; +use OCA\Files\Command\DeleteOrphanedFiles; +use OCP\Files\IRootFolder; +use OCP\Files\StorageNotAvailableException; +use OCP\IDBConnection; +use OCP\IUserManager; +use OCP\Server; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Test\TestCase; + +/** + * Class DeleteOrphanedFilesTest + * + * @group DB + * + * @package OCA\Files\Tests\Command + */ +class DeleteOrphanedFilesTest extends TestCase { + + private DeleteOrphanedFiles $command; + private IDBConnection $connection; + private string $user1; + + protected function setUp(): void { + parent::setUp(); + + $this->connection = Server::get(IDBConnection::class); + + $this->user1 = $this->getUniqueID('user1_'); + + $userManager = Server::get(IUserManager::class); + $userManager->createUser($this->user1, 'pass'); + + $this->command = new DeleteOrphanedFiles($this->connection); + } + + protected function tearDown(): void { + $userManager = Server::get(IUserManager::class); + $user1 = $userManager->get($this->user1); + if ($user1) { + $user1->delete(); + } + + $this->logout(); + + parent::tearDown(); + } + + protected function getFile(int $fileId): array { + $query = $this->connection->getQueryBuilder(); + $query->select('*') + ->from('filecache') + ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId))); + return $query->executeQuery()->fetchAll(); + } + + protected function getMounts(int $storageId): array { + $query = $this->connection->getQueryBuilder(); + $query->select('*') + ->from('mounts') + ->where($query->expr()->eq('storage_id', $query->createNamedParameter($storageId))); + return $query->executeQuery()->fetchAll(); + } + + /** + * Test clearing orphaned files + */ + public function testClearFiles(): void { + $input = $this->createMock(InputInterface::class); + $output = $this->createMock(OutputInterface::class); + + $rootFolder = Server::get(IRootFolder::class); + + // scan home storage so that mounts are properly setup + $rootFolder->getUserFolder($this->user1)->getStorage()->getScanner()->scan(''); + + $this->loginAsUser($this->user1); + + $view = new View('/' . $this->user1 . '/'); + $view->mkdir('files/test'); + + $fileInfo = $view->getFileInfo('files/test'); + + $storageId = $fileInfo->getStorage()->getId(); + $numericStorageId = $fileInfo->getStorage()->getStorageCache()->getNumericId(); + + $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is available'); + $this->assertCount(1, $this->getMounts($numericStorageId), 'Asserts that mount is available'); + + $this->command->execute($input, $output); + + $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is still available'); + $this->assertCount(1, $this->getMounts($numericStorageId), 'Asserts that mount is still available'); + + + $deletedRows = $this->connection->executeUpdate('DELETE FROM `*PREFIX*storages` WHERE `id` = ?', [$storageId]); + $this->assertNotNull($deletedRows, 'Asserts that storage got deleted'); + $this->assertSame(1, $deletedRows, 'Asserts that storage got deleted'); + + // parent folder, `files`, ´test` and `welcome.txt` => 4 elements + $calls = [ + '3 orphaned file cache entries deleted', + '0 orphaned file cache extended entries deleted', + '1 orphaned mount entries deleted', + ]; + $output + ->expects($this->exactly(3)) + ->method('writeln') + ->willReturnCallback(function (string $message) use (&$calls): void { + $expected = array_shift($calls); + $this->assertSame($expected, $message); + }); + + $this->command->execute($input, $output); + + $this->assertCount(0, $this->getFile($fileInfo->getId()), 'Asserts that file gets cleaned up'); + $this->assertCount(0, $this->getMounts($numericStorageId), 'Asserts that mount gets cleaned up'); + + // Rescan folder to add back to cache before deleting + $rootFolder->getUserFolder($this->user1)->getStorage()->getScanner()->scan(''); + // since we deleted the storage it might throw a (valid) StorageNotAvailableException + try { + $view->unlink('files/test'); + } catch (StorageNotAvailableException $e) { + } + } +} diff --git a/apps/files/tests/Controller/ApiControllerTest.php b/apps/files/tests/Controller/ApiControllerTest.php new file mode 100644 index 00000000000..e74989eb2f5 --- /dev/null +++ b/apps/files/tests/Controller/ApiControllerTest.php @@ -0,0 +1,300 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ +namespace OCA\Files\Controller; + +use OCA\Files\Service\TagService; +use OCA\Files\Service\UserConfig; +use OCA\Files\Service\ViewConfig; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\Http\FileDisplayResponse; +use OCP\AppFramework\Http\Response; +use OCP\Files\File; +use OCP\Files\Folder; +use OCP\Files\IRootFolder; +use OCP\Files\NotFoundException; +use OCP\Files\SimpleFS\ISimpleFile; +use OCP\Files\Storage\ISharedStorage; +use OCP\Files\Storage\IStorage; +use OCP\Files\StorageNotAvailableException; +use OCP\IConfig; +use OCP\IL10N; +use OCP\IPreview; +use OCP\IRequest; +use OCP\IUser; +use OCP\IUserSession; +use OCP\Share\IManager; +use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; +use Test\TestCase; + +/** + * Class ApiController + * + * @package OCA\Files\Controller + */ +class ApiControllerTest extends TestCase { + private string $appName = 'files'; + private IUser $user; + private IRequest $request; + private TagService $tagService; + private IPreview&MockObject $preview; + private ApiController $apiController; + private IManager $shareManager; + private IConfig $config; + private Folder&MockObject $userFolder; + private UserConfig&MockObject $userConfig; + private ViewConfig&MockObject $viewConfig; + private IL10N&MockObject $l10n; + private IRootFolder&MockObject $rootFolder; + private LoggerInterface&MockObject $logger; + + protected function setUp(): void { + parent::setUp(); + + $this->request = $this->createMock(IRequest::class); + $this->user = $this->createMock(IUser::class); + $this->user->expects($this->any()) + ->method('getUID') + ->willReturn('user1'); + $userSession = $this->createMock(IUserSession::class); + $userSession->expects($this->any()) + ->method('getUser') + ->willReturn($this->user); + $this->tagService = $this->createMock(TagService::class); + $this->shareManager = $this->createMock(IManager::class); + $this->preview = $this->createMock(IPreview::class); + $this->config = $this->createMock(IConfig::class); + $this->userFolder = $this->createMock(Folder::class); + $this->userConfig = $this->createMock(UserConfig::class); + $this->viewConfig = $this->createMock(ViewConfig::class); + $this->l10n = $this->createMock(IL10N::class); + $this->rootFolder = $this->createMock(IRootFolder::class); + $this->logger = $this->createMock(LoggerInterface::class); + + $this->apiController = new ApiController( + $this->appName, + $this->request, + $userSession, + $this->tagService, + $this->preview, + $this->shareManager, + $this->config, + $this->userFolder, + $this->userConfig, + $this->viewConfig, + $this->l10n, + $this->rootFolder, + $this->logger, + ); + } + + public function testUpdateFileTagsEmpty(): void { + $expected = new DataResponse([]); + $this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt')); + } + + public function testUpdateFileTagsWorking(): void { + $this->tagService->expects($this->once()) + ->method('updateFileTags') + ->with('/path.txt', ['Tag1', 'Tag2']); + + $expected = new DataResponse([ + 'tags' => [ + 'Tag1', + 'Tag2' + ], + ]); + $this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2'])); + } + + public function testUpdateFileTagsNotFoundException(): void { + $this->tagService->expects($this->once()) + ->method('updateFileTags') + ->with('/path.txt', ['Tag1', 'Tag2']) + ->willThrowException(new NotFoundException('My error message')); + + $expected = new DataResponse(['message' => 'My error message'], Http::STATUS_NOT_FOUND); + $this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2'])); + } + + public function testUpdateFileTagsStorageNotAvailableException(): void { + $this->tagService->expects($this->once()) + ->method('updateFileTags') + ->with('/path.txt', ['Tag1', 'Tag2']) + ->willThrowException(new StorageNotAvailableException('My error message')); + + $expected = new DataResponse(['message' => 'My error message'], Http::STATUS_SERVICE_UNAVAILABLE); + $this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2'])); + } + + public function testUpdateFileTagsStorageGenericException(): void { + $this->tagService->expects($this->once()) + ->method('updateFileTags') + ->with('/path.txt', ['Tag1', 'Tag2']) + ->willThrowException(new \Exception('My error message')); + + $expected = new DataResponse(['message' => 'My error message'], Http::STATUS_NOT_FOUND); + $this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2'])); + } + + public function testGetThumbnailInvalidSize(): void { + $this->userFolder->method('get') + ->with($this->equalTo('')) + ->willThrowException(new NotFoundException()); + $expected = new DataResponse(['message' => 'Requested size must be numeric and a positive value.'], Http::STATUS_BAD_REQUEST); + $this->assertEquals($expected, $this->apiController->getThumbnail(0, 0, '')); + } + + public function testGetThumbnailInvalidImage(): void { + $storage = $this->createMock(IStorage::class); + $storage->method('instanceOfStorage')->with(ISharedStorage::class)->willReturn(false); + + $file = $this->createMock(File::class); + $file->method('getId')->willReturn(123); + $file->method('getStorage')->willReturn($storage); + $this->userFolder->method('get') + ->with($this->equalTo('unknown.jpg')) + ->willReturn($file); + $this->preview->expects($this->once()) + ->method('getPreview') + ->with($file, 10, 10, true) + ->willThrowException(new NotFoundException()); + $expected = new DataResponse(['message' => 'File not found.'], Http::STATUS_NOT_FOUND); + $this->assertEquals($expected, $this->apiController->getThumbnail(10, 10, 'unknown.jpg')); + } + + public function testGetThumbnailInvalidPartFile(): void { + $file = $this->createMock(File::class); + $file->method('getId')->willReturn(0); + $this->userFolder->method('get') + ->with($this->equalTo('unknown.jpg')) + ->willReturn($file); + $expected = new DataResponse(['message' => 'File not found.'], Http::STATUS_NOT_FOUND); + $this->assertEquals($expected, $this->apiController->getThumbnail(10, 10, 'unknown.jpg')); + } + + public function testGetThumbnailSharedNoDownload(): void { + $share = $this->createMock(IShare::class); + $share->expects(self::once()) + ->method('canSeeContent') + ->willReturn(false); + + $storage = $this->createMock(ISharedStorage::class); + $storage->expects(self::once()) + ->method('instanceOfStorage') + ->with(ISharedStorage::class) + ->willReturn(true); + $storage->expects(self::once()) + ->method('getShare') + ->willReturn($share); + + $file = $this->createMock(File::class); + $file->method('getId')->willReturn(123); + $file->method('getStorage')->willReturn($storage); + + $this->userFolder->method('get') + ->with('unknown.jpg') + ->willReturn($file); + + $this->preview->expects($this->never()) + ->method('getPreview'); + + $expected = new DataResponse(['message' => 'File not found.'], Http::STATUS_NOT_FOUND); + $this->assertEquals($expected, $this->apiController->getThumbnail(10, 10, 'unknown.jpg')); + } + + public function testGetThumbnailShared(): void { + $share = $this->createMock(IShare::class); + $share->expects(self::once()) + ->method('canSeeContent') + ->willReturn(true); + + $storage = $this->createMock(ISharedStorage::class); + $storage->expects(self::once()) + ->method('instanceOfStorage') + ->with(ISharedStorage::class) + ->willReturn(true); + $storage->expects(self::once()) + ->method('getShare') + ->willReturn($share); + + $file = $this->createMock(File::class); + $file->method('getId')->willReturn(123); + $file->method('getStorage')->willReturn($storage); + + $this->userFolder->method('get') + ->with($this->equalTo('known.jpg')) + ->willReturn($file); + $preview = $this->createMock(ISimpleFile::class); + $preview->method('getName')->willReturn('my name'); + $preview->method('getMTime')->willReturn(42); + $this->preview->expects($this->once()) + ->method('getPreview') + ->with($this->equalTo($file), 10, 10, true) + ->willReturn($preview); + + $ret = $this->apiController->getThumbnail(10, 10, 'known.jpg'); + + $this->assertEquals(Http::STATUS_OK, $ret->getStatus()); + $this->assertInstanceOf(FileDisplayResponse::class, $ret); + } + + public function testGetThumbnail(): void { + $storage = $this->createMock(IStorage::class); + $storage->method('instanceOfStorage')->with(ISharedStorage::class)->willReturn(false); + + $file = $this->createMock(File::class); + $file->method('getId')->willReturn(123); + $file->method('getStorage')->willReturn($storage); + + $this->userFolder->method('get') + ->with($this->equalTo('known.jpg')) + ->willReturn($file); + $preview = $this->createMock(ISimpleFile::class); + $preview->method('getName')->willReturn('my name'); + $preview->method('getMTime')->willReturn(42); + $this->preview->expects($this->once()) + ->method('getPreview') + ->with($this->equalTo($file), 10, 10, true) + ->willReturn($preview); + + $ret = $this->apiController->getThumbnail(10, 10, 'known.jpg'); + + $this->assertEquals(Http::STATUS_OK, $ret->getStatus()); + $this->assertInstanceOf(FileDisplayResponse::class, $ret); + } + + public function testShowHiddenFiles(): void { + $show = false; + + $this->config->expects($this->once()) + ->method('setUserValue') + ->with($this->user->getUID(), 'files', 'show_hidden', '0'); + + $expected = new Response(); + $actual = $this->apiController->showHiddenFiles($show); + + $this->assertEquals($expected, $actual); + } + + public function testCropImagePreviews(): void { + $crop = true; + + $this->config->expects($this->once()) + ->method('setUserValue') + ->with($this->user->getUID(), 'files', 'crop_image_previews', '1'); + + $expected = new Response(); + $actual = $this->apiController->cropImagePreviews($crop); + + $this->assertEquals($expected, $actual); + } +} diff --git a/apps/files/tests/Controller/ConversionApiControllerTest.php b/apps/files/tests/Controller/ConversionApiControllerTest.php new file mode 100644 index 00000000000..659fbe1a956 --- /dev/null +++ b/apps/files/tests/Controller/ConversionApiControllerTest.php @@ -0,0 +1,96 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCA\Files\Controller; + +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\OCS\OCSException; +use OCP\AppFramework\OCS\OCSNotFoundException; +use OCP\Files\Conversion\IConversionManager; +use OCP\Files\File; +use OCP\Files\Folder; +use OCP\Files\IRootFolder; +use OCP\IL10N; +use OCP\IRequest; +use PHPUnit\Framework\MockObject\MockObject; +use Test\TestCase; + +/** + * Class ConversionApiController + * + * @package OCA\Files\Controller + */ +class ConversionApiControllerTest extends TestCase { + private string $appName = 'files'; + private ConversionApiController $conversionApiController; + private IRequest&MockObject $request; + private IConversionManager&MockObject $fileConversionManager; + private IRootFolder&MockObject $rootFolder; + private File&MockObject $file; + private Folder&MockObject $userFolder; + private IL10N&MockObject $l10n; + private string $user; + + protected function setUp(): void { + parent::setUp(); + + $this->request = $this->createMock(IRequest::class); + $this->fileConversionManager = $this->createMock(IConversionManager::class); + $this->file = $this->createMock(File::class); + $this->l10n = $this->createMock(IL10N::class); + $this->user = 'userid'; + + $this->userFolder = $this->createMock(Folder::class); + + $this->rootFolder = $this->createMock(IRootFolder::class); + $this->rootFolder->method('getUserFolder')->with($this->user)->willReturn($this->userFolder); + + $this->conversionApiController = new ConversionApiController( + $this->appName, + $this->request, + $this->fileConversionManager, + $this->rootFolder, + $this->l10n, + $this->user, + ); + } + + public function testThrowsNotFoundException(): void { + $this->expectException(OCSNotFoundException::class); + $this->conversionApiController->convert(42, 'image/png'); + } + + public function testThrowsOcsException(): void { + $this->userFolder->method('getFirstNodeById')->with(42)->willReturn($this->file); + $this->fileConversionManager->method('convert')->willThrowException(new \Exception()); + + $this->expectException(OCSException::class); + $this->conversionApiController->convert(42, 'image/png'); + } + + public function testConvert(): void { + $convertedFileAbsolutePath = $this->user . '/files/test.png'; + + $this->userFolder->method('getFirstNodeById')->with(42)->willReturn($this->file); + $this->userFolder->method('getRelativePath')->with($convertedFileAbsolutePath)->willReturn('/test.png'); + $this->userFolder->method('get')->with('/test.png')->willReturn($this->file); + + $this->file->method('getId')->willReturn(42); + + $this->fileConversionManager->method('convert')->with($this->file, 'image/png', null)->willReturn($convertedFileAbsolutePath); + + $actual = $this->conversionApiController->convert(42, 'image/png', null); + $expected = new DataResponse([ + 'path' => '/test.png', + 'fileId' => 42, + ], Http::STATUS_CREATED); + + $this->assertEquals($expected, $actual); + } +} diff --git a/apps/files/tests/Controller/ViewControllerTest.php b/apps/files/tests/Controller/ViewControllerTest.php new file mode 100644 index 00000000000..01aa955a13e --- /dev/null +++ b/apps/files/tests/Controller/ViewControllerTest.php @@ -0,0 +1,313 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ +namespace OCA\Files\Tests\Controller; + +use OC\Files\FilenameValidator; +use OC\Route\Router; +use OC\URLGenerator; +use OCA\Files\Controller\ViewController; +use OCA\Files\Service\UserConfig; +use OCA\Files\Service\ViewConfig; +use OCP\App\IAppManager; +use OCP\AppFramework\Http\ContentSecurityPolicy; +use OCP\AppFramework\Http\RedirectResponse; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IInitialState; +use OCP\Authentication\TwoFactorAuth\IRegistry; +use OCP\Diagnostics\IEventLogger; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\File; +use OCP\Files\Folder; +use OCP\Files\IRootFolder; +use OCP\Files\Template\ITemplateManager; +use OCP\ICacheFactory; +use OCP\IConfig; +use OCP\IL10N; +use OCP\IRequest; +use OCP\IURLGenerator; +use OCP\IUser; +use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Container\ContainerInterface; +use Psr\Log\LoggerInterface; +use Test\TestCase; + +/** + * Class ViewControllerTest + * + * @group RoutingWeirdness + * + * @package OCA\Files\Tests\Controller + */ +class ViewControllerTest extends TestCase { + private ContainerInterface&MockObject $container; + private IAppManager&MockObject $appManager; + private ICacheFactory&MockObject $cacheFactory; + private IConfig&MockObject $config; + private IEventDispatcher $eventDispatcher; + private IEventLogger&MockObject $eventLogger; + private IInitialState&MockObject $initialState; + private IL10N&MockObject $l10n; + private IRequest&MockObject $request; + private IRootFolder&MockObject $rootFolder; + private ITemplateManager&MockObject $templateManager; + private IURLGenerator $urlGenerator; + private IUser&MockObject $user; + private IUserSession&MockObject $userSession; + private LoggerInterface&MockObject $logger; + private UserConfig&MockObject $userConfig; + private ViewConfig&MockObject $viewConfig; + private Router $router; + private IRegistry&MockObject $twoFactorRegistry; + + private ViewController&MockObject $viewController; + + protected function setUp(): void { + parent::setUp(); + $this->appManager = $this->createMock(IAppManager::class); + $this->config = $this->createMock(IConfig::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); + $this->initialState = $this->createMock(IInitialState::class); + $this->l10n = $this->createMock(IL10N::class); + $this->request = $this->createMock(IRequest::class); + $this->rootFolder = $this->createMock(IRootFolder::class); + $this->templateManager = $this->createMock(ITemplateManager::class); + $this->userConfig = $this->createMock(UserConfig::class); + $this->userSession = $this->createMock(IUserSession::class); + $this->viewConfig = $this->createMock(ViewConfig::class); + $this->twoFactorRegistry = $this->createMock(IRegistry::class); + + $this->user = $this->getMockBuilder(IUser::class)->getMock(); + $this->user->expects($this->any()) + ->method('getUID') + ->willReturn('testuser1'); + $this->userSession->expects($this->any()) + ->method('getUser') + ->willReturn($this->user); + + // Make sure we know the app is enabled + $this->appManager->expects($this->any()) + ->method('cleanAppId') + ->willReturnArgument(0); + $this->appManager->expects($this->any()) + ->method('getAppPath') + ->willReturnCallback(fn (string $appid): string => \OC::$SERVERROOT . '/apps/' . $appid); + $this->appManager->expects($this->any()) + ->method('isAppLoaded') + ->willReturn(true); + + $this->cacheFactory = $this->createMock(ICacheFactory::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->eventLogger = $this->createMock(IEventLogger::class); + $this->container = $this->createMock(ContainerInterface::class); + $this->router = new Router( + $this->logger, + $this->request, + $this->config, + $this->eventLogger, + $this->container, + $this->appManager, + ); + + // Create a real URLGenerator instance to generate URLs + $this->urlGenerator = new URLGenerator( + $this->config, + $this->userSession, + $this->cacheFactory, + $this->request, + $this->router + ); + + $filenameValidator = $this->createMock(FilenameValidator::class); + $this->viewController = $this->getMockBuilder(ViewController::class) + ->setConstructorArgs([ + 'files', + $this->request, + $this->urlGenerator, + $this->l10n, + $this->config, + $this->eventDispatcher, + $this->userSession, + $this->appManager, + $this->rootFolder, + $this->initialState, + $this->templateManager, + $this->userConfig, + $this->viewConfig, + $filenameValidator, + $this->twoFactorRegistry, + ]) + ->onlyMethods([ + 'getStorageInfo', + ]) + ->getMock(); + } + + public function testIndexWithRegularBrowser(): void { + $this->viewController + ->expects($this->any()) + ->method('getStorageInfo') + ->willReturn([ + 'used' => 123, + 'quota' => 100, + 'total' => 100, + 'relative' => 123, + 'owner' => 'MyName', + 'ownerDisplayName' => 'MyDisplayName', + ]); + + $this->config + ->method('getUserValue') + ->willReturnMap([ + [$this->user->getUID(), 'files', 'file_sorting', 'name', 'name'], + [$this->user->getUID(), 'files', 'file_sorting_direction', 'asc', 'asc'], + [$this->user->getUID(), 'files', 'files_sorting_configs', '{}', '{}'], + [$this->user->getUID(), 'files', 'show_hidden', false, false], + [$this->user->getUID(), 'files', 'crop_image_previews', true, true], + [$this->user->getUID(), 'files', 'show_grid', true], + ]); + + $baseFolderFiles = $this->getMockBuilder(Folder::class)->getMock(); + + $this->rootFolder->expects($this->any()) + ->method('getUserFolder') + ->with('testuser1') + ->willReturn($baseFolderFiles); + + $this->config + ->expects($this->any()) + ->method('getAppValue') + ->willReturnArgument(2); + + $expected = new TemplateResponse( + 'files', + 'index', + ); + $policy = new ContentSecurityPolicy(); + $policy->addAllowedWorkerSrcDomain('\'self\''); + $policy->addAllowedFrameDomain('\'self\''); + $expected->setContentSecurityPolicy($policy); + + $this->assertEquals($expected, $this->viewController->index('MyDir', 'MyView')); + } + + public static function dataTestShortRedirect(): array { + // openfile is true by default + // opendetails is undefined by default + // both will be evaluated as truthy + return [ + [null, null, '/index.php/apps/files/files/123456?openfile=true'], + ['', null, '/index.php/apps/files/files/123456?openfile=true'], + [null, '', '/index.php/apps/files/files/123456?openfile=true&opendetails=true'], + ['', '', '/index.php/apps/files/files/123456?openfile=true&opendetails=true'], + ['false', '', '/index.php/apps/files/files/123456?openfile=false'], + [null, 'false', '/index.php/apps/files/files/123456?openfile=true&opendetails=false'], + ['true', 'false', '/index.php/apps/files/files/123456?openfile=true&opendetails=false'], + ['false', 'true', '/index.php/apps/files/files/123456?openfile=false&opendetails=true'], + ['false', 'false', '/index.php/apps/files/files/123456?openfile=false&opendetails=false'], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestShortRedirect')] + public function testShortRedirect(?string $openfile, ?string $opendetails, string $result): void { + $this->appManager->expects($this->any()) + ->method('isEnabledForUser') + ->with('files') + ->willReturn(true); + + $baseFolderFiles = $this->getMockBuilder(Folder::class)->getMock(); + $this->rootFolder->expects($this->any()) + ->method('getUserFolder') + ->with('testuser1') + ->willReturn($baseFolderFiles); + + $parentNode = $this->getMockBuilder(Folder::class)->getMock(); + $parentNode->expects($this->once()) + ->method('getPath') + ->willReturn('testuser1/files/Folder'); + + $node = $this->getMockBuilder(File::class)->getMock(); + $node->expects($this->once()) + ->method('getParent') + ->willReturn($parentNode); + + $baseFolderFiles->expects($this->any()) + ->method('getFirstNodeById') + ->with(123456) + ->willReturn($node); + + $response = $this->viewController->showFile('123456', $opendetails, $openfile); + $this->assertStringContainsString($result, $response->getHeaders()['Location']); + } + + public function testShowFileRouteWithTrashedFile(): void { + $this->appManager->expects($this->exactly(2)) + ->method('isEnabledForUser') + ->willReturn(true); + + $parentNode = $this->createMock(Folder::class); + $parentNode->expects($this->once()) + ->method('getPath') + ->willReturn('testuser1/files_trashbin/files/test.d1462861890/sub'); + + $baseFolderFiles = $this->createMock(Folder::class); + $baseFolderTrash = $this->createMock(Folder::class); + + $this->rootFolder->expects($this->any()) + ->method('getUserFolder') + ->with('testuser1') + ->willReturn($baseFolderFiles); + $this->rootFolder->expects($this->once()) + ->method('get') + ->with('testuser1/files_trashbin/files/') + ->willReturn($baseFolderTrash); + + $baseFolderFiles->expects($this->any()) + ->method('getFirstNodeById') + ->with(123) + ->willReturn(null); + + $node = $this->createMock(File::class); + $node->expects($this->once()) + ->method('getParent') + ->willReturn($parentNode); + + $baseFolderTrash->expects($this->once()) + ->method('getFirstNodeById') + ->with(123) + ->willReturn($node); + $baseFolderTrash->expects($this->once()) + ->method('getRelativePath') + ->with('testuser1/files_trashbin/files/test.d1462861890/sub') + ->willReturn('/test.d1462861890/sub'); + + $expected = new RedirectResponse('/index.php/apps/files/trashbin/123?dir=/test.d1462861890/sub'); + $this->assertEquals($expected, $this->viewController->index('', '', '123')); + } + + public function testTwoFactorAuthEnabled(): void { + $this->twoFactorRegistry->method('getProviderStates') + ->willReturn([ + 'totp' => true, + 'backup_codes' => true, + ]); + + $invokedCountProvideInitialState = $this->exactly(9); + $this->initialState->expects($invokedCountProvideInitialState) + ->method('provideInitialState') + ->willReturnCallback(function ($key, $data) use ($invokedCountProvideInitialState) { + if ($invokedCountProvideInitialState->numberOfInvocations() === 9) { + $this->assertEquals('isTwoFactorEnabled', $key); + $this->assertTrue($data); + } + }); + + $this->viewController->index('', '', null); + } +} diff --git a/apps/files/tests/HelperTest.php b/apps/files/tests/HelperTest.php new file mode 100644 index 00000000000..ba93fa0efdf --- /dev/null +++ b/apps/files/tests/HelperTest.php @@ -0,0 +1,95 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ + +use OC\Files\FileInfo; +use OCA\Files\Helper; + +class HelperTest extends \Test\TestCase { + private static function makeFileInfo($name, $size, $mtime, $isDir = false): FileInfo { + return new FileInfo( + '/' . $name, + null, + '/', + [ + 'name' => $name, + 'size' => $size, + 'mtime' => $mtime, + 'type' => $isDir ? 'dir' : 'file', + 'mimetype' => $isDir ? 'httpd/unix-directory' : 'application/octet-stream' + ], + null + ); + } + + /** + * Returns a file list for testing + */ + private static function getTestFileList(): array { + return [ + self::makeFileInfo('a.txt', 4, 2.3 * pow(10, 9)), + self::makeFileInfo('q.txt', 5, 150), + self::makeFileInfo('subdir2', 87, 128, true), + self::makeFileInfo('b.txt', 2.2 * pow(10, 9), 800), + self::makeFileInfo('o.txt', 12, 100), + self::makeFileInfo('subdir', 88, 125, true), + ]; + } + + public static function sortDataProvider(): array { + return [ + [ + 'name', + false, + ['subdir', 'subdir2', 'a.txt', 'b.txt', 'o.txt', 'q.txt'], + ], + [ + 'name', + true, + ['q.txt', 'o.txt', 'b.txt', 'a.txt', 'subdir2', 'subdir'], + ], + [ + 'size', + false, + ['a.txt', 'q.txt', 'o.txt', 'subdir2', 'subdir', 'b.txt'], + ], + [ + 'size', + true, + ['b.txt', 'subdir', 'subdir2', 'o.txt', 'q.txt', 'a.txt'], + ], + [ + 'mtime', + false, + ['o.txt', 'subdir', 'subdir2', 'q.txt', 'b.txt', 'a.txt'], + ], + [ + 'mtime', + true, + ['a.txt', 'b.txt', 'q.txt', 'subdir2', 'subdir', 'o.txt'], + ], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('sortDataProvider')] + public function testSortByName(string $sort, bool $sortDescending, array $expectedOrder): void { + if (($sort === 'mtime') && (PHP_INT_SIZE < 8)) { + $this->markTestSkipped('Skip mtime sorting on 32bit'); + } + $files = self::getTestFileList(); + $files = Helper::sortFiles($files, $sort, $sortDescending); + $fileNames = []; + foreach ($files as $fileInfo) { + $fileNames[] = $fileInfo->getName(); + } + $this->assertEquals( + $expectedOrder, + $fileNames + ); + } +} diff --git a/apps/files/tests/Service/TagServiceTest.php b/apps/files/tests/Service/TagServiceTest.php new file mode 100644 index 00000000000..424e483102c --- /dev/null +++ b/apps/files/tests/Service/TagServiceTest.php @@ -0,0 +1,121 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ +namespace OCA\Files\Tests\Service; + +use OCA\Files\Service\TagService; +use OCP\Activity\IManager; +use OCP\Files\Folder; +use OCP\Files\IRootFolder; +use OCP\Files\NotFoundException; +use OCP\ITagManager; +use OCP\ITags; +use OCP\IUser; +use OCP\IUserManager; +use OCP\IUserSession; +use OCP\Server; +use PHPUnit\Framework\MockObject\MockObject; + +/** + * Class TagServiceTest + * + * @group DB + * + * @package OCA\Files + */ +class TagServiceTest extends \Test\TestCase { + private string $user; + private IUserSession&MockObject $userSession; + private IManager&MockObject $activityManager; + private Folder $root; + private TagService&MockObject $tagService; + private ITags $tagger; + + protected function setUp(): void { + parent::setUp(); + $this->user = static::getUniqueID('user'); + $this->activityManager = $this->createMock(IManager::class); + Server::get(IUserManager::class)->createUser($this->user, 'test'); + \OC_User::setUserId($this->user); + \OC_Util::setupFS($this->user); + $user = $this->createMock(IUser::class); + /** + * @var IUserSession + */ + $this->userSession = $this->createMock(IUserSession::class); + $this->userSession->expects($this->any()) + ->method('getUser') + ->withAnyParameters() + ->willReturn($user); + + $this->root = Server::get(IRootFolder::class)->getUserFolder($this->user); + + $this->tagger = Server::get(ITagManager::class)->load('files'); + $this->tagService = $this->getTagService(); + } + + protected function getTagService(array $methods = []): TagService&MockObject { + return $this->getMockBuilder(TagService::class) + ->setConstructorArgs([ + $this->userSession, + $this->activityManager, + $this->tagger, + $this->root, + ]) + ->onlyMethods($methods) + ->getMock(); + } + + protected function tearDown(): void { + \OC_User::setUserId(''); + $user = Server::get(IUserManager::class)->get($this->user); + if ($user !== null) { + $user->delete(); + } + + parent::tearDown(); + } + + public function testUpdateFileTags(): void { + $tag1 = 'tag1'; + $tag2 = 'tag2'; + + $subdir = $this->root->newFolder('subdir'); + $testFile = $subdir->newFile('test.txt'); + $testFile->putContent('test contents'); + + $fileId = $testFile->getId(); + + // set tags + $this->tagService->updateFileTags('subdir/test.txt', [$tag1, $tag2]); + + $this->assertEquals([$fileId], $this->tagger->getIdsForTag($tag1)); + $this->assertEquals([$fileId], $this->tagger->getIdsForTag($tag2)); + + // remove tag + $this->tagService->updateFileTags('subdir/test.txt', [$tag2]); + $this->assertEquals([], $this->tagger->getIdsForTag($tag1)); + $this->assertEquals([$fileId], $this->tagger->getIdsForTag($tag2)); + + // clear tags + $this->tagService->updateFileTags('subdir/test.txt', []); + $this->assertEquals([], $this->tagger->getIdsForTag($tag1)); + $this->assertEquals([], $this->tagger->getIdsForTag($tag2)); + + // non-existing file + $caught = false; + try { + $this->tagService->updateFileTags('subdir/unexist.txt', [$tag1]); + } catch (NotFoundException $e) { + $caught = true; + } + $this->assertTrue($caught); + + $subdir->delete(); + } +} diff --git a/apps/files/tests/activitytest.php b/apps/files/tests/activitytest.php deleted file mode 100644 index 5e73ff0b5dd..00000000000 --- a/apps/files/tests/activitytest.php +++ /dev/null @@ -1,375 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * - * @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 OCA\Files\Tests; - -use OCA\Files\Activity; -use Test\TestCase; - -/** - * Class ActivityTest - * - * @group DB - * @package OCA\Files\Tests - */ -class ActivityTest extends TestCase { - - /** @var \OC\ActivityManager */ - private $activityManager; - - /** @var \OCP\IRequest|\PHPUnit_Framework_MockObject_MockObject */ - protected $request; - - /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject */ - protected $session; - - /** @var \OCP\IConfig|\PHPUnit_Framework_MockObject_MockObject */ - protected $config; - - /** @var \OCA\Files\ActivityHelper|\PHPUnit_Framework_MockObject_MockObject */ - protected $activityHelper; - - /** @var \OCP\L10N\IFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $l10nFactory; - - /** @var \OCA\Files\Activity */ - protected $activityExtension; - - protected function setUp() { - parent::setUp(); - - $this->request = $this->getMockBuilder('OCP\IRequest') - ->disableOriginalConstructor() - ->getMock(); - $this->session = $this->getMockBuilder('OCP\IUserSession') - ->disableOriginalConstructor() - ->getMock(); - $this->config = $this->getMockBuilder('OCP\IConfig') - ->disableOriginalConstructor() - ->getMock(); - $this->activityHelper = $this->getMockBuilder('OCA\Files\ActivityHelper') - ->disableOriginalConstructor() - ->getMock(); - - $this->activityManager = new \OC\ActivityManager( - $this->request, - $this->session, - $this->config - ); - - $this->l10nFactory = $this->getMockBuilder('OCP\L10N\IFactory') - ->disableOriginalConstructor() - ->getMock(); - $deL10n = $this->getMockBuilder('OC_L10N') - ->disableOriginalConstructor() - ->getMock(); - $deL10n->expects($this->any()) - ->method('t') - ->willReturnCallback(function ($argument) { - return 'translate(' . $argument . ')'; - }); - - $this->l10nFactory->expects($this->any()) - ->method('get') - ->willReturnMap([ - ['files', null, new \OC_L10N('files', 'en')], - ['files', 'en', new \OC_L10N('files', 'en')], - ['files', 'de', $deL10n], - ]); - - $this->activityExtension = $activityExtension = new Activity( - $this->l10nFactory, - $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), - $this->activityManager, - $this->activityHelper, - \OC::$server->getDatabaseConnection(), - $this->config - ); - - $this->activityManager->registerExtension(function() use ($activityExtension) { - return $activityExtension; - }); - } - - public function testNotificationTypes() { - $result = $this->activityExtension->getNotificationTypes('en'); - $this->assertTrue(is_array($result), 'Asserting getNotificationTypes() returns an array'); - $this->assertCount(5, $result); - $this->assertArrayHasKey(Activity::TYPE_SHARE_CREATED, $result); - $this->assertArrayHasKey(Activity::TYPE_SHARE_CHANGED, $result); - $this->assertArrayHasKey(Activity::TYPE_FAVORITES, $result); - $this->assertArrayHasKey(Activity::TYPE_SHARE_DELETED, $result); - $this->assertArrayHasKey(Activity::TYPE_SHARE_RESTORED, $result); - } - - public function testDefaultTypes() { - $result = $this->activityExtension->getDefaultTypes('stream'); - $this->assertTrue(is_array($result), 'Asserting getDefaultTypes(stream) returns an array'); - $this->assertCount(4, $result); - $result = array_flip($result); - $this->assertArrayHasKey(Activity::TYPE_SHARE_CREATED, $result); - $this->assertArrayHasKey(Activity::TYPE_SHARE_CHANGED, $result); - $this->assertArrayNotHasKey(Activity::TYPE_FAVORITES, $result); - $this->assertArrayHasKey(Activity::TYPE_SHARE_DELETED, $result); - $this->assertArrayHasKey(Activity::TYPE_SHARE_RESTORED, $result); - - $result = $this->activityExtension->getDefaultTypes('email'); - $this->assertFalse($result, 'Asserting getDefaultTypes(email) returns false'); - } - - public function testTranslate() { - $this->assertFalse( - $this->activityExtension->translate('files_sharing', '', [], false, false, 'en'), - 'Asserting that no translations are set for files_sharing' - ); - - // Test english - $this->assertNotFalse( - $this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'en'), - 'Asserting that translations are set for files.deleted_self' - ); - $this->assertStringStartsWith( - 'You deleted ', - $this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'en') - ); - - // Test translation - $this->assertNotFalse( - $this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'de'), - 'Asserting that translations are set for files.deleted_self' - ); - $this->assertStringStartsWith( - 'translate(You deleted ', - $this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'de') - ); - } - - public function testGetSpecialParameterList() { - $this->assertFalse( - $this->activityExtension->getSpecialParameterList('files_sharing', ''), - 'Asserting that no special parameters are set for files_sharing' - ); - } - - public function typeIconData() { - return [ - [Activity::TYPE_SHARE_CHANGED, 'icon-change'], - [Activity::TYPE_SHARE_CREATED, 'icon-add-color'], - [Activity::TYPE_SHARE_DELETED, 'icon-delete-color'], - [Activity::TYPE_SHARE_RESTORED, false], - [Activity::TYPE_FAVORITES, false], - ['unknown type', false], - ]; - } - - /** - * @dataProvider typeIconData - * - * @param string $type - * @param mixed $expected - */ - public function testTypeIcon($type, $expected) { - $this->assertSame($expected, $this->activityExtension->getTypeIcon($type)); - } - - public function testGroupParameter() { - $this->assertFalse( - $this->activityExtension->getGroupParameter(['app' => 'files_sharing']), - 'Asserting that no group parameters are set for files_sharing' - ); - } - - public function testNavigation() { - $result = $this->activityExtension->getNavigation(); - $this->assertCount(1, $result['top']); - $this->assertArrayHasKey(Activity::FILTER_FAVORITES, $result['top']); - - $this->assertCount(1, $result['apps']); - $this->assertArrayHasKey(Activity::FILTER_FILES, $result['apps']); - } - - public function testIsFilterValid() { - $this->assertTrue($this->activityExtension->isFilterValid(Activity::FILTER_FAVORITES)); - $this->assertTrue($this->activityExtension->isFilterValid(Activity::FILTER_FILES)); - $this->assertFalse($this->activityExtension->isFilterValid('unknown filter')); - } - - public function filterNotificationTypesData() { - return [ - [ - Activity::FILTER_FILES, - [ - 'NT0', - Activity::TYPE_SHARE_CREATED, - Activity::TYPE_SHARE_CHANGED, - Activity::TYPE_SHARE_DELETED, - Activity::TYPE_SHARE_RESTORED, - Activity::TYPE_FAVORITES, - ], [ - Activity::TYPE_SHARE_CREATED, - Activity::TYPE_SHARE_CHANGED, - Activity::TYPE_SHARE_DELETED, - Activity::TYPE_SHARE_RESTORED, - ], - ], - [ - Activity::FILTER_FILES, - [ - 'NT0', - Activity::TYPE_SHARE_CREATED, - Activity::TYPE_FAVORITES, - ], - [ - Activity::TYPE_SHARE_CREATED, - ], - ], - [ - Activity::FILTER_FAVORITES, - [ - 'NT0', - Activity::TYPE_SHARE_CREATED, - Activity::TYPE_SHARE_CHANGED, - Activity::TYPE_SHARE_DELETED, - Activity::TYPE_SHARE_RESTORED, - Activity::TYPE_FAVORITES, - ], [ - Activity::TYPE_SHARE_CREATED, - Activity::TYPE_SHARE_CHANGED, - Activity::TYPE_SHARE_DELETED, - Activity::TYPE_SHARE_RESTORED, - ], - ], - [ - 'unknown filter', - [ - 'NT0', - Activity::TYPE_SHARE_CREATED, - Activity::TYPE_SHARE_CHANGED, - Activity::TYPE_SHARE_DELETED, - Activity::TYPE_SHARE_RESTORED, - Activity::TYPE_FAVORITES, - ], - false, - ], - ]; - } - - /** - * @dataProvider filterNotificationTypesData - * - * @param string $filter - * @param array $types - * @param mixed $expected - */ - public function testFilterNotificationTypes($filter, $types, $expected) { - $result = $this->activityExtension->filterNotificationTypes($types, $filter); - $this->assertEquals($expected, $result); - } - - public function queryForFilterData() { - return [ - [ - new \RuntimeException(), - '`app` = ?', - ['files'] - ], - [ - [ - 'items' => [], - 'folders' => [], - ], - ' CASE WHEN `app` <> ? THEN 1 WHEN `app` = ? AND ((`type` <> ? AND `type` <> ?)) THEN 1 ELSE 0 END = 1 ', - ['files', 'files', Activity::TYPE_SHARE_CREATED, Activity::TYPE_SHARE_CHANGED] - ], - [ - [ - 'items' => ['file.txt', 'folder'], - 'folders' => ['folder'], - ], - ' CASE WHEN `app` <> ? THEN 1 WHEN `app` = ? AND ((`type` <> ? AND `type` <> ?) OR `file` = ? OR `file` = ? OR `file` LIKE ?) THEN 1 ELSE 0 END = 1 ', - ['files', 'files', Activity::TYPE_SHARE_CREATED, Activity::TYPE_SHARE_CHANGED, 'file.txt', 'folder', 'folder/%'] - ], - ]; - } - - /** - * @dataProvider queryForFilterData - * - * @param mixed $will - * @param string $query - * @param array $parameters - */ - public function testQueryForFilter($will, $query, $parameters) { - $this->mockUserSession('test'); - - $this->config->expects($this->any()) - ->method('getUserValue') - ->willReturnMap([ - ['test', 'activity', 'notify_stream_' . Activity::TYPE_FAVORITES, false, true], - ]); - if (is_array($will)) { - $this->activityHelper->expects($this->any()) - ->method('getFavoriteFilePaths') - ->with('test') - ->willReturn($will); - } else { - $this->activityHelper->expects($this->any()) - ->method('getFavoriteFilePaths') - ->with('test') - ->willThrowException($will); - } - - $result = $this->activityExtension->getQueryForFilter('all'); - $this->assertEquals([$query, $parameters], $result); - - $this->executeQueryForFilter($result); - } - - public function executeQueryForFilter(array $result) { - list($resultQuery, $resultParameters) = $result; - $resultQuery = str_replace('`file`', '`user`', $resultQuery); - $resultQuery = str_replace('`type`', '`key`', $resultQuery); - - $connection = \OC::$server->getDatabaseConnection(); - // Test the query on the privatedata table, because the activity table - // does not exist in core - $result = $connection->executeQuery('SELECT * FROM `*PREFIX*privatedata` WHERE ' . $resultQuery, $resultParameters); - $rows = $result->fetchAll(); - $result->closeCursor(); - } - - protected function mockUserSession($user) { - $mockUser = $this->getMockBuilder('\OCP\IUser') - ->disableOriginalConstructor() - ->getMock(); - $mockUser->expects($this->any()) - ->method('getUID') - ->willReturn($user); - - $this->session->expects($this->any()) - ->method('isLoggedIn') - ->willReturn(true); - $this->session->expects($this->any()) - ->method('getUser') - ->willReturn($mockUser); - } -} diff --git a/apps/files/tests/backgroundjob/ScanFilesTest.php b/apps/files/tests/backgroundjob/ScanFilesTest.php deleted file mode 100644 index eab28071b70..00000000000 --- a/apps/files/tests/backgroundjob/ScanFilesTest.php +++ /dev/null @@ -1,133 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@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 OCA\Files\Tests\BackgroundJob; - -use Test\TestCase; -use OCP\IConfig; -use OCP\IUserManager; -use OCA\Files\BackgroundJob\ScanFiles; - -/** - * Class ScanFilesTest - * - * @package OCA\Files\Tests\BackgroundJob - */ -class ScanFilesTest extends TestCase { - /** @var IConfig */ - private $config; - /** @var IUserManager */ - private $userManager; - /** @var ScanFiles */ - private $scanFiles; - - public function setUp() { - parent::setUp(); - - $this->config = $this->getMock('\OCP\IConfig'); - $this->userManager = $this->getMock('\OCP\IUserManager'); - - $this->scanFiles = $this->getMockBuilder('\OCA\Files\BackgroundJob\ScanFiles') - ->setConstructorArgs([ - $this->config, - $this->userManager, - ]) - ->setMethods(['runScanner']) - ->getMock(); - } - - public function testRunWithoutUsers() { - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('files', 'cronjob_scan_files', 0) - ->will($this->returnValue(50)); - $this->userManager - ->expects($this->at(0)) - ->method('search') - ->with('', 500, 50) - ->will($this->returnValue([])); - $this->userManager - ->expects($this->at(1)) - ->method('search') - ->with('', 500) - ->will($this->returnValue([])); - $this->config - ->expects($this->at(1)) - ->method('setAppValue') - ->with('files', 'cronjob_scan_files', 500); - - $this->invokePrivate($this->scanFiles, 'run', [[]]); - } - - public function testRunWithUsers() { - $fakeUser = $this->getMock('\OCP\IUser'); - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('files', 'cronjob_scan_files', 0) - ->will($this->returnValue(50)); - $this->userManager - ->expects($this->at(0)) - ->method('search') - ->with('', 500, 50) - ->will($this->returnValue([ - $fakeUser - ])); - $this->config - ->expects($this->at(1)) - ->method('setAppValue') - ->with('files', 'cronjob_scan_files', 550); - $this->scanFiles - ->expects($this->once()) - ->method('runScanner') - ->with($fakeUser); - - $this->invokePrivate($this->scanFiles, 'run', [[]]); - } - - public function testRunWithUsersAndOffsetAtEndOfUserList() { - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('files', 'cronjob_scan_files', 0) - ->will($this->returnValue(50)); - $this->userManager - ->expects($this->at(0)) - ->method('search') - ->with('', 500, 50) - ->will($this->returnValue([])); - $this->userManager - ->expects($this->at(1)) - ->method('search') - ->with('', 500) - ->will($this->returnValue([])); - $this->config - ->expects($this->at(1)) - ->method('setAppValue') - ->with('files', 'cronjob_scan_files', 500); - $this->scanFiles - ->expects($this->never()) - ->method('runScanner'); - - $this->invokePrivate($this->scanFiles, 'run', [[]]); - } - -} diff --git a/apps/files/tests/command/deleteorphanedfilestest.php b/apps/files/tests/command/deleteorphanedfilestest.php deleted file mode 100644 index ff29942bc4a..00000000000 --- a/apps/files/tests/command/deleteorphanedfilestest.php +++ /dev/null @@ -1,130 +0,0 @@ -<?php -/** - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 OCA\Files\Tests\Command; - -use OCA\Files\Command\DeleteOrphanedFiles; -use OCP\Files\StorageNotAvailableException; - -/** - * Class DeleteOrphanedFilesTest - * - * @group DB - * - * @package OCA\Files\Tests\Command - */ -class DeleteOrphanedFilesTest extends \Test\TestCase { - - /** - * @var DeleteOrphanedFiles - */ - private $command; - - /** - * @var \OCP\IDBConnection - */ - private $connection; - - /** - * @var string - */ - private $user1; - - protected function setup() { - parent::setUp(); - - $this->connection = \OC::$server->getDatabaseConnection(); - - $this->user1 = $this->getUniqueID('user1_'); - - $userManager = \OC::$server->getUserManager(); - $userManager->createUser($this->user1, 'pass'); - - $this->command = new DeleteOrphanedFiles($this->connection); - } - - protected function tearDown() { - $userManager = \OC::$server->getUserManager(); - $user1 = $userManager->get($this->user1); - if($user1) { - $user1->delete(); - } - - $this->logout(); - - parent::tearDown(); - } - - protected function getFile($fileId) { - $stmt = $this->connection->executeQuery('SELECT * FROM `*PREFIX*filecache` WHERE `fileid` = ?', [$fileId]); - return $stmt->fetchAll(); - } - - /** - * Test clearing orphaned files - */ - public function testClearFiles() { - $input = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface') - ->disableOriginalConstructor() - ->getMock(); - $output = $this->getMockBuilder('Symfony\Component\Console\Output\OutputInterface') - ->disableOriginalConstructor() - ->getMock(); - - $this->loginAsUser($this->user1); - - $view = new \OC\Files\View('/' . $this->user1 . '/'); - $view->mkdir('files/test'); - - $fileInfo = $view->getFileInfo('files/test'); - - $storageId = $fileInfo->getStorage()->getId(); - - $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is available'); - - $this->command->execute($input, $output); - - $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is still available'); - - $deletedRows = $this->connection->executeUpdate('DELETE FROM `*PREFIX*storages` WHERE `id` = ?', [$storageId]); - $this->assertNotNull($deletedRows, 'Asserts that storage got deleted'); - $this->assertSame(1, $deletedRows, 'Asserts that storage got deleted'); - - // parent folder, `files`, ´test` and `welcome.txt` => 4 elements - $output - ->expects($this->once()) - ->method('writeln') - ->with('4 orphaned file cache entries deleted'); - - $this->command->execute($input, $output); - - $this->assertCount(0, $this->getFile($fileInfo->getId()), 'Asserts that file gets cleaned up'); - - // since we deleted the storage it might throw a (valid) StorageNotAvailableException - try { - $view->unlink('files/test'); - } catch (StorageNotAvailableException $e) { - } - } -} - diff --git a/apps/files/tests/controller/ViewControllerTest.php b/apps/files/tests/controller/ViewControllerTest.php deleted file mode 100644 index 657ab6cb338..00000000000 --- a/apps/files/tests/controller/ViewControllerTest.php +++ /dev/null @@ -1,268 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Vincent Petry <pvince81@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 OCA\Files\Tests\Controller; - -use OCA\Files\Controller\ViewController; -use OCP\AppFramework\Http; -use OCP\Template; -use Test\TestCase; -use OCP\IRequest; -use OCP\IURLGenerator; -use OCP\AppFramework\Http\RedirectResponse; -use OCP\INavigationManager; -use OCP\IL10N; -use OCP\IConfig; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; - -/** - * Class ViewControllerTest - * - * @package OCA\Files\Tests\Controller - */ -class ViewControllerTest extends TestCase { - /** @var IRequest */ - private $request; - /** @var IURLGenerator */ - private $urlGenerator; - /** @var INavigationManager */ - private $navigationManager; - /** @var IL10N */ - private $l10n; - /** @var IConfig */ - private $config; - /** @var EventDispatcherInterface */ - private $eventDispatcher; - /** @var ViewController */ - private $viewController; - - public function setUp() { - parent::setUp(); - $this->request = $this->getMock('\OCP\IRequest'); - $this->urlGenerator = $this->getMock('\OCP\IURLGenerator'); - $this->navigationManager = $this->getMock('\OCP\INavigationManager'); - $this->l10n = $this->getMock('\OCP\IL10N'); - $this->config = $this->getMock('\OCP\IConfig'); - $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface'); - $this->viewController = $this->getMockBuilder('\OCA\Files\Controller\ViewController') - ->setConstructorArgs([ - 'files', - $this->request, - $this->urlGenerator, - $this->navigationManager, - $this->l10n, - $this->config, - $this->eventDispatcher - ]) - ->setMethods([ - 'getStorageInfo', - 'renderScript' - ]) - ->getMock(); - } - - public function testIndexWithIE8RedirectAndDirDefined() { - $this->request - ->expects($this->once()) - ->method('isUserAgent') - ->with(['/MSIE 8.0/']) - ->will($this->returnValue(true)); - $this->urlGenerator - ->expects($this->once()) - ->method('linkToRoute') - ->with('files.view.index') - ->will($this->returnValue('/apps/files/')); - - $expected = new Http\RedirectResponse('/apps/files/#?dir=MyDir'); - $this->assertEquals($expected, $this->viewController->index('MyDir')); - } - - public function testIndexWithIE8RedirectAndViewDefined() { - $this->request - ->expects($this->once()) - ->method('isUserAgent') - ->with(['/MSIE 8.0/']) - ->will($this->returnValue(true)); - $this->urlGenerator - ->expects($this->once()) - ->method('linkToRoute') - ->with('files.view.index') - ->will($this->returnValue('/apps/files/')); - - $expected = new Http\RedirectResponse('/apps/files/#?dir=/&view=MyView'); - $this->assertEquals($expected, $this->viewController->index('', 'MyView')); - } - - public function testIndexWithIE8RedirectAndViewAndDirDefined() { - $this->request - ->expects($this->once()) - ->method('isUserAgent') - ->with(['/MSIE 8.0/']) - ->will($this->returnValue(true)); - $this->urlGenerator - ->expects($this->once()) - ->method('linkToRoute') - ->with('files.view.index') - ->will($this->returnValue('/apps/files/')); - - $expected = new RedirectResponse('/apps/files/#?dir=MyDir&view=MyView'); - $this->assertEquals($expected, $this->viewController->index('MyDir', 'MyView')); - } - - public function testIndexWithRegularBrowser() { - $this->request - ->expects($this->once()) - ->method('isUserAgent') - ->with(['/MSIE 8.0/']) - ->will($this->returnValue(false)); - $this->viewController - ->expects($this->once()) - ->method('getStorageInfo') - ->will($this->returnValue([ - 'relative' => 123, - 'owner' => 'MyName', - 'ownerDisplayName' => 'MyDisplayName', - ])); - - $this->config - ->expects($this->any()) - ->method('getAppValue') - ->will($this->returnArgument(2)); - - $nav = new Template('files', 'appnavigation'); - $nav->assign('navigationItems', [ - [ - 'id' => 'files', - 'appname' => 'files', - 'script' => 'list.php', - 'order' => 0, - 'name' => new \OC_L10N_String(new \OC_L10N('files'), 'All files', []), - 'active' => false, - 'icon' => '', - ], - [ - 'id' => 'favorites', - 'appname' => 'files', - 'script' => 'simplelist.php', - 'order' => 5, - 'name' => null, - 'active' => false, - 'icon' => '', - ], - [ - 'id' => 'sharingin', - 'appname' => 'files_sharing', - 'script' => 'list.php', - 'order' => 10, - 'name' => new \OC_L10N_String(new \OC_L10N('files_sharing'), 'Shared with you', []), - 'active' => false, - 'icon' => '', - ], - [ - 'id' => 'sharingout', - 'appname' => 'files_sharing', - 'script' => 'list.php', - 'order' => 15, - 'name' => new \OC_L10N_String(new \OC_L10N('files_sharing'), 'Shared with others', []), - 'active' => false, - 'icon' => '', - ], - [ - 'id' => 'sharinglinks', - 'appname' => 'files_sharing', - 'script' => 'list.php', - 'order' => 20, - 'name' => new \OC_L10N_String(new \OC_L10N('files_sharing'), 'Shared by link', []), - 'active' => false, - 'icon' => '', - ], - [ - 'id' => 'systemtagsfilter', - 'appname' => 'systemtags', - 'script' => 'list.php', - 'order' => 25, - 'name' => new \OC_L10N_String(new \OC_L10N('systemtags'), 'Tags', []), - 'active' => false, - 'icon' => '', - ], - [ - 'id' => 'trashbin', - 'appname' => 'files_trashbin', - 'script' => 'list.php', - 'order' => 50, - 'name' => new \OC_L10N_String(new \OC_L10N('files_trashbin'), 'Deleted files', []), - 'active' => false, - 'icon' => '', - ], - ]); - - $expected = new Http\TemplateResponse( - 'files', - 'index', - [ - 'usedSpacePercent' => 123, - 'owner' => 'MyName', - 'ownerDisplayName' => 'MyDisplayName', - 'isPublic' => false, - 'mailNotificationEnabled' => 'no', - 'mailPublicNotificationEnabled' => 'no', - 'allowShareWithLink' => 'yes', - 'appNavigation' => $nav, - 'appContents' => [ - [ - 'id' => 'files', - 'content' => null, - ], - [ - 'id' => 'favorites', - 'content' => null, - ], - [ - 'id' => 'sharingin', - 'content' => null, - ], - [ - 'id' => 'sharingout', - 'content' => null, - ], - [ - 'id' => 'sharinglinks', - 'content' => null, - ], - [ - 'id' => 'systemtagsfilter', - 'content' => null, - ], - [ - 'id' => 'trashbin', - 'content' => null, - ], - ], - ] - ); - $policy = new Http\ContentSecurityPolicy(); - $policy->addAllowedFrameDomain('\'self\''); - $expected->setContentSecurityPolicy($policy); - $this->assertEquals($expected, $this->viewController->index('MyDir', 'MyView')); - } -} diff --git a/apps/files/tests/controller/apicontrollertest.php b/apps/files/tests/controller/apicontrollertest.php deleted file mode 100644 index a9b248a36fe..00000000000 --- a/apps/files/tests/controller/apicontrollertest.php +++ /dev/null @@ -1,338 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <rullzer@owncloud.com> - * @author Vincent Petry <pvince81@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 OCA\Files\Controller; - -use OC\Files\FileInfo; -use OCP\AppFramework\Http; -use OCP\Files\NotFoundException; -use OCP\Files\StorageNotAvailableException; -use Test\TestCase; -use OCP\IRequest; -use OCA\Files\Service\TagService; -use OCP\AppFramework\Http\DataResponse; -use OCP\IPreview; -use OCP\Image; - -/** - * Class ApiController - * - * @package OCA\Files\Controller - */ -class ApiControllerTest extends TestCase { - /** @var string */ - private $appName = 'files'; - /** @var IRequest */ - private $request; - /** @var TagService */ - private $tagService; - /** @var IPreview */ - private $preview; - /** @var ApiController */ - private $apiController; - /** @var \OCP\Share\IManager */ - private $shareManager; - - public function setUp() { - $this->request = $this->getMockBuilder('\OCP\IRequest') - ->disableOriginalConstructor() - ->getMock(); - $user = $this->getMock('\OCP\IUser'); - $user->expects($this->any()) - ->method('getUID') - ->will($this->returnValue('user1')); - $userSession = $this->getMock('\OCP\IUserSession'); - $userSession->expects($this->any()) - ->method('getUser') - ->will($this->returnValue($user)); - $this->tagService = $this->getMockBuilder('\OCA\Files\Service\TagService') - ->disableOriginalConstructor() - ->getMock(); - $this->shareManager = $this->getMockBuilder('\OCP\Share\IManager') - ->disableOriginalConstructor() - ->getMock(); - $this->preview = $this->getMockBuilder('\OCP\IPreview') - ->disableOriginalConstructor() - ->getMock(); - - $this->apiController = new ApiController( - $this->appName, - $this->request, - $userSession, - $this->tagService, - $this->preview, - $this->shareManager - ); - } - - public function testGetFilesByTagEmpty() { - $tagName = 'MyTagName'; - $this->tagService->expects($this->once()) - ->method('getFilesByTag') - ->with($this->equalTo([$tagName])) - ->will($this->returnValue([])); - - $expected = new DataResponse(['files' => []]); - $this->assertEquals($expected, $this->apiController->getFilesByTag([$tagName])); - } - - public function testGetFilesByTagSingle() { - $tagName = 'MyTagName'; - $fileInfo = new FileInfo( - '/root.txt', - $this->getMockBuilder('\OC\Files\Storage\Storage') - ->disableOriginalConstructor() - ->getMock(), - '/var/www/root.txt', - [ - 'mtime' => 55, - 'mimetype' => 'application/pdf', - 'permissions' => 31, - 'size' => 1234, - 'etag' => 'MyEtag', - ], - $this->getMockBuilder('\OCP\Files\Mount\IMountPoint') - ->disableOriginalConstructor() - ->getMock() - ); - $node = $this->getMockBuilder('\OC\Files\Node\File') - ->disableOriginalConstructor() - ->getMock(); - $node->expects($this->once()) - ->method('getFileInfo') - ->will($this->returnValue($fileInfo)); - $this->tagService->expects($this->once()) - ->method('getFilesByTag') - ->with($this->equalTo([$tagName])) - ->will($this->returnValue([$node])); - - $this->shareManager->expects($this->any()) - ->method('getSharesBy') - ->with( - $this->equalTo('user1'), - $this->anything(), - $node, - $this->equalTo(false), - $this->equalTo(1) - ) - ->will($this->returnCallback(function($userId, $shareType) { - if ($shareType === \OCP\Share::SHARE_TYPE_USER || $shareType === \OCP\Share::SHARE_TYPE_LINK) { - return ['dummy_share']; - } - return []; - })); - - $expected = new DataResponse([ - 'files' => [ - [ - 'id' => null, - 'parentId' => null, - 'mtime' => 55000, - 'name' => 'root.txt', - 'permissions' => 31, - 'mimetype' => 'application/pdf', - 'size' => 1234, - 'type' => 'file', - 'etag' => 'MyEtag', - 'path' => '/', - 'tags' => [ - [ - 'MyTagName' - ] - ], - 'shareTypes' => [\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK] - ], - ], - ]); - $this->assertEquals($expected, $this->apiController->getFilesByTag([$tagName])); - } - - public function testGetFilesByTagMultiple() { - $tagName = 'MyTagName'; - $fileInfo1 = new FileInfo( - '/root.txt', - $this->getMockBuilder('\OC\Files\Storage\Storage') - ->disableOriginalConstructor() - ->getMock(), - '/var/www/root.txt', - [ - 'mtime' => 55, - 'mimetype' => 'application/pdf', - 'permissions' => 31, - 'size' => 1234, - 'etag' => 'MyEtag', - ], - $this->getMockBuilder('\OCP\Files\Mount\IMountPoint') - ->disableOriginalConstructor() - ->getMock() - ); - $fileInfo2 = new FileInfo( - '/root.txt', - $this->getMockBuilder('\OC\Files\Storage\Storage') - ->disableOriginalConstructor() - ->getMock(), - '/var/www/some/sub.txt', - [ - 'mtime' => 999, - 'mimetype' => 'application/binary', - 'permissions' => 31, - 'size' => 9876, - 'etag' => 'SubEtag', - ], - $this->getMockBuilder('\OCP\Files\Mount\IMountPoint') - ->disableOriginalConstructor() - ->getMock() - ); - $node1 = $this->getMockBuilder('\OC\Files\Node\File') - ->disableOriginalConstructor() - ->getMock(); - $node1->expects($this->once()) - ->method('getFileInfo') - ->will($this->returnValue($fileInfo1)); - $node2 = $this->getMockBuilder('\OC\Files\Node\File') - ->disableOriginalConstructor() - ->getMock(); - $node2->expects($this->once()) - ->method('getFileInfo') - ->will($this->returnValue($fileInfo2)); - $this->tagService->expects($this->once()) - ->method('getFilesByTag') - ->with($this->equalTo([$tagName])) - ->will($this->returnValue([$node1, $node2])); - - $expected = new DataResponse([ - 'files' => [ - [ - 'id' => null, - 'parentId' => null, - 'mtime' => 55000, - 'name' => 'root.txt', - 'permissions' => 31, - 'mimetype' => 'application/pdf', - 'size' => 1234, - 'type' => 'file', - 'etag' => 'MyEtag', - 'path' => '/', - 'tags' => [ - [ - 'MyTagName' - ] - ], - ], - [ - 'id' => null, - 'parentId' => null, - 'mtime' => 999000, - 'name' => 'root.txt', - 'permissions' => 31, - 'mimetype' => 'application/binary', - 'size' => 9876, - 'type' => 'file', - 'etag' => 'SubEtag', - 'path' => '/', - 'tags' => [ - [ - 'MyTagName' - ] - ], - ] - ], - ]); - $this->assertEquals($expected, $this->apiController->getFilesByTag([$tagName])); - } - - public function testUpdateFileTagsEmpty() { - $expected = new DataResponse([]); - $this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt')); - } - - public function testUpdateFileTagsWorking() { - $this->tagService->expects($this->once()) - ->method('updateFileTags') - ->with('/path.txt', ['Tag1', 'Tag2']); - - $expected = new DataResponse([ - 'tags' => [ - 'Tag1', - 'Tag2' - ], - ]); - $this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2'])); - } - - public function testUpdateFileTagsNotFoundException() { - $this->tagService->expects($this->once()) - ->method('updateFileTags') - ->with('/path.txt', ['Tag1', 'Tag2']) - ->will($this->throwException(new NotFoundException('My error message'))); - - $expected = new DataResponse(['message' => 'My error message'], Http::STATUS_NOT_FOUND); - $this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2'])); - } - - public function testUpdateFileTagsStorageNotAvailableException() { - $this->tagService->expects($this->once()) - ->method('updateFileTags') - ->with('/path.txt', ['Tag1', 'Tag2']) - ->will($this->throwException(new StorageNotAvailableException('My error message'))); - - $expected = new DataResponse(['message' => 'My error message'], Http::STATUS_SERVICE_UNAVAILABLE); - $this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2'])); - } - - public function testUpdateFileTagsStorageGenericException() { - $this->tagService->expects($this->once()) - ->method('updateFileTags') - ->with('/path.txt', ['Tag1', 'Tag2']) - ->will($this->throwException(new \Exception('My error message'))); - - $expected = new DataResponse(['message' => 'My error message'], Http::STATUS_NOT_FOUND); - $this->assertEquals($expected, $this->apiController->updateFileTags('/path.txt', ['Tag1', 'Tag2'])); - } - - public function testGetThumbnailInvalidSize() { - $expected = new DataResponse(['message' => 'Requested size must be numeric and a positive value.'], Http::STATUS_BAD_REQUEST); - $this->assertEquals($expected, $this->apiController->getThumbnail(0, 0, '')); - } - - public function testGetThumbnailInvaidImage() { - $this->preview->expects($this->once()) - ->method('createPreview') - ->with('files/unknown.jpg', 10, 10, true) - ->willReturn(new Image); - $expected = new DataResponse(['message' => 'File not found.'], Http::STATUS_NOT_FOUND); - $this->assertEquals($expected, $this->apiController->getThumbnail(10, 10, 'unknown.jpg')); - } - - public function testGetThumbnail() { - $this->preview->expects($this->once()) - ->method('createPreview') - ->with('files/known.jpg', 10, 10, true) - ->willReturn(new Image(\OC::$SERVERROOT.'/tests/data/testimage.jpg')); - - $ret = $this->apiController->getThumbnail(10, 10, 'known.jpg'); - - $this->assertEquals(Http::STATUS_OK, $ret->getStatus()); - } -} diff --git a/apps/files/tests/helper.php b/apps/files/tests/helper.php deleted file mode 100644 index 654ec8332ed..00000000000 --- a/apps/files/tests/helper.php +++ /dev/null @@ -1,114 +0,0 @@ -<?php -/** - * @author brumsel <brumsel@losecatcher.de> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Vincent Petry <pvince81@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/> - * - */ - -use OCA\Files; - -/** - * Class Test_Files_Helper - */ -class Test_Files_Helper extends \Test\TestCase { - - private function makeFileInfo($name, $size, $mtime, $isDir = false) { - return new \OC\Files\FileInfo( - '/' . $name, - null, - '/', - array( - 'name' => $name, - 'size' => $size, - 'mtime' => $mtime, - 'type' => $isDir ? 'dir' : 'file', - 'mimetype' => $isDir ? 'httpd/unix-directory' : 'application/octet-stream' - ), - null - ); - } - - /** - * Returns a file list for testing - */ - private function getTestFileList() { - return array( - self::makeFileInfo('a.txt', 4, 2.3 * pow(10, 9)), - self::makeFileInfo('q.txt', 5, 150), - self::makeFileInfo('subdir2', 87, 128, true), - self::makeFileInfo('b.txt', 2.2 * pow(10, 9), 800), - self::makeFileInfo('o.txt', 12, 100), - self::makeFileInfo('subdir', 88, 125, true), - ); - } - - function sortDataProvider() { - return array( - array( - 'name', - false, - array('subdir', 'subdir2', 'a.txt', 'b.txt', 'o.txt', 'q.txt'), - ), - array( - 'name', - true, - array('q.txt', 'o.txt', 'b.txt', 'a.txt', 'subdir2', 'subdir'), - ), - array( - 'size', - false, - array('a.txt', 'q.txt', 'o.txt', 'subdir2', 'subdir', 'b.txt'), - ), - array( - 'size', - true, - array('b.txt', 'subdir', 'subdir2', 'o.txt', 'q.txt', 'a.txt'), - ), - array( - 'mtime', - false, - array('o.txt', 'subdir', 'subdir2', 'q.txt', 'b.txt', 'a.txt'), - ), - array( - 'mtime', - true, - array('a.txt', 'b.txt', 'q.txt', 'subdir2', 'subdir', 'o.txt'), - ), - ); - } - - /** - * @dataProvider sortDataProvider - */ - public function testSortByName($sort, $sortDescending, $expectedOrder) { - $files = self::getTestFileList(); - $files = \OCA\Files\Helper::sortFiles($files, $sort, $sortDescending); - $fileNames = array(); - foreach ($files as $fileInfo) { - $fileNames[] = $fileInfo->getName(); - } - $this->assertEquals( - $expectedOrder, - $fileNames - ); - } - -} diff --git a/apps/files/tests/js/appSpec.js b/apps/files/tests/js/appSpec.js deleted file mode 100644 index dce513339f0..00000000000 --- a/apps/files/tests/js/appSpec.js +++ /dev/null @@ -1,271 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2014 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -describe('OCA.Files.App tests', function() { - var App = OCA.Files.App; - var pushStateStub; - var parseUrlQueryStub; - var oldLegacyFileActions; - - beforeEach(function() { - $('#testArea').append( - '<div id="content" class="app-files">' + - '<div id="app-navigation">' + - '<ul><li data-id="files"><a>Files</a></li>' + - '<li data-id="other"><a>Other</a></li>' + - '</div>' + - '<div id="app-content">' + - '<div id="app-content-files" class="hidden">' + - '</div>' + - '<div id="app-content-other" class="hidden">' + - '</div>' + - '</div>' + - '</div>' + - '</div>' - ); - - oldLegacyFileActions = window.FileActions; - window.FileActions = new OCA.Files.FileActions(); - OCA.Files.legacyFileActions = window.FileActions; - OCA.Files.fileActions = new OCA.Files.FileActions(); - - pushStateStub = sinon.stub(OC.Util.History, 'pushState'); - parseUrlQueryStub = sinon.stub(OC.Util.History, 'parseUrlQuery'); - parseUrlQueryStub.returns({}); - - App.initialize(); - }); - afterEach(function() { - App.destroy(); - - window.FileActions = oldLegacyFileActions; - - pushStateStub.restore(); - parseUrlQueryStub.restore(); - }); - - describe('initialization', function() { - it('initializes the default file list with the default file actions', function() { - expect(App.fileList).toBeDefined(); - expect(App.fileList.fileActions.actions.all).toBeDefined(); - expect(App.fileList.$el.is('#app-content-files')).toEqual(true); - }); - it('merges the legacy file actions with the default ones', function() { - var legacyActionStub = sinon.stub(); - var actionStub = sinon.stub(); - // legacy action - window.FileActions.register( - 'all', - 'LegacyTest', - OC.PERMISSION_READ, - OC.imagePath('core', 'actions/test'), - legacyActionStub - ); - // legacy action to be overwritten - window.FileActions.register( - 'all', - 'OverwriteThis', - OC.PERMISSION_READ, - OC.imagePath('core', 'actions/test'), - legacyActionStub - ); - - // regular file actions - OCA.Files.fileActions.register( - 'all', - 'RegularTest', - OC.PERMISSION_READ, - OC.imagePath('core', 'actions/test'), - actionStub - ); - - // overwrite - OCA.Files.fileActions.register( - 'all', - 'OverwriteThis', - OC.PERMISSION_READ, - OC.imagePath('core', 'actions/test'), - actionStub - ); - - App.initialize(); - - var actions = App.fileList.fileActions.actions; - expect(actions.all.OverwriteThis.action).toBe(actionStub); - expect(actions.all.LegacyTest.action).toBe(legacyActionStub); - expect(actions.all.RegularTest.action).toBe(actionStub); - // default one still there - expect(actions.dir.Open.action).toBeDefined(); - }); - }); - - describe('URL handling', function() { - it('pushes the state to the URL when current app changed directory', function() { - $('#app-content-files').trigger(new $.Event('changeDirectory', {dir: 'subdir'})); - expect(pushStateStub.calledOnce).toEqual(true); - expect(pushStateStub.getCall(0).args[0].dir).toEqual('subdir'); - expect(pushStateStub.getCall(0).args[0].view).not.toBeDefined(); - - $('li[data-id=other]>a').click(); - pushStateStub.reset(); - - $('#app-content-other').trigger(new $.Event('changeDirectory', {dir: 'subdir'})); - expect(pushStateStub.calledOnce).toEqual(true); - expect(pushStateStub.getCall(0).args[0].dir).toEqual('subdir'); - expect(pushStateStub.getCall(0).args[0].view).toEqual('other'); - }); - describe('onpopstate', function() { - it('sends "urlChanged" event to current app', function() { - var handler = sinon.stub(); - $('#app-content-files').on('urlChanged', handler); - App._onPopState({view: 'files', dir: '/somedir'}); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0].view).toEqual('files'); - expect(handler.getCall(0).args[0].dir).toEqual('/somedir'); - }); - it('sends "show" event to current app and sets navigation', function() { - var showHandlerFiles = sinon.stub(); - var showHandlerOther = sinon.stub(); - var hideHandlerFiles = sinon.stub(); - var hideHandlerOther = sinon.stub(); - $('#app-content-files').on('show', showHandlerFiles); - $('#app-content-files').on('hide', hideHandlerFiles); - $('#app-content-other').on('show', showHandlerOther); - $('#app-content-other').on('hide', hideHandlerOther); - App._onPopState({view: 'other', dir: '/somedir'}); - expect(showHandlerFiles.notCalled).toEqual(true); - expect(hideHandlerFiles.calledOnce).toEqual(true); - expect(showHandlerOther.calledOnce).toEqual(true); - expect(hideHandlerOther.notCalled).toEqual(true); - - showHandlerFiles.reset(); - showHandlerOther.reset(); - hideHandlerFiles.reset(); - hideHandlerOther.reset(); - - App._onPopState({view: 'files', dir: '/somedir'}); - expect(showHandlerFiles.calledOnce).toEqual(true); - expect(hideHandlerFiles.notCalled).toEqual(true); - expect(showHandlerOther.notCalled).toEqual(true); - expect(hideHandlerOther.calledOnce).toEqual(true); - - expect(App.navigation.getActiveItem()).toEqual('files'); - expect($('#app-content-files').hasClass('hidden')).toEqual(false); - expect($('#app-content-other').hasClass('hidden')).toEqual(true); - }); - it('does not send "show" or "hide" event to current app when already visible', function() { - var showHandler = sinon.stub(); - var hideHandler = sinon.stub(); - $('#app-content-files').on('show', showHandler); - $('#app-content-files').on('hide', hideHandler); - App._onPopState({view: 'files', dir: '/somedir'}); - expect(showHandler.notCalled).toEqual(true); - expect(hideHandler.notCalled).toEqual(true); - }); - it('state defaults to files app with root dir', function() { - var handler = sinon.stub(); - parseUrlQueryStub.returns({}); - $('#app-content-files').on('urlChanged', handler); - App._onPopState(); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0].view).toEqual('files'); - expect(handler.getCall(0).args[0].dir).toEqual('/'); - }); - it('activates files app if invalid view is passed', function() { - App._onPopState({view: 'invalid', dir: '/somedir'}); - - expect(App.navigation.getActiveItem()).toEqual('files'); - expect($('#app-content-files').hasClass('hidden')).toEqual(false); - }); - }); - describe('navigation', function() { - it('switches the navigation item and panel visibility when onpopstate', function() { - App._onPopState({view: 'other', dir: '/somedir'}); - expect(App.navigation.getActiveItem()).toEqual('other'); - expect($('#app-content-files').hasClass('hidden')).toEqual(true); - expect($('#app-content-other').hasClass('hidden')).toEqual(false); - expect($('li[data-id=files]').hasClass('active')).toEqual(false); - expect($('li[data-id=other]').hasClass('active')).toEqual(true); - - App._onPopState({view: 'files', dir: '/somedir'}); - - expect(App.navigation.getActiveItem()).toEqual('files'); - expect($('#app-content-files').hasClass('hidden')).toEqual(false); - expect($('#app-content-other').hasClass('hidden')).toEqual(true); - expect($('li[data-id=files]').hasClass('active')).toEqual(true); - expect($('li[data-id=other]').hasClass('active')).toEqual(false); - }); - it('clicking on navigation switches the panel visibility', function() { - $('li[data-id=other]>a').click(); - expect(App.navigation.getActiveItem()).toEqual('other'); - expect($('#app-content-files').hasClass('hidden')).toEqual(true); - expect($('#app-content-other').hasClass('hidden')).toEqual(false); - expect($('li[data-id=files]').hasClass('active')).toEqual(false); - expect($('li[data-id=other]').hasClass('active')).toEqual(true); - - $('li[data-id=files]>a').click(); - expect(App.navigation.getActiveItem()).toEqual('files'); - expect($('#app-content-files').hasClass('hidden')).toEqual(false); - expect($('#app-content-other').hasClass('hidden')).toEqual(true); - expect($('li[data-id=files]').hasClass('active')).toEqual(true); - expect($('li[data-id=other]').hasClass('active')).toEqual(false); - }); - it('clicking on navigation sends "show" and "urlChanged" event', function() { - var handler = sinon.stub(); - var showHandler = sinon.stub(); - $('#app-content-other').on('urlChanged', handler); - $('#app-content-other').on('show', showHandler); - $('li[data-id=other]>a').click(); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0].view).toEqual('other'); - expect(handler.getCall(0).args[0].dir).toEqual('/'); - expect(showHandler.calledOnce).toEqual(true); - }); - it('clicking on activate navigation only sends "urlChanged" event', function() { - var handler = sinon.stub(); - var showHandler = sinon.stub(); - $('#app-content-files').on('urlChanged', handler); - $('#app-content-files').on('show', showHandler); - $('li[data-id=files]>a').click(); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0].view).toEqual('files'); - expect(handler.getCall(0).args[0].dir).toEqual('/'); - expect(showHandler.notCalled).toEqual(true); - }); - }); - describe('viewer mode', function() { - it('toggles the sidebar when viewer mode is enabled', function() { - $('#app-content-files').trigger( - new $.Event('changeViewerMode', {viewerModeEnabled: true} - )); - expect($('#app-navigation').hasClass('hidden')).toEqual(true); - expect($('.app-files').hasClass('viewer-mode no-sidebar')).toEqual(true); - - $('#app-content-files').trigger( - new $.Event('changeViewerMode', {viewerModeEnabled: false} - )); - - expect($('#app-navigation').hasClass('hidden')).toEqual(false); - expect($('.app-files').hasClass('viewer-mode no-sidebar')).toEqual(false); - }); - }); - }); -}); diff --git a/apps/files/tests/js/breadcrumbSpec.js b/apps/files/tests/js/breadcrumbSpec.js deleted file mode 100644 index a26f0176f15..00000000000 --- a/apps/files/tests/js/breadcrumbSpec.js +++ /dev/null @@ -1,270 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2014 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -describe('OCA.Files.BreadCrumb tests', function() { - var BreadCrumb = OCA.Files.BreadCrumb; - - describe('Rendering', function() { - var bc; - beforeEach(function() { - bc = new BreadCrumb({ - getCrumbUrl: function(part, index) { - // for testing purposes - return part.dir + '#' + index; - } - }); - }); - afterEach(function() { - bc = null; - }); - it('Renders its own container', function() { - bc.render(); - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - }); - it('Renders root by default', function() { - var $crumbs; - bc.render(); - $crumbs = bc.$el.find('.crumb'); - expect($crumbs.length).toEqual(1); - expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0'); - expect($crumbs.eq(0).find('img').length).toEqual(1); - expect($crumbs.eq(0).attr('data-dir')).toEqual('/'); - }); - it('Renders root when switching to root', function() { - var $crumbs; - bc.setDirectory('/somedir'); - bc.setDirectory('/'); - $crumbs = bc.$el.find('.crumb'); - expect($crumbs.length).toEqual(1); - expect($crumbs.eq(0).attr('data-dir')).toEqual('/'); - }); - it('Renders last crumb with "last" class', function() { - bc.setDirectory('/abc/def'); - expect(bc.$el.find('.crumb:last').hasClass('last')).toEqual(true); - }); - it('Renders single path section', function() { - var $crumbs; - bc.setDirectory('/somedir'); - $crumbs = bc.$el.find('.crumb'); - expect($crumbs.length).toEqual(2); - expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0'); - expect($crumbs.eq(0).find('img').length).toEqual(1); - expect($crumbs.eq(0).attr('data-dir')).toEqual('/'); - expect($crumbs.eq(1).find('a').attr('href')).toEqual('/somedir#1'); - expect($crumbs.eq(1).find('img').length).toEqual(0); - expect($crumbs.eq(1).attr('data-dir')).toEqual('/somedir'); - }); - it('Renders multiple path sections and special chars', function() { - var $crumbs; - bc.setDirectory('/somedir/with space/abc'); - $crumbs = bc.$el.find('.crumb'); - expect($crumbs.length).toEqual(4); - expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0'); - expect($crumbs.eq(0).find('img').length).toEqual(1); - expect($crumbs.eq(0).attr('data-dir')).toEqual('/'); - - expect($crumbs.eq(1).find('a').attr('href')).toEqual('/somedir#1'); - expect($crumbs.eq(1).find('img').length).toEqual(0); - expect($crumbs.eq(1).attr('data-dir')).toEqual('/somedir'); - - expect($crumbs.eq(2).find('a').attr('href')).toEqual('/somedir/with space#2'); - expect($crumbs.eq(2).find('img').length).toEqual(0); - expect($crumbs.eq(2).attr('data-dir')).toEqual('/somedir/with space'); - - expect($crumbs.eq(3).find('a').attr('href')).toEqual('/somedir/with space/abc#3'); - expect($crumbs.eq(3).find('img').length).toEqual(0); - expect($crumbs.eq(3).attr('data-dir')).toEqual('/somedir/with space/abc'); - }); - it('Renders backslashes as regular directory separator', function() { - var $crumbs; - bc.setDirectory('/somedir\\with/mixed\\separators'); - $crumbs = bc.$el.find('.crumb'); - expect($crumbs.length).toEqual(5); - expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0'); - expect($crumbs.eq(0).find('img').length).toEqual(1); - expect($crumbs.eq(0).attr('data-dir')).toEqual('/'); - - expect($crumbs.eq(1).find('a').attr('href')).toEqual('/somedir#1'); - expect($crumbs.eq(1).find('img').length).toEqual(0); - expect($crumbs.eq(1).attr('data-dir')).toEqual('/somedir'); - - expect($crumbs.eq(2).find('a').attr('href')).toEqual('/somedir/with#2'); - expect($crumbs.eq(2).find('img').length).toEqual(0); - expect($crumbs.eq(2).attr('data-dir')).toEqual('/somedir/with'); - - expect($crumbs.eq(3).find('a').attr('href')).toEqual('/somedir/with/mixed#3'); - expect($crumbs.eq(3).find('img').length).toEqual(0); - expect($crumbs.eq(3).attr('data-dir')).toEqual('/somedir/with/mixed'); - - expect($crumbs.eq(4).find('a').attr('href')).toEqual('/somedir/with/mixed/separators#4'); - expect($crumbs.eq(4).find('img').length).toEqual(0); - expect($crumbs.eq(4).attr('data-dir')).toEqual('/somedir/with/mixed/separators'); - }); - }); - describe('Events', function() { - it('Calls onClick handler when clicking on a crumb', function() { - var handler = sinon.stub(); - var bc = new BreadCrumb({ - onClick: handler - }); - bc.setDirectory('/one/two/three/four'); - bc.$el.find('.crumb:eq(3)').click(); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).thisValue).toEqual(bc.$el.find('.crumb').get(3)); - - handler.reset(); - bc.$el.find('.crumb:eq(0) a').click(); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).thisValue).toEqual(bc.$el.find('.crumb').get(0)); - }); - it('Calls onDrop handler when dropping on a crumb', function() { - var droppableStub = sinon.stub($.fn, 'droppable'); - var handler = sinon.stub(); - var bc = new BreadCrumb({ - onDrop: handler - }); - bc.setDirectory('/one/two/three/four'); - expect(droppableStub.calledOnce).toEqual(true); - - expect(droppableStub.getCall(0).args[0].drop).toBeDefined(); - // simulate drop - droppableStub.getCall(0).args[0].drop({dummy: true}); - - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0]).toEqual({dummy: true}); - - droppableStub.restore(); - }); - }); - describe('Resizing', function() { - var bc, dummyDir, widths, oldUpdateTotalWidth; - - beforeEach(function() { - dummyDir = '/short name/longer name/looooooooooooonger/' + - 'even longer long long long longer long/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/last one'; - - // using hard-coded widths (pre-measured) to avoid getting different - // results on different browsers due to font engine differences - widths = [41, 106, 112, 160, 257, 251, 91]; - - oldUpdateTotalWidth = BreadCrumb.prototype._updateTotalWidth; - BreadCrumb.prototype._updateTotalWidth = function() { - // pre-set a width to simulate consistent measurement - $('div.crumb').each(function(index){ - $(this).css('width', widths[index]); - }); - - return oldUpdateTotalWidth.apply(this, arguments); - }; - - bc = new BreadCrumb(); - // append dummy navigation and controls - // as they are currently used for measurements - $('#testArea').append( - '<div id="controls"></div>' - ); - $('#controls').append(bc.$el); - }); - afterEach(function() { - BreadCrumb.prototype._updateTotalWidth = oldUpdateTotalWidth; - bc = null; - }); - it('Hides breadcrumbs to fit max allowed width', function() { - var $crumbs; - - bc.setMaxWidth(500); - // triggers resize implicitly - bc.setDirectory(dummyDir); - $crumbs = bc.$el.find('.crumb'); - - // first one is always visible - expect($crumbs.eq(0).hasClass('hidden')).toEqual(false); - // second one has ellipsis - expect($crumbs.eq(1).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(1).find('.ellipsis').length).toEqual(1); - // there is only one ellipsis in total - expect($crumbs.find('.ellipsis').length).toEqual(1); - // subsequent elements are hidden - expect($crumbs.eq(2).hasClass('hidden')).toEqual(true); - expect($crumbs.eq(3).hasClass('hidden')).toEqual(true); - expect($crumbs.eq(4).hasClass('hidden')).toEqual(true); - expect($crumbs.eq(5).hasClass('hidden')).toEqual(true); - expect($crumbs.eq(6).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(7).hasClass('hidden')).toEqual(false); - }); - it('Updates the breadcrumbs when reducing max allowed width', function() { - var $crumbs; - - // enough space - bc.setMaxWidth(1800); - - expect(bc.$el.find('.ellipsis').length).toEqual(0); - - // triggers resize implicitly - bc.setDirectory(dummyDir); - - // simulate increase - bc.setMaxWidth(950); - - $crumbs = bc.$el.find('.crumb'); - // first one is always visible - expect($crumbs.eq(0).hasClass('hidden')).toEqual(false); - // second one has ellipsis - expect($crumbs.eq(1).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(1).find('.ellipsis').length).toEqual(1); - // there is only one ellipsis in total - expect($crumbs.find('.ellipsis').length).toEqual(1); - // subsequent elements are hidden - expect($crumbs.eq(2).hasClass('hidden')).toEqual(true); - expect($crumbs.eq(3).hasClass('hidden')).toEqual(true); - // the rest is visible - expect($crumbs.eq(4).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(5).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(6).hasClass('hidden')).toEqual(false); - }); - it('Removes the ellipsis when there is enough space', function() { - var $crumbs; - - bc.setMaxWidth(500); - // triggers resize implicitly - bc.setDirectory(dummyDir); - $crumbs = bc.$el.find('.crumb'); - - // ellipsis - expect(bc.$el.find('.ellipsis').length).toEqual(1); - - // simulate increase - bc.setMaxWidth(1800); - - // no ellipsis - expect(bc.$el.find('.ellipsis').length).toEqual(0); - - // all are visible - expect($crumbs.eq(0).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(1).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(2).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(3).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(4).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(5).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(6).hasClass('hidden')).toEqual(false); - }); - }); -}); diff --git a/apps/files/tests/js/detailsviewSpec.js b/apps/files/tests/js/detailsviewSpec.js deleted file mode 100644 index 26a16b31530..00000000000 --- a/apps/files/tests/js/detailsviewSpec.js +++ /dev/null @@ -1,234 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2015 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -describe('OCA.Files.DetailsView tests', function() { - var detailsView; - - beforeEach(function() { - detailsView = new OCA.Files.DetailsView(); - }); - afterEach(function() { - detailsView.remove(); - detailsView = undefined; - }); - it('renders itself empty when nothing registered', function() { - detailsView.render(); - expect(detailsView.$el.find('.detailFileInfoContainer').length).toEqual(1); - expect(detailsView.$el.find('.tabsContainer').length).toEqual(1); - }); - describe('file info detail view', function() { - it('renders registered view', function() { - var testView = new OCA.Files.DetailFileInfoView(); - var testView2 = new OCA.Files.DetailFileInfoView(); - detailsView.addDetailView(testView); - detailsView.addDetailView(testView2); - detailsView.render(); - - expect(detailsView.$el.find('.detailFileInfoContainer .detailFileInfoView').length).toEqual(2); - }); - it('updates registered tabs when fileinfo is updated', function() { - var viewRenderStub = sinon.stub(OCA.Files.DetailFileInfoView.prototype, 'render'); - var testView = new OCA.Files.DetailFileInfoView(); - var testView2 = new OCA.Files.DetailFileInfoView(); - detailsView.addDetailView(testView); - detailsView.addDetailView(testView2); - detailsView.render(); - - var fileInfo = {id: 5, name: 'test.txt'}; - viewRenderStub.reset(); - detailsView.setFileInfo(fileInfo); - - expect(testView.getFileInfo()).toEqual(fileInfo); - expect(testView2.getFileInfo()).toEqual(fileInfo); - - expect(viewRenderStub.callCount).toEqual(2); - viewRenderStub.restore(); - }); - }); - describe('tabs', function() { - var testView, testView2; - - beforeEach(function() { - testView = new OCA.Files.DetailTabView({id: 'test1'}); - testView2 = new OCA.Files.DetailTabView({id: 'test2'}); - detailsView.addTabView(testView); - detailsView.addTabView(testView2); - detailsView.render(); - }); - it('initially renders only the selected tab', function() { - expect(detailsView.$el.find('.tab').length).toEqual(1); - expect(detailsView.$el.find('.tab').attr('id')).toEqual('test1'); - }); - it('updates tab model and rerenders on-demand as soon as it gets selected', function() { - var tab1RenderStub = sinon.stub(testView, 'render'); - var tab2RenderStub = sinon.stub(testView2, 'render'); - var fileInfo1 = new OCA.Files.FileInfoModel({id: 5, name: 'test.txt'}); - var fileInfo2 = new OCA.Files.FileInfoModel({id: 8, name: 'test2.txt'}); - - detailsView.setFileInfo(fileInfo1); - - // first tab renders, not the second one - expect(tab1RenderStub.calledOnce).toEqual(true); - expect(tab2RenderStub.notCalled).toEqual(true); - - // info got set only to the first visible tab - expect(testView.getFileInfo()).toEqual(fileInfo1); - expect(testView2.getFileInfo()).toBeUndefined(); - - // select second tab for first render - detailsView.$el.find('.tabHeader').eq(1).click(); - - // second tab got rendered - expect(tab2RenderStub.calledOnce).toEqual(true); - expect(testView2.getFileInfo()).toEqual(fileInfo1); - - // select the first tab again - detailsView.$el.find('.tabHeader').eq(0).click(); - - // no re-render - expect(tab1RenderStub.calledOnce).toEqual(true); - expect(tab2RenderStub.calledOnce).toEqual(true); - - tab1RenderStub.reset(); - tab2RenderStub.reset(); - - // switch to another file - detailsView.setFileInfo(fileInfo2); - - // only the visible tab was updated and rerendered - expect(tab1RenderStub.calledOnce).toEqual(true); - expect(testView.getFileInfo()).toEqual(fileInfo2); - - // second/invisible tab still has old info, not rerendered - expect(tab2RenderStub.notCalled).toEqual(true); - expect(testView2.getFileInfo()).toEqual(fileInfo1); - - // reselect the second one - detailsView.$el.find('.tabHeader').eq(1).click(); - - // second tab becomes visible, updated and rendered - expect(testView2.getFileInfo()).toEqual(fileInfo2); - expect(tab2RenderStub.calledOnce).toEqual(true); - - tab1RenderStub.restore(); - tab2RenderStub.restore(); - }); - it('selects the first tab by default', function() { - expect(detailsView.$el.find('.tabHeader').eq(0).hasClass('selected')).toEqual(true); - expect(detailsView.$el.find('.tabHeader').eq(1).hasClass('selected')).toEqual(false); - expect(detailsView.$el.find('.tab').eq(0).hasClass('hidden')).toEqual(false); - expect(detailsView.$el.find('.tab').eq(1).length).toEqual(0); - }); - it('switches the current tab when clicking on tab header', function() { - detailsView.$el.find('.tabHeader').eq(1).click(); - expect(detailsView.$el.find('.tabHeader').eq(0).hasClass('selected')).toEqual(false); - expect(detailsView.$el.find('.tabHeader').eq(1).hasClass('selected')).toEqual(true); - expect(detailsView.$el.find('.tab').eq(0).hasClass('hidden')).toEqual(true); - expect(detailsView.$el.find('.tab').eq(1).hasClass('hidden')).toEqual(false); - }); - describe('tab visibility', function() { - beforeEach(function() { - detailsView.remove(); - detailsView = new OCA.Files.DetailsView(); - }); - it('does not display tab headers when only one tab exists', function() { - testView = new OCA.Files.DetailTabView({id: 'test1'}); - detailsView.addTabView(testView); - detailsView.render(); - - expect(detailsView.$el.find('.tabHeaders').hasClass('hidden')).toEqual(true); - expect(detailsView.$el.find('.tabHeader').length).toEqual(1); - }); - it('does not display tab that do not pass visibility check', function() { - testView = new OCA.Files.DetailTabView({id: 'test1'}); - testView.canDisplay = sinon.stub().returns(false); - testView2 = new OCA.Files.DetailTabView({id: 'test2'}); - var testView3 = new OCA.Files.DetailTabView({id: 'test3'}); - detailsView.addTabView(testView); - detailsView.addTabView(testView2); - detailsView.addTabView(testView3); - - var fileInfo = {id: 5, name: 'test.txt'}; - detailsView.setFileInfo(fileInfo); - - expect(testView.canDisplay.calledOnce).toEqual(true); - expect(testView.canDisplay.calledWith(fileInfo)).toEqual(true); - - expect(detailsView.$el.find('.tabHeaders').hasClass('hidden')).toEqual(false); - expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('hidden')).toEqual(true); - expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('hidden')).toEqual(false); - expect(detailsView.$el.find('.tabHeader[data-tabid=test3]').hasClass('hidden')).toEqual(false); - }); - it('does not show tab headers if only one header is visible due to visibility check', function() { - testView = new OCA.Files.DetailTabView({id: 'test1'}); - testView.canDisplay = sinon.stub().returns(false); - testView2 = new OCA.Files.DetailTabView({id: 'test2'}); - detailsView.addTabView(testView); - detailsView.addTabView(testView2); - - var fileInfo = {id: 5, name: 'test.txt'}; - detailsView.setFileInfo(fileInfo); - - expect(testView.canDisplay.calledOnce).toEqual(true); - expect(testView.canDisplay.calledWith(fileInfo)).toEqual(true); - - expect(detailsView.$el.find('.tabHeaders').hasClass('hidden')).toEqual(true); - expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('hidden')).toEqual(true); - expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('hidden')).toEqual(false); - }); - it('deselects the current tab if a model update does not pass the visibility check', function() { - testView = new OCA.Files.DetailTabView({id: 'test1'}); - testView.canDisplay = function(fileInfo) { - return fileInfo.mimetype !== 'httpd/unix-directory'; - }; - testView2 = new OCA.Files.DetailTabView({id: 'test2'}); - detailsView.addTabView(testView); - detailsView.addTabView(testView2); - - var fileInfo = {id: 5, name: 'test.txt', mimetype: 'text/plain'}; - detailsView.setFileInfo(fileInfo); - - expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('selected')).toEqual(true); - expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('selected')).toEqual(false); - - detailsView.setFileInfo({id: 10, name: 'folder', mimetype: 'httpd/unix-directory'}); - - expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('selected')).toEqual(false); - expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('selected')).toEqual(true); - }); - }); - it('sorts by order and then label', function() { - detailsView.remove(); - detailsView = new OCA.Files.DetailsView(); - detailsView.addTabView(new OCA.Files.DetailTabView({id: 'abc', order: 20})); - detailsView.addTabView(new OCA.Files.DetailTabView({id: 'def', order: 10})); - detailsView.addTabView(new OCA.Files.DetailTabView({id: 'jkl'})); - detailsView.addTabView(new OCA.Files.DetailTabView({id: 'ghi'})); - detailsView.render(); - - var tabs = detailsView.$el.find('.tabHeader').map(function() { - return $(this).attr('data-tabid'); - }).toArray(); - - expect(tabs).toEqual(['ghi', 'jkl', 'def', 'abc']); - }); - }); -}); diff --git a/apps/files/tests/js/favoritesfilelistspec.js b/apps/files/tests/js/favoritesfilelistspec.js deleted file mode 100644 index 1c833d334e2..00000000000 --- a/apps/files/tests/js/favoritesfilelistspec.js +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com> - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -describe('OCA.Files.FavoritesFileList tests', function() { - var fileList; - - beforeEach(function() { - // init parameters and test table elements - $('#testArea').append( - '<div id="app-content-container">' + - // init horrible parameters - '<input type="hidden" id="dir" value="/"></input>' + - '<input type="hidden" id="permissions" value="31"></input>' + - // dummy controls - '<div id="controls">' + - ' <div class="actions creatable"></div>' + - ' <div class="notCreatable"></div>' + - '</div>' + - // dummy table - // TODO: at some point this will be rendered by the fileList class itself! - '<table id="filestable">' + - '<thead><tr>' + - '<th id="headerName" class="hidden column-name">' + - '<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' + - '</th>' + - '<th class="hidden column-mtime">' + - '<a class="columntitle" data-sort="mtime"><span class="sort-indicator"></span></a>' + - '</th>' + - '</tr></thead>' + - '<tbody id="fileList"></tbody>' + - '<tfoot></tfoot>' + - '</table>' + - '<div id="emptycontent">Empty content message</div>' + - '</div>' - ); - }); - afterEach(function() { - fileList.destroy(); - fileList = undefined; - }); - - describe('loading file list', function() { - var response; - - beforeEach(function() { - fileList = new OCA.Files.FavoritesFileList( - $('#app-content-container') - ); - OCA.Files.FavoritesPlugin.attach(fileList); - - fileList.reload(); - - /* jshint camelcase: false */ - response = { - files: [{ - id: 7, - name: 'test.txt', - path: '/somedir', - size: 123, - mtime: 11111000, - tags: [OC.TAG_FAVORITE], - permissions: OC.PERMISSION_ALL, - mimetype: 'text/plain' - }] - }; - }); - it('render files', function() { - var request; - - expect(fakeServer.requests.length).toEqual(1); - request = fakeServer.requests[0]; - expect(request.url).toEqual( - OC.generateUrl('apps/files/api/v1/tags/{tagName}/files', {tagName: OC.TAG_FAVORITE}) - ); - - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(response) - ); - - var $rows = fileList.$el.find('tbody tr'); - var $tr = $rows.eq(0); - expect($rows.length).toEqual(1); - expect($tr.attr('data-id')).toEqual('7'); - expect($tr.attr('data-type')).toEqual('file'); - expect($tr.attr('data-file')).toEqual('test.txt'); - expect($tr.attr('data-path')).toEqual('/somedir'); - expect($tr.attr('data-size')).toEqual('123'); - expect(parseInt($tr.attr('data-permissions'), 10)) - .toEqual(OC.PERMISSION_ALL); - expect($tr.attr('data-mime')).toEqual('text/plain'); - expect($tr.attr('data-mtime')).toEqual('11111000'); - expect($tr.find('a.name').attr('href')).toEqual( - OC.webroot + - '/remote.php/webdav/somedir/test.txt' - ); - expect($tr.find('.nametext').text().trim()).toEqual('test.txt'); - }); - }); -}); diff --git a/apps/files/tests/js/favoritespluginspec.js b/apps/files/tests/js/favoritespluginspec.js deleted file mode 100644 index 1b144c28707..00000000000 --- a/apps/files/tests/js/favoritespluginspec.js +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com> - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -describe('OCA.Files.FavoritesPlugin tests', function() { - var Plugin = OCA.Files.FavoritesPlugin; - var fileList; - - beforeEach(function() { - $('#testArea').append( - '<div id="app-navigation">' + - '<ul><li data-id="files"><a>Files</a></li>' + - '<li data-id="sharingin"><a></a></li>' + - '<li data-id="sharingout"><a></a></li>' + - '</ul></div>' + - '<div id="app-content">' + - '<div id="app-content-files" class="hidden">' + - '</div>' + - '<div id="app-content-favorites" class="hidden">' + - '</div>' + - '</div>' + - '</div>' - ); - OC.Plugins.attach('OCA.Files.App', Plugin); - fileList = Plugin.showFileList($('#app-content-favorites')); - }); - afterEach(function() { - OC.Plugins.detach('OCA.Files.App', Plugin); - }); - - describe('initialization', function() { - it('inits favorites list on show', function() { - expect(fileList).toBeDefined(); - }); - }); - describe('file actions', function() { - var oldLegacyFileActions; - - beforeEach(function() { - oldLegacyFileActions = window.FileActions; - window.FileActions = new OCA.Files.FileActions(); - }); - - afterEach(function() { - window.FileActions = oldLegacyFileActions; - }); - it('provides default file actions', function() { - var fileActions = fileList.fileActions; - - expect(fileActions.actions.all).toBeDefined(); - expect(fileActions.actions.all.Delete).toBeDefined(); - expect(fileActions.actions.all.Rename).toBeDefined(); - expect(fileActions.actions.all.Download).toBeDefined(); - - expect(fileActions.defaults.dir).toEqual('Open'); - }); - it('provides custom file actions', function() { - var actionStub = sinon.stub(); - // regular file action - OCA.Files.fileActions.register( - 'all', - 'RegularTest', - OC.PERMISSION_READ, - OC.imagePath('core', 'actions/shared'), - actionStub - ); - - Plugin.favoritesFileList = null; - fileList = Plugin.showFileList($('#app-content-favorites')); - - expect(fileList.fileActions.actions.all.RegularTest).toBeDefined(); - }); - it('does not provide legacy file actions', function() { - var actionStub = sinon.stub(); - // legacy file action - window.FileActions.register( - 'all', - 'LegacyTest', - OC.PERMISSION_READ, - OC.imagePath('core', 'actions/shared'), - actionStub - ); - - Plugin.favoritesFileList = null; - fileList = Plugin.showFileList($('#app-content-favorites')); - - expect(fileList.fileActions.actions.all.LegacyTest).not.toBeDefined(); - }); - it('redirects to files app when opening a directory', function() { - var oldList = OCA.Files.App.fileList; - // dummy new list to make sure it exists - OCA.Files.App.fileList = new OCA.Files.FileList($('<table><thead></thead><tbody></tbody></table>')); - - var setActiveViewStub = sinon.stub(OCA.Files.App, 'setActiveView'); - // create dummy table so we can click the dom - var $table = '<table><thead></thead><tbody id="fileList"></tbody></table>'; - $('#app-content-favorites').append($table); - - Plugin.favoritesFileList = null; - fileList = Plugin.showFileList($('#app-content-favorites')); - - fileList.setFiles([{ - name: 'testdir', - type: 'dir', - path: '/somewhere/inside/subdir', - counterParts: ['user2'], - shareOwner: 'user2' - }]); - - fileList.findFileEl('testdir').find('td .nametext').click(); - - expect(OCA.Files.App.fileList.getCurrentDirectory()).toEqual('/somewhere/inside/subdir/testdir'); - - expect(setActiveViewStub.calledOnce).toEqual(true); - expect(setActiveViewStub.calledWith('files')).toEqual(true); - - setActiveViewStub.restore(); - - // restore old list - OCA.Files.App.fileList = oldList; - }); - }); -}); - diff --git a/apps/files/tests/js/fileUploadSpec.js b/apps/files/tests/js/fileUploadSpec.js deleted file mode 100644 index 0483d4649d4..00000000000 --- a/apps/files/tests/js/fileUploadSpec.js +++ /dev/null @@ -1,218 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2014 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/* global FileList */ - -describe('OC.Upload tests', function() { - var $dummyUploader; - var testFile; - - beforeEach(function() { - testFile = { - name: 'test.txt', - size: 5000, // 5 KB - type: 'text/plain', - lastModifiedDate: new Date() - }; - // need a dummy button because file-upload checks on it - $('#testArea').append( - '<input type="file" id="file_upload_start" name="files[]" multiple="multiple">' + - '<input type="hidden" id="upload_limit" name="upload_limit" value="10000000">' + // 10 MB - '<input type="hidden" id="free_space" name="free_space" value="50000000">' + // 50 MB - // TODO: handlebars! - '<div id="new">' + - '<a>New</a>' + - '<ul>' + - '<li data-type="file" data-newname="New text file.txt"><p>Text file</p></li>' + - '</ul>' + - '</div>' - ); - $dummyUploader = $('#file_upload_start'); - }); - afterEach(function() { - delete window.file_upload_param; - $dummyUploader = undefined; - }); - describe('Adding files for upload', function() { - var params; - var failStub; - - beforeEach(function() { - params = OC.Upload.init(); - failStub = sinon.stub(); - $dummyUploader.on('fileuploadfail', failStub); - }); - afterEach(function() { - params = undefined; - failStub = undefined; - }); - - /** - * Add file for upload - * @param file file data - */ - function addFile(file) { - return params.add.call( - $dummyUploader[0], - {}, - { - originalFiles: {}, - files: [file] - }); - } - - it('adds file when size is below limits', function() { - var result = addFile(testFile); - expect(result).toEqual(true); - }); - it('adds file when free space is unknown', function() { - var result; - $('#free_space').val(-2); - - result = addFile(testFile); - - expect(result).toEqual(true); - expect(failStub.notCalled).toEqual(true); - }); - it('does not add file if it exceeds upload limit', function() { - var result; - $('#upload_limit').val(1000); - - result = addFile(testFile); - - expect(result).toEqual(false); - expect(failStub.calledOnce).toEqual(true); - expect(failStub.getCall(0).args[1].textStatus).toEqual('sizeexceedlimit'); - expect(failStub.getCall(0).args[1].errorThrown).toEqual( - 'Total file size 5 KB exceeds upload limit 1000 B' - ); - }); - it('does not add file if it exceeds free space', function() { - var result; - $('#free_space').val(1000); - - result = addFile(testFile); - - expect(result).toEqual(false); - expect(failStub.calledOnce).toEqual(true); - expect(failStub.getCall(0).args[1].textStatus).toEqual('notenoughspace'); - expect(failStub.getCall(0).args[1].errorThrown).toEqual( - 'Not enough free space, you are uploading 5 KB but only 1000 B is left' - ); - }); - }); - describe('Upload conflicts', function() { - var oldFileList; - var conflictDialogStub; - var callbacks; - - beforeEach(function() { - oldFileList = FileList; - $('#testArea').append( - '<div id="tableContainer">' + - '<table id="filestable">' + - '<thead><tr>' + - '<th id="headerName" class="hidden column-name">' + - '<input type="checkbox" id="select_all_files" class="select-all">' + - '<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' + - '<span id="selectedActionsList" class="selectedActions hidden">' + - '<a href class="download"><img src="actions/download.svg">Download</a>' + - '<a href class="delete-selected">Delete</a></span>' + - '</th>' + - '<th class="hidden column-size"><a class="columntitle" data-sort="size"><span class="sort-indicator"></span></a></th>' + - '<th class="hidden column-mtime"><a class="columntitle" data-sort="mtime"><span class="sort-indicator"></span></a></th>' + - '</tr></thead>' + - '<tbody id="fileList"></tbody>' + - '<tfoot></tfoot>' + - '</table>' + - '</div>' - ); - FileList = new OCA.Files.FileList($('#tableContainer')); - - FileList.add({name: 'conflict.txt', mimetype: 'text/plain'}); - FileList.add({name: 'conflict2.txt', mimetype: 'text/plain'}); - - conflictDialogStub = sinon.stub(OC.dialogs, 'fileexists'); - callbacks = { - onNoConflicts: sinon.stub() - }; - }); - afterEach(function() { - conflictDialogStub.restore(); - - FileList.destroy(); - FileList = oldFileList; - }); - it('does not show conflict dialog when no client side conflict', function() { - var selection = { - // yes, the format of uploads is weird... - uploads: [ - {files: [{name: 'noconflict.txt'}]}, - {files: [{name: 'noconflict2.txt'}]} - ] - }; - - OC.Upload.checkExistingFiles(selection, callbacks); - - expect(conflictDialogStub.notCalled).toEqual(true); - expect(callbacks.onNoConflicts.calledOnce).toEqual(true); - expect(callbacks.onNoConflicts.calledWith(selection)).toEqual(true); - }); - it('shows conflict dialog when no client side conflict', function() { - var selection = { - // yes, the format of uploads is weird... - uploads: [ - {files: [{name: 'conflict.txt'}]}, - {files: [{name: 'conflict2.txt'}]}, - {files: [{name: 'noconflict.txt'}]} - ] - }; - - var deferred = $.Deferred(); - conflictDialogStub.returns(deferred.promise()); - deferred.resolve(); - - OC.Upload.checkExistingFiles(selection, callbacks); - - expect(conflictDialogStub.callCount).toEqual(3); - expect(conflictDialogStub.getCall(1).args[0]) - .toEqual({files: [ { name: 'conflict.txt' } ]}); - expect(conflictDialogStub.getCall(1).args[1]) - .toEqual({ name: 'conflict.txt', mimetype: 'text/plain', directory: '/' }); - expect(conflictDialogStub.getCall(1).args[2]).toEqual({ name: 'conflict.txt' }); - - // yes, the dialog must be called several times... - expect(conflictDialogStub.getCall(2).args[0]).toEqual({ - files: [ { name: 'conflict2.txt' } ] - }); - expect(conflictDialogStub.getCall(2).args[1]) - .toEqual({ name: 'conflict2.txt', mimetype: 'text/plain', directory: '/' }); - expect(conflictDialogStub.getCall(2).args[2]).toEqual({ name: 'conflict2.txt' }); - - expect(callbacks.onNoConflicts.calledOnce).toEqual(true); - expect(callbacks.onNoConflicts.calledWith({ - uploads: [ - {files: [{name: 'noconflict.txt'}]} - ] - })).toEqual(true); - }); - }); -}); diff --git a/apps/files/tests/js/fileactionsSpec.js b/apps/files/tests/js/fileactionsSpec.js deleted file mode 100644 index 3f46a27d1f9..00000000000 --- a/apps/files/tests/js/fileactionsSpec.js +++ /dev/null @@ -1,679 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2014 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -describe('OCA.Files.FileActions tests', function() { - var fileList, fileActions, clock; - - beforeEach(function() { - clock = sinon.useFakeTimers(); - // init horrible parameters - var $body = $('#testArea'); - $body.append('<input type="hidden" id="dir" value="/subdir"></input>'); - $body.append('<input type="hidden" id="permissions" value="31"></input>'); - $body.append('<table id="filestable"><tbody id="fileList"></tbody></table>'); - // dummy files table - fileActions = new OCA.Files.FileActions(); - fileActions.registerAction({ - name: 'Testdropdown', - displayName: 'Testdropdowndisplay', - mime: 'all', - permissions: OC.PERMISSION_READ, - icon: function () { - return OC.imagePath('core', 'actions/download'); - } - }); - - fileActions.registerAction({ - name: 'Testinline', - displayName: 'Testinlinedisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - permissions: OC.PERMISSION_READ - }); - - fileActions.registerAction({ - name: 'Testdefault', - displayName: 'Testdefaultdisplay', - mime: 'all', - permissions: OC.PERMISSION_READ - }); - fileActions.setDefault('all', 'Testdefault'); - fileList = new OCA.Files.FileList($body, { - fileActions: fileActions - }); - }); - afterEach(function() { - fileActions = null; - fileList.destroy(); - fileList = undefined; - clock.restore(); - $('#dir, #permissions, #filestable').remove(); - }); - it('calling clear() clears file actions', function() { - fileActions.clear(); - expect(fileActions.actions).toEqual({}); - expect(fileActions.defaults).toEqual({}); - expect(fileActions.icons).toEqual({}); - expect(fileActions.currentFile).toBe(null); - }); - describe('displaying actions', function() { - var $tr; - - beforeEach(function() { - var fileData = { - id: 18, - type: 'file', - name: 'testName.txt', - mimetype: 'text/plain', - size: '1234', - etag: 'a01234c', - mtime: '123456', - permissions: OC.PERMISSION_READ | OC.PERMISSION_UPDATE - }; - - // note: FileActions.display() is called implicitly - $tr = fileList.add(fileData); - }); - it('renders inline file actions', function() { - // actions defined after call - expect($tr.find('.action.action-testinline').length).toEqual(1); - expect($tr.find('.action.action-testinline').attr('data-action')).toEqual('Testinline'); - }); - it('does not render dropdown actions', function() { - expect($tr.find('.action.action-testdropdown').length).toEqual(0); - }); - it('does not render default action', function() { - expect($tr.find('.action.action-testdefault').length).toEqual(0); - }); - it('replaces file actions when displayed twice', function() { - fileActions.display($tr.find('td.filename'), true, fileList); - fileActions.display($tr.find('td.filename'), true, fileList); - - expect($tr.find('.action.action-testinline').length).toEqual(1); - }); - it('renders actions menu trigger', function() { - expect($tr.find('.action.action-menu').length).toEqual(1); - expect($tr.find('.action.action-menu').attr('data-action')).toEqual('menu'); - }); - it('only renders actions relevant to the mime type', function() { - fileActions.registerAction({ - name: 'Match', - displayName: 'MatchDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'text/plain', - permissions: OC.PERMISSION_READ - }); - fileActions.registerAction({ - name: 'Nomatch', - displayName: 'NoMatchDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'application/octet-stream', - permissions: OC.PERMISSION_READ - }); - - fileActions.display($tr.find('td.filename'), true, fileList); - expect($tr.find('.action.action-match').length).toEqual(1); - expect($tr.find('.action.action-nomatch').length).toEqual(0); - }); - it('only renders actions relevant to the permissions', function() { - fileActions.registerAction({ - name: 'Match', - displayName: 'MatchDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'text/plain', - permissions: OC.PERMISSION_UPDATE - }); - fileActions.registerAction({ - name: 'Nomatch', - displayName: 'NoMatchDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'text/plain', - permissions: OC.PERMISSION_DELETE - }); - - fileActions.display($tr.find('td.filename'), true, fileList); - expect($tr.find('.action.action-match').length).toEqual(1); - expect($tr.find('.action.action-nomatch').length).toEqual(0); - }); - it('display inline icon with image path', function() { - fileActions.registerAction({ - name: 'Icon', - displayName: 'IconDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - icon: OC.imagePath('core', 'actions/icon'), - permissions: OC.PERMISSION_READ - }); - fileActions.registerAction({ - name: 'NoIcon', - displayName: 'NoIconDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - permissions: OC.PERMISSION_READ - }); - - fileActions.display($tr.find('td.filename'), true, fileList); - - expect($tr.find('.action.action-icon').length).toEqual(1); - expect($tr.find('.action.action-icon').find('img').length).toEqual(1); - expect($tr.find('.action.action-icon').find('img').eq(0).attr('src')).toEqual(OC.imagePath('core', 'actions/icon')); - - expect($tr.find('.action.action-noicon').length).toEqual(1); - expect($tr.find('.action.action-noicon').find('img').length).toEqual(0); - }); - it('display alt text on inline icon with image path', function() { - fileActions.registerAction({ - name: 'IconAltText', - displayName: 'IconAltTextDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - icon: OC.imagePath('core', 'actions/iconAltText'), - altText: 'alt icon text', - permissions: OC.PERMISSION_READ - }); - - fileActions.registerAction({ - name: 'IconNoAltText', - displayName: 'IconNoAltTextDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - icon: OC.imagePath('core', 'actions/iconNoAltText'), - permissions: OC.PERMISSION_READ - }); - - fileActions.display($tr.find('td.filename'), true, fileList); - - expect($tr.find('.action.action-iconalttext').length).toEqual(1); - expect($tr.find('.action.action-iconalttext').find('img').length).toEqual(1); - expect($tr.find('.action.action-iconalttext').find('img').eq(0).attr('alt')).toEqual('alt icon text'); - - expect($tr.find('.action.action-iconnoalttext').length).toEqual(1); - expect($tr.find('.action.action-iconnoalttext').find('img').length).toEqual(1); - expect($tr.find('.action.action-iconnoalttext').find('img').eq(0).attr('alt')).toEqual(''); - }); - it('display inline icon with iconClass', function() { - fileActions.registerAction({ - name: 'Icon', - displayName: 'IconDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - iconClass: 'icon-test', - permissions: OC.PERMISSION_READ - }); - fileActions.registerAction({ - name: 'NoIcon', - displayName: 'NoIconDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - permissions: OC.PERMISSION_READ - }); - - fileActions.display($tr.find('td.filename'), true, fileList); - - expect($tr.find('.action.action-icon').length).toEqual(1); - expect($tr.find('.action.action-icon').find('.icon').length).toEqual(1); - expect($tr.find('.action.action-icon').find('.icon').hasClass('icon-test')).toEqual(true); - - expect($tr.find('.action.action-noicon').length).toEqual(1); - expect($tr.find('.action.action-noicon').find('.icon').length).toEqual(0); - }); - it('display alt text on inline icon with iconClass when no display name exists', function() { - fileActions.registerAction({ - name: 'IconAltText', - displayName: '', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - iconClass: 'icon-alttext', - altText: 'alt icon text', - permissions: OC.PERMISSION_READ - }); - - fileActions.registerAction({ - name: 'IconNoAltText', - displayName: 'IconNoAltTextDisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - altText: 'useless alt text', - iconClass: 'icon-noalttext', - permissions: OC.PERMISSION_READ - }); - - fileActions.display($tr.find('td.filename'), true, fileList); - - expect($tr.find('.action.action-iconalttext').length).toEqual(1); - expect($tr.find('.action.action-iconalttext').find('.icon').length).toEqual(1); - expect($tr.find('.action.action-iconalttext').find('.hidden-visually').text()).toEqual('alt icon text'); - - expect($tr.find('.action.action-iconnoalttext').length).toEqual(1); - expect($tr.find('.action.action-iconnoalttext').find('.icon').length).toEqual(1); - expect($tr.find('.action.action-iconnoalttext').find('.hidden-visually').length).toEqual(0); - }); - }); - describe('action handler', function() { - var actionStub, $tr, clock; - - beforeEach(function() { - clock = sinon.useFakeTimers(); - var fileData = { - id: 18, - type: 'file', - name: 'testName.txt', - mimetype: 'text/plain', - size: '1234', - etag: 'a01234c', - mtime: '123456' - }; - actionStub = sinon.stub(); - fileActions.registerAction({ - name: 'Test', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - icon: OC.imagePath('core', 'actions/test'), - permissions: OC.PERMISSION_READ, - actionHandler: actionStub - }); - $tr = fileList.add(fileData); - }); - afterEach(function() { - OC.hideMenus(); - // jump past animations - clock.tick(1000); - clock.restore(); - }); - it('passes context to action handler', function() { - $tr.find('.action-test').click(); - expect(actionStub.calledOnce).toEqual(true); - expect(actionStub.getCall(0).args[0]).toEqual('testName.txt'); - var context = actionStub.getCall(0).args[1]; - expect(context.$file.is($tr)).toEqual(true); - expect(context.fileList).toBeDefined(); - expect(context.fileActions).toBeDefined(); - expect(context.dir).toEqual('/subdir'); - expect(context.fileInfoModel.get('name')).toEqual('testName.txt'); - - // when data-path is defined - actionStub.reset(); - $tr.attr('data-path', '/somepath'); - $tr.find('.action-test').click(); - context = actionStub.getCall(0).args[1]; - expect(context.dir).toEqual('/somepath'); - }); - it('also triggers action handler when calling triggerAction()', function() { - var model = new OCA.Files.FileInfoModel({ - id: 1, - name: 'Test.txt', - path: '/subdir', - mime: 'text/plain', - permissions: 31 - }); - fileActions.triggerAction('Test', model, fileList); - - expect(actionStub.calledOnce).toEqual(true); - expect(actionStub.getCall(0).args[0]).toEqual('Test.txt'); - expect(actionStub.getCall(0).args[1].fileList).toEqual(fileList); - expect(actionStub.getCall(0).args[1].fileActions).toEqual(fileActions); - expect(actionStub.getCall(0).args[1].fileInfoModel).toEqual(model); - }); - describe('actions menu', function() { - it('shows actions menu inside row when clicking the menu trigger', function() { - expect($tr.find('td.filename .fileActionsMenu').length).toEqual(0); - $tr.find('.action-menu').click(); - expect($tr.find('td.filename .fileActionsMenu').length).toEqual(1); - }); - it('shows highlight on current row', function() { - $tr.find('.action-menu').click(); - expect($tr.hasClass('mouseOver')).toEqual(true); - }); - it('cleans up after hiding', function() { - var slideUpStub = sinon.stub($.fn, 'slideUp'); - $tr.find('.action-menu').click(); - expect($tr.find('.fileActionsMenu').length).toEqual(1); - OC.hideMenus(); - // sliding animation - expect(slideUpStub.calledOnce).toEqual(true); - slideUpStub.getCall(0).args[1](); - expect($tr.hasClass('mouseOver')).toEqual(false); - expect($tr.find('.fileActionsMenu').length).toEqual(0); - }); - }); - }); - describe('custom rendering', function() { - var $tr; - beforeEach(function() { - var fileData = { - id: 18, - type: 'file', - name: 'testName.txt', - mimetype: 'text/plain', - size: '1234', - etag: 'a01234c', - mtime: '123456' - }; - $tr = fileList.add(fileData); - }); - it('regular function', function() { - var actionStub = sinon.stub(); - fileActions.registerAction({ - name: 'Test', - displayName: '', - mime: 'all', - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_READ, - render: function(actionSpec, isDefault, context) { - expect(actionSpec.name).toEqual('Test'); - expect(actionSpec.displayName).toEqual(''); - expect(actionSpec.permissions).toEqual(OC.PERMISSION_READ); - expect(actionSpec.mime).toEqual('all'); - expect(isDefault).toEqual(false); - - expect(context.fileList).toEqual(fileList); - expect(context.$file[0]).toEqual($tr[0]); - - var $customEl = $('<a class="action action-test" href="#"><span>blabli</span><span>blabla</span></a>'); - $tr.find('td:first').append($customEl); - return $customEl; - }, - actionHandler: actionStub - }); - fileActions.display($tr.find('td.filename'), true, fileList); - - var $actionEl = $tr.find('td:first .action-test'); - expect($actionEl.length).toEqual(1); - expect($actionEl.hasClass('action')).toEqual(true); - - $actionEl.click(); - expect(actionStub.calledOnce).toEqual(true); - expect(actionStub.getCall(0).args[0]).toEqual('testName.txt'); - }); - }); - describe('merging', function() { - var $tr; - beforeEach(function() { - var fileData = { - id: 18, - type: 'file', - name: 'testName.txt', - path: '/anotherpath/there', - mimetype: 'text/plain', - size: '1234', - etag: 'a01234c', - mtime: '123456' - }; - $tr = fileList.add(fileData); - }); - afterEach(function() { - $tr = null; - }); - it('copies all actions to target file actions', function() { - var actions1 = new OCA.Files.FileActions(); - var actions2 = new OCA.Files.FileActions(); - var actionStub1 = sinon.stub(); - var actionStub2 = sinon.stub(); - actions1.registerAction({ - name: 'Test', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub1 - }); - actions2.registerAction({ - name: 'Test2', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub2 - }); - actions2.merge(actions1); - - actions2.display($tr.find('td.filename'), true, fileList); - - expect($tr.find('.action-test').length).toEqual(1); - expect($tr.find('.action-test2').length).toEqual(1); - - $tr.find('.action-test').click(); - expect(actionStub1.calledOnce).toEqual(true); - expect(actionStub2.notCalled).toEqual(true); - - actionStub1.reset(); - - $tr.find('.action-test2').click(); - expect(actionStub1.notCalled).toEqual(true); - expect(actionStub2.calledOnce).toEqual(true); - }); - it('overrides existing actions on merge', function() { - var actions1 = new OCA.Files.FileActions(); - var actions2 = new OCA.Files.FileActions(); - var actionStub1 = sinon.stub(); - var actionStub2 = sinon.stub(); - actions1.registerAction({ - name: 'Test', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub1 - }); - actions2.registerAction({ - name: 'Test', // override - mime: 'all', - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub2 - }); - actions1.merge(actions2); - - actions1.display($tr.find('td.filename'), true, fileList); - - expect($tr.find('.action-test').length).toEqual(1); - - $tr.find('.action-test').click(); - expect(actionStub1.notCalled).toEqual(true); - expect(actionStub2.calledOnce).toEqual(true); - }); - it('overrides existing action when calling register after merge', function() { - var actions1 = new OCA.Files.FileActions(); - var actions2 = new OCA.Files.FileActions(); - var actionStub1 = sinon.stub(); - var actionStub2 = sinon.stub(); - actions1.registerAction({ - mime: 'all', - name: 'Test', - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub1 - }); - - actions1.merge(actions2); - - // late override - actions1.registerAction({ - mime: 'all', - name: 'Test', // override - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub2 - }); - - actions1.display($tr.find('td.filename'), true, fileList); - - expect($tr.find('.action-test').length).toEqual(1); - - $tr.find('.action-test').click(); - expect(actionStub1.notCalled).toEqual(true); - expect(actionStub2.calledOnce).toEqual(true); - }); - it('leaves original file actions untouched (clean copy)', function() { - var actions1 = new OCA.Files.FileActions(); - var actions2 = new OCA.Files.FileActions(); - var actionStub1 = sinon.stub(); - var actionStub2 = sinon.stub(); - actions1.registerAction({ - mime: 'all', - name: 'Test', - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub1 - }); - - // copy the Test action to actions2 - actions2.merge(actions1); - - // late override - actions2.registerAction({ - mime: 'all', - name: 'Test', // override - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub2 - }); - - // check if original actions still call the correct handler - actions1.display($tr.find('td.filename'), true, fileList); - - expect($tr.find('.action-test').length).toEqual(1); - - $tr.find('.action-test').click(); - expect(actionStub1.calledOnce).toEqual(true); - expect(actionStub2.notCalled).toEqual(true); - }); - }); - describe('events', function() { - var clock; - beforeEach(function() { - clock = sinon.useFakeTimers(); - }); - afterEach(function() { - clock.restore(); - }); - it('notifies update event handlers once after multiple changes', function() { - var actionStub = sinon.stub(); - var handler = sinon.stub(); - fileActions.on('registerAction', handler); - fileActions.registerAction({ - mime: 'all', - name: 'Test', - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub - }); - fileActions.registerAction({ - mime: 'all', - name: 'Test2', - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub - }); - expect(handler.calledTwice).toEqual(true); - }); - it('does not notifies update event handlers after unregistering', function() { - var actionStub = sinon.stub(); - var handler = sinon.stub(); - fileActions.on('registerAction', handler); - fileActions.off('registerAction', handler); - fileActions.registerAction({ - mime: 'all', - name: 'Test', - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub - }); - fileActions.registerAction({ - mime: 'all', - name: 'Test2', - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_READ, - icon: OC.imagePath('core', 'actions/test'), - actionHandler: actionStub - }); - expect(handler.notCalled).toEqual(true); - }); - }); - describe('default actions', function() { - describe('download', function() { - it('redirects to URL and sets busy state to list', function() { - var handleDownloadStub = sinon.stub(OCA.Files.Files, 'handleDownload'); - var busyStub = sinon.stub(fileList, 'showFileBusyState'); - var fileData = { - id: 18, - type: 'file', - name: 'testName.txt', - mimetype: 'text/plain', - size: '1234', - etag: 'a01234c', - mtime: '123456', - permissions: OC.PERMISSION_READ | OC.PERMISSION_UPDATE - }; - - // note: FileActions.display() is called implicitly - fileList.add(fileData); - - var model = fileList.getModelForFile('testName.txt'); - - fileActions.registerDefaultActions(); - fileActions.triggerAction('Download', model, fileList); - - expect(busyStub.calledOnce).toEqual(true); - expect(busyStub.calledWith('testName.txt', true)).toEqual(true); - expect(handleDownloadStub.calledOnce).toEqual(true); - expect(handleDownloadStub.getCall(0).args[0]).toEqual( - OC.webroot + '/remote.php/webdav/subdir/testName.txt' - ); - busyStub.reset(); - handleDownloadStub.yield(); - - expect(busyStub.calledOnce).toEqual(true); - expect(busyStub.calledWith('testName.txt', false)).toEqual(true); - - busyStub.restore(); - handleDownloadStub.restore(); - }); - }); - }); - describe('download spinner', function() { - var FileActions = OCA.Files.FileActions; - var $el; - - beforeEach(function() { - $el = $('<a href="#"><span class="icon icon-download"></span><span>Download</span></a>'); - }); - - it('replaces download icon with spinner', function() { - FileActions.updateFileActionSpinner($el, true); - expect($el.find('.icon.loading').length).toEqual(1); - expect($el.find('.icon.icon-download').hasClass('hidden')).toEqual(true); - }); - it('replaces spinner back with download icon with spinner', function() { - FileActions.updateFileActionSpinner($el, true); - FileActions.updateFileActionSpinner($el, false); - expect($el.find('.icon.loading').length).toEqual(0); - expect($el.find('.icon.icon-download').hasClass('hidden')).toEqual(false); - }); - }); -}); diff --git a/apps/files/tests/js/fileactionsmenuSpec.js b/apps/files/tests/js/fileactionsmenuSpec.js deleted file mode 100644 index 3028db2b3ac..00000000000 --- a/apps/files/tests/js/fileactionsmenuSpec.js +++ /dev/null @@ -1,325 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2015 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -describe('OCA.Files.FileActionsMenu tests', function() { - var fileList, fileActions, menu, actionStub, menuContext, $tr; - - beforeEach(function() { - // init horrible parameters - var $body = $('#testArea'); - $body.append('<input type="hidden" id="dir" value="/subdir"></input>'); - $body.append('<input type="hidden" id="permissions" value="31"></input>'); - // dummy files table - actionStub = sinon.stub(); - fileActions = new OCA.Files.FileActions(); - fileList = new OCA.Files.FileList($body, { - fileActions: fileActions - }); - - fileActions.registerAction({ - name: 'Testdropdown', - displayName: 'Testdropdowndisplay', - mime: 'all', - permissions: OC.PERMISSION_READ, - icon: function () { - return OC.imagePath('core', 'actions/download'); - }, - actionHandler: actionStub - }); - - fileActions.registerAction({ - name: 'Testdropdownnoicon', - displayName: 'Testdropdowndisplaynoicon', - mime: 'all', - permissions: OC.PERMISSION_READ, - actionHandler: actionStub - }); - - fileActions.registerAction({ - name: 'Testinline', - displayName: 'Testinlinedisplay', - type: OCA.Files.FileActions.TYPE_INLINE, - mime: 'all', - permissions: OC.PERMISSION_READ - }); - - fileActions.registerAction({ - name: 'Testdefault', - displayName: 'Testdefaultdisplay', - mime: 'all', - permissions: OC.PERMISSION_READ - }); - fileActions.setDefault('all', 'Testdefault'); - - var fileData = { - id: 18, - type: 'file', - name: 'testName.txt', - mimetype: 'text/plain', - size: '1234', - etag: 'a01234c', - mtime: '123456' - }; - $tr = fileList.add(fileData); - - menuContext = { - $file: $tr, - fileList: fileList, - fileActions: fileActions, - dir: fileList.getCurrentDirectory() - }; - menu = new OCA.Files.FileActionsMenu(); - menu.show(menuContext); - }); - afterEach(function() { - fileActions = null; - fileList.destroy(); - fileList = undefined; - menu.remove(); - $('#dir, #permissions, #filestable').remove(); - }); - - describe('rendering', function() { - it('renders dropdown actions in menu', function() { - var $action = menu.$el.find('a[data-action=Testdropdown]'); - expect($action.length).toEqual(1); - expect($action.find('img').attr('src')) - .toEqual(OC.imagePath('core', 'actions/download')); - expect($action.find('.no-icon').length).toEqual(0); - - $action = menu.$el.find('a[data-action=Testdropdownnoicon]'); - expect($action.length).toEqual(1); - expect($action.find('img').length).toEqual(0); - expect($action.find('.no-icon').length).toEqual(1); - }); - it('does not render default actions', function() { - expect(menu.$el.find('a[data-action=Testdefault]').length).toEqual(0); - }); - it('does not render inline actions', function() { - expect(menu.$el.find('a[data-action=Testinline]').length).toEqual(0); - }); - it('only renders actions relevant to the mime type', function() { - fileActions.registerAction({ - name: 'Match', - displayName: 'MatchDisplay', - mime: 'text/plain', - permissions: OC.PERMISSION_READ - }); - fileActions.registerAction({ - name: 'Nomatch', - displayName: 'NoMatchDisplay', - mime: 'application/octet-stream', - permissions: OC.PERMISSION_READ - }); - - menu.render(); - expect(menu.$el.find('a[data-action=Match]').length).toEqual(1); - expect(menu.$el.find('a[data-action=NoMatch]').length).toEqual(0); - }); - it('only renders actions relevant to the permissions', function() { - fileActions.registerAction({ - name: 'Match', - displayName: 'MatchDisplay', - mime: 'text/plain', - permissions: OC.PERMISSION_UPDATE - }); - fileActions.registerAction({ - name: 'Nomatch', - displayName: 'NoMatchDisplay', - mime: 'text/plain', - permissions: OC.PERMISSION_DELETE - }); - - menu.render(); - expect(menu.$el.find('a[data-action=Match]').length).toEqual(1); - expect(menu.$el.find('a[data-action=NoMatch]').length).toEqual(0); - }); - it('sorts by order attribute, then name', function() { - fileActions.registerAction({ - name: 'Baction', - displayName: 'Baction', - order: 2, - mime: 'text/plain', - permissions: OC.PERMISSION_ALL - }); - fileActions.registerAction({ - name: 'Zaction', - displayName: 'Zaction', - order: 1, - mime: 'text/plain', - permissions: OC.PERMISSION_ALL - }); - fileActions.registerAction({ - name: 'Yaction', - displayName: 'Yaction', - mime: 'text/plain', - permissions: OC.PERMISSION_ALL - }); - fileActions.registerAction({ - name: 'Waction', - displayName: 'Waction', - mime: 'text/plain', - permissions: OC.PERMISSION_ALL - }); - - menu.render(); - var zactionIndex = menu.$el.find('a[data-action=Zaction]').closest('li').index(); - var bactionIndex = menu.$el.find('a[data-action=Baction]').closest('li').index(); - expect(zactionIndex).toBeLessThan(bactionIndex); - - var wactionIndex = menu.$el.find('a[data-action=Waction]').closest('li').index(); - var yactionIndex = menu.$el.find('a[data-action=Yaction]').closest('li').index(); - expect(wactionIndex).toBeLessThan(yactionIndex); - }); - it('calls displayName function', function() { - var displayNameStub = sinon.stub().returns('Test'); - - fileActions.registerAction({ - name: 'Something', - displayName: displayNameStub, - mime: 'text/plain', - permissions: OC.PERMISSION_ALL - }); - - menu.render(); - - expect(displayNameStub.calledOnce).toEqual(true); - expect(displayNameStub.calledWith(menuContext)).toEqual(true); - expect(menu.$el.find('a[data-action=Something]').text()).toEqual('Test'); - }); - }); - - describe('action handler', function() { - it('calls action handler when clicking menu item', function() { - var $action = menu.$el.find('a[data-action=Testdropdown]'); - $action.click(); - - expect(actionStub.calledOnce).toEqual(true); - expect(actionStub.getCall(0).args[0]).toEqual('testName.txt'); - expect(actionStub.getCall(0).args[1].$file[0]).toEqual($tr[0]); - expect(actionStub.getCall(0).args[1].fileList).toEqual(fileList); - expect(actionStub.getCall(0).args[1].fileActions).toEqual(fileActions); - expect(actionStub.getCall(0).args[1].dir).toEqual('/subdir'); - }); - }); - describe('default actions from registerDefaultActions', function() { - beforeEach(function() { - fileActions.clear(); - fileActions.registerDefaultActions(); - }); - it('redirects to download URL when clicking download', function() { - var redirectStub = sinon.stub(OC, 'redirect'); - var fileData = { - id: 18, - type: 'file', - name: 'testName.txt', - mimetype: 'text/plain', - size: '1234', - etag: 'a01234c', - mtime: '123456' - }; - var $tr = fileList.add(fileData); - fileActions.display($tr.find('td.filename'), true, fileList); - - var menuContext = { - $file: $tr, - fileList: fileList, - fileActions: fileActions, - dir: fileList.getCurrentDirectory() - }; - menu = new OCA.Files.FileActionsMenu(); - menu.show(menuContext); - - menu.$el.find('.action-download').click(); - - expect(redirectStub.calledOnce).toEqual(true); - expect(redirectStub.getCall(0).args[0]).toContain( - OC.webroot + - '/remote.php/webdav/subdir/testName.txt' - ); - redirectStub.restore(); - }); - it('takes the file\'s path into account when clicking download', function() { - var redirectStub = sinon.stub(OC, 'redirect'); - var fileData = { - id: 18, - type: 'file', - name: 'testName.txt', - path: '/anotherpath/there', - mimetype: 'text/plain', - size: '1234', - etag: 'a01234c', - mtime: '123456' - }; - var $tr = fileList.add(fileData); - fileActions.display($tr.find('td.filename'), true, fileList); - - var menuContext = { - $file: $tr, - fileList: fileList, - fileActions: fileActions, - dir: '/anotherpath/there' - }; - menu = new OCA.Files.FileActionsMenu(); - menu.show(menuContext); - - menu.$el.find('.action-download').click(); - - expect(redirectStub.calledOnce).toEqual(true); - expect(redirectStub.getCall(0).args[0]).toContain( - OC.webroot + '/remote.php/webdav/anotherpath/there/testName.txt' - ); - redirectStub.restore(); - }); - it('deletes file when clicking delete', function() { - var deleteStub = sinon.stub(fileList, 'do_delete'); - var fileData = { - id: 18, - type: 'file', - name: 'testName.txt', - path: '/somepath/dir', - mimetype: 'text/plain', - size: '1234', - etag: 'a01234c', - mtime: '123456' - }; - var $tr = fileList.add(fileData); - fileActions.display($tr.find('td.filename'), true, fileList); - - var menuContext = { - $file: $tr, - fileList: fileList, - fileActions: fileActions, - dir: '/somepath/dir' - }; - menu = new OCA.Files.FileActionsMenu(); - menu.show(menuContext); - - menu.$el.find('.action-delete').click(); - - expect(deleteStub.calledOnce).toEqual(true); - expect(deleteStub.getCall(0).args[0]).toEqual('testName.txt'); - expect(deleteStub.getCall(0).args[1]).toEqual('/somepath/dir'); - deleteStub.restore(); - }); - }); -}); - diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js deleted file mode 100644 index a83c8c4c0bc..00000000000 --- a/apps/files/tests/js/filelistSpec.js +++ /dev/null @@ -1,2608 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2014 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -describe('OCA.Files.FileList tests', function() { - var FileInfo = OC.Files.FileInfo; - var testFiles, testRoot, notificationStub, fileList, pageSizeStub; - var bcResizeStub; - var filesClient; - var redirectStub; - - /** - * Generate test file data - */ - function generateFiles(startIndex, endIndex) { - var files = []; - var name; - for (var i = startIndex; i <= endIndex; i++) { - name = 'File with index '; - if (i < 10) { - // do not rely on localeCompare here - // and make the sorting predictable - // cross-browser - name += '0'; - } - name += i + '.txt'; - files.push(new FileInfo({ - id: i, - type: 'file', - name: name, - mimetype: 'text/plain', - size: i * 2, - etag: 'abc' - })); - } - return files; - } - - beforeEach(function() { - filesClient = new OC.Files.Client({ - host: 'localhost', - port: 80, - // FIXME: uncomment after fixing the test OC.webroot - //root: OC.webroot + '/remote.php/webdav', - root: '/remote.php/webdav', - useHTTPS: false - }); - redirectStub = sinon.stub(OC, 'redirect'); - notificationStub = sinon.stub(OC.Notification, 'showTemporary'); - // prevent resize algo to mess up breadcrumb order while - // testing - bcResizeStub = sinon.stub(OCA.Files.BreadCrumb.prototype, '_resize'); - - // init parameters and test table elements - $('#testArea').append( - '<div id="app-content-files">' + - // init horrible parameters - '<input type="hidden" id="dir" value="/subdir"/>' + - '<input type="hidden" id="permissions" value="31"/>' + - // dummy controls - '<div id="controls">' + - ' <div class="actions creatable"></div>' + - ' <div class="notCreatable"></div>' + - '</div>' + - // uploader - '<input type="file" id="file_upload_start" name="files[]" multiple="multiple">' + - // dummy table - // TODO: at some point this will be rendered by the fileList class itself! - '<table id="filestable">' + - '<thead><tr>' + - '<th id="headerName" class="hidden column-name">' + - '<input type="checkbox" id="select_all_files" class="select-all checkbox">' + - '<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' + - '<span id="selectedActionsList" class="selectedActions hidden">' + - '<a href class="download"><img src="actions/download.svg">Download</a>' + - '<a href class="delete-selected">Delete</a></span>' + - '</th>' + - '<th class="hidden column-size"><a class="columntitle" data-sort="size"><span class="sort-indicator"></span></a></th>' + - '<th class="hidden column-mtime"><a class="columntitle" data-sort="mtime"><span class="sort-indicator"></span></a></th>' + - '</tr></thead>' + - '<tbody id="fileList"></tbody>' + - '<tfoot></tfoot>' + - '</table>' + - // TODO: move to handlebars template - '<div id="emptycontent"><h2>Empty content message</h2><p class="uploadmessage">Upload message</p></div>' + - '<div class="nofilterresults hidden"></div>' + - '</div>' - ); - - testRoot = new FileInfo({ - // root entry - id: 99, - type: 'dir', - name: '/subdir', - mimetype: 'httpd/unix-directory', - size: 1200000, - etag: 'a0b0c0d0', - permissions: OC.PERMISSION_ALL - }); - testFiles = [new FileInfo({ - id: 1, - type: 'file', - name: 'One.txt', - mimetype: 'text/plain', - mtime: 123456789, - size: 12, - etag: 'abc', - permissions: OC.PERMISSION_ALL - }), new FileInfo({ - id: 2, - type: 'file', - name: 'Two.jpg', - mimetype: 'image/jpeg', - mtime: 234567890, - size: 12049, - etag: 'def', - permissions: OC.PERMISSION_ALL - }), new FileInfo({ - id: 3, - type: 'file', - name: 'Three.pdf', - mimetype: 'application/pdf', - mtime: 234560000, - size: 58009, - etag: '123', - permissions: OC.PERMISSION_ALL - }), new FileInfo({ - id: 4, - type: 'dir', - name: 'somedir', - mimetype: 'httpd/unix-directory', - mtime: 134560000, - size: 250, - etag: '456', - permissions: OC.PERMISSION_ALL - })]; - pageSizeStub = sinon.stub(OCA.Files.FileList.prototype, 'pageSize').returns(20); - fileList = new OCA.Files.FileList($('#app-content-files'), { - filesClient: filesClient - }); - }); - afterEach(function() { - testFiles = undefined; - if (fileList) { - fileList.destroy(); - } - fileList = undefined; - - notificationStub.restore(); - bcResizeStub.restore(); - pageSizeStub.restore(); - redirectStub.restore(); - }); - describe('Getters', function() { - it('Returns the current directory', function() { - $('#dir').val('/one/two/three'); - expect(fileList.getCurrentDirectory()).toEqual('/one/two/three'); - }); - it('Returns the directory permissions as int', function() { - $('#permissions').val('23'); - expect(fileList.getDirectoryPermissions()).toEqual(23); - }); - }); - describe('Adding files', function() { - var clock, now; - beforeEach(function() { - // to prevent date comparison issues - clock = sinon.useFakeTimers(); - now = new Date(); - }); - afterEach(function() { - clock.restore(); - }); - it('generates file element with correct attributes when calling add() with file data', function() { - var fileData = new FileInfo({ - id: 18, - name: 'testName.txt', - mimetype: 'text/plain', - size: 1234, - etag: 'a01234c', - mtime: 123456 - }); - var $tr = fileList.add(fileData); - - expect($tr).toBeDefined(); - expect($tr[0].tagName.toLowerCase()).toEqual('tr'); - expect($tr.attr('data-id')).toEqual('18'); - expect($tr.attr('data-type')).toEqual('file'); - expect($tr.attr('data-file')).toEqual('testName.txt'); - expect($tr.attr('data-size')).toEqual('1234'); - expect($tr.attr('data-etag')).toEqual('a01234c'); - expect($tr.attr('data-permissions')).toEqual('31'); - expect($tr.attr('data-mime')).toEqual('text/plain'); - expect($tr.attr('data-mtime')).toEqual('123456'); - expect($tr.find('a.name').attr('href')) - .toEqual(OC.webroot + '/remote.php/webdav/subdir/testName.txt'); - expect($tr.find('.nametext').text().trim()).toEqual('testName.txt'); - - expect($tr.find('.filesize').text()).toEqual('1 KB'); - expect($tr.find('.date').text()).not.toEqual('?'); - expect(fileList.findFileEl('testName.txt')[0]).toEqual($tr[0]); - }); - it('generates dir element with correct attributes when calling add() with dir data', function() { - var fileData = new FileInfo({ - id: 19, - name: 'testFolder', - mimetype: 'httpd/unix-directory', - size: 1234, - etag: 'a01234c', - mtime: 123456 - }); - var $tr = fileList.add(fileData); - - expect($tr).toBeDefined(); - expect($tr[0].tagName.toLowerCase()).toEqual('tr'); - expect($tr.attr('data-id')).toEqual('19'); - expect($tr.attr('data-type')).toEqual('dir'); - expect($tr.attr('data-file')).toEqual('testFolder'); - expect($tr.attr('data-size')).toEqual('1234'); - expect($tr.attr('data-etag')).toEqual('a01234c'); - expect($tr.attr('data-permissions')).toEqual('31'); - expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); - expect($tr.attr('data-mtime')).toEqual('123456'); - - expect($tr.find('.filesize').text()).toEqual('1 KB'); - expect($tr.find('.date').text()).not.toEqual('?'); - - expect(fileList.findFileEl('testFolder')[0]).toEqual($tr[0]); - }); - it('generates file element with default attributes when calling add() with minimal data', function() { - var fileData = { - type: 'file', - name: 'testFile.txt' - }; - - clock.tick(123456); - var $tr = fileList.add(fileData); - - expect($tr).toBeDefined(); - expect($tr[0].tagName.toLowerCase()).toEqual('tr'); - expect($tr.attr('data-id')).toBeUndefined(); - expect($tr.attr('data-type')).toEqual('file'); - expect($tr.attr('data-file')).toEqual('testFile.txt'); - expect($tr.attr('data-size')).toBeUndefined(); - expect($tr.attr('data-etag')).toBeUndefined(); - expect($tr.attr('data-permissions')).toEqual('31'); - expect($tr.attr('data-mime')).toBeUndefined(); - expect($tr.attr('data-mtime')).toEqual('123456'); - - expect($tr.find('.filesize').text()).toEqual('Pending'); - expect($tr.find('.date').text()).not.toEqual('?'); - }); - it('generates dir element with default attributes when calling add() with minimal data', function() { - var fileData = { - type: 'dir', - name: 'testFolder' - }; - clock.tick(123456); - var $tr = fileList.add(fileData); - - expect($tr).toBeDefined(); - expect($tr[0].tagName.toLowerCase()).toEqual('tr'); - expect($tr.attr('data-id')).toBeUndefined(); - expect($tr.attr('data-type')).toEqual('dir'); - expect($tr.attr('data-file')).toEqual('testFolder'); - expect($tr.attr('data-size')).toBeUndefined(); - expect($tr.attr('data-etag')).toBeUndefined(); - expect($tr.attr('data-permissions')).toEqual('31'); - expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); - expect($tr.attr('data-mtime')).toEqual('123456'); - - expect($tr.find('.filesize').text()).toEqual('Pending'); - expect($tr.find('.date').text()).not.toEqual('?'); - }); - it('generates file element with zero size when size is explicitly zero', function() { - var fileData = { - type: 'dir', - name: 'testFolder', - size: '0' - }; - var $tr = fileList.add(fileData); - expect($tr.find('.filesize').text()).toEqual('0 KB'); - }); - it('generates file element with unknown date when mtime invalid', function() { - var fileData = { - type: 'dir', - name: 'testFolder', - mtime: -1 - }; - var $tr = fileList.add(fileData); - expect($tr.find('.date .modified').text()).toEqual('?'); - }); - it('adds new file to the end of the list', function() { - var $tr; - var fileData = { - type: 'file', - name: 'ZZZ.txt' - }; - fileList.setFiles(testFiles); - $tr = fileList.add(fileData); - expect($tr.index()).toEqual(4); - }); - it('inserts files in a sorted manner when insert option is enabled', function() { - for (var i = 0; i < testFiles.length; i++) { - fileList.add(testFiles[i]); - } - expect(fileList.files[0].name).toEqual('somedir'); - expect(fileList.files[1].name).toEqual('One.txt'); - expect(fileList.files[2].name).toEqual('Three.pdf'); - expect(fileList.files[3].name).toEqual('Two.jpg'); - }); - it('inserts new file at correct position', function() { - var $tr; - var fileData = { - type: 'file', - name: 'P comes after O.txt' - }; - for (var i = 0; i < testFiles.length; i++) { - fileList.add(testFiles[i]); - } - $tr = fileList.add(fileData); - // after "One.txt" - expect($tr.index()).toEqual(2); - expect(fileList.files[2]).toEqual(fileData); - }); - it('inserts new folder at correct position in insert mode', function() { - var $tr; - var fileData = { - type: 'dir', - name: 'somedir2 comes after somedir' - }; - for (var i = 0; i < testFiles.length; i++) { - fileList.add(testFiles[i]); - } - $tr = fileList.add(fileData); - expect($tr.index()).toEqual(1); - expect(fileList.files[1]).toEqual(fileData); - }); - it('inserts new file at the end correctly', function() { - var $tr; - var fileData = { - type: 'file', - name: 'zzz.txt' - }; - for (var i = 0; i < testFiles.length; i++) { - fileList.add(testFiles[i]); - } - $tr = fileList.add(fileData); - expect($tr.index()).toEqual(4); - expect(fileList.files[4]).toEqual(fileData); - }); - it('removes empty content message and shows summary when adding first file', function() { - var $summary; - var fileData = { - type: 'file', - name: 'first file.txt', - size: 12 - }; - fileList.setFiles([]); - expect(fileList.isEmpty).toEqual(true); - fileList.add(fileData); - $summary = $('#filestable .summary'); - expect($summary.hasClass('hidden')).toEqual(false); - // yes, ugly... - expect($summary.find('.info').text()).toEqual('0 folders and 1 file'); - expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(true); - expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false); - expect($summary.find('.filesize').text()).toEqual('12 B'); - expect($('#filestable thead th').hasClass('hidden')).toEqual(false); - expect($('#emptycontent').hasClass('hidden')).toEqual(true); - expect(fileList.isEmpty).toEqual(false); - }); - it('correctly adds the extension markup and show hidden files completely in gray', function() { - var $tr; - var testDataAndExpectedResult = [ - {file: {type: 'file', name: 'ZZZ.txt'}, extension: '.txt'}, - {file: {type: 'file', name: 'ZZZ.tar.gz'}, extension: '.gz'}, - {file: {type: 'file', name: 'test.with.some.dots.in.it.txt'}, extension: '.txt'}, - // we render hidden files completely in gray - {file: {type: 'file', name: '.test.with.some.dots.in.it.txt'}, extension: '.test.with.some.dots.in.it.txt'}, - {file: {type: 'file', name: '.hidden'}, extension: '.hidden'}, - ]; - fileList.setFiles(testFiles); - - for(var i = 0; i < testDataAndExpectedResult.length; i++) { - var testSet = testDataAndExpectedResult[i]; - var fileData = testSet['file']; - $tr = fileList.add(fileData); - expect($tr.find('.nametext .extension').text()).toEqual(testSet['extension']); - } - }); - }); - describe('Removing files from the list', function() { - it('Removes file from list when calling remove() and updates summary', function() { - var $summary; - var $removedEl; - fileList.setFiles(testFiles); - $removedEl = fileList.remove('One.txt'); - expect($removedEl).toBeDefined(); - expect($removedEl.attr('data-file')).toEqual('One.txt'); - expect($('#fileList tr').length).toEqual(3); - expect(fileList.files.length).toEqual(3); - expect(fileList.findFileEl('One.txt').length).toEqual(0); - - $summary = $('#filestable .summary'); - expect($summary.hasClass('hidden')).toEqual(false); - expect($summary.find('.info').text()).toEqual('1 folder and 2 files'); - expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(false); - expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false); - expect($summary.find('.filesize').text()).toEqual('69 KB'); - expect(fileList.isEmpty).toEqual(false); - }); - it('Shows empty content when removing last file', function() { - var $summary; - fileList.setFiles([testFiles[0]]); - fileList.remove('One.txt'); - expect($('#fileList tr').length).toEqual(0); - expect(fileList.files.length).toEqual(0); - expect(fileList.findFileEl('One.txt').length).toEqual(0); - - $summary = $('#filestable .summary'); - expect($summary.hasClass('hidden')).toEqual(true); - expect($('#filestable thead th').hasClass('hidden')).toEqual(true); - expect($('#emptycontent').hasClass('hidden')).toEqual(false); - expect(fileList.isEmpty).toEqual(true); - }); - }); - describe('Deleting files', function() { - var deferredDelete; - var deleteStub; - - beforeEach(function() { - deferredDelete = $.Deferred(); - deleteStub = sinon.stub(filesClient, 'remove').returns(deferredDelete.promise()); - }); - afterEach(function() { - deleteStub.restore(); - }); - - function doDelete() { - // note: normally called from FileActions - fileList.do_delete(['One.txt', 'Two.jpg']); - - expect(deleteStub.calledTwice).toEqual(true); - expect(deleteStub.getCall(0).args[0]).toEqual('/subdir/One.txt'); - expect(deleteStub.getCall(1).args[0]).toEqual('/subdir/Two.jpg'); - } - it('calls delete.php, removes the deleted entries and updates summary', function() { - var $summary; - fileList.setFiles(testFiles); - doDelete(); - - deferredDelete.resolve(200); - - expect(fileList.findFileEl('One.txt').length).toEqual(0); - expect(fileList.findFileEl('Two.jpg').length).toEqual(0); - expect(fileList.findFileEl('Three.pdf').length).toEqual(1); - expect(fileList.$fileList.find('tr').length).toEqual(2); - - $summary = $('#filestable .summary'); - expect($summary.hasClass('hidden')).toEqual(false); - expect($summary.find('.info').text()).toEqual('1 folder and 1 file'); - expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(false); - expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false); - expect($summary.find('.filesize').text()).toEqual('57 KB'); - expect(fileList.isEmpty).toEqual(false); - expect($('#filestable thead th').hasClass('hidden')).toEqual(false); - expect($('#emptycontent').hasClass('hidden')).toEqual(true); - - expect(notificationStub.notCalled).toEqual(true); - }); - it('shows busy state on files to be deleted', function() { - fileList.setFiles(testFiles); - doDelete(); - - expect(fileList.findFileEl('One.txt').hasClass('busy')).toEqual(true); - expect(fileList.findFileEl('Three.pdf').hasClass('busy')).toEqual(false); - }); - it('shows busy state on all files when deleting all', function() { - fileList.setFiles(testFiles); - - fileList.do_delete(); - - expect(fileList.$fileList.find('tr.busy').length).toEqual(4); - }); - it('updates summary when deleting last file', function() { - var $summary; - fileList.setFiles([testFiles[0], testFiles[1]]); - doDelete(); - - deferredDelete.resolve(200); - - expect(fileList.$fileList.find('tr').length).toEqual(0); - - $summary = $('#filestable .summary'); - expect($summary.hasClass('hidden')).toEqual(true); - expect(fileList.isEmpty).toEqual(true); - expect(fileList.files.length).toEqual(0); - expect($('#filestable thead th').hasClass('hidden')).toEqual(true); - expect($('#emptycontent').hasClass('hidden')).toEqual(false); - }); - it('bring back deleted item when delete call failed', function() { - fileList.setFiles(testFiles); - doDelete(); - - deferredDelete.reject(403); - - // files are still in the list - expect(fileList.findFileEl('One.txt').length).toEqual(1); - expect(fileList.findFileEl('Two.jpg').length).toEqual(1); - expect(fileList.$fileList.find('tr').length).toEqual(4); - - expect(notificationStub.calledTwice).toEqual(true); - }); - it('remove file from list if delete call returned 404 not found', function() { - fileList.setFiles(testFiles); - doDelete(); - - deferredDelete.reject(404); - - // files are still in the list - expect(fileList.findFileEl('One.txt').length).toEqual(0); - expect(fileList.findFileEl('Two.jpg').length).toEqual(0); - expect(fileList.$fileList.find('tr').length).toEqual(2); - - expect(notificationStub.notCalled).toEqual(true); - }); - }); - describe('Renaming files', function() { - var deferredRename; - var renameStub; - - beforeEach(function() { - deferredRename = $.Deferred(); - renameStub = sinon.stub(filesClient, 'move').returns(deferredRename.promise()); - }); - afterEach(function() { - renameStub.restore(); - }); - - function doCancelRename() { - var $input; - for (var i = 0; i < testFiles.length; i++) { - fileList.add(testFiles[i]); - } - - // trigger rename prompt - fileList.rename('One.txt'); - $input = fileList.$fileList.find('input.filename'); - // keep same name - $input.val('One.txt'); - // trigger submit because triggering blur doesn't work in all browsers - $input.closest('form').trigger('submit'); - - expect(renameStub.notCalled).toEqual(true); - } - function doRename() { - var $input; - - for (var i = 0; i < testFiles.length; i++) { - var file = testFiles[i]; - file.path = '/some/subdir'; - fileList.add(file, {silent: true}); - } - - // trigger rename prompt - fileList.rename('One.txt'); - $input = fileList.$fileList.find('input.filename'); - $input.val('Tu_after_three.txt'); - // trigger submit because triggering blur doesn't work in all browsers - $input.closest('form').trigger('submit'); - - expect(renameStub.calledOnce).toEqual(true); - expect(renameStub.getCall(0).args[0]).toEqual('/some/subdir/One.txt'); - expect(renameStub.getCall(0).args[1]).toEqual('/some/subdir/Tu_after_three.txt'); - } - it('Inserts renamed file entry at correct position if rename ajax call suceeded', function() { - doRename(); - - deferredRename.resolve(201); - - // element stays renamed - expect(fileList.findFileEl('One.txt').length).toEqual(0); - expect(fileList.findFileEl('Tu_after_three.txt').length).toEqual(1); - expect(fileList.findFileEl('Tu_after_three.txt').index()).toEqual(2); // after Two.jpg - - expect(notificationStub.notCalled).toEqual(true); - }); - it('Reverts file entry if rename ajax call failed', function() { - doRename(); - - deferredRename.reject(403); - - // element was reverted - expect(fileList.findFileEl('One.txt').length).toEqual(1); - expect(fileList.findFileEl('One.txt').index()).toEqual(1); // after somedir - expect(fileList.findFileEl('Tu_after_three.txt').length).toEqual(0); - - expect(notificationStub.calledOnce).toEqual(true); - }); - it('Correctly updates file link after rename', function() { - var $tr; - doRename(); - - deferredRename.resolve(201); - - $tr = fileList.findFileEl('Tu_after_three.txt'); - expect($tr.find('a.name').attr('href')) - .toEqual(OC.webroot + '/remote.php/webdav/some/subdir/Tu_after_three.txt'); - }); - it('Triggers "fileActionsReady" event after rename', function() { - var handler = sinon.stub(); - fileList.$fileList.on('fileActionsReady', handler); - doRename(); - expect(handler.notCalled).toEqual(true); - - deferredRename.resolve(201); - - expect(handler.calledOnce).toEqual(true); - expect(fileList.$fileList.find('.test').length).toEqual(0); - }); - it('Leaves the summary alone when reinserting renamed element', function() { - var $summary = $('#filestable .summary'); - doRename(); - - deferredRename.resolve(201); - - expect($summary.find('.info').text()).toEqual('1 folder and 3 files'); - }); - it('Leaves the summary alone when cancel renaming', function() { - var $summary = $('#filestable .summary'); - doCancelRename(); - expect($summary.find('.info').text()).toEqual('1 folder and 3 files'); - }); - it('Shows busy state while rename in progress', function() { - var $tr; - doRename(); - - // element is renamed before the request finishes - $tr = fileList.findFileEl('Tu_after_three.txt'); - expect($tr.length).toEqual(1); - expect(fileList.findFileEl('One.txt').length).toEqual(0); - // file actions are hidden - expect($tr.hasClass('busy')).toEqual(true); - - // input and form are gone - expect(fileList.$fileList.find('input.filename').length).toEqual(0); - expect(fileList.$fileList.find('form').length).toEqual(0); - }); - it('Validates the file name', function() { - var $input, $tr; - - for (var i = 0; i < testFiles.length; i++) { - fileList.add(testFiles[i], {silent: true}); - } - - // trigger rename prompt - fileList.rename('One.txt'); - $input = fileList.$fileList.find('input.filename'); - $input.val('Two.jpg'); - - // simulate key to trigger validation - $input.trigger(new $.Event('keyup', {keyCode: 97})); - - // input is still there with error - expect(fileList.$fileList.find('input.filename').length).toEqual(1); - expect(fileList.$fileList.find('input.filename').hasClass('error')).toEqual(true); - - // trigger submit does not send server request - $input.closest('form').trigger('submit'); - expect(renameStub.notCalled).toEqual(true); - - // simulate escape key - $input.trigger(new $.Event('keyup', {keyCode: 27})); - - // element is added back with the correct name - $tr = fileList.findFileEl('One.txt'); - expect($tr.length).toEqual(1); - expect($tr.find('a .nametext').text().trim()).toEqual('One.txt'); - expect($tr.find('a.name').is(':visible')).toEqual(true); - - $tr = fileList.findFileEl('Two.jpg'); - expect($tr.length).toEqual(1); - expect($tr.find('a .nametext').text().trim()).toEqual('Two.jpg'); - expect($tr.find('a.name').is(':visible')).toEqual(true); - - // input and form are gone - expect(fileList.$fileList.find('input.filename').length).toEqual(0); - expect(fileList.$fileList.find('form').length).toEqual(0); - }); - it('Restores thumbnail when rename was cancelled', function() { - doRename(); - - expect(OC.TestUtil.getImageUrl(fileList.findFileEl('Tu_after_three.txt').find('.thumbnail'))) - .toEqual(OC.imagePath('core', 'loading.gif')); - - deferredRename.reject(409); - - expect(fileList.findFileEl('One.txt').length).toEqual(1); - expect(OC.TestUtil.getImageUrl(fileList.findFileEl('One.txt').find('.thumbnail'))) - .toEqual(OC.imagePath('core', 'filetypes/text.svg')); - }); - }); - describe('Moving files', function() { - var deferredMove; - var moveStub; - - beforeEach(function() { - deferredMove = $.Deferred(); - moveStub = sinon.stub(filesClient, 'move').returns(deferredMove.promise()); - - fileList.setFiles(testFiles); - }); - afterEach(function() { - moveStub.restore(); - }); - - it('Moves single file to target folder', function() { - fileList.move('One.txt', '/somedir'); - - expect(moveStub.calledOnce).toEqual(true); - expect(moveStub.getCall(0).args[0]).toEqual('/subdir/One.txt'); - expect(moveStub.getCall(0).args[1]).toEqual('/somedir/One.txt'); - - deferredMove.resolve(201); - - expect(fileList.findFileEl('One.txt').length).toEqual(0); - - // folder size has increased - expect(fileList.findFileEl('somedir').data('size')).toEqual(262); - expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B'); - - expect(notificationStub.notCalled).toEqual(true); - }); - it('Moves list of files to target folder', function() { - var deferredMove1 = $.Deferred(); - var deferredMove2 = $.Deferred(); - moveStub.onCall(0).returns(deferredMove1.promise()); - moveStub.onCall(1).returns(deferredMove2.promise()); - - fileList.move(['One.txt', 'Two.jpg'], '/somedir'); - - expect(moveStub.calledTwice).toEqual(true); - expect(moveStub.getCall(0).args[0]).toEqual('/subdir/One.txt'); - expect(moveStub.getCall(0).args[1]).toEqual('/somedir/One.txt'); - expect(moveStub.getCall(1).args[0]).toEqual('/subdir/Two.jpg'); - expect(moveStub.getCall(1).args[1]).toEqual('/somedir/Two.jpg'); - - deferredMove1.resolve(201); - - expect(fileList.findFileEl('One.txt').length).toEqual(0); - - // folder size has increased during move - expect(fileList.findFileEl('somedir').data('size')).toEqual(262); - expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B'); - - deferredMove2.resolve(201); - - expect(fileList.findFileEl('Two.jpg').length).toEqual(0); - - // folder size has increased - expect(fileList.findFileEl('somedir').data('size')).toEqual(12311); - expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('12 KB'); - - expect(notificationStub.notCalled).toEqual(true); - }); - it('Shows notification if a file could not be moved', function() { - fileList.move('One.txt', '/somedir'); - - expect(moveStub.calledOnce).toEqual(true); - - deferredMove.reject(409); - - expect(fileList.findFileEl('One.txt').length).toEqual(1); - - expect(notificationStub.calledOnce).toEqual(true); - expect(notificationStub.getCall(0).args[0]).toEqual('Could not move "One.txt"'); - }); - it('Restores thumbnail if a file could not be moved', function() { - fileList.move('One.txt', '/somedir'); - - expect(OC.TestUtil.getImageUrl(fileList.findFileEl('One.txt').find('.thumbnail'))) - .toEqual(OC.imagePath('core', 'loading.gif')); - - expect(moveStub.calledOnce).toEqual(true); - - deferredMove.reject(409); - - expect(fileList.findFileEl('One.txt').length).toEqual(1); - - expect(notificationStub.calledOnce).toEqual(true); - expect(notificationStub.getCall(0).args[0]).toEqual('Could not move "One.txt"'); - - expect(OC.TestUtil.getImageUrl(fileList.findFileEl('One.txt').find('.thumbnail'))) - .toEqual(OC.imagePath('core', 'filetypes/text.svg')); - }); - }); - describe('Update file', function() { - it('does not change summary', function() { - var $summary = $('#filestable .summary'); - var fileData = new FileInfo({ - type: 'file', - name: 'test file', - }); - var $tr = fileList.add(fileData); - - expect($summary.find('.info').text()).toEqual('0 folders and 1 file'); - - var model = fileList.getModelForFile('test file'); - model.set({size: '100'}); - expect($summary.find('.info').text()).toEqual('0 folders and 1 file'); - }); - }) - describe('List rendering', function() { - it('renders a list of files using add()', function() { - expect(fileList.files.length).toEqual(0); - expect(fileList.files).toEqual([]); - fileList.setFiles(testFiles); - expect($('#fileList tr').length).toEqual(4); - expect(fileList.files.length).toEqual(4); - expect(fileList.files).toEqual(testFiles); - }); - it('updates summary using the file sizes', function() { - var $summary; - fileList.setFiles(testFiles); - $summary = $('#filestable .summary'); - expect($summary.hasClass('hidden')).toEqual(false); - expect($summary.find('.info').text()).toEqual('1 folder and 3 files'); - expect($summary.find('.filesize').text()).toEqual('69 KB'); - }); - it('shows headers, summary and hide empty content message after setting files', function(){ - fileList.setFiles(testFiles); - expect($('#filestable thead th').hasClass('hidden')).toEqual(false); - expect($('#emptycontent').hasClass('hidden')).toEqual(true); - expect(fileList.$el.find('.summary').hasClass('hidden')).toEqual(false); - }); - it('hides headers, summary and show empty content message after setting empty file list', function(){ - fileList.setFiles([]); - expect($('#filestable thead th').hasClass('hidden')).toEqual(true); - expect($('#emptycontent').hasClass('hidden')).toEqual(false); - expect($('#emptycontent .uploadmessage').hasClass('hidden')).toEqual(false); - expect(fileList.$el.find('.summary').hasClass('hidden')).toEqual(true); - }); - it('hides headers, upload message, and summary when list is empty and user has no creation permission', function(){ - $('#permissions').val(0); - fileList.setFiles([]); - expect($('#filestable thead th').hasClass('hidden')).toEqual(true); - expect($('#emptycontent').hasClass('hidden')).toEqual(false); - expect($('#emptycontent .uploadmessage').hasClass('hidden')).toEqual(true); - expect(fileList.$el.find('.summary').hasClass('hidden')).toEqual(true); - }); - it('calling findFileEl() can find existing file element', function() { - fileList.setFiles(testFiles); - expect(fileList.findFileEl('Two.jpg').length).toEqual(1); - }); - it('calling findFileEl() returns empty when file not found in file', function() { - fileList.setFiles(testFiles); - expect(fileList.findFileEl('unexist.dat').length).toEqual(0); - }); - it('only add file if in same current directory', function() { - $('#dir').val('/current dir'); - var fileData = { - type: 'file', - name: 'testFile.txt', - directory: '/current dir' - }; - fileList.add(fileData); - expect(fileList.findFileEl('testFile.txt').length).toEqual(1); - }); - it('triggers "fileActionsReady" event after update', function() { - var handler = sinon.stub(); - fileList.$fileList.on('fileActionsReady', handler); - fileList.setFiles(testFiles); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0].$files.length).toEqual(testFiles.length); - }); - it('triggers "fileActionsReady" event after single add', function() { - var handler = sinon.stub(); - var $tr; - fileList.setFiles(testFiles); - fileList.$fileList.on('fileActionsReady', handler); - $tr = fileList.add({name: 'test.txt'}); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0].$files.is($tr)).toEqual(true); - }); - it('triggers "fileActionsReady" event after next page load with the newly appended files', function() { - var handler = sinon.stub(); - fileList.setFiles(generateFiles(0, 64)); - fileList.$fileList.on('fileActionsReady', handler); - fileList._nextPage(); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0].$files.length).toEqual(fileList.pageSize()); - }); - it('does not trigger "fileActionsReady" event after single add with silent argument', function() { - var handler = sinon.stub(); - fileList.setFiles(testFiles); - fileList.$fileList.on('fileActionsReady', handler); - fileList.add({name: 'test.txt'}, {silent: true}); - expect(handler.notCalled).toEqual(true); - }); - it('triggers "updated" event after update', function() { - var handler = sinon.stub(); - fileList.$fileList.on('updated', handler); - fileList.setFiles(testFiles); - expect(handler.calledOnce).toEqual(true); - }); - it('does not update summary when removing non-existing files', function() { - var $summary; - // single file - fileList.setFiles([testFiles[0]]); - $summary = $('#filestable .summary'); - expect($summary.hasClass('hidden')).toEqual(false); - expect($summary.find('.info').text()).toEqual('0 folders and 1 file'); - fileList.remove('unexist.txt'); - expect($summary.hasClass('hidden')).toEqual(false); - expect($summary.find('.info').text()).toEqual('0 folders and 1 file'); - }); - }); - describe('Filtered list rendering', function() { - it('filters the list of files using filter()', function() { - expect(fileList.files.length).toEqual(0); - expect(fileList.files).toEqual([]); - fileList.setFiles(testFiles); - var $summary = $('#filestable .summary'); - var $nofilterresults = fileList.$el.find(".nofilterresults"); - expect($nofilterresults.length).toEqual(1); - expect($summary.hasClass('hidden')).toEqual(false); - - expect($('#fileList tr:not(.hidden)').length).toEqual(4); - expect(fileList.files.length).toEqual(4); - expect($summary.hasClass('hidden')).toEqual(false); - expect($nofilterresults.hasClass('hidden')).toEqual(true); - - fileList.setFilter('e'); - expect($('#fileList tr:not(.hidden)').length).toEqual(3); - expect(fileList.files.length).toEqual(4); - expect($summary.hasClass('hidden')).toEqual(false); - expect($summary.find('.info').text()).toEqual("1 folder and 2 files match 'e'"); - expect($nofilterresults.hasClass('hidden')).toEqual(true); - - fileList.setFilter('ee'); - expect($('#fileList tr:not(.hidden)').length).toEqual(1); - expect(fileList.files.length).toEqual(4); - expect($summary.hasClass('hidden')).toEqual(false); - expect($summary.find('.info').text()).toEqual("0 folders and 1 file matches 'ee'"); - expect($nofilterresults.hasClass('hidden')).toEqual(true); - - fileList.setFilter('eee'); - expect($('#fileList tr:not(.hidden)').length).toEqual(0); - expect(fileList.files.length).toEqual(4); - expect($summary.hasClass('hidden')).toEqual(true); - expect($nofilterresults.hasClass('hidden')).toEqual(false); - - fileList.setFilter('ee'); - expect($('#fileList tr:not(.hidden)').length).toEqual(1); - expect(fileList.files.length).toEqual(4); - expect($summary.hasClass('hidden')).toEqual(false); - expect($summary.find('.info').text()).toEqual("0 folders and 1 file matches 'ee'"); - expect($nofilterresults.hasClass('hidden')).toEqual(true); - - fileList.setFilter('e'); - expect($('#fileList tr:not(.hidden)').length).toEqual(3); - expect(fileList.files.length).toEqual(4); - expect($summary.hasClass('hidden')).toEqual(false); - expect($summary.find('.info').text()).toEqual("1 folder and 2 files match 'e'"); - expect($nofilterresults.hasClass('hidden')).toEqual(true); - - fileList.setFilter(''); - expect($('#fileList tr:not(.hidden)').length).toEqual(4); - expect(fileList.files.length).toEqual(4); - expect($summary.hasClass('hidden')).toEqual(false); - expect($summary.find('.info').text()).toEqual("1 folder and 3 files"); - expect($nofilterresults.hasClass('hidden')).toEqual(true); - }); - it('hides the emptyfiles notice when using filter()', function() { - expect(fileList.files.length).toEqual(0); - expect(fileList.files).toEqual([]); - fileList.setFiles([]); - var $summary = $('#filestable .summary'); - var $emptycontent = fileList.$el.find("#emptycontent"); - var $nofilterresults = fileList.$el.find(".nofilterresults"); - expect($emptycontent.length).toEqual(1); - expect($nofilterresults.length).toEqual(1); - - expect($('#fileList tr:not(.hidden)').length).toEqual(0); - expect(fileList.files.length).toEqual(0); - expect($summary.hasClass('hidden')).toEqual(true); - expect($emptycontent.hasClass('hidden')).toEqual(false); - expect($nofilterresults.hasClass('hidden')).toEqual(true); - - fileList.setFilter('e'); - expect($('#fileList tr:not(.hidden)').length).toEqual(0); - expect(fileList.files.length).toEqual(0); - expect($summary.hasClass('hidden')).toEqual(true); - expect($emptycontent.hasClass('hidden')).toEqual(true); - expect($nofilterresults.hasClass('hidden')).toEqual(false); - - fileList.setFilter(''); - expect($('#fileList tr:not(.hidden)').length).toEqual(0); - expect(fileList.files.length).toEqual(0); - expect($summary.hasClass('hidden')).toEqual(true); - expect($emptycontent.hasClass('hidden')).toEqual(false); - expect($nofilterresults.hasClass('hidden')).toEqual(true); - }); - it('does not show the emptyfiles or nofilterresults notice when the mask is active', function() { - expect(fileList.files.length).toEqual(0); - expect(fileList.files).toEqual([]); - fileList.showMask(); - fileList.setFiles(testFiles); - var $emptycontent = fileList.$el.find("#emptycontent"); - var $nofilterresults = fileList.$el.find(".nofilterresults"); - expect($emptycontent.length).toEqual(1); - expect($nofilterresults.length).toEqual(1); - - expect($emptycontent.hasClass('hidden')).toEqual(true); - expect($nofilterresults.hasClass('hidden')).toEqual(true); - - /* - fileList.setFilter('e'); - expect($emptycontent.hasClass('hidden')).toEqual(true); - expect($nofilterresults.hasClass('hidden')).toEqual(false); - */ - - fileList.setFilter(''); - expect($emptycontent.hasClass('hidden')).toEqual(true); - expect($nofilterresults.hasClass('hidden')).toEqual(true); - }); - }); - describe('Rendering next page on scroll', function() { - beforeEach(function() { - fileList.setFiles(generateFiles(0, 64)); - }); - it('renders only the first page', function() { - expect(fileList.files.length).toEqual(65); - expect($('#fileList tr').length).toEqual(20); - }); - it('renders the second page when scrolling down (trigger nextPage)', function() { - // TODO: can't simulate scrolling here, so calling nextPage directly - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(40); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(60); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(65); - fileList._nextPage(true); - // stays at 65 - expect($('#fileList tr').length).toEqual(65); - }); - it('inserts into the DOM if insertion point is in the visible page ', function() { - fileList.add({ - id: 2000, - type: 'file', - name: 'File with index 15b.txt' - }); - expect($('#fileList tr').length).toEqual(21); - expect(fileList.findFileEl('File with index 15b.txt').index()).toEqual(16); - }); - it('does not inserts into the DOM if insertion point is not the visible page ', function() { - fileList.add({ - id: 2000, - type: 'file', - name: 'File with index 28b.txt' - }); - expect($('#fileList tr').length).toEqual(20); - expect(fileList.findFileEl('File with index 28b.txt').length).toEqual(0); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(40); - expect(fileList.findFileEl('File with index 28b.txt').index()).toEqual(29); - }); - it('appends into the DOM when inserting a file after the last visible element', function() { - fileList.add({ - id: 2000, - type: 'file', - name: 'File with index 19b.txt' - }); - expect($('#fileList tr').length).toEqual(21); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(41); - }); - it('appends into the DOM when inserting a file on the last page when visible', function() { - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(40); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(60); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(65); - fileList._nextPage(true); - fileList.add({ - id: 2000, - type: 'file', - name: 'File with index 88.txt' - }); - expect($('#fileList tr').length).toEqual(66); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(66); - }); - it('shows additional page when appending a page of files and scrolling down', function() { - var newFiles = generateFiles(66, 81); - for (var i = 0; i < newFiles.length; i++) { - fileList.add(newFiles[i]); - } - expect($('#fileList tr').length).toEqual(20); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(40); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(60); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(80); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(81); - fileList._nextPage(true); - expect($('#fileList tr').length).toEqual(81); - }); - it('automatically renders next page when there are not enough elements visible', function() { - // delete the 15 first elements - for (var i = 0; i < 15; i++) { - fileList.remove(fileList.files[0].name); - } - // still makes sure that there are 20 elements visible, if any - expect($('#fileList tr').length).toEqual(25); - }); - }); - describe('file previews', function() { - var previewLoadStub; - - beforeEach(function() { - previewLoadStub = sinon.stub(OCA.Files.FileList.prototype, 'lazyLoadPreview'); - }); - afterEach(function() { - previewLoadStub.restore(); - }); - it('renders default file icon when none provided and no mime type is set', function() { - var fileData = { - name: 'testFile.txt' - }; - var $tr = fileList.add(fileData); - var $imgDiv = $tr.find('td.filename .thumbnail'); - expect(OC.TestUtil.getImageUrl($imgDiv)).toEqual(OC.webroot + '/core/img/filetypes/file.svg'); - // tries to load preview - expect(previewLoadStub.calledOnce).toEqual(true); - }); - it('renders default icon for folder when none provided', function() { - var fileData = { - name: 'test dir', - mimetype: 'httpd/unix-directory' - }; - - var $tr = fileList.add(fileData); - var $imgDiv = $tr.find('td.filename .thumbnail'); - expect(OC.TestUtil.getImageUrl($imgDiv)).toEqual(OC.webroot + '/core/img/filetypes/folder.svg'); - // no preview since it's a directory - expect(previewLoadStub.notCalled).toEqual(true); - }); - it('renders provided icon for file when provided', function() { - var fileData = new FileInfo({ - type: 'file', - name: 'test file', - icon: OC.webroot + '/core/img/filetypes/application-pdf.svg', - mimetype: 'application/pdf' - }); - var $tr = fileList.add(fileData); - var $imgDiv = $tr.find('td.filename .thumbnail'); - expect(OC.TestUtil.getImageUrl($imgDiv)).toEqual(OC.webroot + '/core/img/filetypes/application-pdf.svg'); - // try loading preview - expect(previewLoadStub.calledOnce).toEqual(true); - }); - it('renders provided icon for file when provided', function() { - var fileData = new FileInfo({ - name: 'somefile.pdf', - icon: OC.webroot + '/core/img/filetypes/application-pdf.svg' - }); - - var $tr = fileList.add(fileData); - var $imgDiv = $tr.find('td.filename .thumbnail'); - expect(OC.TestUtil.getImageUrl($imgDiv)).toEqual(OC.webroot + '/core/img/filetypes/application-pdf.svg'); - // try loading preview - expect(previewLoadStub.calledOnce).toEqual(true); - }); - it('renders provided icon for folder when provided', function() { - var fileData = new FileInfo({ - name: 'some folder', - mimetype: 'httpd/unix-directory', - icon: OC.webroot + '/core/img/filetypes/folder-alt.svg' - }); - - var $tr = fileList.add(fileData); - var $imgDiv = $tr.find('td.filename .thumbnail'); - expect(OC.TestUtil.getImageUrl($imgDiv)).toEqual(OC.webroot + '/core/img/filetypes/folder-alt.svg'); - // do not load preview for folders - expect(previewLoadStub.notCalled).toEqual(true); - }); - it('renders preview when no icon was provided', function() { - var fileData = { - type: 'file', - name: 'test file' - }; - var $tr = fileList.add(fileData); - var $td = $tr.find('td.filename'); - expect(OC.TestUtil.getImageUrl($td.find('.thumbnail'))) - .toEqual(OC.webroot + '/core/img/filetypes/file.svg'); - expect(previewLoadStub.calledOnce).toEqual(true); - // third argument is callback - previewLoadStub.getCall(0).args[0].callback(OC.webroot + '/somepath.png'); - expect(OC.TestUtil.getImageUrl($td.find('.thumbnail'))).toEqual(OC.webroot + '/somepath.png'); - }); - it('does not render preview for directories', function() { - var fileData = { - type: 'dir', - mimetype: 'httpd/unix-directory', - name: 'test dir' - }; - var $tr = fileList.add(fileData); - var $td = $tr.find('td.filename'); - expect(OC.TestUtil.getImageUrl($td.find('.thumbnail'))).toEqual(OC.webroot + '/core/img/filetypes/folder.svg'); - expect(previewLoadStub.notCalled).toEqual(true); - }); - it('render external storage icon for external storage root', function() { - var fileData = { - type: 'dir', - mimetype: 'httpd/unix-directory', - name: 'test dir', - mountType: 'external-root' - }; - var $tr = fileList.add(fileData); - var $td = $tr.find('td.filename'); - expect(OC.TestUtil.getImageUrl($td.find('.thumbnail'))).toEqual(OC.webroot + '/core/img/filetypes/folder-external.svg'); - expect(previewLoadStub.notCalled).toEqual(true); - }); - it('render external storage icon for external storage subdir', function() { - var fileData = { - type: 'dir', - mimetype: 'httpd/unix-directory', - name: 'test dir', - mountType: 'external' - }; - var $tr = fileList.add(fileData); - var $td = $tr.find('td.filename'); - expect(OC.TestUtil.getImageUrl($td.find('.thumbnail'))).toEqual(OC.webroot + '/core/img/filetypes/folder-external.svg'); - expect(previewLoadStub.notCalled).toEqual(true); - // default icon override - expect($tr.attr('data-icon')).toEqual(OC.webroot + '/core/img/filetypes/folder-external.svg'); - }); - - }); - describe('viewer mode', function() { - it('enabling viewer mode hides files table and action buttons', function() { - fileList.setViewerMode(true); - expect($('#filestable').hasClass('hidden')).toEqual(true); - expect($('.actions').hasClass('hidden')).toEqual(true); - expect($('.notCreatable').hasClass('hidden')).toEqual(true); - }); - it('disabling viewer mode restores files table and action buttons', function() { - fileList.setViewerMode(true); - fileList.setViewerMode(false); - expect($('#filestable').hasClass('hidden')).toEqual(false); - expect($('.actions').hasClass('hidden')).toEqual(false); - expect($('.notCreatable').hasClass('hidden')).toEqual(true); - }); - it('disabling viewer mode restores files table and action buttons with correct permissions', function() { - $('#permissions').val(0); - fileList.setViewerMode(true); - fileList.setViewerMode(false); - expect($('#filestable').hasClass('hidden')).toEqual(false); - expect($('.actions').hasClass('hidden')).toEqual(true); - expect($('.notCreatable').hasClass('hidden')).toEqual(false); - }); - it('toggling viewer mode triggers event', function() { - var handler = sinon.stub(); - fileList.$el.on('changeViewerMode', handler); - fileList.setViewerMode(true); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0].viewerModeEnabled).toEqual(true); - - handler.reset(); - fileList.setViewerMode(false); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0].viewerModeEnabled).toEqual(false); - }); - }); - describe('loading file list', function() { - var deferredList; - var getFolderContentsStub; - - beforeEach(function() { - deferredList = $.Deferred(); - getFolderContentsStub = sinon.stub(filesClient, 'getFolderContents').returns(deferredList.promise()); - }); - afterEach(function() { - getFolderContentsStub.restore(); - }); - it('fetches file list from server and renders it when reload() is called', function() { - fileList.reload(); - expect(getFolderContentsStub.calledOnce).toEqual(true); - expect(getFolderContentsStub.calledWith('/subdir')).toEqual(true); - deferredList.resolve(200, [testRoot].concat(testFiles)); - expect($('#fileList tr').length).toEqual(4); - expect(fileList.findFileEl('One.txt').length).toEqual(1); - }); - it('switches dir and fetches file list when calling changeDirectory()', function() { - fileList.changeDirectory('/anothersubdir'); - expect(fileList.getCurrentDirectory()).toEqual('/anothersubdir'); - expect(getFolderContentsStub.calledOnce).toEqual(true); - expect(getFolderContentsStub.calledWith('/anothersubdir')).toEqual(true); - }); - it('converts backslashes to slashes when calling changeDirectory()', function() { - fileList.changeDirectory('/another\\subdir'); - expect(fileList.getCurrentDirectory()).toEqual('/another/subdir'); - }); - it('switches to root dir when current directory does not exist', function() { - fileList.changeDirectory('/unexist'); - deferredList.reject(404); - expect(fileList.getCurrentDirectory()).toEqual('/'); - }); - it('switches to root dir when current directory is forbidden', function() { - fileList.changeDirectory('/unexist'); - deferredList.reject(403); - expect(fileList.getCurrentDirectory()).toEqual('/'); - }); - it('switches to root dir when current directory is unavailable', function() { - fileList.changeDirectory('/unexist'); - deferredList.reject(500); - expect(fileList.getCurrentDirectory()).toEqual('/'); - }); - it('shows mask before loading file list then hides it at the end', function() { - var showMaskStub = sinon.stub(fileList, 'showMask'); - var hideMaskStub = sinon.stub(fileList, 'hideMask'); - fileList.changeDirectory('/anothersubdir'); - expect(showMaskStub.calledOnce).toEqual(true); - expect(hideMaskStub.calledOnce).toEqual(false); - deferredList.resolve(200, [testRoot].concat(testFiles)); - expect(showMaskStub.calledOnce).toEqual(true); - expect(hideMaskStub.calledOnce).toEqual(true); - showMaskStub.restore(); - hideMaskStub.restore(); - }); - it('triggers "changeDirectory" event when changing directory', function() { - var handler = sinon.stub(); - $('#app-content-files').on('changeDirectory', handler); - fileList.changeDirectory('/somedir'); - deferredList.resolve(200, [testRoot].concat(testFiles)); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).args[0].dir).toEqual('/somedir'); - }); - it('changes the directory when receiving "urlChanged" event', function() { - $('#app-content-files').trigger(new $.Event('urlChanged', {view: 'files', dir: '/somedir'})); - expect(fileList.getCurrentDirectory()).toEqual('/somedir'); - }); - it('refreshes breadcrumb after update', function() { - var setDirSpy = sinon.spy(fileList.breadcrumb, 'setDirectory'); - fileList.changeDirectory('/anothersubdir'); - deferredList.resolve(200, [testRoot].concat(testFiles)); - expect(fileList.breadcrumb.setDirectory.calledOnce).toEqual(true); - expect(fileList.breadcrumb.setDirectory.calledWith('/anothersubdir')).toEqual(true); - setDirSpy.restore(); - getFolderContentsStub.restore(); - }); - }); - describe('breadcrumb events', function() { - var deferredList; - var getFolderContentsStub; - - beforeEach(function() { - deferredList = $.Deferred(); - getFolderContentsStub = sinon.stub(filesClient, 'getFolderContents').returns(deferredList.promise()); - }); - afterEach(function() { - getFolderContentsStub.restore(); - }); - it('clicking on root breadcrumb changes directory to root', function() { - fileList.changeDirectory('/subdir/two/three with space/four/five'); - deferredList.resolve(200, [testRoot].concat(testFiles)); - var changeDirStub = sinon.stub(fileList, 'changeDirectory'); - fileList.breadcrumb.$el.find('.crumb:eq(0)').trigger({type: 'click', which: 1}); - - expect(changeDirStub.calledOnce).toEqual(true); - expect(changeDirStub.getCall(0).args[0]).toEqual('/'); - changeDirStub.restore(); - }); - it('clicking on breadcrumb changes directory', function() { - fileList.changeDirectory('/subdir/two/three with space/four/five'); - deferredList.resolve(200, [testRoot].concat(testFiles)); - var changeDirStub = sinon.stub(fileList, 'changeDirectory'); - fileList.breadcrumb.$el.find('.crumb:eq(3)').trigger({type: 'click', which: 1}); - - expect(changeDirStub.calledOnce).toEqual(true); - expect(changeDirStub.getCall(0).args[0]).toEqual('/subdir/two/three with space'); - changeDirStub.restore(); - }); - it('dropping files on breadcrumb calls move operation', function() { - var testDir = '/subdir/two/three with space/four/five'; - var moveStub = sinon.stub(filesClient, 'move').returns($.Deferred().promise()); - fileList.changeDirectory(testDir); - deferredList.resolve(200, [testRoot].concat(testFiles)); - var $crumb = fileList.breadcrumb.$el.find('.crumb:eq(3)'); - // no idea what this is but is required by the handler - var ui = { - helper: { - find: sinon.stub() - } - }; - // returns a list of tr that were dragged - ui.helper.find.returns([ - $('<tr data-file="One.txt" data-dir="' + testDir + '"></tr>'), - $('<tr data-file="Two.jpg" data-dir="' + testDir + '"></tr>') - ]); - // simulate drop event - fileList._onDropOnBreadCrumb(new $.Event('drop', {target: $crumb}), ui); - - expect(moveStub.callCount).toEqual(2); - expect(moveStub.getCall(0).args[0]).toEqual(testDir + '/One.txt'); - expect(moveStub.getCall(0).args[1]).toEqual('/subdir/two/three with space/One.txt'); - expect(moveStub.getCall(1).args[0]).toEqual(testDir + '/Two.jpg'); - expect(moveStub.getCall(1).args[1]).toEqual('/subdir/two/three with space/Two.jpg'); - moveStub.restore(); - }); - it('dropping files on same dir breadcrumb does nothing', function() { - var testDir = '/subdir/two/three with space/four/five'; - var moveStub = sinon.stub(filesClient, 'move').returns($.Deferred().promise()); - fileList.changeDirectory(testDir); - deferredList.resolve(200, [testRoot].concat(testFiles)); - var $crumb = fileList.breadcrumb.$el.find('.crumb:last'); - // no idea what this is but is required by the handler - var ui = { - helper: { - find: sinon.stub() - } - }; - // returns a list of tr that were dragged - ui.helper.find.returns([ - $('<tr data-file="One.txt" data-dir="' + testDir + '"></tr>'), - $('<tr data-file="Two.jpg" data-dir="' + testDir + '"></tr>') - ]); - // simulate drop event - fileList._onDropOnBreadCrumb(new $.Event('drop', {target: $crumb}), ui); - - // no extra server request - expect(moveStub.notCalled).toEqual(true); - }); - }); - describe('Download Url', function() { - it('returns correct download URL for single files', function() { - expect(fileList.getDownloadUrl('some file.txt')) - .toEqual(OC.webroot + '/remote.php/webdav/subdir/some%20file.txt'); - expect(fileList.getDownloadUrl('some file.txt', '/anotherpath/abc')) - .toEqual(OC.webroot + '/remote.php/webdav/anotherpath/abc/some%20file.txt'); - $('#dir').val('/'); - expect(fileList.getDownloadUrl('some file.txt')) - .toEqual(OC.webroot + '/remote.php/webdav/some%20file.txt'); - }); - it('returns correct download URL for multiple files', function() { - expect(fileList.getDownloadUrl(['a b c.txt', 'd e f.txt'])) - .toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=%5B%22a%20b%20c.txt%22%2C%22d%20e%20f.txt%22%5D'); - }); - it('returns the correct ajax URL', function() { - expect(fileList.getAjaxUrl('test', {a:1, b:'x y'})) - .toEqual(OC.webroot + '/index.php/apps/files/ajax/test.php?a=1&b=x%20y'); - }); - }); - describe('File selection', function() { - beforeEach(function() { - fileList.setFiles(testFiles); - }); - it('Selects a file when clicking its checkbox', function() { - var $tr = fileList.findFileEl('One.txt'); - expect($tr.find('input:checkbox').prop('checked')).toEqual(false); - $tr.find('td.filename input:checkbox').click(); - - expect($tr.find('input:checkbox').prop('checked')).toEqual(true); - }); - it('Selects/deselect a file when clicking on the name while holding Ctrl', function() { - var $tr = fileList.findFileEl('One.txt'); - var $tr2 = fileList.findFileEl('Three.pdf'); - var e; - expect($tr.find('input:checkbox').prop('checked')).toEqual(false); - expect($tr2.find('input:checkbox').prop('checked')).toEqual(false); - e = new $.Event('click'); - e.ctrlKey = true; - $tr.find('td.filename .name').trigger(e); - - expect($tr.find('input:checkbox').prop('checked')).toEqual(true); - expect($tr2.find('input:checkbox').prop('checked')).toEqual(false); - - // click on second entry, does not clear the selection - e = new $.Event('click'); - e.ctrlKey = true; - $tr2.find('td.filename .name').trigger(e); - expect($tr.find('input:checkbox').prop('checked')).toEqual(true); - expect($tr2.find('input:checkbox').prop('checked')).toEqual(true); - - expect(_.pluck(fileList.getSelectedFiles(), 'name')).toEqual(['One.txt', 'Three.pdf']); - - // deselect now - e = new $.Event('click'); - e.ctrlKey = true; - $tr2.find('td.filename .name').trigger(e); - expect($tr.find('input:checkbox').prop('checked')).toEqual(true); - expect($tr2.find('input:checkbox').prop('checked')).toEqual(false); - expect(_.pluck(fileList.getSelectedFiles(), 'name')).toEqual(['One.txt']); - }); - it('Selects a range when clicking on one file then Shift clicking on another one', function() { - var $tr = fileList.findFileEl('One.txt'); - var $tr2 = fileList.findFileEl('Three.pdf'); - var e; - $tr.find('td.filename input:checkbox').click(); - e = new $.Event('click'); - e.shiftKey = true; - $tr2.find('td.filename .name').trigger(e); - - expect($tr.find('input:checkbox').prop('checked')).toEqual(true); - expect($tr2.find('input:checkbox').prop('checked')).toEqual(true); - expect(fileList.findFileEl('Two.jpg').find('input:checkbox').prop('checked')).toEqual(true); - var selection = _.pluck(fileList.getSelectedFiles(), 'name'); - expect(selection.length).toEqual(3); - expect(selection).toContain('One.txt'); - expect(selection).toContain('Two.jpg'); - expect(selection).toContain('Three.pdf'); - }); - it('Selects a range when clicking on one file then Shift clicking on another one that is above the first one', function() { - var $tr = fileList.findFileEl('One.txt'); - var $tr2 = fileList.findFileEl('Three.pdf'); - var e; - $tr2.find('td.filename input:checkbox').click(); - e = new $.Event('click'); - e.shiftKey = true; - $tr.find('td.filename .name').trigger(e); - - expect($tr.find('input:checkbox').prop('checked')).toEqual(true); - expect($tr2.find('input:checkbox').prop('checked')).toEqual(true); - expect(fileList.findFileEl('Two.jpg').find('input:checkbox').prop('checked')).toEqual(true); - var selection = _.pluck(fileList.getSelectedFiles(), 'name'); - expect(selection.length).toEqual(3); - expect(selection).toContain('One.txt'); - expect(selection).toContain('Two.jpg'); - expect(selection).toContain('Three.pdf'); - }); - it('Selecting all files will automatically check "select all" checkbox', function() { - expect($('.select-all').prop('checked')).toEqual(false); - $('#fileList tr td.filename input:checkbox').click(); - expect($('.select-all').prop('checked')).toEqual(true); - }); - it('Selecting all files on the first visible page will not automatically check "select all" checkbox', function() { - fileList.setFiles(generateFiles(0, 41)); - expect($('.select-all').prop('checked')).toEqual(false); - $('#fileList tr td.filename input:checkbox').click(); - expect($('.select-all').prop('checked')).toEqual(false); - }); - it('Clicking "select all" will select/deselect all files', function() { - fileList.setFiles(generateFiles(0, 41)); - $('.select-all').click(); - expect($('.select-all').prop('checked')).toEqual(true); - $('#fileList tr input:checkbox').each(function() { - expect($(this).prop('checked')).toEqual(true); - }); - expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(42); - - $('.select-all').click(); - expect($('.select-all').prop('checked')).toEqual(false); - - $('#fileList tr input:checkbox').each(function() { - expect($(this).prop('checked')).toEqual(false); - }); - expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(0); - }); - it('Clicking "select all" then deselecting a file will uncheck "select all"', function() { - $('.select-all').click(); - expect($('.select-all').prop('checked')).toEqual(true); - - var $tr = fileList.findFileEl('One.txt'); - $tr.find('input:checkbox').click(); - - expect($('.select-all').prop('checked')).toEqual(false); - expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(3); - }); - it('Updates the selection summary when doing a few manipulations with "Select all"', function() { - $('.select-all').click(); - expect($('.select-all').prop('checked')).toEqual(true); - - var $tr = fileList.findFileEl('One.txt'); - // unselect one - $tr.find('input:checkbox').click(); - - expect($('.select-all').prop('checked')).toEqual(false); - expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(3); - - // select all - $('.select-all').click(); - expect($('.select-all').prop('checked')).toEqual(true); - expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(4); - - // unselect one - $tr.find('input:checkbox').click(); - expect($('.select-all').prop('checked')).toEqual(false); - expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(3); - - // re-select it - $tr.find('input:checkbox').click(); - expect($('.select-all').prop('checked')).toEqual(true); - expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(4); - }); - it('Auto-selects files on next page when "select all" is checked', function() { - fileList.setFiles(generateFiles(0, 41)); - $('.select-all').click(); - - expect(fileList.$fileList.find('tr input:checkbox:checked').length).toEqual(20); - fileList._nextPage(true); - expect(fileList.$fileList.find('tr input:checkbox:checked').length).toEqual(40); - fileList._nextPage(true); - expect(fileList.$fileList.find('tr input:checkbox:checked').length).toEqual(42); - expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(42); - }); - it('Selecting files updates selection summary', function() { - var $summary = $('#headerName a.name>span:first'); - expect($summary.text()).toEqual('Name'); - fileList.findFileEl('One.txt').find('input:checkbox').click(); - fileList.findFileEl('Three.pdf').find('input:checkbox').click(); - fileList.findFileEl('somedir').find('input:checkbox').click(); - expect($summary.text()).toEqual('1 folder and 2 files'); - }); - it('Unselecting files hides selection summary', function() { - var $summary = $('#headerName a.name>span:first'); - fileList.findFileEl('One.txt').find('input:checkbox').click().click(); - expect($summary.text()).toEqual('Name'); - }); - it('Select/deselect files shows/hides file actions', function() { - var $actions = $('#headerName .selectedActions'); - var $checkbox = fileList.findFileEl('One.txt').find('input:checkbox'); - expect($actions.hasClass('hidden')).toEqual(true); - $checkbox.click(); - expect($actions.hasClass('hidden')).toEqual(false); - $checkbox.click(); - expect($actions.hasClass('hidden')).toEqual(true); - }); - it('Selection is cleared when switching dirs', function() { - $('.select-all').click(); - var deferredList = $.Deferred(); - var getFolderContentsStub = sinon.stub(filesClient, 'getFolderContents').returns(deferredList.promise()); - - fileList.changeDirectory('/'); - - deferredList.resolve(200, [testRoot].concat(testFiles)); - - expect($('.select-all').prop('checked')).toEqual(false); - expect(_.pluck(fileList.getSelectedFiles(), 'name')).toEqual([]); - - getFolderContentsStub.restore(); - }); - it('getSelectedFiles returns the selected files even when they are on the next page', function() { - var selectedFiles; - fileList.setFiles(generateFiles(0, 41)); - $('.select-all').click(); - // unselect one to not have the "allFiles" case - fileList.$fileList.find('tr input:checkbox:first').click(); - - // only 20 files visible, must still return all the selected ones - selectedFiles = _.pluck(fileList.getSelectedFiles(), 'name'); - - expect(selectedFiles.length).toEqual(41); - }); - describe('clearing the selection', function() { - it('clears selected files selected individually calling setFiles()', function() { - var selectedFiles; - - fileList.setFiles(generateFiles(0, 41)); - fileList.$fileList.find('tr:eq(5) input:checkbox:first').click(); - fileList.$fileList.find('tr:eq(7) input:checkbox:first').click(); - - selectedFiles = _.pluck(fileList.getSelectedFiles(), 'name'); - expect(selectedFiles.length).toEqual(2); - - fileList.setFiles(generateFiles(0, 2)); - - selectedFiles = _.pluck(fileList.getSelectedFiles(), 'name'); - expect(selectedFiles.length).toEqual(0); - }); - it('clears selected files selected with select all when calling setFiles()', function() { - var selectedFiles; - - fileList.setFiles(generateFiles(0, 41)); - $('.select-all').click(); - - selectedFiles = _.pluck(fileList.getSelectedFiles(), 'name'); - expect(selectedFiles.length).toEqual(42); - - fileList.setFiles(generateFiles(0, 2)); - - selectedFiles = _.pluck(fileList.getSelectedFiles(), 'name'); - expect(selectedFiles.length).toEqual(0); - }); - }); - describe('Selection overlay', function() { - it('show doesnt show the delete action if one or more files are not deletable', function () { - fileList.setFiles(testFiles); - $('#permissions').val(OC.PERMISSION_READ | OC.PERMISSION_DELETE); - $('.select-all').click(); - expect(fileList.$el.find('.delete-selected').hasClass('hidden')).toEqual(false); - testFiles[0].permissions = OC.PERMISSION_READ; - $('.select-all').click(); - fileList.setFiles(testFiles); - $('.select-all').click(); - expect(fileList.$el.find('.delete-selected').hasClass('hidden')).toEqual(true); - }); - }); - describe('Actions', function() { - beforeEach(function() { - fileList.findFileEl('One.txt').find('input:checkbox').click(); - fileList.findFileEl('Three.pdf').find('input:checkbox').click(); - fileList.findFileEl('somedir').find('input:checkbox').click(); - }); - it('getSelectedFiles returns the selected file data', function() { - var files = fileList.getSelectedFiles(); - expect(files.length).toEqual(3); - expect(files[0]).toEqual({ - id: 1, - name: 'One.txt', - mimetype: 'text/plain', - mtime: 123456789, - type: 'file', - size: 12, - etag: 'abc', - permissions: OC.PERMISSION_ALL - }); - expect(files[1]).toEqual({ - id: 3, - type: 'file', - name: 'Three.pdf', - mimetype: 'application/pdf', - mtime: 234560000, - size: 58009, - etag: '123', - permissions: OC.PERMISSION_ALL - }); - expect(files[2]).toEqual({ - id: 4, - type: 'dir', - name: 'somedir', - mimetype: 'httpd/unix-directory', - mtime: 134560000, - size: 250, - etag: '456', - permissions: OC.PERMISSION_ALL - }); - expect(files[0].id).toEqual(1); - expect(files[0].name).toEqual('One.txt'); - expect(files[1].id).toEqual(3); - expect(files[1].name).toEqual('Three.pdf'); - expect(files[2].id).toEqual(4); - expect(files[2].name).toEqual('somedir'); - }); - it('Removing a file removes it from the selection', function() { - fileList.remove('Three.pdf'); - var files = fileList.getSelectedFiles(); - expect(files.length).toEqual(2); - expect(files[0]).toEqual({ - id: 1, - name: 'One.txt', - mimetype: 'text/plain', - mtime: 123456789, - type: 'file', - size: 12, - etag: 'abc', - permissions: OC.PERMISSION_ALL - }); - expect(files[1]).toEqual({ - id: 4, - type: 'dir', - name: 'somedir', - mimetype: 'httpd/unix-directory', - mtime: 134560000, - size: 250, - etag: '456', - permissions: OC.PERMISSION_ALL - }); - }); - describe('Download', function() { - it('Opens download URL when clicking "Download"', function() { - $('.selectedActions .download').click(); - expect(redirectStub.calledOnce).toEqual(true); - expect(redirectStub.getCall(0).args[0]).toContain(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=%5B%22One.txt%22%2C%22Three.pdf%22%2C%22somedir%22%5D'); - redirectStub.restore(); - }); - it('Downloads root folder when all selected in root folder', function() { - $('#dir').val('/'); - $('.select-all').click(); - $('.selectedActions .download').click(); - expect(redirectStub.calledOnce).toEqual(true); - expect(redirectStub.getCall(0).args[0]).toContain(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files='); - }); - it('Downloads parent folder when all selected in subfolder', function() { - $('.select-all').click(); - $('.selectedActions .download').click(); - expect(redirectStub.calledOnce).toEqual(true); - expect(redirectStub.getCall(0).args[0]).toContain(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files=subdir'); - }); - }); - describe('Delete', function() { - var deleteStub, deferredDelete; - beforeEach(function() { - deferredDelete = $.Deferred(); - deleteStub = sinon.stub(filesClient, 'remove').returns(deferredDelete.promise()); - }); - afterEach(function() { - deleteStub.restore(); - }); - it('Deletes selected files when "Delete" clicked', function() { - $('.selectedActions .delete-selected').click(); - - expect(deleteStub.callCount).toEqual(3); - expect(deleteStub.getCall(0).args[0]).toEqual('/subdir/One.txt'); - expect(deleteStub.getCall(1).args[0]).toEqual('/subdir/Three.pdf'); - expect(deleteStub.getCall(2).args[0]).toEqual('/subdir/somedir'); - - deferredDelete.resolve(204); - - expect(fileList.findFileEl('One.txt').length).toEqual(0); - expect(fileList.findFileEl('Three.pdf').length).toEqual(0); - expect(fileList.findFileEl('somedir').length).toEqual(0); - expect(fileList.findFileEl('Two.jpg').length).toEqual(1); - }); - it('Deletes all files when all selected when "Delete" clicked', function() { - $('.select-all').click(); - $('.selectedActions .delete-selected').click(); - - expect(deleteStub.callCount).toEqual(4); - expect(deleteStub.getCall(0).args[0]).toEqual('/subdir/One.txt'); - expect(deleteStub.getCall(1).args[0]).toEqual('/subdir/Two.jpg'); - expect(deleteStub.getCall(2).args[0]).toEqual('/subdir/Three.pdf'); - expect(deleteStub.getCall(3).args[0]).toEqual('/subdir/somedir'); - - deferredDelete.resolve(204); - - expect(fileList.isEmpty).toEqual(true); - }); - }); - }); - it('resets the file selection on reload', function() { - fileList.$el.find('.select-all').click(); - fileList.reload(); - expect(fileList.$el.find('.select-all').prop('checked')).toEqual(false); - expect(fileList.getSelectedFiles()).toEqual([]); - }); - describe('Disabled selection', function() { - beforeEach(function() { - fileList._allowSelection = false; - fileList.setFiles(testFiles); - }); - it('Does not render checkboxes', function() { - expect(fileList.$fileList.find('.selectCheckBox').length).toEqual(0); - }); - it('Does not select a file with Ctrl or Shift if selection is not allowed', function() { - var $tr = fileList.findFileEl('One.txt'); - var $tr2 = fileList.findFileEl('Three.pdf'); - var e; - e = new $.Event('click'); - e.ctrlKey = true; - $tr.find('td.filename .name').trigger(e); - - // click on second entry, does not clear the selection - e = new $.Event('click'); - e.ctrlKey = true; - $tr2.find('td.filename .name').trigger(e); - - expect(fileList.getSelectedFiles().length).toEqual(0); - - // deselect now - e = new $.Event('click'); - e.shiftKey = true; - $tr2.find('td.filename .name').trigger(e); - expect(fileList.getSelectedFiles().length).toEqual(0); - }); - }); - }); - describe('Details sidebar', function() { - beforeEach(function() { - fileList.setFiles(testFiles); - fileList.showDetailsView('Two.jpg'); - }); - describe('registering', function() { - var addTabStub; - var addDetailStub; - - beforeEach(function() { - addTabStub = sinon.stub(OCA.Files.DetailsView.prototype, 'addTabView'); - addDetailStub = sinon.stub(OCA.Files.DetailsView.prototype, 'addDetailView'); - }); - afterEach(function() { - addTabStub.restore(); - addDetailStub.restore(); - }); - it('forward the registered views to the underlying DetailsView', function() { - fileList.destroy(); - fileList = new OCA.Files.FileList($('#app-content-files'), { - detailsViewEnabled: true - }); - fileList.registerTabView(new OCA.Files.DetailTabView()); - fileList.registerDetailView(new OCA.Files.DetailFileInfoView()); - - expect(addTabStub.calledOnce).toEqual(true); - // twice because the filelist already registers one by default - expect(addDetailStub.calledTwice).toEqual(true); - }); - it('does not error when registering panels when not details view configured', function() { - fileList.destroy(); - fileList = new OCA.Files.FileList($('#app-content-files'), { - detailsViewEnabled: false - }); - fileList.registerTabView(new OCA.Files.DetailTabView()); - fileList.registerDetailView(new OCA.Files.DetailFileInfoView()); - - expect(addTabStub.notCalled).toEqual(true); - expect(addDetailStub.notCalled).toEqual(true); - }); - }); - it('triggers file action when clicking on row if no details view configured', function() { - fileList.destroy(); - fileList = new OCA.Files.FileList($('#app-content-files'), { - detailsViewEnabled: false - }); - var updateDetailsViewStub = sinon.stub(fileList, '_updateDetailsView'); - var actionStub = sinon.stub(); - fileList.setFiles(testFiles); - fileList.fileActions.register( - 'text/plain', - 'Test', - OC.PERMISSION_ALL, - function() { - // Specify icon for hitory button - return OC.imagePath('core','actions/history'); - }, - actionStub - ); - fileList.fileActions.setDefault('text/plain', 'Test'); - var $tr = fileList.findFileEl('One.txt'); - $tr.find('td.filename>a.name').click(); - expect(actionStub.calledOnce).toEqual(true); - expect(updateDetailsViewStub.notCalled).toEqual(true); - updateDetailsViewStub.restore(); - }); - it('highlights current file when clicked and updates sidebar', function() { - fileList.fileActions.setDefault('text/plain', 'Test'); - var $tr = fileList.findFileEl('One.txt'); - $tr.find('td.filename>a.name').click(); - expect($tr.hasClass('highlighted')).toEqual(true); - - expect(fileList._detailsView.getFileInfo().id).toEqual(1); - }); - it('keeps the last highlighted file when clicking outside', function() { - var $tr = fileList.findFileEl('One.txt'); - $tr.find('td.filename>a.name').click(); - - fileList.$el.find('tfoot').click(); - - expect($tr.hasClass('highlighted')).toEqual(true); - expect(fileList._detailsView.getFileInfo().id).toEqual(1); - }); - it('removes last highlighted file when selecting via checkbox', function() { - var $tr = fileList.findFileEl('One.txt'); - - // select - $tr.find('td.filename>a.name').click(); - $tr.find('input:checkbox').click(); - expect($tr.hasClass('highlighted')).toEqual(false); - - // deselect - $tr.find('td.filename>a.name').click(); - $tr.find('input:checkbox').click(); - expect($tr.hasClass('highlighted')).toEqual(false); - - expect(fileList._detailsView.getFileInfo()).toEqual(null); - }); - it('removes last highlighted file when selecting all files via checkbox', function() { - var $tr = fileList.findFileEl('One.txt'); - - // select - $tr.find('td.filename>a.name').click(); - fileList.$el.find('.select-all.checkbox').click(); - expect($tr.hasClass('highlighted')).toEqual(false); - - // deselect - $tr.find('td.filename>a.name').click(); - fileList.$el.find('.select-all.checkbox').click(); - expect($tr.hasClass('highlighted')).toEqual(false); - - expect(fileList._detailsView.getFileInfo()).toEqual(null); - }); - it('closes sidebar whenever the currently highlighted file was removed from the list', function() { - var $tr = fileList.findFileEl('One.txt'); - $tr.find('td.filename>a.name').click(); - expect($tr.hasClass('highlighted')).toEqual(true); - - expect(fileList._detailsView.getFileInfo().id).toEqual(1); - - expect($('#app-sidebar').hasClass('disappear')).toEqual(false); - fileList.remove('One.txt'); - expect($('#app-sidebar').hasClass('disappear')).toEqual(true); - }); - it('returns the currently selected model instance when calling getModelForFile', function() { - var $tr = fileList.findFileEl('One.txt'); - $tr.find('td.filename>a.name').click(); - - var model1 = fileList.getModelForFile('One.txt'); - var model2 = fileList.getModelForFile('One.txt'); - model1.set('test', true); - - // it's the same model - expect(model2).toEqual(model1); - - var model3 = fileList.getModelForFile($tr); - expect(model3).toEqual(model1); - }); - it('closes the sidebar when switching folders', function() { - var $tr = fileList.findFileEl('One.txt'); - $tr.find('td.filename>a.name').click(); - - expect($('#app-sidebar').hasClass('disappear')).toEqual(false); - fileList.changeDirectory('/another'); - expect($('#app-sidebar').hasClass('disappear')).toEqual(true); - }); - }); - describe('File actions', function() { - it('Clicking on a file name will trigger default action', function() { - var actionStub = sinon.stub(); - fileList.setFiles(testFiles); - fileList.fileActions.registerAction({ - mime: 'text/plain', - name: 'Test', - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_ALL, - icon: function() { - // Specify icon for hitory button - return OC.imagePath('core','actions/history'); - }, - actionHandler: actionStub - }); - fileList.fileActions.setDefault('text/plain', 'Test'); - var $tr = fileList.findFileEl('One.txt'); - $tr.find('td.filename .nametext').click(); - expect(actionStub.calledOnce).toEqual(true); - expect(actionStub.getCall(0).args[0]).toEqual('One.txt'); - var context = actionStub.getCall(0).args[1]; - expect(context.$file.is($tr)).toEqual(true); - expect(context.fileList).toBeDefined(); - expect(context.fileActions).toBeDefined(); - expect(context.dir).toEqual('/subdir'); - }); - it('redisplays actions when new actions have been registered', function() { - var actionStub = sinon.stub(); - var readyHandler = sinon.stub(); - var clock = sinon.useFakeTimers(); - var debounceStub = sinon.stub(_, 'debounce', function(callback) { - return function() { - // defer instead of debounce, to make it work with clock - _.defer(callback); - }; - }); - - // need to reinit the list to make the debounce call - fileList.destroy(); - fileList = new OCA.Files.FileList($('#app-content-files')); - - fileList.setFiles(testFiles); - - fileList.$fileList.on('fileActionsReady', readyHandler); - - fileList.fileActions.registerAction({ - mime: 'text/plain', - name: 'Test', - type: OCA.Files.FileActions.TYPE_INLINE, - permissions: OC.PERMISSION_ALL, - icon: function() { - // Specify icon for hitory button - return OC.imagePath('core','actions/history'); - }, - actionHandler: actionStub - }); - var $tr = fileList.findFileEl('One.txt'); - expect($tr.find('.action-test').length).toEqual(0); - expect(readyHandler.notCalled).toEqual(true); - - // update is delayed - clock.tick(100); - expect($tr.find('.action-test').length).toEqual(1); - expect(readyHandler.calledOnce).toEqual(true); - - clock.restore(); - debounceStub.restore(); - }); - }); - describe('Sorting files', function() { - it('Toggles the sort indicator when clicking on a column header', function() { - var ASC_CLASS = fileList.SORT_INDICATOR_ASC_CLASS; - var DESC_CLASS = fileList.SORT_INDICATOR_DESC_CLASS; - fileList.$el.find('.column-size .columntitle').click(); - // moves triangle to size column, check indicator on name is hidden - expect( - fileList.$el.find('.column-name .sort-indicator').hasClass('hidden') - ).toEqual(true); - // check indicator on size is visible and defaults to descending - expect( - fileList.$el.find('.column-size .sort-indicator').hasClass('hidden') - ).toEqual(false); - expect( - fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS) - ).toEqual(true); - - // click again on size column, reverses direction - fileList.$el.find('.column-size .columntitle').click(); - expect( - fileList.$el.find('.column-size .sort-indicator').hasClass('hidden') - ).toEqual(false); - expect( - fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS) - ).toEqual(true); - - // click again on size column, reverses direction - fileList.$el.find('.column-size .columntitle').click(); - expect( - fileList.$el.find('.column-size .sort-indicator').hasClass('hidden') - ).toEqual(false); - expect( - fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS) - ).toEqual(true); - - // click on mtime column, moves indicator there - fileList.$el.find('.column-mtime .columntitle').click(); - expect( - fileList.$el.find('.column-size .sort-indicator').hasClass('hidden') - ).toEqual(true); - expect( - fileList.$el.find('.column-mtime .sort-indicator').hasClass('hidden') - ).toEqual(false); - expect( - fileList.$el.find('.column-mtime .sort-indicator').hasClass(DESC_CLASS) - ).toEqual(true); - }); - it('Uses correct sort comparator when inserting files', function() { - testFiles.sort(OCA.Files.FileList.Comparators.size); - testFiles.reverse(); //default is descending - fileList.setFiles(testFiles); - fileList.$el.find('.column-size .columntitle').click(); - var newFileData = new FileInfo({ - id: 999, - name: 'new file.txt', - mimetype: 'text/plain', - size: 40001, - etag: '999' - }); - fileList.add(newFileData); - expect(fileList.findFileEl('Three.pdf').index()).toEqual(0); - expect(fileList.findFileEl('new file.txt').index()).toEqual(1); - expect(fileList.findFileEl('Two.jpg').index()).toEqual(2); - expect(fileList.findFileEl('somedir').index()).toEqual(3); - expect(fileList.findFileEl('One.txt').index()).toEqual(4); - expect(fileList.files.length).toEqual(5); - expect(fileList.$fileList.find('tr').length).toEqual(5); - }); - it('Uses correct reversed sort comparator when inserting files', function() { - testFiles.sort(OCA.Files.FileList.Comparators.size); - fileList.setFiles(testFiles); - fileList.$el.find('.column-size .columntitle').click(); - - // reverse sort - fileList.$el.find('.column-size .columntitle').click(); - var newFileData = new FileInfo({ - id: 999, - name: 'new file.txt', - mimetype: 'text/plain', - size: 40001, - etag: '999' - }); - fileList.add(newFileData); - expect(fileList.findFileEl('One.txt').index()).toEqual(0); - expect(fileList.findFileEl('somedir').index()).toEqual(1); - expect(fileList.findFileEl('Two.jpg').index()).toEqual(2); - expect(fileList.findFileEl('new file.txt').index()).toEqual(3); - expect(fileList.findFileEl('Three.pdf').index()).toEqual(4); - expect(fileList.files.length).toEqual(5); - expect(fileList.$fileList.find('tr').length).toEqual(5); - }); - it('does not sort when clicking on header whenever multiselect is enabled', function() { - var sortStub = sinon.stub(OCA.Files.FileList.prototype, 'setSort'); - - fileList.setFiles(testFiles); - fileList.findFileEl('One.txt').find('input:checkbox:first').click(); - - fileList.$el.find('.column-size .columntitle').click(); - - expect(sortStub.notCalled).toEqual(true); - - // can sort again after deselecting - fileList.findFileEl('One.txt').find('input:checkbox:first').click(); - - fileList.$el.find('.column-size .columntitle').click(); - - expect(sortStub.calledOnce).toEqual(true); - - sortStub.restore(); - }); - }); - describe('create file', function() { - var deferredCreate; - var deferredInfo; - var createStub; - var getFileInfoStub; - - beforeEach(function() { - deferredCreate = $.Deferred(); - deferredInfo = $.Deferred(); - createStub = sinon.stub(filesClient, 'putFileContents') - .returns(deferredCreate.promise()); - getFileInfoStub = sinon.stub(filesClient, 'getFileInfo') - .returns(deferredInfo.promise()); - }); - afterEach(function() { - createStub.restore(); - getFileInfoStub.restore(); - }); - - it('creates file with given name and adds it to the list', function() { - fileList.createFile('test.txt'); - - expect(createStub.calledOnce).toEqual(true); - expect(createStub.getCall(0).args[0]).toEqual('/subdir/test.txt'); - expect(createStub.getCall(0).args[2]).toEqual({ - contentType: 'text/plain', - overwrite: true - }); - - deferredCreate.resolve(200); - - expect(getFileInfoStub.calledOnce).toEqual(true); - expect(getFileInfoStub.getCall(0).args[0]).toEqual('/subdir/test.txt'); - - deferredInfo.resolve( - 200, - new FileInfo({ - path: '/subdir', - name: 'test.txt', - mimetype: 'text/plain' - }) - ); - - var $tr = fileList.findFileEl('test.txt'); - expect($tr.length).toEqual(1); - expect($tr.attr('data-mime')).toEqual('text/plain'); - }); - // TODO: error cases - // TODO: unique name cases - }); - describe('create folder', function() { - var deferredCreate; - var deferredInfo; - var createStub; - var getFileInfoStub; - - beforeEach(function() { - deferredCreate = $.Deferred(); - deferredInfo = $.Deferred(); - createStub = sinon.stub(filesClient, 'createDirectory') - .returns(deferredCreate.promise()); - getFileInfoStub = sinon.stub(filesClient, 'getFileInfo') - .returns(deferredInfo.promise()); - }); - afterEach(function() { - createStub.restore(); - getFileInfoStub.restore(); - }); - - it('creates folder with given name and adds it to the list', function() { - fileList.createDirectory('sub dir'); - - expect(createStub.calledOnce).toEqual(true); - expect(createStub.getCall(0).args[0]).toEqual('/subdir/sub dir'); - - deferredCreate.resolve(200); - - expect(getFileInfoStub.calledOnce).toEqual(true); - expect(getFileInfoStub.getCall(0).args[0]).toEqual('/subdir/sub dir'); - - deferredInfo.resolve( - 200, - new FileInfo({ - path: '/subdir', - name: 'sub dir', - mimetype: 'httpd/unix-directory' - }) - ); - - var $tr = fileList.findFileEl('sub dir'); - expect($tr.length).toEqual(1); - expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); - }); - // TODO: error cases - // TODO: unique name cases - }); - /** - * Test upload mostly by testing the code inside the event handlers - * that were registered on the magic upload object - */ - describe('file upload', function() { - var $uploader; - - beforeEach(function() { - // note: this isn't the real blueimp file uploader from jquery.fileupload - // but it makes it possible to simulate the event triggering to - // test the response of the handlers - $uploader = $('#file_upload_start'); - fileList.setFiles(testFiles); - }); - - afterEach(function() { - $uploader = null; - }); - - describe('dropping external files', function() { - var uploadData; - - /** - * Simulate drop event on the given target - * - * @param $target target element to drop on - * @return event object including the result - */ - function dropOn($target, data) { - var eventData = { - originalEvent: { - target: $target - } - }; - var ev = new $.Event('fileuploaddrop', eventData); - // using triggerHandler instead of trigger so we can pass - // extra data - $uploader.triggerHandler(ev, data || {}); - return ev; - } - - beforeEach(function() { - // simulate data structure from jquery.upload - uploadData = { - files: [{ - relativePath: 'fileToUpload.txt' - }] - }; - }); - afterEach(function() { - uploadData = null; - }); - it('drop on a tr or crumb outside file list does not trigger upload', function() { - var $anotherTable = $('<table><tbody><tr><td>outside<div class="crumb">crumb</div></td></tr></table>'); - var ev; - $('#testArea').append($anotherTable); - ev = dropOn($anotherTable.find('tr'), uploadData); - expect(ev.result).toEqual(false); - - ev = dropOn($anotherTable.find('.crumb')); - expect(ev.result).toEqual(false); - }); - it('drop on an element outside file list container does not trigger upload', function() { - var $anotherEl = $('<div>outside</div>'); - var ev; - $('#testArea').append($anotherEl); - ev = dropOn($anotherEl); - - expect(ev.result).toEqual(false); - }); - it('drop on an element inside the table triggers upload', function() { - var ev; - ev = dropOn(fileList.$fileList.find('th:first'), uploadData); - - expect(ev.result).not.toEqual(false); - }); - it('drop on an element on the table container triggers upload', function() { - var ev; - ev = dropOn($('#app-content-files'), uploadData); - - expect(ev.result).not.toEqual(false); - }); - it('drop on an element inside the table does not trigger upload if no upload permission', function() { - $('#permissions').val(0); - var ev; - ev = dropOn(fileList.$fileList.find('th:first')); - - expect(ev.result).toEqual(false); - expect(notificationStub.calledOnce).toEqual(true); - }); - it('drop on an folder does not trigger upload if no upload permission on that folder', function() { - var $tr = fileList.findFileEl('somedir'); - var ev; - $tr.data('permissions', OC.PERMISSION_READ); - ev = dropOn($tr); - - expect(ev.result).toEqual(false); - expect(notificationStub.calledOnce).toEqual(true); - }); - it('drop on a file row inside the table triggers upload to current folder', function() { - var ev; - ev = dropOn(fileList.findFileEl('One.txt').find('td:first'), uploadData); - - expect(ev.result).not.toEqual(false); - }); - it('drop on a folder row inside the table triggers upload to target folder', function() { - var ev; - ev = dropOn(fileList.findFileEl('somedir').find('td:eq(2)'), uploadData); - - expect(ev.result).not.toEqual(false); - expect(uploadData.targetDir).toEqual('/subdir/somedir'); - }); - it('drop on a breadcrumb inside the table triggers upload to target folder', function() { - var ev; - fileList.changeDirectory('a/b/c/d'); - ev = dropOn(fileList.$el.find('.crumb:eq(2)'), uploadData); - - expect(ev.result).not.toEqual(false); - expect(uploadData.targetDir).toEqual('/a/b'); - }); - it('renders upload indicator element for folders only', function() { - fileList.add({ - name: 'afolder', - type: 'dir', - mime: 'httpd/unix-directory' - }); - fileList.add({ - name: 'afile.txt', - type: 'file', - mime: 'text/plain' - }); - - expect(fileList.findFileEl('afolder').find('.uploadtext').length).toEqual(1); - expect(fileList.findFileEl('afile.txt').find('.uploadtext').length).toEqual(0); - }); - }); - }); - describe('Handling errors', function () { - var deferredList; - var getFolderContentsStub; - - beforeEach(function() { - deferredList = $.Deferred(); - getFolderContentsStub = - sinon.stub(filesClient, 'getFolderContents'); - getFolderContentsStub.onCall(0).returns(deferredList.promise()); - getFolderContentsStub.onCall(1).returns($.Deferred().promise()); - fileList.reload(); - }); - afterEach(function() { - getFolderContentsStub.restore(); - fileList = undefined; - }); - it('redirects to root folder in case of forbidden access', function () { - deferredList.reject(403); - - expect(fileList.getCurrentDirectory()).toEqual('/'); - expect(getFolderContentsStub.calledTwice).toEqual(true); - }); - it('redirects to root folder and shows notification in case of internal server error', function () { - expect(notificationStub.notCalled).toEqual(true); - deferredList.reject(500); - - expect(fileList.getCurrentDirectory()).toEqual('/'); - expect(getFolderContentsStub.calledTwice).toEqual(true); - expect(notificationStub.calledOnce).toEqual(true); - }); - it('redirects to root folder and shows notification in case of storage not available', function () { - expect(notificationStub.notCalled).toEqual(true); - deferredList.reject(503, 'Storage not available'); - - expect(fileList.getCurrentDirectory()).toEqual('/'); - expect(getFolderContentsStub.calledTwice).toEqual(true); - expect(notificationStub.calledOnce).toEqual(true); - }); - }); - describe('showFileBusyState', function() { - var $tr; - - beforeEach(function() { - fileList.setFiles(testFiles); - $tr = fileList.findFileEl('Two.jpg'); - }); - it('shows spinner on busy rows', function() { - fileList.showFileBusyState('Two.jpg', true); - expect($tr.hasClass('busy')).toEqual(true); - expect(OC.TestUtil.getImageUrl($tr.find('.thumbnail'))) - .toEqual(OC.imagePath('core', 'loading.gif')); - - fileList.showFileBusyState('Two.jpg', false); - expect($tr.hasClass('busy')).toEqual(false); - expect(OC.TestUtil.getImageUrl($tr.find('.thumbnail'))) - .toEqual(OC.imagePath('core', 'filetypes/image.svg')); - }); - it('accepts multiple input formats', function() { - _.each([ - 'Two.jpg', - ['Two.jpg'], - $tr, - [$tr] - ], function(testCase) { - fileList.showFileBusyState(testCase, true); - expect($tr.hasClass('busy')).toEqual(true); - fileList.showFileBusyState(testCase, false); - expect($tr.hasClass('busy')).toEqual(false); - }); - }); - }); - describe('elementToFile', function() { - var $tr; - - beforeEach(function() { - fileList.setFiles(testFiles); - $tr = fileList.findFileEl('One.txt'); - }); - - it('converts data attributes to file info structure', function() { - var fileInfo = fileList.elementToFile($tr); - expect(fileInfo.id).toEqual(1); - expect(fileInfo.name).toEqual('One.txt'); - expect(fileInfo.mtime).toEqual(123456789); - expect(fileInfo.etag).toEqual('abc'); - expect(fileInfo.permissions).toEqual(OC.PERMISSION_ALL); - expect(fileInfo.size).toEqual(12); - expect(fileInfo.mimetype).toEqual('text/plain'); - expect(fileInfo.type).toEqual('file'); - expect(fileInfo.path).not.toBeDefined(); - }); - it('adds path attribute if available', function() { - $tr.attr('data-path', '/subdir'); - var fileInfo = fileList.elementToFile($tr); - expect(fileInfo.path).toEqual('/subdir'); - }); - }); - describe('new file menu', function() { - var newFileMenuStub; - - beforeEach(function() { - newFileMenuStub = sinon.stub(OCA.Files.NewFileMenu.prototype, 'showAt'); - }); - afterEach(function() { - newFileMenuStub.restore(); - }) - it('renders new button when no legacy upload button exists', function() { - expect(fileList.$el.find('.button.upload').length).toEqual(0); - expect(fileList.$el.find('.button.new').length).toEqual(1); - }); - it('does not render new button when no legacy upload button exists (public page)', function() { - fileList.destroy(); - $('#controls').append('<input type="button" class="button upload" />'); - fileList = new OCA.Files.FileList($('#app-content-files')); - expect(fileList.$el.find('.button.upload').length).toEqual(1); - expect(fileList.$el.find('.button.new').length).toEqual(0); - }); - it('opens the new file menu when clicking on the "New" button', function() { - var $button = fileList.$el.find('.button.new'); - $button.click(); - expect(newFileMenuStub.calledOnce).toEqual(true); - }); - it('does not open the new file menu when button is disabled', function() { - var $button = fileList.$el.find('.button.new'); - $button.addClass('disabled'); - $button.click(); - expect(newFileMenuStub.notCalled).toEqual(true); - }); - }); - describe('mount type detection', function() { - function testMountType(dirInfoId, dirInfoMountType, inputMountType, expectedMountType) { - var $tr; - fileList.dirInfo.id = dirInfoId; - fileList.dirInfo.mountType = dirInfoMountType; - $tr = fileList.add({ - type: 'dir', - mimetype: 'httpd/unix-directory', - name: 'test dir', - mountType: inputMountType - }); - - expect($tr.attr('data-mounttype')).toEqual(expectedMountType); - } - - it('leaves mount type as is if no parent exists', function() { - testMountType(null, null, 'external', 'external'); - testMountType(null, null, 'shared', 'shared'); - }); - it('detects share root if parent exists', function() { - testMountType(123, null, 'shared', 'shared-root'); - testMountType(123, 'shared', 'shared', 'shared'); - testMountType(123, 'shared-root', 'shared', 'shared'); - }); - it('detects external storage root if parent exists', function() { - testMountType(123, null, 'external', 'external-root'); - testMountType(123, 'external', 'external', 'external'); - testMountType(123, 'external-root', 'external', 'external'); - }); - }); -}); diff --git a/apps/files/tests/js/filesSpec.js b/apps/files/tests/js/filesSpec.js deleted file mode 100644 index b7627d59fdf..00000000000 --- a/apps/files/tests/js/filesSpec.js +++ /dev/null @@ -1,142 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2014 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -describe('OCA.Files.Files tests', function() { - var Files = OCA.Files.Files; - - describe('File name validation', function() { - it('Validates correct file names', function() { - var fileNames = [ - 'boringname', - 'something.with.extension', - 'now with spaces', - '.a', - '..a', - '.dotfile', - 'single\'quote', - ' spaces before', - 'spaces after ', - 'allowed chars including the crazy ones $%&_-^@!,()[]{}=;#', - '汉字也能用', - 'und Ümläüte sind auch willkommen' - ]; - for ( var i = 0; i < fileNames.length; i++ ) { - var error = false; - try { - expect(Files.isFileNameValid(fileNames[i])).toEqual(true); - } - catch (e) { - error = e; - } - expect(error).toEqual(false); - } - }); - it('Detects invalid file names', function() { - var fileNames = [ - '', - ' ', - '.', - '..', - ' ..', - '.. ', - '. ', - ' .' - ]; - for ( var i = 0; i < fileNames.length; i++ ) { - var threwException = false; - try { - Files.isFileNameValid(fileNames[i]); - console.error('Invalid file name not detected:', fileNames[i]); - } - catch (e) { - threwException = true; - } - expect(threwException).toEqual(true); - } - }); - }); - describe('getDownloadUrl', function() { - it('returns the ajax download URL when filename and dir specified', function() { - var url = Files.getDownloadUrl('test file.txt', '/subdir'); - expect(url).toEqual(OC.webroot + '/remote.php/webdav/subdir/test%20file.txt'); - }); - it('returns the webdav download URL when filename and root dir specified', function() { - var url = Files.getDownloadUrl('test file.txt', '/'); - expect(url).toEqual(OC.webroot + '/remote.php/webdav/test%20file.txt'); - }); - it('returns the ajax download URL when multiple files specified', function() { - var url = Files.getDownloadUrl(['test file.txt', 'abc.txt'], '/subdir'); - expect(url).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=%5B%22test%20file.txt%22%2C%22abc.txt%22%5D'); - }); - }); - describe('handleDownload', function() { - var redirectStub; - var cookieStub; - var clock; - var testUrl; - - beforeEach(function() { - testUrl = 'http://example.com/owncloud/path/download.php'; - redirectStub = sinon.stub(OC, 'redirect'); - cookieStub = sinon.stub(OC.Util, 'isCookieSetToValue'); - clock = sinon.useFakeTimers(); - }); - afterEach(function() { - redirectStub.restore(); - cookieStub.restore(); - clock.restore(); - }); - - it('appends secret to url when no existing parameters', function() { - Files.handleDownload(testUrl); - expect(redirectStub.calledOnce).toEqual(true); - expect(redirectStub.getCall(0).args[0]).toContain(testUrl + '?downloadStartSecret='); - }); - it('appends secret to url with existing parameters', function() { - Files.handleDownload(testUrl + '?test=1'); - expect(redirectStub.calledOnce).toEqual(true); - expect(redirectStub.getCall(0).args[0]).toContain(testUrl + '?test=1&downloadStartSecret='); - }); - it('sets cookie and calls callback when cookie appears', function() { - var callbackStub = sinon.stub(); - var token; - Files.handleDownload(testUrl, callbackStub); - expect(redirectStub.calledOnce).toEqual(true); - token = OC.parseQueryString(redirectStub.getCall(0).args[0]).downloadStartSecret; - expect(token).toBeDefined(); - - expect(cookieStub.calledOnce).toEqual(true); - cookieStub.returns(false); - clock.tick(600); - - expect(cookieStub.calledTwice).toEqual(true); - expect(cookieStub.getCall(1).args[0]).toEqual('ocDownloadStarted'); - expect(cookieStub.getCall(1).args[1]).toEqual(token); - expect(callbackStub.notCalled).toEqual(true); - - cookieStub.returns(true); - clock.tick(2000); - - expect(cookieStub.callCount).toEqual(3); - expect(callbackStub.calledOnce).toEqual(true); - }); - }); -}); diff --git a/apps/files/tests/js/filesummarySpec.js b/apps/files/tests/js/filesummarySpec.js deleted file mode 100644 index ec94c28acb6..00000000000 --- a/apps/files/tests/js/filesummarySpec.js +++ /dev/null @@ -1,184 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2014 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/* global FileSummary */ -describe('OCA.Files.FileSummary tests', function() { - var FileSummary = OCA.Files.FileSummary; - var $container; - - beforeEach(function() { - $container = $('<table><tr></tr></table>').find('tr'); - }); - afterEach(function() { - $container = null; - }); - - it('renders summary as text', function() { - var s = new FileSummary($container); - s.setSummary({ - totalDirs: 5, - totalFiles: 2, - totalSize: 256000 - }); - expect($container.hasClass('hidden')).toEqual(false); - expect($container.find('.info').text()).toEqual('5 folders and 2 files'); - expect($container.find('.filesize').text()).toEqual('250 KB'); - }); - it('hides summary when no files or folders', function() { - var s = new FileSummary($container); - s.setSummary({ - totalDirs: 0, - totalFiles: 0, - totalSize: 0 - }); - expect($container.hasClass('hidden')).toEqual(true); - }); - it('increases summary when adding files', function() { - var s = new FileSummary($container); - s.setSummary({ - totalDirs: 5, - totalFiles: 2, - totalSize: 256000 - }); - s.add({type: 'file', size: 256000}); - s.add({type: 'dir', size: 100}); - s.update(); - expect($container.hasClass('hidden')).toEqual(false); - expect($container.find('.info').text()).toEqual('6 folders and 3 files'); - expect($container.find('.filesize').text()).toEqual('500 KB'); - expect(s.summary.totalDirs).toEqual(6); - expect(s.summary.totalFiles).toEqual(3); - expect(s.summary.totalSize).toEqual(512100); - }); - it('decreases summary when removing files', function() { - var s = new FileSummary($container); - s.setSummary({ - totalDirs: 5, - totalFiles: 2, - totalSize: 256000 - }); - s.remove({type: 'file', size: 128000}); - s.remove({type: 'dir', size: 100}); - s.update(); - expect($container.hasClass('hidden')).toEqual(false); - expect($container.find('.info').text()).toEqual('4 folders and 1 file'); - expect($container.find('.filesize').text()).toEqual('125 KB'); - expect(s.summary.totalDirs).toEqual(4); - expect(s.summary.totalFiles).toEqual(1); - expect(s.summary.totalSize).toEqual(127900); - }); - - it('renders filtered summary as text', function() { - var s = new FileSummary($container); - s.setSummary({ - totalDirs: 5, - totalFiles: 2, - totalSize: 256000, - filter: 'foo' - }); - expect($container.hasClass('hidden')).toEqual(false); - expect($container.find('.info').text()).toEqual('5 folders and 2 files match \'foo\''); - expect($container.find('.filesize').text()).toEqual('250 KB'); - }); - it('hides filtered summary when no files or folders', function() { - var s = new FileSummary($container); - s.setSummary({ - totalDirs: 0, - totalFiles: 0, - totalSize: 0, - filter: 'foo' - }); - expect($container.hasClass('hidden')).toEqual(true); - }); - it('increases filtered summary when adding files', function() { - var s = new FileSummary($container); - s.setSummary({ - totalDirs: 5, - totalFiles: 2, - totalSize: 256000, - filter: 'foo' - }); - s.add({name: 'bar.txt', type: 'file', size: 256000}); - s.add({name: 'foo.txt', type: 'file', size: 256001}); - s.add({name: 'bar', type: 'dir', size: 100}); - s.add({name: 'foo', type: 'dir', size: 102}); - s.update(); - expect($container.hasClass('hidden')).toEqual(false); - expect($container.find('.info').text()).toEqual('6 folders and 3 files match \'foo\''); - expect($container.find('.filesize').text()).toEqual('500 KB'); - expect(s.summary.totalDirs).toEqual(6); - expect(s.summary.totalFiles).toEqual(3); - expect(s.summary.totalSize).toEqual(512103); - }); - it('decreases filtered summary when removing files', function() { - var s = new FileSummary($container); - s.setSummary({ - totalDirs: 5, - totalFiles: 2, - totalSize: 256000, - filter: 'foo' - }); - s.remove({name: 'bar.txt', type: 'file', size: 128000}); - s.remove({name: 'foo.txt', type: 'file', size: 127999}); - s.remove({name: 'bar', type: 'dir', size: 100}); - s.remove({name: 'foo', type: 'dir', size: 98}); - s.update(); - expect($container.hasClass('hidden')).toEqual(false); - expect($container.find('.info').text()).toEqual('4 folders and 1 file match \'foo\''); - expect($container.find('.filesize').text()).toEqual('125 KB'); - expect(s.summary.totalDirs).toEqual(4); - expect(s.summary.totalFiles).toEqual(1); - expect(s.summary.totalSize).toEqual(127903); - }); - it('properly sum up pending folder sizes after adding', function() { - var s = new FileSummary($container); - s.setSummary({ - totalDirs: 0, - totalFiles: 0, - totalSize: 0 - }); - s.add({type: 'dir', size: -1}); - s.update(); - expect($container.hasClass('hidden')).toEqual(false); - expect($container.find('.info').text()).toEqual('1 folder and 0 files'); - expect($container.find('.filesize').text()).toEqual('Pending'); - expect(s.summary.totalDirs).toEqual(1); - expect(s.summary.totalFiles).toEqual(0); - expect(s.summary.totalSize).toEqual(0); - }); - it('properly sum up pending folder sizes after remove', function() { - var s = new FileSummary($container); - s.setSummary({ - totalDirs: 0, - totalFiles: 0, - totalSize: 0 - }); - s.add({type: 'dir', size: -1}); - s.remove({type: 'dir', size: -1}); - s.update(); - expect($container.hasClass('hidden')).toEqual(true); - expect($container.find('.info').text()).toEqual('0 folders and 0 files'); - expect($container.find('.filesize').text()).toEqual('0 B'); - expect(s.summary.totalDirs).toEqual(0); - expect(s.summary.totalFiles).toEqual(0); - expect(s.summary.totalSize).toEqual(0); - }); -}); diff --git a/apps/files/tests/js/mainfileinfodetailviewSpec.js b/apps/files/tests/js/mainfileinfodetailviewSpec.js deleted file mode 100644 index 460629806c8..00000000000 --- a/apps/files/tests/js/mainfileinfodetailviewSpec.js +++ /dev/null @@ -1,252 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2015 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -describe('OCA.Files.MainFileInfoDetailView tests', function() { - var view, tooltipStub, fileActions, fileList, testFileInfo; - - beforeEach(function() { - tooltipStub = sinon.stub($.fn, 'tooltip'); - fileActions = new OCA.Files.FileActions(); - fileList = new OCA.Files.FileList($('<table></table>'), { - fileActions: fileActions - }); - view = new OCA.Files.MainFileInfoDetailView({ - fileList: fileList, - fileActions: fileActions - }); - testFileInfo = new OCA.Files.FileInfoModel({ - id: 5, - name: 'One.txt', - mimetype: 'text/plain', - permissions: 31, - path: '/subdir', - size: 123456789, - etag: 'abcdefg', - mtime: Date.UTC(2015, 6, 17, 1, 2, 0, 0) - }); - }); - afterEach(function() { - view.remove(); - view = undefined; - tooltipStub.restore(); - - }); - describe('rendering', function() { - it('displays basic info', function() { - var clock = sinon.useFakeTimers(Date.UTC(2015, 6, 17, 1, 2, 0, 3)); - var dateExpected = OC.Util.formatDate(Date(Date.UTC(2015, 6, 17, 1, 2, 0, 0))); - view.setFileInfo(testFileInfo); - expect(view.$el.find('.fileName h3').text()).toEqual('One.txt'); - expect(view.$el.find('.fileName h3').attr('title')).toEqual('One.txt'); - expect(view.$el.find('.size').text()).toEqual('117.7 MB'); - expect(view.$el.find('.size').attr('title')).toEqual('123456789 bytes'); - expect(view.$el.find('.date').text()).toEqual('seconds ago'); - expect(view.$el.find('.date').attr('title')).toEqual(dateExpected); - clock.restore(); - }); - it('displays favorite icon', function() { - testFileInfo.set('tags', [OC.TAG_FAVORITE]); - view.setFileInfo(testFileInfo); - expect(view.$el.find('.favorite img').attr('src')) - .toEqual(OC.imagePath('core', 'actions/starred')); - - testFileInfo.set('tags', []); - view.setFileInfo(testFileInfo); - expect(view.$el.find('.favorite img').attr('src')) - .toEqual(OC.imagePath('core', 'actions/star')); - }); - it('displays mime icon', function() { - // File - var lazyLoadPreviewStub = sinon.stub(fileList, 'lazyLoadPreview'); - testFileInfo.set('mimetype', 'text/calendar'); - view.setFileInfo(testFileInfo); - - expect(lazyLoadPreviewStub.calledOnce).toEqual(true); - var previewArgs = lazyLoadPreviewStub.getCall(0).args; - expect(previewArgs[0].mime).toEqual('text/calendar'); - expect(previewArgs[0].path).toEqual('/subdir/One.txt'); - expect(previewArgs[0].etag).toEqual('abcdefg'); - - expect(view.$el.find('.thumbnail').hasClass('icon-loading')).toEqual(true); - - // returns mime icon first without img parameter - previewArgs[0].callback( - OC.imagePath('core', 'filetypes/text-calendar.svg') - ); - - // still loading - expect(view.$el.find('.thumbnail').hasClass('icon-loading')).toEqual(true); - - // preview loading failed, no prview - previewArgs[0].error(); - - // loading stopped, the mimetype icon gets displayed - expect(view.$el.find('.thumbnail').hasClass('icon-loading')).toEqual(false); - expect(view.$el.find('.thumbnail').css('background-image')) - .toContain('filetypes/text-calendar.svg'); - - // Folder - testFileInfo.set('mimetype', 'httpd/unix-directory'); - view.setFileInfo(testFileInfo); - - expect(view.$el.find('.thumbnail').css('background-image')) - .toContain('filetypes/folder.svg'); - - lazyLoadPreviewStub.restore(); - }); - it('uses icon from model if present in model', function() { - var lazyLoadPreviewStub = sinon.stub(fileList, 'lazyLoadPreview'); - testFileInfo.set('mimetype', 'httpd/unix-directory'); - testFileInfo.set('icon', OC.MimeType.getIconUrl('dir-external')); - view.setFileInfo(testFileInfo); - - expect(lazyLoadPreviewStub.notCalled).toEqual(true); - - expect(view.$el.find('.thumbnail').hasClass('icon-loading')).toEqual(false); - expect(view.$el.find('.thumbnail').css('background-image')) - .toContain('filetypes/folder-external.svg'); - - lazyLoadPreviewStub.restore(); - }); - it('displays thumbnail', function() { - var lazyLoadPreviewStub = sinon.stub(fileList, 'lazyLoadPreview'); - - testFileInfo.set('mimetype', 'text/plain'); - view.setFileInfo(testFileInfo); - - expect(lazyLoadPreviewStub.calledOnce).toEqual(true); - var previewArgs = lazyLoadPreviewStub.getCall(0).args; - expect(previewArgs[0].mime).toEqual('text/plain'); - expect(previewArgs[0].path).toEqual('/subdir/One.txt'); - expect(previewArgs[0].etag).toEqual('abcdefg'); - - expect(view.$el.find('.thumbnail').hasClass('icon-loading')).toEqual(true); - - // returns mime icon first without img parameter - previewArgs[0].callback( - OC.imagePath('core', 'filetypes/text-plain.svg') - ); - - // still loading - expect(view.$el.find('.thumbnail').hasClass('icon-loading')).toEqual(true); - - // return an actual (simulated) image - previewArgs[0].callback( - 'testimage', { - width: 100, - height: 200 - } - ); - - // loading stopped, image got displayed - expect(view.$el.find('.thumbnail').css('background-image')) - .toContain('testimage'); - - expect(view.$el.find('.thumbnail').hasClass('icon-loading')).toEqual(false); - - lazyLoadPreviewStub.restore(); - }); - it('does not show size if no size available', function() { - testFileInfo.unset('size'); - view.setFileInfo(testFileInfo); - - expect(view.$el.find('.size').length).toEqual(0); - }); - it('renders displayName instead of name if available', function() { - testFileInfo.set('displayName', 'hello.txt'); - view.setFileInfo(testFileInfo); - - expect(view.$el.find('.fileName h3').text()).toEqual('hello.txt'); - expect(view.$el.find('.fileName h3').attr('title')).toEqual('hello.txt'); - }); - it('rerenders when changes are made on the model', function() { - view.setFileInfo(testFileInfo); - - testFileInfo.set('tags', [OC.TAG_FAVORITE]); - - expect(view.$el.find('.favorite img').attr('src')) - .toEqual(OC.imagePath('core', 'actions/starred')); - - testFileInfo.set('tags', []); - - expect(view.$el.find('.favorite img').attr('src')) - .toEqual(OC.imagePath('core', 'actions/star')); - }); - it('unbinds change listener from model', function() { - view.setFileInfo(testFileInfo); - view.setFileInfo(new OCA.Files.FileInfoModel({ - id: 999, - name: 'test.txt', - path: '/' - })); - - // set value on old model - testFileInfo.set('tags', [OC.TAG_FAVORITE]); - - // no change - expect(view.$el.find('.favorite img').attr('src')) - .toEqual(OC.imagePath('core', 'actions/star')); - }); - }); - describe('events', function() { - it('triggers default action when clicking on the thumbnail', function() { - var actionHandler = sinon.stub(); - - fileActions.registerAction({ - name: 'Something', - mime: 'all', - permissions: OC.PERMISSION_READ, - actionHandler: actionHandler - }); - fileActions.setDefault('text/plain', 'Something'); - - view.setFileInfo(testFileInfo); - - view.$el.find('.thumbnail').click(); - - expect(actionHandler.calledOnce).toEqual(true); - expect(actionHandler.getCall(0).args[0]).toEqual('One.txt'); - expect(actionHandler.getCall(0).args[1].fileList).toEqual(fileList); - expect(actionHandler.getCall(0).args[1].fileActions).toEqual(fileActions); - expect(actionHandler.getCall(0).args[1].fileInfoModel).toEqual(testFileInfo); - }); - it('triggers "Favorite" action when clicking on the star', function() { - var actionHandler = sinon.stub(); - - fileActions.registerAction({ - name: 'Favorite', - mime: 'all', - permissions: OC.PERMISSION_READ, - actionHandler: actionHandler - }); - - view.setFileInfo(testFileInfo); - - view.$el.find('.action-favorite').click(); - - expect(actionHandler.calledOnce).toEqual(true); - expect(actionHandler.getCall(0).args[0]).toEqual('One.txt'); - expect(actionHandler.getCall(0).args[1].fileList).toEqual(fileList); - expect(actionHandler.getCall(0).args[1].fileActions).toEqual(fileActions); - expect(actionHandler.getCall(0).args[1].fileInfoModel).toEqual(testFileInfo); - }); - }); -}); diff --git a/apps/files/tests/js/newfilemenuSpec.js b/apps/files/tests/js/newfilemenuSpec.js deleted file mode 100644 index 20f617d24d6..00000000000 --- a/apps/files/tests/js/newfilemenuSpec.js +++ /dev/null @@ -1,148 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2015 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -describe('OCA.Files.NewFileMenu', function() { - var FileList = OCA.Files.FileList; - var menu, fileList, $uploadField, $trigger; - - beforeEach(function() { - // dummy upload button - var $container = $('<div id="app-content-files"></div>'); - $uploadField = $('<input id="file_upload_start"></input>'); - $trigger = $('<a href="#">Menu</a>'); - $container.append($uploadField).append($trigger); - $('#testArea').append($container); - - fileList = new FileList($container); - menu = new OCA.Files.NewFileMenu({ - fileList: fileList - }); - menu.showAt($trigger); - }); - afterEach(function() { - OC.hideMenus(); - fileList = null; - menu = null; - }); - - describe('rendering', function() { - it('renders menu items', function() { - var $items = menu.$el.find('.menuitem'); - expect($items.length).toEqual(2); - // label points to the file_upload_start item - var $item = $items.eq(0); - expect($item.is('label')).toEqual(true); - expect($item.attr('for')).toEqual('file_upload_start'); - }); - }); - describe('New file/folder', function() { - var $input; - var createDirectoryStub; - - beforeEach(function() { - createDirectoryStub = sinon.stub(FileList.prototype, 'createDirectory'); - menu.$el.find('.menuitem').eq(1).click(); - $input = menu.$el.find('form.filenameform input'); - }); - afterEach(function() { - createDirectoryStub.restore(); - }); - - it('sets default text in field', function() { - expect($input.length).toEqual(1); - expect($input.val()).toEqual('New folder'); - }); - it('prevents entering invalid file names', function() { - $input.val('..'); - $input.trigger(new $.Event('keyup', {keyCode: 13})); - $input.closest('form').submit(); - - expect(createDirectoryStub.notCalled).toEqual(true); - }); - it('prevents entering file names that already exist', function() { - var inListStub = sinon.stub(fileList, 'inList').returns(true); - $input.val('existing.txt'); - $input.trigger(new $.Event('keyup', {keyCode: 13})); - $input.closest('form').submit(); - - expect(createDirectoryStub.notCalled).toEqual(true); - inListStub.restore(); - }); - it('creates directory when clicking on create directory field', function() { - $input = menu.$el.find('form.filenameform input'); - $input.val('some folder'); - $input.trigger(new $.Event('keyup', {keyCode: 13})); - $input.closest('form').submit(); - - expect(createDirectoryStub.calledOnce).toEqual(true); - expect(createDirectoryStub.getCall(0).args[0]).toEqual('some folder'); - }); - }); - describe('custom entries', function() { - var oldPlugins; - var plugin; - var actionStub; - - beforeEach(function() { - oldPlugins = _.extend({}, OC.Plugins._plugins); - actionStub = sinon.stub(); - plugin = { - attach: function(menu) { - menu.addMenuEntry({ - id: 'file', - displayName: t('files_texteditor', 'Text file'), - templateName: t('files_texteditor', 'New text file.txt'), - iconClass: 'icon-filetype-text', - fileType: 'file', - actionHandler: actionStub - }); - } - }; - - OC.Plugins.register('OCA.Files.NewFileMenu', plugin); - menu = new OCA.Files.NewFileMenu({ - fileList: fileList - }); - menu.showAt($trigger); - }); - afterEach(function() { - OC.Plugins._plugins = oldPlugins; - }); - it('renders custom menu items', function() { - expect(menu.$el.find('.menuitem').length).toEqual(3); - expect(menu.$el.find('.menuitem[data-action=file]').length).toEqual(1); - }); - it('calls action handler when clicking on custom item', function() { - menu.$el.find('.menuitem').eq(2).click(); - var $input = menu.$el.find('form.filenameform input'); - $input.val('some name'); - $input.trigger(new $.Event('keyup', {keyCode: 13})); - $input.closest('form').submit(); - - expect(actionStub.calledOnce).toEqual(true); - expect(actionStub.getCall(0).args[0]).toEqual('some name'); - }); - it('switching fields removes the previous form', function() { - menu.$el.find('.menuitem').eq(2).click(); - expect(menu.$el.find('form').length).toEqual(1); - }); - }); -}); diff --git a/apps/files/tests/js/tagspluginspec.js b/apps/files/tests/js/tagspluginspec.js deleted file mode 100644 index a4efc08aa53..00000000000 --- a/apps/files/tests/js/tagspluginspec.js +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com> - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -describe('OCA.Files.TagsPlugin tests', function() { - var fileList; - var testFiles; - - beforeEach(function() { - var $content = $('<div id="content"></div>'); - $('#testArea').append($content); - // dummy file list - var $div = $( - '<div>' + - '<table id="filestable">' + - '<thead></thead>' + - '<tbody id="fileList"></tbody>' + - '</table>' + - '</div>'); - $('#content').append($div); - - fileList = new OCA.Files.FileList($div); - OCA.Files.TagsPlugin.attach(fileList); - - testFiles = [{ - id: 1, - type: 'file', - name: 'One.txt', - path: '/subdir', - mimetype: 'text/plain', - size: 12, - permissions: OC.PERMISSION_ALL, - etag: 'abc', - shareOwner: 'User One', - isShareMountPoint: false, - tags: ['tag1', 'tag2'] - }]; - }); - afterEach(function() { - fileList.destroy(); - fileList = null; - }); - - describe('Favorites icon', function() { - it('renders favorite icon and extra data', function() { - var $action, $tr; - fileList.setFiles(testFiles); - $tr = fileList.$el.find('tbody tr:first'); - $action = $tr.find('.action-favorite'); - expect($action.length).toEqual(1); - expect($action.hasClass('permanent')).toEqual(false); - - expect($tr.attr('data-tags').split('|')).toEqual(['tag1', 'tag2']); - expect($tr.attr('data-favorite')).not.toBeDefined(); - }); - it('renders permanent favorite icon and extra data', function() { - var $action, $tr; - testFiles[0].tags.push(OC.TAG_FAVORITE); - fileList.setFiles(testFiles); - $tr = fileList.$el.find('tbody tr:first'); - $action = $tr.find('.action-favorite'); - expect($action.length).toEqual(1); - expect($action.hasClass('permanent')).toEqual(true); - - expect($tr.attr('data-tags').split('|')).toEqual(['tag1', 'tag2', OC.TAG_FAVORITE]); - expect($tr.attr('data-favorite')).toEqual('true'); - }); - it('adds has-favorites class on table', function() { - expect(fileList.$el.hasClass('has-favorites')).toEqual(true); - }); - }); - describe('Applying tags', function() { - it('sends request to server and updates icon', function() { - var request; - fileList.setFiles(testFiles); - var $tr = fileList.findFileEl('One.txt'); - var $action = $tr.find('.action-favorite'); - $action.click(); - - expect(fakeServer.requests.length).toEqual(1); - request = fakeServer.requests[0]; - expect(JSON.parse(request.requestBody)).toEqual({ - tags: ['tag1', 'tag2', OC.TAG_FAVORITE] - }); - request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({ - tags: ['tag1', 'tag2', 'tag3', OC.TAG_FAVORITE] - })); - - // re-read the element as it was re-inserted - $tr = fileList.findFileEl('One.txt'); - $action = $tr.find('.action-favorite'); - - expect($tr.attr('data-favorite')).toEqual('true'); - expect($tr.attr('data-tags').split('|')).toEqual(['tag1', 'tag2', 'tag3', OC.TAG_FAVORITE]); - expect(fileList.files[0].tags).toEqual(['tag1', 'tag2', 'tag3', OC.TAG_FAVORITE]); - expect($action.find('.icon').hasClass('icon-star')).toEqual(false); - expect($action.find('.icon').hasClass('icon-starred')).toEqual(true); - - $action.click(); - - expect(fakeServer.requests.length).toEqual(2); - request = fakeServer.requests[1]; - expect(JSON.parse(request.requestBody)).toEqual({ - tags: ['tag1', 'tag2', 'tag3'] - }); - request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({ - tags: ['tag1', 'tag2', 'tag3'] - })); - - // re-read the element as it was re-inserted - $tr = fileList.findFileEl('One.txt'); - $action = $tr.find('.action-favorite'); - - expect($tr.attr('data-favorite')).toBeFalsy(); - expect($tr.attr('data-tags').split('|')).toEqual(['tag1', 'tag2', 'tag3']); - expect(fileList.files[0].tags).toEqual(['tag1', 'tag2', 'tag3']); - expect($action.find('.icon').hasClass('icon-star')).toEqual(true); - expect($action.find('.icon').hasClass('icon-starred')).toEqual(false); - }); - }); - describe('elementToFile', function() { - it('returns tags', function() { - fileList.setFiles(testFiles); - var $tr = fileList.findFileEl('One.txt'); - var data = fileList.elementToFile($tr); - expect(data.tags).toEqual(['tag1', 'tag2']); - }); - it('returns empty array when no tags present', function() { - delete testFiles[0].tags; - fileList.setFiles(testFiles); - var $tr = fileList.findFileEl('One.txt'); - var data = fileList.elementToFile($tr); - expect(data.tags).toEqual([]); - }); - }); -}); diff --git a/apps/files/tests/service/tagservice.php b/apps/files/tests/service/tagservice.php deleted file mode 100644 index 5fcf64b1352..00000000000 --- a/apps/files/tests/service/tagservice.php +++ /dev/null @@ -1,129 +0,0 @@ -<?php -/** - * @author Roeland Jago Douma <rullzer@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Vincent Petry <pvince81@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 OCA\Files; - -use \OCA\Files\Service\TagService; - -/** - * Class TagServiceTest - * - * @group DB - * - * @package OCA\Files - */ -class TagServiceTest extends \Test\TestCase { - - /** - * @var string - */ - private $user; - - /** - * @var \OCP\Files\Folder - */ - private $root; - - /** - * @var \OCA\Files\Service\TagService - */ - private $tagService; - - /** - * @var \OCP\ITags - */ - private $tagger; - - protected function setUp() { - parent::setUp(); - $this->user = $this->getUniqueId('user'); - \OC::$server->getUserManager()->createUser($this->user, 'test'); - \OC_User::setUserId($this->user); - \OC_Util::setupFS($this->user); - /** - * @var \OCP\IUser - */ - $user = new \OC\User\User($this->user, null); - /** - * @var \OCP\IUserSession - */ - $userSession = $this->getMock('\OCP\IUserSession'); - $userSession->expects($this->any()) - ->method('getUser') - ->withAnyParameters() - ->will($this->returnValue($user)); - - $this->root = \OC::$server->getUserFolder(); - - $this->tagger = \OC::$server->getTagManager()->load('files'); - $this->tagService = new TagService( - $userSession, - $this->tagger, - $this->root - ); - } - - protected function tearDown() { - \OC_User::setUserId(''); - $user = \OC::$server->getUserManager()->get($this->user); - if ($user !== null) { $user->delete(); } - } - - public function testUpdateFileTags() { - $tag1 = 'tag1'; - $tag2 = 'tag2'; - - $subdir = $this->root->newFolder('subdir'); - $testFile = $subdir->newFile('test.txt'); - $testFile->putContent('test contents'); - - $fileId = $testFile->getId(); - - // set tags - $this->tagService->updateFileTags('subdir/test.txt', array($tag1, $tag2)); - - $this->assertEquals(array($fileId), $this->tagger->getIdsForTag($tag1)); - $this->assertEquals(array($fileId), $this->tagger->getIdsForTag($tag2)); - - // remove tag - $result = $this->tagService->updateFileTags('subdir/test.txt', array($tag2)); - $this->assertEquals(array(), $this->tagger->getIdsForTag($tag1)); - $this->assertEquals(array($fileId), $this->tagger->getIdsForTag($tag2)); - - // clear tags - $result = $this->tagService->updateFileTags('subdir/test.txt', array()); - $this->assertEquals(array(), $this->tagger->getIdsForTag($tag1)); - $this->assertEquals(array(), $this->tagger->getIdsForTag($tag2)); - - // non-existing file - $caught = false; - try { - $this->tagService->updateFileTags('subdir/unexist.txt', array($tag1)); - } catch (\OCP\Files\NotFoundException $e) { - $caught = true; - } - $this->assertTrue($caught); - - $subdir->delete(); - } -} - |