CakePHP2 testing login()
cakephp, cakephp-2.0, cakephp-2.1, phpunit, unit-testing
Solution
Thanks to @jeremyharris I was able to test my login()
UsersControllerTest.php
public function testLogin() {
$this->Users = $this->generate('Users', array(
'components' => array(
'Security' => array('_validatePost'),
)
));
$data = array();
$data['User']['username'] = 'admin';
$data['User']['password'] = 'test';
$this->Users->Auth->logout();
$this->testAction('/users/login',
array('data' => $data, 'method' => 'post', 'return' => 'contents')
);
$result = $this->testAction('/',
array('method' => 'get', 'return' => 'contents')
);
// debug($result);
$this->assertContains('You are logged in as: <span class="label">admin</span>',$result);
}
public function testLoginInvalid() {
$this->Users = $this->generate('Users', array(
'components' => array(
'Security' => array('_validatePost'),
)
));
$data = array();
$data['User']['username'] = 'admin';
$data['User']['password'] = 'BLAH!';
$this->Users->Auth->logout();
$this->testAction('/users/login',
array('data' => $data, 'method' => 'post', 'return' => 'contents')
);
$result = $this->testAction('/users/login',
array('method' => 'get', 'return' => 'contents')
);
// debug($result);
$this->assertNotContains('You are logged in as',$result);
$this->assertContains('id="UserLoginForm" method="post"',$result);
}
UserFixture.php, I used the init() method - as @jeremyharris said regarding the hashed passwords.
<?php
App::uses('AuthComponent', 'Controller/Component');
class UserFixture extends CakeTestFixture {
/* Optional. Set this property to load fixtures to a different test datasource */
public $useDbConfig = 'test';
public $fields = array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'account_id' => array('type' => 'integer'),
'username' => array('type' => 'string', 'length' => 255, 'null' => false),
'email' => array('type' => 'string', 'length' => 255, 'null' => false),
'password' => array('type' => 'string', 'length' => 255, 'null' => false),
'password_token' => array('type' => 'string', 'length' => 255, 'null' => false),
'password_token_expiry' => array('type' => 'string', 'length' => 255, 'null' => false),
'role' => array('type' => 'string', 'length' => 25, 'null' => false),
'created' => 'datetime',
'modified' => 'datetime'
);
/* public $records = array(
array('id'=>1, 'account_id' => 1, 'username' => 'admin', 'email' => 'admin@test.com', 'password' => 'f57f702f8d557ae5318fa49455cbe9838c1d1712', 'role' => 'admin', 'password_token'=>'', 'password_token_expiry'=>'','created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31'),
array('id'=>2, 'account_id' => 1, 'username' => 'user', 'email' => 'user@test.com', 'password' => 'f57f702f8d557ae5318fa49455cbe9838c1d1712', 'role' => 'user', 'password_token'=>'', 'password_token_expiry'=>'', 'created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31')
);
*/
public function init() {
$this->records = array(
array('id'=>1, 'account_id' => 1, 'username' => 'admin', 'email' => 'admin@test.com', 'password' => AuthComponent::password('test'), 'role' => 'admin', 'password_token'=>'', 'password_token_expiry'=>'','created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31'),
array('id'=>2, 'account_id' => 1, 'username' => 'user', 'email' => 'user@test.com', 'password' => AuthComponent::password('test'), 'role' => 'user', 'password_token'=>'', 'password_token_expiry'=>'','created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31'),
);
parent::init();
}
}
The first testAction() is a POST, then the second one gets the "next" page - from there I do the asserts.
Problem
I want to test the login() action in my UsersController.php ``` <?php class UsersController extends AppController { public $helpers = array('Html', 'Form'); public $components = array('RequestHandler'); public function beforeFilter() { parent::beforeFilter(); $this->Auth->allow('logout', 'login'); // $this->Auth->allow('logout'); $this->Security->csrfExpires = '+1 hour'; } public function login() { if($this->request->is('post')) { if ($this->Auth->login()) { return $this->redirect($this->Auth->redirect()); } else { $this->Session->setFlash(__('Invalid username or password, try again'),'info'); } } } ``` The AppController.php ``` <?php App::uses('Controller', 'Controller'); class AppController extends Controller { public $components = array( 'Session', 'Security', 'Auth' => array( 'loginRedirect' => array('controller' => 'dashboards', 'action' => 'index'), 'logoutRedirect' => array('controller' => 'dashboards', 'action' => 'welcome'), 'authorize' => array('Controller') ) ); public function isAuthorized($user) { //Admin can access every action if (isset($user['role']) && $user['role'] === 'admin') { return true; } //Default deny $this->Session->setFlash('You are not allowed to access the requested page'); return false; } } ``` The UsersControllerTest.php ``` <?php class UsersControllerTest extends ControllerTestCase { public $autoRender = false; public $fixtures = array('app.user','app.account'); public function setUp() { parent::setUp(); $this->User = ClassRegistry::init('User'); } ...snip... public function testLogin() { $this->Users = $this->generate('Users', array( 'components' => array( //'Session', 'Security' => array('_validatePost'), ) )); $this->Users->Security->expects($this->any()) ->method('_validatePost') ->will($this->returnValue(true)); $user = array(); $user['User']['username'] = 'admin'; //$user['User']['password'] = Security::hash('test', null, true); $user['User']['password'] = 'test'; $result = $this->testAction('/users/login', array('data' => $user, 'method' => 'post', 'return' => 'contents') ); debug( $this->contents); //OUTPUTS: I get "Invalid username or password, try again" //EXPECTED: A successful login message since I provided the correct credentials } ``` So, how would I test my login() method when the `$this->testAction('/users/login', array('data' => $user, 'method' => 'post', 'return' => 'contents'));` returns nothing? OUTPUTS: I get "Invalid username or password, try again" EXPECTED: A successful login message since I provided the correct credentials Any reply would be greatly appreciated. Thanks!