3 * @copyright Copyright (C) 2010-2023, the Friendica project
5 * @license GNU AGPL version 3 or any later version
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.
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.
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/>.
22 namespace Friendica\Test\src\Core\Config\Cache;
24 use Friendica\Core\Config\ValueObject\Cache;
25 use Friendica\Test\MockedTest;
26 use ParagonIE\HiddenString\HiddenString;
29 class CacheTest extends MockedTest
31 public function dataTests()
42 'array' => ['1', 2, '3', true, false],
52 private function assertConfigValues($data, Cache $configCache)
54 foreach ($data as $cat => $values) {
55 foreach ($values as $key => $value) {
56 self::assertEquals($data[$cat][$key], $configCache->get($cat, $key));
62 * Test the loadConfigArray() method without override
63 * @dataProvider dataTests
65 public function testLoadConfigArray($data)
67 $configCache = new Cache();
68 $configCache->load($data);
70 self::assertConfigValues($data, $configCache);
74 * Test the loadConfigArray() method with overrides
75 * @dataProvider dataTests
77 public function testLoadConfigArrayOverride($data)
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);
91 self::assertConfigValues($data, $configCache);
93 // override the value - High Prio due Server Env
94 $configCache->load($override, Cache::SOURCE_ENV);
96 self::assertEquals($override['system']['test'], $configCache->get('system', 'test'));
97 self::assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
99 // Don't overwrite server ENV variables - even in load mode
100 $configCache->load($data, Cache::SOURCE_DATA);
102 self::assertEquals($override['system']['test'], $configCache->get('system', 'test'));
103 self::assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
105 // Overwrite ENV variables with ENV variables
106 $configCache->load($data, Cache::SOURCE_ENV);
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'));
114 * Test the loadConfigArray() method with only a category
116 public function testLoadConfigArrayWithOnlyCategory()
118 $configCache = new Cache();
121 $configCache->load([]);
122 self::assertEmpty($configCache->getAll());
125 $configCache->load(['system' => 'not_array']);
126 self::assertEquals([], $configCache->getAll());
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));
135 * Test the getAll() method
136 * @dataProvider dataTests
138 public function testGetAll($data)
140 $configCache = new Cache();
141 $configCache->load($data);
143 $all = $configCache->getAll();
145 self::assertContains($data['system'], $all);
146 self::assertContains($data['config'], $all);
150 * Test the set() and get() method
151 * @dataProvider dataTests
153 public function testSetGet($data)
155 $configCache = new Cache();
157 foreach ($data as $cat => $values) {
158 foreach ($values as $key => $value) {
159 $configCache->set($cat, $key, $value);
163 self::assertConfigValues($data, $configCache);
167 * Test the get() method without a value
169 public function testGetEmpty()
171 $configCache = new Cache();
173 self::assertNull($configCache->get('something', 'value'));
177 * Test the get() method with a category
179 public function testGetCat()
181 $configCache = new Cache([
194 ], $configCache->get('system'));
196 // explicit null as key
200 ], $configCache->get('system', null));
204 * Test the delete() method
205 * @dataProvider dataTests
207 public function testDelete($data)
209 $configCache = new Cache($data);
211 foreach ($data as $cat => $values) {
212 foreach ($values as $key => $value) {
213 $configCache->delete($cat, $key);
217 self::assertEmpty($configCache->getAll());
221 * Test the keyDiff() method with result
222 * @dataProvider dataTests
224 public function testKeyDiffWithResult($data)
226 $configCache = new Cache($data);
230 'fakeKey' => 'value',
234 self::assertEquals($diffConfig, $configCache->keyDiff($diffConfig));
238 * Test the keyDiff() method without result
239 * @dataProvider dataTests
241 public function testKeyDiffWithoutResult($data)
243 $configCache = new Cache($data);
245 $diffConfig = $configCache->getAll();
247 self::assertEmpty($configCache->keyDiff($diffConfig));
251 * Test the default hiding of passwords inside the cache
253 public function testPasswordHide()
255 $configCache = new Cache([
257 'password' => 'supersecure',
258 'username' => 'notsecured',
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));
268 * Test disabling the hiding of passwords inside the cache
270 public function testPasswordShow()
272 $configCache = new Cache([
274 'password' => 'supersecure',
275 'username' => 'notsecured',
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));
285 * Test a empty password
287 public function testEmptyPassword()
289 $configCache = new Cache([
296 self::assertNotEmpty($configCache->get('database', 'password'));
297 self::assertInstanceOf(HiddenString::class, $configCache->get('database', 'password'));
298 self::assertEmpty($configCache->get('database', 'username'));
301 public function testWrongTypePassword()
303 $configCache = new Cache([
305 'password' => new stdClass(),
310 self::assertNotEmpty($configCache->get('database', 'password'));
311 self::assertEmpty($configCache->get('database', 'username'));
313 $configCache = new Cache([
320 self::assertEquals(23, $configCache->get('database', 'password'));
321 self::assertEmpty($configCache->get('database', 'username'));
325 * Test the set() method with overrides
326 * @dataProvider dataTests
328 public function testSetOverrides($data)
331 $configCache = new Cache();
332 $configCache->load($data, Cache::SOURCE_DATA);
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'));
338 // test with override (equal)
339 self::assertTrue($configCache->set('system', 'test', '8910', Cache::SOURCE_DATA));
340 self::assertEquals('8910', $configCache->get('system', 'test'));
342 // test with override (over)
343 self::assertTrue($configCache->set('system', 'test', '111213', Cache::SOURCE_ENV));
344 self::assertEquals('111213', $configCache->get('system', 'test'));
348 * @dataProvider dataTests
352 public function testSetData($data)
354 $configCache = new Cache();
355 $configCache->load($data, Cache::SOURCE_FILE);
357 $configCache->set('system', 'test_2','with_data', Cache::SOURCE_DATA);
359 $this->assertEquals(['system' => ['test_2' => 'with_data']], $configCache->getDataBySource(Cache::SOURCE_DATA));
360 $this->assertEquals($data, $configCache->getDataBySource(Cache::SOURCE_FILE));
364 * @dataProvider dataTests
366 public function testMerge($data)
368 $configCache = new Cache();
369 $configCache->load($data, Cache::SOURCE_FILE);
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);
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);
380 $mergedCache = $configCache->merge($newCache);
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'));
389 public function dataTestCat()
392 'test_with_hashmap' => [
394 'test_with_hashmap' => [
396 'last_update' => 1671051565,
400 'last_update' => 1658952852,
405 'register_policy' => 2,
406 'register_text' => '',
407 'sitename' => 'Friendica Social Network23',
408 'hostname' => 'friendica.local',
409 'private_addons' => false,
412 'dbclean_expire_conversation' => 90,
415 'cat' => 'test_with_hashmap',
418 'last_update' => 1671051565,
422 'last_update' => 1658952852,
427 'test_with_keys' => [
429 'test_with_keys' => [
431 'last_update' => 1671051565,
435 'last_update' => 1658952852,
440 'register_policy' => 2,
441 'register_text' => '',
442 'sitename' => 'Friendica Social Network23',
443 'hostname' => 'friendica.local',
444 'private_addons' => false,
447 'dbclean_expire_conversation' => 90,
450 'cat' => 'test_with_keys',
453 'last_update' => 1671051565,
457 'last_update' => 1658952852,
462 'test_with_inner_array' => [
464 'test_with_inner_array' => [
466 'last_update' => 1671051565,
473 'last_update' => 1658952852,
478 'register_policy' => 2,
479 'register_text' => '',
480 'sitename' => 'Friendica Social Network23',
481 'hostname' => 'friendica.local',
482 'private_addons' => false,
485 'dbclean_expire_conversation' => 90,
488 'cat' => 'test_with_inner_array',
491 'last_update' => 1671051565,
498 'last_update' => 1658952852,
503 /** @see https://github.com/friendica/friendica/issues/12486#issuecomment-1374609349 */
504 'test_with_null' => [
506 'test_with_null' => null,
508 'register_policy' => 2,
509 'register_text' => '',
510 'sitename' => 'Friendica Social Network23',
511 'hostname' => 'friendica.local',
512 'private_addons' => false,
515 'dbclean_expire_conversation' => 90,
518 'cat' => 'test_with_null',
525 * Tests that the Cache can return a whole category at once
527 * @dataProvider dataTestCat
529 public function testGetCategory($data, string $category, $assertion)
531 $cache = new Cache($data);
533 self::assertEquals($assertion, $cache->get($category));
537 * Test that the cache can get merged with different categories
539 * @dataProvider dataTestCat
541 public function testCatMerge($data, string $category)
543 $cache = new Cache($data);
545 $newCache = $cache->merge(new Cache([
547 'new_key' => 'new_value',
551 self::assertEquals('new_value', $newCache->get($category, 'new_key'));
555 * Test that keys are removed after a deletion
557 * @dataProvider dataTests
560 public function testDeleteRemovesKey($data)
562 $cache = new Cache();
563 $cache->load($data, Cache::SOURCE_FILE);
565 $cache->set('system', 'test', 'overwrite!', Cache::SOURCE_DATA);
566 self::assertEquals('overwrite!', $cache->get('system', 'test'));
568 // array should now be removed
569 $cache->delete('system', 'test');
570 self::assertArrayNotHasKey('test', $cache->getAll()['system']);
572 self::assertArrayHasKey('config', $cache->getAll());
573 self::assertArrayHasKey('a', $cache->getAll()['config']);
575 // category should now be removed
576 $cache->delete('config', 'a');
577 self::assertArrayNotHasKey('config', $cache->getAll());
581 * Test that deleted keys are working with merge
583 * @dataProvider dataTests
585 public function testDeleteAndMergeWithDefault($data)
587 $cache = new Cache();
588 $cache->load($data, Cache::SOURCE_FILE);
590 $cache2 = new Cache();
591 $cache2->set('system', 'test', 'overrride');
592 $cache2->delete('system', 'test');
594 self::assertEquals('it', $cache->get('system', 'test'));
595 self::assertNull($cache2->get('system', 'test'));
597 $mergedCache = $cache->merge($cache2);
598 self::assertNull($mergedCache->get('system', 'test'));