]> git.mxchange.org Git - friendica.git/blob - tests/src/Core/Config/Cache/CacheTest.php
Merge pull request #12674 from nupplaphil/bug/config_typesafe
[friendica.git] / tests / src / Core / Config / Cache / CacheTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, 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\Config\Cache;
23
24 use Friendica\Core\Config\ValueObject\Cache;
25 use Friendica\Test\MockedTest;
26 use ParagonIE\HiddenString\HiddenString;
27 use stdClass;
28
29 class CacheTest extends MockedTest
30 {
31         public function dataTests()
32         {
33                 return [
34                         'normal' => [
35                                 'data' => [
36                                         'system' => [
37                                                 'test' => 'it',
38                                                 'boolTrue' => true,
39                                                 'boolFalse' => false,
40                                                 'int' => 235,
41                                                 'dec' => 2.456,
42                                                 'array' => ['1', 2, '3', true, false],
43                                         ],
44                                         'config' => [
45                                                 'a' => 'value',
46                                         ],
47                                 ]
48                         ]
49                 ];
50         }
51
52         private function assertConfigValues($data, Cache $configCache)
53         {
54                 foreach ($data as $cat => $values) {
55                         foreach ($values as $key => $value) {
56                                 self::assertEquals($data[$cat][$key], $configCache->get($cat, $key));
57                         }
58                 }
59         }
60
61         /**
62          * Test the loadConfigArray() method without override
63          * @dataProvider dataTests
64          */
65         public function testLoadConfigArray($data)
66         {
67                 $configCache = new Cache();
68                 $configCache->load($data);
69
70                 self::assertConfigValues($data, $configCache);
71         }
72
73         /**
74          * Test the loadConfigArray() method with overrides
75          * @dataProvider dataTests
76          */
77         public function testLoadConfigArrayOverride($data)
78         {
79                 $override = [
80                         'system' => [
81                                 'test' => 'not',
82                                 'boolTrue' => false,
83                         ]
84                 ];
85
86                 $configCache = new Cache();
87                 $configCache->load($data, Cache::SOURCE_DATA);
88                 // doesn't override - Low Priority due Config file
89                 $configCache->load($override, Cache::SOURCE_FILE);
90
91                 self::assertConfigValues($data, $configCache);
92
93                 // override the value - High Prio due Server Env
94                 $configCache->load($override, Cache::SOURCE_ENV);
95
96                 self::assertEquals($override['system']['test'], $configCache->get('system', 'test'));
97                 self::assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
98
99                 // Don't overwrite server ENV variables - even in load mode
100                 $configCache->load($data, Cache::SOURCE_DATA);
101
102                 self::assertEquals($override['system']['test'], $configCache->get('system', 'test'));
103                 self::assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
104
105                 // Overwrite ENV variables with ENV variables
106                 $configCache->load($data, Cache::SOURCE_ENV);
107
108                 self::assertConfigValues($data, $configCache);
109                 self::assertNotEquals($override['system']['test'], $configCache->get('system', 'test'));
110                 self::assertNotEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
111         }
112
113         /**
114          * Test the loadConfigArray() method with only a category
115          */
116         public function testLoadConfigArrayWithOnlyCategory()
117         {
118                 $configCache = new Cache();
119
120                 // empty dataset
121                 $configCache->load([]);
122                 self::assertEmpty($configCache->getAll());
123
124                 // wrong dataset
125                 $configCache->load(['system' => 'not_array']);
126                 self::assertEquals([], $configCache->getAll());
127
128                 // incomplete dataset (key is integer ID of the array)
129                 $configCache = new Cache();
130                 $configCache->load(['system' => ['value']]);
131                 self::assertEquals('value', $configCache->get('system', 0));
132         }
133
134         /**
135          * Test the getAll() method
136          * @dataProvider dataTests
137          */
138         public function testGetAll($data)
139         {
140                 $configCache = new Cache();
141                 $configCache->load($data);
142
143                 $all = $configCache->getAll();
144
145                 self::assertContains($data['system'], $all);
146                 self::assertContains($data['config'], $all);
147         }
148
149         /**
150          * Test the set() and get() method
151          * @dataProvider dataTests
152          */
153         public function testSetGet($data)
154         {
155                 $configCache = new Cache();
156
157                 foreach ($data as $cat => $values) {
158                         foreach ($values as $key => $value) {
159                                 $configCache->set($cat, $key, $value);
160                         }
161                 }
162
163                 self::assertConfigValues($data, $configCache);
164         }
165
166         /**
167          * Test the get() method without a value
168          */
169         public function testGetEmpty()
170         {
171                 $configCache = new Cache();
172
173                 self::assertNull($configCache->get('something', 'value'));
174         }
175
176         /**
177          * Test the get() method with a category
178          */
179         public function testGetCat()
180         {
181                 $configCache = new Cache([
182                         'system' => [
183                                 'key1' => 'value1',
184                                 'key2' => 'value2',
185                         ],
186                         'config' => [
187                                 'key3' => 'value3',
188                         ],
189                 ]);
190
191                 self::assertEquals([
192                         'key1' => 'value1',
193                         'key2' => 'value2',
194                 ], $configCache->get('system'));
195
196                 // explicit null as key
197                 self::assertEquals([
198                         'key1' => 'value1',
199                         'key2' => 'value2',
200                 ], $configCache->get('system', null));
201         }
202
203         /**
204          * Test the delete() method
205          * @dataProvider dataTests
206          */
207         public function testDelete($data)
208         {
209                 $configCache = new Cache($data);
210
211                 foreach ($data as $cat => $values) {
212                         foreach ($values as $key => $value) {
213                                 $configCache->delete($cat, $key);
214                         }
215                 }
216
217                 self::assertEmpty($configCache->getAll());
218         }
219
220         /**
221          * Test the keyDiff() method with result
222          * @dataProvider dataTests
223          */
224         public function testKeyDiffWithResult($data)
225         {
226                 $configCache = new Cache($data);
227
228                 $diffConfig = [
229                         'fakeCat' => [
230                                 'fakeKey' => 'value',
231                         ]
232                 ];
233
234                 self::assertEquals($diffConfig, $configCache->keyDiff($diffConfig));
235         }
236
237         /**
238          * Test the keyDiff() method without result
239          * @dataProvider dataTests
240          */
241         public function testKeyDiffWithoutResult($data)
242         {
243                 $configCache = new Cache($data);
244
245                 $diffConfig = $configCache->getAll();
246
247                 self::assertEmpty($configCache->keyDiff($diffConfig));
248         }
249
250         /**
251          * Test the default hiding of passwords inside the cache
252          */
253         public function testPasswordHide()
254         {
255                 $configCache = new Cache([
256                         'database' => [
257                                 'password' => 'supersecure',
258                                 'username' => 'notsecured',
259                         ],
260                 ]);
261
262                 self::assertEquals('supersecure', $configCache->get('database', 'password'));
263                 self::assertNotEquals('supersecure', print_r($configCache->get('database', 'password'), true));
264                 self::assertEquals('notsecured', print_r($configCache->get('database', 'username'), true));
265         }
266
267         /**
268          * Test disabling the hiding of passwords inside the cache
269          */
270         public function testPasswordShow()
271         {
272                 $configCache = new Cache([
273                         'database' => [
274                                 'password' => 'supersecure',
275                                 'username' => 'notsecured',
276                         ],
277                 ], false);
278
279                 self::assertEquals('supersecure', $configCache->get('database', 'password'));
280                 self::assertEquals('supersecure', print_r($configCache->get('database', 'password'), true));
281                 self::assertEquals('notsecured', print_r($configCache->get('database', 'username'), true));
282         }
283
284         /**
285          * Test a empty password
286          */
287         public function testEmptyPassword()
288         {
289                 $configCache = new Cache([
290                         'database' => [
291                                 'password' => '',
292                                 'username' => '',
293                         ]
294                 ]);
295
296                 self::assertNotEmpty($configCache->get('database', 'password'));
297                 self::assertInstanceOf(HiddenString::class, $configCache->get('database', 'password'));
298                 self::assertEmpty($configCache->get('database', 'username'));
299         }
300
301         public function testWrongTypePassword()
302         {
303                 $configCache = new Cache([
304                         'database' => [
305                                 'password' => new stdClass(),
306                                 'username' => '',
307                         ]
308                 ]);
309
310                 self::assertNotEmpty($configCache->get('database', 'password'));
311                 self::assertEmpty($configCache->get('database', 'username'));
312
313                 $configCache = new Cache([
314                         'database' => [
315                                 'password' => 23,
316                                 'username' => '',
317                         ]
318                 ]);
319
320                 self::assertEquals(23, $configCache->get('database', 'password'));
321                 self::assertEmpty($configCache->get('database', 'username'));
322         }
323
324         /**
325          * Test the set() method with overrides
326          * @dataProvider dataTests
327          */
328         public function testSetOverrides($data)
329         {
330
331                 $configCache = new Cache();
332                 $configCache->load($data, Cache::SOURCE_DATA);
333
334                 // test with wrong override
335                 self::assertFalse($configCache->set('system', 'test', '1234567', Cache::SOURCE_FILE));
336                 self::assertEquals($data['system']['test'], $configCache->get('system', 'test'));
337
338                 // test with override (equal)
339                 self::assertTrue($configCache->set('system', 'test', '8910', Cache::SOURCE_DATA));
340                 self::assertEquals('8910', $configCache->get('system', 'test'));
341
342                 // test with override (over)
343                 self::assertTrue($configCache->set('system', 'test', '111213', Cache::SOURCE_ENV));
344                 self::assertEquals('111213', $configCache->get('system', 'test'));
345         }
346
347         /**
348          * @dataProvider dataTests
349          *
350          * @return void
351          */
352         public function testSetData($data)
353         {
354                 $configCache = new Cache();
355                 $configCache->load($data, Cache::SOURCE_FILE);
356
357                 $configCache->set('system', 'test_2','with_data', Cache::SOURCE_DATA);
358
359                 $this->assertEquals(['system' => ['test_2' => 'with_data']], $configCache->getDataBySource(Cache::SOURCE_DATA));
360                 $this->assertEquals($data, $configCache->getDataBySource(Cache::SOURCE_FILE));
361         }
362
363         /**
364          * @dataProvider dataTests
365          */
366         public function testMerge($data)
367         {
368                 $configCache = new Cache();
369                 $configCache->load($data, Cache::SOURCE_FILE);
370
371                 $configCache->set('system', 'test_2','with_data', Cache::SOURCE_DATA);
372                 $configCache->set('config', 'test_override','with_another_data', Cache::SOURCE_DATA);
373                 $configCache->set('old_category', 'test_45','given category', Cache::SOURCE_DATA);
374
375                 $newCache = new Cache();
376                 $newCache->set('config', 'test_override','override it again', Cache::SOURCE_DATA);
377                 $newCache->set('system', 'test_3','new value', Cache::SOURCE_DATA);
378                 $newCache->set('new_category', 'test_23','added category', Cache::SOURCE_DATA);
379
380                 $mergedCache = $configCache->merge($newCache);
381
382                 self::assertEquals('with_data', $mergedCache->get('system', 'test_2'));
383                 self::assertEquals('override it again', $mergedCache->get('config', 'test_override'));
384                 self::assertEquals('new value', $mergedCache->get('system', 'test_3'));
385                 self::assertEquals('given category', $mergedCache->get('old_category', 'test_45'));
386                 self::assertEquals('added category', $mergedCache->get('new_category', 'test_23'));
387         }
388
389         public function dataTestCat()
390         {
391                 return [
392                         'test_with_hashmap'     => [
393                                 'data'      => [
394                                         'test_with_hashmap' => [
395                                                 'notifyall' => [
396                                                         'last_update' => 1671051565,
397                                                         'admin'       => true,
398                                                 ],
399                                                 'blockbot'  => [
400                                                         'last_update' => 1658952852,
401                                                         'admin'       => true,
402                                                 ],
403                                         ],
404                                         'config'            => [
405                                                 'register_policy' => 2,
406                                                 'register_text'   => '',
407                                                 'sitename'        => 'Friendica Social Network23',
408                                                 'hostname'        => 'friendica.local',
409                                                 'private_addons'  => false,
410                                         ],
411                                         'system'            => [
412                                                 'dbclean_expire_conversation' => 90,
413                                         ],
414                                 ],
415                                 'cat'       => 'test_with_hashmap',
416                                 'assertion' => [
417                                         'notifyall' => [
418                                                 'last_update' => 1671051565,
419                                                 'admin'       => true,
420                                         ],
421                                         'blockbot'  => [
422                                                 'last_update' => 1658952852,
423                                                 'admin'       => true,
424                                         ],
425                                 ],
426                         ],
427                         'test_with_keys'        => [
428                                 'data'      => [
429                                         'test_with_keys' => [
430                                                 [
431                                                         'last_update' => 1671051565,
432                                                         'admin'       => true,
433                                                 ],
434                                                 [
435                                                         'last_update' => 1658952852,
436                                                         'admin'       => true,
437                                                 ],
438                                         ],
439                                         'config'            => [
440                                                 'register_policy' => 2,
441                                                 'register_text'   => '',
442                                                 'sitename'        => 'Friendica Social Network23',
443                                                 'hostname'        => 'friendica.local',
444                                                 'private_addons'  => false,
445                                         ],
446                                         'system'            => [
447                                                 'dbclean_expire_conversation' => 90,
448                                         ],
449                                 ],
450                                 'cat'       => 'test_with_keys',
451                                 'assertion' => [
452                                         [
453                                                 'last_update' => 1671051565,
454                                                 'admin'       => true,
455                                         ],
456                                         [
457                                                 'last_update' => 1658952852,
458                                                 'admin'       => true,
459                                         ],
460                                 ],
461                         ],
462                         'test_with_inner_array' => [
463                                 'data'      => [
464                                         'test_with_inner_array' => [
465                                                 'notifyall' => [
466                                                         'last_update' => 1671051565,
467                                                         'admin'       => [
468                                                                 'yes' => true,
469                                                                 'no'  => 1.5,
470                                                         ],
471                                                 ],
472                                                 'blogbot'   => [
473                                                         'last_update' => 1658952852,
474                                                         'admin'       => true,
475                                                 ],
476                                         ],
477                                         'config'                => [
478                                                 'register_policy' => 2,
479                                                 'register_text'   => '',
480                                                 'sitename'        => 'Friendica Social Network23',
481                                                 'hostname'        => 'friendica.local',
482                                                 'private_addons'  => false,
483                                         ],
484                                         'system'                => [
485                                                 'dbclean_expire_conversation' => 90,
486                                         ],
487                                 ],
488                                 'cat'       => 'test_with_inner_array',
489                                 'assertion' => [
490                                         'notifyall' => [
491                                                 'last_update' => 1671051565,
492                                                 'admin'       => [
493                                                         'yes' => true,
494                                                         'no'  => 1.5,
495                                                 ],
496                                         ],
497                                         'blogbot'   => [
498                                                 'last_update' => 1658952852,
499                                                 'admin'       => true,
500                                         ],
501                                 ],
502                         ],
503                         /** @see https://github.com/friendica/friendica/issues/12486#issuecomment-1374609349 */
504                         'test_with_null' => [
505                                 'data'      => [
506                                         'test_with_null' => null,
507                                         'config'                => [
508                                                 'register_policy' => 2,
509                                                 'register_text'   => '',
510                                                 'sitename'        => 'Friendica Social Network23',
511                                                 'hostname'        => 'friendica.local',
512                                                 'private_addons'  => false,
513                                         ],
514                                         'system'                => [
515                                                 'dbclean_expire_conversation' => 90,
516                                         ],
517                                 ],
518                                 'cat'       => 'test_with_null',
519                                 'assertion' => null,
520                         ],
521                 ];
522         }
523
524         /**
525          * Tests that the Cache can return a whole category at once
526          *
527          * @dataProvider dataTestCat
528          */
529         public function testGetCategory($data, string $category, $assertion)
530         {
531                 $cache = new Cache($data);
532
533                 self::assertEquals($assertion, $cache->get($category));
534         }
535
536         /**
537          * Test that the cache can get merged with different categories
538          *
539          * @dataProvider dataTestCat
540          */
541         public function testCatMerge($data, string $category)
542         {
543                 $cache = new Cache($data);
544
545                 $newCache = $cache->merge(new Cache([
546                         $category => [
547                                 'new_key' => 'new_value',
548                         ],
549                 ]));
550
551                 self::assertEquals('new_value', $newCache->get($category, 'new_key'));
552         }
553
554         /**
555          * Test that keys are removed after a deletion
556          *
557          * @dataProvider dataTests
558          *
559          */
560         public function testDeleteRemovesKey($data)
561         {
562                 $cache = new Cache();
563                 $cache->load($data, Cache::SOURCE_FILE);
564
565                 $cache->set('system', 'test', 'overwrite!', Cache::SOURCE_DATA);
566                 self::assertEquals('overwrite!', $cache->get('system', 'test'));
567
568                 // array should now be removed
569                 $cache->delete('system', 'test');
570                 self::assertArrayNotHasKey('test', $cache->getAll()['system']);
571
572                 self::assertArrayHasKey('config', $cache->getAll());
573                 self::assertArrayHasKey('a', $cache->getAll()['config']);
574
575                 // category should now be removed
576                 $cache->delete('config', 'a');
577                 self::assertArrayNotHasKey('config', $cache->getAll());
578         }
579
580         /**
581          * Test that deleted keys are working with merge
582          *
583          * @dataProvider dataTests
584          */
585         public function testDeleteAndMergeWithDefault($data)
586         {
587                 $cache = new Cache();
588                 $cache->load($data, Cache::SOURCE_FILE);
589
590                 $cache2 = new Cache();
591                 $cache2->set('system', 'test', 'overrride');
592                 $cache2->delete('system', 'test');
593
594                 self::assertEquals('it', $cache->get('system', 'test'));
595                 self::assertNull($cache2->get('system', 'test'));
596
597                 $mergedCache = $cache->merge($cache2);
598                 self::assertNull($mergedCache->get('system', 'test'));
599         }
600 }