aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/tests
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/tests')
-rw-r--r--apps/files/tests/Activity/Filter/GenericTest.php81
-rw-r--r--apps/files/tests/Activity/ProviderTest.php189
-rw-r--r--apps/files/tests/Activity/Setting/GenericTest.php82
-rw-r--r--apps/files/tests/AdvancedCapabilitiesTest.php46
-rw-r--r--apps/files/tests/BackgroundJob/DeleteOrphanedItemsJobTest.php (renamed from apps/files/tests/backgroundjob/DeleteOrphanedItemsJobTest.php)105
-rw-r--r--apps/files/tests/BackgroundJob/ScanFilesTest.php101
-rw-r--r--apps/files/tests/Command/DeleteOrphanedFilesTest.php138
-rw-r--r--apps/files/tests/Controller/ApiControllerTest.php300
-rw-r--r--apps/files/tests/Controller/ConversionApiControllerTest.php96
-rw-r--r--apps/files/tests/Controller/ViewControllerTest.php313
-rw-r--r--apps/files/tests/HelperTest.php95
-rw-r--r--apps/files/tests/Service/TagServiceTest.php121
-rw-r--r--apps/files/tests/activitytest.php375
-rw-r--r--apps/files/tests/backgroundjob/ScanFilesTest.php133
-rw-r--r--apps/files/tests/command/deleteorphanedfilestest.php130
-rw-r--r--apps/files/tests/controller/ViewControllerTest.php268
-rw-r--r--apps/files/tests/controller/apicontrollertest.php338
-rw-r--r--apps/files/tests/helper.php114
-rw-r--r--apps/files/tests/js/appSpec.js271
-rw-r--r--apps/files/tests/js/breadcrumbSpec.js270
-rw-r--r--apps/files/tests/js/detailsviewSpec.js234
-rw-r--r--apps/files/tests/js/favoritesfilelistspec.js108
-rw-r--r--apps/files/tests/js/favoritespluginspec.js130
-rw-r--r--apps/files/tests/js/fileUploadSpec.js218
-rw-r--r--apps/files/tests/js/fileactionsSpec.js679
-rw-r--r--apps/files/tests/js/fileactionsmenuSpec.js325
-rw-r--r--apps/files/tests/js/filelistSpec.js2608
-rw-r--r--apps/files/tests/js/filesSpec.js142
-rw-r--r--apps/files/tests/js/filesummarySpec.js184
-rw-r--r--apps/files/tests/js/mainfileinfodetailviewSpec.js252
-rw-r--r--apps/files/tests/js/newfilemenuSpec.js148
-rw-r--r--apps/files/tests/js/tagspluginspec.js142
-rw-r--r--apps/files/tests/service/tagservice.php129
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();
- }
-}
-