I am testing my controller from Symfony2 with PHPUnit and the class WebTestCase
return self::$client->request(
'POST', '/withdraw',
array("amount" => 130),
array(),array());
$this->assertEquals(
"You can withdraw up to £100.00.",
$crawler->filter("#error-notification")->text());
But I get this error:
Expected: "You can withdraw up to £100.00."
Actual: "You can withdraw up to £100.00."
The thing is that in the webpage and the source code it looks fine, so I am thinking that maybe PHPUnit is having some trouble to fetch the text as UTF8?
What am I missing?
solution:
Make sure the mbstring extension is enabled.
There was a bug about failing tests with iconv reported in the kohana bugtracker.
tips:
As proposed in this question/answer - you can test for correct UTF-8 output:
$this->assertEquals(
mb_detect_encoding(
crawler->filter("#error-notification")->text(),
'UTF-8'
),
'UTF-8'
);
You can include accept-charset headers with requests sent by the client:
$client->request(
'POST', '/withdraw',
array("amount" => 130),
array(),
array(),
array('HTTP_ACCEPT_CHARSET' => 'utf-8')
);
Related
I want to make phpunit tests for lumen app, like :
public function testRegisterUser()
{
$newUserData = [
'name' => 'test_user',
'email' => 'test_user#mail.com',
'password' => Hash::make('111111'),
'status' => 'A',
'has_debts' => false
];
$response = $this->get('/api/v1/register', $newUserData); // http://localhost:8000/api/v1/register
$this->assertResponseOk();
}
But running tests I got 405 error :
1) PagesTest::testRegisterUser
Expected response status code [200] but received 405.
Failed asserting that 200 is identical to 405.
/ProjectPath/vendor/illuminate/testing/TestResponse.php:177
/ProjectPath/vendor/illuminate/testing/TestResponse.php:99
/ProjectPath/vendor/laravel/lumen-framework/src/Testing/Concerns/MakesHttpRequests.php:415
/ProjectPath/tests/PagesTest.php:27
Why I got 405 Method Not Allowed ? I postman I check my method : https://prnt.sc/207bu03
Method /api/v1/register in postman has no any token protection.
How to make my test working ?
UPDATED BLOCK :
I got error :
Error: Call to undefined method PagesTest::getJson()
If I modify :
$response = $this->getJson('/api/v1/register', $newUserData);
method getJson is mentioned here : https://laravel.com/docs/8.x/http-tests
But on this page I see in test file header:
namespace Tests\Feature;
But not in my generated lumen test file.
In my routes/web.php I have :
$router->group(['prefix'=>'api/v1'], function() use($router){
$router->post('/register','AuthController#register');
$router->post('/login', 'AuthController#login');
$router->group(['middleware' => 'auth'], function () use ($router) {
$router->get('/profile', 'UserProfileController#index');
What is wrong ?
Thanks!
Because you maybe have to use $this->getJson instead of $this->get.
It is not http://localhost:8000 as you are testing, you are not literally accessing the URL. It is simulating that.
Also share your api.php or routes file and the controller please (also the middlewares working on that URL).
Looking at the Lumen's documentation I can see that there is no getJson, my bad. You have to use $this->json('GET' instead.
I've a multisite installation of Drupal 8, the "main" website expose some REST webservices, locally i've some troubles on testing them, because there's no way for the various sites to see each other, when i try to do something like that
try {
$response = $this->httpClient->get($this->baseUri . '/myendpoint', [
'headers' => [
'Accept' => 'application/json',
'Content-type' => 'application/hal+json',
],
'query' => [
'_format' => 'json',
'myparameters' => 'value'
],
]);
$results = $this->serializer->decode($response->getBody(), 'json');
}
catch (RequestException $e) {
$this->logger->warning($e->getMessage());
}
return $results;
I always receive a timeout and there's no way i can make it work, i've my main website with the usual url project.ddev.site (and $this->baseUri is https://myproject.ddev.site ) and all the other websites are in the form subsite.ddev.local
If i ssh in the project and run ping myproject.ddev.site i see 172.19.0.6
I don't understand why they cannot see each other...
Just for other people who can have a similar problem: my issue was with xdebug i have it with the autoconnect, so when the request from the subsite to the main site was made, it get stuck somewhere (phpstorm didn't stop anywhere by the way) so it made the request time out.
By disabling, or configuring only for the subdomain, and avoiding it to accept the external connenction from unconfigured servers (in phpstorm) it started working, still have to do some work as i need to debug "both sides" of the request, but in this way i can work with that...
I've not thought before to try disabling xdebug because actually it didn't came into my mind...
I'm currently writing a RESTful API in Cakephp 3 whereby I need to test a POST operation through http://host.com/api/pictures. The code for the test:
<?php
namespace App\Test\TestCase\Controller;
use App\Controller\Api\UsersController;
use Cake\TestSuite\IntegrationTestCase;
use Cake\Network\Http\Client;
use Cake\Network\Http\FormData;
class ApiPicturesControllerTest extends IntegrationTestCase{
public $fixtures = [
'app.users',
'app.comments',
'app.albums',
'app.users_albums'
];
public function testAdd(){
// $data = new FormData();
$accessToken ='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjksImV4cCI6MTQ1NzYyOTU3NH0.NnjXWEQCno3PUiwHhnUCBjiknR-NlmT42oPLA5KhuYo';
$http = new Client([
'headers' => ['Authorization' => 'Bearer ' . $accessToken, 'Content-Type' => 'application/json']
]);
$data = [
"album_id" => 1,
"link" => "http://www.google.com",
"description" => "testtesttest",
"favorite" => true
];
$result = $http->post('http://vecto.app/api/pictures/add.json', $data, ['type'=>'json']);
// $this->assertResponseOk();
// debug($result);
}
}
When I try to debug the result I get a 'cannot add or update child row' while I'm sure the responding id does exists
(the fixtures does have the id's too). Additionally, the log indicates that it only tries to insert the create/update rows. Therefore, I'm pretty sure the data is ignored but however I can't find a solution. I already tried different combination of headers like only application/json for Accept, application/json for Content-Type etc. I'm using the CRUD plugin for Cakephp to pass the data to an add function.
Postman output
Furthermore, I tried the Postman Chrome plugin to save the data and that actually does work. Does anyone know what I'm doing wrong in the test?
That's not how the integration test case is ment to be used. You are dispatching an external, real request, which will leave the test environment, while you should use the request dispatching tools that the integration test case supplies, that is
IntegrationTestCase::get()
IntegrationTestCase::post()
IntegrationTestCase::put()
etc...
These methods will dispatch simulated requests that do not leave the test environment, which is crucial for things to work properly, as you want to use test connections, inspect possible exceptions, have access to the used session, etc...
ie, you should do something along the lines of
$accessToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjksImV4cCI6MTQ1NzYyOTU3NH0.NnjXWEQCno3PUiwHhnUCBjiknR-NlmT42oPLA5KhuYo';
$this->configRequest([
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
'Content-Type' => 'application/json'
]
]);
$data = [
"album_id" => 1,
"link" => "http://www.google.com",
"description" => "testtesttest",
"favorite" => true
];
$this->post('/api/pictures/add.json', json_encode($data));
Note that a content type of application/json will require you to send raw JSON data! If you don't actually need/want to test parsing of raw input, then you could skip that header, and pass the array as data instead.
See also
Cookbook > Testing > Controller Integration Testing
API > \Cake\TestSuite\IntegrationTestCase
I am generating PDF reports about the bundle knp_snappy, as it says in the title, so wkhtmltopdf command works perfectly in command mode but it does in the bundle, I get the following error:
The exit status code '127' says something went wrong:
stderr, "PROT_EXEC | PROT_WRITE failed.
I understand it is something related to permissions but do not know what I have to change to make it work.
my config.yml
knp_snappy:
pdf:
enabled: true
binary: "/usr/bin/wkhtmltopdf"
options: []
My controller:
$html = $this->renderView('PanelBundle:Default:hotel-booking-summary.pdf.html.twig', array(
'summary' => $summary,
'agency' => $agency
));
return new Response(
$this->get('knp_snappy.pdf')->getOutputFromHtml($html),
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="file.pdf"'
)
);
I hope you can help me, greetings and thank you very much.
pls show
ls -la /usr/bin/wkhtmltopdf
Actually you can try set permissions something like
sudo chown %your_ssh_user%:%your_www_group% /usr/bin/wkhtmltopdf
I'm trying to do BDD testing on an upload method. I'm using Behat with Mink in a symfony2 project.
Now I'm able to do simple request with this client:
$this->client = $this->mink->getSession('goutte')->getDriver()->getClient();
and
$this->client->request("POST", $url, array('content-type' => 'application/json'), array(), array(), $fields);
without any issue.
How to do a request with a file? I tried this:
$file = new \Symfony\Component\HttpFoundation\File\UploadedFile($path, "video");
$fields = json_encode($table->getColumnsHash()[0]);
$this->client->request("POST", $url, array('content-type' => 'multipart/form-data'), array($file), array(), $fields);
And the error I receive is:
PHP Fatal error: Call to undefined method
GuzzleHttp\Stream\Stream::addFile()
What is the mistake?
Thanks!
Ok finally I found the answer. Hope that helps someone.
To upload a file, the correct way is:
$fields = $table->getColumnsHash()[0]; //array('name' => 'test', 'surname' => 'test');
$fields["file"] = fopen($path, 'rb');
$this->client->request("POST", $url, array('Content-Type => multipart/form-data'), array(), array(), $fields);
The trick is that you must not use the fourth parameter of the Goutte request, but you have to pass all fields as body raw data.
I don't know about Guzzle upload but simple upload works like below. You can remove unnecessary bits.
Note: I would suggest you to keep dummy image files in project folder because if there are a lot of developers work on same project they would have exactly same folder structure so image would be accessible. I've seen some guys selecting an image from their desktop which differs from person to person so tests fail.
files_path below must point to your project directory and it should exist as e.g. /var/www/html/myproject/test/build/dummy/
behat.yml
default:
context:
class: Site\FrontendBundle\Features\Context\FeatureContext
parameters:
output_path: %behat.paths.base%/build/behat/output/
screen_shot_path: %behat.paths.base%/build/behat/screenshot/
extensions:
Behat\Symfony2Extension\Extension:
mink_driver: true
kernel:
env: test
debug: true
Behat\MinkExtension\Extension:
base_url: 'http://localhost/local/symfony/web/app_test.php/'
files_path: %behat.paths.base%/build/dummy/
javascript_session: selenium2
browser_name: firefox
goutte: ~
selenium2: ~
paths:
features: %behat.paths.base%/src
bootstrap: %behat.paths.features%/Context
Assuming that you have jpg.jpg under /var/www/html/myproject/test/build/dummy/ folder as below.
Example feature for upload:
Feature: Create League
In order to upload a file
As a user
I should be able to select and upload a file
#javascript
Scenario: I can create league
Given I am on "/"
When I attach the file "jpg.jpg" to "league_flag"
And I press "Submit"
Then I should see "Succeeded."