Split Storage usage and Storage configuration
authorPhilipp <admin@philipp.info>
Mon, 4 Oct 2021 08:25:29 +0000 (10:25 +0200)
committerPhilipp <admin@philipp.info>
Tue, 5 Oct 2021 18:07:12 +0000 (20:07 +0200)
12 files changed:
src/Core/StorageManager.php
src/Model/Storage/Database.php
src/Model/Storage/Filesystem.php
src/Model/Storage/FilesystemConfig.php [new file with mode: 0644]
src/Model/Storage/IStorageConfiguration.php [new file with mode: 0644]
src/Model/Storage/IWritableStorage.php
src/Module/Admin/Storage.php
tests/src/Model/Storage/DatabaseStorageTest.php
tests/src/Model/Storage/FilesystemStorageConfigTest.php [new file with mode: 0644]
tests/src/Model/Storage/FilesystemStorageTest.php
tests/src/Model/Storage/StorageConfigTest.php [new file with mode: 0644]
tests/src/Model/Storage/StorageTest.php

index f206868885e66acec7d99c2383c2f885d4eb1609..61dd8d375d6659e46102feeec142f4e084da4f19 100644 (file)
@@ -119,6 +119,43 @@ class StorageManager
                return $storage;
        }
 
+       /**
+        * Return storage backend configuration by registered name
+        *
+        * @param string     $name Backend name
+        *
+        * @return Storage\IStorageConfiguration|false
+        *
+        * @throws Storage\InvalidClassStorageException in case there's no backend class for the name
+        * @throws Storage\StorageException in case of an unexpected failure during the hook call
+        */
+       public function getConfigurationByName(string $name)
+       {
+               switch ($name) {
+                       // Try the filesystem backend
+                       case Storage\Filesystem::getName():
+                               return new Storage\FilesystemConfig($this->config, $this->l10n);
+                       // try the database backend
+                       case Storage\Database::getName():
+                               return false;
+                       default:
+                               $data = [
+                                       'name'           => $name,
+                                       'storage_config' => null,
+                               ];
+                               try {
+                                       Hook::callAll('storage_config', $data);
+                                       if (!($data['storage_config'] ?? null) instanceof Storage\IStorageConfiguration) {
+                                               throw new Storage\InvalidClassStorageException(sprintf('Configuration for backend %s was not found', $name));
+                                       }
+
+                                       return $data['storage_config'];
+                               } catch (InternalServerErrorException $exception) {
+                                       throw new Storage\StorageException(sprintf('Failed calling hook::storage_config for backend %s', $name), $exception);
+                               }
+               }
+       }
+
        /**
         * Return storage backend class by registered name
         *
@@ -142,7 +179,8 @@ class StorageManager
                        switch ($name) {
                                // Try the filesystem backend
                                case Storage\Filesystem::getName():
-                                       $this->backendInstances[$name] = new Storage\Filesystem($this->config, $this->l10n);
+                                       $storageConfig                 = new Storage\FilesystemConfig($this->config, $this->l10n);
+                                       $this->backendInstances[$name] = new Storage\Filesystem($storageConfig->getStoragePath());
                                        break;
                                // try the database backend
                                case Storage\Database::getName():
index 3457fa4a3045c07099c4888a7f11a4034525d1fc..7b90d878909221d8f2ac59d48e990c8cd0f51f08 100644 (file)
@@ -113,22 +113,6 @@ class Database implements IWritableStorage
                }
        }
 
-       /**
-        * @inheritDoc
-        */
-       public function getOptions(): array
-       {
-               return [];
-       }
-
-       /**
-        * @inheritDoc
-        */
-       public function saveOptions(array $data): array
-       {
-               return [];
-       }
-
        /**
         * @inheritDoc
         */
index c6c939bd464353154eab1193916cdd2c79ecb1d9..5a4ea1f0d3d8f76e31d45f653289958ce7b7c2eb 100644 (file)
@@ -22,8 +22,6 @@
 namespace Friendica\Model\Storage;
 
 use Exception;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\L10n;
 use Friendica\Util\Strings;
 
 /**
@@ -40,30 +38,17 @@ class Filesystem implements IWritableStorage
 {
        const NAME = 'Filesystem';
 
-       // Default base folder
-       const DEFAULT_BASE_FOLDER = 'storage';
-
-       /** @var IConfig */
-       private $config;
-
        /** @var string */
        private $basePath;
 
