diff --git a/src/Adapter/Language/CommandHandler/EditLanguageHandler.php b/src/Adapter/Language/CommandHandler/EditLanguageHandler.php index ab2efa2b535b3..a910d4090bc6b 100644 --- a/src/Adapter/Language/CommandHandler/EditLanguageHandler.php +++ b/src/Adapter/Language/CommandHandler/EditLanguageHandler.php @@ -249,15 +249,12 @@ private function uploadFlagImageIfChanged(Language $language, EditLanguageComman */ private function assertLanguageWithIsoCodeDoesNotExist(Language $language, EditLanguageCommand $command) { - if (null !== $command->getIsoCode()) { + if (null === $command->getIsoCode()) { return; } - /* @phpstan-ignore-next-line */ - if ($language->iso_code === $command->getIsoCode()->getValue() && Language::getIdByIso($command->getIsoCode()->getValue()) - ) { - /* @phpstan-ignore-next-line */ - throw new LanguageConstraintException(sprintf('Language with ISO code "%s" already exists', $command->getIsoCode()->getValue()), LanguageConstraintException::INVALID_ISO_CODE); + if ($language->iso_code !== $command->getIsoCode()->getValue() && Language::getIdByIso($command->getIsoCode()->getValue())) { + throw new LanguageConstraintException(sprintf('Language with ISO code "%s" already exists', $command->getIsoCode()->getValue()), LanguageConstraintException::DUPLICATE_ISO_CODE); } } } diff --git a/src/Adapter/Language/QueryHandler/GetLanguageForEditingHandler.php b/src/Adapter/Language/QueryHandler/GetLanguageForEditingHandler.php index bbf13670561b6..5d04686b0c46e 100644 --- a/src/Adapter/Language/QueryHandler/GetLanguageForEditingHandler.php +++ b/src/Adapter/Language/QueryHandler/GetLanguageForEditingHandler.php @@ -32,9 +32,7 @@ use PrestaShop\PrestaShop\Core\Domain\Language\Query\GetLanguageForEditing; use PrestaShop\PrestaShop\Core\Domain\Language\QueryHandler\GetLanguageForEditingHandlerInterface; use PrestaShop\PrestaShop\Core\Domain\Language\QueryResult\EditableLanguage; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\TagIETF; /** * Gets language for editing @@ -52,10 +50,11 @@ public function handle(GetLanguageForEditing $query) $language = $this->getLegacyLanguageObject($query->getLanguageId()); return new EditableLanguage( - $query->getLanguageId(), + $query->getLanguageId()->getValue(), $language->name, - new IsoCode($language->iso_code), - new TagIETF($language->language_code), + $language->iso_code, + $language->language_code, + $language->locale, $language->date_format_lite, $language->date_format_full, (bool) $language->is_rtl, diff --git a/src/Core/Domain/Language/QueryResult/EditableLanguage.php b/src/Core/Domain/Language/QueryResult/EditableLanguage.php index 4f6c6f61f40b7..b60f9bfb69b68 100644 --- a/src/Core/Domain/Language/QueryResult/EditableLanguage.php +++ b/src/Core/Domain/Language/QueryResult/EditableLanguage.php @@ -26,161 +26,71 @@ namespace PrestaShop\PrestaShop\Core\Domain\Language\QueryResult; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\TagIETF; - /** * Transfers editable language's data */ class EditableLanguage { - /** - * @var LanguageId - */ - private $languageId; - - /** - * @var string - */ - private $name; - - /** - * @var IsoCode - */ - private $isoCode; - - /** - * @var TagIETF - */ - private $tagIETF; - - /** - * @var string - */ - private $shortDateFormat; - - /** - * @var string - */ - private $fullDateFormat; - - /** - * @var bool - */ - private $isRtl; - - /** - * @var bool - */ - private $isActive; - - /** - * @var array - */ - private $shopAssociation; - - /** - * @param LanguageId $languageId - * @param string $name - * @param IsoCode $isoCode - * @param TagIETF $tagIETF - * @param string $shortDateFormat - * @param string $fullDateFormat - * @param bool $isRtl - * @param bool $isActive - * @param array $shopAssociation - */ public function __construct( - LanguageId $languageId, - $name, - IsoCode $isoCode, - TagIETF $tagIETF, - $shortDateFormat, - $fullDateFormat, - $isRtl, - $isActive, - array $shopAssociation + private readonly int $languageId, + private readonly string $name, + private readonly string $isoCode, + private readonly string $tagIETF, + private readonly string $locale, + private readonly string $shortDateFormat, + private readonly string $fullDateFormat, + private readonly bool $isRtl, + private readonly bool $isActive, + private readonly array $shopAssociation, ) { - $this->languageId = $languageId; - $this->name = $name; - $this->isoCode = $isoCode; - $this->tagIETF = $tagIETF; - $this->shortDateFormat = $shortDateFormat; - $this->fullDateFormat = $fullDateFormat; - $this->isRtl = $isRtl; - $this->isActive = $isActive; - $this->shopAssociation = $shopAssociation; } - /** - * @return LanguageId - */ - public function getLanguageId() + public function getLanguageId(): int { return $this->languageId; } - /** - * @return string - */ - public function getName() + public function getName(): string { return $this->name; } - /** - * @return IsoCode - */ - public function getIsoCode() + public function getIsoCode(): string { return $this->isoCode; } - /** - * @return TagIETF - */ - public function getTagIETF() + public function getTagIETF(): string { return $this->tagIETF; } - /** - * @return string - */ - public function getShortDateFormat() + public function getLocale(): string + { + return $this->locale; + } + + public function getShortDateFormat(): string { return $this->shortDateFormat; } - /** - * @return string - */ - public function getFullDateFormat() + public function getFullDateFormat(): string { return $this->fullDateFormat; } - /** - * @return bool - */ - public function isRtl() + public function isRtl(): bool { return $this->isRtl; } - /** - * @return bool - */ - public function isActive() + public function isActive(): bool { return $this->isActive; } - /** - * @return array - */ - public function getShopAssociation() + public function getShopAssociation(): array { return $this->shopAssociation; } diff --git a/src/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProvider.php index ebdcb204a7b73..7811f81117e62 100644 --- a/src/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProvider.php +++ b/src/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProvider.php @@ -35,48 +35,26 @@ */ final class LanguageFormDataProvider implements FormDataProviderInterface { - /** - * @var CommandBusInterface - */ - private $bus; - - /** - * @var bool - */ - private $isMultistoreFeatureActive; - - /** - * @var int[] - */ - private $defaultShopAssociation; - - /** - * @param CommandBusInterface $bus - * @param bool $isMultistoreFeatureActive - * @param int[] $defaultShopAssociation - */ public function __construct( - CommandBusInterface $bus, - $isMultistoreFeatureActive, - array $defaultShopAssociation + private readonly CommandBusInterface $bus, + private readonly bool $isMultistoreFeatureActive, + private readonly array $defaultShopAssociation ) { - $this->bus = $bus; - $this->isMultistoreFeatureActive = $isMultistoreFeatureActive; - $this->defaultShopAssociation = $defaultShopAssociation; } /** * {@inheritdoc} */ - public function getData($languageId) + public function getData($id) { /** @var EditableLanguage $editableLanguage */ - $editableLanguage = $this->bus->handle(new GetLanguageForEditing($languageId)); + $editableLanguage = $this->bus->handle(new GetLanguageForEditing($id)); $data = [ 'name' => $editableLanguage->getName(), - 'iso_code' => $editableLanguage->getIsoCode()->getValue(), - 'tag_ietf' => $editableLanguage->getTagIETF()->getValue(), + 'iso_code' => $editableLanguage->getIsoCode(), + 'tag_ietf' => $editableLanguage->getTagIETF(), + 'locale' => $editableLanguage->getLocale(), 'short_date_format' => $editableLanguage->getShortDateFormat(), 'full_date_format' => $editableLanguage->getFullDateFormat(), 'is_rtl' => $editableLanguage->isRtl(), diff --git a/src/Core/Grid/Definition/Factory/LanguageGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/LanguageGridDefinitionFactory.php index da2d9e32074f4..f2d993befc72f 100644 --- a/src/Core/Grid/Definition/Factory/LanguageGridDefinitionFactory.php +++ b/src/Core/Grid/Definition/Factory/LanguageGridDefinitionFactory.php @@ -213,7 +213,7 @@ protected function getFilters() ->setTypeOptions([ 'required' => false, 'attr' => [ - 'placeholder' => $this->translator->trans('Search ISO code', [], 'Admin.Internaltional.Help'), + 'placeholder' => $this->translator->trans('Search ISO code', [], 'Admin.International.Help'), ], ]) ->setAssociatedColumn('iso_code') @@ -223,7 +223,7 @@ protected function getFilters() ->setTypeOptions([ 'required' => false, 'attr' => [ - 'placeholder' => $this->translator->trans('Search code', [], 'Admin.Internaltional.Help'), + 'placeholder' => $this->translator->trans('Search code', [], 'Admin.International.Help'), ], ]) ->setAssociatedColumn('language_code') @@ -233,7 +233,7 @@ protected function getFilters() ->setTypeOptions([ 'required' => false, 'attr' => [ - 'placeholder' => $this->translator->trans('Search locale', [], 'Admin.Internaltional.Help'), + 'placeholder' => $this->translator->trans('Search locale', [], 'Admin.International.Help'), ], ]) ->setAssociatedColumn('locale') @@ -243,7 +243,7 @@ protected function getFilters() ->setTypeOptions([ 'required' => false, 'attr' => [ - 'placeholder' => $this->translator->trans('Search date format', [], 'Admin.Internaltional.Help'), + 'placeholder' => $this->translator->trans('Search date format', [], 'Admin.International.Help'), ], ]) ->setAssociatedColumn('date_format_lite') @@ -253,7 +253,7 @@ protected function getFilters() ->setTypeOptions([ 'required' => false, 'attr' => [ - 'placeholder' => $this->translator->trans('Search date format', [], 'Admin.Internaltional.Help'), + 'placeholder' => $this->translator->trans('Search date format', [], 'Admin.International.Help'), ], ]) ->setAssociatedColumn('date_format_full') diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/International/LanguageController.php b/src/PrestaShopBundle/Controller/Admin/Improve/International/LanguageController.php index 99724a36d80ca..eebe21a5a5f49 100644 --- a/src/PrestaShopBundle/Controller/Admin/Improve/International/LanguageController.php +++ b/src/PrestaShopBundle/Controller/Admin/Improve/International/LanguageController.php @@ -182,18 +182,14 @@ public function editAction( } } - /** @var EditableLanguage $editableLanguage */ - $editableLanguage = $this->dispatchQuery(new GetLanguageForEditing((int) $languageId)); - return $this->render('@PrestaShop/Admin/Improve/International/Language/edit.html.twig', [ 'languageForm' => $languageForm->createView(), - 'editableLanguage' => $editableLanguage, 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), 'enableSidebar' => true, 'layoutTitle' => $this->trans( 'Editing language %name%', [ - '%name%' => $editableLanguage->getName(), + '%name%' => $languageForm->get('name')->getData(), ], 'Admin.Navigation.Menu' ), diff --git a/src/PrestaShopBundle/Form/Admin/Improve/International/Language/LanguageType.php b/src/PrestaShopBundle/Form/Admin/Improve/International/Language/LanguageType.php index 3e0c993dc168d..19399a1939651 100644 --- a/src/PrestaShopBundle/Form/Admin/Improve/International/Language/LanguageType.php +++ b/src/PrestaShopBundle/Form/Admin/Improve/International/Language/LanguageType.php @@ -29,6 +29,7 @@ use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex; use PrestaShopBundle\Form\Admin\Type\ShopChoiceTreeType; use PrestaShopBundle\Form\Admin\Type\SwitchType; +use PrestaShopBundle\Form\Admin\Type\TextPreviewType; use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType; use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -104,7 +105,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'maxLength' => 5, ], 'label' => $this->trans('Language code', 'Admin.International.Feature'), - 'help' => $this->trans('IETF language tag (e.g. en-US, pt-BR).', 'Admin.International.Help'), + 'help' => $this->trans('IETF language tag (e.g. en-US, pt-BR) in lower case.', 'Admin.International.Help'), 'constraints' => [ new NotBlank([ 'message' => $this->trans('This field cannot be empty.', 'Admin.Notifications.Error'), @@ -114,6 +115,10 @@ public function buildForm(FormBuilderInterface $builder, array $options) ]), ], ]) + ->add('locale', TextPreviewType::class, [ + 'label' => $this->trans('Locale', 'Admin.International.Feature'), + 'help' => $this->trans('IETF language tag (e.g. en-US, pt-BR).', 'Admin.International.Help'), + ]) ->add('short_date_format', TextType::class, [ 'label' => $this->trans('Date format', 'Admin.International.Feature'), 'help' => $this->trans('Short date format (e.g., Y-m-d).', 'Admin.International.Help'), diff --git a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig index bc5da751bc17d..6bedee885fdd2 100644 --- a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig +++ b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig @@ -1317,6 +1317,7 @@ {% endif %} + {{- block('form_help') -}} {% endblock %} {% block link_preview_widget %} diff --git a/tests/Integration/Behaviour/Features/Context/Domain/LanguageFeatureContext.php b/tests/Integration/Behaviour/Features/Context/Domain/LanguageFeatureContext.php index 67eeace6dfe21..eeb58bb957071 100644 --- a/tests/Integration/Behaviour/Features/Context/Domain/LanguageFeatureContext.php +++ b/tests/Integration/Behaviour/Features/Context/Domain/LanguageFeatureContext.php @@ -38,6 +38,7 @@ use PrestaShop\PrestaShop\Core\Domain\Language\Command\EditLanguageCommand; use PrestaShop\PrestaShop\Core\Domain\Language\Command\ToggleLanguageStatusCommand; use PrestaShop\PrestaShop\Core\Domain\Language\Exception\DefaultLanguageException; +use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageConstraintException; use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageNotFoundException; use PrestaShop\PrestaShop\Core\Domain\Language\Query\GetLanguageForEditing; @@ -49,11 +50,12 @@ class LanguageFeatureContext extends AbstractDomainFeatureContext { /** - * @Given I add a new language with the following details: + * @Given I add a new language :languageReference with the following details: * + * @param string $languageReference * @param TableNode $table */ - public function addNewLanguage(TableNode $table): void + public function addNewLanguage(string $languageReference, TableNode $table): void { $data = $table->getRowsHash(); @@ -83,25 +85,21 @@ public function addNewLanguage(TableNode $table): void ] )); - SharedStorage::getStorage()->set($data['isoCode'], $languageId->getValue()); + SharedStorage::getStorage()->set($languageReference, $languageId->getValue()); } catch (LanguageException $e) { $this->setLastException($e); } } /** - * @Given I update the language with ISOCode :isoCode with the following details: + * @Given I update the language :languageReference with the following details: * - * @param string $isoCode + * @param string $languageReference * @param TableNode $table */ - public function updateLanguage(string $isoCode, TableNode $table): void + public function updateLanguage(string $languageReference, TableNode $table): void { - $languageId = SharedStorage::getStorage()->get($isoCode); - - $editableLanguage = new EditLanguageCommand((int) $languageId); - $editableLanguage->setIsoCode($isoCode); - + $editableLanguage = new EditLanguageCommand($this->referenceToId($languageReference)); $data = $table->getRowsHash(); if (isset($data['name'])) { $editableLanguage->setName($data['name']); @@ -133,15 +131,14 @@ public function updateLanguage(string $isoCode, TableNode $table): void } /** - * @When I delete the language with ISOCode :isoCode + * @When I delete the language :languageReference * - * @param string $isoCode + * @param string $languageReference */ - public function deleteLanguage(string $isoCode): void + public function deleteLanguage(string $languageReference): void { - $languageId = SharedStorage::getStorage()->get($isoCode); - try { + $languageId = $this->referenceToId($languageReference); $this->getCommandBus()->handle(new DeleteLanguageCommand($languageId)); SharedStorage::getStorage()->clear($languageId); @@ -153,19 +150,14 @@ public function deleteLanguage(string $isoCode): void } /** - * @When I bulk delete languages with ISOCode :isoCode + * @When I bulk delete languages :languageReferences * - * @param string $isoCodes + * @param string $languageReferences */ - public function bulkDeleteLanguage(string $isoCodes): void + public function bulkDeleteLanguage(string $languageReferences): void { - $isoCodes = explode(',', $isoCodes); - $languageIds = []; - foreach ($isoCodes as $isoCode) { - $languageIds[] = SharedStorage::getStorage()->get($isoCode); - } - try { + $languageIds = $this->referencesToIds($languageReferences); $this->getCommandBus()->handle(new BulkDeleteLanguagesCommand($languageIds)); // Important to clean this cache or Language::getIdByIso still returns stored value for next adding @@ -180,18 +172,22 @@ public function bulkDeleteLanguage(string $isoCodes): void } /** - * @When /^I (enable|disable) the language with ISOCode "([a-z]{2})"$/ + * @When I toggle the language :languageReference status to :status * - * @param string $statusVerb - * @param string $isoCode + * @param string $status + * @param string $languageReference */ - public function setStatusLanguage(string $statusVerb, string $isoCode): void + public function setStatusLanguage(string $status, string $languageReference): void { + if (!in_array($status, ['enabled', 'disabled'])) { + throw new RuntimeException(sprintf('A status should be "enabled" or "disabled", not "%s"', $status)); + } + try { $this->getCommandBus()->handle( new ToggleLanguageStatusCommand( - SharedStorage::getStorage()->get($isoCode), - $statusVerb === 'enable' + $this->referenceToId($languageReference), + $status === 'enabled' ) ); } catch (LanguageException $e) { @@ -200,22 +196,20 @@ public function setStatusLanguage(string $statusVerb, string $isoCode): void } /** - * @When /^I bulk (enable|disable) languages with ISOCode "([a-z,]+)"$/ + * @When I bulk toggle languages :languageReferences status to :status * - * @param string $statusVerb - * @param string $isoCodes + * @param string $status + * @param string $languageReferences */ - public function bulkSetStatusLanguage(string $statusVerb, string $isoCodes): void + public function bulkSetStatusLanguage(string $status, string $languageReferences): void { - $isoCodes = explode(',', $isoCodes); - $languageIds = []; - foreach ($isoCodes as $isoCode) { - $languageIds[] = SharedStorage::getStorage()->get($isoCode); + if (!in_array($status, ['enabled', 'disabled'])) { + throw new RuntimeException(sprintf('A status should be "enabled" or "disabled", not "%s"', $status)); } try { $this->getCommandBus()->handle( - new BulkToggleLanguagesStatusCommand($languageIds, $statusVerb === 'enable') + new BulkToggleLanguagesStatusCommand($this->referencesToIds($languageReferences), $status === 'enabled') ); } catch (LanguageException $e) { $this->setLastException($e); @@ -223,21 +217,22 @@ public function bulkSetStatusLanguage(string $statusVerb, string $isoCodes): voi } /** - * @Then the language with ISOCode :isoCode should have the following details: + * @Then the language :languageReference should have the following details: * - * @param string $isoCode + * @param string $languageReference * @param TableNode $table */ - public function checkLanguageDetails(string $isoCode, TableNode $table): void + public function checkLanguageDetails(string $languageReference, TableNode $table): void { - $editableLanguage = $this->getLanguage($isoCode); + $editableLanguage = $this->getLanguage($languageReference); $this->assertLastErrorIsNull(); $data = $table->getRowsHash(); Assert::assertEquals($data['name'], $editableLanguage->getName()); - Assert::assertEquals($data['isoCode'], $editableLanguage->getIsoCode()->getValue()); - Assert::assertEquals($data['tagIETF'], $editableLanguage->getTagIETF()->getValue()); + Assert::assertEquals($data['isoCode'], $editableLanguage->getIsoCode()); + Assert::assertEquals($data['tagIETF'], $editableLanguage->getTagIETF()); + Assert::assertEquals($data['locale'], $editableLanguage->getLocale()); Assert::assertEquals($data['shortDateFormat'], $editableLanguage->getShortDateFormat()); Assert::assertEquals($data['fullDateFormat'], $editableLanguage->getFullDateFormat()); Assert::assertEquals((bool) $data['isRtl'], $editableLanguage->isRtl()); @@ -248,41 +243,41 @@ public function checkLanguageDetails(string $isoCode, TableNode $table): void } /** - * @Then the language with ISOCode :isoCode should exist + * @Then the language :languageReference should exist * - * @param string $isoCode + * @param string $languageReference */ - public function checkLanguageExists(string $isoCode): void + public function checkLanguageExists(string $languageReference): void { - $this->getLanguage($isoCode); + $this->getLanguage($languageReference); $this->assertLastErrorIsNull(); } /** - * @Then the language with ISOCode :isoCode shouldn't exist + * @Then the language :languageReference shouldn't exist * - * @param string $isoCode + * @param string $languageReference */ - public function checkLanguageNotExists(string $isoCode): void + public function checkLanguageNotExists(string $languageReference): void { - $this->getLanguage($isoCode); + $this->getLanguage($languageReference); $this->assertLastErrorIs(LanguageNotFoundException::class); } /** - * @Then the language with ISOCode :isoCode should be :status + * @Then the language :languageReference should be :status * - * @param string $isoCode + * @param string $languageReference */ - public function checkLanguageStatus(string $isoCode, string $status): void + public function checkLanguageStatus(string $languageReference, string $status): void { if (!in_array($status, ['enabled', 'disabled'])) { throw new RuntimeException(sprintf('A status should be "enabled" or "disabled", not "%s"', $status)); } - $editableLanguage = $this->getLanguage($isoCode); + $editableLanguage = $this->getLanguage($languageReference); $this->assertLastErrorIsNull(); Assert::assertEquals($status === 'enabled', $editableLanguage->isActive()); @@ -311,15 +306,26 @@ public function checkErrorDefaultLanguageCantBeDisabled(): void } /** - * @param string $isoCode + * @Then I should get an error that a language with this ISO code already exists + */ + public function checkDuplicateIsoCode(): void + { + $this->assertLastErrorIs( + LanguageConstraintException::class, + LanguageConstraintException::DUPLICATE_ISO_CODE + ); + } + + /** + * @param string $languageReference * * @return EditableLanguage|null */ - private function getLanguage(string $isoCode): ?EditableLanguage + private function getLanguage(string $languageReference): ?EditableLanguage { try { return $this->getQueryBus()->handle( - new GetLanguageForEditing(SharedStorage::getStorage()->get($isoCode)) + new GetLanguageForEditing($this->referenceToId($languageReference)) ); } catch (LanguageException $e) { $this->setLastException($e); diff --git a/tests/Integration/Behaviour/Features/Scenario/Language/language.feature b/tests/Integration/Behaviour/Features/Scenario/Language/language.feature index 667b400f9f3f2..9b4c7756c26f7 100644 --- a/tests/Integration/Behaviour/Features/Scenario/Language/language.feature +++ b/tests/Integration/Behaviour/Features/Scenario/Language/language.feature @@ -5,7 +5,7 @@ Feature: Language Background: Given shop "shop1" with name "test_shop" exists And I restore languages tables - And I add a new language with the following details: + And I add a new language "french" with the following details: | name | Français (French) | | isoCode | fr | | tagIETF | fr | @@ -14,23 +14,43 @@ Feature: Language | isRtl | 0 | | isActive | 1 | | shop | shop1 | - And the language with ISOCode "fr" should exist - And I add a new language with the following details: + And the language "french" should exist + And the language "french" should have the following details: + | name | Français (French) | + | isoCode | fr | + | tagIETF | fr | + | locale | fr-FR | + | shortDateFormat | d/m/Y | + | fullDateFormat | d/m/Y H:i:s | + | isRtl | 0 | + | isActive | 1 | + | shop | shop1 | + And I add a new language "british" with the following details: + | name | English GB (English) | + | isoCode | gb | + | tagIETF | en-gb | + | shortDateFormat | Y-m-d | + | fullDateFormat | Y-m-d H:i:s | + | isRtl | 0 | + | isActive | 1 | + | shop | shop1 | + And the language "british" should exist + And the language "british" should have the following details: | name | English GB (English) | | isoCode | gb | | tagIETF | en-gb | + | locale | en-GB | | shortDateFormat | Y-m-d | | fullDateFormat | Y-m-d H:i:s | | isRtl | 0 | | isActive | 1 | | shop | shop1 | - And the language with ISOCode "gb" should exist And the robots.txt file has a rule where the directory "/en/app/" is allowed And the robots.txt file has a rule where the directory "/fr/app/" is allowed And the robots.txt file has a rule where the directory "/gb/app/" is allowed Scenario: Add new language - When I add a new language with the following details: + When I add a new language "spanish" with the following details: | name | Español AR (Spanish) | | isoCode | ag | | tagIETF | es-ar | @@ -40,105 +60,139 @@ Feature: Language | isActive | 1 | | shop | shop1 | And the robots.txt file has a rule where the directory "/ag/app/" is allowed - And the language with ISOCode "ag" should have the following details: + And the language "spanish" should have the following details: | name | Español AR (Spanish) | | isoCode | ag | | tagIETF | es-ar | + | locale | es-AR | | shortDateFormat | Y-m-d | | fullDateFormat | Y-m-d H:i:s | | isRtl | 0 | | isActive | 1 | | shop | shop1 | ## Reset - When I delete the language with ISOCode "ag" + When I delete the language "spanish" And the robots.txt file hasn't a rule where the directory "/ag/app/" is allowed Scenario: Edit language - When I update the language with ISOCode "fr" with the following details: - | name | Language | - | tagIETF | it | - | shortDateFormat | Y-m-d | - | fullDateFormat | Y-m-d H:i:s | - | isRtl | 0 | - | isActive | 1 | - | shop | shop1 | - And the language with ISOCode "fr" should have the following details: - | name | Language | - | isoCode | fr | - | tagIETF | it | - | shortDateFormat | Y-m-d | - | fullDateFormat | Y-m-d H:i:s | - | isRtl | 0 | - | isActive | 1 | - | shop | shop1 | + When I update the language "french" with the following details: + | name | Language | + | tagIETF | it | + | shortDateFormat | Y-m-d | + | fullDateFormat | Y-m-d H:i:s | + | isRtl | 0 | + | isActive | 1 | + | shop | shop1 | + And the language "french" should have the following details: + | name | Language | + | isoCode | fr | + | tagIETF | it | + | locale | fr-FR | + | shortDateFormat | Y-m-d | + | fullDateFormat | Y-m-d H:i:s | + | isRtl | 0 | + | isActive | 1 | + | shop | shop1 | + # When iso code is updated locale is automatically updated + When I update the language "french" with the following details: + | name | Language | + | isoCode | it | + And the language "french" should have the following details: + | name | Language | + | isoCode | it | + | tagIETF | it | + | locale | it-IT | + | shortDateFormat | Y-m-d | + | fullDateFormat | Y-m-d H:i:s | + | isRtl | 0 | + | isActive | 1 | + | shop | shop1 | Scenario: Delete language - When I delete the language with ISOCode "fr" - And the language with ISOCode "fr" shouldn't exist + When I delete the language "french" + And the language "french" shouldn't exist And the robots.txt file hasn't a rule where the directory "/fr/app/" is allowed Scenario: Delete a default language When language with iso code "fr" is the default one - And I delete the language with ISOCode "fr" + And I delete the language "french" Then I should get an error that a default language can't be deleted - And the language with ISOCode "fr" should exist + And the language "french" should exist And the robots.txt file has a rule where the directory "/fr/app/" is allowed Scenario: Bulk Delete - When I bulk delete languages with ISOCode "fr,gb" - And the language with ISOCode "fr" shouldn't exist - And the language with ISOCode "gb" shouldn't exist + When I bulk delete languages "french,british" + And the language "french" shouldn't exist + And the language "british" shouldn't exist And the robots.txt file hasn't a rule where the directory "/fr/app/" is allowed And the robots.txt file hasn't a rule where the directory "/gb/app/" is allowed Scenario: Bulk Delete (with a default one) When language with iso code "fr" is the default one - And I bulk delete languages with ISOCode "fr,gb" + And I bulk delete languages "french,british" Then I should get an error that a default language can't be deleted - Then the language with ISOCode "fr" should exist - And the language with ISOCode "gb" should exist - And I bulk delete languages with ISOCode "gb,fr" + Then the language "french" should exist + And the language "british" should exist + And I bulk delete languages "british,french" Then I should get an error that a default language can't be deleted - Then the language with ISOCode "fr" should exist - And the language with ISOCode "gb" shouldn't exist + Then the language "french" should exist + And the language "british" shouldn't exist Scenario: Toggle Status - Given the language with ISOCode "fr" should be enabled - When I disable the language with ISOCode "fr" - Then the language with ISOCode "fr" should be disabled + Given the language "french" should be enabled + When I toggle the language "french" status to disabled + Then the language "french" should be disabled And the robots.txt file hasn't a rule where the directory "/fr/app/" is allowed - When I enable the language with ISOCode "fr" - And the language with ISOCode "fr" should be enabled + When I toggle the language "french" status to enabled + And the language "french" should be enabled And the robots.txt file has a rule where the directory "/fr/app/" is allowed Scenario: Toggle the status of the default language Given language with iso code "fr" is the default one - And I disable the language with ISOCode "fr" + When I toggle the language "french" status to disabled Then I should get an error that a default language can't be disabled - And the language with ISOCode "fr" should be enabled + And the language "french" should be enabled Scenario: Bulk Toggle Status - Given the language with ISOCode "fr" should be enabled - And the language with ISOCode "gb" should be enabled - When I bulk disable languages with ISOCode "gb,fr" - And the language with ISOCode "fr" should be disabled - And the language with ISOCode "gb" should be disabled + Given the language "french" should be enabled + And the language "british" should be enabled + When I bulk toggle languages "french,british" status to disabled + And the language "french" should be disabled + And the language "british" should be disabled And the robots.txt file hasn't a rule where the directory "/fr/app/" is allowed And the robots.txt file hasn't a rule where the directory "/gb/app/" is allowed - When I bulk enable languages with ISOCode "gb,fr" - And the language with ISOCode "fr" should be enabled - And the language with ISOCode "gb" should be enabled + When I bulk toggle languages "british,french" status to enabled + And the language "french" should be enabled + And the language "british" should be enabled And the robots.txt file has a rule where the directory "/fr/app/" is allowed And the robots.txt file has a rule where the directory "/gb/app/" is allowed Scenario: Bulk Toggle Status (with a default one) Given language with iso code "fr" is the default one - When I bulk disable languages with ISOCode "fr,gb" + When I bulk toggle languages "french,british" status to disabled Then I should get an error that a default language can't be disabled - And the language with ISOCode "fr" should be enabled - And the language with ISOCode "gb" should be enabled + And the language "french" should be enabled + And the language "british" should be enabled # Second case the gb is provided first so it is disabled before the exception is thrown for default language - When I bulk disable languages with ISOCode "gb,fr" + When I bulk toggle languages "british,french" status to disabled Then I should get an error that a default language can't be disabled - And the language with ISOCode "fr" should be enabled - And the language with ISOCode "gb" should be disabled + And the language "french" should be enabled + And the language "british" should be disabled + + Scenario: Adding a language with an ISO code already in database is forbidden + # Adding new language with ISO code already existing is forbidden + And I add a new language "french2" with the following details: + | name | Français (French) | + | isoCode | fr | + | tagIETF | fr | + | shortDateFormat | d/m/Y | + | fullDateFormat | d/m/Y H:i:s | + | isRtl | 0 | + | isActive | 1 | + | shop | shop1 | + Then I should get an error that a language with this ISO code already exists + # Updating a language with ISO code already existing is also forbidden + When I update the language "french" with the following details: + | name | Language | + | isoCode | gb | + Then I should get an error that a language with this ISO code already exists diff --git a/tests/Unit/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProviderTest.php b/tests/Unit/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProviderTest.php index 6f07eefa17e6c..eab9f2dd59765 100644 --- a/tests/Unit/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProviderTest.php +++ b/tests/Unit/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProviderTest.php @@ -30,9 +30,6 @@ use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; use PrestaShop\PrestaShop\Core\Domain\Language\Query\GetLanguageForEditing; use PrestaShop\PrestaShop\Core\Domain\Language\QueryResult\EditableLanguage; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\TagIETF; use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\LanguageFormDataProvider; class LanguageFormDataProviderTest extends TestCase @@ -49,6 +46,7 @@ public function testItProvideFormDataForLanguageEditingWhenMultistoreFeatureIsOf 'name' => 'Lithuanian', 'iso_code' => 'lt', 'tag_ietf' => 'lt-LT', + 'locale' => 'lt-LT', 'short_date_format' => 'Y-m-d', 'full_date_format' => 'Y-m-d H:i:s', 'is_rtl' => false, @@ -68,6 +66,7 @@ public function testItProvideFormDataForLanguageEditingWhenMultistoreFeatureIsUs 'name' => 'Lithuanian', 'iso_code' => 'lt', 'tag_ietf' => 'lt-LT', + 'locale' => 'lt-LT', 'short_date_format' => 'Y-m-d', 'full_date_format' => 'Y-m-d H:i:s', 'is_rtl' => false, @@ -119,10 +118,11 @@ private function createQueryBusMock() ->with($this->isInstanceOf(GetLanguageForEditing::class)) ->willReturn( new EditableLanguage( - new LanguageId(2), + 2, 'Lithuanian', - new IsoCode('lt'), - new TagIETF('lt-LT'), + 'lt', + 'lt-LT', + 'lt-LT', 'Y-m-d', 'Y-m-d H:i:s', false,