diff --git a/api/migrations/Version20220407091642.php b/api/migrations/Version20220407091642.php
index 29e1f1c0b..3bfc31a2a 100644
--- a/api/migrations/Version20220407091642.php
+++ b/api/migrations/Version20220407091642.php
@@ -27,7 +27,6 @@ public function up(Schema $schema): void
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
- $this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE source_field DROP is_system');
$this->addSql('ALTER TABLE source_field DROP default_label');
}
diff --git a/api/migrations/Version20220408122945.php b/api/migrations/Version20220408122945.php
new file mode 100644
index 000000000..3223ddc0b
--- /dev/null
+++ b/api/migrations/Version20220408122945.php
@@ -0,0 +1,31 @@
+addSql('ALTER TABLE localized_catalog ADD is_default BOOLEAN DEFAULT \'false\' NOT NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ // this down() migration is auto-generated, please modify it to your needs
+ $this->addSql('ALTER TABLE localized_catalog DROP is_default');
+ }
+}
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/DataPersister/LocalizedCatalogDataPersister.php b/api/src/Elasticsuite/Standard/src/Catalog/DataPersister/LocalizedCatalogDataPersister.php
new file mode 100644
index 000000000..82b12c025
--- /dev/null
+++ b/api/src/Elasticsuite/Standard/src/Catalog/DataPersister/LocalizedCatalogDataPersister.php
@@ -0,0 +1,68 @@
+
+ * @copyright 2022 Smile
+ * @license Licensed to Smile-SA. All rights reserved. No warranty, explicit or implicit, provided.
+ * Unauthorized copying of this file, via any medium, is strictly prohibited.
+ */
+
+declare(strict_types=1);
+
+namespace Elasticsuite\Catalog\DataPersister;
+
+use ApiPlatform\Core\DataPersister\DataPersisterInterface;
+use Doctrine\ORM\EntityManagerInterface;
+use Elasticsuite\Catalog\Model\LocalizedCatalog;
+use Elasticsuite\Catalog\Repository\LocalizedCatalogRepository;
+
+class LocalizedCatalogDataPersister implements DataPersisterInterface
+{
+ public function __construct(
+ private EntityManagerInterface $entityManager,
+ private LocalizedCatalogRepository $localizedCatalogRepository
+ ) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($data): bool
+ {
+ return $data instanceof LocalizedCatalog;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param LocalizedCatalog $data
+ *
+ * @return LocalizedCatalog
+ */
+ public function persist($data)
+ {
+ if ($data->isDefault()) {
+ $this->localizedCatalogRepository->unsetDefaultLocalizedCatalog();
+ }
+ $this->entityManager->persist($data);
+ $this->entityManager->flush();
+
+ return $data;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param LocalizedCatalog $data
+ */
+ public function remove($data)
+ {
+ $this->entityManager->remove($data);
+ $this->entityManager->flush();
+ }
+}
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Exception/NoCatalogException.php b/api/src/Elasticsuite/Standard/src/Catalog/Exception/NoCatalogException.php
new file mode 100644
index 000000000..924333eb9
--- /dev/null
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Exception/NoCatalogException.php
@@ -0,0 +1,30 @@
+
+ * @copyright 2022 Smile
+ * @license Licensed to Smile-SA. All rights reserved. No warranty, explicit or implicit, provided.
+ * Unauthorized copying of this file, via any medium, is strictly prohibited.
+ */
+
+declare(strict_types=1);
+
+namespace Elasticsuite\Catalog\Exception;
+
+use ApiPlatform\Core\Exception\ExceptionInterface;
+
+class NoCatalogException extends \LogicException implements ExceptionInterface
+{
+ public function __construct(
+ string $message = 'No localized catalog found',
+ int $code = 0,
+ ?\Throwable $previous = null
+ ) {
+ parent::__construct($message, $code, $previous);
+ }
+}
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Model/LocalizedCatalog.php b/api/src/Elasticsuite/Standard/src/Catalog/Model/LocalizedCatalog.php
index 375e5bb44..becd08cae 100644
--- a/api/src/Elasticsuite/Standard/src/Catalog/Model/LocalizedCatalog.php
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Model/LocalizedCatalog.php
@@ -48,6 +48,8 @@ class LocalizedCatalog
private string $locale;
+ private bool $isDefault = false;
+
private Catalog $catalog;
public function getId(): ?int
@@ -91,6 +93,18 @@ public function setLocale(string $locale): self
return $this;
}
+ public function isDefault(): bool
+ {
+ return $this->isDefault;
+ }
+
+ public function setIsDefault(bool $isDefault): self
+ {
+ $this->isDefault = $isDefault;
+
+ return $this;
+ }
+
public function getCatalog(): ?Catalog
{
return $this->catalog;
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Repository/LocalizedCatalogRepository.php b/api/src/Elasticsuite/Standard/src/Catalog/Repository/LocalizedCatalogRepository.php
index f7f3f2dc1..8f03de637 100644
--- a/api/src/Elasticsuite/Standard/src/Catalog/Repository/LocalizedCatalogRepository.php
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Repository/LocalizedCatalogRepository.php
@@ -32,4 +32,14 @@ public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, LocalizedCatalog::class);
}
+
+ public function unsetDefaultLocalizedCatalog(): void
+ {
+ $this->createQueryBuilder('')
+ ->update(LocalizedCatalog::class, 'lc')
+ ->set('lc.isDefault', ':isDefault')
+ ->setParameter('isDefault', false)
+ ->getQuery()
+ ->execute();
+ }
}
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/doctrine/LocalizedCatalog.orm.xml b/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/doctrine/LocalizedCatalog.orm.xml
index 967cc76d4..6cd378598 100644
--- a/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/doctrine/LocalizedCatalog.orm.xml
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/doctrine/LocalizedCatalog.orm.xml
@@ -11,6 +11,11 @@
+
+
+
+
+
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/services.yaml b/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/services.yaml
index 82f0a36f1..1686e987c 100644
--- a/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/services.yaml
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/services.yaml
@@ -10,3 +10,15 @@ services:
- '@Doctrine\Persistence\ManagerRegistry'
tags:
- { name: doctrine.repository_service }
+
+ Elasticsuite\Catalog\DataPersister\LocalizedCatalogDataPersister:
+ arguments:
+ - '@doctrine.orm.entity_manager'
+ - '@Elasticsuite\Catalog\Repository\LocalizedCatalogRepository'
+ tags:
+ - { name: api_platform.data_persister }
+
+ Elasticsuite\Catalog\Service\DefaultCatalogProvider:
+ arguments:
+ - '@Elasticsuite\Catalog\Repository\LocalizedCatalogRepository'
+
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/test/services.yaml b/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/test/services.yaml
new file mode 100644
index 000000000..719db40f9
--- /dev/null
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Resources/config/test/services.yaml
@@ -0,0 +1,4 @@
+services:
+ Elasticsuite\Catalog\Service\DefaultCatalogProviderTest:
+ alias: Elasticsuite\Catalog\Service\DefaultCatalogProvider
+ public: true
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Service/DefaultCatalogProvider.php b/api/src/Elasticsuite/Standard/src/Catalog/Service/DefaultCatalogProvider.php
new file mode 100644
index 000000000..77fa3fca9
--- /dev/null
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Service/DefaultCatalogProvider.php
@@ -0,0 +1,42 @@
+
+ * @copyright 2022 Smile
+ * @license Licensed to Smile-SA. All rights reserved. No warranty, explicit or implicit, provided.
+ * Unauthorized copying of this file, via any medium, is strictly prohibited.
+ */
+
+declare(strict_types=1);
+
+namespace Elasticsuite\Catalog\Service;
+
+use Elasticsuite\Catalog\Exception\NoCatalogException;
+use Elasticsuite\Catalog\Model\LocalizedCatalog;
+use Elasticsuite\Catalog\Repository\LocalizedCatalogRepository;
+
+class DefaultCatalogProvider
+{
+ /**
+ * @param LocalizedCatalogRepository $localizedCatalogRepository
+ */
+ public function __construct(
+ private LocalizedCatalogRepository $localizedCatalogRepository
+ ) {
+ }
+
+ public function getDefaultLocalizedCatalog(): LocalizedCatalog
+ {
+ $catalog = $this->localizedCatalogRepository->findOneBy([], ['isDefault' => 'DESC', 'id' => 'ASC']);
+ if (null === $catalog) {
+ throw new NoCatalogException();
+ }
+
+ return $catalog;
+ }
+}
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Tests/Api/Rest/CatalogsTest.php b/api/src/Elasticsuite/Standard/src/Catalog/Tests/Api/Rest/CatalogsTest.php
index 03bb37a10..197fe47ab 100644
--- a/api/src/Elasticsuite/Standard/src/Catalog/Tests/Api/Rest/CatalogsTest.php
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Tests/Api/Rest/CatalogsTest.php
@@ -16,63 +16,22 @@
namespace Elasticsuite\Catalog\Tests\Api\Rest;
-use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
use Elasticsuite\Catalog\Model\Catalog;
-use Elasticsuite\User\DataFixtures\LoginTrait;
-use Liip\TestFixturesBundle\Services\DatabaseToolCollection;
-use Liip\TestFixturesBundle\Services\DatabaseTools\AbstractDatabaseTool;
+use Elasticsuite\Standard\src\Test\AbstractEntityTest;
-class CatalogsTest extends ApiTestCase
+class CatalogsTest extends AbstractEntityTest
{
- use LoginTrait;
-
- private AbstractDatabaseTool $databaseTool;
-
- protected function setUp(): void
+ protected static function getFixtureFiles(): array
{
- $this->databaseTool = static::getContainer()->get(DatabaseToolCollection::class)->get();
+ return [__DIR__ . '/../../fixtures/catalogs.yaml'];
}
- /**
- * @dataProvider validCatalogProvider
- *
- * @param mixed $validCatalog
- */
- public function testCreateValidCatalog($validCatalog): void
+ protected function getEntityClass(): string
{
- $client = static::createClient();
-
- $loginJson = $this->login(
- $client,
- static::getContainer()->get('doctrine')->getManager(), // @phpstan-ignore-line
- static::getContainer()->get('security.user_password_hasher')
- );
-
- $response = $client->request('POST', '/catalogs', ['auth_bearer' => $loginJson['token'], 'json' => $validCatalog]);
-
- $this->assertResponseStatusCodeSame(201);
- $this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
- $this->assertJsonContains(
- [
- '@context' => '/contexts/Catalog',
- '@type' => 'Catalog',
- 'code' => $validCatalog['code'],
- ]
- );
-
- if (isset($validCatalog['name'])) {
- $this->assertJsonContains(
- [
- 'name' => $validCatalog['name'] ?? '',
- ]
- );
- }
-
- $this->assertMatchesRegularExpression('~^/catalogs/\d+$~', $response->toArray()['@id']);
- $this->assertMatchesResourceItemJsonSchema(Catalog::class);
+ return Catalog::class;
}
- public function validCatalogProvider(): array
+ public function createValidDataProvider(): array
{
return [
[['code' => 'valid_code', 'name' => 'B2C Catalog']],
@@ -81,55 +40,30 @@ public function validCatalogProvider(): array
];
}
- /**
- * @dataProvider invalidCatalogProvider
- *
- * @param mixed $invalidCatalog
- */
- public function testCreateInvalidCatalog($invalidCatalog): void
+ public function createInvalidDataProvider(): array
{
- $client = static::createClient();
-
- $loginJson = $this->login(
- $client,
- static::getContainer()->get('doctrine')->getManager(),// @phpstan-ignore-line
- static::getContainer()->get('security.user_password_hasher')
- );
-
- $client->request('POST', '/catalogs', ['auth_bearer' => $loginJson['token'], 'json' => $invalidCatalog]);
-
- $this->assertResponseStatusCodeSame(422);
- $this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
- $this->assertJsonContains(
- [
- '@context' => '/contexts/ConstraintViolationList',
- '@type' => 'ConstraintViolationList',
- 'hydra:title' => 'An error occurred',
- 'hydra:description' => 'code: This value should not be blank.',
- ]
- );
+ return [
+ [['code' => '', 'name' => 'Empty Code'], 'code: This value should not be blank.'],
+ [['code' => ''], 'code: This value should not be blank.'],
+ [['name' => 'Missing Code'], 'code: This value should not be blank.'],
+ ];
}
- public function invalidCatalogProvider(): array
+ protected function getJsonCreationValidation(array $validData): array
{
- return [
- [['code' => '', 'name' => 'Empty Code']],
- [['code' => '']],
- [['name' => 'Missing Code']],
+ $data = [
+ 'code' => $validData['code'],
];
+
+ if (isset($validData['name'])) {
+ $data['name'] = $validData['name'];
+ }
+
+ return $data;
}
- /**
- * @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
- * @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface
- * @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
- * @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
- * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
- */
public function testGetCollection(): void
{
- $this->databaseTool->loadAliceFixture([__DIR__ . '/../../fixtures/catalogs.yaml']);
-
$client = static::createClient();
$loginJson = $this->login(
@@ -153,4 +87,37 @@ public function testGetCollection(): void
]
);
}
+
+ public function getDataProvider(): array
+ {
+ return [
+ [1, ['id' => 1, 'code' => 'b2c_test', 'name' => 'B2C Test Catalog'], 200],
+ [5, ['id' => 5, 'code' => 'missing_name'], 200],
+ [10, [], 404],
+ ];
+ }
+
+ protected function getJsonGetValidation(array $expectedData): array
+ {
+ $data = ['code' => $expectedData['code']];
+ if (isset($expectedData['name'])) {
+ $data['name'] = $expectedData['name'];
+ }
+
+ return $data;
+ }
+
+ public function deleteDataProvider(): array
+ {
+ return [
+ [1, 200],
+ [5, 200],
+ [10, 404],
+ ];
+ }
+
+ protected function getJsonGetCollectionValidation(): array
+ {
+ return ['hydra:totalItems' => 20];
+ }
}
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Tests/Api/Rest/LocalizedCatalogsTest.php b/api/src/Elasticsuite/Standard/src/Catalog/Tests/Api/Rest/LocalizedCatalogsTest.php
index d08fad0a0..6f4bf5a30 100644
--- a/api/src/Elasticsuite/Standard/src/Catalog/Tests/Api/Rest/LocalizedCatalogsTest.php
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Tests/Api/Rest/LocalizedCatalogsTest.php
@@ -16,15 +16,100 @@
namespace Elasticsuite\Catalog\Tests\Api\Rest;
-use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
use Elasticsuite\Catalog\Model\LocalizedCatalog;
-use Elasticsuite\User\DataFixtures\LoginTrait;
+use Elasticsuite\Standard\src\Test\AbstractEntityTest;
use Liip\TestFixturesBundle\Services\DatabaseToolCollection;
use Liip\TestFixturesBundle\Services\DatabaseTools\AbstractDatabaseTool;
-class LocalizedCatalogsTest extends ApiTestCase
+class LocalizedCatalogsTest extends AbstractEntityTest
{
- use LoginTrait;
+ protected static function getFixtureFiles(): array
+ {
+ return [
+ __DIR__ . '/../../fixtures/catalogs.yaml',
+ __DIR__ . '/../../fixtures/localized_catalogs.yaml',
+ ];
+ }
+
+ protected function getEntityClass(): string
+ {
+ return LocalizedCatalog::class;
+ }
+
+ public function createValidDataProvider(): array
+ {
+ return [
+ [['catalog' => '/catalogs/1', 'code' => 'valid_code', 'name' => 'B2C French catalog', 'locale' => 'fr_FR']],
+ [['catalog' => '/catalogs/1', 'code' => 'empty_name', 'name' => '', 'locale' => 'en_US']],
+ [['catalog' => '/catalogs/1', 'code' => 'missing_name', 'locale' => 'fr_FR']],
+ ];
+ }
+
+ public function createInvalidDataProvider(): array
+ {
+ return [
+ [['code' => 'no_catalog', 'name' => 'B2C French catalog', 'locale' => 'fr_FR'], 'catalog: This value should not be blank.'],
+ [['catalog' => '/catalogs/2', 'code' => 'valid_code', 'locale' => 'fr_FR', 'name' => 'Empty Code'], 'locale: This code and locale couple already exists.'],
+ [['catalog' => '/catalogs/1', 'code' => '', 'locale' => 'en_US', 'name' => 'Empty Code'], 'code: This value should not be blank.'],
+ [['catalog' => '/catalogs/1', 'code' => '', 'locale' => 'en_US'], 'code: This value should not be blank.'],
+ [['catalog' => '/catalogs/1', 'locale' => 'en_US', 'name' => 'Missing Code'], 'code: This value should not be blank.'],
+ [['catalog' => '/catalogs/1', 'code' => 'missing_locale'], 'locale: This value should not be blank.'],
+ [['catalog' => '/catalogs/1', 'code' => 'cat_1_invalid', 'locale' => 'fr-fr'], 'locale: This value is not valid.'],
+ [['catalog' => '/catalogs/1', 'code' => 'cat_1_invalid', 'locale' => 'strin'], 'locale: This value is not valid.'],
+ [['catalog' => '/catalogs/1', 'code' => 'cat_1_invalid', 'locale' => 'too_long_locale'], "locale: This value is not valid.\nlocale: This value should have exactly 5 characters."],
+ [['catalog' => '/catalogs/1', 'code' => 'cat_1_invalid', 'locale' => 'a'], "locale: This value is not valid.\nlocale: This value should have exactly 5 characters."],
+ [['catalog' => '/catalogs/1', 'code' => 'cat_1_invalid', 'locale' => 'abc'], "locale: This value is not valid.\nlocale: This value should have exactly 5 characters."],
+ ];
+ }
+
+ protected function getJsonCreationValidation(array $validData): array
+ {
+ $data = [
+ 'code' => $validData['code'],
+ 'locale' => $validData['locale'],
+ ];
+ if (isset($validData['name'])) {
+ $data['name'] = $validData['name'];
+ }
+
+ return $data;
+ }
+
+ public function getDataProvider(): array
+ {
+ return [
+ [1, ['id' => 1, 'code' => 'b2c_fr', 'locale' => 'fr_FR', 'name' => 'B2C French Store View'], 200],
+ [5, ['id' => 5, 'code' => 'empty_name', 'locale' => 'en_US'], 200],
+ [10, [], 404],
+ ];
+ }
+
+ protected function getJsonGetValidation(array $expectedData): array
+ {
+ $data = [
+ 'code' => $expectedData['code'],
+ 'locale' => $expectedData['locale'],
+ ];
+ if (isset($expectedData['name'])) {
+ $data['name'] = $expectedData['name'];
+ }
+
+ return $data;
+ }
+
+ public function deleteDataProvider(): array
+ {
+ return [
+ [1, 200],
+ [5, 200],
+ [10, 404],
+ ];
+ }
+
+ protected function getJsonGetCollectionValidation(): array
+ {
+ return ['hydra:totalItems' => 3];
+ }
private AbstractDatabaseTool $databaseTool;
@@ -280,7 +365,7 @@ public function invalidCatalogLocaleLengthProvider(): array
*/
public function testGetCollection(): void
{
- $this->databaseTool->loadAliceFixture([__DIR__ . '/../../fixtures/localized_catalogs.yaml']);
+ $this->databaseTool->loadAliceFixture([__DIR__ . '/../../fixtures/catalogs.yaml', __DIR__ . '/../../fixtures/localized_catalogs.yaml']);
$client = static::createClient();
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Tests/Unit/DefaultCatalogProviderTest.php b/api/src/Elasticsuite/Standard/src/Catalog/Tests/Unit/DefaultCatalogProviderTest.php
new file mode 100644
index 000000000..e5568a34d
--- /dev/null
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Tests/Unit/DefaultCatalogProviderTest.php
@@ -0,0 +1,50 @@
+
+ * @copyright 2022 Smile
+ * @license Licensed to Smile-SA. All rights reserved. No warranty, explicit or implicit, provided.
+ * Unauthorized copying of this file, via any medium, is strictly prohibited.
+ */
+
+declare(strict_types=1);
+
+namespace Elasticsuite\Catalog\Tests\Unit;
+
+use Elasticsuite\Catalog\Exception\NoCatalogException;
+use Elasticsuite\Catalog\Service\DefaultCatalogProvider;
+use Elasticsuite\Standard\src\Test\AbstractTest;
+
+class DefaultCatalogProviderTest extends AbstractTest
+{
+ protected DefaultCatalogProvider $defaultCatalogProvider;
+
+ protected function setUp(): void
+ {
+ parent::setUp();
+ $this->defaultCatalogProvider = static::getContainer()->get('Elasticsuite\Catalog\Service\DefaultCatalogProviderTest'); // @phpstan-ignore-line
+ $this->loadFixture([__DIR__ . '/../fixtures/catalogs.yaml']);
+ }
+
+ public function testNoLocalizedCatalog(): void
+ {
+ $this->expectException(NoCatalogException::class);
+ $this->defaultCatalogProvider->getDefaultLocalizedCatalog();
+ }
+
+ public function testGetLocalizedCatalog(): void
+ {
+ $this->loadFixture([__DIR__ . '/../fixtures/catalogs.yaml', __DIR__ . '/../fixtures/localized_catalogs.yaml']);
+ $catalog = $this->defaultCatalogProvider->getDefaultLocalizedCatalog();
+ $this->assertEquals('B2C French Store View', $catalog->getName());
+
+ $this->loadFixture([__DIR__ . '/../fixtures/catalogs.yaml', __DIR__ . '/../fixtures/localized_catalogs_with_default.yaml']);
+ $catalog = $this->defaultCatalogProvider->getDefaultLocalizedCatalog();
+ $this->assertEquals('B2B English Store View', $catalog->getName());
+ }
+}
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Tests/fixtures/localized_catalogs.yaml b/api/src/Elasticsuite/Standard/src/Catalog/Tests/fixtures/localized_catalogs.yaml
index d0e6437f8..37c7fc3cb 100644
--- a/api/src/Elasticsuite/Standard/src/Catalog/Tests/fixtures/localized_catalogs.yaml
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Tests/fixtures/localized_catalogs.yaml
@@ -1,10 +1,3 @@
-Elasticsuite\Catalog\Model\Catalog:
- catalog1:
- code: b2c
- name: B2C Catalog
- catalog2:
- code: b2b
- name: B2B Catalog
Elasticsuite\Catalog\Model\LocalizedCatalog:
localized_catalog1:
@@ -12,13 +5,16 @@ Elasticsuite\Catalog\Model\LocalizedCatalog:
code: b2c_fr
locale: fr_FR
name: B2C French Store View
+ isDefault: false
localized_catalog2:
catalog: '@catalog1'
code: b2c_en
locale: en_US
name: B2C English Store View
+ isDefault: false
localized_catalog3:
catalog: '@catalog2'
code: b2b_en
locale: en_US
name: B2B English Store View
+ isDefault: false
diff --git a/api/src/Elasticsuite/Standard/src/Catalog/Tests/fixtures/localized_catalogs_with_default.yaml b/api/src/Elasticsuite/Standard/src/Catalog/Tests/fixtures/localized_catalogs_with_default.yaml
new file mode 100644
index 000000000..4d3496464
--- /dev/null
+++ b/api/src/Elasticsuite/Standard/src/Catalog/Tests/fixtures/localized_catalogs_with_default.yaml
@@ -0,0 +1,20 @@
+
+Elasticsuite\Catalog\Model\LocalizedCatalog:
+ localized_catalog1:
+ catalog: '@catalog1'
+ code: b2c_fr
+ locale: fr_FR
+ name: B2C French Store View
+ isDefault: false
+ localized_catalog2:
+ catalog: '@catalog1'
+ code: b2c_en
+ locale: en_US
+ name: B2C English Store View
+ isDefault: false
+ localized_catalog3:
+ catalog: '@catalog2'
+ code: b2b_en
+ locale: en_US
+ name: B2B English Store View
+ isDefault: true
diff --git a/api/src/Elasticsuite/Standard/src/DependencyInjection/ElasticsuiteExtension.php b/api/src/Elasticsuite/Standard/src/DependencyInjection/ElasticsuiteExtension.php
index 685633f5d..f31b35ae8 100644
--- a/api/src/Elasticsuite/Standard/src/DependencyInjection/ElasticsuiteExtension.php
+++ b/api/src/Elasticsuite/Standard/src/DependencyInjection/ElasticsuiteExtension.php
@@ -112,6 +112,9 @@ public function load(array $configs, ContainerBuilder $container)
}
$loader->load('Fixture/Resources/config/services.yaml');
$loader->load('Catalog/Resources/config/services.yaml');
+ if ('test' === $container->getParameter('kernel.environment')) {
+ $loader->load('Catalog/Resources/config/test/services.yaml');
+ }
$loader->load('User/Resources/config/services.yaml');
$loader->load('Security/Resources/config/services.yaml');
$loader->load('Cache/Resources/config/services.yaml');
diff --git a/api/src/Elasticsuite/Standard/src/Index/Tests/Api/Rest/IndexOperationsTest.php b/api/src/Elasticsuite/Standard/src/Index/Tests/Api/Rest/IndexOperationsTest.php
index 5f6715a79..db189ea7d 100644
--- a/api/src/Elasticsuite/Standard/src/Index/Tests/Api/Rest/IndexOperationsTest.php
+++ b/api/src/Elasticsuite/Standard/src/Index/Tests/Api/Rest/IndexOperationsTest.php
@@ -52,11 +52,6 @@ protected function getEntityClass(): string
return Index::class;
}
- protected function getApiPath(): string
- {
- return '/indices';
- }
-
protected static function getFixtureFiles(): array
{
return [
@@ -68,8 +63,6 @@ protected static function getFixtureFiles(): array
protected function getJsonCreationValidation(array $validData): array
{
return [
- '@context' => '/contexts/Index',
- '@type' => 'Index',
'aliases' => [
'.catalog_' . $validData['catalog'],
'.entity_' . $validData['entityType'],
@@ -79,19 +72,12 @@ protected function getJsonCreationValidation(array $validData): array
protected function getJsonGetValidation(array $expectedData): array
{
- return [
- '@context' => '/contexts/Index',
- '@id' => '/indices/' . $expectedData['id'],
- '@type' => 'Index',
- ];
+ return [];
}
protected function getJsonGetCollectionValidation(): array
{
return [
- '@context' => '/contexts/Index',
- '@id' => '/indices',
- '@type' => 'hydra:Collection',
'hydra:totalItems' => self::$initialIndicesCount + 6,
];
}
diff --git a/api/src/Elasticsuite/Standard/src/Index/Tests/fixtures/catalogs.yaml b/api/src/Elasticsuite/Standard/src/Index/Tests/fixtures/catalogs.yaml
index 79f4a7965..26917b801 100644
--- a/api/src/Elasticsuite/Standard/src/Index/Tests/fixtures/catalogs.yaml
+++ b/api/src/Elasticsuite/Standard/src/Index/Tests/fixtures/catalogs.yaml
@@ -12,13 +12,16 @@ Elasticsuite\Catalog\Model\LocalizedCatalog:
code: b2c_fr
locale: fr_FR
name: B2C French Store View
+ isDefault: false
catalog1_en:
catalog: '@catalog1'
code: b2c_en
locale: en_US
name: B2C English Store View
+ isDefault: false
catalog2_en:
catalog: '@catalog2'
code: b2b_en
locale: en_US
name: B2B English Store View
+ isDefault: false
diff --git a/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/MetadataTest.php b/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/MetadataTest.php
index 197350a18..d2f75a35f 100644
--- a/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/MetadataTest.php
+++ b/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/MetadataTest.php
@@ -31,16 +31,9 @@ protected function getEntityClass(): string
return Metadata::class;
}
- protected function getApiPath(): string
- {
- return '/metadata';
- }
-
protected function getJsonCreationValidation(array $validData): array
{
return [
- '@context' => '/contexts/Metadata',
- '@type' => 'Metadata',
'entity' => $validData['entity'],
];
}
@@ -48,9 +41,6 @@ protected function getJsonCreationValidation(array $validData): array
protected function getJsonGetValidation(array $expectedData): array
{
return [
- '@context' => '/contexts/Metadata',
- '@id' => '/metadata/' . $expectedData['id'],
- '@type' => 'Metadata',
'entity' => $expectedData['entity'],
];
}
@@ -58,9 +48,6 @@ protected function getJsonGetValidation(array $expectedData): array
protected function getJsonGetCollectionValidation(): array
{
return [
- '@context' => '/contexts/Metadata',
- '@id' => '/metadata',
- '@type' => 'hydra:Collection',
'hydra:totalItems' => 2,
];
}
diff --git a/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldLabelTest.php b/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldLabelTest.php
index 99d692ec4..9a295131e 100644
--- a/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldLabelTest.php
+++ b/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldLabelTest.php
@@ -36,35 +36,21 @@ protected function getEntityClass(): string
return SourceFieldLabel::class;
}
- protected function getApiPath(): string
- {
- return '/source_field_labels';
- }
-
protected function getJsonCreationValidation(array $validData): array
{
return [
- '@context' => '/contexts/SourceFieldLabel',
- '@type' => 'SourceFieldLabel',
'label' => $validData['label'],
];
}
protected function getJsonGetValidation(array $expectedData): array
{
- return [
- '@context' => '/contexts/SourceFieldLabel',
- '@id' => '/source_field_labels/' . $expectedData['id'],
- '@type' => 'SourceFieldLabel',
- ];
+ return [];
}
protected function getJsonGetCollectionValidation(): array
{
return [
- '@context' => '/contexts/SourceFieldLabel',
- '@id' => '/source_field_labels',
- '@type' => 'hydra:Collection',
'hydra:totalItems' => 4,
];
}
diff --git a/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldOptionLabelTest.php b/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldOptionLabelTest.php
index 35af6e66b..6776f8271 100644
--- a/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldOptionLabelTest.php
+++ b/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldOptionLabelTest.php
@@ -37,35 +37,21 @@ protected function getEntityClass(): string
return SourceFieldOptionLabel::class;
}
- protected function getApiPath(): string
- {
- return '/source_field_option_labels';
- }
-
protected function getJsonCreationValidation(array $validData): array
{
return [
- '@context' => '/contexts/SourceFieldOptionLabel',
- '@type' => 'SourceFieldOptionLabel',
'label' => $validData['label'],
];
}
protected function getJsonGetValidation(array $expectedData): array
{
- return [
- '@context' => '/contexts/SourceFieldOptionLabel',
- '@id' => '/source_field_option_labels/' . $expectedData['id'],
- '@type' => 'SourceFieldOptionLabel',
- ];
+ return [];
}
protected function getJsonGetCollectionValidation(): array
{
return [
- '@context' => '/contexts/SourceFieldOptionLabel',
- '@id' => '/source_field_option_labels',
- '@type' => 'hydra:Collection',
'hydra:totalItems' => 4,
];
}
diff --git a/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldOptionTest.php b/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldOptionTest.php
index d521ec904..4dd09bb41 100644
--- a/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldOptionTest.php
+++ b/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldOptionTest.php
@@ -35,34 +35,19 @@ protected function getEntityClass(): string
return SourceFieldOption::class;
}
- protected function getApiPath(): string
- {
- return '/source_field_options';
- }
-
protected function getJsonCreationValidation(array $validData): array
{
- return [
- '@context' => '/contexts/SourceFieldOption',
- '@type' => 'SourceFieldOption',
- ];
+ return [];
}
protected function getJsonGetValidation(array $expectedData): array
{
- return [
- '@context' => '/contexts/SourceFieldOption',
- '@id' => '/source_field_options/' . $expectedData['id'],
- '@type' => 'SourceFieldOption',
- ];
+ return [];
}
protected function getJsonGetCollectionValidation(): array
{
return [
- '@context' => '/contexts/SourceFieldOption',
- '@id' => '/source_field_options',
- '@type' => 'hydra:Collection',
'hydra:totalItems' => 4,
];
}
diff --git a/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldTest.php b/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldTest.php
index 625be3d6a..b8a634ade 100644
--- a/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldTest.php
+++ b/api/src/Elasticsuite/Standard/src/Metadata/Tests/Api/Rest/SourceFieldTest.php
@@ -34,16 +34,9 @@ protected function getEntityClass(): string
return SourceField::class;
}
- protected function getApiPath(): string
- {
- return '/source_fields';
- }
-
protected function getJsonCreationValidation(array $validData): array
{
$json = [
- '@context' => '/contexts/SourceField',
- '@type' => 'SourceField',
'name' => $validData['name'],
];
@@ -57,9 +50,6 @@ protected function getJsonCreationValidation(array $validData): array
protected function getJsonGetValidation(array $expectedData): array
{
return [
- '@context' => '/contexts/SourceField',
- '@id' => '/source_fields/' . $expectedData['id'],
- '@type' => 'SourceField',
'name' => $expectedData['name'],
];
}
@@ -67,9 +57,6 @@ protected function getJsonGetValidation(array $expectedData): array
protected function getJsonGetCollectionValidation(): array
{
return [
- '@context' => '/contexts/SourceField',
- '@id' => '/source_fields',
- '@type' => 'hydra:Collection',
'hydra:totalItems' => 11,
];
}
diff --git a/api/src/Elasticsuite/Standard/src/Test/AbstractEntityTest.php b/api/src/Elasticsuite/Standard/src/Test/AbstractEntityTest.php
index 2547a76f0..5b1f8f154 100644
--- a/api/src/Elasticsuite/Standard/src/Test/AbstractEntityTest.php
+++ b/api/src/Elasticsuite/Standard/src/Test/AbstractEntityTest.php
@@ -16,8 +16,23 @@
namespace Elasticsuite\Standard\src\Test;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
+use ApiPlatform\Core\Operation\PathSegmentNameGeneratorInterface;
+
abstract class AbstractEntityTest extends AbstractTest
{
+ private PathSegmentNameGeneratorInterface $pathGenerator;
+ private ResourceMetadataFactoryInterface $metadataFactory;
+ private ?ResourceMetadata $resource = null;
+
+ public function __construct(?string $name = null, array $data = [], $dataName = '')
+ {
+ parent::__construct($name, $data, $dataName);
+ $this->pathGenerator = static::getContainer()->get('api_platform.path_segment_name_generator');
+ $this->metadataFactory = static::getContainer()->get('api_platform.metadata.resource.metadata_factory');
+ }
+
public static function setUpBeforeClass(): void
{
static::loadFixture(static::getFixtureFiles());
@@ -27,32 +42,32 @@ abstract protected static function getFixtureFiles(): array;
abstract protected function getEntityClass(): string;
- abstract protected function getApiPath(): string;
-
abstract protected function getJsonCreationValidation(array $validData): array;
abstract protected function getJsonGetValidation(array $expectedData): array;
abstract protected function getJsonGetCollectionValidation(): array;
- public function createValidDataProvider(): array
- {
- return [];
- }
+ abstract public function createValidDataProvider(): array;
- public function createInvalidDataProvider(): array
- {
- return [];
- }
+ abstract public function createInvalidDataProvider(): array;
+
+ abstract public function getDataProvider(): array;
+
+ abstract public function deleteDataProvider(): array;
- public function getDataProvider(): array
+ protected function getShortName(): string
{
- return [];
+ if (!$this->resource) {
+ $this->resource = $this->metadataFactory->create($this->getEntityClass());
+ }
+
+ return $this->resource->getShortName();
}
- public function deleteDataProvider(): array
+ protected function getApiPath(): string
{
- return [];
+ return '/' . $this->pathGenerator->getSegmentName($this->getShortName());
}
/**
@@ -62,7 +77,16 @@ public function testCreateValidData(array $validData, string $validRegex = null)
{
$response = $this->requestRest('POST', $this->getApiPath(), $validData);
$this->assertResponseStatusCodeSame(201);
- $this->assertJsonContains($this->getJsonCreationValidation($validData));
+ $shortName = $this->getShortName();
+ $this->assertJsonContains(
+ array_merge(
+ [
+ '@context' => "/contexts/$shortName",
+ '@type' => $shortName,
+ ],
+ $this->getJsonCreationValidation($validData)
+ )
+ );
$this->assertMatchesRegularExpression($validRegex ?? '~^' . $this->getApiPath() . '/\d+$~', $response->toArray()['@id']);
$this->assertMatchesResourceItemJsonSchema($this->getEntityClass());
}
@@ -104,7 +128,17 @@ public function testGet(int|string $id, array $expectedData, int $statusCode): v
$this->assertResponseStatusCodeSame($statusCode);
} else {
$this->assertResponseIsSuccessful();
- $this->assertJsonContains($this->getJsonGetValidation($expectedData));
+ $shortName = $this->getShortName();
+ $this->assertJsonContains(
+ array_merge(
+ [
+ '@context' => "/contexts/$shortName",
+ '@type' => $shortName,
+ '@id' => $this->getApiPath() . '/' . $expectedData['id'],
+ ],
+ $this->getJsonGetValidation($expectedData)
+ )
+ );
}
}
@@ -129,6 +163,16 @@ public function testGetCollection(): void
{
$this->requestRest('GET', $this->getApiPath());
$this->assertResponseIsSuccessful();
- $this->assertJsonContains($this->getJsonGetCollectionValidation());
+ $shortName = $this->getShortName();
+ $this->assertJsonContains(
+ array_merge(
+ [
+ '@context' => "/contexts/$shortName",
+ '@id' => $this->getApiPath(),
+ '@type' => 'hydra:Collection',
+ ],
+ $this->getJsonGetCollectionValidation()
+ )
+ );
}
}