Extract authorized user assignment to separate method

This commit is contained in:
everwhatever 2023-01-04 08:41:22 +01:00
parent 59912ead00
commit 1689d05d58
20 changed files with 177 additions and 96 deletions

View file

@ -7,16 +7,27 @@ Feature: Clearing cart after logging out
Background:
Given the store operates on a single channel in "United States"
And the store has a product "Stark T-shirt" priced at "$12.00"
And I am a logged in customer
And I have product "Stark T-Shirt" in the cart
@ui
Scenario: Clearing cart after logging out
Given I am a logged in customer
And I have product "Stark T-Shirt" in the cart
When I log out
And I see the summary of my cart
Then my cart should be empty
@api
Scenario: Clearing cart after logging out
Given I am a logged in customer
And I have product "Stark T-Shirt" in the cart
When I log out
Then I don't have access to see the summary of my previous cart
Then I should not have access to the summary of my previous cart
@api
Scenario: Blocking access to cart if logged user did any action over it (what can be treated as signing it)
Given there is a user "john@snow.com"
When I add this product to the cart
And I log in as "john@snow.com" with "sylius" password
And I add this product to the cart
And I log out
Then I should not have access to the summary of my previous cart

View file

@ -11,7 +11,7 @@ Feature: Checking out as guest with a registered email
And the store allows paying offline
And there is a customer account "john@example.com"
@ui
@ui @api
Scenario: Successfully placing an order
Given I have product "PHP T-Shirt" in the cart
When I complete addressing step with email "john@example.com" and "United States" based billing address

View file

@ -269,7 +269,7 @@ final class CartContext implements Context
}
/**
* @Then /^I don't have access to see the summary of my (previous cart)$/
* @Then /^I should not have access to the summary of my (previous cart)$/
*/
public function iDoNotHaveAccessToSeeTheSummaryOfMyCart(string $tokenValue): void
{

View file

@ -50,7 +50,7 @@ final class BlameCartHandler implements MessageHandlerInterface
throw new \InvalidArgumentException('There is an assigned customer to this cart');
}
$cart->setCustomer($user->getCustomer());
$cart->setCustomerWithAuthorization($user->getCustomer());
$this->orderProcessor->process($cart);
}

View file

@ -70,9 +70,9 @@ final class PickupCartHandler implements MessageHandlerInterface
$cart->setLocaleCode($this->getLocaleCode($pickupCart->localeCode, $channel));
$cart->setCurrencyCode($currency->getCode());
$cart->setTokenValue($pickupCart->tokenValue ?? $this->generator->generateUriSafeString(10));
if ($customer !== null) {
$cart->setCustomer($customer);
$cart->setCreatedByGuest(false);
$cart->setCustomerWithAuthorization($customer);
}
$this->orderManager->persist($cart);

View file

@ -69,9 +69,9 @@ final class OrderGetMethodItemExtension implements QueryItemExtensionInterface
sprintf('%s.customer IS NULL', $rootAlias),
$queryBuilder->expr()->andX(
sprintf('%s.customer IS NOT NULL', $rootAlias),
sprintf('%s.createdByGuest = true', $rootAlias),
),
))
sprintf('%s.createdByGuest = :createdByGuest', $rootAlias)
)
))->setParameter('createdByGuest', true)
;
return;

View file

