List of channel currencies endpoint

This commit is contained in:
Paula 2021-11-11 16:42:33 +01:00
parent e125bb1580
commit f3824d6f04
9 changed files with 238 additions and 1 deletions

View file

@ -13,11 +13,16 @@ Feature: Switching the current currency
When I browse that channel
Then I should shop using the "EUR" currency
@ui
@ui @no-api
Scenario: Showing available currencies
When I browse that channel
Then I should be able to shop using the "USD" currency
@api
Scenario: Showing available currencies
When I browse currencies
Then I should see "USD" and "EUR" in the list
@ui @no-api
Scenario: Switching the current currency
When I browse that channel

View file

@ -0,0 +1,57 @@
<?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\Behat\Context\Api\Shop;
use Behat\Behat\Context\Context;
use Sylius\Behat\Client\ApiClientInterface;
use Sylius\Behat\Client\ResponseCheckerInterface;
use Sylius\Component\Currency\Model\CurrencyInterface;
use Webmozart\Assert\Assert;
final class CurrencyContext implements Context
{
private ApiClientInterface $client;
private ResponseCheckerInterface $responseChecker;
public function __construct(
ApiClientInterface $client,
ResponseCheckerInterface $responseChecker
) {
$this->client = $client;
$this->responseChecker = $responseChecker;
}
/**
* @When /^I (?:start browsing|try to browse|browse) currencies$/
*/
public function iBrowseCurrencies(): void
{
$this->client->index();
}
/**
* @Then I should see :firstCurrency in the list
* @Then I should see :firstCurrency and :secondCurrency in the list
* @Then I should see :firstCurrency, :secondCurrency and :thirdCurrency in the list
*/
public function iShouldSeeCurrenciesInTheList(... $currencies): void
{
$response = $this->client->getLastResponse();
foreach ($currencies as $currency) {
$this->responseChecker->getCollectionItemsWithValue($response, 'code', $currency);
}
}
}

View file

@ -44,6 +44,11 @@
<argument>shop</argument>
</service>
<service id="sylius.behat.api_platform_client.shop.currency" class="Sylius\Behat\Client\ApiPlatformClient" parent="sylius.behat.api_platform_client">
<argument>currencies</argument>
<argument>shop</argument>
</service>
<service id="sylius.behat.api_platform_client.admin.country" class="Sylius\Behat\Client\ApiPlatformClient" parent="sylius.behat.api_platform_client">
<argument>countries</argument>
<argument>admin</argument>

View file

@ -32,6 +32,12 @@
<argument type="service" id="sylius.behat.shared_storage" />
</service>
<service id="sylius.behat.context.api.shop.currency" class="Sylius\Behat\Context\Api\Shop\CurrencyContext">
<argument type="service" id="sylius.behat.api_platform_client.shop.currency" />
<argument type="service" id="Sylius\Behat\Client\ResponseCheckerInterface" />
<argument type="service" id="sylius.behat.shared_storage" />
</service>
<service id="sylius.behat.context.api.shop.cart" class="Sylius\Behat\Context\Api\Shop\CartContext">
<argument type="service" id="sylius.behat.api_platform_client.shop.cart" />
<argument type="service" id="sylius.behat.api_platform_client.admin.order" />

View file

@ -16,6 +16,7 @@ default:
- sylius.behat.context.setup.currency
- sylius.behat.context.api.shop.channel
- sylius.behat.context.api.shop.currency
filters:
tags: "@currencies&&@api"

View file

@ -0,0 +1,61 @@
<?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\Bundle\ApiBundle\Serializer\ContextKeys;
use Sylius\Component\Core\Model\AdminUserInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Currency\Model\CurrencyInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Webmozart\Assert\Assert;
/** @experimental */
final class CurrencyCollectionDataProvider implements CollectionDataProviderInterface, RestrictedDataProviderInterface
{
private UserContextInterface $userContext;
private RepositoryInterface $currencyRepository;
public function __construct(
RepositoryInterface $currencyRepository,
UserContextInterface $userContext
) {
$this->userContext = $userContext;
$this->currencyRepository = $currencyRepository;
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return is_a($resourceClass, CurrencyInterface::class, true);
}
public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
{
$user = $this->userContext->getUser();
if ($user instanceof AdminUserInterface && in_array('ROLE_API_ACCESS', $user->getRoles())) {
return $this->currencyRepository->findAll();
}
Assert::keyExists($context, ContextKeys::CHANNEL);
/** @var ChannelInterface $channel */
$channel = $context[ContextKeys::CHANNEL];
return $channel->getCurrencies();
}
}

