Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

spencerfeng's avatar

Got 'This action is unauthorised.' error when testing a page even if the user is authorised

Hi,

When I act as an authorised user to test a page, I still get the 'This action is unauthorised.' error.

Below is the method in the testing file:

/** @test */
        
function an_admin_can_see_the_workshop_a_ticket_belongs_to_on_the_tickets_list_page()
    {
        //-------------------------------------
        // Arrange
        //-------------------------------------
        // 1. Create an admin
        $admin = factory(User::class)->create([
            'username' => 'testadmin',
            'email' => '[email protected]'
        ]);

        // 2. Create a customer
        $customer = factory(User::class)->create([
            'username' => 'testcustomer',
            'email' => '[email protected]'
        ]);

        // 3. Create an administrator role
        $adminRole = factory(Role::class)->create([
            'name' => 'administrator'
        ]);

        // 4. Create the 'read-tickets' permission
        $readTicketsPermission = factory(Permission::class)->create([
            'name' => 'read-tickets'
        ]);

        // 5. Create an account for the admin
        factory(Account::class)->create([
            'user_id' => $admin->id
        ]);

        // 6. Assign the 'read-tickets' permission to the 'administrator' role
        $adminRole->permissions()->attach($readTicketsPermission->id);

        // 7. Assign the user to the role
        $admin->roles()->attach($adminRole->id);

        // 8. Create a workshop topic
        $workshopTopic = factory(WorkshopTopic::class)->create([
            'name' => 'Exploring Water'
        ]);

        // 9. Create a workshop
        $workshop = factory(Workshop::class)->create([
            'date' => '20/10/2027',
            'topic_id' => $workshopTopic->id
        ]);

        // 10. Create an order
        $order = factory(Order::class)->create([
            'user_id' => $customer->id,
            'workshop_id' => $workshop->id
        ]);

        // 11. Create a ticket
        factory(Ticket::class)->create([
            'workshop_id' => $workshop->id,
            'order_id' => $order->id,
            'user_id' => $customer->id
        ]);

        //-------------------------------------
        // Act
        //-------------------------------------
        $this->withoutMiddleware()
             ->actingAs($admin)
             ->visit('dashboard/tickets');

        //-------------------------------------
        // Assert
        //-------------------------------------
        $this->see('20/10/2027 TOPIC: ' . $workshopTopic->name);
    }

Below is the controller method:

public function index()
    {
        $this->authorize('read-tickets');

        // The current user can view tickets...

        $tickets = Ticket::orderBy('created_at', 'desc')->paginate(10);
        return view('pages.backend.tickets.index', [
            'tickets' => $tickets
        ]);
    }

Thank you

0 likes
4 replies
KenoKokoro's avatar

"This action is unauthorised." Refers to the authorization you have using the Laravel Policy. Double check there. Maybe your roles and permissions aren't filled in the db correctly?

Use the seeInDatabase method in your test to validate their existance.

Hope this helps.

spencerfeng's avatar

Hi KenoKoKoro,

Thank you for your answer.

However, I have already tested if the user has the permission to perform the 'read-tickets' task and the user does have this permission.

In addition, if I just login as a user with the 'read-tickets' permission in the browser, I can see that page and there is no such 'This action is unauthorised' error.

So, I am really stuck there.

KenoKokoro's avatar

Maybe try set up some tool like xdebug on your editor, and debug that stuff to see what's going on behind the scenes.

spencerfeng's avatar

Hi @KenoKokoro,

Thank you for your reply.

I think I just found my problem:

This is how I set up my ACL in the AuthServiceProvider:

/**
     * Register any authentication / authorization services.
     *
     * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate
     * @return void
     */
    public function boot(GateContract $gate)
    {
        $this->registerPolicies();

        foreach ($this->getPermissions() as $permission) {

            $gate->define($permission->name, function($user) use ($permission) {

                // check if the user has the roles that the permission is associated with
                return $user->hasRole($permission->roles);

            });
        }
    }

    /**
     * Get all permissions
     */
    protected function getPermissions()
    {
        try {
            return Permission::with('roles')->get();
        } catch (\Exception $e) {
            return [];
        }
    }

It looks like that, in the test, the getPermissions() method always returns an empty array, while in the browser, once the permissions table is not empty, getPermissions() method will return an array containing permissions.

I am just wondering if the boot method in AuthServicerProvider is only run once in the beginning of the

function an_admin_can_see_the_workshop_a_ticket_belongs_to_on_the_tickets_list_page() 
{
  ...
}

testing method.

Another question, so when this line of code:

$this->visit('dashboard/tickets') 

is executed, the Laravel serviceprovider is not initialised?

Thank you

Please or to participate in this conversation.