I’ve got a JSON login query which works in curl (ie I’m sending the data and it finds the user). I want to create a behat test to check it, but I cannot reproduce it in my behat test, and the test fail. I made sure that the database was correctly set up (the user and their password are correctly set), but the error message tells me that the fields are missing anyway.
My curl call (that succeeds):
curl --request POST
--url http://localhost/login
--header 'content-type: application/json'
--data '{
"username": "my_username",
"password": "my_password"
}'
My loginController:
<?php
declare(strict_types=1);
namespace AppController;
use AppEntityUser;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
use SymfonyComponentSecurityHttpAttributeCurrentUser;
class LoginController extends AbstractController
{
#[Route('/login', name: 'app_login', methods: ['POST'])]
public function index(#[CurrentUser] ?User $user): Response
{
if ($user === null) {
return $this->json([
'message' => 'An error occured',
'errors' => ['missing credentials'],
], Response::HTTP_UNAUTHORIZED);
}
$token = 'RANDOM_TOKEN';
return $this->json([
'user' => $user->getUserIdentifier(),
'token' => $token,
]);
}
}
My behat scenario and the associated function:
Scenario: Login successful
Given I am an unlogged user
And these users already exist
| email | username | password |
| [email protected] | test | test_pwd |
When I POST to the login route with the following JSON data:
| username | password |
| test | test_pwd |
Then the response status code should be 200
And the response should be valid JSON
And the "user" key should contain "test"
And the "token" key should not be empty
/**
* @When I :verb to the :route route with the following JSON data:
*/
public function iVerbToTheRouteWithJSONData(string $verb, string $route, TableNode $table): void
{
Assert::count($table->getLines(), 2); // One for the header, one for the data
$params = [];
foreach ($table as $row) {
Assert::isArray($row);
$params = $row;
}
$encoded = json_encode($params);
$this->response = $this->kernel->handle(
Request::create($route, $verb, [], [], [], ['Content-Type' => 'application/json'], $encoded)
);
}
If I dump de $encoded
it looks exactly like what I want ({"username":"test","password":"test_pwd"}
).
If I dump the response’s content, I have this error message, which is the one Symfony sends when the fields are missing :
{"message":"An error occured","errors":["missing credentials"]}
I feel like I’m missing a simple thing in my request creation, but I’m not able to find what.
2
Answers
If basic authent is enough for you, try this :
See https://symfony.com/doc/current/http_client.html for more information 😉
In Symfony’s
Request::create
method, headers should be specified using the correct server parameter keys. Specifically, theContent-Type
header should be set asCONTENT_TYPE
in the server parameters array, notContent-Type
.