View file

@ -31,6 +31,15 @@
<attribute name="method">POST</attribute>
<attribute name="path">/admin/currencies</attribute>
</collectionOperation>
<collectionOperation name="shop_get">
<attribute name="method">GET</attribute>
<attribute name="route_prefix">shop</attribute>
<attribute name="path">/shop/currencies</attribute>
<attribute name="normalization_context">
<attribute name="groups">shop:currency:read</attribute>
</attribute>
</collectionOperation>
</collectionOperations>
<itemOperations>

View file

@ -66,6 +66,12 @@
<tag name="api_platform.collection_data_provider" priority="10" />
</service>
<service id="Sylius\Bundle\ApiBundle\DataProvider\CurrencyCollectionDataProvider">
<argument type="service" id="sylius.repository.currency" />
<argument type="service" id="Sylius\Bundle\ApiBundle\Context\UserContextInterface" />
<tag name="api_platform.collection_data_provider" priority="10" />
</service>
<service id="Sylius\Bundle\ApiBundle\DataProvider\ProductItemDataProvider">
<argument type="service" id="sylius.repository.product" />
<argument type="service" id="Sylius\Bundle\ApiBundle\Context\UserContextInterface" />

View file

@ -0,0 +1,87 @@
<?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 spec\Sylius\Bundle\ApiBundle\DataProvider;
use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
use Sylius\Bundle\ApiBundle\Serializer\ContextKeys;
use Sylius\Component\Core\Model\AdminUserInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Currency\Model\CurrencyInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\Component\User\Model\UserInterface;
final class CurrencyCollectionDataProviderSpec extends ObjectBehavior
{
function let(RepositoryInterface $currencyRepository, UserContextInterface $userContext): void
{
$this->beConstructedWith($currencyRepository, $userContext);
}
function it_supports_only_currencies(): void
{
$this->supports(ProductInterface::class, 'get')->shouldReturn(false);
$this->supports(CurrencyInterface::class, 'get')->shouldReturn(true);
}
function it_throws_an_exception_if_context_has_not_channel(): void
{
$this
->shouldThrow(\InvalidArgumentException::class)
->during('getCollection', [CurrencyInterface::class, 'shop_get', []])
;
}
function it_provides_currencies_available_in_channel_if_user_is_not_admin(
UserContextInterface $userContext,
UserInterface $user,
ChannelInterface $channel,
CurrencyInterface $firstCurrency,
CurrencyInterface $secondCurrency
): void {
$userContext->getUser()->willReturn($user);
$user->getRoles()->willReturn(['ROLE_USER']);
$channel->addCurrency($firstCurrency);
$channel->addCurrency($secondCurrency);
$channel->getCurrencies()->willReturn(new ArrayCollection([$firstCurrency->getWrappedObject(), $secondCurrency->getWrappedObject()]));
$this
->getCollection(CurrencyInterface::class, 'get', [ContextKeys::CHANNEL => $channel])
->shouldBeLike(new ArrayCollection([$firstCurrency->getWrappedObject(), $secondCurrency->getWrappedObject()]))
;
}
function it_provides_all_currencies_if_user_is_admin(
UserContextInterface $userContext,
AdminUserInterface $user,
ChannelInterface $channel,
CurrencyInterface $firstCurrency,
CurrencyInterface $secondCurrency,
RepositoryInterface $currencyRepository
): void {
$userContext->getUser()->willReturn($user);
$user->getRoles()->willReturn(['ROLE_API_ACCESS']);
$currencyRepository->findAll()->willReturn([$firstCurrency, $secondCurrency]);
$this
->getCollection(CurrencyInterface::class, 'get', [ContextKeys::CHANNEL => $channel])
->shouldReturn([$firstCurrency, $secondCurrency])
;
}
}