Pixelairport's avatar

Filament Pest test throws 403 for actingUser

Hi. I create an package to create authors and want to test it. I use orchestra, pest and filament. This is my code:

use Workbench\App\Models\User;

test('Only users can access authors.', function () {
    $this->get('/admin/authors')->assertStatus(302)->assertRedirect('/admin/login');
    
    $this->actingAs(User::factory()->create());

    $this->get('/admin/authors')->assertStatus(200);
});

When I visit my application everything works. The admin/authors route redirects to login and when Im logged in I see the page. But the test says:

Expected response status code [200] but received 403.
Failed asserting that 403 is identical to 200.

I also added the policy to the package provider:

    public function bootingPackage(){
        Gate::policy(Author::class, AuthorPolicy::class);
    }

Just to be sure it is loaded. Does anybody have an idea what is the problem here?

1 like
10 replies
LaryAI's avatar
Level 58

This is a common situation when testing Filament with Pest (and/or Orchestra): you get a 403 instead of 200 after calling $this->actingAs(). Here are typical reasons and how to solve it:


1. Your User Lacks Proper Roles or Permissions

In Filament, you usually need a user who can access the Filament admin panel. Merely being authenticated is not enough; by default, Filament calls canAccessPanel() or checks permissions/roles.

Solution:
Either, assign a specific role or permission to your test user, or implement a canAccessFilament/canAccessPanel method that returns true for your test user.

Option A: Add can_access_filament attribute or role

$user = User::factory()->create([
    // Fill any attributes required for access
    'is_admin' => true, // if your FilamentServiceProvider uses this attribute
]);

$this->actingAs($user);

Option B: Quickly Enable Access in Your User Model (for tests)

Add this to your User model (you can use a trait or directly):

public function canAccessFilament(): bool
{
    return true;
}

Option C: If Using Permissions/Roles

If you have Spatie's laravel-permission package:

$user = User::factory()->create();
$user->assignRole('admin'); // or whatever your gate requires
$this->actingAs($user);

2. Policies/Gates Preventing Access

Check your AuthorPolicy and ensure that the user can viewAny or view authors if the route requires it. If your policy returns false by default for unprivileged users, your test user ends up forbidden.

Double check:
Does your policy check for a certain ability or role? Make your test user pass those checks!


3. Testing Environment and Guards

Make sure that you're using the same authentication guard as Filament (by default, Filament uses the web guard). In Pest, make sure you're not overriding guards accidentally.


4. Updated Test Example

Your working test (assuming Filament uses canAccessFilament):

use Workbench\App\Models\User;

test('Only users can access authors.', function () {
    $this->get('/admin/authors')->assertStatus(302)->assertRedirect('/admin/login');
    
    $user = User::factory()->create([
        // Add any attributes required for admin access
    ]);
    // Optionally, add: $user->assignRole('admin');

    $this->actingAs($user);

    $this->get('/admin/authors')->assertStatus(200);
});

If you're using custom access logic, implement it on your User model just for tests.


5. Summary Checklist

  • ✅ User model is recognized as able to access the Filament admin panel
  • ✅ Any relevant policy/role/permission is satisfied
  • ✅ You're using the correct guard

Reference:


If you implement canAccessFilament on your User model (or whatever Filament expects), your test should pass.

Pixelairport's avatar

In my policy each method returns true. Also

    public function canAccessPanel(Panel $panel): bool
    {
        if ($panel->getId() === 'admin') {
            return true;
        }

        return true;
    }

is set in my model. But it is still not working.

1 like
Pixelairport's avatar

I just dont understand why in the first check I get the 302 and in the second a 404?

test('Only users can access authors.', function () {

    $url = \LaravelEz\Authors\Filament\Resources\AuthorResource::getUrl('index');

    $this->get($url)->assertStatus(302);

    $user = User::factory()->create();

    $this->actingAs($user);

    $this->withoutExceptionHandling();

    $this->get($url)->assertStatus(200);

});

