Skip to content
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

[Api] orders index for customer's account #11891

Merged
merged 3 commits into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,11 @@ Feature: Seeing customer's orders placed as guest
And the store ships everywhere for free
And the store allows paying offline
And the guest customer placed order with "PHP T-Shirt" product for "john@snow.com" and "United States" based billing address with "Free" shipping method and "Offline" payment
And the another guest customer placed order with "PHP T-Shirt" product for "ned@stark.com" and "United States" based billing address with "Free" shipping method and "Offline" payment

@ui
@ui @api
Scenario: Not being able to hijack another customer's orders
Given I have product "PHP T-Shirt" in the cart
When I complete addressing step with email "john@snow.com" and "United States" based billing address
And I decide to change my address
And I specify the email as "ned@stark.com"
And I complete the addressing step
And I select "Free" shipping method
And I complete the shipping step
And I select "Offline" payment method
And I complete the payment step
And I confirm my order
And I register with previously used "ned@stark.com" email and "lannistersAreDumb" password
Given I registered with previously used "ned@stark.com" email and "lannistersAreDumb" password
And I log in as "ned@stark.com" with "lannistersAreDumb" password
And I browse my orders
Then I should see a single order in the list
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Feature: Viewing orders on my account page
And the customer bought a single "Green Arrow"
And the customer "Oliver Queen" addressed it to "Seaside Fwy", "90802" "Los Angeles" in the "United States" with identical billing address

@ui
@ui @api
Scenario: Viewing orders
When I browse my orders
Then I should see a single order in the list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Feature: Viewing only my orders on my account page
And I addressed it to "Lucifer Morningstar", "Seaside Fwy", "90802" "Los Angeles" in the "United States" with identical billing address
And I chose "Free" shipping method with "Cash on Delivery" payment

@ui
@ui @api
Scenario: Viewing orders
When I browse my orders
Then I should see a single order in the list
58 changes: 58 additions & 0 deletions src/Sylius/Behat/Context/Api/Shop/AccountContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Sylius\Behat\Client\ResponseCheckerInterface;
use Sylius\Behat\Context\Setup\ShopSecurityContext;
use Sylius\Behat\Service\SharedStorageInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Symfony\Component\HttpFoundation\Response;
use Webmozart\Assert\Assert;
Expand All @@ -27,24 +28,39 @@ final class AccountContext implements Context
/** @var ApiClientInterface */
private $accountClient;

/** @var ApiClientInterface */
private $orderShopClient;

/** @var SharedStorageInterface */
private $sharedStorage;

/** @var ResponseCheckerInterface */
private $responseChecker;

/** @var RegistrationContext */
private $registrationContext;

/** @var LoginContext */
private $loginContext;

/** @var ShopSecurityContext */
private $shopApiSecurityContext;

public function __construct(
ApiClientInterface $accountClient,
ApiClientInterface $orderShopClient,
SharedStorageInterface $sharedStorage,
ResponseCheckerInterface $responseChecker,
RegistrationContext $registrationContext,
LoginContext $loginContext,
ShopSecurityContext $shopApiSecurityContext
) {
$this->accountClient = $accountClient;
$this->orderShopClient = $orderShopClient;
$this->sharedStorage = $sharedStorage;
$this->responseChecker = $responseChecker;
$this->registrationContext = $registrationContext;
$this->loginContext = $loginContext;
$this->shopApiSecurityContext = $shopApiSecurityContext;
}

Expand Down Expand Up @@ -189,6 +205,48 @@ public function iShouldBeNotifiedThatElementIsInvalid(): void
);
}

/**
* @When I browse my orders
*/
public function iBrowseMyOrders(): void
{
$this->orderShopClient->index();
}

/**
* @When I register with previously used :email email and :password password
*/
public function iRegisterWithPreviouslyUsedEmailAndPassword(string $email, string $password): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't it be extracted to RegistrationContext?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be... but if I do that I get many names conflicts, so I left it here.

