CakePHP 2.1 - testing a simple admin_add() controller action - cakephp

New to unit testing... testing an articles controller and I am getting a fail on the $this->assertNotEmpty();
Shouldn't this be displaying an array full of validation errors? Instead I am getting an empty array.
It seems my validation rules are not being picked up... as further inspection show that Article::save() is returning true on data that should fail....
/**
* Admin Add
* #see controllers/MastersController::_admin_add()
* #return void
*/
public function admin_add(){
//parent::_admin_add();
if(!empty($this->request->data){
$this->Article->save($this->request->data);
}
}
/**
* Test Admin Add
*
* #return void
*/
public function testAdminAdd() {
#define sample passing data
$sampleDataPass = array(
'Article'=>array(
'title'=>'Test Article Add Will Pass',
'body'=>'Test Article Add Body',
'status_id'=>1,
'category_id'=>1,
)
);
#test action
$this->testAction('admin/articles/add', array('data'=>$sampleDataPass));
$this->assertEmpty($this->Articles->Article->validationErrors); #####PASSES#####
#define sample failing data
$sampleDataFail = array(
'Article'=>array(
'title'=>'Test Article Add Will Fail',
)
);
$this->testAction('admin/articles/add', array('data'=>$sampleDataFail));
$this->assertNotEmpty($this->Articles->Article->validationErrors); #####FAILS#####
}
class Article extends AppModel {
/*
* Name
*/
public $name = 'Article';
/*
* Validation Rules
*/
public $validate = array(
'title' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'You must supply an article title in order to save.',
),
),
'body' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'You must supply an article title in order to save.',
),
),
'status_id' => array(
'numeric' => array(
'rule' => array('numeric'),
'message' => 'You must choose a status.',
'allowEmpty' => false,
),
),
'category_id' => array(
'numeric' => array(
'rule' => array('numeric'),
'message' => 'You must choose a category.',
'allowEmpty' => false,
),
)
);
}

CakePHP will ignore validation rules if the field is not present in the data.
By setting the option 'required' to true the validation rule will always be checked.
For example:
'title' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'You must supply an article title in order to save.',
'required' => true
),
),
Documention on validation in CakePHP can be found here: http://book.cakephp.org/2.0/en/models/data-validation.html#one-rule-per-field

Related

Difference between two dates validation in cakephp

I am a beginner at CakePHP and I have o problem. I have to validate 2 dates(date_start & date_end). Date_end must be at least 30 days later than date_start. I am little confused of how to write the function for date difference. I don't know what parameteres I have to add and how to find them from the variable $validate. I also added another validation for the dates which tells date_end must be later than date_start and it works. Here's is the code of validations:
public $validate = array(
'user_id' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
),
),
'name' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
),
),
'date_start' => array(
'rule' => 'date',
'message' => 'Enter a valid date'
),
'date_end' => array(
'date' => array(
'rule' => array('date'),
'message' => 'The date must be valid'),
'dates' => array(
'rule' => 'dates',
'message' => 'The end date must be later tha start date'),
),
);
public function dates(){
if($this->data['Lesson']['date_end'] > $this->data['Lesson']['date_start']){
return true;
}
else{
return false;
}
}
public function date_diff($date_start, $date_end){
}
Do you do you know the code I should write in function date_diff?
Thank you!
Thank you very much #ndm and the other guys of course for you help. I wrote this code in function diff and it worked:
public function date_diff($check1,$ckeck2){
$check1 = $this->data['Lesson']['date_start'];
$check2 = $this->data['Lesson']['date_end'];
$diff = abs(strtotime($check2) - strtotime($check1));
if($diff >= 2592000){
return true;
}
else
return false;
}

CakePHP - How can add more validate fields to an existed model?

I have a Model
class Model extends AppModel {
public function __construct() {
parent::__construct();
$this->validate=array(
'first_name' => array(
'NotEmpty' => array(
'rule' => 'NotEmpty',
'required' => true,
'message'=> 'Not empty'
)
),
'last_name' => array(
'NotEmpty' => array(
'rule' => 'NotEmpty',
'required' => true,
'message'=> 'Not empty'
)
),
);
}
}
The problem is in view I have a dynamic data need to validation (last_name and firstname up to 30). How can I add them dynamical into Model and validate in Controller?
You can dinamically change validation rules
Make a new function in the model that will update your validation rules, as described in the documentation.
In the controller, before validating the model, call the model function that changes the validation rules.

