Bear with me, new to testing.
So, I have this current structure of middlewares:
class IsActive
{
public function handle($request, Closure $next)
{
if (self::active()) {
return $next($request);
}
Auth::guard('web')->logout();
return redirect('/');
}
protected function active()
{
if (Auth::guard('web')->check()) {
$state = Auth::guard('web')->user()->state;
if ($state == 'enabled') {
return true;
}
}
return false;
}
}
class IsAdmin extends IsActive
{
public function handle($request, Closure $next)
{
if (parent::active()) {
if (Auth::guard('web')->check()) {
$role = Auth::guard('web')->user()->role->name;
if ($role == 'admin' || $role == 'superAdmin') {
return $next($request);
}
}
return redirect('/');
}
Auth::guard('web')->logout();
return redirect('/');
}
}
This is the route
Route::group(['middleware' => 'admin'], function () {
Route::get('/', 'ReportingController@reportingPage');
});
//Its registered on RouteServiceProvider that these routes require IsActive and this specific route needs for the admin
And in the Reporting Controller, I got this function
public function reportingPage(Request $request) {
return view('reporting.reporting');
}
So good so far. If the user has access, great, if not it gets redirected.
Now for the testing, I want to validate if an admin can view it (and an unauthorized can't, but for this question im trying to figure out the admin)
protected $user;
public function setUp()
{
parent::setUp();
$this->user = new \App\Models\User(['role_id' => 6, //admin
'name' => 'Admin',
'user' => 'admin',
'email' => '[email protected]',
'state' => 'enabled',
'deleted_at' => null]);
$this->be($this->user);
}
public function testCanAccessReportingPage()
{
$this->get("/reporting/")->assertStatus(200);
}
This is the error I'm getting and I'm trying to figure out whats the process. Obviously I'm doing something wrong or I'm forgetting something, so tips and ideas on how to test this authorization are greatly appreciated.
Edit:
After an answer that was deleted envolving a bit of refactor and some attempts, I've determined that Auth::guard('web')->user()
has a user, Auth::guard('web')->user()->role()
is null on testing environment. I've solved by loading the relationship but the question I now have is: Why does this happen on test environment.
May be created user (mocked) is not used in $this context.
If you look at documentation https://laravel.com/docs/5.6/http-tests#session-and-authentication, you see method
$this->actingAs($user)
Full example:
<?php
use App\User;
class ExampleTest extends TestCase
{
public function testApplication()
{
$user = factory(User::class)->create();
$response = $this->actingAs($user)
->withSession(['foo' => 'bar'])
->get('/');
}
}
I have changed your code little bit. Removed duplicate code and added lazy eager loading for user role $user->load('role')
. Try it
class IsAdmin
{
public function handle($request, Closure $next)
{
//no need to check active again, because you said IsActive is already applied in RouteServiceProvider
$user = Auth::guard('web')->user();
$user->load('role'); //lazy eager load
$role = $user->role->name;
if ($role == 'admin' || $role == 'superAdmin') {
return $next($request);
}
Auth::guard('web')->logout();
return redirect('/');
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With