]> git.mxchange.org Git - friendica.git/blob - tests/src/Core/PConfig/PConfigTest.php
Merge pull request #11087 from nupplaphil/feat/tests_adaption
[friendica.git] / tests / src / Core / PConfig / PConfigTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2021, the Friendica project
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\PConfig;
23
24 use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
25 use Friendica\Core\PConfig\Type\AbstractPConfigValues;
26 use Friendica\Core\PConfig\Repository\PConfig as PConfigModel;
27 use Friendica\Core\PConfig\ValueObject\Cache;
28 use Friendica\Test\MockedTest;
29 use Mockery;
30 use Mockery\MockInterface;
31
32 abstract class PConfigTest extends MockedTest
33 {
34         use ArraySubsetAsserts;
35
36         /** @var PConfigModel|MockInterface */
37         protected $configModel;
38
39         /** @var Cache */
40         protected $configCache;
41
42         /** @var AbstractPConfigValues */
43         protected $testedConfig;
44
45         /**
46          * Assert a config tree
47          *
48          * @param int    $uid  The uid to assert
49          * @param string $cat  The category to assert
50          * @param array  $data The result data array
51          */
52         protected function assertConfig(int $uid, string $cat, array $data)
53         {
54                 $result = $this->testedConfig->getCache()->getAll();
55
56                 self::assertNotEmpty($result);
57                 self::assertArrayHasKey($uid, $result);
58                 self::assertArrayHasKey($cat, $result[$uid]);
59                 self::assertArraySubset($data, $result[$uid][$cat]);
60         }
61
62
63         protected function setUp(): void
64         {
65                 parent::setUp();
66
67                 // Create the config model
68                 $this->configModel = Mockery::mock(PConfigModel::class);
69                 $this->configCache = new Cache();
70         }
71
72         /**
73          * @return \Friendica\Core\PConfig\Type\AbstractPConfigValues
74          */
75         abstract public function getInstance();
76
77         public function dataTests()
78         {
79                 return [
80                         'string'       => ['uid' => 1, 'data' => 'it'],
81                         'boolTrue'     => ['uid' => 2, 'data' => true],
82                         'boolFalse'    => ['uid' => 3, 'data' => false],
83                         'integer'      => ['uid' => 4, 'data' => 235],
84                         'decimal'      => ['uid' => 5, 'data' => 2.456],
85                         'array'        => ['uid' => 6, 'data' => ['1', 2, '3', true, false]],
86                         'boolIntTrue'  => ['uid' => 7, 'data' => 1],
87                         'boolIntFalse' => ['uid' => 8, 'data' => 0],
88                 ];
89         }
90
91         public function dataConfigLoad()
92         {
93                 $data = [
94                         'system' => [
95                                 'key1' => 'value1',
96                                 'key2' => 'value2',
97                                 'key3' => 'value3',
98                         ],
99                         'config' => [
100                                 'key1' => 'value1a',
101                                 'key4' => 'value4',
102                         ],
103                         'other'  => [
104                                 'key5' => 'value5',
105                                 'key6' => 'value6',
106                         ],
107                 ];
108
109                 return [
110                         'system' => [
111                                 'uid' => 1,
112                                 'data'         => $data,
113                                 'possibleCats' => [
114                                         'system',
115                                         'config',
116                                         'other'
117                                 ],
118                                 'load'         => [
119                                         'system',
120                                 ],
121                         ],
122                         'other'  => [
123                                 'uid' => 2,
124                                 'data'         => $data,
125                                 'possibleCats' => [
126                                         'system',
127                                         'config',
128                                         'other'
129                                 ],
130                                 'load'         => [
131                                         'other',
132                                 ],
133                         ],
134                         'config' => [
135                                 'uid' => 3,
136                                 'data'         => $data,
137                                 'possibleCats' => [
138                                         'system',
139                                         'config',
140                                         'other'
141                                 ],
142                                 'load'         => [
143                                         'config',
144                                 ],
145                         ],
146                         'all'    => [
147                                 'uid' => 4,
148                                 'data'         => $data,
149                                 'possibleCats' => [
150                                         'system',
151                                         'config',
152                                         'other'
153                                 ],
154                                 'load'         => [
155                                         'system',
156                                         'config',
157                                         'other'
158                                 ],
159                         ],
160                 ];
161         }
162
163         /**
164          * Test the configuration initialization
165          */
166         public function testSetUp()
167         {
168                 $this->testedConfig = $this->getInstance();
169                 self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
170
171                 self::assertEmpty($this->testedConfig->getCache()->getAll());
172         }
173
174         /**
175          * Test the configuration load() method
176          */
177         public function testLoad(int $uid, array $data, array $possibleCats, array $load)
178         {
179                 $this->testedConfig = $this->getInstance();
180                 self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
181
182                 foreach ($load as $loadedCats) {
183                         $this->testedConfig->load($uid, $loadedCats);
184                 }
185
186                 // Assert at least loaded cats are loaded
187                 foreach ($load as $loadedCats) {
188                         self::assertConfig($uid, $loadedCats, $data[$loadedCats]);
189                 }
190         }
191
192         public function dataDoubleLoad()
193         {
194                 return [
195                         'config' => [
196                                 'uid' => 1,
197                                 'data1'  => [
198                                         'config' => [
199                                                 'key1' => 'value1',
200                                                 'key2' => 'value2',
201                                         ],
202                                 ],
203                                 'data2'  => [
204                                         'config' => [
205                                                 'key1' => 'overwritten!',
206                                                 'key3' => 'value3',
207                                         ],
208                                 ],
209                                 'expect' => [
210                                         'config' => [
211                                                 // load should overwrite values everytime!
212                                                 'key1' => 'overwritten!',
213                                                 'key2' => 'value2',
214                                                 'key3' => 'value3',
215                                         ],
216                                 ],
217                         ],
218                         'other'  => [
219                                 'uid' => 1,
220                                 'data1'  => [
221                                         'config' => [
222                                                 'key12' => 'data4',
223                                                 'key45' => 7,
224                                         ],
225                                         'other'  => [
226                                                 'key1' => 'value1',
227                                                 'key2' => 'value2',
228                                         ],
229                                 ],
230                                 'data2'  => [
231                                         'other'  => [
232                                                 'key1' => 'overwritten!',
233                                                 'key3' => 'value3',
234                                         ],
235                                         'config' => [
236                                                 'key45' => 45,
237                                                 'key52' => true,
238                                         ]
239                                 ],
240                                 'expect' => [
241                                         'other'  => [
242                                                 // load should overwrite values everytime!
243                                                 'key1' => 'overwritten!',
244                                                 'key2' => 'value2',
245                                                 'key3' => 'value3',
246                                         ],
247                                         'config' => [
248                                                 'key12' => 'data4',
249                                                 'key45' => 45,
250                                                 'key52' => true,
251                                         ],
252                                 ],
253                         ],
254                 ];
255         }
256
257         /**
258          * Test the configuration load() method with overwrite
259          */
260         public function testCacheLoadDouble(int $uid, array $data1, array $data2, array $expect)
261         {
262                 $this->testedConfig = $this->getInstance();
263                 self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
264
265                 foreach ($data1 as $cat => $data) {
266                         $this->testedConfig->load($uid, $cat);
267                 }
268
269                 // Assert at least loaded cats are loaded
270                 foreach ($data1 as $cat => $data) {
271                         self::assertConfig($uid, $cat, $data);
272                 }
273
274                 foreach ($data2 as $cat => $data) {
275                         $this->testedConfig->load($uid, $cat);
276                 }
277         }
278
279         /**
280          * Test the configuration get() and set() methods without adapter
281          *
282          * @dataProvider dataTests
283          */
284         public function testSetGetWithoutDB(int $uid, $data)
285         {
286                 $this->testedConfig = $this->getInstance();
287                 self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
288
289                 self::assertTrue($this->testedConfig->set($uid, 'test', 'it', $data));
290
291                 self::assertEquals($data, $this->testedConfig->get($uid, 'test', 'it'));
292                 self::assertEquals($data, $this->testedConfig->getCache()->get($uid, 'test', 'it'));
293         }
294
295         /**
296          * Test the configuration get() and set() methods with a model/db
297          *
298          * @dataProvider dataTests
299          */
300         public function testSetGetWithDB(int $uid, $data)
301         {
302                 $this->configModel->shouldReceive('set')
303                                   ->with($uid, 'test', 'it', $data)
304                                   ->andReturn(true)
305                                   ->once();
306
307                 $this->testedConfig = $this->getInstance();
308                 self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
309
310                 self::assertTrue($this->testedConfig->set($uid, 'test', 'it', $data));
311
312                 self::assertEquals($data, $this->testedConfig->get($uid, 'test', 'it'));
313                 self::assertEquals($data, $this->testedConfig->getCache()->get($uid, 'test', 'it'));
314         }
315
316         /**
317          * Test the configuration get() method with wrong value and no db
318          */
319         public function testGetWrongWithoutDB()
320         {
321                 $this->testedConfig = $this->getInstance();
322                 self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
323
324                 // without refresh
325                 self::assertNull($this->testedConfig->get(0, 'test', 'it'));
326
327                 /// beware that the cache returns '!<unset>!' and not null for a non existing value
328                 self::assertNull($this->testedConfig->getCache()->get(0, 'test', 'it'));
329
330                 // with default value
331                 self::assertEquals('default', $this->testedConfig->get(0, 'test', 'it', 'default'));
332
333                 // with default value and refresh
334                 self::assertEquals('default', $this->testedConfig->get(0, 'test', 'it', 'default', true));
335         }
336
337         /**
338          * Test the configuration get() method with refresh
339          *
340          * @dataProvider dataTests
341          */
342         public function testGetWithRefresh(int $uid, $data)
343         {
344                 $this->configCache->load($uid, ['test' => ['it' => 'now']]);
345
346                 $this->testedConfig = $this->getInstance();
347                 self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
348
349                 // without refresh
350                 self::assertEquals('now', $this->testedConfig->get($uid, 'test', 'it'));
351                 self::assertEquals('now', $this->testedConfig->getCache()->get($uid, 'test', 'it'));
352
353                 // with refresh
354                 self::assertEquals($data, $this->testedConfig->get($uid, 'test', 'it', null, true));
355                 self::assertEquals($data, $this->testedConfig->getCache()->get($uid, 'test', 'it'));
356
357                 // without refresh and wrong value and default
358                 self::assertEquals('default', $this->testedConfig->get($uid, 'test', 'not', 'default'));
359                 self::assertNull($this->testedConfig->getCache()->get($uid, 'test', 'not'));
360         }
361
362         /**
363          * Test the configuration delete() method without a model/db
364          *
365          * @dataProvider dataTests
366          */
367         public function testDeleteWithoutDB(int $uid, $data)
368         {
369                 $this->configCache->load($uid, ['test' => ['it' => $data]]);
370
371                 $this->testedConfig = $this->getInstance();
372                 self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
373
374                 self::assertEquals($data, $this->testedConfig->get($uid, 'test', 'it'));
375                 self::assertEquals($data, $this->testedConfig->getCache()->get($uid, 'test', 'it'));
376
377                 self::assertTrue($this->testedConfig->delete($uid, 'test', 'it'));
378                 self::assertNull($this->testedConfig->get($uid, 'test', 'it'));
379                 self::assertNull($this->testedConfig->getCache()->get($uid, 'test', 'it'));
380
381                 self::assertEmpty($this->testedConfig->getCache()->getAll());
382         }
383
384         /**
385          * Test the configuration delete() method with a model/db
386          */
387         public function testDeleteWithDB()
388         {
389                 $uid = 42;
390
391                 $this->configCache->load($uid, ['test' => ['it' => 'now', 'quarter' => 'true']]);
392
393                 $this->configModel->shouldReceive('delete')
394                                   ->with($uid, 'test', 'it')
395                                   ->andReturn(false)
396                                   ->once();
397                 $this->configModel->shouldReceive('delete')
398                                   ->with($uid, 'test', 'second')
399                                   ->andReturn(true)
400                                   ->once();
401                 $this->configModel->shouldReceive('delete')
402                                   ->with($uid, 'test', 'third')
403                                   ->andReturn(false)
404                                   ->once();
405                 $this->configModel->shouldReceive('delete')
406                                   ->with($uid, 'test', 'quarter')
407                                   ->andReturn(true)
408                                   ->once();
409
410                 $this->testedConfig = $this->getInstance();
411                 self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
412
413                 // directly set the value to the cache
414                 $this->testedConfig->getCache()->set($uid, 'test', 'it', 'now');
415
416                 self::assertEquals('now', $this->testedConfig->get($uid, 'test', 'it'));
417                 self::assertEquals('now', $this->testedConfig->getCache()->get($uid, 'test', 'it'));
418
419                 // delete from cache only
420                 self::assertTrue($this->testedConfig->delete($uid, 'test', 'it'));
421                 // delete from db only
422                 self::assertTrue($this->testedConfig->delete($uid, 'test', 'second'));
423                 // no delete
424                 self::assertFalse($this->testedConfig->delete($uid, 'test', 'third'));
425                 // delete both
426                 self::assertTrue($this->testedConfig->delete($uid, 'test', 'quarter'));
427
428                 self::assertEmpty($this->testedConfig->getCache()->getAll());
429         }
430
431         public function dataMultiUid()
432         {
433                 return [
434                         'normal' => [
435                                 'data1' => [
436                                         'uid'  => 1,
437                                         'data' => [
438                                                 'cat1' => [
439                                                         'key1' => 'value1',
440                                                 ],
441                                                 'cat2' => [
442                                                         'key2' => 'value2',
443                                                 ]
444                                         ],
445                                 ],
446                                 'data2' => [
447                                         'uid' => 2,
448                                         'data' => [
449                                                 'cat1' => [
450                                                         'key1' => 'value1a',
451                                                 ],
452                                                 'cat2' => [
453                                                         'key2' => 'value2',
454                                                 ],
455                                         ],
456                                 ],
457                         ],
458                 ];
459         }
460
461         /**
462          * Test if multiple uids for caching are usable without errors
463          * @dataProvider dataMultiUid
464          */
465         public function testMultipleUidsWithCache(array $data1, array $data2)
466         {
467                 $this->configCache->load($data1['uid'], $data1['data']);
468                 $this->configCache->load($data2['uid'], $data2['data']);
469
470                 $this->testedConfig = $this->getInstance();
471                 self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
472
473                 self::assertConfig($data1['uid'], 'cat1', $data1['data']['cat1']);
474                 self::assertConfig($data1['uid'], 'cat2', $data1['data']['cat2']);
475                 self::assertConfig($data2['uid'], 'cat1', $data2['data']['cat1']);
476                 self::assertConfig($data2['uid'], 'cat2', $data2['data']['cat2']);
477         }
478
479         /**
480          * Test when using an invalid UID
481          * @todo check it the clean way before using the config class
482          */
483         public function testInvalidUid()
484         {
485                 // bad UID!
486                 $uid = 0;
487
488                 $this->testedConfig = $this->getInstance();
489
490                 self::assertNull($this->testedConfig->get($uid, 'cat1', 'cat2'));
491                 self::assertEquals('fallback!', $this->testedConfig->get($uid, 'cat1', 'cat2', 'fallback!'));
492
493                 self::assertFalse($this->testedConfig->set($uid, 'cat1', 'key1', 'doesn\'t matter!'));
494                 self::assertFalse($this->testedConfig->delete($uid, 'cat1', 'key1'));
495         }
496 }