Skip to content

Commit

Permalink
#3 Select attribute throws error (#7)
Browse files Browse the repository at this point in the history
Resolve #3
  • Loading branch information
plewandowski authored Sep 30, 2021
1 parent bb70c95 commit 829137e
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 9 deletions.
31 changes: 31 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Sylius and PHP version:**
- Sylius 1.9
- PHP 7.4

**Additional context**
Add any other context about the problem here.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE]"
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ imports:
madcoders_sylius_sizechart_plugin:
resource: "@MadcodersSyliusSizechartPlugin/Resources/config/routing.yaml"
```
5. Run migrations:
```bash
php bin/console doctrine:migrations:migrate
```

## Development

* See [How to contribute](docs/CONTRIBUTING.md)
Expand All @@ -55,3 +60,5 @@ Developed by [MADCODERS](https://madcoders.co)
Architects of this package:
- [Piotr Lewandowski](https://github.com/plewandowski)
- [Leonid Moshko](https://github.com/LeoMoshko)

<a href="https://www.buymeacoffee.com/madcoders" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>
27 changes: 25 additions & 2 deletions src/Form/Provider/AttributeOptionsProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
namespace Madcoders\SyliusSizechartPlugin\Form\Provider;

use Sylius\Bundle\ProductBundle\Doctrine\ORM\ProductAttributeValueRepository;
use Sylius\Component\Attribute\AttributeType\IntegerAttributeType;
use Sylius\Component\Attribute\AttributeType\SelectAttributeType;
use Sylius\Component\Attribute\AttributeType\TextAttributeType;
use Sylius\Component\Product\Model\ProductAttributeInterface;
use Sylius\Component\Product\Model\ProductAttributeValueInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
Expand Down Expand Up @@ -59,8 +62,28 @@ public function provideOptionsByAttributeCode(string $code): array
$choices = [];
foreach($qb->getQuery()->getResult() as $value) {
/** @var ProductAttributeValueInterface $value */
$index = (string)$value->getValue();
$choices[$index] = $value->getValue();
switch($value->getType()) {
case SelectAttributeType::TYPE:
/** @var string[] $values */
$values = $value->getValue();
foreach($values as $index) {
if (!$value->getAttribute()) {
continue;
}
$config = $value->getAttribute()->getConfiguration();
/** @var array $attributeChoices */
$attributeChoices = $config['choices'] ?? [];
$label = (string)($attributeChoices[$index][$this->localeCode] ?? '');
$choices[$label] = $index;
}
break;
case IntegerAttributeType::TYPE:
case TextAttributeType::TYPE:
default:
$textValue = (string)$value->getValue();
$choices[$textValue] = $textValue;
break;
}
}

return $choices;
Expand Down
36 changes: 32 additions & 4 deletions src/Matcher/SizeChartValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
namespace Madcoders\SyliusSizechartPlugin\Matcher;

use Madcoders\SyliusSizechartPlugin\Entity\SizeChartInterface;
use Sylius\Component\Attribute\AttributeType\IntegerAttributeType;
use Sylius\Component\Attribute\AttributeType\SelectAttributeType;
use Sylius\Component\Attribute\AttributeType\TextAttributeType;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Product\Model\ProductAttributeInterface;

final class SizeChartValidator implements SizeChartValidatorInterface
{
Expand All @@ -39,14 +41,40 @@ public function isValidForTheProduct(SizeChartInterface $sizeChart, ProductInter
/** @var string[] $attributeCodes */
$attributeCodes = $criteria['attributes'] ?? [];

foreach($attributeCodes as $attributeCode) {
foreach ($attributeCodes as $attributeCode) {
/** @var string $value */
$value = $criteria['attribute' . $attributeCode ] ?? '';
$value = $criteria['attribute' . $attributeCode] ?? '';
$productAttributeValue = $product->getAttributeByCodeAndLocale($attributeCode, $this->localeCode);

if (!$productAttributeValue || $productAttributeValue->getValue() !== $value) {
if (!$productAttributeValue) {
return false;
}

if (!$productAttributeValue->getAttribute()) {
return false;
}

switch ($productAttributeValue->getAttribute()->getType()) {
case SelectAttributeType::TYPE:
/** @var array|null $selectAttributeValue */
$selectAttributeValue = $productAttributeValue->getValue();
if (!is_array($selectAttributeValue)) {
return false;
}

if (!in_array($value, $selectAttributeValue)) {
return false;
}

break;
case IntegerAttributeType::TYPE:
case TextAttributeType::TYPE:
default:
if ($productAttributeValue->getValue() !== $value) {
return false;
}
break;
}
}

return true;
Expand Down
60 changes: 57 additions & 3 deletions tests/Unit/Matcher/SizeChartValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
use Madcoders\SyliusSizechartPlugin\Entity\SizeChartInterface;
use Madcoders\SyliusSizechartPlugin\Matcher\SizeChartValidator;
use Prophecy\Argument;
use Sylius\Component\Attribute\AttributeType\SelectAttributeType;
use Sylius\Component\Attribute\AttributeType\TextAttributeType;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Product\Model\ProductAttributeInterface;
use Sylius\Component\Product\Model\ProductAttributeValueInterface;
Expand All @@ -35,7 +37,7 @@ function it_returns_true_when_there_are_no_attributes_in_criteria_defined()
$product = $this->prophesize(ProductInterface::class);
$sizeChart = $this->prophesize(SizeChartInterface::class);
$sizeChart->getCriteria()->willReturn([ 'attributes' => [] ]);
$validator = new SizeChartValidator();
$validator = new SizeChartValidator('en_US');

// when
$result = $validator->isValidForTheProduct($sizeChart->reveal(), $product->reveal());
Expand All @@ -50,10 +52,17 @@ function it_returns_true_when_there_are_no_attributes_in_criteria_defined()
function it_returns_true_when_all_criteria_are_matched()
{
// given
$attributeA = $this->prophesize(ProductAttributeInterface::class);
$attributeA->getType()->willReturn(TextAttributeType::TYPE);
$attributeB = $this->prophesize(ProductAttributeInterface::class);
$attributeB->getType()->willReturn(TextAttributeType::TYPE);

$valueX = $this->prophesize(ProductAttributeValueInterface::class);
$valueX->getValue()->willReturn('x');
$valueX->getAttribute()->willReturn($attributeA->reveal());
$valueY = $this->prophesize(ProductAttributeValueInterface::class);
$valueY->getValue()->willReturn('y');
$valueY->getAttribute()->willReturn($attributeB->reveal());

$product = $this->prophesize(ProductInterface::class);
$product->getAttributeByCodeAndLocale('A', Argument::any())->willReturn($valueX->reveal());
Expand All @@ -66,7 +75,7 @@ function it_returns_true_when_all_criteria_are_matched()
'attributeB' => 'y',
]);

$validator = new SizeChartValidator();
$validator = new SizeChartValidator('en_US');

// when
$result = $validator->isValidForTheProduct($sizeChart->reveal(), $product->reveal());
Expand All @@ -81,10 +90,17 @@ function it_returns_true_when_all_criteria_are_matched()
function it_returns_false_when_a_criteria_fails()
{
// given
$attributeA = $this->prophesize(ProductAttributeInterface::class);
$attributeA->getType()->willReturn(TextAttributeType::TYPE);
$attributeB = $this->prophesize(ProductAttributeInterface::class);
$attributeB->getType()->willReturn(TextAttributeType::TYPE);

$valueX = $this->prophesize(ProductAttributeValueInterface::class);
$valueX->getValue()->willReturn('x');
$valueX->getAttribute()->willReturn($attributeA->reveal());
$valueY = $this->prophesize(ProductAttributeValueInterface::class);
$valueY->getValue()->willReturn('VALUE_THAT_IS_NOT_SELECTED_IN_CRITERIA');
$valueY->getAttribute()->willReturn($attributeB->reveal());

$product = $this->prophesize(ProductInterface::class);
$product->getAttributeByCodeAndLocale('A', Argument::any())->willReturn($valueX->reveal());
Expand All @@ -97,12 +113,50 @@ function it_returns_false_when_a_criteria_fails()
'attributeB' => 'y',
]);

$validator = new SizeChartValidator();
$validator = new SizeChartValidator('en_US');

// when
$result = $validator->isValidForTheProduct($sizeChart->reveal(), $product->reveal());

// then
$this->assertFalse($result);
}

/**
* @test
*/
function it_supports_select_attributes()
{
// given
$attributeA = $this->prophesize(ProductAttributeInterface::class);
$attributeA->getType()->willReturn(SelectAttributeType::TYPE);
$attributeB = $this->prophesize(ProductAttributeInterface::class);
$attributeB->getType()->willReturn(SelectAttributeType::TYPE);

$valueX = $this->prophesize(ProductAttributeValueInterface::class);
$valueX->getValue()->willReturn(['x']);
$valueX->getAttribute()->willReturn($attributeA->reveal());
$valueY = $this->prophesize(ProductAttributeValueInterface::class);
$valueY->getValue()->willReturn(['y']);
$valueY->getAttribute()->willReturn($attributeB->reveal());

$product = $this->prophesize(ProductInterface::class);
$product->getAttributeByCodeAndLocale('A', Argument::any())->willReturn($valueX->reveal());
$product->getAttributeByCodeAndLocale('B', Argument::any())->willReturn($valueY->reveal());

$sizeChart = $this->prophesize(SizeChartInterface::class);
$sizeChart->getCriteria()->willReturn([
'attributes' => [ 'A', 'B' ],
'attributeA' => 'x',
'attributeB' => 'y',
]);

$validator = new SizeChartValidator('en_US');

// when
$result = $validator->isValidForTheProduct($sizeChart->reveal(), $product->reveal());

// then
$this->assertTrue($result);
}
}

0 comments on commit 829137e

Please sign in to comment.