mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 09:02:12 +00:00
[AdminBundle] Add QuestionFactory
This commit is contained in:
parent
7385cab236
commit
4b94f51140
13 changed files with 294 additions and 128 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
@change_admin_password @cli
|
@change_admin_password
|
||||||
Feature: Changing an administrator's password via CLI
|
Feature: Changing an administrator's password via CLI
|
||||||
In order to login to my administrator account when I forget my password
|
In order to login to my administrator account when I forget my password
|
||||||
As a administrator
|
As a administrator
|
||||||
|
|
@ -12,4 +12,6 @@ Feature: Changing an administrator's password via CLI
|
||||||
When I want to change password
|
When I want to change password
|
||||||
And I specify email as "sylius_change_password@example.com"
|
And I specify email as "sylius_change_password@example.com"
|
||||||
And I specify my new password as "newp@ssw0rd"
|
And I specify my new password as "newp@ssw0rd"
|
||||||
Then I should be able to log in as "sylius_change_password@example.com" authenticated by "newp@ssw0rd" password
|
And I run command
|
||||||
|
Then I should be informed that password has been changed successfully
|
||||||
|
And I should be able to log in as "sylius_change_password@example.com" authenticated by "newp@ssw0rd" password
|
||||||
|
|
|
||||||
|
|
@ -85,20 +85,6 @@ parameters:
|
||||||
count: 1
|
count: 1
|
||||||
path: src/Sylius/Bundle/AdminBundle/Action/ResendShipmentConfirmationEmailAction.php
|
path: src/Sylius/Bundle/AdminBundle/Action/ResendShipmentConfirmationEmailAction.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Method Sylius\\\\Bundle\\\\AdminBundle\\\\Command\\\\CreateAdminUserCommand\\:\\:askAdminUserData\\(\\) return type has no value type specified in iterable type array\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Sylius/Bundle/AdminBundle/Command/CreateAdminUserCommand.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Method Sylius\\\\Bundle\\\\AdminBundle\\\\Command\\\\CreateAdminUserCommand\\:\\:showSummary\\(\\) has parameter \\$adminUserData with no value type specified in iterable type array\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Sylius/Bundle/AdminBundle/Command/CreateAdminUserCommand.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Method Sylius\\\\Bundle\\\\AdminBundle\\\\Command\\\\ChangeAdminUserPasswordCommand\\:\\:__construct\\(\\) has parameter \\$adminUserRepository with generic interface Sylius\\\\Component\\\\User\\\\Repository\\\\UserRepositoryInterface but does not specify its types\\: T$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Sylius/Bundle/AdminBundle/Command/ChangeAdminUserPasswordCommand.php
|
|
||||||
-
|
-
|
||||||
message: "#^Method Sylius\\\\Bundle\\\\AdminBundle\\\\Controller\\\\CustomerStatisticsController\\:\\:__construct\\(\\) has parameter \\$customerRepository with generic interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface but does not specify its types\\: T$#"
|
message: "#^Method Sylius\\\\Bundle\\\\AdminBundle\\\\Controller\\\\CustomerStatisticsController\\:\\:__construct\\(\\) has parameter \\$customerRepository with generic interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface but does not specify its types\\: T$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ declare(strict_types=1);
|
||||||
namespace Sylius\Behat\Context\Cli;
|
namespace Sylius\Behat\Context\Cli;
|
||||||
|
|
||||||
use Behat\Behat\Context\Context;
|
use Behat\Behat\Context\Context;
|
||||||
|
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||||
|
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
||||||
|
use Sylius\Component\User\Security\UserPasswordHasherInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||||
use Symfony\Component\Console\Tester\CommandTester;
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
|
|
@ -29,8 +32,11 @@ final class ChangeAdminPasswordContext implements Context
|
||||||
|
|
||||||
private $input = [];
|
private $input = [];
|
||||||
|
|
||||||
|
/** @param UserRepositoryInterface<AdminUserInterface> $adminUserRepository */
|
||||||
public function __construct(
|
public function __construct(
|
||||||
KernelInterface $kernel
|
KernelInterface $kernel,
|
||||||
|
private UserRepositoryInterface $adminUserRepository,
|
||||||
|
private UserPasswordHasherInterface $userPasswordHasher,
|
||||||
) {
|
) {
|
||||||
$this->application = new Application($kernel);
|
$this->application = new Application($kernel);
|
||||||
}
|
}
|
||||||
|
|
@ -61,14 +67,31 @@ final class ChangeAdminPasswordContext implements Context
|
||||||
$this->input['password'] = $password;
|
$this->input['password'] = $password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @When I run command
|
||||||
|
*/
|
||||||
|
public function iRunCommand(): void
|
||||||
|
{
|
||||||
|
$this->commandTester->setInputs($this->input);
|
||||||
|
$this->commandTester->execute(['command' => self::ADMIN_USER_CHANGE_PASSWORD]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Then I should be informed that password has been changed successfully
|
||||||
|
*/
|
||||||
|
public function iShouldBeInformedThatPasswordHasBeenChangedSuccessfully(): void
|
||||||
|
{
|
||||||
|
Assert::contains($this->commandTester->getDisplay(), 'Admin user password has been changed successfully.');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Then I should be able to log in as :email authenticated by :password password
|
* @Then I should be able to log in as :email authenticated by :password password
|
||||||
*/
|
*/
|
||||||
public function iShouldBeAbleToLoginWithEmailAndPassword(string $email = '', string $password = ''): void
|
public function iShouldBeAbleToLoginWithEmailAndPassword(string $email = '', string $password = ''): void
|
||||||
{
|
{
|
||||||
$this->commandTester->setInputs($this->input);
|
/** @var AdminUserInterface|null $adminUser */
|
||||||
$this->commandTester->execute(['command' => self::ADMIN_USER_CHANGE_PASSWORD]);
|
$adminUser = $this->adminUserRepository->findOneByEmail($email);
|
||||||
|
$adminUser->setPlainPassword($password);
|
||||||
Assert::contains($this->commandTester->getDisplay(), 'Admin user password has been changed successfully.');
|
Assert::same($adminUser->getPassword(), $this->userPasswordHasher->hash($adminUser));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
<service id="sylius.behat.context.cli.change_admin_password" class="Sylius\Behat\Context\Cli\ChangeAdminPasswordContext">
|
<service id="sylius.behat.context.cli.change_admin_password" class="Sylius\Behat\Context\Cli\ChangeAdminPasswordContext">
|
||||||
<argument type="service" id="kernel" />
|
<argument type="service" id="kernel" />
|
||||||
|
<argument type="service" id="sylius.repository.admin_user" />
|
||||||
|
<argument type="service" id="sylius.security.password_hasher" />
|
||||||
</service>
|
</service>
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,10 @@ default:
|
||||||
suites:
|
suites:
|
||||||
change_admin_password:
|
change_admin_password:
|
||||||
contexts:
|
contexts:
|
||||||
|
- sylius.behat.context.hook.doctrine_orm
|
||||||
|
|
||||||
- sylius.behat.context.setup.admin_user
|
- sylius.behat.context.setup.admin_user
|
||||||
|
|
||||||
- sylius.behat.context.cli.change_admin_password
|
- sylius.behat.context.cli.change_admin_password
|
||||||
|
|
||||||
filters:
|
filters:
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\AdminBundle\Command;
|
namespace Sylius\Bundle\AdminBundle\Command;
|
||||||
|
|
||||||
|
use Sylius\Bundle\AdminBundle\Command\Factory\QuestionFactoryInterface;
|
||||||
use Sylius\Component\Core\Model\AdminUserInterface;
|
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||||
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
||||||
use Sylius\Component\User\Security\PasswordUpdaterInterface;
|
use Sylius\Component\User\Security\PasswordUpdaterInterface;
|
||||||
|
|
@ -20,20 +21,30 @@ use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
#[AsCommand(
|
#[AsCommand(
|
||||||
name: 'sylius:admin-user:change-password',
|
name: 'sylius:admin-user:change-password',
|
||||||
description: 'Change password of admin user'
|
description: 'Change password of admin user'
|
||||||
)]
|
)]
|
||||||
final class ChangeAdminUserPasswordCommand extends AbstractAdminUserCommand
|
final class ChangeAdminUserPasswordCommand extends Command
|
||||||
{
|
{
|
||||||
|
protected SymfonyStyle $io;
|
||||||
|
|
||||||
|
/** @param UserRepositoryInterface<AdminUserInterface> $adminUserRepository */
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private UserRepositoryInterface $adminUserRepository,
|
private UserRepositoryInterface $adminUserRepository,
|
||||||
private PasswordUpdaterInterface $passwordUpdater
|
private PasswordUpdaterInterface $passwordUpdater,
|
||||||
|
private QuestionFactoryInterface $questionFactory,
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function initialize(InputInterface $input, OutputInterface $output): void
|
||||||
|
{
|
||||||
|
$this->io = new SymfonyStyle($input, $output);
|
||||||
|
}
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
{
|
{
|
||||||
if (!$input->isInteractive()) {
|
if (!$input->isInteractive()) {
|
||||||
|
|
@ -44,7 +55,7 @@ final class ChangeAdminUserPasswordCommand extends AbstractAdminUserCommand
|
||||||
|
|
||||||
$this->io->title('Change admin user password');
|
$this->io->title('Change admin user password');
|
||||||
|
|
||||||
$email = $this->io->askQuestion($this->createEmailQuestion());
|
$email = $this->io->askQuestion($this->questionFactory->createEmail());
|
||||||
|
|
||||||
/** @var AdminUserInterface|null $adminUser */
|
/** @var AdminUserInterface|null $adminUser */
|
||||||
$adminUser = $this->adminUserRepository->findOneByEmail($email);
|
$adminUser = $this->adminUserRepository->findOneByEmail($email);
|
||||||
|
|
@ -54,7 +65,7 @@ final class ChangeAdminUserPasswordCommand extends AbstractAdminUserCommand
|
||||||
return Command::INVALID;
|
return Command::INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
$password = $this->io->askQuestion($this->createQuestionWithNonBlankValidator('New password', true));
|
$password = $this->io->askQuestion($this->questionFactory->createWithNotNullValidator('New password', true));
|
||||||
$adminUser->setPlainPassword($password);
|
$adminUser->setPlainPassword($password);
|
||||||
|
|
||||||
$this->passwordUpdater->updatePassword($adminUser);
|
$this->passwordUpdater->updatePassword($adminUser);
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,14 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\AdminBundle\Command;
|
namespace Sylius\Bundle\AdminBundle\Command;
|
||||||
|
|
||||||
|
use Sylius\Bundle\AdminBundle\Command\Factory\QuestionFactoryInterface;
|
||||||
use Sylius\Bundle\AdminBundle\Exception\CreateAdminUserFailedException;
|
use Sylius\Bundle\AdminBundle\Exception\CreateAdminUserFailedException;
|
||||||
use Sylius\Bundle\AdminBundle\Message\CreateAdminUser;
|
use Sylius\Bundle\AdminBundle\Message\CreateAdminUser;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
use Symfony\Component\Intl\Locales;
|
use Symfony\Component\Intl\Locales;
|
||||||
use Symfony\Component\Messenger\Exception\HandlerFailedException;
|
use Symfony\Component\Messenger\Exception\HandlerFailedException;
|
||||||
use Symfony\Component\Messenger\HandleTrait;
|
use Symfony\Component\Messenger\HandleTrait;
|
||||||
|
|
@ -28,17 +30,27 @@ use Symfony\Component\Messenger\MessageBusInterface;
|
||||||
name: 'sylius:admin-user:create',
|
name: 'sylius:admin-user:create',
|
||||||
description: 'Create a new admin user',
|
description: 'Create a new admin user',
|
||||||
)]
|
)]
|
||||||
final class CreateAdminUserCommand extends AbstractAdminUserCommand
|
final class CreateAdminUserCommand extends Command
|
||||||
{
|
{
|
||||||
use HandleTrait;
|
use HandleTrait;
|
||||||
|
|
||||||
public function __construct(MessageBusInterface $messageBus, private string $defaultLocaleCode)
|
protected SymfonyStyle $io;
|
||||||
{
|
|
||||||
|
public function __construct(
|
||||||
|
MessageBusInterface $messageBus,
|
||||||
|
private string $defaultLocaleCode,
|
||||||
|
private QuestionFactoryInterface $questionFactory,
|
||||||
|
) {
|
||||||
$this->messageBus = $messageBus;
|
$this->messageBus = $messageBus;
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function initialize(InputInterface $input, OutputInterface $output): void
|
||||||
|
{
|
||||||
|
$this->io = new SymfonyStyle($input, $output);
|
||||||
|
}
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
{
|
{
|
||||||
if (!$input->isInteractive()) {
|
if (!$input->isInteractive()) {
|
||||||
|
|
@ -76,18 +88,19 @@ final class CreateAdminUserCommand extends AbstractAdminUserCommand
|
||||||
return Command::SUCCESS;
|
return Command::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return array<array-key, mixed> */
|
||||||
private function askAdminUserData(): array
|
private function askAdminUserData(): array
|
||||||
{
|
{
|
||||||
$adminUserData = [];
|
$adminUserData = [];
|
||||||
|
|
||||||
$adminUserData['email'] = $this->io->askQuestion($this->createEmailQuestion());
|
$adminUserData['email'] = $this->io->askQuestion($this->questionFactory->createEmail());
|
||||||
$adminUserData['username'] = $this->io->askQuestion(
|
$adminUserData['username'] = $this->io->askQuestion(
|
||||||
$this->createQuestionWithNonBlankValidator('Username'),
|
$this->questionFactory->createWithNotNullValidator('Username'),
|
||||||
);
|
);
|
||||||
$adminUserData['first_name'] = $this->io->ask('First name');
|
$adminUserData['first_name'] = $this->io->ask('First name');
|
||||||
$adminUserData['last_name'] = $this->io->ask('Last name');
|
$adminUserData['last_name'] = $this->io->ask('Last name');
|
||||||
$adminUserData['plain_password'] = $this->io->askQuestion(
|
$adminUserData['plain_password'] = $this->io->askQuestion(
|
||||||
$this->createQuestionWithNonBlankValidator('Password', true),
|
$this->questionFactory->createWithNotNullValidator('Password', true),
|
||||||
);
|
);
|
||||||
|
|
||||||
$localeCodes = Locales::getNames();
|
$localeCodes = Locales::getNames();
|
||||||
|
|
@ -98,6 +111,7 @@ final class CreateAdminUserCommand extends AbstractAdminUserCommand
|
||||||
return $adminUserData;
|
return $adminUserData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @param array<array-key, mixed> $adminUserData */
|
||||||
private function showSummary(array $adminUserData): void
|
private function showSummary(array $adminUserData): void
|
||||||
{
|
{
|
||||||
$this->io->writeln('The following admin user will be created:');
|
$this->io->writeln('The following admin user will be created:');
|
||||||
|
|
|
||||||
|
|
@ -11,24 +11,13 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\AdminBundle\Command;
|
namespace Sylius\Bundle\AdminBundle\Command\Factory;
|
||||||
|
|
||||||
use Symfony\Component\Console\Command\Command;
|
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
|
||||||
use Symfony\Component\Console\Question\Question;
|
use Symfony\Component\Console\Question\Question;
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
|
||||||
|
|
||||||
abstract class AbstractAdminUserCommand extends Command
|
final class QuestionFactory implements QuestionFactoryInterface
|
||||||
{
|
{
|
||||||
protected SymfonyStyle $io;
|
public function createEmail(): Question
|
||||||
|
|
||||||
protected function initialize(InputInterface $input, OutputInterface $output): void
|
|
||||||
{
|
|
||||||
$this->io = new SymfonyStyle($input, $output);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function createEmailQuestion(): Question
|
|
||||||
{
|
{
|
||||||
$question = new Question('Email');
|
$question = new Question('Email');
|
||||||
$question->setValidator(function (?string $email) {
|
$question->setValidator(function (?string $email) {
|
||||||
|
|
@ -43,7 +32,7 @@ abstract class AbstractAdminUserCommand extends Command
|
||||||
return $question;
|
return $question;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createQuestionWithNonBlankValidator(string $askedQuestion, bool $hidden = false): Question
|
public function createWithNotNullValidator(string $askedQuestion, bool $hidden = false): Question
|
||||||
{
|
{
|
||||||
$question = new Question($askedQuestion);
|
$question = new Question($askedQuestion);
|
||||||
$question->setValidator(function (?string $value) {
|
$question->setValidator(function (?string $value) {
|
||||||
|
|
@ -54,10 +43,7 @@ abstract class AbstractAdminUserCommand extends Command
|
||||||
return $value;
|
return $value;
|
||||||
});
|
});
|
||||||
$question->setMaxAttempts(3);
|
$question->setMaxAttempts(3);
|
||||||
|
$question->setHidden($hidden);
|
||||||
if ($hidden) {
|
|
||||||
$question->setHidden(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $question;
|
return $question;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\AdminBundle\Command\Factory;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Question\Question;
|
||||||
|
|
||||||
|
interface QuestionFactoryInterface
|
||||||
|
{
|
||||||
|
public function createEmail(): Question;
|
||||||
|
|
||||||
|
public function createWithNotNullValidator(string $askedQuestion, bool $hidden = false): Question;
|
||||||
|
}
|
||||||
|
|
@ -38,12 +38,14 @@
|
||||||
<service id="Sylius\Bundle\AdminBundle\Command\CreateAdminUserCommand">
|
<service id="Sylius\Bundle\AdminBundle\Command\CreateAdminUserCommand">
|
||||||
<argument type="service" id="sylius.command_bus" />
|
<argument type="service" id="sylius.command_bus" />
|
||||||
<argument>%sylius_locale.locale%</argument>
|
<argument>%sylius_locale.locale%</argument>
|
||||||
|
<argument type="service" id="sylius.command_factory.question" />
|
||||||
<tag name="console.command" />
|
<tag name="console.command" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="Sylius\Bundle\AdminBundle\Command\ChangeAdminUserPasswordCommand">
|
<service id="Sylius\Bundle\AdminBundle\Command\ChangeAdminUserPasswordCommand">
|
||||||
<argument type="service" id="sylius.repository.admin_user" />
|
<argument type="service" id="sylius.repository.admin_user" />
|
||||||
<argument type="service" id="sylius.security.password_updater" />
|
<argument type="service" id="sylius.security.password_updater" />
|
||||||
|
<argument type="service" id="sylius.command_factory.question" />
|
||||||
<tag name="console.command" />
|
<tag name="console.command" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
|
@ -57,6 +59,10 @@
|
||||||
<tag name="messenger.message_handler" bus="sylius_default.bus" />
|
<tag name="messenger.message_handler" bus="sylius_default.bus" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="sylius.command_factory.question" class="Sylius\Bundle\AdminBundle\Command\Factory\QuestionFactory" />
|
||||||
|
|
||||||
|
<service id="Sylius\Bundle\AdminBundle\Command\Factory\QuestionFactoryInterface" alias="sylius.command_factory.question" />
|
||||||
|
|
||||||
<service id="sylius.context.locale.admin_based" class="Sylius\Bundle\AdminBundle\Context\AdminBasedLocaleContext">
|
<service id="sylius.context.locale.admin_based" class="Sylius\Bundle\AdminBundle\Context\AdminBasedLocaleContext">
|
||||||
<argument type="service" id="security.token_storage" />
|
<argument type="service" id="security.token_storage" />
|
||||||
<tag name="sylius.context.locale" priority="128" />
|
<tag name="sylius.context.locale" priority="128" />
|
||||||
|
|
|
||||||
|
|
@ -13,23 +13,31 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\AdminBundle\Tests\Command;
|
namespace Sylius\Bundle\AdminBundle\Tests\Command;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Sylius\Bundle\AdminBundle\Command\ChangeAdminUserPasswordCommand;
|
use Sylius\Bundle\AdminBundle\Command\ChangeAdminUserPasswordCommand;
|
||||||
|
use Sylius\Bundle\AdminBundle\Command\Factory\QuestionFactoryInterface;
|
||||||
use Sylius\Component\Core\Model\AdminUser;
|
use Sylius\Component\Core\Model\AdminUser;
|
||||||
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
||||||
use Sylius\Component\User\Security\PasswordUpdaterInterface;
|
use Sylius\Component\User\Security\PasswordUpdaterInterface;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Question\Question;
|
||||||
use Symfony\Component\Console\Tester\CommandTester;
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
|
|
||||||
final class ChangeAdminUserPasswordCommandTest extends TestCase
|
final class ChangeAdminUserPasswordCommandTest extends TestCase
|
||||||
{
|
{
|
||||||
private const EMAIL = 'sylius@example.com';
|
private const EMAIL = 'sylius@example.com';
|
||||||
|
|
||||||
private const PASSWORD = 'Password';
|
private const PASSWORD = 'Password';
|
||||||
|
|
||||||
private CommandTester $command;
|
private CommandTester $command;
|
||||||
|
|
||||||
private UserRepositoryInterface $userRepository;
|
private UserRepositoryInterface $userRepository;
|
||||||
|
|
||||||
private PasswordUpdaterInterface $passwordUpdater;
|
private PasswordUpdaterInterface $passwordUpdater;
|
||||||
|
|
||||||
|
private QuestionFactoryInterface $questionFactory;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
@ -38,8 +46,10 @@ final class ChangeAdminUserPasswordCommandTest extends TestCase
|
||||||
|
|
||||||
$this->passwordUpdater = $this->createMock(PasswordUpdaterInterface::class);
|
$this->passwordUpdater = $this->createMock(PasswordUpdaterInterface::class);
|
||||||
|
|
||||||
|
$this->questionFactory = $this->createMock(QuestionFactoryInterface::class);
|
||||||
|
|
||||||
$this->command = new CommandTester(
|
$this->command = new CommandTester(
|
||||||
new ChangeAdminUserPasswordCommand($this->userRepository, $this->passwordUpdater),
|
new ChangeAdminUserPasswordCommand($this->userRepository, $this->passwordUpdater, $this->questionFactory),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,6 +64,12 @@ final class ChangeAdminUserPasswordCommandTest extends TestCase
|
||||||
/** @test */
|
/** @test */
|
||||||
public function it_does_not_change_password_when_admin_user_is_not_found(): void
|
public function it_does_not_change_password_when_admin_user_is_not_found(): void
|
||||||
{
|
{
|
||||||
|
$this
|
||||||
|
->questionFactory
|
||||||
|
->expects($this->once())
|
||||||
|
->method('createEmail')
|
||||||
|
->willReturn($this->createQuestionMock('Email'));
|
||||||
|
|
||||||
$this
|
$this
|
||||||
->userRepository
|
->userRepository
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
|
|
@ -74,7 +90,24 @@ final class ChangeAdminUserPasswordCommandTest extends TestCase
|
||||||
/** @test */
|
/** @test */
|
||||||
public function it_changes_password_for_existing_admin_user(): void
|
public function it_changes_password_for_existing_admin_user(): void
|
||||||
{
|
{
|
||||||
$adminUser = new AdminUser();
|
$adminUser = $this->createMock(AdminUser::class);
|
||||||
|
$adminUser
|
||||||
|
->expects($this->once())
|
||||||
|
->method('setPlainPassword')
|
||||||
|
->with(self::PASSWORD);
|
||||||
|
|
||||||
|
$this
|
||||||
|
->questionFactory
|
||||||
|
->expects($this->once())
|
||||||
|
->method('createEmail')
|
||||||
|
->willReturn($this->createQuestionMock('Email'));
|
||||||
|
|
||||||
|
$this
|
||||||
|
->questionFactory
|
||||||
|
->expects($this->once())
|
||||||
|
->method('createWithNotNullValidator')
|
||||||
|
->with('New password', true)
|
||||||
|
->willReturn($this->createQuestionMock('New password'));
|
||||||
|
|
||||||
$this
|
$this
|
||||||
->userRepository
|
->userRepository
|
||||||
|
|
@ -104,4 +137,17 @@ final class ChangeAdminUserPasswordCommandTest extends TestCase
|
||||||
|
|
||||||
self::assertSame(Command::SUCCESS, $this->command->getStatusCode());
|
self::assertSame(Command::SUCCESS, $this->command->getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createQuestionMock(string $askedQuestion): MockObject
|
||||||
|
{
|
||||||
|
$question = $this->createMock(Question::class);
|
||||||
|
$question
|
||||||
|
->method('isTrimmable')
|
||||||
|
->willReturn(true);
|
||||||
|
$question
|
||||||
|
->method('getQuestion')
|
||||||
|
->willReturn($askedQuestion);
|
||||||
|
|
||||||
|
return $question;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,11 @@ namespace Sylius\Bundle\AdminBundle\Tests\Command;
|
||||||
use PHPUnit\Framework\MockObject\MockObject;
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Sylius\Bundle\AdminBundle\Command\CreateAdminUserCommand;
|
use Sylius\Bundle\AdminBundle\Command\CreateAdminUserCommand;
|
||||||
|
use Sylius\Bundle\AdminBundle\Command\Factory\QuestionFactoryInterface;
|
||||||
use Sylius\Bundle\AdminBundle\Exception\CreateAdminUserFailedException;
|
use Sylius\Bundle\AdminBundle\Exception\CreateAdminUserFailedException;
|
||||||
use Sylius\Bundle\AdminBundle\Message\CreateAdminUser;
|
use Sylius\Bundle\AdminBundle\Message\CreateAdminUser;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Question\Question;
|
||||||
use Symfony\Component\Console\Tester\CommandTester;
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
use Symfony\Component\Messenger\Envelope;
|
use Symfony\Component\Messenger\Envelope;
|
||||||
use Symfony\Component\Messenger\Exception\HandlerFailedException;
|
use Symfony\Component\Messenger\Exception\HandlerFailedException;
|
||||||
|
|
@ -47,83 +49,53 @@ final class CreateAdminUserCommandTest extends TestCase
|
||||||
|
|
||||||
private MockObject $messageBus;
|
private MockObject $messageBus;
|
||||||
|
|
||||||
|
private QuestionFactoryInterface $questionFactory;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->messageBus = $this->createMock(MessageBusInterface::class);
|
$this->messageBus = $this->createMock(MessageBusInterface::class);
|
||||||
|
|
||||||
|
$this->questionFactory = $this->createMock(QuestionFactoryInterface::class);
|
||||||
|
|
||||||
$this->command = new CommandTester(
|
$this->command = new CommandTester(
|
||||||
new CreateAdminUserCommand($this->messageBus, self::LOCALE_CODE),
|
new CreateAdminUserCommand($this->messageBus, self::LOCALE_CODE, $this->questionFactory),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function it_creates_an_admin_user_if_accepted_in_the_summary(): void
|
public function it_creates_an_admin_user_if_accepted_in_the_summary(): void
|
||||||
{
|
{
|
||||||
$adminUserData = $this->getDefaultAdminUserDataSetup();
|
$this
|
||||||
|
->questionFactory
|
||||||
|
->expects($this->once())
|
||||||
|
->method('createEmail')
|
||||||
|
->willReturn($this->createQuestionMock('Email'));
|
||||||
|
|
||||||
$commandInputs = $this->getDefaultCommandInputsSetup();
|
$this
|
||||||
|
->questionFactory
|
||||||
|
->expects($this->exactly(2))
|
||||||
|
->method('createWithNotNullValidator')
|
||||||
|
->willReturnOnConsecutiveCalls(
|
||||||
|
$this->createQuestionMock('Username'),
|
||||||
|
$this->createQuestionMock('New password'),
|
||||||
|
);
|
||||||
|
|
||||||
$this->assertSuccessfulCommandExecution($adminUserData, $commandInputs);
|
$this->command->setInputs($this->getDefaultCommandInputsSetup());
|
||||||
}
|
|
||||||
|
|
||||||
/** @test */
|
$message = new CreateAdminUser(...array_values($this->getDefaultAdminUserDataSetup()));
|
||||||
public function it_has_set_up_three_attempts_to_write_a_valid_email(): void
|
|
||||||
{
|
|
||||||
$adminUserData = $this->getDefaultAdminUserDataSetup();
|
|
||||||
|
|
||||||
$commandInputs = array_merge(
|
$this->messageBus->expects($this->once())
|
||||||
[
|
->method('dispatch')
|
||||||
'first_email_entry' => 'invalid-email',
|
->with($message)
|
||||||
'second_email_entry' => 'still-invalid-email',
|
->willReturn(new Envelope($message, [new HandledStamp(self::anything(), 'handler')]))
|
||||||
],
|
;
|
||||||
$this->getDefaultCommandInputsSetup(),
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertSuccessfulCommandExecution($adminUserData, $commandInputs);
|
$this->command->execute([]);
|
||||||
}
|
|
||||||
|
|
||||||
/** @test */
|
$this->command->assertCommandIsSuccessful();
|
||||||
public function it_has_set_up_three_attempts_to_write_a_non_blank_username(): void
|
self::assertStringContainsString('Admin user has been successfully created.', $this->command->getDisplay());
|
||||||
{
|
|
||||||
$adminUserData = $this->getDefaultAdminUserDataSetup();
|
|
||||||
|
|
||||||
$commandInputs = [
|
|
||||||
'email' => self::EMAIL,
|
|
||||||
'first_username_entry' => '',
|
|
||||||
'second_username_entry' => '',
|
|
||||||
'username' => self::USERNAME,
|
|
||||||
'first_name' => self::FIRST_NAME,
|
|
||||||
'last_name' => self::LAST_NAME,
|
|
||||||
'password' => self::PASSWORD,
|
|
||||||
'locale_code' => self::LOCALE_CODE,
|
|
||||||
'admin_user_enabled' => self::YES,
|
|
||||||
'creation_confirmation' => self::YES,
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->assertSuccessfulCommandExecution($adminUserData, $commandInputs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @test */
|
|
||||||
public function it_has_set_up_three_attempts_to_write_a_non_blank_password(): void
|
|
||||||
{
|
|
||||||
$adminUserData = $this->getDefaultAdminUserDataSetup();
|
|
||||||
|
|
||||||
$commandInputs = [
|
|
||||||
'email' => self::EMAIL,
|
|
||||||
'username' => self::USERNAME,
|
|
||||||
'first_name' => self::FIRST_NAME,
|
|
||||||
'last_name' => self::LAST_NAME,
|
|
||||||
'first_password_entry' => '',
|
|
||||||
'second_password_entry' => '',
|
|
||||||
'password' => self::PASSWORD,
|
|
||||||
'locale_code' => self::LOCALE_CODE,
|
|
||||||
'admin_user_enabled' => self::YES,
|
|
||||||
'creation_confirmation' => self::YES,
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->assertSuccessfulCommandExecution($adminUserData, $commandInputs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
|
|
@ -140,6 +112,21 @@ final class CreateAdminUserCommandTest extends TestCase
|
||||||
'creation_confirmation' => self::NO,
|
'creation_confirmation' => self::NO,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this
|
||||||
|
->questionFactory
|
||||||
|
->expects($this->once())
|
||||||
|
->method('createEmail')
|
||||||
|
->willReturn($this->createQuestionMock('Email'));
|
||||||
|
|
||||||
|
$this
|
||||||
|
->questionFactory
|
||||||
|
->expects($this->exactly(2))
|
||||||
|
->method('createWithNotNullValidator')
|
||||||
|
->willReturnOnConsecutiveCalls(
|
||||||
|
$this->createQuestionMock('Username'),
|
||||||
|
$this->createQuestionMock('New password'),
|
||||||
|
);
|
||||||
|
|
||||||
$this->messageBus->expects($this->never())->method('dispatch');
|
$this->messageBus->expects($this->never())->method('dispatch');
|
||||||
|
|
||||||
self::assertSame(Command::INVALID, $this->command->execute([]));
|
self::assertSame(Command::INVALID, $this->command->execute([]));
|
||||||
|
|
@ -155,6 +142,21 @@ final class CreateAdminUserCommandTest extends TestCase
|
||||||
|
|
||||||
$message = new CreateAdminUser(...array_values($adminUserData));
|
$message = new CreateAdminUser(...array_values($adminUserData));
|
||||||
|
|
||||||
|
$this
|
||||||
|
->questionFactory
|
||||||
|
->expects($this->once())
|
||||||
|
->method('createEmail')
|
||||||
|
->willReturn($this->createQuestionMock('Email'));
|
||||||
|
|
||||||
|
$this
|
||||||
|
->questionFactory
|
||||||
|
->expects($this->exactly(2))
|
||||||
|
->method('createWithNotNullValidator')
|
||||||
|
->willReturnOnConsecutiveCalls(
|
||||||
|
$this->createQuestionMock('Username'),
|
||||||
|
$this->createQuestionMock('New password'),
|
||||||
|
);
|
||||||
|
|
||||||
$this->messageBus->expects($this->once())
|
$this->messageBus->expects($this->once())
|
||||||
->method('dispatch')
|
->method('dispatch')
|
||||||
->with($message)
|
->with($message)
|
||||||
|
|
@ -175,24 +177,6 @@ final class CreateAdminUserCommandTest extends TestCase
|
||||||
self::assertSame(Command::FAILURE, $this->command->execute([], ['interactive' => false]));
|
self::assertSame(Command::FAILURE, $this->command->execute([], ['interactive' => false]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function assertSuccessfulCommandExecution(array $adminUserData, array $commandInputs): void
|
|
||||||
{
|
|
||||||
$this->command->setInputs($commandInputs);
|
|
||||||
|
|
||||||
$message = new CreateAdminUser(...array_values($adminUserData));
|
|
||||||
|
|
||||||
$this->messageBus->expects($this->once())
|
|
||||||
->method('dispatch')
|
|
||||||
->with($message)
|
|
||||||
->willReturn(new Envelope($message, [new HandledStamp(self::anything(), 'handler')]))
|
|
||||||
;
|
|
||||||
|
|
||||||
$this->command->execute([]);
|
|
||||||
|
|
||||||
$this->command->assertCommandIsSuccessful();
|
|
||||||
self::assertStringContainsString('Admin user has been successfully created.', $this->command->getDisplay());
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getDefaultCommandInputsSetup(): array
|
private function getDefaultCommandInputsSetup(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
@ -219,4 +203,17 @@ final class CreateAdminUserCommandTest extends TestCase
|
||||||
'admin_user_enabled' => true,
|
'admin_user_enabled' => true,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createQuestionMock(string $askedQuestion): MockObject
|
||||||
|
{
|
||||||
|
$question = $this->createMock(Question::class);
|
||||||
|
$question
|
||||||
|
->method('isTrimmable')
|
||||||
|
->willReturn(true);
|
||||||
|
$question
|
||||||
|
->method('getQuestion')
|
||||||
|
->willReturn($askedQuestion);
|
||||||
|
|
||||||
|
return $question;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?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\Bundle\AdminBundle\Tests\Command\Factory;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Sylius\Bundle\AdminBundle\Command\Factory\QuestionFactory;
|
||||||
|
|
||||||
|
final class QuestionFactoryTest extends TestCase
|
||||||
|
{
|
||||||
|
/** @test */
|
||||||
|
public function it_creates_email_question(): void
|
||||||
|
{
|
||||||
|
$questionFactory = new QuestionFactory();
|
||||||
|
$question = $questionFactory->createEmail();
|
||||||
|
|
||||||
|
$this->assertSame('Email', $question->getQuestion());
|
||||||
|
$this->assertSame(3, $question->getMaxAttempts());
|
||||||
|
$this->assertEquals('test@example.com', $question->getValidator()('test@example.com'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_creates_email_question_with_invalid_email(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('The email address provided is invalid. Please try again.');
|
||||||
|
|
||||||
|
$questionFactory = new QuestionFactory();
|
||||||
|
$emailQuestion = $questionFactory->createEmail();
|
||||||
|
|
||||||
|
$emailQuestion->getValidator()('invalid-email');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_creates_email_question_with_null_email(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('The email address provided is invalid. Please try again.');
|
||||||
|
|
||||||
|
$questionFactory = new QuestionFactory();
|
||||||
|
$emailQuestion = $questionFactory->createEmail();
|
||||||
|
|
||||||
|
$emailQuestion->getValidator()(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_creates_question_with_not_null_validator(): void
|
||||||
|
{
|
||||||
|
$questionFactory = new QuestionFactory();
|
||||||
|
$question = $questionFactory->createWithNotNullValidator('Question');
|
||||||
|
|
||||||
|
$this->assertSame('Question', $question->getQuestion());
|
||||||
|
$this->assertSame(3, $question->getMaxAttempts());
|
||||||
|
$this->assertEquals('test', $question->getValidator()('test'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_creates_question_with_not_null_validator_with_null_value(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('The value cannot be empty.');
|
||||||
|
|
||||||
|
$questionFactory = new QuestionFactory();
|
||||||
|
$question = $questionFactory->createWithNotNullValidator('Question');
|
||||||
|
|
||||||
|
$question->getValidator()(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue