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

[Products][CatalogPromotions] Catalog promotion details on both simple and configurable products #14378

Merged
merged 3 commits into from
Sep 29, 2022
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
@@ -0,0 +1,20 @@
@viewing_products
Feature: Seeing applied catalog promotions details for a simple product
In order to be aware of simple product price change reason
As an Administrator
I want to see details of catalog promotion nearby product's price

Background:
Given the store operates on a single channel in "United States"
And the store has a product "Ursus C-355" priced at "$1000.00" in "United States" channel
And there is a catalog promotion with "company_bankruptcy_sale" code and "Company bankruptcy sale" name
And the catalog promotion "Company bankruptcy sale" is available in "United States"
And it applies on "Ursus C-355" product
And it reduces price by "90%"
And it is enabled
And I am logged in as an administrator

@ui
Scenario: Seeing applied catalog promotion details on a simple product
When I access "Ursus C-355" product
Then this product price should be decreased by catalog promotion "Company bankruptcy sale" in "United States" channel
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@viewing_products
Feature: Seeing applied catalog promotions details within variant
In order to be aware of variant's price change reason
As an Administrator
I want to see details of catalog promotion nearby variant's price

Background:
Given the store operates on a single channel in "United States"
And the store has a "Wyborowa Vodka" configurable product
And the product "Wyborowa Vodka" has a "Wyborowa Vodka Exquisite" variant priced at "$40.00"
And the product "Wyborowa Vodka" has a "Wyborowa Vodka Lemon" variant priced at "$10.00"
And there is a catalog promotion with "winter_sale" code and "Winter sale" name
And the catalog promotion "Winter sale" is available in "United States"
And it applies on "Wyborowa Vodka Exquisite" variant
And it reduces price by "13%"
And it is enabled
And there is also a catalog promotion with "christmas_sale" code and "Christmas sale" name
And the catalog promotion "Christmas sale" is available in "United States"
And it applies on "Wyborowa Vodka Lemon" variant
And it reduces price by "37%"
And it is enabled
And I am logged in as an administrator

@ui
Scenario: Seeing applied catalog promotion details within variant
When I access "Wyborowa Vodka" product
Then "Wyborowa Vodka Exquisite" variant price should be decreased by catalog promotion "Winter sale" in "United States" channel
And "Wyborowa Vodka Lemon" variant price should not be decreased by catalog promotion "Winter sale" in "United States" channel
And "Wyborowa Vodka Exquisite" variant price should not be decreased by catalog promotion "Christmas sale" in "United States" channel
And "Wyborowa Vodka Lemon" variant price should be decreased by catalog promotion "Christmas sale" in "United States" channel
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ Feature: Viewing details of a product with variants
Scenario: Viewing variants block
When I access "Iron Shield" product page
Then I should see 2 variants
And I should see "Iron Shield - very big" variant with code "123456789-xl", priced "$25.00" and current stock 5
And I should see "Iron Shield - very small" variant with code "123456789-xs", priced "$15.00" and current stock 12
And I should see "Iron Shield - very big" variant with code "123456789-xl", priced "$25.00" and current stock 5 and in "United States" channel
And I should see "Iron Shield - very small" variant with code "123456789-xs", priced "$15.00" and current stock 12 and in "United States" channel

