Unit Testing OAuth Login with Cake 2.3 - unit-testing

I need some advice on how to set up a unit test in Cake 2.3 that tests OAuth login. I'm using the thomseddon/cakephp-oauth-server plugin. Note: I've reviewed examples such as CakePHP 2.3 - Unit testing User Login, but I'm still confused about how exactly to approach an OAuth test using the plugin. Any help appreciated.
The following is what I currently have in my unit test. Not very much of a test, yet.
/**
* testOAuthLogin method
* Tests that OAuth login works
* #return void
*/
public function testOAuthLogin(){
$data = array(
'response_type' => 'code',
'client_id' => getenv('THREE_SCALE_APP_ID'),
'User' => array(
'username' => TEST_USERNAME,
'passwd' => TEST_PASSWORD
)
);
$result = $this->testAction('/oauth/login', array(
'data' => $data,
'method' => 'post'
));
debug($result);
}
This returns:
{"error":"invalid_client","error_description":"No client id supplied"}

I was able to figure this out. I just needed to setup up proper fixtures for User and AccessToken. And then I had to ensure that these were imported in the controller that I was testing in via $fixtures.
Example of my AccessTokenFixture:
<?php
App::uses('OAuthComponent', 'OAuth.Controller/Component');
/**
* AccessTokenFixture
*
*/
class AccessTokenFixture extends CakeTestFixture {
/**
* Fields
*
* #var array
*/
public $fields = array(
'oauth_token' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 40, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'client_id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'user_id' => array('type' => 'integer', 'null' => false, 'default' => null),
'expires' => array('type' => 'integer', 'null' => false, 'default' => null),
'scope' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'indexes' => array(
'PRIMARY' => array('column' => 'oauth_token', 'unique' => 1)
),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MyISAM')
);
/**
* init method
* #return void
*/
public function init() {
$this->records = array(
array(
'oauth_token' => OAuthComponent::hash('SAMPLE_ACCESS_TOKEN'),
'client_id' => 'YOUR_CLIENT_ID',
'user_id' => 1,
'expires' => 1367263611232323,
'scope' => ''
),
array(
'oauth_token' => OAuthComponent::hash('SAMPLE_ACCESS_TOKEN'),
'client_id' => 'YOUR_CLIENT_ID',
'user_id' => 2,
'expires' => 13672640632323323,
'scope' => ''
)
);
parent::init();
}
}

Related

SimpleSAMLphp missing some configuration. What is missing?