@ -79,7 +79,14 @@ final class OrderMethodsItemExtension implements QueryItemExtensionInterface
$queryBuilder
->leftJoin(sprintf('%s.customer', $rootAlias), 'customer')
->leftJoin('customer.user', 'user')
->andWhere($queryBuilder->expr()->orX('user IS NULL', sprintf('%s.customer IS NULL', $rootAlias)))
->andWhere($queryBuilder->expr()->orX(
'user IS NULL',
sprintf('%s.customer IS NULL', $rootAlias),
$queryBuilder->expr()->andX(
sprintf('%s.customer IS NOT NULL', $rootAlias),
sprintf('%s.createdByGuest = :createdByGuest', $rootAlias)
)
))->setParameter('createdByGuest', true)
;
if ($operationName !== 'shop_select_payment_method') {

View file

@ -45,7 +45,7 @@ final class ApiCartBlamerListener
}
$cart = $this->getCart();
if (null === $cart || null !== $cart->getCustomer()) {
if (null === $cart || !$cart->isCreatedByGuest()) {
return;
}

View file

@ -57,7 +57,7 @@ final class BlameCartHandlerSpec extends ObjectBehavior
$user->getCustomer()->willReturn($customer);
$cart->setCustomer($customer)->shouldBeCalled();
$cart->setCustomerWithAuthorization($customer)->shouldBeCalled();
$orderProcessor->process($cart)->shouldBeCalled();

View file

@ -87,8 +87,7 @@ final class PickupCartHandlerSpec extends ObjectBehavior
$channel->getLocales()->willReturn(new ArrayCollection([$locale->getWrappedObject()]));
$cartFactory->createNew()->willReturn($cart);
$cart->setCustomer($customer)->shouldBeCalled();
$cart->setCreatedByGuest(false)->shouldBeCalled();
$cart->setCustomerWithAuthorization($customer)->shouldBeCalled();
$cart->setChannel($channel)->shouldBeCalled();
$cart->setCurrencyCode('USD')->shouldBeCalled();
$cart->setLocaleCode('en_US')->shouldBeCalled();

View file

@ -60,18 +60,27 @@ final class OrderGetMethodItemExtensionSpec extends ObjectBehavior
->willReturn($expr)
;
$expr
->andX('o.customer IS NOT NULL', 'o.createdByGuest = true')
->willReturn('o.customer IS NOT NULL AND o.createdByGuest = true')
$queryBuilder
->setParameter('createdByGuest', true)
->shouldBeCalled()
->willReturn($expr)
;
$expr
->orX('user IS NULL', 'o.customer IS NULL', 'o.customer IS NOT NULL AND o.createdByGuest = true')
->willReturn('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = true)')
->andX('o.customer IS NOT NULL', 'o.createdByGuest = :createdByGuest')
->shouldBeCalled()
->willReturn('o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest')
;
$expr
->orX('user IS NULL', 'o.customer IS NULL', 'o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest')
->shouldBeCalled()
->willReturn('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest)')
;
$queryBuilder
->andWhere('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = true)')
->andWhere('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest)')
->shouldBeCalled()
->willReturn($queryBuilder)
;

View file

@ -62,14 +62,26 @@ final class OrderMethodsItemExtensionSpec extends ObjectBehavior
->willReturn($expr)
;
$expr
->orX('user IS NULL', sprintf('%s.customer IS NULL', 'o'))
$queryBuilder
->setParameter('createdByGuest', true)
->shouldBeCalled()
->willReturn(sprintf('user IS NULL OR %s.customer IS NULL', 'o'))
->willReturn($expr)
;
$expr
->andX('o.customer IS NOT NULL', 'o.createdByGuest = :createdByGuest')
->shouldBeCalled()
->willReturn('o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest')
;
$expr
->orX('user IS NULL', 'o.customer IS NULL', 'o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest')
->shouldBeCalled()
->willReturn('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest)')
;
$queryBuilder
->andWhere(sprintf('user IS NULL OR %s.customer IS NULL', 'o'))
->andWhere('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest)')
->shouldBeCalled()
->willReturn($queryBuilder)
;
@ -108,7 +120,7 @@ final class OrderMethodsItemExtensionSpec extends ObjectBehavior
$userContext->getUser()->willReturn(null);
$queryBuilder
->leftJoin(sprintf('%s.customer', 'o'), 'customer')
->leftJoin('o.customer', 'customer')
->shouldBeCalled()
->willReturn($queryBuilder)
;
@ -119,20 +131,33 @@ final class OrderMethodsItemExtensionSpec extends ObjectBehavior
->willReturn($queryBuilder)
;
$queryBuilder
->expr()
->shouldBeCalled()
->willReturn($expr)
;
$expr
->orX('user IS NULL', sprintf('%s.customer IS NULL', 'o'))
$queryBuilder
->setParameter('createdByGuest', true)
->shouldBeCalled()
->willReturn(sprintf('user IS NULL OR %s.customer IS NULL', 'o'))
->willReturn($expr)
;
$expr
->andX('o.customer IS NOT NULL', 'o.createdByGuest = :createdByGuest')
->shouldBeCalled()
->willReturn('o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest')
;
$expr
->orX('user IS NULL', 'o.customer IS NULL', 'o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest')
->shouldBeCalled()
->willReturn('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest)')
;
$queryBuilder
->andWhere(sprintf('user IS NULL OR %s.customer IS NULL', 'o'))
->andWhere('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest)')
->shouldBeCalled()
->willReturn($queryBuilder)
;
@ -188,14 +213,26 @@ final class OrderMethodsItemExtensionSpec extends ObjectBehavior
->willReturn($expr)
;
$expr
->orX('user IS NULL', sprintf('%s.customer IS NULL', 'o'))
$queryBuilder
->setParameter('createdByGuest', true)
->shouldBeCalled()
->willReturn(sprintf('user IS NULL OR %s.customer IS NULL', 'o'))
->willReturn($expr)
;
$expr
->andX('o.customer IS NOT NULL', 'o.createdByGuest = :createdByGuest')
->shouldBeCalled()
->willReturn('o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest')
;
$expr
->orX('user IS NULL', 'o.customer IS NULL', 'o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest')
->shouldBeCalled()
->willReturn('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest)')
;
$queryBuilder
->andWhere(sprintf('user IS NULL OR %s.customer IS NULL', 'o'))
->andWhere('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest)')
->shouldBeCalled()
->willReturn($queryBuilder)
;
@ -371,15 +408,32 @@ final class OrderMethodsItemExtensionSpec extends ObjectBehavior
->willReturn($queryBuilder)
;
$queryBuilder->expr()->shouldBeCalled()->willReturn($expr);
$expr
->orX('user IS NULL', sprintf('%s.customer IS NULL', 'o'))
$queryBuilder
->expr()
->shouldBeCalled()
->willReturn(sprintf('user IS NULL OR %s.customer IS NULL', 'o'))
->willReturn($expr)
;
$queryBuilder
->andWhere(sprintf('user IS NULL OR %s.customer IS NULL', 'o'))
->setParameter('createdByGuest', true)
->shouldBeCalled()
->willReturn($expr)
;
$expr
->andX('o.customer IS NOT NULL', 'o.createdByGuest = :createdByGuest')
->shouldBeCalled()
->willReturn('o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest')
;
$expr
->orX('user IS NULL', 'o.customer IS NULL', 'o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest')
->shouldBeCalled()
->willReturn('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest)')
;
$queryBuilder
->andWhere('user IS NULL OR o.customer IS NULL OR (o.customer IS NOT NULL AND o.createdByGuest = :createdByGuest)')
->shouldBeCalled()
->willReturn($queryBuilder)
;

View file

@ -75,7 +75,7 @@ final class ApiCartBlamerListenerSpec extends ObjectBehavior
): void {
$sectionResolver->getSection()->willReturn($shopApiOrdersSubSectionSection);
$cartContext->getCart()->willReturn($cart);
$cart->getCustomer()->willReturn(null);
$cart->isCreatedByGuest()->willReturn(true);
$token->getUser()->willReturn($user);
$user->getCustomer()->willReturn($customer);
@ -104,7 +104,7 @@ final class ApiCartBlamerListenerSpec extends ObjectBehavior
): void {
$sectionResolver->getSection()->willReturn($shopApiOrdersSubSectionSection);
$cartContext->getCart()->willReturn($cart);
$cart->getCustomer()->willReturn($customer);
$cart->isCreatedByGuest()->willReturn(false);
$cart->setCustomer(Argument::any())->shouldNotBeCalled();

View file

@ -65,8 +65,7 @@ final class ShopCartBlamerListener
return;
}
$cart->setCustomer($user->getCustomer());
$cart->setCreatedByGuest(false);
$cart->setCustomerWithAuthorization($user->getCustomer());
}
/**

View file

@ -88,8 +88,7 @@ final class ShopCartBlamerListenerSpec extends ObjectBehavior
$userEvent->getUser()->willReturn($user);
$user->getCustomer()->willReturn($customer);
$cart->setCustomer($customer)->shouldBeCalled();
$cart->setCreatedByGuest(false)->shouldBeCalled();
$cart->setCustomerWithAuthorization($customer)->shouldBeCalled();
$this->onImplicitLogin($userEvent);
}
@ -110,8 +109,7 @@ final class ShopCartBlamerListenerSpec extends ObjectBehavior
$token->getUser()->willReturn($user);
$user->getCustomer()->willReturn($customer);
$cart->setCustomer($customer)->shouldBeCalled();
$cart->setCreatedByGuest(false)->shouldBeCalled();
$cart->setCustomerWithAuthorization($customer)->shouldBeCalled();
$this->onInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
@ -129,8 +127,7 @@ final class ShopCartBlamerListenerSpec extends ObjectBehavior
$cartContext->getCart()->willReturn($cart);
$cart->getCustomer()->willReturn($customer);
$cart->setCustomer(Argument::any())->shouldNotBeCalled();
$cart->setCreatedByGuest(false)->shouldNotBeCalled();
$cart->setCustomerWithAuthorization(Argument::any())->shouldNotBeCalled();
$this->onInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
@ -147,8 +144,7 @@ final class ShopCartBlamerListenerSpec extends ObjectBehavior
$cartContext->getCart()->willReturn($cart);
$token->getUser()->willReturn('anon.');
$cart->setCustomer(Argument::any())->shouldNotBeCalled();
$cart->setCreatedByGuest(false)->shouldNotBeCalled();
$cart->setCustomerWithAuthorization(Argument::any())->shouldNotBeCalled();
$this->onInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}

View file

@ -90,11 +90,7 @@ final class ShopBasedCartContext implements CartContextInterface
private function setCustomerAndAddressOnCart(OrderInterface $cart, CustomerInterface $customer): void
{
$cart->setCustomer($customer);
if ($this->createdByGuestFlagResolver !== null) {
$cart->setCreatedByGuest($this->createdByGuestFlagResolver->resolveFlag());
}
$this->setCustomer($cart, $customer);
$defaultAddress = $customer->getDefaultAddress();
if (null !== $defaultAddress) {
@ -103,4 +99,15 @@ final class ShopBasedCartContext implements CartContextInterface
$cart->setBillingAddress($clonedAddress);
}
}
private function setCustomer(OrderInterface $cart, CustomerInterface $customer): void
{
if ($this->createdByGuestFlagResolver !== null && !$this->createdByGuestFlagResolver->resolveFlag()) {
$cart->setCustomerWithAuthorization($customer);
return;
}
$cart->setCustomer($customer);
}
}

View file

@ -114,6 +114,12 @@ class Order extends BaseOrder implements OrderInterface
$this->customer = $customer;
}
public function setCustomerWithAuthorization(?BaseCustomerInterface $customer): void
{
$this->setCustomer($customer);
$this->createdByGuest = false;
}
public function getChannel(): ?BaseChannelInterface
{
return $this->channel;
@ -460,11 +466,16 @@ class Order extends BaseOrder implements OrderInterface
return $total;
}
public function getCreatedByGuest(): bool
public function isCreatedByGuest(): bool
{
return $this->createdByGuest;
}
public function getCreatedByGuest(): bool
{
return $this->isCreatedByGuest();
}
public function setCreatedByGuest(bool $createdByGuest): void
{
$this->createdByGuest = $createdByGuest;

View file

@ -17,6 +17,7 @@ use Doctrine\Common\Collections\Collection;
use Sylius\Component\Channel\Model\ChannelAwareInterface;
use Sylius\Component\Channel\Model\ChannelInterface as BaseChannelInterface;
use Sylius\Component\Customer\Model\CustomerAwareInterface;
use Sylius\Component\Customer\Model\CustomerInterface as BaseCustomerInterface;
use Sylius\Component\Order\Model\OrderInterface as BaseOrderInterface;
use Sylius\Component\Payment\Model\PaymentsSubjectInterface;
use Sylius\Component\Promotion\Model\CountablePromotionSubjectInterface;
@ -113,6 +114,10 @@ interface OrderInterface extends
public function setCustomerIp(?string $customerIp): void;
public function setCustomerWithAuthorization(?BaseCustomerInterface $customer): void;
public function isCreatedByGuest(): bool;
public function getCreatedByGuest(): bool;
public function setCreatedByGuest(bool $createdByGuest): void;

View file

@ -189,7 +189,7 @@ final class ShopBasedCartContextSpec extends ObjectBehavior
$this->getCart()->shouldReturn($secondCart);
}
function it_sets_created_by_guest_flag_as_false_if_order_is_created_by_logged_in_customer(
function it_creates_order_for_authorized_user(
CartContextInterface $cartContext,
ShopperContextInterface $shopperContext,
CreatedByGuestFlagResolverInterface $createdByGuestFlagResolver,
@ -202,8 +202,6 @@ final class ShopBasedCartContextSpec extends ObjectBehavior
$createdByGuestFlagResolver->resolveFlag()->willReturn(false);
$cart->setCreatedByGuest(false)->shouldBeCalled();
$cartContext->getCart()->shouldBeCalledTimes(1)->willReturn($cart);
$shopperContext->getChannel()->willReturn($channel);
@ -217,40 +215,7 @@ final class ShopBasedCartContextSpec extends ObjectBehavior
$cart->setChannel($channel)->shouldBeCalled();
$cart->setCurrencyCode('PLN')->shouldBeCalled();
$cart->setLocaleCode('pl')->shouldBeCalled();
$cart->setCustomer($customer)->shouldBeCalled();
$this->getCart()->shouldReturn($cart);
}
function it_sets_created_by_guest_flag_as_true_if_order_is_created_by_anonymous_user(
CartContextInterface $cartContext,
ShopperContextInterface $shopperContext,
CreatedByGuestFlagResolverInterface $createdByGuestFlagResolver,
OrderInterface $cart,
ChannelInterface $channel,
CurrencyInterface $currency,
CustomerInterface $customer,
): void {
$this->beConstructedWith($cartContext, $shopperContext, $createdByGuestFlagResolver);
$createdByGuestFlagResolver->resolveFlag()->willReturn(true);
$cart->setCreatedByGuest(true)->shouldBeCalled();
$cartContext->getCart()->shouldBeCalledTimes(1)->willReturn($cart);
$shopperContext->getChannel()->willReturn($channel);
$shopperContext->getLocaleCode()->willReturn('pl');
$shopperContext->getCustomer()->willReturn($customer);
$customer->getDefaultAddress()->willReturn(null);
$channel->getBaseCurrency()->willReturn($currency);
$currency->getCode()->willReturn('PLN');
$cart->setChannel($channel)->shouldBeCalled();
$cart->setCurrencyCode('PLN')->shouldBeCalled();
$cart->setLocaleCode('pl')->shouldBeCalled();
$cart->setCustomer($customer)->shouldBeCalled();
$cart->setCustomerWithAuthorization($customer)->shouldBeCalled();
$this->getCart()->shouldReturn($cart);
}

View file

@ -51,12 +51,30 @@ final class OrderSpec extends ObjectBehavior
$this->getCustomer()->shouldReturn(null);
}
function its_allows_defining_customer(CustomerInterface $customer): void
function it_allows_defining_customer(CustomerInterface $customer): void
{
$this->setCustomer($customer);
$this->getCustomer()->shouldReturn($customer);
}
function it_allows_defining_authorized_customer(CustomerInterface $customer): void
{
$this->setCustomerWithAuthorization($customer);
$this->getCustomer()->shouldReturn($customer);
$this->isCreatedByGuest()->shouldReturn(false);
}
function its_created_by_guest_customer_by_default(): void
{
$this->isCreatedByGuest()->shouldReturn(true);
}
function it_allows_to_mutate_create_by_guest_field(): void
{
$this->setCreatedByGuest(false);
$this->isCreatedByGuest()->shouldReturn(false);
}
function its_customer_can_be_nullable(): void
{
$this->setCustomer(null);