@ui @javascript
Scenario: Viewing media block
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public function __construct(

/**
* @Given there is a catalog promotion with :code code and :name name
* @Given there is also a catalog promotion with :code code and :name name
*/
public function thereIsACatalogPromotionWithCodeAndName(string $code, string $name): void
{
Expand Down
79 changes: 73 additions & 6 deletions src/Sylius/Behat/Context/Ui/Admin/ProductShowPageContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
use Sylius\Behat\Element\Product\ShowPage\VariantsElementInterface;
use Sylius\Behat\Page\Admin\Product\IndexPageInterface;
use Sylius\Behat\Page\Admin\Product\ShowPageInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Webmozart\Assert\Assert;

final class ProductShowPageContext implements Context
Expand All @@ -45,6 +47,7 @@ public function __construct(
private TaxonomyElementInterface $taxonomyElement,
private OptionsElementInterface $optionsElement,
private VariantsElementInterface $variantsElement,
private UrlGeneratorInterface $urlGenerator,
) {
}

Expand Down Expand Up @@ -88,6 +91,14 @@ public function iGoToEditPage(): void
$this->productShowPage->showProductEditPage();
}

/**
* @When I access :product product
*/
public function iAccessProduct(ProductInterface $product): void
{
$this->productShowPage->open(['id' => $product->getId()]);
}

/**
* @When I go to edit page of :variant variant
*/
Expand Down Expand Up @@ -155,9 +166,9 @@ public function iShouldNotSeePriceForChannel(string $channelName): void
/**
* @Then I should see original price :price for channel :channelName
*/
public function iShouldSeeOrginalPriceForChannel(string $orginalPrice, string $channelName): void
public function iShouldSeeOriginalPriceForChannel(string $originalPrice, string $channelName): void
{
Assert::same($this->pricingElement->getOriginalPriceForChannel($channelName), $orginalPrice);
Assert::same($this->pricingElement->getOriginalPriceForChannel($channelName), $originalPrice);
}

/**
Expand Down Expand Up @@ -329,11 +340,22 @@ public function iShouldSeeVariants(int $count): void
}

/**
* @Then I should see :variantName variant with code :code, priced :price and current stock :currentStock
* @Then I should see :variantName variant with code :code, priced :price and current stock :currentStock and in :channel channel
*/
public function iShouldSeeVariantWithCodePriceAndCurrentStock(string $variantName, string $code, string $price, string $currentStock): void
{
Assert::true($this->variantsElement->hasProductVariantWithCodePriceAndCurrentStock($variantName, $code, $price, $currentStock));
public function iShouldSeeVariantWithCodePriceAndCurrentStock(
string $variantName,
string $code,
string $price,
string $currentStock,
string $channel,
): void {
Assert::true($this->variantsElement->hasProductVariantWithCodePriceAndCurrentStock(
$variantName,
$code,
$price,
$currentStock,
$channel,
));
}

/**
Expand All @@ -359,4 +381,49 @@ public function iShouldNotBeAbleToShowThisProductInShop(): void
{
Assert::true($this->productShowPage->isShowInShopButtonDisabled());
}

/**
* @Then this product price should be decreased by catalog promotion :catalogPromotion in :channelName channel
*/
public function thisProductPriceShouldBeDecreasedByCatalogPromotion(
CatalogPromotionInterface $catalogPromotion,
string $channelName,
): void {
Assert::inArray(
$catalogPromotion->getName(),
$this->pricingElement->getCatalogPromotionsNamesForChannel($channelName)
);

$url = $this->urlGenerator->generate('sylius_admin_catalog_promotion_show', ['id' => $catalogPromotion->getId()]);
Assert::inArray($url, $this->pricingElement->getCatalogPromotionLinksForChannel($channelName));
}

/**
* @Then :variantName variant price should be decreased by catalog promotion :catalogPromotion in :channelName channel
*/
public function variantPriceShouldBeDecreasedByCatalogPromotion(
string $variantName,
CatalogPromotionInterface $catalogPromotion,
string $channelName,
): void {
Assert::inArray(
$catalogPromotion->getName(),
$this->productShowPage->getAppliedCatalogPromotionsNames($variantName, $channelName)
);

$url = $this->urlGenerator->generate('sylius_admin_catalog_promotion_show', ['id' => $catalogPromotion->getId()]);
Assert::inArray($url, $this->productShowPage->getAppliedCatalogPromotionsLinks($variantName, $channelName));
}

/**
* @Then :variantName variant price should not be decreased by catalog promotion :catalogPromotion in :channelName channel
*/
public function variantPriceShouldNotBeDecreasedByCatalogPromotion(
string $variantName,
CatalogPromotionInterface $catalogPromotion,
string $channelName,
): void {
$appliedPromotions = $this->productShowPage->getAppliedCatalogPromotionsNames($variantName, $channelName);
Assert::false(in_array($catalogPromotion->getName(), $appliedPromotions));
}
}
34 changes: 30 additions & 4 deletions src/Sylius/Behat/Element/Product/ShowPage/PricingElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ final class PricingElement extends Element implements PricingElementInterface
{
public function getPriceForChannel(string $channelName): string
{
/** @var NodeElement|null $priceForChannel */
$channelPriceRow = $this->getDocument()->find('css', sprintf('#pricing tr:contains("%s")', $channelName));
$channelPriceRow = $this->getChannelPriceRow($channelName);

if (null === $channelPriceRow) {
return '';
Expand All @@ -34,11 +33,38 @@ public function getPriceForChannel(string $channelName): string

public function getOriginalPriceForChannel(string $channelName): string
{
/** @var NodeElement $priceForChannel */
$channelPriceRow = $this->getDocument()->find('css', sprintf('#pricing tr:contains("%s")', $channelName));
$channelPriceRow = $this->getChannelPriceRow($channelName);

$priceForChannel = $channelPriceRow->find('css', 'td:nth-child(3)');

return $priceForChannel->getText();
}

public function getCatalogPromotionsNamesForChannel(string $channelName): array
{
/** @var NodeElement[] $appliedPromotions */
$appliedPromotions = $this->getAppliedPromotionsForChannel($channelName);

return array_map(fn (NodeElement $element): string => $element->getText(), $appliedPromotions);
}

public function getCatalogPromotionLinksForChannel(string $channelName): array
{
$appliedPromotions = $this->getAppliedPromotionsForChannel($channelName);

return array_map(fn (NodeElement $element): string => $element->getAttribute('href'), $appliedPromotions);
}

private function getAppliedPromotionsForChannel(string $channelName): array
{
/** @var NodeElement $channelPriceRow */
$channelPriceRow = $this->getChannelPriceRow($channelName);

return $channelPriceRow->findAll('css', '.applied-promotion');
}

private function getChannelPriceRow(string $channelName): ?NodeElement
{
return $this->getDocument()->find('css', sprintf('#pricing tr:contains("%s")', $channelName));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ interface PricingElementInterface
public function getPriceForChannel(string $channelName): string;

public function getOriginalPriceForChannel(string $channelName): string;

public function getCatalogPromotionsNamesForChannel(string $channelName): array;

public function getCatalogPromotionLinksForChannel(string $channelName): array;
}
13 changes: 11 additions & 2 deletions src/Sylius/Behat/Element/Product/ShowPage/VariantsElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,22 @@ public function hasProductVariantWithCodePriceAndCurrentStock(
string $code,
string $price,
string $currentStock,
string $channel,
): bool {
/** @var NodeElement $variantRow */
$variantRows = $this->getDocument()->findAll('css', '#variants .variants-accordion__title');

/** @var NodeElement $variant */
foreach ($variantRows as $variant) {
if (
$this->hasProductWithGivenNameCodePriceAndCurrentStock($variant, $name, $code, $price, $currentStock)
$this->hasProductWithGivenNameCodePriceAndCurrentStock(
$variant,
$name,
$code,
$price,
$currentStock,
$channel,
)
) {
return true;
}
Expand All @@ -53,6 +61,7 @@ private function hasProductWithGivenNameCodePriceAndCurrentStock(
string $code,
string $price,
string $currentStock,
string $channel,
): bool {
$variantContent = $variant->getParent()->find(
'css',
Expand All @@ -65,7 +74,7 @@ private function hasProductWithGivenNameCodePriceAndCurrentStock(
if (
$variant->find('css', '.content .variant-name')->getText() === $name &&
$variant->find('css', '.content .variant-code')->getText() === $code &&
$variantContent->find('css', 'tr.pricing:contains("WEB-US") td:nth-child(2)')->getText() === $price &&
$variantContent->find('css', sprintf('tr.pricing:contains("%s") td:nth-child(2)', $channel))->getText() === $price &&
$variant->find('css', '.current-stock')->getText() === $currentStock
) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,11 @@ interface VariantsElementInterface
{
public function countVariantsOnPage(): int;

public function hasProductVariantWithCodePriceAndCurrentStock(string $name, string $code, string $price, string $currentStock): bool;
public function hasProductVariantWithCodePriceAndCurrentStock(
string $name,
string $code,
string $price,
string $currentStock,
string $channel,
): bool;
}
39 changes: 39 additions & 0 deletions src/Sylius/Behat/Page/Admin/Product/ShowPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Sylius\Behat\Page\Admin\Product;

use Behat\Mink\Element\NodeElement;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
use Sylius\Component\Core\Model\ProductVariantInterface;

Expand All @@ -28,6 +29,20 @@ public function isShowInShopButtonDisabled(): bool
return $this->getElement('show_product_single_button')->hasClass('disabled');
}

public function getAppliedCatalogPromotionsLinks(string $variantName, string $channelName): array
{
$appliedPromotions = $this->getAppliedCatalogPromotions($variantName, $channelName);

return array_map(fn (NodeElement $element): string => $element->getAttribute('href'), $appliedPromotions);
}

public function getAppliedCatalogPromotionsNames(string $variantName, string $channelName): array
{
$appliedPromotions = $this->getAppliedCatalogPromotions($variantName, $channelName);

return array_map(fn (NodeElement $element): string => $element->getText(), $appliedPromotions);
}

public function getName(): string
{
return $this->getElement('product_name')->getText();
Expand Down Expand Up @@ -75,4 +90,28 @@ protected function getDefinedElements(): array
'breadcrumb' => '.breadcrumb > div',
]);
}

private function getAppliedCatalogPromotions(string $variantName,string $channelName): array
{
$pricingElement = $this->getPricingRow($variantName, $channelName);

return $pricingElement->findAll('css', '.applied-promotion');
}

private function getPricingRow(string $variantName, string $channelName): NodeElement
{
/** @var NodeElement|null $pricingRow */
$pricingRow = $this->getDocument()->find(
'css',
sprintf('tr:contains("%s") + tr', $variantName)
);

$pricingRow = $pricingRow->find('css', sprintf('td:contains("%s")', $channelName));

if ($pricingRow === null) {
throw new \InvalidArgumentException(sprintf('Cannot find pricing row for variant "%s" in channel "%s"', $variantName, $channelName));
}

return $pricingRow;
}
}
4 changes: 4 additions & 0 deletions src/Sylius/Behat/Page/Admin/Product/ShowPageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

interface ShowPageInterface extends SymfonyPageInterface
{
public function getAppliedCatalogPromotionsLinks(string $variantName, string $channelName): array;

public function getAppliedCatalogPromotionsNames(string $variantName, string $channelName): array;

public function getName(): string;

public function getBreadcrumb(): string;
Expand Down
2 changes: 2 additions & 0 deletions src/Sylius/Behat/Resources/config/services/contexts/ui.xml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
<argument type="service" id="sylius.behat.element.product.show.taxonomy" />
<argument type="service" id="sylius.behat.element.product.show.options" />
<argument type="service" id="sylius.behat.element.product.show.variants" />
<argument type="service" id="router" />
</service>

<service id="sylius.behat.context.ui.admin.managing_products" class="Sylius\Behat\Context\Ui\Admin\ManagingProductsContext">
Expand All @@ -185,6 +186,7 @@
<argument type="service" id="sylius.behat.notification_checker" />
<argument type="service" id="sylius.behat.page.admin.product_variant.update" />
<argument type="service" id="sylius.behat.java_script_test_helper" />
<argument type="service" id="sylius.behat.page.admin.product.show_page" />
</service>

<service id="sylius.behat.context.ui.admin.managing_product_association_types" class="Sylius\Behat\Context\Ui\Admin\ManagingProductAssociationTypesContext">
Expand Down
Loading