Just recently I got into testing pieces of a symfony application... For starters, I thought I would try and test a login form that should grant access to a private area.
The users for this private area are correctly persisted to the database and have been tried on the development enviroment. The config_test.yml file goes like this:
imports:
- { resource: config_dev.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
profiler:
collect: false
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
disable_delivery: true
So it should use the database configuration exposed in config_dev.yml.
There's nothing special about my user provider:
providers:
users:
entity:
class: MyBundle:User
property: login
As requested in the comments section, here's the security info. Please note that all namespaces, class names and relevant data have been changed, as I can't publish the real thing. If you spot any mistake it must have been me changing the relevant code.
security:
encoders:
MyBundle\Entity\User:
algorithm: bcrypt
cost: 12
role_hierarchy:
ROLE_CUSER: ROLE_USER
ROLE_CUSER_A: ROLE_CUSER
ROLE_CUSER_B: ROLE_CUSER
ROLE_CUSER_C: ROLE_CUSER
ROLE_CUSER_D: ROLE_CUSER
ROLE_CUSER_E: ROLE_CUSER
providers:
users:
entity:
class: MyBundle:User
property: login
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
user_tools_login_firewall:
pattern: ^/user_tools/login$
anonymous: ~
user_tools:
pattern: ^/user_tools
http_basic: ~
provider: users
form_login:
login_path: /user_tools/login
check_path: /user_tools/login_check
logout:
path: /user_tools/logout
target: /user_tools/home
invalidate_session: false
access_control:
- {path: /user_tools/login, roles: IS_AUTHENTICATED_ANONYMOUSLY}
- {path: ^/user_tools/users/, roles: ROLE_CUSER_A}
- {path: ^/user_tools/news/, roles: ROLE_CUSER_B}
Let's take a look at the testing unit...
class SecurityControllerTest extends WebTestCase
{
const LOGIN_ERROR='this_is_a_non_existing_user';
const PASS_ERROR='with_a_non_existing_pass';
const LOGIN='this_is_a_valid_user';
const PASS='with_a_valid_pass';
const PASS_CRYPT='##and_this_is_the_encripted_pass_as_pasted_from_the_database##';
const ID_SUBMIT='btn_submit';
private $client;
private $crawler;
public function testIndex()
{
$this->client=static::createClient();
$this->crawler=$this->client->request('GET', '/route_to_login');
//Let's check that there are users in the database...
$em=$this->client->getContainer()->get('doctrine')->getManager();
$users=$em->getRepository("MyBundle:User")->findAll();
$this->assertGreaterThan(0, count($users));
//Now let's check that there's a valid user...
$valid_user=$em->getRepository("MyBundle:User")->findBy(
array('login' => self::LOGIN,
'pass' => self::PASS_CRYPT));
$this->assertGreaterThan(0, count($valid_user));
//Let's check that there is no invalid user ;).
$invalid_user=$em->getRepository("MyBundle:User")->findBy(
array('login' => self::LOGIN_ERROR,
'pass' => self::PASS_ERROR));
$this->assertEquals(0, count($invalid_user));
//The view should be the one I expect...
$this->assertEquals('MyBundle\Controller\User\SecurityController::loginAction', $this->client->getRequest()->attributes->get('_controller'));
//Let's try an invalid access...
$this->form_login(self::LOGIN_ERROR, self::PASS_ERROR);
$this->assertEquals('MyBundle\Controller\User\SecurityController::loginAction', $this->client->getRequest()->attributes->get('_controller'));
//And now, let's try the good one!.
self::form_login(self::LOGIN, self::PASS);
$this->assertEquals('MyBundle\Controller\User\HomeController::homeAction', $this->client->getRequest()->attributes->get('_controller'));
}
private function form_login($login, $pass)
{
$form=$this->crawler->selectButton(self::ID_SUBMIT)->form();
$form['_username']=$login;
$form['_password']=$pass;
$this->client->submit($form);
$this->crawler=$this->client->followRedirect();
}
}
The thing is, all tests are passed except the last one (that is, the good login). It does not go to the expected controller, but back to the login.
Here's the phpunit error:
There was 1 failure:
1) MyBundle\Tests\Controller\User\SecurityControllerTest::testIndex
Failed asserting that null matches expected 'MyBundle\Controller\User\HomeController::homeAction'.
Is there something I am missing here?. Everything is working as expected into the dev enviroment. Users do exists (and are asserted, as you can see). I am prepared to give more info as requested.
Thanks!.