Skip to content

Commit

Permalink
Refactored the code and added some help notes
Browse files Browse the repository at this point in the history
  • Loading branch information
javiereguiluz committed Mar 12, 2017
1 parent a08c746 commit 3e15d59
Showing 1 changed file with 64 additions and 46 deletions.
110 changes: 64 additions & 46 deletions tests/AppBundle/Command/AddUserCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

0 comments on commit 3e15d59

Please sign in to comment.