I am trying to test my Laravel API, but in some cases where I submit a post request I receive a 401 error with the message "Unauthenticated". All the GET requests that are protected are properly accessible and certain POST requests like submitting a status are also doing fine. Why do I get the 401 error in some cases, but not in others?
Here are the files
API Routes
Route::group(['middleware' => ['auth:sanctum']], function() {
Route::get('logout', [MantelAuthController::class, 'logout']);
Route::post('status', [MantelController::class, 'status']);
Route::post('deleteAccount', [MantelController::class, 'deleteAccount']);
});
Logout test
public function test_logoutAPI()
{
$testEmail = getenv('TEST_EMAIL_API');
$testPassword = getenv('TEST_PASSWORD_API');
$response = $this->post('/api/login', [
'email' => $testEmail,
'password' => $testPassword
]);
$auth = $response->assertStatus(201)->decodeResponseJson()['token'];
$response = $this->get('/api/logout',
[
'Authorization' => "Bearer ".$auth
]);
$response->assertStatus(200);
}
Send status test
public function test_post_status()
{
$testEmail = getenv('TEST_EMAIL_API2');
$testPassword = getenv('TEST_PASSWORD_API');
// log in
$response = $this->post('/api/login', [
'email' => $testEmail,
'password' => $testPassword
]);
$auth = $response->assertStatus(201)->decodeResponseJson()['token'];
// get correct datetime
$response = $this->get('/api/getData',
[
'Authorization' => "Bearer ".$auth
]);
$date= $response->assertStatus(200)->decodeResponseJson()['date'];
// submit post request
$response = $this->post('/api/status',
[
'Authorization' => "Bearer ".$auth,
'status' => "secure",
'date' => $date
]);
$response->assertCreated();
}
Delete Account test
public function test_delete_account()
{
$DeletedEmail = "[email protected]";
$DeletedPassword = "temporary";
$response = $this->post('/api/login', [
'email' => $DeletedEmail,
'password' => $DeletedPassword
]);
$auth = $response->assertStatus(201)->decodeResponseJson()['token'];
$response = $this->withHeaders(['Accept' => 'application/json'])
->post('/api/deleteAccount', [
'Authorization' => "Bearer ".$auth,
'password' => $DeletedPassword
]);
$response->assertSuccessful();
}
CodePudding user response:
Part of your issue is you are mixing your header data and post data. You should try using withHeaders
https://laravel.com/docs/8.x/http-tests#customizing-request-headers
$response = $this->withHeaders([
'X-Header' => 'Value',
])->post('/user', ['name' => 'Sally']);
You also don't have to actually login via your API route request for every test as this is pretty inefficient. You should have a test for your login API route, but you should be accessing the user model and using actingAs
to set the authentication for your other requests.
https://laravel.com/docs/5.2/testing#sessions-and-authentication
<?php
class ExampleTest extends TestCase
{
public function testApplication()
{
$user = factory(App\User::class)->create();
$this->actingAs($user)
->withSession(['foo' => 'bar'])
->visit('/')
->see('Hello, '.$user->name);
}
}