Skip to content

Commit

Permalink
Make these tests more robust
Browse files Browse the repository at this point in the history
  • Loading branch information
loevgaard committed Oct 2, 2024
1 parent 542b360 commit 74268cc
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 67 deletions.
68 changes: 8 additions & 60 deletions tests/Functional/SearchSortingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,8 @@

namespace Setono\SyliusMeilisearchPlugin\Tests\Functional;

use Doctrine\ORM\EntityManagerInterface;
use Setono\SyliusMeilisearchPlugin\Engine\SearchEngine;
use Setono\SyliusMeilisearchPlugin\Engine\SearchRequest;
use Setono\SyliusMeilisearchPlugin\Message\Command\Index;
use Sylius\Component\Core\Model\ChannelPricingInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
use Symfony\Component\Messenger\MessageBusInterface;

final class SearchSortingTest extends FunctionalTestCase
{
Expand Down Expand Up @@ -62,63 +55,18 @@ public function testItSortsSearchResultsByNewestDate(): void

public function testItSortsResultsByBiggestDiscount(): void
{
$this->changeProductPrice('990M_regular_fit_jeans', 10);

/** @var SearchEngine $searchEngine */
$searchEngine = self::getContainer()->get(SearchEngine::class);
$result = $searchEngine->execute(new SearchRequest('jeans', sort: 'discount:desc'));

/** @var array $firstHit */
$firstHit = $result->getHit(0);
self::assertSame(0.1, $firstHit['price']);
self::assertGreaterThan(0, $firstHit['discount']);

$this->resetProductPrices();
}

private function changeProductPrice(string $productCode, int $price): void
{
$channelPricing = $this->getChannelPricingOfProduct($productCode);
$channelPricing->setOriginalPrice($channelPricing->getPrice());
$channelPricing->setPrice($price);

$this->saveAndReindexProduct();
}

private function resetProductPrices(): void
{
$channelPricing = $this->getChannelPricingOfProduct('990M_regular_fit_jeans');
$channelPricing->setPrice($channelPricing->getOriginalPrice());
$channelPricing->setOriginalPrice(null);

$this->saveAndReindexProduct();
}

private function getChannelPricingOfProduct(string $code): ChannelPricingInterface
{
/** @var ProductRepositoryInterface $productRepository */
$productRepository = self::getContainer()->get('sylius.repository.product');
/** @var ProductInterface $product */
$product = $productRepository->findOneBy(['code' => $code]);
/** @var ProductVariantInterface $variant */
$variant = $product->getVariants()->first();
/** @var ChannelPricingInterface $channelPricing */
$channelPricing = $variant->getChannelPricings()->first();

return $channelPricing;
}

private function saveAndReindexProduct(): void
{
/** @var EntityManagerInterface $productManager */
$productManager = self::getContainer()->get('sylius.manager.product');
$productManager->flush();

/** @var MessageBusInterface $commandBus */
$commandBus = self::getContainer()->get('sylius.command_bus');
$commandBus->dispatch(new Index('products'));
$previousDiscount = null;
/** @var array{discount: float} $hit */
foreach ($result->getHits() as $hit) {
if (null === $previousDiscount) {
$previousDiscount = $hit['discount'];
}

// we need to wait for reindexing, at least a little bit :/
sleep(1);
self::assertLessThanOrEqual($previousDiscount, $hit['discount']);
}
}
}
55 changes: 48 additions & 7 deletions tests/Functional/SearchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

namespace Setono\SyliusMeilisearchPlugin\Tests\Functional;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
use Setono\SyliusMeilisearchPlugin\Engine\SearchEngine;
use Setono\SyliusMeilisearchPlugin\Engine\SearchRequest;
use Sylius\Component\Core\Model\ChannelPricingInterface;

final class SearchTest extends FunctionalTestCase
{
Expand All @@ -20,21 +23,22 @@ public function testItProvidesSearchResults(): void

public function testItProvidesSearchResultByMultipleCriteria(): void
{
$priceBounds = $this->getPriceBounds();

/** @var SearchEngine $searchEngine */
$searchEngine = self::getContainer()->get(SearchEngine::class);
$result = $searchEngine->execute(
new SearchRequest('jeans', [
'brand' => ['Celsius small', 'You are breathtaking'],
'price' => ['min' => '30', 'max' => '45'],
'price' => ['min' => $priceBounds[0], 'max' => $priceBounds[1]],
]),
);

/** @var array $hit */
$hit = $result->getHit(0);

self::assertLessThan(45, (int) $hit['price']);
self::assertGreaterThan(30, (int) $hit['price']);
self::assertContains(((array) $hit['brand'])[0], ['Celsius small', 'You are breathtaking']);
foreach ($result->getHits() as $hit) {
self::assertGreaterThanOrEqual($priceBounds[0], (int) $hit['price']);
self::assertLessThanOrEqual($priceBounds[1], (int) $hit['price']);
self::assertContains(((array) $hit['brand'])[0], ['Celsius small', 'You are breathtaking']);
}
}

public function testItAlwaysDisplaysFullFacetDistribution(): void
Expand All @@ -50,4 +54,41 @@ public function testItAlwaysDisplaysFullFacetDistribution(): void
$this->assertSame(1, $result->getHitsCount());
$this->assertCount(4, (array) $result->getFacetDistribution()['brand']);
}

/**
* From all available prices in the database, this method will return a lower bound that is at least greater than the 10th cheapest price
* and an upper bound that will include 10 prices starting from the lower bound.
*
* @return array{int, int}
*/
private function getPriceBounds(): array
{
$container = self::getContainer();

/** @var ManagerRegistry $managerRegistry */
$managerRegistry = $container->get('doctrine');

/** @var class-string<ChannelPricingInterface> $channelPricingClass */
$channelPricingClass = $container->getParameter('sylius.model.channel_pricing.class');

/** @var EntityManagerInterface $manager */
$manager = $managerRegistry->getManagerForClass($channelPricingClass);

/** @var array<array-key, int> $prices */
$prices = array_map(
static fn (array $row) => (int) $row['price'],
$manager->createQueryBuilder()
->select('o.price')
->from($channelPricingClass, 'o')
->getQuery()
->getScalarResult(),
);

sort($prices);

$lowerBound = random_int(10, count($prices) - 20);
$upperBound = $lowerBound + 10;

return [(int) floor($prices[$lowerBound] / 100), (int) ceil($prices[$upperBound] / 100)];
}
}

0 comments on commit 74268cc

Please sign in to comment.