Skip to content

Commit

Permalink
Add next iteration
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomanhez committed Mar 29, 2021
1 parent 0cd3da0 commit d95297d
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 153 deletions.
6 changes: 6 additions & 0 deletions UPGRADE-1.10.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
### New API

1. API CartShippingMethod key `cost` has been changed to `price`.

1. To have better control over the serialization process, we introduced `shop` and `admin` prefixes to names of serialization groups on `src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/*` and `src/Sylius/Bundle/ApiBundle/Resources/config/serialization/*`.
Several additional serialization groups have been rephrased, to improve readability and predictability of them.
If you are using they on your custom entity `api_resource` configuration or serialization groups, you should check if one of these changes may affect on your app. If yes, change all occurs by this pattern:

- `product_review:update` changed to: `admin:product_review:update` and `shop:product_review:update`
38 changes: 19 additions & 19 deletions src/Sylius/Behat/Context/Api/Shop/ProductReviewContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,6 @@ public function iCheckThisProductsReviews(): void
$this->client->filter();
}

/**
* @Then I should see :amount product reviews in the list
* @Then I should be notified that there are no reviews
*/
public function iShouldSeeProductReviewsInTheList(int $amount = 0): void
{
$productReviews = $this->responseChecker->getCollection($this->client->getLastResponse());

Assert::count($productReviews, $amount);
}

/**
* @Then I should not see review titled :title in the list
*/
public function iShouldNotSeeReviewTitledInTheList(string $title): void
{
Assert::isEmpty($this->responseChecker->getCollectionItemsWithValue($this->client->getLastResponse(), 'title', $title));
}

/**
* @When I add it
*/
Expand Down Expand Up @@ -126,4 +107,23 @@ public function iShouldBeNotifiedThatMyReviewIsWaitingForTheAcceptation(): void
ReviewInterface::STATUS_NEW
);
}

/**
* @Then I should see :amount product reviews in the list
* @Then I should be notified that there are no reviews
*/
public function iShouldSeeProductReviewsInTheList(int $amount = 0): void
{
$productReviews = $this->responseChecker->getCollection($this->client->getLastResponse());

Assert::count($productReviews, $amount);
}

/**
* @Then I should not see review titled :title in the list
*/
public function iShouldNotSeeReviewTitledInTheList(string $title): void
{
Assert::isEmpty($this->responseChecker->getCollectionItemsWithValue($this->client->getLastResponse(), 'title', $title));
}
}
4 changes: 2 additions & 2 deletions src/Sylius/Bundle/ApiBundle/Command/AddProductReview.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace Sylius\Bundle\ApiBundle\Command;