Validation defined in model - CakePHP

Using CakePHP 1.3 I developed engine for blog with posts and comments tables and recently I have noticed that in database I've got records with null values in content column despite of the fact that Comment model has defined proper validation:
<?php
class Comment extends AppModel {
var $name = 'Comment';
var $sequence = 'comments_seq';
var $belongsTo = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'post_id'
)
);
var $validate = array(
'content' => array(
'required' => array (
'rule' => 'notEmpty',
'message' => 'Content can't be empty.'
)
),
'post_id' => array(
'rule' => 'notEmpty'
),
'created' => array(
'rule' => 'notEmpty'
)
);
?>
Is there a bug in CakePHP framework or validation defined above is not correct or insufficient?
In your validation rules, you're not actually requiring the field. Requiring means that the key must exist when it comes time to validate. The notEmpty rule requires only that the key is not empty but not that it exists.
To require that the field exists, use the required option in your validation rules:
var $validate = array(
'content' => array(
'required' => array ( // here, 'required' is the name of the validation rule
'rule' => 'notEmpty',
'message' => 'Content can\'t be empty.',
'required' => true // here, we say that the field 'content' must
// exist when validating
)
),
'post_id' => array(
'rule' => 'notEmpty'
),
'created' => array(
'rule' => 'notEmpty'
)
);
Without the required key, you could potentially save completely empty records by simply not including the 'content' key when saving. Now that it is required, validation will fail if 'content' is not in the data that you're saving.

Can Cake Php Validation clear input field value

Can Cake Php Validation clear input field value
var $validate = array(
'name' => array(
'isUnique' => array (
'rule' => 'isUnique',
'message' => 'This Person name already exists.'
)
)
);
If error persist in validation, I want to clear name field value. Is it possible to do so with cake php validation itself ?
You can do it with a custom validation rule if you wanted.
var $validate = array(
'name' => array(
'isUnique' => array (
'rule' => 'ifNotUniqueClear', // use custom rule defined below
'message' => 'This Person name already exists.'
)
)
);
function ifNotUniqueClear(&$data) {
$field = key($data);
// see if the record exists
$user = $this->find('first', array(
'conditions' => array(
$field => $data[$field]
),
'recursive' => -1
));
if ($user) {
// unset or empty it, your choice
unset($this->data[$this->alias][$field]);
return false;
}
return true;
}

Cakephp 2.0 Localization for Model Messages

I am trying to get i18n to extract the strings from my model in Cakephp 2.0
The documentation states that
"CakePHP will automatically assume that all model validation error messages in your $validate array are intended to be localized. When running the i18n shell these strings will also be extracted."
http://book.cakephp.org/2.0/en/core-libraries/internationalization-and-localization.html
But my messages in my model are not being extracted into my po file when I run cake i18n and extract the data.
Does anyone know how to get the message strings into the po file?
App::uses('AuthComponent', 'Controller/Component');
class User extends AppModel {
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A Username is required',
'rule' => 'isUnique',
'message' => 'This username has already been taken'
)
);
}
This is how you can solve the problem I came across.
App::uses('AuthComponent', 'Controller/Component');
class User extends AppModel {
function __construct() {
parent::__construct();
$this->validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'))
'message' => __('A Username is required', true)),
'unique' => array(
'rule' => 'isUnique',
'message' => _('This username has already been taken', true)
)
);}
}
The correct way of achieve this is:
class AppModel extends Model {
public $validationDomain = 'validation_errors';
.
.
.
}
internally cake will call:
__d('validation_errors', 'Username should be more fun bla bla');
http://book.cakephp.org/2.0/en/console-and-shells/i18n-shell.html#model-validation-messages
http://book.cakephp.org/2.0/en/core-libraries/internationalization-and-localization.html#translating-model-validation-errors
Your $validate structure is a little messed up, you have two identical array keys (rule,message) under the required key. It should be:
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => __('A Username is required', true),
),
'unique'=>array(
'rule' => 'isUnique',
'message' => __('This username has already been taken', true)
)
)
);

Resources