Skip to content

Instantly share code, notes, and snippets.

@havvg
Created May 30, 2015 10:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save havvg/92c9c946242c0628a55e to your computer and use it in GitHub Desktop.
Save havvg/92c9c946242c0628a55e to your computer and use it in GitHub Desktop.
BDD: Create User Command
<?php
namespace Trnd\Behat\Context\Console;
use Behat\Behat\Context\Context;
use Mockery\MockInterface;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\HttpKernel\KernelInterface;
final class CommandContext implements Context
{
/**
* @var Application
*/
private $application;
/**
* @var Command
*/
private $command;
/**
* @var CommandTester
*/
private $tester;
/**
* @var QuestionHelper|MockInterface
*/
private $questionHelper;
/**
* Constructor.
*
* @param KernelInterface $kernel
*/
public function __construct(KernelInterface $kernel)
{
$this->application = new Application($kernel);
$this->registerCommands($kernel);
}
/**
* @When /^I run "(?P<command>(?:[^"]|\\")*)" command$/
*/
public function execute($command)
{
$this->command = $this->application->find($command);
$this->tester = new CommandTester($this->command);
}
/**
* @When /^I answer "(?P<question>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/
*/
public function answer($question, $value)
{
if (null === $this->questionHelper) {
$this->questionHelper = \Mockery::mock(QuestionHelper::class);
// Being called when setting helper on helper set.
$this->questionHelper->shouldReceive('getName')->andReturn('question');
$this->questionHelper->shouldReceive('setHelperSet');
$this->command->getHelperSet()->set($this->questionHelper, 'question');
}
$this->questionHelper
->shouldReceive('ask')
->with(\Mockery::type(InputInterface::class), \Mockery::type(OutputInterface::class), \Mockery::on(function ($actual) use ($question) {
if (!$actual instanceof Question) {
return false;
}
$phrase = $actual->getQuestion();
if ($phrase === $question) {
return true;
}
if ($phrase === $question.': ') {
return true;
}
$phrase = strip_tags($phrase);
if ($phrase === $question) {
return true;
}
if ($phrase === $question.': ') {
return true;
}
return false;
}))
->once()
->andReturn($value)
;
}
/**
* @Then /^the command should succeed$/
*/
public function assertCommandSucceeded()
{
$exitCode = $this->tester->execute([
'command' => $this->command->getName(),
]);
\PHPUnit_Framework_Assert::assertEquals(0, $exitCode);
}
/**
* Registers all commands to the application.
*
* @see Symfony\Bundle\FrameworkBundle\Console\Application::registerCommands
*
* @param KernelInterface $kernel
*/
private function registerCommands(KernelInterface $kernel)
{
$container = $kernel->getContainer();
foreach ($kernel->getBundles() as $bundle) {
if ($bundle instanceof Bundle) {
$bundle->registerCommands($this->application);
}
}
if ($container->hasParameter('console.command.ids')) {
foreach ($container->getParameter('console.command.ids') as $id) {
$command = $container->get($id);
if ($command instanceof Command) {
$this->application->add($command);
}
}
}
}
}
@cli
@orm
Feature: Creating a user on the command line
In order to bootstrap the application with user accounts
As a developer
I need to be able to create users using the command line
Scenario: Creating a new user on the command line
When I run "user:create" command
And I answer "Please choose a username" with "havvg"
And I answer "Please choose an email address" with "tuebernickel@gmail.com"
And I answer "Please choose a password" with "tester"
Then the command should succeed
And I should be able to login with email "tuebernickel@gmail.com" and password "tester"
<?php
namespace Trnd\Bundle\AppBundle\Command\User;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Trnd\Component\CommandBus\CommandBusInterface;
use Trnd\Domain\User\Command\RegisterUserCommand;
class CreateCommand extends Command
{
/**
* @var CommandBusInterface
*/
private $commandBus;
/**
* Constructor.
*
* @param CommandBusInterface $commandBus
*/
public function __construct(CommandBusInterface $commandBus)
{
$this->commandBus = $commandBus;
parent::__construct();
}
protected function configure()
{
$this->setName('user:create');
$this->setDescription('Creates a new user login for the application.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$question = $this->getHelper('question');
$username = $question->ask($input, $output, new Question('Please choose a <info>username</info>: '));
$email = $question->ask($input, $output, new Question('Please choose an <info>email address</info>: '));
$password = $question->ask($input, $output, (new Question('Please choose a <info>password</info>: '))->setHidden(true));
$this->commandBus->dispatch(new RegisterUserCommand($username, $email, $password));
}
}
<?php
namespace Trnd\Behat\Context\Security;
trait FirewallDictionary
{
/**
* @Then /^I should be able to login with email "(?P<email>(?:[^"]|\\")*)" and password "(?P<password>(?:[^"]|\\")*)"$/
*/
public function assertLogin($email, $password)
{
$this->visit('/login');
$this->fillField('E-Mail', $email);
$this->fillField('Password', $password);
$this->pressButton('Signin');
$this->assertPageAddress('/');
$this->assertResponseStatus(200);
}
/**
* Opens specified page.
*
* @param string $page
*/
abstract public function visit($page);
/**
* Fills in form field with specified id|name|label|value.
*
* @param string $field
* @param string $value
*/
abstract public function fillField($field, $value);
/**
* Presses button with specified id|name|title|alt|value.
*
* @param string $button
*/
abstract public function pressButton($button);
/**
* Checks, that current page PATH is equal to specified.
*
* @param string $page
*/
abstract public function assertPageAddress($page);
/**
* Checks, that current page response status is equal to specified.
*
* @param int $code
*/
abstract public function assertResponseStatus($code);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment