]> git.mxchange.org Git - friendica.git/blob - tests/src/Core/StorageManagerTest.php
Merge pull request #8122 from annando/additional
[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 class StorageManagerTest extends DatabaseTest
28 {
29         /** @var Database */
30         private $dba;
31         /** @var IConfiguration */
32         private $config;
33         /** @var LoggerInterface */
34         private $logger;
35         /** @var L10n */
36         private $l10n;
37
38         use VFSTrait;
39
40         public function setUp()
41         {
42                 parent::setUp();
43
44                 $this->setUpVfsDir();
45
46                 $this->logger = new NullLogger();
47
48                 $profiler = \Mockery::mock(Profiler::class);
49                 $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
50
51                 // load real config to avoid mocking every config-entry which is related to the Database class
52                 $configFactory = new ConfigFactory();
53                 $loader        = new ConfigFileLoader($this->root->url());
54                 $configCache   = $configFactory->createCache($loader);
55
56                 $this->dba = new StaticDatabase($configCache, $profiler, $this->logger);
57
58                 $configModel  = new Config($this->dba);
59                 $this->config = new PreloadConfiguration($configCache, $configModel);
60
61                 $this->l10n = \Mockery::mock(L10n::class);
62         }
63
64         /**
65          * Test plain instancing first
66          */
67         public function testInstance()
68         {
69                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
70
71                 $this->assertInstanceOf(StorageManager::class, $storageManager);
72         }
73
74         public function dataStorages()
75         {
76                 return [
77                         'empty'          => [
78                                 'name'        => '',
79                                 'assert'      => null,
80                                 'assertName'  => '',
81                                 'userBackend' => false,
82                         ],
83                         'database'       => [
84                                 'name'        => Storage\Database::NAME,
85                                 'assert'      => Storage\Database::class,
86                                 'assertName'  => Storage\Database::NAME,
87                                 'userBackend' => true,
88                         ],
89                         'filesystem'     => [
90                                 'name'        => Storage\Filesystem::NAME,
91                                 'assert'      => Storage\Filesystem::class,
92                                 'assertName'  => Storage\Filesystem::NAME,
93                                 'userBackend' => true,
94                         ],
95                         'systemresource' => [
96                                 'name'        => Storage\SystemResource::NAME,
97                                 'assert'      => Storage\SystemResource::class,
98                                 'assertName'  => Storage\SystemResource::NAME,
99                                 // false here, because SystemResource isn't meant to be a user backend,
100                                 // it's for system resources only
101                                 'userBackend' => false,
102                         ],
103                         'invalid'        => [
104                                 'name'        => 'invalid',
105                                 'assert'      => null,
106                                 'assertName'  => '',
107                                 'userBackend' => false,
108                         ],
109                 ];
110         }
111
112         /**
113          * Data array for legacy backends
114          *
115          * @todo 2020.09 After 2 releases, remove the legacy functionality and these data array with it
116          *
117          * @return array
118          */
119         public function dataLegacyBackends()
120         {
121                 return [
122                         'legacyDatabase'          => [
123                                 'name'        => 'Friendica\Model\Storage\Database',
124                                 'assert'      => Storage\Database::class,
125                                 'assertName'  => Storage\Database::NAME,
126                                 'userBackend' => true,
127                         ],
128                         'legacyFilesystem'       => [
129                                 'name'        => 'Friendica\Model\Storage\Filesystem',
130                                 'assert'      => Storage\Filesystem::class,
131                                 'assertName'  => Storage\Filesystem::NAME,
132                                 'userBackend' => true,
133                         ],
134                         'legacySystemResource'     => [
135                                 'name'        => 'Friendica\Model\Storage\SystemResource',
136                                 'assert'      => Storage\SystemResource::class,
137                                 'assertName'  => Storage\SystemResource::NAME,
138                                 'userBackend' => false,
139                         ],
140                 ];
141         }
142
143         /**
144          * Test the getByName() method
145          *
146          * @dataProvider dataStorages
147          * @dataProvider dataLegacyBackends
148          */
149         public function testGetByName($name, $assert, $assertName, $userBackend)
150         {
151                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
152
153                 $storage = $storageManager->getByName($name, $userBackend);
154
155                 if (!empty($assert)) {
156                         $this->assertInstanceOf(Storage\IStorage::class, $storage);
157                         $this->assertInstanceOf($assert, $storage);
158                 } else {
159                         $this->assertNull($storage);
160                 }
161                 $this->assertEquals($assertName, $storage);
162         }
163
164         /**
165          * Test the isValidBackend() method
166          *
167          * @dataProvider dataStorages
168          */
169         public function testIsValidBackend($name, $assert, $assertName, $userBackend)
170         {
171                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
172
173                 // true in every of the backends
174                 $this->assertEquals(!empty($assertName), $storageManager->isValidBackend($name));
175
176                 // if userBackend is set to true, filter out e.g. SystemRessource
177                 $this->assertEquals($userBackend, $storageManager->isValidBackend($name, true));
178         }
179
180         /**
181          * Test the method listBackends() with default setting
182          */
183         public function testListBackends()
184         {
185                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
186
187                 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
188         }
189
190         /**
191          * Test the method getBackend()
192          *
193          * @dataProvider dataStorages
194          */
195         public function testGetBackend($name, $assert, $assertName, $userBackend)
196         {
197                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
198
199                 $this->assertNull($storageManager->getBackend());
200
201                 if ($userBackend) {
202                         $storageManager->setBackend($name);
203
204                         $this->assertInstanceOf($assert, $storageManager->getBackend());
205                 }
206         }
207
208         /**
209          * Test the method getBackend() with a pre-configured backend
210          *
211          * @dataProvider dataStorages
212          * @dataProvider dataLegacyBackends
213          */
214         public function testPresetBackend($name, $assert, $assertName, $userBackend)
215         {
216                 $this->config->set('storage', 'name', $name);
217
218                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
219
220                 if ($userBackend) {
221                         $this->assertInstanceOf($assert, $storageManager->getBackend());
222                 } else {
223                         $this->assertNull($storageManager->getBackend());
224                 }
225         }
226
227         /**
228          * Tests the register and unregister methods for a new backend storage class
229          *
230          * Uses a sample storage for testing
231          *
232          * @see SampleStorageBackend
233          */
234         public function testRegisterUnregisterBackends()
235         {
236                 /// @todo Remove dice once "Hook" is dynamic and mockable
237                 $dice   = (new Dice())
238                         ->addRules(include __DIR__ . '/../../../static/dependencies.config.php')
239                         ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
240                         ->addRule(ISession::class, ['instanceOf' => Session\Memory::class, 'shared' => true, 'call' => null]);
241                 DI::init($dice);
242
243                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
244
245                 $this->assertTrue($storageManager->register(SampleStorageBackend::class));
246
247                 $this->assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
248                         SampleStorageBackend::getName() => SampleStorageBackend::class,
249                 ]), $storageManager->listBackends());
250                 $this->assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
251                         SampleStorageBackend::getName() => SampleStorageBackend::class,
252                 ]), $this->config->get('storage', 'backends'));
253
254                 // inline call to register own class as hook (testing purpose only)
255                 SampleStorageBackend::registerHook();
256                 Hook::loadHooks();
257
258                 $this->assertTrue($storageManager->setBackend(SampleStorageBackend::NAME));
259                 $this->assertEquals(SampleStorageBackend::NAME, $this->config->get('storage', 'name'));
260
261                 $this->assertInstanceOf(SampleStorageBackend::class, $storageManager->getBackend());
262
263                 $this->assertTrue($storageManager->unregister(SampleStorageBackend::class));
264                 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $this->config->get('storage', 'backends'));
265                 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
266
267                 $this->assertNull($storageManager->getBackend());
268                 $this->assertNull($this->config->get('storage', 'name'));
269         }
270
271         /**
272          * Test moving data to a new storage (currently testing db & filesystem)
273          *
274          * @dataProvider dataStorages
275          */
276         public function testMoveStorage($name, $assert, $assertName, $userBackend)
277         {
278                 if (!$userBackend) {
279                         return;
280                 }
281
282                 $this->loadFixture(__DIR__ . '/../../datasets/storage/database.fixture.php', $this->dba);
283
284                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
285                 $storage = $storageManager->getByName($name);
286                 $storageManager->move($storage);
287
288                 $photos = $this->dba->select('photo', ['backend-ref', 'backend-class', 'id', 'data']);
289
290                 while ($photo = $this->dba->fetch($photos)) {
291
292                         $this->assertEmpty($photo['data']);
293
294                         $storage = $storageManager->getByName($photo['backend-class']);
295                         $data = $storage->get($photo['backend-ref']);
296
297                         $this->assertNotEmpty($data);
298                 }
299         }
300
301         /**
302          * Test moving data to a WRONG storage
303          *
304          * @expectedException \Friendica\Model\Storage\StorageException
305          * @expectedExceptionMessage Can't move to storage backend 'SystemResource'
306          */
307         public function testMoveStorageWrong()
308         {
309                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
310                 $storage = $storageManager->getByName(Storage\SystemResource::getName());
311                 $storageManager->move($storage);
312         }
313 }