/** @experimental */
class AddProductReview
class AddProductReview implements CommandAwareDataTransformerInterface
{
/**
* @var string
Expand Down Expand Up @@ -51,7 +51,7 @@ public function __construct(
int $rating,
string $comment,
string $productCode,
string $email = null
?string $email = null
) {
$this->title = $title;
$this->rating = $rating;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,54 +29,44 @@
/** @experimental */
final class AddProductReviewHandler implements MessageHandlerInterface
{
/** @var UserContextInterface */
private $userContext;

/** @var CustomerProviderInterface */
private $customerProvider;
/** @var FactoryInterface */
private $productReviewFactory;

/** @var RepositoryInterface */
private $productReviewRepository;

/** @var FactoryInterface */
private $productReviewFactory;

/** @var ProductRepositoryInterface */
private $productRepository;

/** @var CustomerProviderInterface */
private $customerProvider;

public function __construct(
UserContextInterface $userContext,
CustomerProviderInterface $customerProvider,
RepositoryInterface $productReviewRepository,
FactoryInterface $productReviewFactory,
ProductRepositoryInterface $productRepository
RepositoryInterface $productReviewRepository,
ProductRepositoryInterface $productRepository,
CustomerProviderInterface $customerProvider
) {
$this->userContext = $userContext;
$this->customerProvider = $customerProvider;
$this->productReviewRepository = $productReviewRepository;
$this->productReviewFactory = $productReviewFactory;
$this->productReviewRepository = $productReviewRepository;
$this->productRepository = $productRepository;
$this->customerProvider = $customerProvider;
}

public function __invoke(AddProductReview $addProductReview): ReviewInterface
{
/** @var ProductInterface $product */
$product = $this->productRepository->findOneByCode($addProductReview->productCode);

/** @var CustomerInterface|null $customer */
$customer = $this->getCustomer();

/** @var string|null $email */
$email = $addProductReview->email;

if ($customer === null && $email === null) {
if ($email === null) {
throw new \InvalidArgumentException('Visitor should provide an email');
}

if ($customer === null && $email !== null) {
/** @var CustomerInterface $customer */
$customer = $this->customerProvider->provide($email);
}
/** @var CustomerInterface $customer */
$customer = $this->customerProvider->provide($email);

/** @var ReviewInterface $review */
$review = $this->productReviewFactory->createNew();
Expand All @@ -86,21 +76,10 @@ public function __invoke(AddProductReview $addProductReview): ReviewInterface
$review->setReviewSubject($product);
$review->setAuthor($customer);

$this->productReviewRepository->add($review);

$product->addReview($review);

return $review;
}

private function getCustomer(): ?CustomerInterface
{
/** @var UserInterface|null $user */
$user = $this->userContext->getUser();
if ($user !== null && $user instanceof ShopUserInterface) {
return $user->getCustomer();
}
$this->productReviewRepository->add($review);

return null;
return $review;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use Sylius\Component\Core\Model\ShopUserInterface;

/** @experimental */
final class AddProductReviewInputDataTransformer implements CommandDataTransformerInterface
final class LoggedInShopUserEmailAwareCommandDataTransformer implements CommandDataTransformerInterface
{
/** @var UserContextInterface */
private $userContext;
Expand All @@ -35,7 +35,7 @@ public function transform($object, string $to, array $context = [])
/** @var CustomerInterface|null $customer */
$customer = $this->getCustomer();

if ($object->email === null && $customer !== null) {
if ($customer !== null) {
$object->email = $customer->getEmail();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
</attribute>
<attribute name="status">
<group>admin:product_review:read</group>
<group>shop:product_review:read</group>
</attribute>
<attribute name="reviewSubject">
<group>admin:product_review:read</group>
Expand Down
5 changes: 5 additions & 0 deletions src/Sylius/Bundle/ApiBundle/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@
<tag name="sylius.api.command_data_transformer" />
</service>

<service id="sylius.api.data_transformer.add_product_review_input_data_transformer" class="Sylius\Bundle\ApiBundle\DataTransformer\LoggedInShopUserEmailAwareCommandDataTransformer">
<argument type="service" id="sylius.api.context.user" />
<tag name="sylius.api.command_data_transformer" />
</service>

<service id="sylius.api.data_transformer.locale_code_aware_input_data_transformer" class="Sylius\Bundle\ApiBundle\DataTransformer\LocaleCodeAwareInputCommandDataTransformer">
<argument type="service" id="sylius.context.locale.composite" />
<tag name="sylius.api.command_data_transformer" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,10 @@
</service>

<service id="Sylius\Bundle\ApiBundle\CommandHandler\AddProductReviewHandler">
<argument type="service" id="sylius.api.context.user" />
<argument type="service" id="Sylius\Bundle\ApiBundle\Provider\CustomerProviderInterface" />
<argument type="service" id="sylius.repository.product_review" />
<argument type="service" id="sylius.factory.product_review" />
<argument type="service" id="sylius.repository.product_review" />
<argument type="service" id="sylius.repository.product" />
<argument type="service" id="Sylius\Bundle\ApiBundle\Provider\CustomerProviderInterface" />
<tag name="messenger.message_handler" bus="sylius_default.bus"/>
</service>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@

use PhpSpec\ObjectBehavior;
use Sylius\Bundle\ApiBundle\Command\AddProductReview;
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
use Sylius\Bundle\ApiBundle\Provider\CustomerProviderInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
Expand All @@ -28,116 +26,69 @@
final class AddProductReviewHandlerSpec extends ObjectBehavior
{
function let(
UserContextInterface $userContext,
CustomerProviderInterface $customerProvider,
RepositoryInterface $productReviewRepository,
FactoryInterface $productReviewFactory,
ProductRepositoryInterface $productRepository
RepositoryInterface $productReviewRepository,
ProductRepositoryInterface $productRepository,
CustomerProviderInterface $customerProvider
): void {
$this->beConstructedWith(
$userContext,
$customerProvider,
$productReviewRepository,
$productReviewFactory,
$productRepository
$productReviewRepository,
$productRepository,
$customerProvider
);
}

function it_adds_product_review_for_login_shop_user(
UserContextInterface $userContext,
RepositoryInterface $productReviewRepository,
function it_adds_product_review(
FactoryInterface $productReviewFactory,
RepositoryInterface $productReviewRepository,
ProductRepositoryInterface $productRepository,
CustomerProviderInterface $customerProvider,
ProductInterface $product,
ShopUserInterface $shopUser,
CustomerInterface $customer,
ReviewInterface $review
): void {
$addProductReview = new AddProductReview(
'Good stuff',
5,
'Really good stuff',
'winter_cap'
);

$productRepository->findOneByCode($addProductReview->productCode)->willReturn($product);
$productRepository->findOneByCode('winter_cap')->willReturn($product);

$userContext->getUser()->willReturn($shopUser);

$shopUser->getCustomer()->willReturn($customer);
$customerProvider->provide('mark@example.com')->willReturn($customer);

$productReviewFactory->createNew()->willReturn($review);

$review->setTitle($addProductReview->title)->shouldBeCalled();
$review->setRating($addProductReview->rating)->shouldBeCalled();
$review->setComment($addProductReview->comment)->shouldBeCalled();
$review->setTitle('Good stuff')->shouldBeCalled();
$review->setRating(5)->shouldBeCalled();
$review->setComment('Really good stuff')->shouldBeCalled();
$review->setReviewSubject($product->getWrappedObject())->shouldBeCalled();
$review->setAuthor($customer)->shouldBeCalled();

$productReviewRepository->add($review);

$this($addProductReview);
}
$product->addReview($review->getWrappedObject())->shouldBeCalled();

function it_adds_product_review_for_visitor(
UserContextInterface $userContext,
CustomerProviderInterface $customerProvider,
RepositoryInterface $productReviewRepository,
FactoryInterface $productReviewFactory,
ProductRepositoryInterface $productRepository,
ProductInterface $product,
ShopUserInterface $shopUser,
CustomerInterface $customer,
ReviewInterface $review
): void {
$addProductReview = new AddProductReview(
$this(new AddProductReview(
'Good stuff',
5,
'Really good stuff',
'winter_cap',
'boob@example.com'
);

$productRepository->findOneByCode($addProductReview->productCode)->willReturn($product);

$userContext->getUser()->willReturn($shopUser);

$shopUser->getCustomer()->willReturn($customer);

$customerProvider->provide($addProductReview->email)->willReturn($customer);

$productReviewFactory->createNew()->willReturn($review);

$review->setTitle($addProductReview->title)->shouldBeCalled();
$review->setRating($addProductReview->rating)->shouldBeCalled();
$review->setComment($addProductReview->comment)->shouldBeCalled();
$review->setReviewSubject($product->getWrappedObject())->shouldBeCalled();
$review->setAuthor($customer)->shouldBeCalled();

$productReviewRepository->add($review);

$this($addProductReview);
'mark@example.com'
));
}

function it_throws_exception_if_shop_user_has_not_been_found(
UserContextInterface $userContext,
function it_throws_an_exception_if_email_has_not_been_found(
ProductRepositoryInterface $productRepository,
ProductInterface $product
): void {
$addProductReview = new AddProductReview(
'Good stuff',
5,
'Really good stuff',
'winter_cap'
);

$productRepository->findOneByCode($addProductReview->productCode)->willReturn($product);

$userContext->getUser()->willReturn(null);
$productRepository->findOneByCode('winter_cap')->willReturn($product);

$this
->shouldThrow(\InvalidArgumentException::class)
->during('__invoke', [$addProductReview])
->during('__invoke', [
new AddProductReview(
'Good stuff',
5,
'Really good stuff',
'winter_cap'
)
])
;
}
}
Loading

0 comments on commit d95297d

Please sign in to comment.