mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-05 20:57:12 +00:00
Use subquery in findByTaxon and add tests
This commit is contained in:
parent
77dc7a9547
commit
184d3d5d8d
3 changed files with 176 additions and 4 deletions
|
|
@ -247,11 +247,16 @@ class ProductRepository extends BaseProductRepository implements ProductReposito
|
||||||
|
|
||||||
public function findByTaxon(TaxonInterface $taxon): array
|
public function findByTaxon(TaxonInterface $taxon): array
|
||||||
{
|
{
|
||||||
return $this
|
$subQuery = $this->createQueryBuilder('sub')
|
||||||
->createQueryBuilder('product')
|
->select('sub.id')
|
||||||
->distinct()
|
->innerJoin('sub.productTaxons', 'productTaxon')
|
||||||
->innerJoin('product.productTaxons', 'productTaxon')
|
|
||||||
->andWhere('productTaxon.taxon = :taxon')
|
->andWhere('productTaxon.taxon = :taxon')
|
||||||
|
;
|
||||||
|
|
||||||
|
$queryBuilder = $this->createQueryBuilder('product');
|
||||||
|
|
||||||
|
return $queryBuilder
|
||||||
|
->andWhere($queryBuilder->expr()->in('product.id', $subQuery->getDQL()))
|
||||||
->setParameter('taxon', $taxon)
|
->setParameter('taxon', $taxon)
|
||||||
->getQuery()
|
->getQuery()
|
||||||
->getResult()
|
->getResult()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
Sylius\Component\Core\Model\Taxon:
|
||||||
|
find_by_taxon_mugs:
|
||||||
|
code: "find_by_taxon_mugs"
|
||||||
|
find_by_taxon_books:
|
||||||
|
code: "find_by_taxon_books"
|
||||||
|
|
||||||
|
Sylius\Component\Core\Model\Product:
|
||||||
|
find_by_taxon_product_mugs_only:
|
||||||
|
currentLocale: "en_US"
|
||||||
|
fallbackLocale: "en_US"
|
||||||
|
code: "FIND_BY_TAXON_MUGS_ONLY"
|
||||||
|
find_by_taxon_product_mugs_and_books:
|
||||||
|
currentLocale: "en_US"
|
||||||
|
fallbackLocale: "en_US"
|
||||||
|
code: "FIND_BY_TAXON_MUGS_AND_BOOKS"
|
||||||
|
find_by_taxon_product_books_only:
|
||||||
|
currentLocale: "en_US"
|
||||||
|
fallbackLocale: "en_US"
|
||||||
|
code: "FIND_BY_TAXON_BOOKS_ONLY"
|
||||||
|
|
||||||
|
Sylius\Component\Core\Model\ProductTaxon:
|
||||||
|
find_by_taxon_pt_mugs_only:
|
||||||
|
product: "@find_by_taxon_product_mugs_only"
|
||||||
|
taxon: "@find_by_taxon_mugs"
|
||||||
|
position: 0
|
||||||
|
find_by_taxon_pt_mugs_and_books_mugs:
|
||||||
|
product: "@find_by_taxon_product_mugs_and_books"
|
||||||
|
taxon: "@find_by_taxon_mugs"
|
||||||
|
position: 1
|
||||||
|
find_by_taxon_pt_mugs_and_books_books:
|
||||||
|
product: "@find_by_taxon_product_mugs_and_books"
|
||||||
|
taxon: "@find_by_taxon_books"
|
||||||
|
position: 0
|
||||||
|
find_by_taxon_pt_books_only:
|
||||||
|
product: "@find_by_taxon_product_books_only"
|
||||||
|
taxon: "@find_by_taxon_books"
|
||||||
|
position: 1
|
||||||
130
tests/Functional/Repository/ProductRepositoryTest.php
Normal file
130
tests/Functional/Repository/ProductRepositoryTest.php
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* 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\Tests\Functional\Repository;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Fidry\AliceDataFixtures\LoaderInterface;
|
||||||
|
use Fidry\AliceDataFixtures\Persistence\PurgeMode;
|
||||||
|
use PHPUnit\Framework\Attributes\Test;
|
||||||
|
use Sylius\Component\Core\Model\ProductInterface;
|
||||||
|
use Sylius\Component\Core\Model\TaxonInterface;
|
||||||
|
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
|
||||||
|
use Sylius\Component\Taxonomy\Repository\TaxonRepositoryInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
|
||||||
|
final class ProductRepositoryTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
/** @var ProductRepositoryInterface<ProductInterface> */
|
||||||
|
private ProductRepositoryInterface $productRepository;
|
||||||
|
|
||||||
|
/** @var TaxonRepositoryInterface<TaxonInterface> */
|
||||||
|
private TaxonRepositoryInterface $taxonRepository;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->loadFixtures();
|
||||||
|
|
||||||
|
/** @var EntityManagerInterface $entityManager */
|
||||||
|
$entityManager = self::getContainer()->get('doctrine.orm.entity_manager');
|
||||||
|
$entityManager->clear();
|
||||||
|
|
||||||
|
/** @var ProductRepositoryInterface<ProductInterface> $productRepository */
|
||||||
|
$productRepository = self::getContainer()->get('sylius.repository.product');
|
||||||
|
$this->productRepository = $productRepository;
|
||||||
|
|
||||||
|
/** @var TaxonRepositoryInterface<TaxonInterface> $taxonRepository */
|
||||||
|
$taxonRepository = self::getContainer()->get('sylius.repository.taxon');
|
||||||
|
$this->taxonRepository = $taxonRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Test]
|
||||||
|
public function it_finds_products_belonging_to_a_taxon(): void
|
||||||
|
{
|
||||||
|
/** @var TaxonInterface $mugsTaxon */
|
||||||
|
$mugsTaxon = $this->taxonRepository->findOneBy(['code' => 'find_by_taxon_mugs']);
|
||||||
|
|
||||||
|
$products = $this->productRepository->findByTaxon($mugsTaxon);
|
||||||
|
|
||||||
|
self::assertCount(2, $products);
|
||||||
|
self::assertEqualsCanonicalizing(
|
||||||
|
['FIND_BY_TAXON_MUGS_ONLY', 'FIND_BY_TAXON_MUGS_AND_BOOKS'],
|
||||||
|
$this->getProductCodes($products),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Test]
|
||||||
|
public function it_does_not_return_products_from_other_taxons(): void
|
||||||
|
{
|
||||||
|
/** @var TaxonInterface $booksTaxon */
|
||||||
|
$booksTaxon = $this->taxonRepository->findOneBy(['code' => 'find_by_taxon_books']);
|
||||||
|
|
||||||
|
$products = $this->productRepository->findByTaxon($booksTaxon);
|
||||||
|
|
||||||
|
self::assertCount(2, $products);
|
||||||
|
self::assertEqualsCanonicalizing(
|
||||||
|
['FIND_BY_TAXON_MUGS_AND_BOOKS', 'FIND_BY_TAXON_BOOKS_ONLY'],
|
||||||
|
$this->getProductCodes($products),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Test]
|
||||||
|
public function it_returns_the_full_product_taxons_collection_not_only_filtered_ones(): void
|
||||||
|
{
|
||||||
|
/** @var TaxonInterface $mugsTaxon */
|
||||||
|
$mugsTaxon = $this->taxonRepository->findOneBy(['code' => 'find_by_taxon_mugs']);
|
||||||
|
|
||||||
|
$products = $this->productRepository->findByTaxon($mugsTaxon);
|
||||||
|
|
||||||
|
$productInBothTaxons = null;
|
||||||
|
foreach ($products as $product) {
|
||||||
|
if ($product->getCode() === 'FIND_BY_TAXON_MUGS_AND_BOOKS') {
|
||||||
|
$productInBothTaxons = $product;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self::assertNotNull($productInBothTaxons);
|
||||||
|
self::assertCount(
|
||||||
|
2,
|
||||||
|
$productInBothTaxons->getProductTaxons(),
|
||||||
|
'Product assigned to two taxons must expose both in its productTaxons collection, not just the filtered one.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ProductInterface[] $products
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
private function getProductCodes(array $products): array
|
||||||
|
{
|
||||||
|
return array_map(
|
||||||
|
static fn (ProductInterface $product): string => (string) $product->getCode(),
|
||||||
|
$products,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loadFixtures(): void
|
||||||
|
{
|
||||||
|
/** @var LoaderInterface $fixtureLoader */
|
||||||
|
$fixtureLoader = self::getContainer()->get('fidry_alice_data_fixtures.loader.doctrine');
|
||||||
|
|
||||||
|
$fixtureLoader->load([
|
||||||
|
__DIR__ . '/../../DataFixtures/ORM/resources/product_repository_find_by_taxon.yml',
|
||||||
|
], [], [], PurgeMode::createDeleteMode());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue