Validators specs and structure fixes

This commit is contained in:
Mateusz Zalewski 2022-02-10 10:30:10 +01:00
parent da0e999271
commit 281e2392a0
No known key found for this signature in database
GPG key ID: 9BECA0BB71612E52
11 changed files with 89 additions and 56 deletions

View file

@ -125,7 +125,7 @@ Feature: Validating a catalog promotion creation
And I add scope that applies on variants "PHP T-Shirt" variant and "Kotlin T-Shirt" variant
And I add fixed discount action without amount configured
And I try to add it
Then I should be notified that not all channels are filled
Then I should be notified that a discount amount should be configured for at least one channel
And there should be an empty list of catalog promotions
@api

View file

@ -619,7 +619,7 @@ final class ManagingCatalogPromotionsContext implements Context
/**
* @Then I should be notified that a discount amount is not valid
*/
public function iShouldBeNotifiedThatADiscountAmountIsNotValie(): void
public function iShouldBeNotifiedThatADiscountAmountIsNotValid(): void
{
Assert::same($this->formElement->getValidationMessage(), 'This value is not valid.');
}
@ -630,7 +630,7 @@ final class ManagingCatalogPromotionsContext implements Context
public function iShouldBeNotifiedThatADiscountAmountShouldBeConfiguredForAtLeasOneChannel(): void
{
Assert::true($this->formElement->hasValidationMessage(
'Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.'
'Configuration for one of the required channels is not provided.'
));
}

View file

@ -34,23 +34,21 @@ final class FixedDiscountActionValidator implements ActionValidatorInterface
public function validate(array $configuration, Constraint $constraint, ExecutionContextInterface $context): void
{
/** @var CatalogPromotionAction $constraint */
Assert::isInstanceOf($constraint, CatalogPromotionAction::class);
if (!$this->sectionProvider->getSection() instanceof AdminApiSection) {
$this->baseActionValidator->validate($configuration, $constraint, $context);
return;
}
/** @var CatalogPromotionAction $constraint */
Assert::isInstanceOf($constraint, CatalogPromotionAction::class);
if (empty($configuration)) {
$context->buildViolation('sylius.catalog_promotion_action.fixed_discount.not_valid')->atPath('configuration')->addViolation();
return;
}
$this->baseActionValidator->validate($configuration, $constraint, $context);
foreach ($configuration as $channelConfiguration) {
if ($this->isChannelAmountValid($channelConfiguration)) {
$context->buildViolation('sylius.catalog_promotion_action.fixed_discount.not_valid')->atPath('configuration')->addViolation();
@ -58,6 +56,8 @@ final class FixedDiscountActionValidator implements ActionValidatorInterface
return;
}
}
$this->baseActionValidator->validate($configuration, $constraint, $context);
}
private function isChannelAmountValid(array $channelConfiguration): bool

View file