This is my error:

 
  at vendor/laravel/framework/src/Illuminate/Foundation/Application.php:1426
    1422▕         if ($code == 404) {
    1423▕             throw new NotFoundHttpException($message, null, 0, $headers);
    1424▕         }
    1425▕ 
  ➜ 1426▕         throw new HttpException($code, $message, null, $headers);
    1427▕     }
    1428▕ 
    1429▕     /**
    1430▕      * Register a terminating callback with the application.

      +47 vendor frames 
  48  tests/Feature/ServiceProviderTest.php:20


Is it I use orchestra testbench? Is there a problem that user policy is not right bound? Because I still get 403.

1 like
Pixelairport's avatar

It is my 3rd day with my testing problem and I now build a new plugin, which is only for check what is wrong with my test. I hope somebody have a bit time to check https://github.com/laravel-ez/laratest

It is only a test and problem is currently the line 20 in tests/Feature/ExampleTest.php

$this->get('admin')->assertStatus(200);

I get:

  Illuminate\Support\ViewErrorBag::put(): Argument #2 ($bag) must be of type Illuminate\Contracts\Support\MessageBag, null given, called in ..eatures/SupportValidation/SupportValidation.php on line 21

I now try to find the way with this code, because my other module there are too much needless files to check where the problem is. In my project it now seems to work. Means when im in root directory and do artisan test it seems to work now. But in my package i still have the problem when ich got to my package folder and do ./vendor/bin/pest.

1 like
Pixelairport's avatar

Day 4 :) ... I fixed the problem but now have another one. For all with this error above. The providers for the test must be in the correct order, which is the alphabet order (https://github.com/laravel-ez/laratest/blob/master/tests/TestCase.php) . Now I get this error

Undefined variable $logo ...
... at vendor/orchestra/testbench-core/laravel/storage/framework/views/88986042349707f85b2324601b4f675f.php:18

Did I miss a provider or something in my setup? When I use the browser everything works. But the test throws this error. I dont want to set logo manual, because when I did it there are other variables I have to set... There must be a way to load all from filament directly.

1 like
Pixelairport's avatar

Day 5 with the same problem. When I set $logo var in my test, then the next error comes that $content is needed. I tested the panel and it seems everything is loaded.

This is my test and the first test works and the second still says that $logo is missing:

test('Guest can´t access admin panel.', function () {
    $this->get('admin')->assertStatus(302);
});

test('User can access admin panel', function () {
    $this->withoutExceptionHandling();

    $this->actingAs(User::create([
        'name' => 'Test User',
        'email' => '[email protected]',
        'password' => bcrypt('password'),
    ]));

    $this->get('admin')->assertSuccessful();
});

When I move the test to main application and test it there it works, but when I got to /modules/laratest and do the pest test I still get: Undefined variable $logo

1 like
vincent15000's avatar

You should check the form requests, the roles, ...

You only show the code of your test, but it's not sufficient for us to help you.

If you get a 403 error, you necessarily have a policy or something similar that prevents the user from accessing a resource.

If you get an error saying that the $logo variable is missing, it's really because it's missing.

Either your test is poorly written, or there’s a bug in your application.

1 like
Pixelairport's avatar
Pixelairport
OP
Best Answer
Level 12

Thx @vincent15000 for the answer. To make it short... How I tested and understand workbench was wrong.

After one week with this problem and a few weeks with testing, I met yesterday a friend and we together learned testing with pest, workbench in filament modules. We read docs, checked repos from others and a lot more. We learned more in one day together than in a few weeks alone.

1 like
Pixelairport's avatar

There were multiple problems. One problem was, that I implemented and used orchestra the wrong way. The correct way is to install modules in a seperate directory, which is not connected to a real laravel application. The namespaces will make problems, when I am in a module directory in laravel, but also have workbench with another instance of laravel. I also forgot to load providers for filament in the yaml file. I tried to load them in my TestCase file for Pest. Maybe that was the main problem. I cant say what were the other problems, because when I fixed one thing I got another error. But I started completely from zero and read the docs. In the end it just worked. There were a lot problems, because the topic was complete new. But it helped to learn this together with somebody who was on the same level. We talked about the thing we read and testet together... Sometimes when you learn it alone you think your way is right, even it isnt.

Please or to participate in this conversation.