You cannot use a route without an url generator - symfony

i'm trying to implement the Hateoas with PaginatedRepresentation, like describe in documentation :
see bellow my controller :
$hateoas = HateoasBuilder::create()->build();
$paginatedCollection = new PaginatedRepresentation(
$collection,
$this->generateUrl('getUsers'), // route
array(), // route parameters
1, // page number
2, // limit
11 // total pages
);
return new Response($hateoas->serialize($paginatedCollection, 'json'),
200,
array('Content-Type' => 'application/json'));
but i got this error : You cannot use a route without an url generator

replaced :
$hateoas->serialize($paginatedCollection, 'json')
by
$this->get('serializer')->serialize($paginatedCollection, 'json')

Related

lumen - Why does PHPUnit register test returns 405?

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.

Facebook post wirth php error: (#200) The user hasn't authorized the application to perform this action

i want to post from my website to my facebook site. i have created a app for my site. I use this code (i replace data from my app with '[]'):
require_once 'lib/php-graph-sdk-5.4/src/Facebook/autoload.php';
// initialize Facebook class using your own Facebook App credentials
// see: https://developers.facebook.com/docs/php/gettingstarted/#install
$access_token = '[aaccesstoken]';
$config = array();
$config['app_id'] = '[appid]';
$config['app_secret'] = '[appsecret]';
$config['fileUpload'] = false; // optional
$fb = new \Facebook\Facebook($config);
// define your POST parameters (replace with your own values)
$params = array(
"access_token" => $access_token, // see: https://developers.facebook.com/docs/facebook-login/access-tokens/
"message" => "Test Message",
"link" => "http://www.frauen-styles.de",
"picture" => "http://www.frauen-styles.de/site/assets/files/3545/20.jpg",
"name" => "Test Name",
"caption" => "Caption",
"description" => "Beschreibung"
);
// post to Facebook
// see: https://developers.facebook.com/docs/reference/php/facebook-api/
try {
$ret = $fb->post('/me/feed', $params);
echo 'Successfully posted to Facebook';
} catch(Exception $e) {
echo $e->getMessage();
}
what i'm doing wrong? im administrator of the page. support tells me that no publish_pages is requiered for the app for admins. I only want to send a post from my website to my facebook-page.
support tells me that no publish_pages is requiered
As you can read in the API reference in the official docs, you do need publish_pages and manage_pages to post to a Page (as Page).
Docs: https://developers.facebook.com/docs/graph-api/reference/page/feed#publish

HTTP client Cakephp 3 ignores json body

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

Symfony profiler url to last request

Is there any url like
http://mysymfony.app/_profiler/LAST_ID?panel=db ???
Have no Symfony Profile Footer when profile a json API and it cost time to go back to the overview everytime.
There should be a response header called: "X-Debug-Token-Link" which is a direct link to the latest profiler. You can inspect that in google chrome devtools after each request.
There is no way to do this that I'm aware of. I checked the bundle and there's no route that seems to cover this.
It seems plausible to me, however, that you could write you own route and action for it. Start here and then I think the basic logic of your action would look like this
$token = array_pop($this->profiler->find(null, null, 1, null, null, null));
return new RedirectResponse(
$this->generator->generate(
'_profiler',
array('token' => $token, 'panel' => 'db')
),
302,
array('Content-Type' => 'text/html')
);

Testing File uploads in Symfony2

In the Symfony2 documentation it gives the simple example of:
$client->request('POST', '/submit', array('name' => 'Fabien'), array('photo' => '/path/to/photo'));
To simulate a file upload.
However in all my tests I am getting nothing in the $request object in the app and nothing in the $_FILES array.
Here is a simple WebTestCase which is failing. It is self contained and tests the request that the $client constructs based on the parameters you pass in. It's not testing the app.
class UploadTest extends WebTestCase {
public function testNewPhotos() {
$client = $this->createClient();
$client->request(
'POST',
'/submit',
array('name' => 'Fabien'),
array('photo' => __FILE__)
);
$this->assertEquals(1, count($client->getRequest()->files->all()));
}
}
Just to be clear. This is not a question about how to do file uploads, that I can do. It is about how to test them in Symfony2.
Edit
I'm convinced I'm doing it right. So I've created a test for the Framework and made a pull request.
https://github.com/symfony/symfony/pull/1891
This was an error in the documentation.
Fixed here:
use Symfony\Component\HttpFoundation\File\UploadedFile;
$photo = new UploadedFile('/path/to/photo.jpg', 'photo.jpg', 'image/jpeg', 123);
// or
$photo = array('tmp_name' => '/path/to/photo.jpg', 'name' => 'photo.jpg', 'type' => 'image/jpeg', 'size' => 123, 'error' => UPLOAD_ERR_OK);
$client = static::createClient();
$client->request('POST', '/submit', array('name' => 'Fabien'), array('photo' => $photo));
Documentation here
Here is a code which works with Symfony 2.3 (I didn't tried with another version):
I created an photo.jpg image file and put it in Acme\Bundle\Tests\uploads.
Here is an excerpt from Acme\Bundle\Tests\Controller\AcmeTest.php:
function testUpload()
{
// Open the page
...
// Select the file from the filesystem
$image = new UploadedFile(
// Path to the file to send
dirname(__FILE__).'/../uploads/photo.jpg',
// Name of the sent file
'filename.jpg',
// MIME type
'image/jpeg',
// Size of the file
9988
);
// Select the form (adapt it for your needs)
$form = $crawler->filter('input[type=submit]...')->form();
// Put the file in the upload field
$form['... name of your field ....']->upload($image);
// Send it
$crawler = $this->client->submit($form);
// Check that the file has been successfully sent
// (in my case the filename is displayed in a <a> link so I check
// that it appears on the page)
$this->assertEquals(
1,
$crawler->filter('a:contains("filename.jpg")')->count()
);
}
Even if the question is related to Symfony2, it appears in the top results when searching for Symfony4 in Google.
Instancing an UploadedFile works, but the shortest way I found was also actually in the official documentation:
$crawler = $client->request('GET', '/post/hello-world');
$buttonCrawlerNode = $crawler->selectButton('submit');
$form = $buttonCrawlerNode->form();
$form['photo']->upload('/path/to/lucas.jpg');
https://symfony.com/doc/current/testing.html#forms
I found this article, https://coderwall.com/p/vp52ew/symfony2-unit-testing-uploaded-file, and works perfect.
Regards
if you want to mock a UploadedFile without a client request, you can use:
$path = 'path/to/file.test';
$originalName = 'original_name.test';
$file = new UploadedFile($path, $originalName, null, UPLOAD_ERR_OK, true);
$testSubject->method($file);

Resources