Skip to content

Commit

Permalink
feature Sylius#14724 As an Admin, I want to modify taxons of a produc…
Browse files Browse the repository at this point in the history
…t (everwhatever)

This PR was merged into the 1.13 branch.

Discussion
----------

| Q               | A                                                            |
|-----------------|--------------------------------------------------------------|
| Branch?         | 1.13 |
| Bug fix?        | no |
| New feature?    | yes |
| BC breaks?      | no  |
| Deprecations?   | no |
| Related tickets | [jira]( https://sylius.atlassian.net/browse/SYL-2215)           |
| License         | MIT                                                          |

<!--
 - Bug fixes must be submitted against the 1.11 or 1.12 branch
 - Features and deprecations must be submitted against the 1.13 branch
 - Make sure that the correct base branch is set

 To be sure you are not breaking any Backward Compatibilities, check the documentation:
 https://docs.sylius.com/en/latest/book/organization/backward-compatibility-promise.html
-->


Commits
-------

a1b8d59 As an Admin, I want to modify taxons of a product
e9247b7 after cr
  • Loading branch information
GSadee authored Jan 18, 2023
2 parents 74bdaea + e9247b7 commit 4ea270c
Show file tree
Hide file tree
Showing 18 changed files with 274 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@managing_products
Feature: Modifying taxons assigned to an exisiting product
In order to specify in which taxon a product is available
As an Administrator
I want to be able to change taxon of a product

Background:
Given the store operates on a single channel in "United States"
And the store classifies its products as "Clothes" and "T-Shirts"
And the store has a "Shirt" configurable product
And the store has a "T-Shirt" configurable product
And the product "T-Shirt" belongs to taxon "Clothes"
And I am logged in as an administrator

@ui @api
Scenario: Modifying taxons assigned to a product
When I change that the "T-Shirt" product belongs to the "T-Shirts" taxon
Then the product "T-Shirt" should have the "T-Shirts" taxon

@ui @api
Scenario: Adding taxons to product
When I add "Clothes" taxon to the "Shirt" product
Then the product "Shirt" should have the "Clothes" taxon
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Feature: Reapplying catalog promotions on variants once the product’s taxon ch
When I change that the "T-Shirt" product does not belong to the "Clothes" taxon
Then the visitor should see that the "PHP T-Shirt" variant is not discounted

@ui
@ui @api
Scenario: Adding a taxon to a product
When I change that the "Mug" product belongs to the "Dishes" taxon
When I assign the "Dishes" taxon to the "Mug" product
Then the visitor should see that the "PHP Mug" variant is discounted from "$10.00" to "$5.00" with "Summer sale" promotion
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?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\Admin;

use ApiPlatform\Core\Api\IriConverterInterface;
use Behat\Behat\Context\Context;
use Sylius\Behat\Client\ApiClientInterface;
use Sylius\Behat\Context\Api\Resources;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\TaxonInterface;

final class ManagingProductTaxonsContext implements Context
{
public function __construct(private ApiClientInterface $client, private IriConverterInterface $iriConverter)
{
}

/**
* @When I change that the :product product belongs to the :taxon taxon
*/
public function iChangeThatTheProductBelongsToTheTaxon(ProductInterface $product, TaxonInterface $taxon): void
{
$this->client->buildUpdateRequest(Resources::PRODUCT_TAXONS, (string) $product->getProductTaxons()->current()->getId());
$this->client->updateRequestData(['taxon' => $this->iriConverter->getIriFromItem($taxon)]);
$this->client->update();
}

/**
* @When I assign the :taxon taxon to the :product product
* @When I add :taxon taxon to the :product product
*/
public function iAddTaxonToTheProduct(TaxonInterface $taxon, ProductInterface $product): void
{
$this->client->buildCreateRequest(Resources::PRODUCT_TAXONS);
$this->client->addRequestData('taxon', $this->iriConverter->getIriFromItem($taxon));
$this->client->addRequestData('product', $this->iriConverter->getIriFromItem($product));
$this->client->create();
}
}
22 changes: 22 additions & 0 deletions src/Sylius/Behat/Context/Api/Admin/ManagingProductsContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,20 @@ public function thisProductMainTaxonShouldBe(ProductInterface $product, TaxonInt
Assert::same($mainTaxon, $this->iriConverter->getIriFromItem($taxon));
}

/**
* @Then the product :product should have the :taxon taxon
*/
public function thisProductTaxonShouldBe(ProductInterface $product, TaxonInterface $taxon): void
{
$productTaxonId = $this->getProductTaxonId($product);

$response = $this->client->show(Resources::PRODUCT_TAXONS, (string) $productTaxonId);
$productTaxonIri = $this->responseChecker->getValue($response, 'taxon');
$productTaxonCodes = explode('/', $productTaxonIri);

Assert::same(array_pop($productTaxonCodes), $taxon->getCode());
}

/**
* @Then /^(this product) name should be "([^"]+)"$/
*/
Expand Down Expand Up @@ -547,4 +561,12 @@ private function getLastResponse(): Response
{
return $this->sharedStorage->has('response') ? $this->sharedStorage->get('response') : $this->client->getLastResponse();
}

private function getProductTaxonId(ProductInterface $product): string
{
$productResponse = $this->client->show(Resources::PRODUCTS, (string)$product->getCode());
$productTaxonUrl = explode('/', $this->responseChecker->getValue($productResponse, 'productTaxons')[0]);

return array_pop($productTaxonUrl);
}
}
2 changes: 2 additions & 0 deletions src/Sylius/Behat/Context/Api/Resources.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ final class Resources

