Testing Yii REST application using a second database - php

I wrote an API using Yii2 and following the REST guide. My API is working and I want to write some tests for it, so I once again followed the guide on how to run tests and got unit tests working. I then looked around Codeception documentation about testing WebServices and got this working too.
My problem is that API calls are not using my test database. I have two databases, one called db and the other testdb. Here is my config.php file in tests/codeception/config/:
return [
'components' => [
'db' => [
'dsn' => 'mysql:host=localhost;port=8889;dbname=testdb;unix_socket=/Applications/MAMP/tmp/mysql/mysql.sock',
],
'mailer' => [
'useFileTransport' => true,
],
'urlManager' => [
'showScriptName' => true,
],
],
];
I wrote a simple test that send a GET request to an endpoint to retrieve data. My test database is empty so I am expecting to receive an empty response, but I get the content of my other database instead.
I then tried to set YII_ENV to test as described in the Environment Constant section here so that I could test against the env variable YII_ENV_TEST and change the db configuration accordingly. I tried to set this variable in the _bootstrap.php file in the tests/codeception/ folder:
defined('YII_ENV') or define('YII_ENV', 'test');
I then logged the value of YII_ENV in the web/index.php file (index-test.php is not called, might be a problem too), and it is undefined.
What am I doing wrong? I tried including the Yii2 module in my api.suite.yml file but requests don't have return code anymore if I do that, it returns N/A. Is there another way to change which database Yii should use?

You can make an test_config.php file and at the end of the config place this
if (file_exists('protected/config/test_config.php'))
{
include 'test_config.php';
}
the file will be included if it exists. And the file test_config.php should contain the overwritten value for the db connection.
Hope this helps!
Keep on coding!
Ares.

Well I found a "solution" by using this other app template: https://github.com/githubjeka/yii2-rest
The file organization fits my needs better and I can easily configure which database to use.

Related

Yii2: How to change a system message translation file

The problem
Yii is providing its own translations for system messages, e.g. 'File upload failed' is translated to 'Das Hochladen der Datei ist gescheitert.' when the language on my website is changed to German. This would be fine but some of the translations are grammatically incorrect and I would like to change them.
I've found the messages file that yii is using to handle the translation: yiisoft>yii2>messages>de>yii.php but I can't make changes to it as its part of the vendor directory and any changes I'd make would be overwritten during the next yii update.
What I've tried
I've tried following the instructions laid out by the users here: https://forum.yiiframework.com/t/translating-system-messages/29733. Which involves making a copy of yii.php, putting it in a new directory, making the desired translation changes and then pointing coreMessages towards it in the config. I've followed all these steps but it doesn't seem to actually do anything for me.
As it's stated in the Guide:
Yii comes with the default translation messages for validation errors and some other strings. These messages are all in the category yii. Sometimes you want to correct the default framework message translation for your application. In order to do so, configure the i18n application component like the following:
'i18n' => [
'translations' => [
'yii' => [
'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en-US',
'basePath' => '#app/messages'
],
],
],
Now you can place your adjusted translations to #app/messages/<language>/yii.php.
BTW - you mentioned that
[...] translations are grammatically incorrect [...]
It would be great for Yii 2 and its community if you could fix the problem - please fork this file and send a PR.

Session get destroyed before authTimeout expire in yii2

In Yii2,I have in my config/main.php
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'authTimeout' => 43200,
'loginUrl' => null,
],
...
]
when i am trying to see my authTimeout variable in my whole system is ok and everything works fine except my session get expire before authTimeout.I am using access_token for login because my frontend is angular and also using mdmsoft/yii2-admin for RBAC.
And i am not getting,why i am logging out before my authTimeout?
Thanks
It is probably because globally, session.gc_maxlifetime is set to be lower than what you have set in your application. You can use echo ini_get("session.gc_maxlifetime"); to get the current value.
This answer discusses how to increase that within your application. Note, that some hosts tend to override the session timeout value set in php.ini, as discussed in this thread. Even if that is the case, this answer would help.
If this is not the case, then please provide more information about your script, host and php configuration. I will update the answer accordingly.

Laravel 5.1 GuzzleHttp Client error: 404 when using mailgun