@ -34,13 +34,10 @@ final class ForProductsScopeValidator implements ScopeValidatorInterface
/** @var CatalogPromotionScope $constraint */
Assert::isInstanceOf($constraint, CatalogPromotionScope::class);
if (!$this->sectionProvider->getSection() instanceof AdminApiSection) {
$this->baseScopeValidator->validate($configuration, $constraint, $context);
return;
}
if (!isset($configuration['products']) || empty($configuration['products'])) {
if (
$this->sectionProvider->getSection() instanceof AdminApiSection &&
(!isset($configuration['products']) || empty($configuration['products']))
) {
$context->buildViolation($constraint->productsNotEmpty)->atPath('configuration.products')->addViolation();
return;

View file

@ -32,16 +32,13 @@ final class ForTaxonsScopeValidator implements ScopeValidatorInterface
public function validate(array $configuration, Constraint $constraint, ExecutionContextInterface $context): void
{
if (!$this->sectionProvider->getSection() instanceof AdminApiSection) {
$this->baseScopeValidator->validate($configuration, $constraint, $context);
return;
}
/** @var CatalogPromotionScope $constraint */
Assert::isInstanceOf($constraint, CatalogPromotionScope::class);
if (!isset($configuration['taxons']) || empty($configuration['taxons'])) {
if (
$this->sectionProvider->getSection() instanceof AdminApiSection &&
(!isset($configuration['taxons']) || empty($configuration['taxons']))
) {
$context->buildViolation($constraint->taxonsNotEmpty)->atPath('configuration.taxons')->addViolation();
return;

View file

@ -35,13 +35,10 @@ final class ForVariantsScopeValidator implements ScopeValidatorInterface
/** @var CatalogPromotionScope $constraint */
Assert::isInstanceOf($constraint, CatalogPromotionScope::class);
if (!$this->sectionProvider->getSection() instanceof AdminApiSection) {
$this->baseScopeValidator->validate($configuration, $constraint, $context);
return;
}
if (!array_key_exists('variants', $configuration) || empty($configuration['variants'])) {
if (
$this->sectionProvider->getSection() instanceof AdminApiSection &&
(!isset($configuration['variants']) || empty($configuration['variants']))
) {
$context->buildViolation($constraint->variantsNotEmpty)->atPath('configuration.variants')->addViolation();
return;

View file

@ -36,7 +36,7 @@ final class PercentageDiscountActionValidator implements ActionValidatorInterfac
/** @var CatalogPromotionAction $constraint */
Assert::isInstanceOf($constraint, CatalogPromotionAction::class);
if (!array_key_exists('amount', $configuration)) {
if (!isset($configuration['amount'])) {
$context->buildViolation($constraint->notNumberOrEmpty)->atPath('configuration.amount')->addViolation();
return;

View file

@ -84,11 +84,6 @@ final class FixedDiscountActionValidatorSpec extends ObjectBehavior
): void {
$sectionProvider->getSection()->willReturn(new AdminApiSection());
$baseActionValidator
->validate(['channel' => []], new CatalogPromotionAction(), $executionContext)
->shouldBeCalled()
;
$executionContext->buildViolation('sylius.catalog_promotion_action.fixed_discount.not_valid')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->atPath('configuration')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->addViolation()->shouldBeCalled();
@ -104,15 +99,12 @@ final class FixedDiscountActionValidatorSpec extends ObjectBehavior
): void {
$sectionProvider->getSection()->willReturn(new AdminApiSection());
$baseActionValidator
->validate(['channel' => ['amount' => null]], new CatalogPromotionAction(), $executionContext)
->shouldBeCalled()
;
$executionContext->buildViolation('sylius.catalog_promotion_action.fixed_discount.not_valid')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->atPath('configuration')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->addViolation()->shouldBeCalled();
$baseActionValidator->validate(Argument::any())->shouldNotBeCalled();
$this->validate(['channel' => ['amount' => null]], new CatalogPromotionAction(), $executionContext);
}
@ -126,18 +118,38 @@ final class FixedDiscountActionValidatorSpec extends ObjectBehavior
$sectionProvider->getSection()->willReturn(new AdminApiSection());
$baseActionValidator
->validate(['channel' => ['amount' => 'wrong_value']], $constraint, $executionContext)
->shouldBeCalled()
;
$executionContext->buildViolation('sylius.catalog_promotion_action.fixed_discount.not_valid')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->atPath('configuration')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->addViolation()->shouldBeCalled();
$baseActionValidator->validate(Argument::any())->shouldNotBeCalled();
$this->validate(['channel' => ['amount' => 'wrong_value']], $constraint, $executionContext);
}
function it_adds_violation_if_catalog_promotion_action_has_invalid_amount_configured_for_one_of_channels(
ActionValidatorInterface $baseActionValidator,
SectionProviderInterface $sectionProvider,
ExecutionContextInterface $executionContext,
ConstraintViolationBuilderInterface $constraintViolationBuilder
): void {
$constraint = new CatalogPromotionAction();
$sectionProvider->getSection()->willReturn(new AdminApiSection());
$executionContext->buildViolation('sylius.catalog_promotion_action.fixed_discount.not_valid')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->atPath('configuration')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->addViolation()->shouldBeCalledOnce();
$baseActionValidator->validate(Argument::any())->shouldNotBeCalled();
$this->validate(
['channel' => ['amount' => 'wrong_value'], 'second_channel' => ['amount' => 'wrong_value']],
$constraint,
$executionContext
);
}
function it_does_nothing_if_the_provided_configuration_is_valid(
ActionValidatorInterface $baseActionValidator,
SectionProviderInterface $sectionProvider,
@ -147,15 +159,13 @@ final class FixedDiscountActionValidatorSpec extends ObjectBehavior
$sectionProvider->getSection()->willReturn(new AdminApiSection());
$executionContext->buildViolation('sylius.catalog_promotion_action.fixed_discount.not_valid')->shouldNotBeCalled();
$baseActionValidator
->validate(['channel' => ['amount' => 1000]], $constraint, $executionContext)
->shouldBeCalled()
;
$executionContext->buildViolation('sylius.catalog_promotion_action.fixed_discount.not_empty')->shouldNotBeCalled();
$executionContext->buildViolation('sylius.catalog_promotion_action.fixed_discount.invalid_channel')->shouldNotBeCalled();
$executionContext->buildViolation('sylius.catalog_promotion_action.fixed_discount.not_valid')->shouldNotBeCalled();
$this->validate(['channel' => ['amount' => 1000]], new CatalogPromotionAction(), $executionContext);
}
}

View file

@ -70,6 +70,23 @@ final class ForProductsScopeValidatorSpec extends ObjectBehavior
$this->validate([], new CatalogPromotionScope(), $executionContext);
}
function it_adds_violation_if_catalog_promotion_scope_does_not_have_products_key_defined(
ScopeValidatorInterface $baseScopeValidator,
SectionProviderInterface $sectionProvider,
ExecutionContextInterface $executionContext,
ConstraintViolationBuilderInterface $constraintViolationBuilder
): void {
$sectionProvider->getSection()->willReturn(new AdminApiSection());
$executionContext->buildViolation('sylius.catalog_promotion_scope.for_products.not_empty')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->atPath('configuration.products')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->addViolation()->shouldBeCalled();
$baseScopeValidator->validate(Argument::any())->shouldNotBeCalled();
$this->validate(['products' => []], new CatalogPromotionScope(), $executionContext);
}
function it_does_nothing_if_catalog_promotion_scope_is_valid(
ScopeValidatorInterface $baseScopeValidator,
SectionProviderInterface $sectionProvider,

View file

@ -14,6 +14,7 @@ declare(strict_types=1);
namespace spec\Sylius\Bundle\ApiBundle\Validator\CatalogPromotion;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\ApiBundle\SectionResolver\AdminApiSection;
use Sylius\Bundle\CoreBundle\SectionResolver\SectionProviderInterface;
use Sylius\Bundle\CoreBundle\Validator\CatalogPromotionScope\ScopeValidatorInterface;
@ -48,11 +49,30 @@ final class ForTaxonsScopeValidatorSpec extends ObjectBehavior
$constraintViolationBuilder->atPath('configuration.taxons')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->addViolation()->shouldBeCalled();
$baseScopeValidator->validate([], $constraint, $executionContext)->shouldNotBeCalled();
$baseScopeValidator->validate(Argument::any())->shouldNotBeCalled();
$this->validate([], $constraint, $executionContext);
}
function it_adds_violation_if_catalog_promotion_scope_does_not_have_taxons_key_defined(
ScopeValidatorInterface $baseScopeValidator,
SectionProviderInterface $sectionProvider,
ExecutionContextInterface $executionContext,
ConstraintViolationBuilderInterface $constraintViolationBuilder
): void {
$constraint = new CatalogPromotionScope();
$sectionProvider->getSection()->willReturn(new AdminApiSection());
$executionContext->buildViolation('sylius.catalog_promotion_scope.for_taxons.not_empty')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->atPath('configuration.taxons')->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->addViolation()->shouldBeCalled();
$baseScopeValidator->validate(Argument::any())->shouldNotBeCalled();
$this->validate(['taxons' => []], $constraint, $executionContext);
}
function it_does_nothing_if_catalog_promotion_scope_is_valid(
ScopeValidatorInterface $baseScopeValidator,
SectionProviderInterface $sectionProvider,

View file

@ -2,7 +2,7 @@
"@context": "/api/v2/contexts/ConstraintViolationList",
"@type": "ConstraintViolationList",
"hydra:title": "An error occurred",
"hydra:description": "actions[0].type: Catalog promotion action type is invalid. Please choose a valid type.\nactions[1].configuration.amount: The percentage discount amount must be a number and can not be empty.\nactions[2].configuration.amount: The percentage discount amount must be between 0% and 100%.\nactions[3].configuration.amount: The percentage discount amount must be a number and can not be empty.\nactions[4].configuration: Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.\nactions[5].configuration: Configuration for one of the required channels is not provided.\nactions[5].configuration: Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.\nactions[6].configuration: Configuration for one of the required channels is not provided.\nactions[7].configuration: Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.",
"hydra:description": "actions[0].type: Catalog promotion action type is invalid. Please choose a valid type.\nactions[1].configuration.amount: The percentage discount amount must be a number and can not be empty.\nactions[2].configuration.amount: The percentage discount amount must be between 0% and 100%.\nactions[3].configuration.amount: The percentage discount amount must be a number and can not be empty.\nactions[4].configuration: Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.\nactions[5].configuration: Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.\nactions[6].configuration: Configuration for one of the required channels is not provided.\nactions[7].configuration: Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.",
"violations": [
{
"propertyPath": "actions[0].type",
@ -29,11 +29,6 @@
"message": "Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.",
"code": null
},
{
"propertyPath": "actions[5].configuration",
"message": "Configuration for one of the required channels is not provided.",
"code": null
},
{
"propertyPath": "actions[5].configuration",
"message": "Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.",