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