Intro:
I have a Yii webapp which I want to test using phpunit and selenium testing, but here is the catch, I do not use a DB. I communicate with an API which integrates with Yii's activeRecord (https://github.com/Haensel/ActiveResource).
Situation:
So I have phpunit test working and I have a running Selenium stand alone server running as well. I do not use the FF plugin. I run it as a unit test:
<?php
class TestTest extends WebTestCase
{
public $fixtures=array(
//'posts'=>'Post',
);
public function testShow()
{
$this->open('site/login');
// verify the sample post title exists
$this->assertTextPresent($this->posts['sample1']['title']);
// verify comment form exists
$this->assertTextPresent('Password');
}
}
?>
But it keeps trying to connect to the database, which doesn't exist. My webapp works fine without the database connection so I know it doesn't need it.
Question:
So what I want to know is whether it is actually possible (I am new to Yii, but lots of MVC experience)?
How can I "set it up" to not look for a DB resource?
Has anyone done this and maybe have a few pointers or guide etc?
thanks alot!
"How can I "set it up" to not look for a DB resource" -> I believe that you can do that in the same file "protected/config/main.php", that you set it up to look for a DB.
Related
I am using a rest api to store/retrieve my data which is stored in a postgres database. The api is not laravel, its an external service!
Now i want to create a website with laravel (framework version 7.3.0) and i'm stuck on how to implement the api calls correctly.
For example: i want to have a custom user provider with which users can log-in on the website. But the validation of the provided credentials is done by the api not by laravel.
How do i do that?
Just make a Registration controller and a Login Controller by "php artisan make:controller ControllerName" and write Authentication logics there.
In previous versions of Laravel you had a command like "php artisan make:auth" that will make everything needed to do these operations. But in Laravel 7.0 you need to install a package called laravel/ui.
Run "composer required laravel/ui" to install that package
Then run "php artisan ui bootstrap --auth"
and now, you are able to run "php artisan make:auth"
This command will make whole Registration (Signup) and Login system for you.
and in orer to work with REST, you may need to know REST (Http) verbs. Learn about GET, POST, PUT, PATH, DELETE requests and how to make those request with PHP and Laravel collection methods. Learn about JSON parsing, encoding, and decoding. Then you can work with REST easily. and work without any template codes from other packages.
Thank you so much. I hope this answer give you some new information/thought. Thanks again.
Edit:
This might not be the best way. But this is what I did at that time. I tried curl and guzzle to build the request with session cookie and everything in the header to make it look like a request from a web browser. Couldn't make it work.
I used the web socket's channel id for the browser I want the changes to happen and concatenated it with the other things, then encrypted it with encrypt($string). After that, I used the encrypted string to generate a QR code.
Mobile app (which was already logged in as an authenticated used) scanned it and made a post request with that QR string and other data. Passport took care of the authentication part of this request. After decrypting the QR string I had the web socket's channel id.
Then I broadcasted in that channel with proper event and data. Caught that broadcast in the browser and reloaded that page with JavaScript.
/*... processing other data ...*/
$broadcastService = new BroadcastService();
$broadcastService->trigger($channelId, $eventName, encrypt($$data));
/*... returned response to the mobile app...*/
My BroadcastService :
namespace App\Services;
use Illuminate\Support\Facades\Log;
use Pusher\Pusher;
use Pusher\PusherException;
class BroadcastService {
public $broadcast = null;
public function __construct() {
$config = config('broadcasting.connections.pusher');
try {
$this->broadcast = new Pusher($config['key'], $config['secret'], $config['app_id'], $config['options']);
} catch (PusherException $e) {
Log::info($e->getMessage());
}
}
public function trigger($channel, $event, $data) {
$this->broadcast->trigger($channel, $event, $data);
}
}
In my view :
<script src="{{asset('assets/js/pusher.js')}}"></script>
<script src="{{asset('assets/js/app.js')}}" ></script>
<script>
<?php
use Illuminate\Support\Facades\Cookie;
$channel = 'Channel id';
?>
Echo.channel('{{$channel}}')
.listen('.myEvent' , data => {
// processing data
window.location.reload();
});
</script>
I used Laravel Echo for this.
Again this is not the best way to do it. This is something that just worked for me for that particular feature.
There may be a lot of better ways to do it. If someone knows a better approach, please let me know.
As of my understanding, you are want to implement user creation and authentication over REST. And then retrieve data from the database. Correct me if I'm wrong.
And I'm guessing you already know how to communicate over API using token. You are just stuck with how to implement it with laravel.
You can use Laravel Passport for the authentication part. It has really good documentation.
Also, make use of this medium article. It will help you to go over the step by step process.
I am new in phpUnit,my project is in codeigniter and i am using netbeans IDE 8.2 ,my os is windows10,i am trying to test my web site ,Now i have problem that how to test my login page?
i have tried this below code:
class Welcome_test extends TestCase{
public function addDataProvider(){
return array(array('email'=>'abc#gmail.com','pass'=>'cdef'));
}
/*** #dataProvider addDataProvider*/
public function test_login(){
$output = $this->post('Login/submitlogin');
$this->assertContains('<span class="title">Product List</span>',$output);
}
}
i was expecting result should pass but unfortunately i am getting this error
Welcome_test::test_login()
PHP Fatal error occured.
PHP Fatal error(s) occured, test results can be incomplete!
Review Output window for full output.'
Login page or any page so far can be tested using functional or acceptance testing using codeception.
unit testing helps us know if we are getting right assertions to our databases providing right data but they do not help us properly test the nature and functionality of page.
so I suggest you to use acceptance tests for this purpose.
I want to be able to call the CakeS3 plugin from the Cake Shell. However, as I understand it components cannot be loaded from the shell. I have read this post outlining strategies for overcoming it: using components in Cakephp 2+ Shell - however, I have had no success. The CakeS3 code here is similar to perfectly functioning cake S3 code in the rest of my app.
<?php
App::uses('Folder','Utility');
App::uses('File','Utility');
App::uses('CakeS3.CakeS3','Controller/Component');
class S3Shell extends AppShell {
public $uses = array('Upload', 'User', 'Comment');
public function main() {
$this->CakeS3 = new CakeS3.CakeS3(
array(
's3Key' => 'key',
's3Secret' => 'key',
'bucket' => 'bucket')
);
$this->out('Hello world.');
$this->CakeS3->permission('private');
$response = $this->CakeS3->putObject(WWW_ROOT . '/file.type' , 'file.type', $this->CakeS3->permission('private'));
if ($response == false){
echo "it failed";
} else {
echo "it worked";
}
}
This returns an error of "Fatal error: Class 'CakeS3' not found in /home/app/Console/Command/S3Shell.php. The main reason I am trying to get this to work is so I can automate some uploads with a cron. Of course, if there is a better way, I am all ears.
Forgive me this "advertising"... ;) but my plugin is probably better written and has a better architecture than this CakeS3 plugin if it is using a component which should be a model or behaviour task. Also it was made for exactly the use case you have. Plus it supports a few more storage systems than only S3.
You could do that for example in your shell:
StorageManager::adapter('S3')->write($key, StorageManager::adapter('Local')->read($key));
A file should be handled as an entity on its own that is associated to whatever it needs to be associated to. Every uploaded file (if you use or extend the models that come with the plugin, if not you have to take care of that) is stored as a single database entry that contains the name of the config that was used and some meta data for that file. If you do the line of code above in your shell you will have to keep record in the table if you want to access it this way later. Just check the examples in the readme.md out. You don't have to use the database table as a reference to your files but I really recommend the system the plugin implements.
Also, you might not be aware that WWW_ROOT is public accessible, so in the case you store sensitive data there it can be accessed publicly.
And finally in a shell you should not use echo but $this->out() for proper shell output.
I think the App:uses should look like:
App::uses('CakeS3', 'CakeS3.Controller/Component');
I'm the author of CakeS3, and no I'm afraid there is no "supported" way to do this as when we built this plugin, we didn't need to run uploads from shell and just needed a simple interface to S3 from our controllers. We then open sourced the plugin as a simple S3 connector.
If you'd like to have a go at modifying it to support shell access, I'd welcome a PR.
I don't have a particular road map for the plugin, so I've tagged your issue on github as an enhancement and will certainly consider it in future development, but I can't guarantee that it would fit your time requirements so that's why I mention you doing a PR.
When I'm trying to execute a functional unittest of a module within my Yii code, I keep receiving the following error:
CException: CHttpRequest is unable to determine the request URI.
At first, I though it was because it couldn't find the module. However, If I change the url to a wrong one, I get a correct error,s tating it couldn't find the view.
This is how my testing code looks like
public function testViewControllerModule()
{
ob_start();
Yii::app()->runController('module/controller/view');
}
Any ideas on what I might be missing?
bool.devs answer works so far.
This blog post explains the origin of the exception pretty well:
http://mattmccormick.ca/2012/09/14/unit-testing-url-routes-in-yii-framework/
In my case, I generalized the solution and have set the following variables in /www/protected/tests/bootstrap.php:
...
$_SERVER['SCRIPT_FILENAME'] = 'index-test.php';
$_SERVER['SCRIPT_NAME'] = '/index-test.php';
$_SERVER['REQUEST_URI'] = 'index-test.php';
Yii::createWebApplication($config);
Consider using 'index-test.php' instead of 'index.php' because it contains the config 'test.php' which is responsible for fixtures and maybe other test relevated configurations.
If someone has better suggestions feel free to comment :)
Kind regards
I think it's because you haven't set any server variables, i.e $_SERVER and you might be doing something like this in your controller:
Yii::app()->request ....
So before you run your test, make sure you use a fixture for the server variables also. I think this should suffice for now:
$_SERVER=array(
'REQUEST_URI'=>'index.php', // the other fields should follow
);
However to run functional tests i would recommend using SeleniumRC, you won't have to do these workarounds then, and can simulate user clicks also, i think.
Read the initial guide to Functional Testing , read the selenium rc phpunit guide, and also the CWebTestCase documentation.
Notes: You might still have to use fixtures for some variables, and i don't have much experience in testing(which is bad), so i'm not very sure if i am completely correct about selenium.
Does anyone know how to code restler to work with php and mysql to produce something like the following:
I want to create a XML API Web Service and not sure where to start.
I want people to be able to query the database for information such as the following using a http request.
Example of Data
BrandName
Price
ShortDescription
SKU
Example Query
http://website.com/productxml?dep=1&Count=3&BrandName=Y&Price=Y
How would I go about writing such a script as I have searched the internet and cant find any examples and was wondering if you can help.
Thanks in advance
Roy
You could use Restler (http://luracast.com/products/restler/) and build a method
class YourClass {
public function productxml($dep, $Count, $BrandName, $Price) {
// your MySQL stuff
}
}
which handles your request.
See the examples (http://help.luracast.com/restler/examples/) how this can be done.
Hope this helps.
Greets.
You could use Restler #Restler Luracast.
The development has increased alot and its stable.
The fun part about this framework is that it supports multiple formats. All these formats can be added by just inserting a single line of code:
require_once '../../../vendor/restler.php';
use Luracast\Restler\Restler;
$r = new Restler();
$r->setSupportedFormats('JsonFormat', 'XmlFormat'); <---- Add format here
$r->addAPIClass('BMI');
$r->handle();
Also I would like to refer to my Luracast Restler template on bitbucket its public and its there for everybody to see.
I combined Restler with Doctrine so catching data from databases has never been easier. Its a raw version for now but I'll update it soon.
My version uses vagrant. Its a extension to virtualisation technology that makes development setup easy and fast. Once your application is ready you can deploy it to your server.
Link:Restler+Doctrine
1) Install virtualbox + vagrant
2) Clone my repository
3) Move to the cloned directory.
4) vagrant up
5) Enjoy and start programming your REST API in less than 10 minutes.