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