Enable Discovery debug logging for production troubleshooting

- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -0,0 +1,163 @@
<?php
declare(strict_types=1);
use App\Framework\Reflection\CachedReflectionProvider;
use App\Framework\Validation\GroupAware;
use App\Framework\Validation\Rules\Email;
use App\Framework\Validation\Rules\Required;
use App\Framework\Validation\Rules\StringLength;
use App\Framework\Validation\ValidationResult;
use App\Framework\Validation\ValidationRule;
use App\Framework\Validation\Validator;
beforeEach(function () {
$reflectionProvider = new CachedReflectionProvider();
$this->validator = new Validator($reflectionProvider);
});
test('validation passes for valid object', function () {
$object = new ValidTestObject('test@example.com', 'John Doe');
$result = $this->validator->validate($object);
expect($result->hasErrors())->toBeFalse();
});
test('validation fails for invalid email', function () {
$object = new ValidTestObject('invalid-email', 'John Doe');
$result = $this->validator->validate($object);
expect($result->hasErrors())->toBeTrue()
->and($result->getFieldErrors('email'))->not->toBeEmpty();
});
test('validation fails for empty required field', function () {
$object = new ValidTestObject('test@example.com', '');
$result = $this->validator->validate($object);
expect($result->hasErrors())->toBeTrue()
->and($result->getFieldErrors('name'))->not->toBeEmpty();
});
test('validation fails for too short string', function () {
$object = new ValidTestObject('test@example.com', 'Jo'); // Too short
$result = $this->validator->validate($object);
expect($result->hasErrors())->toBeTrue()
->and($result->getFieldErrors('name'))->not->toBeEmpty();
});
test('validation with groups only validates specified group', function () {
$object = new GroupedTestObject('test@example.com', '');
// Validate only 'basic' group - should pass
$result = $this->validator->validate($object, 'basic');
expect($result->hasErrors())->toBeFalse();
// Validate 'extended' group - should fail due to empty name
$result = $this->validator->validate($object, 'extended');
expect($result->hasErrors())->toBeTrue()
->and($result->getFieldErrors('name'))->not->toBeEmpty();
});
test('validation handles uninitialized non-nullable properties', function () {
$object = new UninitializedTestObject();
$result = $this->validator->validate($object);
expect($result->hasErrors())->toBeTrue()
->and($result->getFieldErrors('requiredField'))->not->toBeEmpty();
});
test('validation handles nullable properties correctly', function () {
$object = new NullableTestObject();
$result = $this->validator->validate($object);
expect($result->hasErrors())->toBeFalse();
});
test('multiple validation errors are collected', function () {
$object = new ValidTestObject('invalid', ''); // Both email and name invalid
$result = $this->validator->validate($object);
expect($result->hasErrors())->toBeTrue()
->and($result->getFieldErrors('email'))->not->toBeEmpty()
->and($result->getFieldErrors('name'))->not->toBeEmpty()
->and($result->getAllErrorMessages())->toHaveCount(2);
});
test('validation result can be merged', function () {
$result1 = new ValidationResult();
$result1->addError('field1', 'Error 1');
$result2 = new ValidationResult();
$result2->addError('field2', 'Error 2');
$merged = $result1->merge($result2);
expect($merged->getFieldErrors('field1'))->toContain('Error 1')
->and($merged->getFieldErrors('field2'))->toContain('Error 2')
->and($merged->getAllErrorMessages())->toHaveCount(2);
});
// Test fixtures
class ValidTestObject
{
public function __construct(
#[Email]
public string $email,
#[Required]
#[StringLength(min: 3, max: 50)]
public string $name
) {
}
}
class GroupedTestObject
{
public function __construct(
#[Email]
#[TestValidationGroup('basic')]
public string $email,
#[Required]
#[TestValidationGroup('extended')]
public string $name
) {
}
}
class UninitializedTestObject
{
#[Required]
public string $requiredField;
}
class NullableTestObject
{
#[Email]
public ?string $optionalEmail = null;
}
// Custom validation rule for testing groups
#[\Attribute(\Attribute::TARGET_PROPERTY)]
class TestValidationGroup implements ValidationRule, GroupAware
{
public function __construct(
private string $group
) {
}
public function validate(mixed $value): bool
{
return true; // Always pass - we're just testing group functionality
}
public function getErrorMessages(): array
{
return [];
}
public function belongsToGroup(string $group): bool
{
return $this->group === $group;
}
}