3 namespace Friendica\Test\src\Core;
6 use Friendica\Core\Config\IConfiguration;
7 use Friendica\Core\Config\PreloadConfiguration;
8 use Friendica\Core\Hook;
9 use Friendica\Core\L10n\L10n;
10 use Friendica\Core\Session\ISession;
11 use Friendica\Core\StorageManager;
12 use Friendica\Database\Database;
14 use Friendica\Factory\ConfigFactory;
15 use Friendica\Model\Config\Config;
16 use Friendica\Model\Storage;
17 use Friendica\Core\Session;
18 use Friendica\Test\DatabaseTest;
19 use Friendica\Test\Util\Database\StaticDatabase;
20 use Friendica\Test\Util\VFSTrait;
21 use Friendica\Util\ConfigFileLoader;
22 use Friendica\Util\Profiler;
23 use Psr\Log\LoggerInterface;
24 use Psr\Log\NullLogger;
25 use Friendica\Test\Util\SampleStorageBackend;
28 * @todo Rework Hook:: methods to dynamic to remove the separated process annotation
30 * @runTestsInSeparateProcesses
31 * @preserveGlobalState disabled
33 class StorageManagerTest extends DatabaseTest
37 /** @var IConfiguration */
39 /** @var LoggerInterface */
46 public function setUp()
52 $this->logger = new NullLogger();
54 $profiler = \Mockery::mock(Profiler::class);
55 $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
57 // load real config to avoid mocking every config-entry which is related to the Database class
58 $configFactory = new ConfigFactory();
59 $loader = new ConfigFileLoader($this->root->url());
60 $configCache = $configFactory->createCache($loader);
62 $this->dba = new StaticDatabase($configCache, $profiler, $this->logger);
64 $configModel = new Config($this->dba);
65 $this->config = new PreloadConfiguration($configCache, $configModel);
67 $this->l10n = \Mockery::mock(L10n::class);
71 * Test plain instancing first
73 public function testInstance()
75 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
77 $this->assertInstanceOf(StorageManager::class, $storageManager);
80 public function dataStorages()
87 'userBackend' => false,
90 'name' => Storage\Database::NAME,
91 'assert' => Storage\Database::class,
92 'assertName' => Storage\Database::NAME,
93 'userBackend' => true,
96 'name' => Storage\Filesystem::NAME,
97 'assert' => Storage\Filesystem::class,
98 'assertName' => Storage\Filesystem::NAME,
99 'userBackend' => true,
101 'systemresource' => [
102 'name' => Storage\SystemResource::NAME,
103 'assert' => Storage\SystemResource::class,
104 'assertName' => Storage\SystemResource::NAME,
105 // false here, because SystemResource isn't meant to be a user backend,
106 // it's for system resources only
107 'userBackend' => false,
113 'userBackend' => false,
119 * Test the getByName() method
121 * @dataProvider dataStorages
123 public function testGetByName($name, $assert, $assertName, $userBackend)
125 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
127 $storage = $storageManager->getByName($name, $userBackend);
129 if (!empty($assert)) {
130 $this->assertInstanceOf(Storage\IStorage::class, $storage);
131 $this->assertInstanceOf($assert, $storage);
132 $this->assertEquals($name, $storage::getName());
134 $this->assertNull($storage);
136 $this->assertEquals($assertName, $storage);
140 * Test the isValidBackend() method
142 * @dataProvider dataStorages
144 public function testIsValidBackend($name, $assert, $assertName, $userBackend)
146 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
148 $this->assertEquals($userBackend, $storageManager->isValidBackend($name));
152 * Test the method listBackends() with default setting
154 public function testListBackends()
156 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
158 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
162 * Test the method getBackend()
164 * @dataProvider dataStorages
166 public function testGetBackend($name, $assert, $assertName, $userBackend)
168 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
170 $this->assertNull($storageManager->getBackend());
173 $storageManager->setBackend($name);
175 $this->assertInstanceOf($assert, $storageManager->getBackend());
180 * Test the method getBackend() with a pre-configured backend
182 * @dataProvider dataStorages
184 public function testPresetBackend($name, $assert, $assertName, $userBackend)
186 $this->config->set('storage', 'name', $name);
188 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
191 $this->assertInstanceOf($assert, $storageManager->getBackend());
193 $this->assertNull($storageManager->getBackend());
198 * Tests the register and unregister methods for a new backend storage class
200 * Uses a sample storage for testing
202 * @see SampleStorageBackend
204 public function testRegisterUnregisterBackends()
206 /// @todo Remove dice once "Hook" is dynamic and mockable
208 ->addRules(include __DIR__ . '/../../../static/dependencies.config.php')
209 ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
210 ->addRule(ISession::class, ['instanceOf' => Session\Memory::class, 'shared' => true, 'call' => null]);
213 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
215 $this->assertTrue($storageManager->register(SampleStorageBackend::class));
217 $this->assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
218 SampleStorageBackend::getName() => SampleStorageBackend::class,
219 ]), $storageManager->listBackends());
220 $this->assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
221 SampleStorageBackend::getName() => SampleStorageBackend::class,
222 ]), $this->config->get('storage', 'backends'));
224 // inline call to register own class as hook (testing purpose only)
225 SampleStorageBackend::registerHook();
228 $this->assertTrue($storageManager->setBackend(SampleStorageBackend::NAME));
229 $this->assertEquals(SampleStorageBackend::NAME, $this->config->get('storage', 'name'));
231 $this->assertInstanceOf(SampleStorageBackend::class, $storageManager->getBackend());
233 $this->assertTrue($storageManager->unregister(SampleStorageBackend::class));
234 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $this->config->get('storage', 'backends'));
235 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
237 $this->assertNull($storageManager->getBackend());
238 $this->assertNull($this->config->get('storage', 'name'));
242 * Test moving data to a new storage (currently testing db & filesystem)
244 * @dataProvider dataStorages
246 public function testMoveStorage($name, $assert, $assertName, $userBackend)
252 $this->loadFixture(__DIR__ . '/../../datasets/storage/database.fixture.php', $this->dba);
254 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
255 $storage = $storageManager->getByName($name);
256 $storageManager->move($storage);
258 $photos = $this->dba->select('photo', ['backend-ref', 'backend-class', 'id', 'data']);
260 while ($photo = $this->dba->fetch($photos)) {
262 $this->assertEmpty($photo['data']);
264 $storage = $storageManager->getByName($photo['backend-class']);
265 $data = $storage->get($photo['backend-ref']);
267 $this->assertNotEmpty($data);