-       /** @var L10n */
-       private $l10n;
-
        /**
         * Filesystem constructor.
         *
-        * @param IConfig         $config
-        * @param L10n            $l10n
+        * @param string $filesystemPath
         */
-       public function __construct(IConfig $config, L10n $l10n)
+       public function __construct(string $filesystemPath = FilesystemConfig::DEFAULT_BASE_FOLDER)
        {
-               $this->config = $config;
-               $this->l10n   = $l10n;
-
-               $path           = $this->config->get('storage', 'filesystem_path', self::DEFAULT_BASE_FOLDER);
+               $path           = $filesystemPath;
                $this->basePath = rtrim($path, '/');
        }
 
@@ -176,37 +161,6 @@ class Filesystem implements IWritableStorage
                }
        }
 
-       /**
-        * @inheritDoc
-        */
-       public function getOptions(): array
-       {
-               return [
-                       'storagepath' => [
-                               'input',
-                               $this->l10n->t('Storage base path'),
-                               $this->basePath,
-                               $this->l10n->t('Folder where uploaded files are saved. For maximum security, This should be a path outside web server folder tree')
-                       ]
-               ];
-       }
-
-       /**
-        * @inheritDoc
-        */
-       public function saveOptions(array $data): array
-       {
-               $storagePath = $data['storagepath'] ?? '';
-               if ($storagePath === '' || !is_dir($storagePath)) {
-                       return [
-                               'storagepath' => $this->l10n->t('Enter a valid existing folder')
-                       ];
-               };
-               $this->config->set('storage', 'filesystem_path', $storagePath);
-               $this->basePath = $storagePath;
-               return [];
-       }
-
        /**
         * @inheritDoc
         */
