firefly-import-preprocessor/tests/ConfigurationLoaderTest.php
Reindl David (IT-PTR-CEN2-SL10) 170b2d2016 release 1.0
2026-05-02 17:53:19 +02:00

256 lines
8.8 KiB
PHP

<?php
namespace UbsCsvTransformer\Tests;
use PHPUnit\Framework\TestCase;
use UbsCsvTransformer\ConfigurationLoader;
class ConfigurationLoaderTest extends TestCase
{
private string $tempFile = '';
protected function setUp(): void
{
// uniqid gives a unique name; .json extension satisfies the loader's check
$this->tempFile = sys_get_temp_dir() . '/cfgloader_test_' . uniqid() . '.json';
}
protected function tearDown(): void
{
if (file_exists($this->tempFile)) {
unlink($this->tempFile);
}
}
private function writeJson(array $data): void
{
file_put_contents($this->tempFile, json_encode($data));
}
/**
* Minimal valid configuration that passes all validation checks.
*/
private function validConfig(): array
{
return [
'metadata' => [
'extractionRules' => [
['name' => 'account_iban', 'lineNumber' => 1, 'regex' => '(.+)'],
],
],
'csvStructure' => [
'headerLine' => 1,
'inputDelimiter' => ';',
'encoding' => 'UTF-8',
],
'columnTransformations' => [
['sourceColumn' => 'A', 'outputColumn' => 'B', 'type' => 'map'],
],
];
}
// -------------------------------------------------------------------------
// Happy path
// -------------------------------------------------------------------------
public function testLoadValidConfigReturnsArray(): void
{
$this->writeJson($this->validConfig());
$loader = new ConfigurationLoader($this->tempFile);
$config = $loader->load();
$this->assertIsArray($config);
$this->assertArrayHasKey('metadata', $config);
$this->assertArrayHasKey('csvStructure', $config);
$this->assertArrayHasKey('columnTransformations', $config);
}
public function testGetAllReturnsFullConfig(): void
{
$this->writeJson($this->validConfig());
$loader = new ConfigurationLoader($this->tempFile);
$loader->load();
$all = $loader->getAll();
$this->assertSame(1, $all['csvStructure']['headerLine']);
}
// -------------------------------------------------------------------------
// get() dot-notation accessor
// -------------------------------------------------------------------------
public function testGetDotNotationReturnsValue(): void
{
$this->writeJson($this->validConfig());
$loader = new ConfigurationLoader($this->tempFile);
$loader->load();
$this->assertSame(1, $loader->get('csvStructure.headerLine'));
$this->assertSame(';', $loader->get('csvStructure.inputDelimiter'));
}
public function testGetNonExistentKeyReturnsNull(): void
{
$this->writeJson($this->validConfig());
$loader = new ConfigurationLoader($this->tempFile);
$loader->load();
$this->assertNull($loader->get('nonexistent.key'));
}
public function testGetNonExistentKeyReturnsDefault(): void
{
$this->writeJson($this->validConfig());
$loader = new ConfigurationLoader($this->tempFile);
$loader->load();
$this->assertSame('fallback', $loader->get('nonexistent', 'fallback'));
}
// -------------------------------------------------------------------------
// File not found / bad extension
// -------------------------------------------------------------------------
public function testFileNotFoundThrows(): void
{
$this->expectException(\RuntimeException::class);
$loader = new ConfigurationLoader('/nonexistent/path/config.json');
$loader->load();
}
public function testNonJsonExtensionThrows(): void
{
$yamlPath = sys_get_temp_dir() . '/test_config_' . uniqid() . '.yaml';
file_put_contents($yamlPath, 'key: value');
try {
$loader = new ConfigurationLoader($yamlPath);
$this->expectException(\RuntimeException::class);
$loader->load();
} finally {
if (file_exists($yamlPath)) {
unlink($yamlPath);
}
}
}
public function testInvalidJsonThrows(): void
{
file_put_contents($this->tempFile, '{invalid json content}');
$this->expectException(\RuntimeException::class);
(new ConfigurationLoader($this->tempFile))->load();
}
// -------------------------------------------------------------------------
// Required top-level sections
// -------------------------------------------------------------------------
public function testMissingMetadataSectionThrows(): void
{
$config = $this->validConfig();
unset($config['metadata']);
$this->writeJson($config);
$this->expectException(\RuntimeException::class);
(new ConfigurationLoader($this->tempFile))->load();
}
public function testMissingExtractionRulesThrows(): void
{
$config = $this->validConfig();
unset($config['metadata']['extractionRules']);
$this->writeJson($config);
$this->expectException(\RuntimeException::class);
(new ConfigurationLoader($this->tempFile))->load();
}
public function testMissingCsvStructureSectionThrows(): void
{
$config = $this->validConfig();
unset($config['csvStructure']);
$this->writeJson($config);
$this->expectException(\RuntimeException::class);
(new ConfigurationLoader($this->tempFile))->load();
}
public function testMissingHeaderLineThrows(): void
{
$config = $this->validConfig();
unset($config['csvStructure']['headerLine']);
$this->writeJson($config);
$this->expectException(\RuntimeException::class);
(new ConfigurationLoader($this->tempFile))->load();
}
public function testMissingColumnTransformationsThrows(): void
{
$config = $this->validConfig();
unset($config['columnTransformations']);
$this->writeJson($config);
$this->expectException(\RuntimeException::class);
(new ConfigurationLoader($this->tempFile))->load();
}
// -------------------------------------------------------------------------
// csvStructure value validation
// -------------------------------------------------------------------------
public function testInvalidEncodingThrows(): void
{
$config = $this->validConfig();
$config['csvStructure']['encoding'] = 'LATIN1';
$this->writeJson($config);
$this->expectException(\Exception::class);
(new ConfigurationLoader($this->tempFile))->load();
}
public function testSupportedEncodingsPass(): void
{
foreach (['UTF-8', 'ISO-8859-1', 'CP1252'] as $encoding) {
$config = $this->validConfig();
$config['csvStructure']['encoding'] = $encoding;
$this->writeJson($config);
$loader = new ConfigurationLoader($this->tempFile);
$result = $loader->load();
$this->assertSame($encoding, $result['csvStructure']['encoding']);
}
}
// -------------------------------------------------------------------------
// directories validation
// -------------------------------------------------------------------------
public function testDirectoriesAllKeysPass(): void
{
$config = $this->validConfig();
$config['directories'] = [
'source' => '/tmp/source',
'output' => '/tmp/output',
'archive' => '/tmp/archive',
'error' => '/tmp/error',
];
$this->writeJson($config);
$result = (new ConfigurationLoader($this->tempFile))->load();
$this->assertArrayHasKey('directories', $result);
}
public function testDirectoriesMissingSubkeyThrows(): void
{
$config = $this->validConfig();
$config['directories'] = [
'source' => '/tmp/source',
'output' => '/tmp/output',
// 'archive' and 'error' intentionally missing
];
$this->writeJson($config);
$this->expectException(\RuntimeException::class);
(new ConfigurationLoader($this->tempFile))->load();
}
// -------------------------------------------------------------------------
// Absent optional 'directories' key does not trigger validation
// -------------------------------------------------------------------------
public function testAbsentDirectoriesKeyDoesNotThrow(): void
{
$config = $this->validConfig();
$this->assertArrayNotHasKey('directories', $config);
$this->writeJson($config);
$result = (new ConfigurationLoader($this->tempFile))->load();
$this->assertArrayNotHasKey('directories', $result);
}
}