Search code examples
phplaravellaravel-5.7php-7.2phpunit

Passing class name to view policy on controller index method returns error that too few arguments were passed


I'm trying to test a policy for the index method of my controller. I'm passing the class name into the authorize helper, but I'm receiving a 500 status and an error that says

1) Tests\Feature\FunderFeatureTest::an_admin_should_be_able_to_view_a_list_of_funders Symfony\Component\Debug\Exception\FatalThrowableError: Too few arguments to function App\Policies\FunderPolicy::view(), 1 passed in /home/vagrant/code/rtl/vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php on line 614 and exactly 2 expected

What am I doing wrong? All other policies work (including the create() and store() methods which do not require a model). I realize this is similar to many other questions on SO, however the majority seem to be due to the fact that people weren't passing the class name to the authorize method or the problem occurs on a different controller method (such as update()). My apologies if this specific question was asked before, I've been researching this off an on for two weeks and can't quite find the answer I'm looking for.

FundersController.php

namespace App\Http\Controllers;

use App\Funder;
use Illuminate\Http\Request;

class FundersController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index()
    {
        $this->authorize('view', Funder::class);

        return view('funders.index', [
            'funders' => Funder::all(),
        ]);
    }
}

FunderPolicy.php

namespace App\Policies;

use App\User;
use App\Funder;
use Illuminate\Auth\Access\HandlesAuthorization;

class FunderPolicy
{
    use HandlesAuthorization;
    public function view(User $user, Funder $funder)
    {
        return ($user->isAdmin() || $user->isSuperAdmin());
    }
}

FunderFeatureTest.php (For reference)

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class FunderFeatureTest extends TestCase
{
    use RefreshDatabase;
    /** @test */
    public function an_admin_should_be_able_to_view_a_list_of_funders()
    {
        $this->withoutExceptionHandling();
        $this->signIn('admin');

        $this->get('/funders')
            ->assertOk();
    }

    /** @test */
     public function a_user_should_not_be_able_to_view_a_list_of_funders()
    {
        $this->signIn();

        $this->get('/funders')
            ->assertStatus(403);
    }
}

Solution

  • I'm not sure if this is the appropriate way to get this to work, but passing a new instance of a Funder model instead of the class name seemed to do the trick.

    Changing $this->authorize('view', Funder::class); to $this->authorize('view', new \App\Funder());