I´m following the manual 'Agile Web Application Develpment with Yii1.1 and PHP5', and I don´t know, why do the test CRUD is failed,
It was created correctly 'Entity AR class' from Gii after tested correctly 'db connection' also (Chapter 4) but at the moment to create testCRUD the output return is a false assertionm, like this:
OK (1 test, 0 assertions)
Just there is one step that I din´t followed in the manual, and was create CDbConnection class, cause testsConnection was ok. And besides, I check all changes class Test and main.php file and was ok.
EntityTest.php
class EntityTest extends CDbTestCase
{
public function testCRUD()
{
}
}
Entity.php
public function testCRUD()
{
$newEntity=new Entity;
$newEntity->setAttributes(
array(
'name' => 'Test Entity 1',
'description' => 'Test entity number one',
'type_id' => 1,
'location_lat' => 77,
'location_lon' => 77,
'create_time' => '2013-02-16 20:36:00',
'create_user_id' => 1,
'update_time' => '0000-00-00 00:00:00',
'update_user_id' => 0,
)
);
$this->assertTrue($newEntity->save(false));
$retrievedEntity=Entity::model()->findByPk(1);
$this->assertTrue($retrievedEntity instanceof Entity);
$this->assertEquals('Salva la Prospe',$retrievedProject->name);
}
Cheers.
The test runs methods in its own class, it does not call test methods in the object it is testing.
This explains why it says 0 assertions. Your test is just an empty method.
Simply move all your testCRUD code from the Entity.php file to the EntityTest.php file and it should work.
Related
I am new to Laravel. I am writing unit testing on laravel for downloading a csv file. When I run the test case, I get assertResponseStatus as 200 and I need to open the created csv file and I am unable to find the location of downloaded file. How can I find the downloaded file.
This is the controller fuction
public function generateCsv(){
$list = $this->csvRepo->getDetails();
$heading = array(
'heading 1',
'heading 2',
'heading 3'
);
$this->csvRepo->generateCsv($heading,'csv',$list);
}
I need to know the location of downloaded file when run the test case
Assuming you are using the latest version of Laravel / PHP Unit you are able to use the following:
class ExampleFileDownload extends TestCase
{
public function fileDownloads()
{
Storage::fake('file');
// assuming we wanted to test like this:
$response = $this->json('POST', '/test', [
'file' => UploadedFile::fake()->image('testing.jpg')
]);
// Assert the file was stored – I believe this is the line you are looking for
Storage::disk('file')->assertExists('testing.jpg');
// Assert a file does not exist...
Storage::disk('file')->assertMissing('missing.jpg');
}
}
Let me know how you get on :)
I have a Questions table which has a validation like :
$validator
->notEmpty('title')
->add('title', [
'unique' => [
'rule' => [
'validateUnique',
['scope' => ['subject_id', 'chapter_id']]
],
'provider' => 'table'
]
]);
I want to save following records into my table at a time.
Array
(
[0] => Array
(
[subject_id] => 1
[chapter_id] => 4
[title] => What is a .ctp file used for in CakePHP?
)
[1] => Array
(
[subject_id] => 1
[chapter_id] => 4
[title] => What is a .ctp file used for in CakePHP?
)
)
I try to save it using saveMany() method. It save both records i.e. validation not working. I also try following code for transactional() method instead of saveMany() method, but validation also not working.
$entities = $this->Questions->newEntities($records);
$this->Questions->connection()->transactional(function () use ($entities) {
foreach ($entities as $entity) {
$this->Questions->save($entity);
}
});
My validation works fine if I save the records one by one using save() method or my records already saved in database. Why my unique validation not working for saveMany() and also for transactional() for duplicate new entities?
Validation happens before saving
Validation happens before saving, so that behavior is to be expected, given that the rule looks up the database, and not the request data (it would only have access to one set of data at the time anyways), ie, no matter how many datasets are being tested, none of the submitted ones will be saved yet, and therefore validation will pass unless a matching record already exists in the database.
So either create/patch and save all entities one by one in a custom transaction (and don't forget to add some proper failure checks),
$this->Questions->connection()->transactional(function () {
foreach ($this->request->data() as $set) {
$entity = $this->Questions->newEntity($set); // < validaton is being applied there
if (!$this->Questions->save($entity)) { // < not there
return false;
}
}
return true;
});
or use application rules instead.
Application rules are being applied in the saving process
Application rules are being applied in the actual saving process, ie upon calling Table::save(), so to avoid the hassle of using custom transactions, and generally to have a last line of defense, use them instead of/additionally to validation.
// QuestionsTable class
public function buildRules(\Cake\ORM\RulesChecker $rules)
{
$rules->add($rules->isUnique(['title', 'subject_id', 'chapter_id']));
// ...
return $rules;
}
See also
Cookbook > Database Access & ORM > Database Basics > Using Transactions
Cookbook > Database Access & ORM > Validation > Applying Application Rules
Cookbook > Database Access & ORM > Validation > Creating Unique Field Rules
Cookbook > Database Access & ORM > Validation > Validation vs. Application Rules
what do you think
step 1
web.php
'language' => 'de',
'components' => [
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#app/messages',
'sourceLanguage' => 'en',
'fileMap' => [
'app' => 'app.php',
'app/error' => 'error.php',`
.....
Step2
I created the -foldert messages, and I added three folder in messages folder (en, fr, de) and created three file(each contained one)-app.php
'language' => 'de', when i change 'language' => 'hu' Works with translation
step 3
But because I am a beginner I do not know what's next.
I created two buttons but I can not write the Controller.
view/index.php
German<br>
Hungarian
My question is how could the button to switch the language,Need to create a Controller, or work without it, it's how?
step 4 ?
Thanks
Create an action to Set Language in your controller for example SiteController i.e.
public function actionSetLang($lang)
{
switch ($lang) {
case "en":
\Yii::$app->language = "en";
break;
case "de":
\Yii::$app->language = "de";
break;
case "hu":
\Yii::$app->language = "hu";
break;
default:
\Yii::$app->language = "en";
}
$this->goBack();
}
Then in your view you can set up your buttons i.e.
Hungarian
German
The above is a very simple approach. Ideally you want to use cookies to store the user's preferred language in the browser, so the users don't have to change the language every time they visit the page. The cookies can be implemented within the setLang action. I will skip the cookies implementation as they are out of the scope of this question.
You could use this to set your language:
Yii::$app->language = 'ru_RU';
use this function in your controller:
public function init()
{
//set here your language
parent::init();
}
And it wil works for all the functions of that controller.
EDIT:
The first function sets the languages for the rest of the application. when you call that function the rest of the Yii::t() labels will be in that language if the label exsists in that language. de init is a function that is always called before the action in a controller every controller have that function. so if you set a language there the rest of the function will be in that language
I’ve added a small form to an index view to allow users to filter the data. I have placed the following code for the form inside the controller, but I question whether this is the right place to put it.
// ...
public function indexAction()
// ...
// build group list
$groupList = array(
0 => 'all',
1 => 'short people',
2 => 'tall people',
3 => 'fun people',
4 => 'boring people',
);
// create group selection box
$groupSelect = new Element\Select('group');
$groupSelect->setValueOptions($groupList);
$groupSelect->setAttributes(array(
'onChange' => 'this.form.submit()',
));
// create filter form
$form = new Form('group-filter');
$form->add($groupSelect);
$form->setData(array(
'group' => $group,
));
// process the form
$request = $this->getRequest();
if ($request->isPost()) {
$groupSelection = $request->getPost('group', 0);
return $this->redirect()->toRoute('admin-members', array('group'=>$groupSelection,));
}
// ...
Following the MVC pattern, does all of this code belong in the controller?
Nope it does not belong in the controller. Create a new form class (that extends Zend\Form\Form) and inject into the controller class. You can do that through the controllers factory, either through a factory class or the anonymous function "factory".
Other way to do it would be to get it (the form you created) in the controller from the service manager, but as far I know that's not the recommended method anymore, even though it still in the ZF2 docs.
That way your form code will be separated from the controller code, not mixing with the actual controller logic and, in the former case, also more easily testable.
You can learn more from this ZF2 forum thread. It's lengthy, but there are code samples and lead devs from ZF2 team are weighing in.
I have a list of User records that I'm saving at one time (the form is populated from an uploaded CSV).
Everything seems to be working fine, and my validation rules are being honoured, but one thing that's eluding me are the specific validation error messages.
I get the general validation error (if say, a field that is supposed to be unique is not), but I'm not getting an error on the specific field to let the user know what the actual problem is.
Is this a bug, or is there something wrong with my Code? Here's the action from my Controller (fwiw I'm passing the CSV data to this action from another action, hence the snippet at the beginning):
public function finalizeCsv() {
if ( isset($this->request->params['named']['csvData']) ) {
$csvData = unserialize( $this->request->params['named']['csvData'] );
} else {
$csvData = $this->request->data;
}
$this->set('users', $csvData);
if ($this->request->is('get')) {
$this->request->data = $csvData;
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->User->saveAll($this->request->data)) {
$this->Session->setFlash('Users added!', 'default', array('class' => 'success'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('There were errors with your data.');
}
}
}
For unique fields add a validation rule
'field_name' => array(
'rule' => 'isUnique',
'required' => 'create'
),
Next - when you get a error you will need to review $this->User->validationErrors. There will be many arrays inside - 1 for each created record. Loop through them, collect errors and send them to $this->Session->setFlash().
Also you better wrap $this->User->saveAll($this->request->data) into transaction if you're using InnoDB or other engine that supports transactions. On error - do rollback and try again.
$ds = $this->User->getDataSource();
$ds->begin();
// > saving here < //
$ds->commit(); //< on success
$ds->rollback(); //< on error