]> git.mxchange.org Git - friendica.git/blob - tests/src/Core/StorageManagerTest.php
Merge pull request #9187 from MrPetovan/bug/9182-frio-modal-width
[friendica.git] / tests / src / Core / StorageManagerTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2020, Friendica
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Test\src\Core;
23
24 use Dice\Dice;
25 use Friendica\Core\Config\IConfig;
26 use Friendica\Core\Config\PreloadConfig;
27 use Friendica\Core\Hook;
28 use Friendica\Core\L10n;
29 use Friendica\Core\Session\ISession;
30 use Friendica\Core\StorageManager;
31 use Friendica\Database\Database;
32 use Friendica\DI;
33 use Friendica\Factory\ConfigFactory;
34 use Friendica\Model\Config\Config;
35 use Friendica\Model\Storage;
36 use Friendica\Core\Session;
37 use Friendica\Test\DatabaseTest;
38 use Friendica\Test\Util\Database\StaticDatabase;
39 use Friendica\Test\Util\VFSTrait;
40 use Friendica\Util\ConfigFileLoader;
41 use Friendica\Util\Profiler;
42 use Psr\Log\LoggerInterface;
43 use Psr\Log\NullLogger;
44 use Friendica\Test\Util\SampleStorageBackend;
45
46 class StorageManagerTest extends DatabaseTest
47 {
48         /** @var Database */
49         private $dba;
50         /** @var IConfig */
51         private $config;
52         /** @var LoggerInterface */
53         private $logger;
54         /** @var L10n */
55         private $l10n;
56
57         use VFSTrait;
58
59         public function setUp()
60         {
61                 parent::setUp();
62
63                 $this->setUpVfsDir();
64
65                 $this->logger = new NullLogger();
66
67                 $profiler = \Mockery::mock(Profiler::class);
68                 $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
69
70                 // load real config to avoid mocking every config-entry which is related to the Database class
71                 $configFactory = new ConfigFactory();
72                 $loader        = new ConfigFileLoader($this->root->url());
73                 $configCache   = $configFactory->createCache($loader);
74
75                 $this->dba = new StaticDatabase($configCache, $profiler, $this->logger);
76
77                 $configModel  = new Config($this->dba);
78                 $this->config = new PreloadConfig($configCache, $configModel);
79
80                 $this->l10n = \Mockery::mock(L10n::class);
81         }
82
83         /**
84          * Test plain instancing first
85          */
86         public function testInstance()
87         {
88                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
89
90                 $this->assertInstanceOf(StorageManager::class, $storageManager);
91         }
92
93         public function dataStorages()
94         {
95                 return [
96                         'empty'          => [
97                                 'name'        => '',
98                                 'assert'      => null,
99                                 'assertName'  => '',
100                                 'userBackend' => false,
101                         ],
102                         'database'       => [
103                                 'name'        => Storage\Database::NAME,
104                                 'assert'      => Storage\Database::class,
105                                 'assertName'  => Storage\Database::NAME,
106                                 'userBackend' => true,
107                         ],
108                         'filesystem'     => [
109                                 'name'        => Storage\Filesystem::NAME,
110                                 'assert'      => Storage\Filesystem::class,
111                                 'assertName'  => Storage\Filesystem::NAME,
112                                 'userBackend' => true,
113                         ],
114                         'systemresource' => [
115                                 'name'        => Storage\SystemResource::NAME,
116                                 'assert'      => Storage\SystemResource::class,
117                                 'assertName'  => Storage\SystemResource::NAME,
118                                 // false here, because SystemResource isn't meant to be a user backend,
119                                 // it's for system resources only
120                                 'userBackend' => false,
121                         ],
122                         'invalid'        => [
123                                 'name'        => 'invalid',
124                                 'assert'      => null,
125                                 'assertName'  => '',
126                                 'userBackend' => false,
127                         ],
128                 ];
129         }
130
131         /**
132          * Data array for legacy backends
133          *
134          * @todo 2020.09 After 2 releases, remove the legacy functionality and these data array with it
135          *
136          * @return array
137          */
138         public function dataLegacyBackends()
139         {
140                 return [
141                         'legacyDatabase'          => [
142                                 'name'        => 'Friendica\Model\Storage\Database',
143                                 'assert'      => Storage\Database::class,
144                                 'assertName'  => Storage\Database::NAME,
145                                 'userBackend' => true,
146                         ],
147                         'legacyFilesystem'       => [
148                                 'name'        => 'Friendica\Model\Storage\Filesystem',
149                                 'assert'      => Storage\Filesystem::class,
150                                 'assertName'  => Storage\Filesystem::NAME,
151                                 'userBackend' => true,
152                         ],
153                         'legacySystemResource'     => [
154                                 'name'        => 'Friendica\Model\Storage\SystemResource',
155                                 'assert'      => Storage\SystemResource::class,
156                                 'assertName'  => Storage\SystemResource::NAME,
157                                 'userBackend' => false,
158                         ],
159                 ];
160         }
161
162         /**
163          * Test the getByName() method
164          *
165          * @dataProvider dataStorages
166          * @dataProvider dataLegacyBackends
167          */
168         public function testGetByName($name, $assert, $assertName, $userBackend)
169         {
170                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
171
172                 $storage = $storageManager->getByName($name, $userBackend);
173
174                 if (!empty($assert)) {
175                         $this->assertInstanceOf(Storage\IStorage::class, $storage);
176                         $this->assertInstanceOf($assert, $storage);
177                 } else {
178                         $this->assertNull($storage);
179                 }
180                 $this->assertEquals($assertName, $storage);
181         }
182
183         /**
184          * Test the isValidBackend() method
185          *
186          * @dataProvider dataStorages
187          */
188         public function testIsValidBackend($name, $assert, $assertName, $userBackend)
189         {
190                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
191
192                 // true in every of the backends
193                 $this->assertEquals(!empty($assertName), $storageManager->isValidBackend($name));
194
195                 // if userBackend is set to true, filter out e.g. SystemRessource
196                 $this->assertEquals($userBackend, $storageManager->isValidBackend($name, true));
197         }
198
199         /**
200          * Test the method listBackends() with default setting
201          */
202         public function testListBackends()
203         {
204                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
205
206                 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
207         }
208
209         /**
210          * Test the method getBackend()
211          *
212          * @dataProvider dataStorages
213          */
214         public function testGetBackend($name, $assert, $assertName, $userBackend)
215         {
216                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
217
218                 $this->assertNull($storageManager->getBackend());
219
220                 if ($userBackend) {
221                         $storageManager->setBackend($name);
222
223                         $this->assertInstanceOf($assert, $storageManager->getBackend());
224                 }
225         }
226
227         /**
228          * Test the method getBackend() with a pre-configured backend
229          *
230          * @dataProvider dataStorages
231          * @dataProvider dataLegacyBackends
232          */
233         public function testPresetBackend($name, $assert, $assertName, $userBackend)
234         {
235                 $this->config->set('storage', 'name', $name);
236
237                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
238
239                 if ($userBackend) {
240                         $this->assertInstanceOf($assert, $storageManager->getBackend());
241                 } else {
242                         $this->assertNull($storageManager->getBackend());
243                 }
244         }
245
246         /**
247          * Tests the register and unregister methods for a new backend storage class
248          *
249          * Uses a sample storage for testing
250          *
251          * @see SampleStorageBackend
252          */
253         public function testRegisterUnregisterBackends()
254         {
255                 /// @todo Remove dice once "Hook" is dynamic and mockable
256                 $dice   = (new Dice())
257                         ->addRules(include __DIR__ . '/../../../static/dependencies.config.php')
258                         ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
259                         ->addRule(ISession::class, ['instanceOf' => Session\Memory::class, 'shared' => true, 'call' => null]);
260                 DI::init($dice);
261
262                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
263
264                 $this->assertTrue($storageManager->register(SampleStorageBackend::class));
265
266                 $this->assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
267                         SampleStorageBackend::getName() => SampleStorageBackend::class,
268                 ]), $storageManager->listBackends());
269                 $this->assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
270                         SampleStorageBackend::getName() => SampleStorageBackend::class,
271                 ]), $this->config->get('storage', 'backends'));
272
273                 // inline call to register own class as hook (testing purpose only)
274                 SampleStorageBackend::registerHook();
275                 Hook::loadHooks();
276
277                 $this->assertTrue($storageManager->setBackend(SampleStorageBackend::NAME));
278                 $this->assertEquals(SampleStorageBackend::NAME, $this->config->get('storage', 'name'));
279
280                 $this->assertInstanceOf(SampleStorageBackend::class, $storageManager->getBackend());
281
282                 $this->assertTrue($storageManager->unregister(SampleStorageBackend::class));
283                 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $this->config->get('storage', 'backends'));
284                 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
285
286                 $this->assertNull($storageManager->getBackend());
287                 $this->assertNull($this->config->get('storage', 'name'));
288         }
289
290         /**
291          * Test moving data to a new storage (currently testing db & filesystem)
292          *
293          * @dataProvider dataStorages
294          */
295         public function testMoveStorage($name, $assert, $assertName, $userBackend)
296         {
297                 if (!$userBackend) {
298                         return;
299                 }
300
301                 $this->loadFixture(__DIR__ . '/../../datasets/storage/database.fixture.php', $this->dba);
302
303                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
304                 $storage = $storageManager->getByName($name);
305                 $storageManager->move($storage);
306
307                 $photos = $this->dba->select('photo', ['backend-ref', 'backend-class', 'id', 'data']);
308
309                 while ($photo = $this->dba->fetch($photos)) {
310
311                         $this->assertEmpty($photo['data']);
312
313                         $storage = $storageManager->getByName($photo['backend-class']);
314                         $data = $storage->get($photo['backend-ref']);
315
316                         $this->assertNotEmpty($data);
317                 }
318         }
319
320         /**
321          * Test moving data to a WRONG storage
322          *
323          * @expectedException \Friendica\Model\Storage\StorageException
324          * @expectedExceptionMessage Can't move to storage backend 'SystemResource'
325          */
326         public function testMoveStorageWrong()
327         {
328                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
329                 $storage = $storageManager->getByName(Storage\SystemResource::getName());
330                 $storageManager->move($storage);
331         }
332 }