From a08c74675005a170a7b5e35e4c3a78967cd9c951 Mon Sep 17 00:00:00 2001 From: David Maicher Date: Thu, 23 Feb 2017 19:21:00 +0100 Subject: [PATCH 1/4] add simple test for AddUserCommand --- .../AppBundle/Command/AddUserCommandTest.php | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 tests/AppBundle/Command/AddUserCommandTest.php diff --git a/tests/AppBundle/Command/AddUserCommandTest.php b/tests/AppBundle/Command/AddUserCommandTest.php new file mode 100644 index 000000000..ee5cb4b9e --- /dev/null +++ b/tests/AppBundle/Command/AddUserCommandTest.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Tests\Command; + +use AppBundle\Command\AddUserCommand; +use AppBundle\Entity\User; +use Symfony\Bundle\FrameworkBundle\Console\Application; +use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use Symfony\Component\Console\Tester\CommandTester; + +class AddUserCommandTest extends KernelTestCase +{ + private function executeCommand(array $inputArgs, array $interactiveInputs = []) + { + self::bootKernel(); + + $command = new AddUserCommand(); + $command->setApplication(new Application(self::$kernel)); + + $commandTester = new CommandTester($command); + $commandTester->setInputs($interactiveInputs); + $commandTester->execute($inputArgs); + } + + /** + * @param bool $isAdmin + */ + private function assertUserCreated($isAdmin) + { + $container = self::$kernel->getContainer(); + + /** @var User $user */ + $user = $container->get('doctrine')->getRepository(User::class)->findOneByEmail('chuck@norris.com'); + $this->assertNotNull($user); + + $this->assertSame('Chuck Norris', $user->getFullName()); + $this->assertSame('chuck_norris', $user->getUsername()); + $this->assertTrue($container->get('security.password_encoder')->isPasswordValid($user, 'foobar')); + $this->assertSame($isAdmin ? ['ROLE_ADMIN'] : ['ROLE_USER'], $user->getRoles()); + } + + /** + * @dataProvider isAdminDataProvider + * + * @param bool $isAdmin + */ + public function testCreateUserNonInteractive($isAdmin) + { + $input = [ + 'username' => 'chuck_norris', + 'password' => 'foobar', + 'email' => 'chuck@norris.com', + 'full-name' => 'Chuck Norris', + ]; + + if ($isAdmin) { + $input['--admin'] = 1; + } + + $this->executeCommand($input); + $this->assertUserCreated($isAdmin); + } + + /** + * @dataProvider isAdminDataProvider + * + * @param bool $isAdmin + */ + public function testCreateUserInteractive($isAdmin) + { + // see https://symfony.com/doc/current/components/console/helpers/questionhelper.html#testing-a-command-that-expects-input + $this->executeCommand($isAdmin ? ['--admin' => 1] : [], [ + 'chuck_norris', + 'foobar', + 'chuck@norris.com', + 'Chuck Norris', + ]); + $this->assertUserCreated($isAdmin); + } + + public function isAdminDataProvider() + { + yield [true]; + yield [false]; + } +} From 3e15d59b674cb841fe52f9ba44cdb128c48bbec0 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sun, 12 Mar 2017 16:18:38 +0100 Subject: [PATCH 2/4] Refactored the code and added some help notes --- .../AppBundle/Command/AddUserCommandTest.php | 110 ++++++++++-------- 1 file changed, 64 insertions(+), 46 deletions(-) diff --git a/tests/AppBundle/Command/AddUserCommandTest.php b/tests/AppBundle/Command/AddUserCommandTest.php index ee5cb4b9e..9ae0e411f 100644 --- a/tests/AppBundle/Command/AddUserCommandTest.php +++ b/tests/AppBundle/Command/AddUserCommandTest.php @@ -19,77 +19,95 @@ class AddUserCommandTest extends KernelTestCase { - private function executeCommand(array $inputArgs, array $interactiveInputs = []) - { - self::bootKernel(); - - $command = new AddUserCommand(); - $command->setApplication(new Application(self::$kernel)); - - $commandTester = new CommandTester($command); - $commandTester->setInputs($interactiveInputs); - $commandTester->execute($inputArgs); - } - - /** - * @param bool $isAdmin - */ - private function assertUserCreated($isAdmin) - { - $container = self::$kernel->getContainer(); - - /** @var User $user */ - $user = $container->get('doctrine')->getRepository(User::class)->findOneByEmail('chuck@norris.com'); - $this->assertNotNull($user); - - $this->assertSame('Chuck Norris', $user->getFullName()); - $this->assertSame('chuck_norris', $user->getUsername()); - $this->assertTrue($container->get('security.password_encoder')->isPasswordValid($user, 'foobar')); - $this->assertSame($isAdmin ? ['ROLE_ADMIN'] : ['ROLE_USER'], $user->getRoles()); - } + private $userData = [ + 'username' => 'chuck_norris', + 'password' => 'foobar', + 'email' => 'chuck@norris.com', + 'full-name' => 'Chuck Norris', + ]; /** * @dataProvider isAdminDataProvider * - * @param bool $isAdmin + * This test provides all the arguments required by the command, so the + * command runs non-interactively and it won't ask for any argument. */ public function testCreateUserNonInteractive($isAdmin) { - $input = [ - 'username' => 'chuck_norris', - 'password' => 'foobar', - 'email' => 'chuck@norris.com', - 'full-name' => 'Chuck Norris', - ]; - + $input = $this->userData; if ($isAdmin) { $input['--admin'] = 1; } - $this->executeCommand($input); + $this->assertUserCreated($isAdmin); } /** * @dataProvider isAdminDataProvider * - * @param bool $isAdmin + * This test doesn't provide all the arguments required by the command, so + * the command runs interactively and it will ask for the value of the missing + * arguments. + * See https://symfony.com/doc/current/components/console/helpers/questionhelper.html#testing-a-command-that-expects-input */ public function testCreateUserInteractive($isAdmin) { - // see https://symfony.com/doc/current/components/console/helpers/questionhelper.html#testing-a-command-that-expects-input - $this->executeCommand($isAdmin ? ['--admin' => 1] : [], [ - 'chuck_norris', - 'foobar', - 'chuck@norris.com', - 'Chuck Norris', - ]); + $this->executeCommand( + // these are the arguments (only 1 is passed, the rest are missing) + $isAdmin ? ['--admin' => 1] : [], + // these are the responses given to the questions asked by the command + // to get the value of the missing required arguments + array_values($this->userdata) + ); + $this->assertUserCreated($isAdmin); } + /** + * This is used to execute the same test twice: first for normal users + * (isAdmin = false) and then for admin users (isAdmin = true). + */ public function isAdminDataProvider() { - yield [true]; yield [false]; + yield [true]; + } + + /** + * This helper method checks that the user was correctly created and saved + * it in the database. + */ + private function assertUserCreated($isAdmin) + { + $container = self::$kernel->getContainer(); + + /** @var User $user */ + $user = $container->get('doctrine')->getRepository(User::class)->findOneByEmail($this->userData['email']); + $this->assertNotNull($user); + + $this->assertSame($this->userData['full-name'], $user->getFullName()); + $this->assertSame($this->userData['username'], $user->getUsername()); + $this->assertTrue($container->get('security.password_encoder')->isPasswordValid($user, $this->userData['password'])); + $this->assertSame($isAdmin ? ['ROLE_ADMIN'] : ['ROLE_USER'], $user->getRoles()); + } + + /** + * This helper method abstracts the boilerplate code needed to test the + * execution of a command. When the command is executed non-interactively, + * all its arguments are passed in $arguments. If some needed argument is + * missing, the command will ask for it interactively. Use the $inputs + * argument to define the answers to provide to the command. + */ + private function executeCommand(array $arguments, array $inputs = []) + { + self::bootKernel(); + + $command = new AddUserCommand(); + $command->setApplication(new Application(self::$kernel)); + + $commandTester = new CommandTester($command); + $commandTester->setInputs($inputs); + $commandTester->execute($arguments); } } From c1d23f90d052f20a10c38b471d8ca0aec1e96bbd Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sun, 12 Mar 2017 17:10:30 +0100 Subject: [PATCH 3/4] Fixed a variable name --- tests/AppBundle/Command/AddUserCommandTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/AppBundle/Command/AddUserCommandTest.php b/tests/AppBundle/Command/AddUserCommandTest.php index 9ae0e411f..c4a3d10b2 100644 --- a/tests/AppBundle/Command/AddUserCommandTest.php +++ b/tests/AppBundle/Command/AddUserCommandTest.php @@ -58,7 +58,7 @@ public function testCreateUserInteractive($isAdmin) $isAdmin ? ['--admin' => 1] : [], // these are the responses given to the questions asked by the command // to get the value of the missing required arguments - array_values($this->userdata) + array_values($this->userData) ); $this->assertUserCreated($isAdmin); From 774adca218e95d0a68f5ac1d41948dfd927899d2 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sun, 12 Mar 2017 17:14:59 +0100 Subject: [PATCH 4/4] Improved the PHPdoc of some methods --- tests/AppBundle/Command/AddUserCommandTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/AppBundle/Command/AddUserCommandTest.php b/tests/AppBundle/Command/AddUserCommandTest.php index c4a3d10b2..38335e9e6 100644 --- a/tests/AppBundle/Command/AddUserCommandTest.php +++ b/tests/AppBundle/Command/AddUserCommandTest.php @@ -76,7 +76,7 @@ public function isAdminDataProvider() /** * This helper method checks that the user was correctly created and saved - * it in the database. + * in the database. */ private function assertUserCreated($isAdmin) { @@ -94,10 +94,10 @@ private function assertUserCreated($isAdmin) /** * This helper method abstracts the boilerplate code needed to test the - * execution of a command. When the command is executed non-interactively, - * all its arguments are passed in $arguments. If some needed argument is - * missing, the command will ask for it interactively. Use the $inputs - * argument to define the answers to provide to the command. + * execution of a command. + * + * @param array $arguments All the arguments passed when executing the command + * @param array $inputs The (optional) answers given to the command when it asks for the value of the missing arguments */ private function executeCommand(array $arguments, array $inputs = []) {