diff --git a/src/Model/Storage/FilesystemConfig.php b/src/Model/Storage/FilesystemConfig.php
new file mode 100644 (file)
index 0000000..735808e
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Model\Storage;
+
+use Friendica\Core\Config\IConfig;
+use Friendica\Core\L10n;
+
+/**
+ * Filesystem based storage backend configuration
+ */
+class FilesystemConfig implements IStorageConfiguration
+{
+       // Default base folder
+       const DEFAULT_BASE_FOLDER = 'storage';
+
+       /** @var IConfig */
+       private $config;
+
+       /** @var string */
+       private $storagePath;
+
+       /** @var L10n */
+       private $l10n;
+
+       /**
+        * Returns the current storage path
+        *
+        * @return string
+        */
+       public function getStoragePath(): string
+       {
+               return $this->storagePath;
+       }
+
+       /**
+        * Filesystem constructor.
+        *
+        * @param IConfig         $config
+        * @param L10n            $l10n
+        */
+       public function __construct(IConfig $config, L10n $l10n)
+       {
+               $this->config = $config;
+               $this->l10n   = $l10n;
+
+               $path              = $this->config->get('storage', 'filesystem_path', self::DEFAULT_BASE_FOLDER);
+               $this->storagePath = rtrim($path, '/');
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function getOptions(): array
+       {
+               return [
+                       'storagepath' => [
+                               'input',
+                               $this->l10n->t('Storage base path'),
+                               $this->storagePath,
+                               $this->l10n->t('Folder where uploaded files are saved. For maximum security, This should be a path outside web server folder tree')
+                       ]
+               ];
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function saveOptions(array $data): array
+       {
+               $storagePath = $data['storagepath'] ?? '';
+               if ($storagePath === '' || !is_dir($storagePath)) {
+                       return [
+                               'storagepath' => $this->l10n->t('Enter a valid existing folder')
+                       ];
+               };
+               $this->config->set('storage', 'filesystem_path', $storagePath);
+               $this->storagePath = $storagePath;
+               return [];
+       }
+}
diff --git a/src/Model/Storage/IStorageConfiguration.php b/src/Model/Storage/IStorageConfiguration.php
new file mode 100644 (file)
index 0000000..c589f5e
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Model\Storage;
+
+/**
+ * The interface to use for configurable storage backends
+ */
+interface IStorageConfiguration
+{
+       /**
+        * Get info about storage options
+        *
+        * @return array
+        *
+        * This method return an array with information about storage options
+        * from which the form presented to the user is build.
+        *
+        * The returned array is:
+        *
+        *    [
+        *      'option1name' => [ ..info.. ],
+        *      'option2name' => [ ..info.. ],
+        *      ...
+        *    ]
+        *
+        * An empty array can be returned if backend doesn't have any options
+        *
+        * The info array for each option MUST be as follows:
+        *
+        *    [
+        *      'type',      // define the field used in form, and the type of data.
+        *                   // one of 'checkbox', 'combobox', 'custom', 'datetime',
+        *                   // 'input', 'intcheckbox', 'password', 'radio', 'richtext'
+        *                   // 'select', 'select_raw', 'textarea'
+        *
+        *      'label',     // Translatable label of the field
+        *      'value',     // Current value
+        *      'help text', // Translatable description for the field
+        *      extra data   // Optional. Depends on 'type':
+        *                   // select: array [ value => label ] of choices
+        *                   // intcheckbox: value of input element
+        *                   // select_raw: prebuild html string of < option > tags
+        *    ]
+        *
+        * See https://github.com/friendica/friendica/wiki/Quick-Template-Guide
+        */
+       public function getOptions(): array;
+
+       /**
+        * Validate and save options
+        *
+        * @param array $data Array [optionname => value] to be saved
+        *
+        * @return array  Validation errors: [optionname => error message]
+        *
+        * Return array must be empty if no error.
+        */
+       public function saveOptions(array $data): array;
+}
index ee0001a669dfa3cf8b150c0c54169ef01eb969a9..118f4b25619f36304e56a5d8e63fdb882ffd4393 100644 (file)
@@ -50,54 +50,4 @@ interface IWritableStorage extends IStorage
         * @throws ReferenceStorageException in case the reference doesn't exist
         */
        public function delete(string $reference);
-
-       /**
-        * Get info about storage options
-        *
-        * @return array
-        *
-        * This method return an array with informations about storage options
-        * from which the form presented to the user is build.
-        *
-        * The returned array is:
-        *
-        *    [
-        *      'option1name' => [ ..info.. ],
-        *      'option2name' => [ ..info.. ],
-        *      ...
-        *    ]
-        *
-        * An empty array can be returned if backend doesn't have any options
-        *
-        * The info array for each option MUST be as follows:
-        *
-        *    [
-        *      'type',      // define the field used in form, and the type of data.
-        *                   // one of 'checkbox', 'combobox', 'custom', 'datetime',
-        *                   // 'input', 'intcheckbox', 'password', 'radio', 'richtext'
-        *                   // 'select', 'select_raw', 'textarea'
-        *
-        *      'label',     // Translatable label of the field
-        *      'value',     // Current value
-        *      'help text', // Translatable description for the field
-        *      extra data   // Optional. Depends on 'type':
-        *                   // select: array [ value => label ] of choices
-        *                   // intcheckbox: value of input element
-        *                   // select_raw: prebuild html string of < option > tags
-        *    ]
-        *
-        * See https://github.com/friendica/friendica/wiki/Quick-Template-Guide
-        */
-       public function getOptions(): array;
-
-       /**
-        * Validate and save options
-        *
-        * @param array $data Array [optionname => value] to be saved
-        *
-        * @return array  Validation errors: [optionname => error message]
-        *
-        * Return array must be empty if no error.
-        */
-       public function saveOptions(array $data): array;
 }
index c6bc3878efdf41d40d672d5511487b28574ec598..6b22d905cf2474cbb6f48f17a7f32aa238099d59 100644 (file)
@@ -24,6 +24,7 @@ namespace Friendica\Module\Admin;
 use Friendica\Core\Renderer;
 use Friendica\DI;
 use Friendica\Model\Storage\InvalidClassStorageException;
+use Friendica\Model\Storage\IStorageConfiguration;
 use Friendica\Model\Storage\IWritableStorage;
 use Friendica\Module\BaseAdmin;
 use Friendica\Util\Strings;
@@ -39,38 +40,40 @@ class Storage extends BaseAdmin
                $storagebackend = Strings::escapeTags(trim($parameters['name'] ?? ''));
 
                try {
-                       /** @var IWritableStorage $newstorage */
-                       $newstorage = DI::storageManager()->getWritableStorageByName($storagebackend);
+                       /** @var IStorageConfiguration|false $newStorageConfig */
+                       $newStorageConfig = DI::storageManager()->getConfigurationByName($storagebackend);
                } catch (InvalidClassStorageException $storageException) {
                        notice(DI::l10n()->t('Storage backend, %s is invalid.', $storagebackend));
                        DI::baseUrl()->redirect('admin/storage');
                }
 
-               // save storage backend form
-               $storage_opts        = $newstorage->getOptions();
-               $storage_form_prefix = preg_replace('|[^a-zA-Z0-9]|', '', $storagebackend);
-               $storage_opts_data   = [];
-               foreach ($storage_opts as $name => $info) {
-                       $fieldname = $storage_form_prefix . '_' . $name;
-                       switch ($info[0]) { // type
-                               case 'checkbox':
-                               case 'yesno':
-                                       $value = !empty($_POST[$fieldname]);
-                                       break;
-                               default:
-                                       $value = $_POST[$fieldname] ?? '';
+               if ($newStorageConfig !== false) {
+                       // save storage backend form
+                       $storage_opts        = $newStorageConfig->getOptions();
+                       $storage_form_prefix = preg_replace('|[^a-zA-Z0-9]|', '', $storagebackend);
+                       $storage_opts_data   = [];
+                       foreach ($storage_opts as $name => $info) {
+                               $fieldname = $storage_form_prefix . '_' . $name;
+                               switch ($info[0]) { // type
+                                       case 'checkbox':
+                                       case 'yesno':
+                                               $value = !empty($_POST[$fieldname]);
+                                               break;
+                                       default:
+                                               $value = $_POST[$fieldname] ?? '';
+                               }
+                               $storage_opts_data[$name] = $value;
                        }
-                       $storage_opts_data[$name] = $value;
-               }
-               unset($name);
-               unset($info);
+                       unset($name);
+                       unset($info);
 
-               $storage_form_errors = $newstorage->saveOptions($storage_opts_data);
-               if (count($storage_form_errors)) {
-                       foreach ($storage_form_errors as $name => $err) {
-                               notice(DI::l10n()->t('Storage backend %s error: %s', $storage_opts[$name][1], $err));
+                       $storage_form_errors = $newStorageConfig->saveOptions($storage_opts_data);
+                       if (count($storage_form_errors)) {
+                               foreach ($storage_form_errors as $name => $err) {
+                                       notice(DI::l10n()->t('Storage backend %s error: %s', $storage_opts[$name][1], $err));
+                               }
+                               DI::baseUrl()->redirect('admin/storage');
                        }
-                       DI::baseUrl()->redirect('admin/storage');
                }
 
                if (!empty($_POST['submit_save_set'])) {
@@ -101,20 +104,25 @@ class Storage extends BaseAdmin
                        // build storage config form,
                        $storage_form_prefix = preg_replace('|[^a-zA-Z0-9]|', '', $name);
 
-                       $storage_form = [];
-                       foreach (DI::storageManager()->getWritableStorageByName($name)->getOptions() as $option => $info) {
-                               $type = $info[0];
-                               // Backward compatibilty with yesno field description
-                               if ($type == 'yesno') {
-                                       $type = 'checkbox';
-                                       // Remove translated labels Yes No from field info
-                                       unset($info[4]);
-                               }
+                       $storage_form  = [];
+                       $storageConfig = DI::storageManager()->getConfigurationByName($name);
+
+                       if ($storageConfig !== false) {
+                               foreach ($storageConfig->getOptions() as $option => $info) {
 
-                               $info[0]               = $storage_form_prefix . '_' . $option;
-                               $info['type']          = $type;
-                               $info['field']         = 'field_' . $type . '.tpl';
-                               $storage_form[$option] = $info;
+                                       $type = $info[0];
+                                       // Backward compatibilty with yesno field description
+                                       if ($type == 'yesno') {
+                                               $type = 'checkbox';
+                                               // Remove translated labels Yes No from field info
+                                               unset($info[4]);
+                                       }
+
+                                       $info[0]               = $storage_form_prefix . '_' . $option;
+                                       $info['type']          = $type;
+                                       $info['field']         = 'field_' . $type . '.tpl';
+                                       $storage_form[$option] = $info;
+                               }
                        }
 
                        $available_storage_forms[] = [
index aa25d1cc7f994360bebe4e49ae9fb4501fae1617..e1dfef9a18a4f114aabeedb1a3ea6ed0c2fe8edd 100644 (file)
@@ -23,11 +23,9 @@ namespace Friendica\Test\src\Model\Storage;
 
 use Friendica\Factory\ConfigFactory;
 use Friendica\Model\Storage\Database;
-use Friendica\Model\Storage\IWritableStorage;
 use Friendica\Test\DatabaseTestTrait;
 use Friendica\Test\Util\Database\StaticDatabase;
 use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\ConfigFileLoader;
 use Friendica\Util\Profiler;
 use Psr\Log\NullLogger;
 
@@ -47,7 +45,7 @@ class DatabaseStorageTest extends StorageTest
 
        protected function getInstance()
        {
-               $logger = new NullLogger();
+               $logger   = new NullLogger();
                $profiler = \Mockery::mock(Profiler::class);
                $profiler->shouldReceive('startRecording');
                $profiler->shouldReceive('stopRecording');
@@ -55,19 +53,14 @@ class DatabaseStorageTest extends StorageTest
 
                // load real config to avoid mocking every config-entry which is related to the Database class
                $configFactory = new ConfigFactory();
-               $loader = (new ConfigFactory())->createConfigFileLoader($this->root->url(), []);
-               $configCache = $configFactory->createCache($loader);
+               $loader        = (new ConfigFactory())->createConfigFileLoader($this->root->url(), []);
+               $configCache   = $configFactory->createCache($loader);
 
                $dba = new StaticDatabase($configCache, $profiler, $logger);
 
                return new Database($dba);
        }
 
-       protected function assertOption(IWritableStorage $storage)
-       {
-               self::assertEmpty($storage->getOptions());
-       }
-
        protected function tearDown(): void
        {
                $this->tearDownDb();
diff --git a/tests/src/Model/Storage/FilesystemStorageConfigTest.php b/tests/src/Model/Storage/FilesystemStorageConfigTest.php
new file mode 100644 (file)
index 0000000..5821309
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Test\src\Model\Storage;
+
+use Friendica\Core\Config\IConfig;
+use Friendica\Core\L10n;
+use Friendica\Model\Storage\FilesystemConfig;
+use Friendica\Model\Storage\IStorageConfiguration;
+use Friendica\Test\Util\VFSTrait;
+use Mockery\MockInterface;
+use org\bovigo\vfs\vfsStream;
+
+class FilesystemStorageConfigTest extends StorageConfigTest
+{
+       use VFSTrait;
+
+       protected function setUp(): void
+       {
+               $this->setUpVfsDir();
+
+               vfsStream::create(['storage' => []], $this->root);
+
+               parent::setUp();
+       }
+
+       protected function getInstance()
+       {
+               /** @var MockInterface|L10n $l10n */
+               $l10n   = \Mockery::mock(L10n::class)->makePartial();
+               $config = \Mockery::mock(IConfig::class);
+               $config->shouldReceive('get')
+                                        ->with('storage', 'filesystem_path', FilesystemConfig::DEFAULT_BASE_FOLDER)
+                                        ->andReturn($this->root->getChild('storage')->url());
+
+               return new FilesystemConfig($config, $l10n);
+       }
+
+       protected function assertOption(IStorageConfiguration $storage)
+       {
+               self::assertEquals([
+                       'storagepath' => [
+                               'input', 'Storage base path',
+                               $this->root->getChild('storage')->url(),
+                               'Folder where uploaded files are saved. For maximum security, This should be a path outside web server folder tree'
+                       ]
+               ], $storage->getOptions());
+       }
+}
index 45a72641630f8af4ac4fbdf2174fd93ff4705ac9..d3204c682979caf8ff021e0a885f5dd0711a5167 100644 (file)
 
 namespace Friendica\Test\src\Model\Storage;
 
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\L10n;
 use Friendica\Model\Storage\Filesystem;
-use Friendica\Model\Storage\IWritableStorage;
 use Friendica\Model\Storage\StorageException;
 use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\Profiler;
-use Mockery\MockInterface;
 use org\bovigo\vfs\vfsStream;
 
 class FilesystemStorageTest extends StorageTest
 {
        use VFSTrait;
 
-       /** @var MockInterface|IConfig */
-       protected $config;
-
        protected function setUp(): void
        {
                $this->setUpVfsDir();
@@ -49,30 +41,7 @@ class FilesystemStorageTest extends StorageTest
 
        protected function getInstance()
        {
-               $profiler = \Mockery::mock(Profiler::class);
-               $profiler->shouldReceive('startRecording');
-               $profiler->shouldReceive('stopRecording');
-               $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
-
-               /** @var MockInterface|L10n $l10n */
-               $l10n = \Mockery::mock(L10n::class)->makePartial();
-               $this->config = \Mockery::mock(IConfig::class);
-               $this->config->shouldReceive('get')
-                            ->with('storage', 'filesystem_path', Filesystem::DEFAULT_BASE_FOLDER)
-                            ->andReturn($this->root->getChild('storage')->url());
-
-               return new Filesystem($this->config, $l10n);
-       }
-
-       protected function assertOption(IWritableStorage $storage)
-       {
-               self::assertEquals([
-                       'storagepath' => [
-                               'input', 'Storage base path',
-                               $this->root->getChild('storage')->url(),
-                               'Folder where uploaded files are saved. For maximum security, This should be a path outside web server folder tree'
-                       ]
-               ], $storage->getOptions());
+               return new Filesystem($this->root->getChild('storage')->url());
        }
 
        /**
@@ -116,7 +85,7 @@ class FilesystemStorageTest extends StorageTest
 
                $instance->put('test', 'f0c0d0i0');
 
-               $dir = $this->root->getChild('storage/f0/c0')->url();
+               $dir  = $this->root->getChild('storage/f0/c0')->url();
                $file = $this->root->getChild('storage/f0/c0/d0i0')->url();
 
                self::assertDirectoryExists($dir);
diff --git a/tests/src/Model/Storage/StorageConfigTest.php b/tests/src/Model/Storage/StorageConfigTest.php
new file mode 100644 (file)
index 0000000..80cbbae
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Test\src\Model\Storage;
+
+use Friendica\Model\Storage\IStorageConfiguration;
+use Friendica\Test\MockedTest;
+
+abstract class StorageConfigTest extends MockedTest
+{
+       /** @return IStorageConfiguration */
+       abstract protected function getInstance();
+
+       abstract protected function assertOption(IStorageConfiguration $storage);
+
+       /**
+        * Test if the "getOption" is asserted
+        */
+       public function testGetOptions()
+       {
+               $instance = $this->getInstance();
+
+               $this->assertOption($instance);
+       }
+}
index 340aee8bfd45f9e6dcc6257f493067a8c5dab633..7433747575edf0c73d530064d41bab301df577b7 100644 (file)
@@ -31,8 +31,6 @@ abstract class StorageTest extends MockedTest
        /** @return IWritableStorage */
        abstract protected function getInstance();
 
-       abstract protected function assertOption(IWritableStorage $storage);
-
        /**
         * Test if the instance is "really" implementing the interface
         */
@@ -42,16 +40,6 @@ abstract class StorageTest extends MockedTest
                self::assertInstanceOf(IStorage::class, $instance);
        }
 
-       /**
-        * Test if the "getOption" is asserted
-        */
-       public function testGetOptions()
-       {
-               $instance = $this->getInstance();
-
-               $this->assertOption($instance);
-       }
-
        /**
         * Test basic put, get and delete operations
         */