I am trying to use SimpleSAMLphp in AWS ubuntu instance but for some reason I can make it run correctly. I am using AWS-LoadBalancer for https, I do not know if it affect the configuration.
config.php
$config = array(
'baseurlpath' => 'simplesaml/',
'certdir' => 'cert/',
'loggingdir' => 'log/',
'datadir' => 'data/',
'tempdir' => '/tmp/simplesaml',
'technicalcontact_name' => 'David Pacheco',
'technicalcontact_email' => 'dpacheco#lumstons.com',
'timezone' => 'America/Mexico_City',
'secretsalt' => '6ogT+0kPWJAO6FbKThWcI1spujbVVdmFEsPVRiPKEWw=',
'auth.adminpassword' => 'david',
'admin.protectindexpage' => false,
'admin.protectmetadata' => false,
'admin.checkforupdates' => true,
'trusted.url.domains' => array(),
'trusted.url.regex' => false,
'enable.http_post' => false,
'debug' => array(
'saml' => false,
'backtraces' => true,
'validatexml' => false,
),
'showerrors' => true,
'errorreporting' => true,
'logging.level' => SimpleSAML\Logger::NOTICE,
'logging.handler' => 'syslog',
'logging.facility' => defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER,
'logging.processname' => 'simplesamlphp',
'logging.logfile' => 'simplesamlphp.log',
'statistics.out' => array(
),
'proxy' => null,
'database.dsn' => 'mysql:host=localhost;dbname=saml',
'database.username' => 'simplesamlphp',
'database.password' => 'secret',
'database.options' => array(),
'database.prefix' => '',
'database.persistent' => false,
'database.slaves' => array(
),
'enable.saml20-idp' => false,
'enable.shib13-idp' => false,
'enable.adfs-idp' => false,
'enable.wsfed-sp' => false,
'enable.authmemcookie' => false,
'default-wsfed-idp' => 'urn:federation:pingfederate:localhost',
'shib13.signresponse' => true,
'session.duration' => 8 * (60 * 60),
'session.datastore.timeout' => (4 * 60 * 60),
'session.state.timeout' => (60 * 60),
'session.cookie.name' => 'SimpleSAMLSessionID',
'session.cookie.lifetime' => 0,
'session.cookie.path' => '/',
'session.cookie.domain' => null,
'session.cookie.secure' => false,
'session.phpsession.cookiename' => 'SimpleSAML',
'session.phpsession.savepath' => null,
'session.phpsession.httponly' => true,
'session.authtoken.cookiename' => 'SimpleSAMLAuthToken',
'session.rememberme.enable' => false,
'session.rememberme.checked' => false,
'session.rememberme.lifetime' => (14 * 86400),
'memcache_store.servers' => array(
array(
array('hostname' => 'localhost'),
),
),
'memcache_store.prefix' => '',
'memcache_store.expires' => 36 * (60 * 60),
'language' => array(
'priorities' => array(
'no' => array('nb', 'nn', 'en', 'se'),
'nb' => array('no', 'nn', 'en', 'se'),
'nn' => array('no', 'nb', 'en', 'se'),
'se' => array('nb', 'no', 'nn', 'en'),
),
),
'language.available' => array(
'en', 'no', 'nn', 'se', 'da', 'de', 'sv', 'fi', 'es', 'ca', 'fr', 'it', 'nl', 'lb',
'cs', 'sl', 'lt', 'hr', 'hu', 'pl', 'pt', 'pt-br', 'tr', 'ja', 'zh', 'zh-tw', 'ru',
'et', 'he', 'id', 'sr', 'lv', 'ro', 'eu', 'el', 'af'
),
'language.rtl' => array('ar', 'dv', 'fa', 'ur', 'he'),
'language.default' => 'en',
'language.parameter.name' => 'language',
'language.parameter.setcookie' => true,
'language.cookie.name' => 'language',
'language.cookie.domain' => null,
'language.cookie.path' => '/',
'language.cookie.secure' => false,
'language.cookie.httponly' => false,
'language.cookie.lifetime' => (60 * 60 * 24 * 900),
'language.i18n.backend' => 'SimpleSAMLphp',
'attributes.extradictionary' => null,
'theme.use' => 'default',
'template.auto_reload' => false,
'production' => true,
'idpdisco.enableremember' => true,
'idpdisco.rememberchecked' => true,
'idpdisco.validate' => true,
'idpdisco.extDiscoveryStorage' => null,
'idpdisco.layout' => 'dropdown',
'authproc.idp' => array(
30 => 'core:LanguageAdaptor',
45 => array(
'class' => 'core:StatisticsWithAttribute',
'attributename' => 'realm',
'type' => 'saml20-idp-SSO',
),
50 => 'core:AttributeLimit',
99 => 'core:LanguageAdaptor',
),
'authproc.sp' => array(
90 => 'core:LanguageAdaptor',
),
'metadata.sources' => array(
array('type' => 'flatfile'),
),
'metadata.sign.enable' => false,
'metadata.sign.privatekey' => null,
'metadata.sign.privatekey_pass' => null,
'metadata.sign.certificate' => null,
'metadata.sign.algorithm' => null,
'store.type' => 'phpsession',
'store.sql.dsn' => 'sqlite:/path/to/sqlitedatabase.sq3',
'store.sql.username' => null,
'store.sql.password' => null,
'store.sql.prefix' => 'SimpleSAMLphp',
'store.redis.host' => 'localhost',
'store.redis.port' => 6379,
'store.redis.prefix' => 'SimpleSAMLphp',
);
Apache 2 site config:
<VirtualHost *:80>
ServerName saml.veptec.mx
DocumentRoot /var/www/html
Alias /simplesaml /var/simplesamlphp/www
<Directory /var/simplesamlphp/www>
Require all granted
</Directory>
</VirtualHost>
The https://saml.dominian.com/simplesaml is redirected to https://saml.dominian.com/simplesaml/module.php/core/frontpage_welcome.php but that file return HTTP ERROR 500, I try to track down the error and I fond out that is problem with the config file.
Any ideas?
I found the answer, the location it was not initializing. It was a bug.
In the ./lib/SimpleSAML/Locale/Localization.php file I only call this method:
$this->setupTranslator();
in the end of the constructor and it works correctly.

Configure multiple databases in zf2 with doctrine2

