refactor(console, id, config): Dialog mode in Console, consolidated id modul, added config support for ini directives
This commit is contained in:
44
tests/Unit/Framework/Core/System/Ini/AccessTest.php
Normal file
44
tests/Unit/Framework/Core/System/Ini/AccessTest.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Core\System\Ini\Access;
|
||||
|
||||
describe('Access', function () {
|
||||
it('converts INI_USER bitmask to USER enum', function () {
|
||||
$access = Access::fromBitmask(INI_USER);
|
||||
|
||||
expect($access)->toBe(Access::USER);
|
||||
});
|
||||
|
||||
it('converts INI_PERDIR bitmask to PERDIR enum', function () {
|
||||
$access = Access::fromBitmask(INI_PERDIR);
|
||||
|
||||
expect($access)->toBe(Access::PERDIR);
|
||||
});
|
||||
|
||||
it('converts INI_SYSTEM bitmask to SYSTEM enum', function () {
|
||||
$access = Access::fromBitmask(INI_SYSTEM);
|
||||
|
||||
expect($access)->toBe(Access::SYSTEM);
|
||||
});
|
||||
|
||||
it('converts INI_ALL bitmask to ALL enum', function () {
|
||||
$access = Access::fromBitmask(INI_ALL);
|
||||
|
||||
expect($access)->toBe(Access::ALL);
|
||||
});
|
||||
|
||||
it('throws exception for invalid bitmask', function () {
|
||||
expect(fn () => Access::fromBitmask(999))
|
||||
->toThrow(InvalidArgumentException::class, 'Invalid bitmask value: 999');
|
||||
});
|
||||
|
||||
it('has correct string values', function () {
|
||||
expect(Access::USER->value)->toBe('USER');
|
||||
expect(Access::PERDIR->value)->toBe('Per Directory');
|
||||
expect(Access::SYSTEM->value)->toBe('System');
|
||||
expect(Access::ALL->value)->toBe('All');
|
||||
});
|
||||
});
|
||||
|
||||
95
tests/Unit/Framework/Core/System/Ini/IniDirectiveTest.php
Normal file
95
tests/Unit/Framework/Core/System/Ini/IniDirectiveTest.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Core\System\Ini\Access;
|
||||
use App\Framework\Core\System\Ini\IniDirective;
|
||||
|
||||
describe('IniDirective', function () {
|
||||
it('returns Access enum from getAccess()', function () {
|
||||
$directive = new IniDirective(
|
||||
name: 'test_directive',
|
||||
value: 'test_value',
|
||||
global: 'global_value',
|
||||
accessMask: INI_USER
|
||||
);
|
||||
|
||||
$access = $directive->getAccess();
|
||||
|
||||
expect($access)->toBeInstanceOf(Access::class);
|
||||
expect($access)->toBe(Access::USER);
|
||||
});
|
||||
|
||||
it('returns access mask from getAccessMask()', function () {
|
||||
$directive = new IniDirective(
|
||||
name: 'test_directive',
|
||||
value: 'test_value',
|
||||
global: 'global_value',
|
||||
accessMask: INI_USER
|
||||
);
|
||||
|
||||
$mask = $directive->getAccessMask();
|
||||
|
||||
expect($mask)->toBeInt();
|
||||
expect($mask)->toBe(INI_USER);
|
||||
});
|
||||
|
||||
it('correctly converts INI_USER bitmask', function () {
|
||||
$directive = new IniDirective(
|
||||
name: 'test_directive',
|
||||
value: 'test_value',
|
||||
global: 'global_value',
|
||||
accessMask: INI_USER
|
||||
);
|
||||
|
||||
expect($directive->getAccess())->toBe(Access::USER);
|
||||
});
|
||||
|
||||
it('correctly converts INI_PERDIR bitmask', function () {
|
||||
$directive = new IniDirective(
|
||||
name: 'test_directive',
|
||||
value: 'test_value',
|
||||
global: 'global_value',
|
||||
accessMask: INI_PERDIR
|
||||
);
|
||||
|
||||
expect($directive->getAccess())->toBe(Access::PERDIR);
|
||||
});
|
||||
|
||||
it('correctly converts INI_SYSTEM bitmask', function () {
|
||||
$directive = new IniDirective(
|
||||
name: 'test_directive',
|
||||
value: 'test_value',
|
||||
global: 'global_value',
|
||||
accessMask: INI_SYSTEM
|
||||
);
|
||||
|
||||
expect($directive->getAccess())->toBe(Access::SYSTEM);
|
||||
});
|
||||
|
||||
it('correctly converts INI_ALL bitmask', function () {
|
||||
$directive = new IniDirective(
|
||||
name: 'test_directive',
|
||||
value: 'test_value',
|
||||
global: 'global_value',
|
||||
accessMask: INI_ALL
|
||||
);
|
||||
|
||||
expect($directive->getAccess())->toBe(Access::ALL);
|
||||
});
|
||||
|
||||
it('stores and returns all properties correctly', function () {
|
||||
$directive = new IniDirective(
|
||||
name: 'my_directive',
|
||||
value: 'my_value',
|
||||
global: 'global_value',
|
||||
accessMask: INI_USER
|
||||
);
|
||||
|
||||
expect($directive->name)->toBe('my_directive');
|
||||
expect($directive->value)->toBe('my_value');
|
||||
expect($directive->global)->toBe('global_value');
|
||||
expect($directive->getAccessMask())->toBe(INI_USER);
|
||||
});
|
||||
});
|
||||
|
||||
70
tests/Unit/Framework/Core/System/Ini/IniKeyTest.php
Normal file
70
tests/Unit/Framework/Core/System/Ini/IniKeyTest.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Core\System\Ini\IniKey;
|
||||
|
||||
describe('IniKey', function () {
|
||||
it('has correct string value for MEMORY_LIMIT', function () {
|
||||
expect(IniKey::MEMORY_LIMIT->value)->toBe('memory_limit');
|
||||
});
|
||||
|
||||
it('has correct string value for MAX_EXECUTION_TIME', function () {
|
||||
expect(IniKey::MAX_EXECUTION_TIME->value)->toBe('max_execution_time');
|
||||
});
|
||||
|
||||
it('has correct string value for UPLOAD_MAX_FILESIZE', function () {
|
||||
expect(IniKey::UPLOAD_MAX_FILESIZE->value)->toBe('upload_max_filesize');
|
||||
});
|
||||
|
||||
it('has correct string value for POST_MAX_SIZE', function () {
|
||||
expect(IniKey::POST_MAX_SIZE->value)->toBe('post_max_size');
|
||||
});
|
||||
|
||||
it('has correct string value for DISPLAY_ERRORS', function () {
|
||||
expect(IniKey::DISPLAY_ERRORS->value)->toBe('display_errors');
|
||||
});
|
||||
|
||||
it('has correct string value for LOG_ERRORS', function () {
|
||||
expect(IniKey::LOG_ERRORS->value)->toBe('log_errors');
|
||||
});
|
||||
|
||||
it('has correct string value for DATE_TIMEZONE', function () {
|
||||
expect(IniKey::DATE_TIMEZONE->value)->toBe('date.timezone');
|
||||
});
|
||||
|
||||
it('has correct string value for ERROR_REPORTING', function () {
|
||||
expect(IniKey::ERROR_REPORTING->value)->toBe('error_reporting');
|
||||
});
|
||||
|
||||
it('has correct string value for ERROR_LOG', function () {
|
||||
expect(IniKey::ERROR_LOG->value)->toBe('error_log');
|
||||
});
|
||||
|
||||
it('has all expected commonly used keys', function () {
|
||||
$expectedKeys = [
|
||||
'memory_limit',
|
||||
'max_execution_time',
|
||||
'max_input_time',
|
||||
'upload_max_filesize',
|
||||
'post_max_size',
|
||||
'max_file_uploads',
|
||||
'display_errors',
|
||||
'display_startup_errors',
|
||||
'error_log',
|
||||
'date.timezone',
|
||||
'log_errors',
|
||||
'error_reporting',
|
||||
];
|
||||
|
||||
$actualValues = array_map(
|
||||
fn (IniKey $key) => $key->value,
|
||||
IniKey::cases()
|
||||
);
|
||||
|
||||
foreach ($expectedKeys as $expectedKey) {
|
||||
expect($actualValues)->toContain($expectedKey);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
165
tests/Unit/Framework/Core/System/Ini/IniManagerTest.php
Normal file
165
tests/Unit/Framework/Core/System/Ini/IniManagerTest.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Core\System\Ini\Access;
|
||||
use App\Framework\Core\System\Ini\IniDirective;
|
||||
use App\Framework\Core\System\Ini\IniKey;
|
||||
use App\Framework\Core\System\Ini\IniManager;
|
||||
|
||||
describe('IniManager', function () {
|
||||
it('gets ini value by IniKey enum', function () {
|
||||
$manager = new IniManager();
|
||||
$value = $manager->get(IniKey::MEMORY_LIMIT);
|
||||
|
||||
expect($value)->not->toBeNull();
|
||||
expect($value)->toBeString();
|
||||
});
|
||||
|
||||
it('gets ini value by string key', function () {
|
||||
$manager = new IniManager();
|
||||
$value = $manager->get('memory_limit');
|
||||
|
||||
expect($value)->not->toBeNull();
|
||||
expect($value)->toBeString();
|
||||
});
|
||||
|
||||
it('returns null for non-existent key', function () {
|
||||
$manager = new IniManager();
|
||||
$value = $manager->get('non_existent_ini_key_12345');
|
||||
|
||||
expect($value)->toBeNull();
|
||||
});
|
||||
|
||||
it('sets ini value for modifiable key', function () {
|
||||
$manager = new IniManager();
|
||||
|
||||
// Get original value
|
||||
$original = $manager->get(IniKey::DISPLAY_ERRORS);
|
||||
|
||||
// Set a new value
|
||||
$result = $manager->set(IniKey::DISPLAY_ERRORS, '1');
|
||||
|
||||
// Restore original value
|
||||
if ($original !== null) {
|
||||
$manager->set(IniKey::DISPLAY_ERRORS, $original);
|
||||
}
|
||||
|
||||
expect($result)->toBeTrue();
|
||||
});
|
||||
|
||||
it('gets directive object with access information', function () {
|
||||
$manager = new IniManager();
|
||||
$directive = $manager->getDirective(IniKey::MEMORY_LIMIT);
|
||||
|
||||
expect($directive)->toBeInstanceOf(IniDirective::class);
|
||||
expect($directive->name)->toBe('memory_limit');
|
||||
expect($directive->value)->not->toBeEmpty();
|
||||
expect($directive->getAccess())->toBeInstanceOf(Access::class);
|
||||
});
|
||||
|
||||
it('returns null for non-existent directive', function () {
|
||||
$manager = new IniManager();
|
||||
// Using a key that likely doesn't exist
|
||||
$directive = $manager->getDirective(IniKey::ALLOW_URL_INCLUDE);
|
||||
|
||||
// This might return null if the directive is not available
|
||||
// or return an IniDirective if it exists
|
||||
if ($directive === null) {
|
||||
expect($directive)->toBeNull();
|
||||
} else {
|
||||
expect($directive)->toBeInstanceOf(IniDirective::class);
|
||||
}
|
||||
});
|
||||
|
||||
it('gets all ini directives', function () {
|
||||
$manager = new IniManager();
|
||||
$all = $manager->getAll();
|
||||
|
||||
expect($all)->toBeArray();
|
||||
expect($all)->not->toBeEmpty();
|
||||
|
||||
// Check that all values are IniDirective objects
|
||||
foreach ($all as $name => $directive) {
|
||||
expect($name)->toBeString();
|
||||
expect($directive)->toBeInstanceOf(IniDirective::class);
|
||||
}
|
||||
});
|
||||
|
||||
it('filters directives by access level', function () {
|
||||
$manager = new IniManager();
|
||||
$userDirectives = $manager->getAllByAccess(Access::USER);
|
||||
|
||||
expect($userDirectives)->toBeArray();
|
||||
|
||||
// Verify all returned directives have the correct access level
|
||||
foreach ($userDirectives as $directive) {
|
||||
expect($directive->getAccess())->toBe(Access::USER);
|
||||
}
|
||||
});
|
||||
|
||||
it('checks if directive is modifiable', function () {
|
||||
$manager = new IniManager();
|
||||
|
||||
// DISPLAY_ERRORS is typically INI_USER and should be modifiable
|
||||
$isModifiable = $manager->isModifiable(IniKey::DISPLAY_ERRORS);
|
||||
|
||||
expect($isModifiable)->toBeBool();
|
||||
});
|
||||
|
||||
it('returns false for non-modifiable directive', function () {
|
||||
$manager = new IniManager();
|
||||
|
||||
// Some directives like ENGINE are typically INI_SYSTEM and not modifiable
|
||||
// MEMORY_LIMIT might be INI_SYSTEM depending on configuration
|
||||
$directive = $manager->getDirective(IniKey::MEMORY_LIMIT);
|
||||
|
||||
if ($directive !== null) {
|
||||
$isModifiable = $manager->isModifiable(IniKey::MEMORY_LIMIT);
|
||||
|
||||
// If it's SYSTEM or PERDIR, it should not be modifiable
|
||||
if ($directive->getAccess() === Access::SYSTEM || $directive->getAccess() === Access::PERDIR) {
|
||||
expect($isModifiable)->toBeFalse();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('handles enum and string keys consistently', function () {
|
||||
$manager = new IniManager();
|
||||
|
||||
$valueFromEnum = $manager->get(IniKey::MEMORY_LIMIT);
|
||||
$valueFromString = $manager->get('memory_limit');
|
||||
|
||||
expect($valueFromEnum)->toBe($valueFromString);
|
||||
});
|
||||
|
||||
it('updates cached directive after set', function () {
|
||||
$manager = new IniManager();
|
||||
|
||||
// Get original value
|
||||
$original = $manager->get(IniKey::DISPLAY_ERRORS);
|
||||
$originalDirective = $manager->getDirective(IniKey::DISPLAY_ERRORS);
|
||||
|
||||
if ($originalDirective === null || $original === null) {
|
||||
return; // Skip if directive doesn't exist
|
||||
}
|
||||
|
||||
// Set a new value
|
||||
$newValue = '1';
|
||||
$result = $manager->set(IniKey::DISPLAY_ERRORS, $newValue);
|
||||
|
||||
expect($result)->toBeTrue();
|
||||
|
||||
// Verify cached value is updated
|
||||
$updatedValue = $manager->get(IniKey::DISPLAY_ERRORS);
|
||||
$updatedDirective = $manager->getDirective(IniKey::DISPLAY_ERRORS);
|
||||
|
||||
expect($updatedValue)->toBe($newValue);
|
||||
expect($updatedDirective)->not->toBeNull();
|
||||
expect($updatedDirective->value)->toBe($newValue);
|
||||
|
||||
// Restore original value
|
||||
$manager->set(IniKey::DISPLAY_ERRORS, $original);
|
||||
});
|
||||
});
|
||||
|
||||
113
tests/Unit/Framework/Core/System/SystemConfigTest.php
Normal file
113
tests/Unit/Framework/Core/System/SystemConfigTest.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Config\Environment;
|
||||
use App\Framework\Core\System\Ini\IniKey;
|
||||
use App\Framework\Core\System\Ini\IniManager;
|
||||
use App\Framework\Core\System\SystemConfig;
|
||||
|
||||
describe('SystemConfig', function () {
|
||||
it('provides access to ini manager via property', function () {
|
||||
$iniManager = new IniManager();
|
||||
$environment = new Environment();
|
||||
$config = new SystemConfig($iniManager, $environment);
|
||||
|
||||
expect($config->ini)->toBeInstanceOf(IniManager::class);
|
||||
expect($config->ini)->toBe($iniManager);
|
||||
});
|
||||
|
||||
it('provides access to environment via property', function () {
|
||||
$iniManager = new IniManager();
|
||||
$environment = new Environment();
|
||||
$config = new SystemConfig($iniManager, $environment);
|
||||
|
||||
expect($config->environment)->toBeInstanceOf(Environment::class);
|
||||
expect($config->environment)->toBe($environment);
|
||||
});
|
||||
|
||||
it('allows accessing ini values through ini property', function () {
|
||||
$iniManager = new IniManager();
|
||||
$environment = new Environment();
|
||||
$config = new SystemConfig($iniManager, $environment);
|
||||
|
||||
$value = $config->ini->get(IniKey::MEMORY_LIMIT);
|
||||
|
||||
expect($value)->not->toBeNull();
|
||||
expect($value)->toBeString();
|
||||
});
|
||||
|
||||
it('allows accessing ini values by string key', function () {
|
||||
$iniManager = new IniManager();
|
||||
$environment = new Environment();
|
||||
$config = new SystemConfig($iniManager, $environment);
|
||||
|
||||
$value = $config->ini->get('memory_limit');
|
||||
|
||||
expect($value)->not->toBeNull();
|
||||
expect($value)->toBeString();
|
||||
});
|
||||
|
||||
it('allows accessing environment variables through environment property', function () {
|
||||
$iniManager = new IniManager();
|
||||
$environment = new Environment(['TEST_KEY' => 'test_value']);
|
||||
$config = new SystemConfig($iniManager, $environment);
|
||||
|
||||
$value = $config->environment->get('TEST_KEY');
|
||||
|
||||
expect($value)->toBe('test_value');
|
||||
});
|
||||
|
||||
it('allows accessing all ini manager methods', function () {
|
||||
$iniManager = new IniManager();
|
||||
$environment = new Environment();
|
||||
$config = new SystemConfig($iniManager, $environment);
|
||||
|
||||
// Test getDirective
|
||||
$directive = $config->ini->getDirective(IniKey::MEMORY_LIMIT);
|
||||
expect($directive)->not->toBeNull();
|
||||
|
||||
// Test getAll
|
||||
$all = $config->ini->getAll();
|
||||
expect($all)->toBeArray();
|
||||
expect($all)->not->toBeEmpty();
|
||||
|
||||
// Test isModifiable
|
||||
$isModifiable = $config->ini->isModifiable(IniKey::DISPLAY_ERRORS);
|
||||
expect($isModifiable)->toBeBool();
|
||||
});
|
||||
|
||||
it('allows accessing all environment methods', function () {
|
||||
$iniManager = new IniManager();
|
||||
$environment = new Environment([
|
||||
'TEST_STRING' => 'hello',
|
||||
'TEST_INT' => '42',
|
||||
'TEST_BOOL' => 'true',
|
||||
]);
|
||||
$config = new SystemConfig($iniManager, $environment);
|
||||
|
||||
// Test getString
|
||||
expect($config->environment->getString('TEST_STRING'))->toBe('hello');
|
||||
|
||||
// Test getInt
|
||||
expect($config->environment->getInt('TEST_INT'))->toBe(42);
|
||||
|
||||
// Test getBool
|
||||
expect($config->environment->getBool('TEST_BOOL'))->toBeTrue();
|
||||
|
||||
// Test has
|
||||
expect($config->environment->has('TEST_STRING'))->toBeTrue();
|
||||
expect($config->environment->has('NON_EXISTENT'))->toBeFalse();
|
||||
});
|
||||
|
||||
it('properties are readonly', function () {
|
||||
$iniManager = new IniManager();
|
||||
$environment = new Environment();
|
||||
$config = new SystemConfig($iniManager, $environment);
|
||||
|
||||
// Properties should be accessible but not modifiable (readonly class)
|
||||
expect($config->ini)->toBe($iniManager);
|
||||
expect($config->environment)->toBe($environment);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Cuid\Cuid;
|
||||
use App\Framework\Cuid\CuidGenerator;
|
||||
use App\Framework\Id\Cuid\Cuid;
|
||||
use App\Framework\Id\Cuid\CuidGenerator;
|
||||
use App\Framework\Random\SecureRandomGenerator;
|
||||
|
||||
it('generates Cuid with current timestamp', function () {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Cuid\Cuid;
|
||||
use App\Framework\Id\Cuid\Cuid;
|
||||
|
||||
it('creates Cuid from string', function () {
|
||||
$value = 'cjld2cjxh0000qzrmn831i7rn';
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Ksuid\Ksuid;
|
||||
use App\Framework\Ksuid\KsuidGenerator;
|
||||
use App\Framework\Id\Ksuid\Ksuid;
|
||||
use App\Framework\Id\Ksuid\KsuidGenerator;
|
||||
use App\Framework\Random\SecureRandomGenerator;
|
||||
|
||||
it('generates KSUID with current timestamp', function () {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Ksuid\Ksuid;
|
||||
use App\Framework\Id\Ksuid\Ksuid;
|
||||
|
||||
it('creates KSUID from string', function () {
|
||||
$value = '2SwcbqZrBNGd67ZJYmPKx42wKZj';
|
||||
|
||||
@@ -159,7 +159,7 @@ final class CorrelationIdTest extends TestCase
|
||||
|
||||
public function test_creates_from_ulid(): void
|
||||
{
|
||||
$ulid = \App\Framework\Ulid\Ulid::generate();
|
||||
$ulid = \App\Framework\Id\Ulid\Ulid::generate();
|
||||
$id = CorrelationId::fromUlid($ulid);
|
||||
|
||||
$this->assertEquals((string) $ulid, $id->toString());
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\DateTime\SystemClock;
|
||||
use App\Framework\Id\Ulid\UlidGenerator;
|
||||
use App\Framework\MagicLinks\MagicLinkToken;
|
||||
use App\Framework\MagicLinks\Services\InMemoryMagicLinkService;
|
||||
use App\Framework\MagicLinks\TokenAction;
|
||||
use App\Framework\MagicLinks\TokenConfig;
|
||||
use App\Framework\Ulid\UlidGenerator;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->clock = new SystemClock();
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\NanoId\NanoId;
|
||||
use App\Framework\NanoId\NanoIdGenerator;
|
||||
use App\Framework\Id\NanoId\NanoId;
|
||||
use App\Framework\Id\NanoId\NanoIdGenerator;
|
||||
use App\Framework\Random\SecureRandomGenerator;
|
||||
|
||||
it('creates generator with default settings', function () {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\NanoId\NanoId;
|
||||
use App\Framework\Id\NanoId\NanoId;
|
||||
|
||||
it('creates NanoId from string', function () {
|
||||
$value = 'test123ABC';
|
||||
|
||||
Reference in New Issue
Block a user