I have index
method in controller like this
public function index()
{
$this->authorize('index', Contact::class);
....
}
and index
method in ContactPolicy
public function index()
{
return Auth::user()->can('view_Contact');
}
and test method like this
/** @test */
public function a_user_without_permission_can_not_see_contacts()
{
$this->login(['no_permission']);
$this->get('/contacts')
->assertStatus(403);
}
When I run my test show me this error
1) Tests\Feature\AccountTest::a_user_without_permission_can_not_see_contacts Illuminate\Auth\Access\AuthorizationException: This action is unauthorized.
Note1: When I change My controller to this it work correctly and show me green
public function index()
{
if(Auth::user()->can('view_Contact')){
........
}else
return response()->view('403',['msg' => 'you_not_have_not_permission'])->setStatusCode(403) ;
Note2:
In login method in test class I send user permissions parameters and it work correctly.
the
authorize
method throws an exception if the user is not authorized. you need to use@expectesException
or similar methods to signal your test to expect an exception.Or, you can add a condition to your Handler class to catch this kind of exception and return a 403 response
edit: more explanation
when you call
authorize
method and the user does not have permission, the program throws an exception. when a user is calling the api, the exception is translated to a response with 403 status and shown to the user, but when you are calling the api from within the program itself, the exception is thrown and the program halts, hence there would be no JSON response whatsoever. To handle this situation, you have two options:1- if you decide not to change your program, then instead of expecting a response with a specific status, you should tell your test to expect an AuthorizationException thrown. you can read how to do this hear
2- you can change your code so that instead of delegating the task of handling the exception to Laravel, you do it yourself in the Handler class and prepare a JSON response with 403 status and then your test should be run correctly.