How can I configure (and use) multiple databases in Zend Framework 2 with doctrine 2 ? Currently I have this in my local.php:
return array(
'doctrine' => array(
'connection' => array(
// default connection name
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => 'root',
'password' => '',
'dbname' => 'data1',
'charset' => 'utf8',
'driverOptions' => array(
1002=>'SET NAMES utf8'
)
)
)
)
),
);
But I do not see a way to add a second one.
Perhaps this example might show you the way, this is how I configured two databases in my application, but I'm not using Doctrine.
DBs configuration
return array(
'doctrine' => array(
'connection1' => array(
// default connection name
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => 'root',
'password' => '',
'dbname' => 'data1',
'charset' => 'utf8',
'driverOptions' => array(1002 => 'SET NAMES utf8')
)
)
),
'connection2' => array(
// default connection name
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => 'root',
'password' => '',
'dbname' => 'data2',
'charset' => 'utf8',
'driverOptions' => array(1002 => 'SET NAMES utf8')
)
)
)
),
);
Then you need to create a DbAdapterFactory that connect to DB connection1 and another factory to connect to DB connection2:
PS: Of course the names are just examples and you can use better ones.
class Adapter1Factory implements FactoryInterface
{
/**
* Create DbAdapter
*
* #param ServiceLocatorInterface $serviceLocator
* #return DbAdapter
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('config');
$configDb1 = $config['connection1'];
$adapter = new \Zend\Db\Adapter\Adapter($configDb1);
return $adapter;
}
}
class Adapter2Factory implements FactoryInterface
{
/**
* Create DbAdapter
*
* #param ServiceLocatorInterface $serviceLocator
* #return DbAdapter
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('config');
$configDb2 = $config['connection2'];
$adapter = new \Zend\Db\Adapter\Adapter($configDb2);
return $adapter;
}
}
Now just use the specific AdapterFactory when you want to connect to certain DB.

zf2 + Doctrine a different database for each member

Each connected member of my site has its database.
Here is the doctrine config for "user_1":
return array(
'doctrine' => array(
'connection' => array(
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => 'user_1',
'password' => 'psswd_user_1',
'dbname' => 'database_user_1',
'charset' => 'utf8',
'driverOptions' => array (1002 => 'SET NAMES utf8'),
)),),),);
Is there a way to replace :
'user_1', 'psswd_user_1' and 'database_user_1'
with
'user_x', 'psswd_user_x' and 'database_user_x' for user_x ?
I don't know how to do that !
I'd like to avoid copying the same code for each user ...
Thank you for help
The proper way to do this might be to inject the configuration that you need when the connection is created. I couldn't find any event that you could hook into to do that, so you have to find the right service manager key to override.
With a little bit of source code digging, I found that these options are sent to a DoctrineORMModule\Options\DBALConnection instance and that this instance is created by DoctrineORMModule\Service\DBALConnectionFactory
You need to override this factory with something like this:
<?php
namespace MyModule\Service;
use DoctrineORMModule\Service\DBALConnectionFactory;
use Zend\ServiceManager\ServiceLocatorInterface;
class MyDBALConnectionFactory extends DBALConnectionFactory
{
public function getOptions(ServiceLocatorInterface $sl, $key, $name = null)
{
$options = parent::getOptions($sl, $key, $name);
// override for everyone that needs a DBALConnection
if ($this->getOptionClass() === 'DoctrineORMModule\Options\DBALConnection') {
// set custom parameters here
// maybe fetch the current user with $sl->get('...')
$params = [/* ... */];
$options->setParams($params);
}
return $options;
}
}
And then you just tell the service manager about it:
<?php
return [
...
'doctrine' => [
'doctrine_factories' => [
'connection' => 'MyModule\Service\DBALConnectionFactory',
]
]
...
];
Thanks to Alejandro Celaya.
1st link and 2d link
I hope it will be useful.
I know it's not perfect but I can't do better ! I'd like critical.
in config/autoload/doctrine.local.php:
'doctrine' => array(
'connection' => array(
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => 'root',
'password' => '',
'dbname' => 'gestion_toto_default',
'charset' => 'utf8',
'driverOptions' => array(1002 => 'SET NAMES utf8'),
)
),
'orm_toto_users' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => 'root',
'password' => '',
//gestion_toto_users has 2 tables : users and db_users
'dbname' => 'gestion_toto_users',
'driverOptions' => array(1002 => 'SET NAMES utf8'),
)
),
'dynamic_orm' => array(
'driverClass' =>'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => '',
'password' => '',
'dbname' => '',
'driverOptions' => array(1002 => 'SET NAMES utf8'),
),
),
),
'driver' => array(
'orm_toto_users' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\DriverChain',
'drivers' => array(
__NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
)
),
'dynamic_orm' => array(
'drivers' => array(
__NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
)
),
),
'entitymanager' => array(
'orm_toto_users' => array(
'connection' => 'orm_toto_users',
'configuration' => 'orm_default'
),
'dynamic_orm' => array(
'connection' => 'dynamic_orm',
),
),
'eventmanager' => array(
'orm_toto_users' => array()
),
'sql_logger_collector' => array(
'orm_toto_users' => array(),
),
'entity_resolver' => array(
'orm_toto_users' => array()
),),
module.config.php :
'doctrine' => array(
'driver' => array(
__NAMESPACE__ . '_driver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(
__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity'
),
),
'orm_default' => array(
'drivers' => array(
__NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
)
),
),
'authentication' => array(
'orm_default' => array(
'object_manager' => 'doctrine.entitymanager.orm_toto_users',
'identity_class' => 'MyModule\Entity\User',
'identity_property' => 'identifiant',
'credential_property' => 'password',
'credential_callable' => function(\MyModule\Entity\User $user, $passwordGiven) {
$bcrypt = new \Zend\Crypt\Password\Bcrypt();
return $bcrypt->verify($psswdGiven, $user->getPsswd()) && $user->getIsactif();
},
),
),
),
in Xcontroller :
public function getEntityManager()
{
if (null === $this->em) {
$this->em = $this->getServiceLocator()->get('dynamic_entity_manager');
}
return $this->em;
}
in userController :
public function getEntityManager()
{
if (null === $this->em) {
$this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_toto_users');
}
return $this->em;
}
in DynamicEMFactory.php:
class DynamicEMFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $serviceLocator)
{
// Get current user
$authService = $serviceLocator->get('Zend\Authentication\AuthenticationService');
if (! $authService->hasIdentity()) {
throw new \RuntimeException(
'It is not possible to create a dynamic entity manager before a user has logged in'
);
}
$user = $authService->getIdentity();
$db_User = $user->getUser_db()->getDbuser();
$db_Psswd = $user->getUser_db()->getDbpsswd();
$db_Name = $user->getUser_db()->getDbname();
// Update connection config
$globalConfig = $serviceLocator->get('config');
$globalConfig['doctrine']['connection']['dynamic_orm']['params']['user'] = $db_User;
$globalConfig['doctrine']['connection']['dynamic_orm']['params']['password'] = $db_Psswd;
$globalConfig['doctrine']['connection']['dynamic_orm']['params']['dbname'] = $db_Name;
$isAllowOverride = $serviceLocator->getAllowOverride();
$serviceLocator->setAllowOverride(true);
$serviceLocator->setService('config', $globalConfig);
$serviceLocator->setAllowOverride($isAllowOverride);
return $serviceLocator->get('doctrine.entitymanager.dynamic_orm');
}
}
in module.config :
'service_manager' => array(
'factories' => array(
'dynamic_entity_manager' => 'XXX\Service\Factory\DynamicEMFactory',
in onBootstrap (to change appearence):
$authService = $serviceManager->get('Zend\Authentication\AuthenticationService');
if ($authService->getIdentity()) {
$em = $serviceManager->get('dynamic_entity_manager');
} else {
$em = $serviceManager->get('doctrine.entitymanager.orm_default');
}
$viewModel = $e->getApplication()->getMvcEvent()->getViewModel();
$query = $serviceManager->get('param_user');
$tab = $query->getReponse($em);
$nom_theme = $tab['something']));
$viewModel->nom_theme = $nom_theme;//to layout

