]> git.mxchange.org Git - friendica.git/blob - tests/src/Core/StorageManagerTest.php
Implement Hook::callAll('storage_instance') call for addons and add a description...
[friendica.git] / tests / src / Core / StorageManagerTest.php
1 <?php
2
3 namespace Friendica\Test\src\Core;
4
5 use Dice\Dice;
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;
13 use Friendica\DI;
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;
26
27 /**
28  * @todo Rework Hook:: methods to dynamic to remove the separated process annotation
29  *
30  * @runTestsInSeparateProcesses
31  * @preserveGlobalState disabled
32  */
33 class StorageManagerTest extends DatabaseTest
34 {
35         /** @var Database */
36         private $dba;
37         /** @var IConfiguration */
38         private $config;
39         /** @var LoggerInterface */
40         private $logger;
41         /** @var L10n */
42         private $l10n;
43
44         use VFSTrait;
45
46         public function setUp()
47         {
48                 parent::setUp();
49
50                 $this->setUpVfsDir();
51
52                 $this->logger = new NullLogger();
53
54                 $profiler = \Mockery::mock(Profiler::class);
55                 $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
56
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);
61
62                 $this->dba = new StaticDatabase($configCache, $profiler, $this->logger);
63
64                 $configModel  = new Config($this->dba);
65                 $this->config = new PreloadConfiguration($configCache, $configModel);
66
67                 $this->l10n = \Mockery::mock(L10n::class);
68         }
69
70         /**
71          * Test plain instancing first
72          */
73         public function testInstance()
74         {
75                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
76
77                 $this->assertInstanceOf(StorageManager::class, $storageManager);
78         }
79
80         public function dataStorages()
81         {
82                 return [
83                         'empty'          => [
84                                 'name'        => '',
85                                 'assert'      => null,
86                                 'assertName'  => '',
87                                 'userBackend' => false,
88                         ],
89                         'database'       => [
90                                 'name'        => Storage\Database::NAME,
91                                 'assert'      => Storage\Database::class,
92                                 'assertName'  => Storage\Database::NAME,
93                                 'userBackend' => true,
94                         ],
95                         'filesystem'     => [
96                                 'name'        => Storage\Filesystem::NAME,
97                                 'assert'      => Storage\Filesystem::class,
98                                 'assertName'  => Storage\Filesystem::NAME,
99                                 'userBackend' => true,
100                         ],
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,
108                         ],
109                         'invalid'        => [
110                                 'name'        => 'invalid',
111                                 'assert'      => null,
112                                 'assertName'  => '',
113                                 'userBackend' => false,
114                         ],
115                 ];
116         }
117
118         /**
119          * Test the getByName() method
120          *
121          * @dataProvider dataStorages
122          */
123         public function testGetByName($name, $assert, $assertName, $userBackend)
124         {
125                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
126
127                 $storage = $storageManager->getByName($name, $userBackend);
128
129                 if (!empty($assert)) {
130                         $this->assertInstanceOf(Storage\IStorage::class, $storage);
131                         $this->assertInstanceOf($assert, $storage);
132                         $this->assertEquals($name, $storage::getName());
133                 } else {
134                         $this->assertNull($storage);
135                 }
136                 $this->assertEquals($assertName, $storage);
137         }
138
139         /**
140          * Test the isValidBackend() method
141          *
142          * @dataProvider dataStorages
143          */
144         public function testIsValidBackend($name, $assert, $assertName, $userBackend)
145         {
146                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
147
148                 $this->assertEquals($userBackend, $storageManager->isValidBackend($name));
149         }
150
151         /**
152          * Test the method listBackends() with default setting
153          */
154         public function testListBackends()
155         {
156                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
157
158                 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
159         }
160
161         /**
162          * Test the method getBackend()
163          *
164          * @dataProvider dataStorages
165          */
166         public function testGetBackend($name, $assert, $assertName, $userBackend)
167         {
168                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
169
170                 $this->assertNull($storageManager->getBackend());
171
172                 if ($userBackend) {
173                         $storageManager->setBackend($name);
174
175                         $this->assertInstanceOf($assert, $storageManager->getBackend());
176                 }
177         }
178
179         /**
180          * Test the method getBackend() with a pre-configured backend
181          *
182          * @dataProvider dataStorages
183          */
184         public function testPresetBackend($name, $assert, $assertName, $userBackend)
185         {
186                 $this->config->set('storage', 'name', $name);
187
188                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
189
190                 if ($userBackend) {
191                         $this->assertInstanceOf($assert, $storageManager->getBackend());
192                 } else {
193                         $this->assertNull($storageManager->getBackend());
194                 }
195         }
196
197         /**
198          * Tests the register and unregister methods for a new backend storage class
199          *
200          * Uses a sample storage for testing
201          *
202          * @see SampleStorageBackend
203          */
204         public function testRegisterUnregisterBackends()
205         {
206                 /// @todo Remove dice once "Hook" is dynamic and mockable
207                 $dice   = (new Dice())
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]);
211                 DI::init($dice);
212
213                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
214
215                 $this->assertTrue($storageManager->register(SampleStorageBackend::class));
216
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'));
223
224                 // inline call to register own class as hook (testing purpose only)
225                 SampleStorageBackend::registerHook();
226                 Hook::loadHooks();
227
228                 $this->assertTrue($storageManager->setBackend(SampleStorageBackend::NAME));
229                 $this->assertEquals(SampleStorageBackend::NAME, $this->config->get('storage', 'name'));
230
231                 $this->assertInstanceOf(SampleStorageBackend::class, $storageManager->getBackend());
232
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());
236
237                 $this->assertNull($storageManager->getBackend());
238                 $this->assertNull($this->config->get('storage', 'name'));
239         }
240
241         /**
242          * Test moving data to a new storage (currently testing db & filesystem)
243          *
244          * @dataProvider dataStorages
245          */
246         public function testMoveStorage($name, $assert, $assertName, $userBackend)
247         {
248                 if (!$userBackend) {
249                         return;
250                 }
251
252                 $this->loadFixture(__DIR__ . '/../../datasets/storage/database.fixture.php', $this->dba);
253
254                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
255                 $storage = $storageManager->getByName($name);
256                 $storageManager->move($storage);
257
258                 $photos = $this->dba->select('photo', ['backend-ref', 'backend-class', 'id', 'data']);
259
260                 while ($photo = $this->dba->fetch($photos)) {
261
262                         $this->assertEmpty($photo['data']);
263
264                         $storage = $storageManager->getByName($photo['backend-class']);
265                         $data = $storage->get($photo['backend-ref']);
266
267                         $this->assertNotEmpty($data);
268                 }
269         }
270 }