-
-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add UUID validation rule, and test #754
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Validator\Rule; | ||
|
||
use Attribute; | ||
use Closure; | ||
use Yiisoft\Validator\DumpedRuleInterface; | ||
use Yiisoft\Validator\Rule\Trait\SkipOnErrorTrait; | ||
use Yiisoft\Validator\Rule\Trait\WhenTrait; | ||
use Yiisoft\Validator\SkipOnErrorInterface; | ||
use Yiisoft\Validator\WhenInterface; | ||
|
||
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] | ||
class Uuid implements DumpedRuleInterface, SkipOnErrorInterface, WhenInterface { | ||
use SkipOnErrorTrait; | ||
use WhenTrait; | ||
|
||
/** | ||
* @param string $message | ||
* @param string $notPassedMessage | ||
* @param bool $skipOnError | ||
* @param Closure|null $when | ||
*/ | ||
public function __construct( | ||
private string $message = 'The value of {property} does not conform to the UUID format.', | ||
private string $notPassedMessage = '{Property} not passed.', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This property is not used. |
||
private bool $skipOnError = false, | ||
Check warning on line 29 in src/Rule/Uuid.php GitHub Actions / mutation / PHP 8.3-ubuntu-latest
|
||
private Closure|null $when = null, | ||
) { | ||
} | ||
|
||
/** | ||
* Gets error message used when validation fails because the validated value is empty. | ||
* | ||
* @return string Error message / template. | ||
* | ||
* @see $message | ||
*/ | ||
public function getMessage(): string { | ||
return $this->message; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getName(): string { | ||
return self::class; | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
public function getOptions(): array { | ||
return []; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getHandler(): string { | ||
return UuidHandler::class; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Validator\Rule; | ||
|
||
use Yiisoft\Validator\Exception\UnexpectedRuleException; | ||
use Yiisoft\Validator\Result; | ||
use Yiisoft\Validator\RuleHandlerInterface; | ||
use Yiisoft\Validator\RuleInterface; | ||
use Yiisoft\Validator\ValidationContext; | ||
|
||
class UuidHandler implements RuleHandlerInterface { | ||
private const PATTERN = '\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\z'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
private const NIL = '00000000-0000-0000-0000-000000000000'; | ||
|
||
/** | ||
* @param mixed $value | ||
* @param RuleInterface $rule | ||
* @param ValidationContext $context | ||
* @return Result | ||
*/ | ||
public function validate(mixed $value, RuleInterface $rule, ValidationContext $context): Result { | ||
if (!$rule instanceof Uuid) { | ||
throw new UnexpectedRuleException(Uuid::class, $rule); | ||
} | ||
|
||
$result = new Result(); | ||
|
||
if ($this->validateUuid($value)) { | ||
Check failure on line 30 in src/Rule/UuidHandler.php GitHub Actions / psalm83 / PHP 8.3-ubuntu-latestMixedArgument
Check failure on line 30 in src/Rule/UuidHandler.php GitHub Actions / psalm / PHP 8.1-ubuntu-latestMixedArgument
Check failure on line 30 in src/Rule/UuidHandler.php GitHub Actions / psalm / PHP 8.2-ubuntu-latestMixedArgument
|
||
return $result; | ||
} | ||
|
||
return $result->addError($rule->getMessage(), [ | ||
'property' => $context->getTranslatedProperty(), | ||
'Property' => $context->getCapitalizedTranslatedProperty(), | ||
]); | ||
} | ||
|
||
/** | ||
* @param string $uuid | ||
* @return bool | ||
*/ | ||
protected function validateUuid(string $uuid): bool { | ||
$uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it should be optional and disabled by default. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Took it from the package There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be customizable in validation rule. |
||
|
||
return $uuid === self::NIL || preg_match('/' . self::PATTERN . '/Dms', $uuid); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?php | ||
|
||
namespace Yiisoft\Validator\Tests\Rule; | ||
|
||
use Yiisoft\Validator\Rule\Url; | ||
use Yiisoft\Validator\Rule\Uuid; | ||
use Yiisoft\Validator\Rule\UuidHandler; | ||
use Yiisoft\Validator\Tests\Rule\Base\DifferentRuleInHandlerTestTrait; | ||
use Yiisoft\Validator\Tests\Rule\Base\RuleTestCase; | ||
use Yiisoft\Validator\Tests\Rule\Base\RuleWithOptionsTestTrait; | ||
use Yiisoft\Validator\Tests\Rule\Base\SkipOnErrorTestTrait; | ||
use Yiisoft\Validator\Tests\Rule\Base\WhenTestTrait; | ||
|
||
class UuidTest extends RuleTestCase { | ||
use DifferentRuleInHandlerTestTrait; | ||
use RuleWithOptionsTestTrait; | ||
use SkipOnErrorTestTrait; | ||
use WhenTestTrait; | ||
|
||
public function testGetName(): void { | ||
$rule = new Uuid(); | ||
$this->assertSame(Uuid::class, $rule->getName()); | ||
} | ||
|
||
/** | ||
* @return string[] | ||
*/ | ||
protected function getDifferentRuleInHandlerItems(): array { | ||
return [Uuid::class, UuidHandler::class]; | ||
} | ||
|
||
/** | ||
* @return array[] | ||
*/ | ||
public function dataValidationPassed(): array { | ||
return [ | ||
['0193ba64-5ef5-7ba3-90c1-2915349a60d3', [new Uuid()]], | ||
['89ffcfc5-d452-4eb9-8949-d35fb577f09d', [new Uuid()]], | ||
|
||
['289cef4c-b873-11ef-9cd2-0242ac120002', [new Uuid()]], | ||
]; | ||
} | ||
|
||
public function dataValidationFailed(): array { | ||
$errors = ['' => ['The value of value does not conform to the UUID format.']]; | ||
|
||
return [ | ||
['not uuid value', [new Uuid()], $errors], | ||
['ea20aba6-1fb2-45de-8582-6ed15f94501', [new Uuid()], $errors], | ||
]; | ||
} | ||
|
||
public function dataOptions(): array { | ||
return [ | ||
[new Uuid(), []], | ||
]; | ||
} | ||
|
||
public function testSkipOnError(): void { | ||
$this->testSkipOnErrorInternal(new Url(), new Url(skipOnError: true)); | ||
} | ||
|
||
/** | ||
* @return void | ||
*/ | ||
public function testWhen(): void { | ||
$when = static fn(mixed $value): bool => $value !== null; | ||
$this->testWhenInternal(new Uuid(), new Uuid(when: $when)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add implementation of
SkipOnEmptyInterface