ZF2 Doctrine 2 ObjectSelect with distinct on field

to populate my form I use the fieldset approach. For one given form field I will use a select and the options are coming directly from an entity like this:
$this->add(
array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'city',
'options' => array(
'label' => 'City: ',
'object_manager' => $this->_om,
'target_class' => 'Hotbed\Entity\AllAdresses',
'property' => 'city',
'is_method' => true,
'find_method' => array(
'name' => 'findBy',
'params' => array(
'criteria' => array('postal_code' => $postalCode),
'orderBy' => array('city' => 'ASC'),
),
),
),
'attributes' => array(
'class' => 'form-control input-large',
'required' => '*'
),
)
);
This works pretty well. The only inconvient is that I have to put a distinct on the field city. How can I solve this problem?
Regards Andrea
The way I got around this was to create a function in the repository to return the distinct entities, and then specify that function name in your form element.
So in your case, for example:
In your repository:
public function findDistinctCitiesByPostalCode($postalCode) {
$dql = "SELECT DISTINCT a.city "
. "FROM Hotbed\Entity\AllAdresses a "
. "WHERE a.postalCode :postalCode";
$qry = $this->getEntityManager()->createQuery($dql);
$qry->setParameter('postalCode', $postalCode);
$results = $qry->getArrayResult();
// $results will be an array in the format
// array(array('city' => 'city_1'), array('city' => 'city_1'),....)
// so you'll need to loop through and create an array of entities
foreach ($results as $row) {
$addresses[] = new Hotbed\Entity\AllAdresses(array('city' => $row['city']);
}
return $addresses;
}
And then in your form:
$this->add(
array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'city',
'options' => array(
'label' => 'City: ',
'object_manager' => $this->_om,
'target_class' => 'Hotbed\Entity\AllAdresses',
'property' => 'city',
'is_method' => true,
'find_method' => array(
'name' => 'findDistinctCitiesByPostalCode'
)
)
)
);

CakePHP2 testing login()

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!
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.
The problem is that you are mocking the entire Session component. This means all the session methods will return null. Remove the 'Session' key from $this->generate() and you should be good.