{
$this->registrationContext->iWantToRegisterNewAccount();
$this->registrationContext->iSpecifyTheEmailAs($email);
$this->registrationContext->iSpecifyThePasswordAs($password);
$this->registrationContext->iRegisterThisAccount();

$this->loginContext->iLogInAsWithPassword($email, $password);
}

/**
* @Then I should see a single order in the list
*/
public function iShouldSeeASingleOrderInTheList(): void
{
Assert::same($this->responseChecker->countCollectionItems($this->orderShopClient->index()), 1);
}

/**
* @Then this order should have :orderNumber number
*/
public function thisOrderShouldHaveNumber(string $orderNumber): void
{
Assert::true(
$this->responseChecker->hasItemWithValue($this->orderShopClient->getLastResponse(),
'number',
$orderNumber
)
);
}

private function isViolationWithMessageInResponse(Response $response, string $message): bool
{
$violations = $this->responseChecker->getResponseContent($response)['violations'];
Expand Down
20 changes: 20 additions & 0 deletions src/Sylius/Behat/Context/Setup/OrderContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,26 @@ public function theGuestCustomerPlacedOrderWithForAndBasedShippingAddress(
$this->objectManager->flush();
}

/**
* @Given /^the another guest customer placed order with ("[^"]+" product) for "([^"]+)" and ("[^"]+" based billing address) with ("[^"]+" shipping method) and ("[^"]+" payment)$/
*/
public function theAnotherGuestCustomerPlacedOrderWithForAndBasedShippingAddress(
ProductInterface $product,
string $email,
AddressInterface $address,
ShippingMethodInterface $shippingMethod,
PaymentMethodInterface $paymentMethod
) {
$customer = $this->createCustomer($email);

$this->customerRepository->add($customer);

$this->sharedStorage->set('customer', $customer);

$this->placeOrder($product, $shippingMethod, $address, $paymentMethod, $customer, 2);
$this->objectManager->flush();
}

/**
* @Given a customer :customer added something to cart
*/
Expand Down
14 changes: 14 additions & 0 deletions src/Sylius/Behat/Context/Setup/UserContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ public function thereIsUserIdentifiedBy($email, $password = 'sylius')
$this->userRepository->add($user);
}

/**
* @Given I registered with previously used :email email and :password password
*/
public function theCustomerCreatedAccountWithPassword(string $email, string $password = 'sylius'): void
{
/** @var ShopUserInterface $user */
$user = $this->userFactory->create(['email' => $email, 'password' => $password, 'enabled' => true]);

$user->setCustomer($this->sharedStorage->get('customer'));
$this->sharedStorage->set('user', $user);

$this->userRepository->add($user);
}

/**
* @Given the account of :email was deleted
* @Given my account :email was deleted
Expand Down
11 changes: 11 additions & 0 deletions src/Sylius/Behat/Context/Ui/Shop/AccountContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,17 @@ public function iViewingTheSummaryOfMyLastOrder()
$this->orderIndexPage->openLastOrderPage();
}

/**
* @When I log in as :email with :password password
*/
public function iLogInAsWithPassword(string $email, string $password): void
{
$this->loginPage->open();
$this->loginPage->specifyUsername($email);
$this->loginPage->specifyPassword($password);
$this->loginPage->logIn();
}

