mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-15 09:30:58 +00:00
Add validation for cart item quantity range
This commit is contained in:
parent
06c6fe06f9
commit
0e2772054e
8 changed files with 171 additions and 5 deletions
|
|
@ -16,7 +16,7 @@ Feature: Changing quantity of a product in cart
|
||||||
Then I should see "T-Shirt banana" with quantity 2 in my cart
|
Then I should see "T-Shirt banana" with quantity 2 in my cart
|
||||||
And my cart items total should be "$25.08"
|
And my cart items total should be "$25.08"
|
||||||
|
|
||||||
@todo-api @ui @javascript
|
@api @ui @javascript
|
||||||
Scenario: Increasing quantity of an item in cart beyond the threshold
|
Scenario: Increasing quantity of an item in cart beyond the threshold
|
||||||
Given I see the summary of my cart
|
Given I see the summary of my cart
|
||||||
When I change product "T-Shirt banana" quantity to 20000 in my cart
|
When I change product "T-Shirt banana" quantity to 20000 in my cart
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ final class CartContext implements Context
|
||||||
*/
|
*/
|
||||||
public function iShouldBeNotifiedThatTheQuantityOfThisProductMustBeBetween(ProductInterface $product): void
|
public function iShouldBeNotifiedThatTheQuantityOfThisProductMustBeBetween(ProductInterface $product): void
|
||||||
{
|
{
|
||||||
Assert::false($this->responseChecker->hasViolationWithMessage(
|
Assert::true($this->responseChecker->hasViolationWithMessage(
|
||||||
$this->shopClient->getLastResponse(),
|
$this->shopClient->getLastResponse(),
|
||||||
'Quantity must be between 1 and 9999.',
|
'Quantity must be between 1 and 9999.',
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,11 @@
|
||||||
</option>
|
</option>
|
||||||
</constraint>
|
</constraint>
|
||||||
<property name="quantity">
|
<property name="quantity">
|
||||||
<constraint name="Range">
|
<constraint name="Sylius\Bundle\CoreBundle\Validator\Constraints\CartItemQuantityRange">
|
||||||
<option name="min">1</option>
|
<option name="min">1</option>
|
||||||
<option name="minMessage">sylius.order_item.quantity.min</option>
|
<option name="groups">
|
||||||
<option name="groups">sylius</option>
|
<value>sylius</value>
|
||||||
|
</option>
|
||||||
</constraint>
|
</constraint>
|
||||||
<constraint name="NotBlank">
|
<constraint name="NotBlank">
|
||||||
<option name="message">sylius.order_item.quantity.not_blank</option>
|
<option name="message">sylius.order_item.quantity.not_blank</option>
|
||||||
|
|
|
||||||
|
|
@ -136,5 +136,11 @@
|
||||||
<argument type="service" id="sylius.repository.zone" />
|
<argument type="service" id="sylius.repository.zone" />
|
||||||
<tag name="validator.constraint_validator" alias="sylius_zone_code_exists" />
|
<tag name="validator.constraint_validator" alias="sylius_zone_code_exists" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="sylius.validator.cart_item_quantity_range" class="Sylius\Bundle\CoreBundle\Validator\Constraints\CartItemQuantityRangeValidator">
|
||||||
|
<argument type="service" id="property_accessor" />
|
||||||
|
<argument>%sylius.order_item_quantity_modifier.limit%</argument>
|
||||||
|
<tag name="validator.constraint_validator" alias="sylius_cart_item_quantity_range" />
|
||||||
|
</service>
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
|
|
||||||
|
|
@ -27,5 +27,13 @@
|
||||||
<value>sylius_checkout_complete</value>
|
<value>sylius_checkout_complete</value>
|
||||||
</option>
|
</option>
|
||||||
</constraint>
|
</constraint>
|
||||||
|
<property name="quantity">
|
||||||
|
<constraint name="Sylius\Bundle\CoreBundle\Validator\Constraints\CartItemQuantityRange">
|
||||||
|
<option name="min">1</option>
|
||||||
|
<option name="groups">
|
||||||
|
<value>sylius</value>
|
||||||
|
</option>
|
||||||
|
</constraint>
|
||||||
|
</property>
|
||||||
</class>
|
</class>
|
||||||
</constraint-mapping>
|
</constraint-mapping>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\CoreBundle\Validator\Constraints;
|
||||||
|
|
||||||
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
use Symfony\Component\Validator\Constraints\Range;
|
||||||
|
|
||||||
|
final class CartItemQuantityRange extends Range
|
||||||
|
{
|
||||||
|
public string $notInRangeMessage = 'sylius.cart_item.quantity.not_in_range';
|
||||||
|
|
||||||
|
public function validatedBy(): string
|
||||||
|
{
|
||||||
|
return 'sylius_cart_item_quantity_range';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTargets(): string
|
||||||
|
{
|
||||||
|
return Constraint::PROPERTY_CONSTRAINT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\CoreBundle\Validator\Constraints;
|
||||||
|
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||||
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
use Symfony\Component\Validator\Constraints\RangeValidator;
|
||||||
|
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||||
|
|
||||||
|
final class CartItemQuantityRangeValidator extends RangeValidator
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
PropertyAccessorInterface $propertyAccessor,
|
||||||
|
private readonly int $orderItemQuantityModifierLimit,
|
||||||
|
) {
|
||||||
|
parent::__construct($propertyAccessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validate(mixed $value, Constraint $constraint): void
|
||||||
|
{
|
||||||
|
if (!$constraint instanceof CartItemQuantityRange) {
|
||||||
|
throw new UnexpectedTypeException($constraint, CartItemQuantityRange::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
$constraint->max = $this->orderItemQuantityModifierLimit;
|
||||||
|
|
||||||
|
parent::validate($value, $constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace spec\Sylius\Bundle\CoreBundle\Validator\Constraints;
|
||||||
|
|
||||||
|
use PhpSpec\ObjectBehavior;
|
||||||
|
use Prophecy\Argument;
|
||||||
|
use Sylius\Bundle\CoreBundle\Validator\Constraints\CartItemQuantityRange;
|
||||||
|
use Sylius\Bundle\CoreBundle\Validator\Constraints\CountryCodeExists;
|
||||||
|
use Sylius\Component\Addressing\Model\CountryInterface;
|
||||||
|
use Sylius\Resource\Doctrine\Persistence\RepositoryInterface;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||||
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
|
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||||
|
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
|
||||||
|
|
||||||
|
final class CartItemQuantityRangeValidatorSpec extends ObjectBehavior
|
||||||
|
{
|
||||||
|
const MESSAGE = 'sylius.cart_item.quantity.not_in_range';
|
||||||
|
|
||||||
|
function let(PropertyAccessorInterface $propertyAccessor, ExecutionContextInterface $context): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith($propertyAccessor, 17);
|
||||||
|
|
||||||
|
$this->initialize($context);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_throws_an_exception_if_constraint_is_not_an_instance_of_cart_item_quantity_range(
|
||||||
|
Constraint $constraint,
|
||||||
|
): void {
|
||||||
|
$this
|
||||||
|
->shouldThrow(UnexpectedTypeException::class)
|
||||||
|
->during('validate', [9, $constraint])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_does_nothing_if_value_is_empty(
|
||||||
|
ExecutionContextInterface $context,
|
||||||
|
): void {
|
||||||
|
$this->validate(null, new CartItemQuantityRange(min: 1));
|
||||||
|
|
||||||
|
$context->buildViolation(self::MESSAGE)->shouldNotHaveBeenCalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_does_nothing_if_value_is_in_range(
|
||||||
|
RepositoryInterface $countryRepository,
|
||||||
|
ExecutionContextInterface $context,
|
||||||
|
CountryInterface $country,
|
||||||
|
): void {
|
||||||
|
$this->validate(5, new CartItemQuantityRange(min: 1));
|
||||||
|
|
||||||
|
$context->buildViolation(self::MESSAGE)->shouldNotHaveBeenCalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_adds_a_violation_if_value_is_not_in_range(
|
||||||
|
ExecutionContextInterface $context,
|
||||||
|
ConstraintViolationBuilderInterface $constraintViolationBuilder,
|
||||||
|
): void {
|
||||||
|
$constraintViolationBuilder->addViolation()->shouldBeCalled();
|
||||||
|
$constraintViolationBuilder->setCode(CartItemQuantityRange::NOT_IN_RANGE_ERROR)->willReturn($constraintViolationBuilder);
|
||||||
|
$constraintViolationBuilder->atPath(Argument::any())->willReturn($constraintViolationBuilder);
|
||||||
|
$constraintViolationBuilder->setParameter(Argument::cetera())->willReturn($constraintViolationBuilder);
|
||||||
|
|
||||||
|
$context->buildViolation(self::MESSAGE)->shouldBeCalled()->willReturn($constraintViolationBuilder);
|
||||||
|
|
||||||
|
$this->validate(18, new CartItemQuantityRange(min: 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue