3 * @copyright Copyright (C) 2020, Friendica
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;
24 use Friendica\Core\Config\Cache;
25 use Friendica\Core\Config\IConfig;
26 use Friendica\Model\Config\Config as ConfigModel;
27 use Friendica\Test\MockedTest;
28 use Mockery\MockInterface;
31 abstract class ConfigTest extends MockedTest
33 /** @var ConfigModel|MockInterface */
34 protected $configModel;
37 protected $configCache;
40 protected $testedConfig;
43 * Assert a config tree
45 * @param string $cat The category to assert
46 * @param array $data The result data array
48 protected function assertConfig(string $cat, array $data)
50 $result = $this->testedConfig->getCache()->getAll();
52 $this->assertNotEmpty($result);
53 $this->assertArrayHasKey($cat, $result);
54 $this->assertArraySubset($data, $result[$cat]);
58 protected function setUp()
62 // Create the config model
63 $this->configModel = Mockery::mock(ConfigModel::class);
64 $this->configCache = new Cache();
70 public abstract function getInstance();
72 public function dataTests()
75 'string' => ['data' => 'it'],
76 'boolTrue' => ['data' => true],
77 'boolFalse' => ['data' => false],
78 'integer' => ['data' => 235],
79 'decimal' => ['data' => 2.456],
80 'array' => ['data' => ['1', 2, '3', true, false]],
81 'boolIntTrue' => ['data' => 1],
82 'boolIntFalse' => ['Data' => 0],
86 public function dataConfigLoad()
155 * Test the configuration initialization
157 public function testSetUp(array $data)
159 $this->configModel->shouldReceive('isConnected')
163 $this->testedConfig = $this->getInstance();
164 $this->assertInstanceOf(Cache::class, $this->testedConfig->getCache());
166 // assert config is loaded everytime
167 $this->assertConfig('config', $data['config']);
171 * Test the configuration load() method
173 public function testLoad(array $data, array $possibleCats, array $load)
175 $this->testedConfig = $this->getInstance();
176 $this->assertInstanceOf(Cache::class, $this->testedConfig->getCache());
178 foreach ($load as $loadedCats) {
179 $this->testedConfig->load($loadedCats);
182 // Assert at least loaded cats are loaded
183 foreach ($load as $loadedCats) {
184 $this->assertConfig($loadedCats, $data[$loadedCats]);
188 public function dataDoubleLoad()
200 'key1' => 'overwritten!',
206 // load should overwrite values everytime!
207 'key1' => 'overwritten!',
226 'key1' => 'overwritten!',
236 // load should overwrite values everytime!
237 'key1' => 'overwritten!',
252 * Test the configuration load() method with overwrite
254 public function testCacheLoadDouble(array $data1, array $data2, array $expect)
256 $this->testedConfig = $this->getInstance();
257 $this->assertInstanceOf(Cache::class, $this->testedConfig->getCache());
259 foreach ($data1 as $cat => $data) {
260 $this->testedConfig->load($cat);
263 // Assert at least loaded cats are loaded
264 foreach ($data1 as $cat => $data) {
265 $this->assertConfig($cat, $data);
268 foreach ($data2 as $cat => $data) {
269 $this->testedConfig->load($cat);
274 * Test the configuration load without result
276 public function testLoadWrong()
278 $this->configModel->shouldReceive('isConnected')->andReturn(true)->once();
279 $this->configModel->shouldReceive('load')->withAnyArgs()->andReturn([])->once();
281 $this->testedConfig = $this->getInstance();
282 $this->assertInstanceOf(Cache::class, $this->testedConfig->getCache());
284 $this->assertEmpty($this->testedConfig->getCache()->getAll());
288 * Test the configuration get() and set() methods without adapter
290 * @dataProvider dataTests
292 public function testSetGetWithoutDB($data)
294 $this->configModel->shouldReceive('isConnected')
298 $this->testedConfig = $this->getInstance();
299 $this->assertInstanceOf(Cache::class, $this->testedConfig->getCache());
301 $this->assertTrue($this->testedConfig->set('test', 'it', $data));
303 $this->assertEquals($data, $this->testedConfig->get('test', 'it'));
304 $this->assertEquals($data, $this->testedConfig->getCache()->get('test', 'it'));
308 * Test the configuration get() and set() methods with a model/db
310 * @dataProvider dataTests
312 public function testSetGetWithDB($data)
314 $this->configModel->shouldReceive('set')->with('test', 'it', $data)->andReturn(true)->once();
316 $this->testedConfig = $this->getInstance();
317 $this->assertInstanceOf(Cache::class, $this->testedConfig->getCache());
319 $this->assertTrue($this->testedConfig->set('test', 'it', $data));
321 $this->assertEquals($data, $this->testedConfig->get('test', 'it'));
322 $this->assertEquals($data, $this->testedConfig->getCache()->get('test', 'it'));
326 * Test the configuration get() method with wrong value and no db
328 public function testGetWrongWithoutDB()
330 $this->testedConfig = $this->getInstance();
331 $this->assertInstanceOf(Cache::class, $this->testedConfig->getCache());
334 $this->assertNull($this->testedConfig->get('test', 'it'));
336 /// beware that the cache returns '!<unset>!' and not null for a non existing value
337 $this->assertNull($this->testedConfig->getCache()->get('test', 'it'));
339 // with default value
340 $this->assertEquals('default', $this->testedConfig->get('test', 'it', 'default'));
342 // with default value and refresh
343 $this->assertEquals('default', $this->testedConfig->get('test', 'it', 'default', true));
347 * Test the configuration get() method with refresh
349 * @dataProvider dataTests
351 public function testGetWithRefresh($data)
353 $this->configCache->load(['test' => ['it' => 'now']]);
355 $this->testedConfig = $this->getInstance();
356 $this->assertInstanceOf(Cache::class, $this->testedConfig->getCache());
359 $this->assertEquals('now', $this->testedConfig->get('test', 'it'));
360 $this->assertEquals('now', $this->testedConfig->getCache()->get('test', 'it'));
363 $this->assertEquals($data, $this->testedConfig->get('test', 'it', null, true));
364 $this->assertEquals($data, $this->testedConfig->getCache()->get('test', 'it'));
366 // without refresh and wrong value and default
367 $this->assertEquals('default', $this->testedConfig->get('test', 'not', 'default'));
368 $this->assertNull($this->testedConfig->getCache()->get('test', 'not'));
372 * Test the configuration delete() method without a model/db
374 * @dataProvider dataTests
376 public function testDeleteWithoutDB($data)
378 $this->configCache->load(['test' => ['it' => $data]]);
380 $this->testedConfig = $this->getInstance();
381 $this->assertInstanceOf(Cache::class, $this->testedConfig->getCache());
383 $this->assertEquals($data, $this->testedConfig->get('test', 'it'));
384 $this->assertEquals($data, $this->testedConfig->getCache()->get('test', 'it'));
386 $this->assertTrue($this->testedConfig->delete('test', 'it'));
387 $this->assertNull($this->testedConfig->get('test', 'it'));
388 $this->assertNull($this->testedConfig->getCache()->get('test', 'it'));
390 $this->assertEmpty($this->testedConfig->getCache()->getAll());
394 * Test the configuration delete() method with a model/db
396 public function testDeleteWithDB()
398 $this->configCache->load(['test' => ['it' => 'now', 'quarter' => 'true']]);
400 $this->configModel->shouldReceive('delete')
404 $this->configModel->shouldReceive('delete')
405 ->with('test', 'second')
408 $this->configModel->shouldReceive('delete')
409 ->with('test', 'third')
412 $this->configModel->shouldReceive('delete')
413 ->with('test', 'quarter')
417 $this->testedConfig = $this->getInstance();
418 $this->assertInstanceOf(Cache::class, $this->testedConfig->getCache());
420 // directly set the value to the cache
421 $this->testedConfig->getCache()->set('test', 'it', 'now');
423 $this->assertEquals('now', $this->testedConfig->get('test', 'it'));
424 $this->assertEquals('now', $this->testedConfig->getCache()->get('test', 'it'));
426 // delete from cache only
427 $this->assertTrue($this->testedConfig->delete('test', 'it'));
428 // delete from db only
429 $this->assertTrue($this->testedConfig->delete('test', 'second'));
431 $this->assertFalse($this->testedConfig->delete('test', 'third'));
433 $this->assertTrue($this->testedConfig->delete('test', 'quarter'));
435 $this->assertEmpty($this->testedConfig->getCache()->getAll());