/**
* @Then it should has number :orderNumber
* @Then it should have the number :orderNumber
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,11 @@

<service id="sylius.behat.context.api.shop.account" class="Sylius\Behat\Context\Api\Shop\AccountContext">
<argument type="service" id="sylius.behat.api_platform_client.shop.account" />
<argument type="service" id="sylius.behat.api_platform_client.shop.order" />
<argument type="service" id="sylius.behat.shared_storage" />
<argument type="service" id="Sylius\Behat\Client\ResponseCheckerInterface" />
<argument type="service" id="sylius.behat.context.api.shop.registration" />
<argument type="service" id="sylius.behat.context.api.shop.login" />
<argument type="service" id="sylius.behat.context.setup.shop_api_security" />
</service>
</services>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ default:
- sylius.behat.context.hook.doctrine_orm

- sylius.behat.context.transform.address
- sylius.behat.context.transform.channel
- sylius.behat.context.transform.country
- sylius.behat.context.transform.customer
- sylius.behat.context.transform.lexical
- sylius.behat.context.transform.order
- sylius.behat.context.transform.payment
- sylius.behat.context.transform.product
- sylius.behat.context.transform.shared_storage
- sylius.behat.context.transform.shipping_method
- sylius.behat.context.transform.user

- sylius.behat.context.setup.cart
- sylius.behat.context.setup.channel
- sylius.behat.context.setup.currency
- sylius.behat.context.setup.customer
Expand All @@ -29,6 +32,8 @@ default:

- sylius.behat.context.api.shop.account
- sylius.behat.context.api.shop.order
- sylius.behat.context.api.shop.checkout
- sylius.behat.context.api.shop.login

filters:
tags: "@customer_account && @api"
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ default:
- sylius.behat.context.ui.shop.cart
- sylius.behat.context.ui.shop.checkout
- sylius.behat.context.ui.shop.checkout.addressing
- sylius.behat.context.ui.shop.checkout.shipping
- sylius.behat.context.ui.shop.checkout.payment
- sylius.behat.context.ui.shop.checkout.complete
- sylius.behat.context.ui.shop.checkout.payment
- sylius.behat.context.ui.shop.checkout.shipping
- sylius.behat.context.ui.shop.currency

filters:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* 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\ApiBundle\DataProvider;

use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
use Sylius\Component\Core\Model\AdminUserInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;

AdamKasp marked this conversation as resolved.
Show resolved Hide resolved
/** @experimental */
final class OrderCollectionDataProvider implements CollectionDataProviderInterface, RestrictedDataProviderInterface
{
/** @var UserContextInterface */
private $userContext;

/** @var OrderRepositoryInterface */
private $orderRepository;

public function __construct(UserContextInterface $userContext, OrderRepositoryInterface $orderRepository)
{
$this->userContext = $userContext;
$this->orderRepository = $orderRepository;
}

public function getCollection(string $resourceClass, string $operationName = null)
{
/** @var ShopUserInterface $user */
$user = $this->userContext->getUser();

if ($user instanceof AdminUserInterface && in_array('ROLE_API_ACCESS', $user->getRoles(), true)) {
return $this->orderRepository->findAllExceptCarts();
}

if ($user instanceof ShopUserInterface) {
/** @var CustomerInterface $customer */
$customer = $user->getCustomer();

return $this->orderRepository->findByCustomer($customer);
}

return [];
}

public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return is_a($resourceClass, OrderInterface::class, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@
<attribute name="summary">Pickups a new cart</attribute>
</attribute>
</collectionOperation>

<collectionOperation name="shop_get">
<attribute name="method">GET</attribute>
<attribute name="path">/shop/orders</attribute>
<attribute name="normalization_context">
<attribute name="groups">
<attribute>shop:order:read</attribute>
</attribute>
</attribute>
</collectionOperation>
</collectionOperations>

<itemOperations>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
<attribute name="id">
<group>order:read</group>
<group>checkout:read</group>
<group>shop:order:read</group>
</attribute>

<attribute name="number">
<group>order:read</group>
<group>checkout:read</group>
<group>shop:order:read</group>
</attribute>

<attribute name="channel">
Expand Down Expand Up @@ -70,6 +72,7 @@
<attribute name="tokenValue">
<group>order:read</group>
<group>checkout:read</group>
<group>shop:order:read</group>
</attribute>

<attribute name="items">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,14 @@
<service id="sylius.api.context.user" class="Sylius\Bundle\ApiBundle\Context\TokenBasedUserContext">
<argument type="service" id="security.token_storage" />
</service>

<service
id="sylius.api.collection_data_provider.orders"
class="Sylius\Bundle\ApiBundle\DataProvider\OrderCollectionDataProvider"
>
<argument type="service" id="sylius.api.context.user" />
<argument type="service" id="sylius.repository.order" />
<tag name="api_platform.collection_data_provider" priority="10" />
</service>
</services>
</container>
Loading