‪TYPO3CMS  10.4
YamlFileLoaderTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
21 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
22 
26 class ‪YamlFileLoaderTest extends UnitTestCase
27 {
32  public function ‪load()
33  {
34  $fileName = 'Berta.yml';
35  $fileContents = '
36 options:
37  - option1
38  - option2
39 betterthanbefore: 1
40 ';
41 
42  $expected = [
43  'options' => [
44  'option1',
45  'option2'
46  ],
47  'betterthanbefore' => 1
48  ];
49 
50  // Accessible mock to $subject since getFileContents calls GeneralUtility methods
51  $subject = $this->getAccessibleMock(YamlFileLoader::class, ['getFileContents', 'getStreamlinedFileName']);
52  $subject->expects(self::once())->method('getStreamlinedFileName')->with($fileName)->willReturn($fileName);
53  $subject->expects(self::once())->method('getFileContents')->with($fileName)->willReturn($fileContents);
54  ‪$output = $subject->load($fileName);
55  self::assertSame($expected, ‪$output);
56  }
57 
62  public function ‪loadWithAnImport()
63  {
64  $fileName = 'Berta.yml';
65  $fileContents = '
66 imports:
67  - { resource: Secondfile.yml }
68 
69 options:
70  - option1
71  - option2
72 betterthanbefore: 1
73 ';
74 
75  $importFileName = 'Secondfile.yml';
76  $importFileContents = '
77 options:
78  - optionBefore
79 betterthanbefore: 2
80 ';
81 
82  $expected = [
83  'options' => [
84  'optionBefore',
85  'option1',
86  'option2'
87  ],
88  'betterthanbefore' => 1
89  ];
90 
91  // Accessible mock to $subject since getFileContents calls GeneralUtility methods
92  $subject = $this->getAccessibleMock(YamlFileLoader::class, ['getFileContents', 'getStreamlinedFileName']);
93  $subject->expects(self::exactly(2))->method('getStreamlinedFileName')
94  ->withConsecutive([$fileName], [$importFileName, $fileName])
95  ->willReturn($fileName, $importFileName);
96  $subject->expects(self::exactly(2))->method('getFileContents')
97  ->withConsecutive([$fileName], [$importFileName])
98  ->willReturn($fileContents, $importFileContents);
99  ‪$output = $subject->load($fileName);
100  self::assertSame($expected, ‪$output);
101  }
102 
107  public function ‪loadWithMultipleImports()
108  {
109  $fileName = 'Berta.yml';
110  $fileContents = '
111 imports:
112  - { resource: Secondfile.yml }
113  - { resource: Thirdfile.yml }
114 
115 options:
116  - option1
117  - option2
118 betterthanbefore: 1
119 ';
120 
121  $importFileName = 'Secondfile.yml';
122  $importFileContents = '
123 options:
124  - optionBefore
125 betterthanbefore: 2
126 ';
127 
128  $importFileName2 = 'Thirdfile.yml';
129  $importFileContents2 = '
130 options:
131  - optionAfterBefore
132 ';
133 
134  $expected = [
135  'options' => [
136  'optionBefore',
137  'optionAfterBefore',
138  'option1',
139  'option2'
140  ],
141  'betterthanbefore' => 1
142  ];
143 
144  // Make sure, feature toggle is activated
145  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['yamlImportsFollowDeclarationOrder'] = true;
146 
147  // Accessible mock to $subject since getFileContents calls GeneralUtility methods
148  $subject = $this->getAccessibleMock(YamlFileLoader::class, ['getFileContents', 'getStreamlinedFileName']);
149  $subject->expects(self::at(0))->method('getStreamlinedFileName')->with($fileName)->willReturn($fileName);
150  $subject->expects(self::at(1))->method('getFileContents')->with($fileName)->willReturn($fileContents);
151  $subject->expects(self::at(2))->method('getStreamlinedFileName')->with($importFileName2, $fileName)->willReturn($importFileName2);
152  $subject->expects(self::at(3))->method('getFileContents')->with($importFileName2)->willReturn($importFileContents2);
153  $subject->expects(self::at(4))->method('getStreamlinedFileName')->with($importFileName, $fileName)->willReturn($importFileName);
154  $subject->expects(self::at(5))->method('getFileContents')->with($importFileName)->willReturn($importFileContents);
155  ‪$output = $subject->load($fileName);
156  self::assertSame($expected, ‪$output);
157  }
158 
164  {
165  $subject = new ‪YamlFileLoader();
166  $result = $subject->load(__DIR__ . '/Fixtures/Berta.yaml');
167  self::assertSame([
168  'enable' => [
169  'frontend' => false,
170  'json.api' => true,
171  'backend' => true,
172  'rest.api' => true,
173  ]
174  ], $result);
175  }
176 
181  public function ‪loadWithPlaceholders(): void
182  {
183  $fileName = 'Berta.yml';
184  $fileContents = '
185 
186 firstset:
187  myinitialversion: 13
188 options:
189  - option1
190  - option2
191 betterthanbefore: \'%firstset.myinitialversion%\'
192 muchbetterthanbefore: \'some::%options.0%::option\'
193 ';
194 
195  $expected = [
196  'firstset' => [
197  'myinitialversion' => 13
198  ],
199  'options' => [
200  'option1',
201  'option2'
202  ],
203  'betterthanbefore' => 13,
204  'muchbetterthanbefore' => 'some::option1::option'
205  ];
206 
207  // Accessible mock to $subject since getFileContents calls GeneralUtility methods
208  $subject = $this->getAccessibleMock(YamlFileLoader::class, ['getFileContents', 'getStreamlinedFileName']);
209  $subject->expects(self::once())->method('getStreamlinedFileName')->with($fileName)->willReturn($fileName);
210  $subject->expects(self::once())->method('getFileContents')->with($fileName)->willReturn($fileContents);
211  ‪$output = $subject->load($fileName);
212  self::assertSame($expected, ‪$output);
213  }
214 
219  public function ‪loadWithNestedPlaceholders(): void
220  {
221  $fileName = 'Berta.yml';
222  $fileContents = '
223 
224 firstset:
225  myinitialversion: 13
226 options:
227  - option1
228  - option2
229 betterthanbefore: \'%env(foo)%\'
230 ';
231 
232  $expected = [
233  'firstset' => [
234  'myinitialversion' => 13
235  ],
236  'options' => [
237  'option1',
238  'option2'
239  ],
240  'betterthanbefore' => 13
241  ];
242 
243  // Accessible mock to $subject since getFileContents calls GeneralUtility methods
244  $subject = $this->getAccessibleMock(YamlFileLoader::class, ['getFileContents', 'getStreamlinedFileName']);
245  $subject->expects(self::once())->method('getStreamlinedFileName')->with($fileName)->willReturn($fileName);
246  $subject->expects(self::once())->method('getFileContents')->with($fileName)->willReturn($fileContents);
247 
248  putenv('foo=%firstset.myinitialversion%');
249  ‪$output = $subject->load($fileName);
250  putenv('foo=');
251  self::assertSame($expected, ‪$output);
252  }
253 
258  public function ‪loadWithImportAndEnvVars(): void
259  {
260  $loader = new ‪YamlFileLoader();
261 
262  putenv('foo=barbaz');
263  ‪$output = $loader->load(__DIR__ . '/Fixtures/Env/Berta.yml');
264  putenv('foo=');
265 
266  $expected = [
267  'loadedWithEnvVars' => 1,
268  'options' => [
269  'optionBefore',
270  'option1',
271  'option2',
272  ],
273  ];
274 
275  self::assertSame($expected, ‪$output);
276  }
277 
278  public function ‪loadWithEnvVarDataProvider(): array
279  {
280  return [
281  'plain' => [
282  ['foo=heinz'],
283  'carl: \'%env(foo)%\'',
284  ['carl' => 'heinz']
285  ],
286  'quoted var' => [
287  ['foo=heinz'],
288  "carl: '%env(''foo'')%'",
289  ['carl' => 'heinz']
290  ],
291  'double quoted var' => [
292  ['foo=heinz'],
293  "carl: '%env(\"foo\")%'",
294  ['carl' => 'heinz']
295  ],
296  'var in the middle' => [
297  ['foo=heinz'],
298  "carl: 'https://%env(foo)%/foo'",
299  ['carl' => 'https://heinz/foo']
300  ],
301  'quoted var in the middle' => [
302  ['foo=heinz'],
303  "carl: 'https://%env(''foo'')%/foo'",
304  ['carl' => 'https://heinz/foo']
305  ],
306  'double quoted var in the middle' => [
307  ['foo=heinz'],
308  "carl: 'https://%env(\"foo\")%/foo'",
309  ['carl' => 'https://heinz/foo']
310  ],
311  'two env vars' => [
312  ['foo=karl', 'bar=heinz'],
313  'carl: \'%env(foo)%::%env(bar)%\'',
314  ['carl' => 'karl::heinz']
315  ],
316  'three env vars' => [
317  ['foo=karl', 'bar=heinz', 'baz=bencer'],
318  'carl: \'%env(foo)%::%env(bar)%::%env(baz)%\'',
319  ['carl' => 'karl::heinz::bencer']
320  ],
321  'three env vars with baz being undefined' => [
322  ['foo=karl', 'bar=heinz'],
323  'carl: \'%env(foo)%::%env(bar)%::%env(baz)%\'',
324  ['carl' => 'karl::heinz::%env(baz)%']
325  ],
326  'three undefined env vars' => [
327  [],
328  'carl: \'%env(foo)%::%env(bar)%::%env(baz)%\'',
329  ['carl' => '%env(foo)%::%env(bar)%::%env(baz)%']
330  ],
331  'nested env variables' => [
332  ['foo=bar', 'bar=heinz'],
333  'carl: \'%env(%env(foo)%)%\'',
334  ['carl' => 'heinz']
335  ],
336  ];
337  }
338 
348  public function ‪loadWithEnvVarPlaceholders(array $envs, string $yamlContent, array $expected): void
349  {
350  foreach ($envs as $env) {
351  putenv($env);
352  }
353  $fileName = 'Berta.yml';
354  $fileContents = $yamlContent;
355 
356  // Accessible mock to $subject since getFileContents calls GeneralUtility methods
357  $subject = $this->getAccessibleMock(YamlFileLoader::class, ['getFileContents', 'getStreamlinedFileName']);
358  $subject->expects(self::once())->method('getStreamlinedFileName')->with($fileName)->willReturn($fileName);
359  $subject->expects(self::once())->method('getFileContents')->with($fileName)->willReturn($fileContents);
360  ‪$output = $subject->load($fileName);
361  self::assertSame($expected, ‪$output);
362  putenv('foo=');
363  putenv('bar=');
364  putenv('baz=');
365  }
366 
373  {
374  $fileName = 'Berta.yml';
375  $fileContents = '
376 
377 firstset:
378  myinitialversion: 13
379 options:
380  - option1
381  - option2
382 betterthanbefore: \'%env(mynonexistingenv)%\'
383 ';
384 
385  $expected = [
386  'firstset' => [
387  'myinitialversion' => 13
388  ],
389  'options' => [
390  'option1',
391  'option2'
392  ],
393  'betterthanbefore' => '%env(mynonexistingenv)%'
394  ];
395 
396  // Accessible mock to $subject since getFileContents calls GeneralUtility methods
397  $subject = $this->getAccessibleMock(YamlFileLoader::class, ['getFileContents', 'getStreamlinedFileName']);
398  $subject->expects(self::once())->method('getStreamlinedFileName')->with($fileName)->willReturn($fileName);
399  $subject->expects(self::once())->method('getFileContents')->with($fileName)->willReturn($fileContents);
400  ‪$output = $subject->load($fileName);
401  self::assertSame($expected, ‪$output);
402  }
403 
409  {
410  return [
411  'regular string' => [
412  'berta13',
413  false
414  ],
415  'regular array' => [
416  ['berta13'],
417  false
418  ],
419  'regular float' => [
420  13.131313,
421  false
422  ],
423  'regular int' => [
424  13,
425  false
426  ],
427  'invalid placeholder with only % at the beginning' => [
428  '%cool',
429  false
430  ],
431  'invalid placeholder with only % at the end' => [
432  'cool%',
433  false
434  ],
435  'invalid placeholder with two % but not at the end' => [
436  '%cool%again',
437  true
438  ],
439  'invalid placeholder with two % but not at the beginning nor end' => [
440  'did%you%know',
441  true
442  ],
443  'valid placeholder with just numbers' => [
444  '%13%',
445  true
446  ],
447  'valid placeholder' => [
448  '%foo%baracks%',
449  true
450  ],
451  ];
452  }
453 
461  public function ‪containsPlaceholderTest($placeholderValue, bool $expected)
462  {
463  $subject = $this->getAccessibleMock(YamlFileLoader::class, ['dummy']);
464  ‪$output = $subject->_call('containsPlaceholder', $placeholderValue);
465  self::assertSame($expected, ‪$output);
466  }
467 }
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\loadWithNestedPlaceholders
‪loadWithNestedPlaceholders()
Definition: YamlFileLoaderTest.php:219
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\loadWithImportAndEnvVars
‪loadWithImportAndEnvVars()
Definition: YamlFileLoaderTest.php:258
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\loadWithImportAndRelativePaths
‪loadWithImportAndRelativePaths()
Definition: YamlFileLoaderTest.php:163
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\containsPlaceholderTest
‪containsPlaceholderTest($placeholderValue, bool $expected)
Definition: YamlFileLoaderTest.php:461
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader
Definition: PageTsConfigLoaderTest.php:18
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\loadWithAnImport
‪loadWithAnImport()
Definition: YamlFileLoaderTest.php:62
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest
Definition: YamlFileLoaderTest.php:27
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\loadWithEnvVarDataProvider
‪loadWithEnvVarDataProvider()
Definition: YamlFileLoaderTest.php:278
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\isPlaceholderDataProvider
‪array isPlaceholderDataProvider()
Definition: YamlFileLoaderTest.php:408
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\loadWithPlaceholders
‪loadWithPlaceholders()
Definition: YamlFileLoaderTest.php:181
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\loadWithEnvVarPlaceholders
‪loadWithEnvVarPlaceholders(array $envs, string $yamlContent, array $expected)
Definition: YamlFileLoaderTest.php:348
‪$output
‪$output
Definition: annotationChecker.php:119
‪TYPO3\CMS\Core\Configuration\Loader\YamlFileLoader
Definition: YamlFileLoader.php:48
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\loadWithMultipleImports
‪loadWithMultipleImports()
Definition: YamlFileLoaderTest.php:107
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\loadWithEnvVarPlaceholdersDoesNotReplaceWithNonExistingValues
‪loadWithEnvVarPlaceholdersDoesNotReplaceWithNonExistingValues()
Definition: YamlFileLoaderTest.php:372
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Loader\YamlFileLoaderTest\load
‪load()
Definition: YamlFileLoaderTest.php:32