I'm using the Mailgun service when sending mail with Laravel. However, i've set this up today and it's just stopped working. I have entered all the correct info in .env, config/services.php and config/mail.php. However i'm still getting the below error:
ClientException in Middleware.php line 69:
Client error: 404
It looks like the domain is not getting passed through somehow, even though in my config/services.php file I have:
'mailgun' => [
'domain' => env('mydomain.com'),
'secret' => env('<my-mailgun-key>'),
],
I have hidden the above credentials for safety, but in my real application they are the proper values.
Please help.
I was having a very similar 404 issue and tried the solution mentioned by Rogério. I thought I was doing it right, but gave it a try anyway. But misuse of the env() function wasn't my problem.
I set the config/services.php back to look like so:
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN',''),
'secret' => env('MAILGUN_SECRET',''),
],
This will provide empty strings if the values named MAILGUN_DOMAIN and MAILGUN_SECRET are not found in the .env file. Then, in my .env file, I included the API Base URL and API Key from the Mailgun domain information page. So the .env looked something like this:
MAILGUN_DOMAIN=https://api.mailgun.net/v3/sandbox123abc.mailgun.org
MAILGUN_SECRET=key-123456abcdef
The values were passing along as they should, but still 404. Looking at How do I start sending email documentation at Mailgun, I saw that their API URL included "messages" on the end - which I tried manually adding to the .env setting:
MAILGUN_DOMAIN=https://api.mailgun.net/v3/sandbox123abc.mailgun.org/messages
That didn't work either, but lead me to look more carefully at the stack trace spit out by Laravel. That's when I noticed that the URL it was trying to connect with was:
https://api.mailgun.net/v3https://api.mailgun.net/v3/sandbox123abc.mailgun.org/messages/messages.mime
Ah-ha! Using Mailgun's Base API URL was incorrect! That was made obvious by the repetition of the "https://api.mailgun.net/v3" portion. So the aptly named MAILGUN_DOMAIN setting really just needed to be:
MAILGUN_DOMAIN=sandbox123abc.mailgun.org
Seems obvious now, but I spent way too much time figuring it out. Thought I'd put it out there in case anyone else happened to miss that detail
I hade the same problem as you and solved it by removing the env() call.
Thats because env will return the value of the env variable in the first argument (not the value of the argument) and otherwise return the second argument.
So:
'mailgun' => [
'domain' => 'mydomain.com',
'secret' => '<my-mailgun-key>',
],
Try that.

Laravel 4 unittest using wrong database

I have created a testing database environment as follows:
return array(
'default' => 'sqlite',
'connections' => array(
'sqlite' => array(
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => ''
),
)
);
When I initialise my database in my setUp function this all appears to work fine:
Mail::pretend(true);
Artisan::call('migrate');
$this->seed();
Any query directly in my test directly in my test class returns what I would expect however if I call a function on my model that does anything with the database it uses my 'live' (I'm running this in a vagrant dev server so no risk of ruining anything) database instead of my test one. Do I need to change my configuration further to ensure it is using my test database? Or do I need to instantiate my model in a special way?
An example of what doesn't work. In my test:
// gets the correct company
$comp = Companies::find(1);
// gets results from wrong database
$comp->quotesAndOrders();
where quotesAndOrders does a simple query on a hasMany relationship (orders)
$this->orders()->get();
First of all on our .env file we have to add a new variable.
looks like this.
DB_CONNECTION=sqlite
That's because of Laravel defaults to MySQL when this variable is absent from .env file:
see here..
'default' => env('DB_CONNECTION', 'mysql')
Now that our app is pointing into our sqlite database we can now run our migrations and seeding. After that if you just want to keep running MySQL remove DB_CONNECTION=sqlite from the .env file.
Now on your root folder you have a phpunit.xml file, open it and a new variable under <php> node
<env name="DB_CONNECTION" value="sqlite"/>
This project is based on someone elses code originally. In my companies model (annoyingly no other class and this was the first one I tested otherwise I would have spotted it sooner) there is an explicit definition to use the mysql database. I'm not sure why this was. I have removed that line and it now works.

YII2 application working on local but PAGE NOT FOUND error on live

I have created a simple application in YII2 and it is working fine at my local machine but giving me Not Found (#404) "Page Not Found" error on live server.
Local URL: http://localhost:8080/basicapp/web/index.php?r=adminPanel%2Fstatemaster%2Findex
Live URL: http://XXXX.com/web/index.php?r=adminPanel%2Fstatemaster%2Findex
I am not using pretty URL, and didn't change in web.php. just added module info in the file. Code Snippet:
'modules' => [
'adminpanel' => [
'class' => 'app\admin\adminpanel',
],
'studentPanel' => [
'class' => 'app\Student\dashboard',
],
],
I can provide detial, whatever is required.
If anyone have similar problem, Just change your naming of models and controllers.
In my problem, model and controller names were like StateMasterController etc but it should be StatemasterController, mind the M.
It works for me, may be this can help you.
Thanks

Categories