public const PRODUCT_REVIEWS = 'product-reviews';

public const PRODUCT_TAXONS = 'product-taxons';

public const PRODUCT_VARIANTS = 'product-variants';

public const PRODUCTS = 'products';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public function __construct(private UpdateSimpleProductPageInterface $updateSimp

/**
* @When I change that the :product product belongs to the :taxon taxon
* @When I add :taxon taxon to the :product product
* @When I assign the :taxon taxon to the :product product
*/
public function iChangeThatTheProductBelongsToTheTaxon(ProductInterface $product, TaxonInterface $taxon): void
{
Expand Down
11 changes: 11 additions & 0 deletions src/Sylius/Behat/Context/Ui/Admin/ManagingProductsContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,17 @@ public function thisProductMainTaxonShouldBe(ProductInterface $product, $taxonNa
Assert::true($currentPage->isMainTaxonChosen($taxonName));
}

/**
* @Then the product :product should have the :taxon taxon
*/
public function thisProductTaxonShouldBe(ProductInterface $product, string $taxonName): void
{
$currentPage = $this->resolveCurrentPage();
$currentPage->open(['id' => $product->getId()]);

Assert::true($currentPage->isTaxonChosen($taxonName));
}

/**
* @Then /^inventory of (this product) should not be tracked$/
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,15 @@ public function isMainTaxonChosen(string $taxonName): bool
return $taxonName === $this->getDocument()->find('css', '.search > .text')->getText();
}

public function isTaxonChosen(string $taxonName): bool
{
$productTaxonsElement = $this->getElement('product_taxons');

$taxonName = strtolower(str_replace('-', '_', $taxonName));

return str_contains($productTaxonsElement->getValue(), $taxonName);
}

public function disableTracking(): void
{
$this->getElement('tracked')->uncheck();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public function hasNonTranslatableAttributeWithValue(string $attributeName, stri

public function isMainTaxonChosen(string $taxonName): bool;

public function isTaxonChosen(string $taxonName): bool;

public function selectMainTaxon(TaxonInterface $taxon): void;

public function selectProductTaxon(TaxonInterface $taxon): void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@
<argument type="service" id="sylius.behat.request_factory" />
</service>

<service id="Sylius\Behat\Context\Api\Admin\ManagingProductTaxonsContext">
<argument type="service" id="sylius.behat.api_platform_client.admin" />
<argument type="service" id="api_platform.iri_converter" />
</service>

<service id="sylius.behat.context.api.admin.managing_channels" class="Sylius\Behat\Context\Api\Admin\ManagingChannelsContext">
<argument type="service" id="sylius.behat.api_platform_client.admin" />
<argument type="service" id="Sylius\Behat\Client\ResponseCheckerInterface" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ default:
- sylius.behat.context.setup.shipping_category
- sylius.behat.context.setup.taxonomy
- sylius.behat.context.setup.zone
- Sylius\Behat\Context\Api\Admin\ManagingProductTaxonsContext

- sylius.behat.context.api.admin.managing_products

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ default:
- sylius.behat.context.api.shop.login
- sylius.behat.context.api.shop.product
- sylius.behat.context.api.shop.product_variant
- Sylius\Behat\Context\Api\Admin\ManagingProductTaxonsContext

filters:
tags: "@applying_catalog_promotions&&@api"
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ default:
- sylius.behat.context.ui.admin.managing_products
- sylius.behat.context.ui.admin.notification
- sylius.behat.context.ui.shop.browsing_product
- Sylius\Behat\Context\Ui\Admin\ManagingProductTaxonsContext

filters:
tags: "@managing_products&&@ui"
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?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\DataPersister;

use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
use Sylius\Component\Core\Event\ProductUpdated;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductTaxonInterface;
use Symfony\Component\Messenger\MessageBusInterface;

/** @experimental */
final class ProductTaxonDataPersister implements ContextAwareDataPersisterInterface
{
public function __construct(
private ContextAwareDataPersisterInterface $decoratedDataPersister,
private MessageBusInterface $eventBus,
) {
}

public function supports($data, array $context = []): bool
{
return $data instanceof ProductTaxonInterface;
}

public function persist($data, array $context = [])
{
/** @var ProductInterface $product */
$product = $data->getProduct();
$product->addProductTaxon($data);

$this->decoratedDataPersister->persist($data, $context);

$this->eventBus->dispatch(new ProductUpdated($product->getCode()));
}

public function remove($data, array $context = [])
{
return $this->decoratedDataPersister->remove($data, $context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
<attribute name="groups">admin:product_taxon:read</attribute>
</attribute>
</collectionOperation>
<collectionOperation name="admin_post">
<attribute name="method">POST</attribute>
<attribute name="path">/admin/product-taxons</attribute>
<attribute name="denormalization_context">
<attribute name="groups">admin:product_taxon:create</attribute>
</attribute>
</collectionOperation>
</collectionOperations>

<itemOperations>
Expand All @@ -25,6 +32,13 @@
<attribute name="groups">admin:product_taxon:read</attribute>
</attribute>
</itemOperation>
<itemOperation name="admin_put">
<attribute name="method">PUT</attribute>
<attribute name="path">/admin/product-taxons/{id}</attribute>
<attribute name="denormalization_context">
<attribute name="groups">admin:product_taxon:update</attribute>
</attribute>
</itemOperation>
<itemOperation name="shop_get">
<attribute name="method">GET</attribute>
<attribute name="path">/shop/product-taxons/{id}</attribute>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
</attribute>
<attribute name="taxon">
<group>admin:product_taxon:read</group>
<group>admin:product_taxon:update</group>
<group>admin:product_taxon:create</group>
<group>shop:product_taxon:read</group>
</attribute>
<attribute name="product">
<group>admin:product_taxon:read</group>
<group>admin:product_taxon:update</group>
<group>admin:product_taxon:create</group>
<group>shop:product_taxon:read</group>
</attribute>
</class>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@
<tag name="api_platform.data_persister" />
</service>

<service id="Sylius\Bundle\ApiBundle\DataPersister\ProductTaxonDataPersister">
<argument type="service" id="api_platform.doctrine.orm.data_persister" />
<argument type="service" id="sylius.event_bus" />
<tag name="api_platform.data_persister" />
</service>

<service id="Sylius\Bundle\ApiBundle\DataPersister\ZoneDataPersister">
<argument type="service" id="api_platform.doctrine.orm.data_persister" />
<argument type="service" id="Sylius\Component\Addressing\Checker\ZoneDeletionCheckerInterface" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?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\DataPersister;

use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Event\ProductUpdated;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductTaxonInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;

class ProductTaxonDataPersisterSpec extends ObjectBehavior
{
function let(
ContextAwareDataPersisterInterface $decoratedDataPersister,
MessageBusInterface $eventBus,
): void {
$this->beConstructedWith($decoratedDataPersister, $eventBus);
}

function it_supports_only_product_taxon_entity(ProductTaxonInterface $productTaxon, ProductInterface $product): void
{
$this->supports($productTaxon)->shouldReturn(true);
$this->supports($product)->shouldReturn(false);
}

function it_uses_decorated_data_persister_to_remove_product_taxon(
ContextAwareDataPersisterInterface $decoratedDataPersister,
ProductTaxonInterface $productTaxon,
): void {
$decoratedDataPersister->remove($productTaxon, [])->shouldBeCalled();

$this->remove($productTaxon, []);
}

function it_uses_decorated_data_persister_to_persist_product_taxon_and_product(
ContextAwareDataPersisterInterface $decoratedDataPersister,
ProductTaxonInterface $productTaxon,
ProductInterface $product,
MessageBusInterface $eventBus,
): void {
$productTaxon->getProduct()->willReturn($product);
$product->getCode()->willReturn('t_shirt');
$message = new ProductUpdated('t_shirt');

$product->addProductTaxon($productTaxon)->shouldBeCalled();
$decoratedDataPersister->persist($productTaxon, [])->shouldBeCalled();
$eventBus->dispatch($message)->willReturn(new Envelope($message))->shouldBeCalled();

$this->persist($productTaxon, []);
}
}

0 comments on commit 4ea270c

Please sign in to comment.