Reputation: 51
I am trying to test controller methods (add, edit, ...) that use Security component.
ContactsController
public function initialize() {
$this->loadComponent('Security');
}
public function add() {
$contact = $this->Contacts->newEntity();
if ($this->request->is('post')) {
$contact = $this->Contacts->patchEntity($contact, $this->request->data);
if ($this->Contacts->save($contact)) {
$this->Flash->success(__d('contact_manager', 'The contact has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__d('contact_manager', 'The contact could not be saved. Please, try again.'));
}
}
$this->set(compact('contact'));
$this->set('_serialize', ['contact']);
}
ContactsControllerTest
public function testAdd() {
$data = $this->_getData();
$this->post('/contacts/add', $data);
$this->assertResponseSuccess();
$query = $this->Contacts->find()->where([
'Profiles.lastname' => $data['profile']['lastname'],
'Profiles.firstname' => $data['profile']['firstname']
]);
$this->assertEquals(1, $query->count());
}
protected function _getData() {
$data = [
'id' => '',
'organization_id' => 2,
'profile_id' => '',
'profile' => [
'lastname' => 'Demo',
'firstname' => 'Demo',
'gender' => 'f',
'birthday' => '1990-05-20',
'email' => '[email protected]',
'phone' => '0102030405',
'phone_mobile' => '0607080900'
]
];
return $data;
}
testAdd()
always failed because the request is black-holed (with 'Auth' indicator), but add()
works well in browser.
Upvotes: 0
Views: 788
Reputation: 1184
Since Cake 3.1.2 the best way is to add
$this->enableCsrfToken();
$this->enableSecurityToken();
to your TestFunction.
Upvotes: 1
Reputation: 60463
That is to be expected, as you're not sending the necessary security token, which is what the security component requires.
Just look at your generated form, it will contain hidden inputs for the _Token
field, with the subkeys fields
and unlocked
, where fields
will contain a hash and possibly the names of locked fields, and unlocked
holds the names of unlocked fields.
Just add the token data to your request and everything should be fine. Here's an example
$data = [
'id' => '',
'organization_id' => 2,
'profile_id' => '',
'profile' => [
'lastname' => 'Demo',
// ...
],
'_Token' => [
'fields' => 'e87e3ad9579abcd289ccec2a7a42065b338cacd0%3Aid'
'unlocked' => ''
]
];
Note that the unlocked
key must be present, even if it doesn't hold any data!
You should be able to simply copy the token values from the generated form, and if you're interested in how the token is being generated and validated, have a look at FormHelper::secure()
, FormHelper::_secure()
, and SecurityComponent::_validatePost()
.
See also Cookbook > Controllers > Components > Security
Upvotes: 3