Your assertion is a 401 response code; but you cannot get this response code unless you allow Laravel to handle the AuthenticationException (it does not handle the exception if you turn off exception handling). If you dive into the framework here, you will see that this is where the 401 status code comes from.
Nov 15, 2020
5
Level 6
Why my test fails when I set $this->withoutExceptionHandling()?
I created a test for my app and find something weird with the authorization stuff which is failing when I enable the exception handling by command described by the title above.
This is the result when $this->withoutExceptionHandling() commented out:
PASS Tests\Unit\SubscriptionTest
✓ subscription table has expected columns
✓ subscription table are seedable through factory
✓ subscription table are seedable through seeder
✓ subscription belongs to an author
✓ subscription has many subscribers
PASS Tests\Feature\SubscriptionTest
✓ subscription should be indexable by guest user
✓ subscription should be showable by guest user
✓ subscription should be updated by internal user
✓ subscription should not be created by guest user
✓ subscription should not be updated by guest user
✓ subscription should not be updated by non internal user
✓ subscription should not be deleted by guest user
Tests: 12 passed
Time: 17.91s
And this is when $this->withoutExceptionHandling() uncommented:
PASS Tests\Unit\SubscriptionTest
✓ subscription table has expected columns
✓ subscription table are seedable through factory
✓ subscription table are seedable through seeder
✓ subscription belongs to an author
✓ subscription has many subscribers
FAIL Tests\Feature\SubscriptionTest
✓ subscription should be indexable by guest user
✓ subscription should be showable by guest user
✓ subscription should be updated by internal user
⨯ subscription should not be created by guest user
⨯ subscription should not be updated by guest user
⨯ subscription should not be updated by non internal user
⨯ subscription should not be deleted by guest user
---
• Tests\Feature\SubscriptionTest > subscription should not be created by guest user
Illuminate\Auth\AuthenticationException
Unauthenticated.
at C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:82
78▕ * @throws \Illuminate\Auth\AuthenticationException
79▕ */
80▕ protected function unauthenticated($request, array $guards)
81▕ {
➜ 82▕ throw new AuthenticationException(
83▕ 'Unauthenticated.', $guards, $this->redirectTo($request)
84▕ );
85▕ }
86▕
1 C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:68
Illuminate\Auth\Middleware\Authenticate::unauthenticated(Object(Illuminate\Http\Request))
2 C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:42
Illuminate\Auth\Middleware\Authenticate::authenticate(Object(Illuminate\Http\Request))
• Tests\Feature\SubscriptionTest > subscription should not be updated by guest user
Illuminate\Auth\AuthenticationException
Unauthenticated.
at C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:82
78▕ * @throws \Illuminate\Auth\AuthenticationException
79▕ */
80▕ protected function unauthenticated($request, array $guards)
81▕ {
➜ 82▕ throw new AuthenticationException(
83▕ 'Unauthenticated.', $guards, $this->redirectTo($request)
84▕ );
85▕ }
86▕
1 C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:68
Illuminate\Auth\Middleware\Authenticate::unauthenticated(Object(Illuminate\Http\Request))
2 C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:42
Illuminate\Auth\Middleware\Authenticate::authenticate(Object(Illuminate\Http\Request))
• Tests\Feature\SubscriptionTest > subscription should not be updated by non internal user
Illuminate\Auth\Access\AuthorizationException
This action is unauthorized.
at C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Access\Response.php:119
115▕ */
116▕ public function authorize()
117▕ {
118▕ if ($this->denied()) {
➜ 119▕ throw (new AuthorizationException($this->message(), $this->code()))
120▕ ->setResponse($this);
121▕ }
122▕
123▕ return $this;
1 C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Access\Gate.php:323
Illuminate\Auth\Access\Response::authorize()
2 C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authorize.php:43
Illuminate\Auth\Access\Gate::authorize("update")
• Tests\Feature\SubscriptionTest > subscription should not be deleted by guest user
Illuminate\Auth\AuthenticationException
Unauthenticated.
at C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:82
78▕ * @throws \Illuminate\Auth\AuthenticationException
79▕ */
80▕ protected function unauthenticated($request, array $guards)
81▕ {
➜ 82▕ throw new AuthenticationException(
83▕ 'Unauthenticated.', $guards, $this->redirectTo($request)
84▕ );
85▕ }
86▕
1 C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:68
Illuminate\Auth\Middleware\Authenticate::unauthenticated(Object(Illuminate\Http\Request))
2 C:\Users\Fukka\Documents\Laravel\prismahr\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:42
Illuminate\Auth\Middleware\Authenticate::authenticate(Object(Illuminate\Http\Request))
Tests: 4 failed, 8 passed
Time: 17.83s
And here is my tests if you guys curious:
<?php
namespace Tests\Feature;
use App\Models\Subscription;
use App\Models\User;
use Database\Seeders\RolesAndPermissionSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use Spatie\Permission\PermissionRegistrar;
class SubscriptionTest extends TestCase
{
use RefreshDatabase;
public function setUp(): void
{
parent::setUp();
$this->withoutExceptionHandling();
$this->app->make(PermissionRegistrar::class)->registerPermissions();
$this->seed(RolesAndPermissionSeeder::class);
}
public function testSubscriptionShouldBeIndexableByGuestUser()
{
$subscriptions = Subscription::factory(3)->create()->toArray();
$this->getJson(route('subscriptions.index'))
->assertOk()
->assertExactJson($subscriptions);
}
public function testSubscriptionShouldBeShowableByGuestUser()
{
$subscription = Subscription::factory()->create();
$this->getJson(route('subscriptions.show', $subscription))
->assertOk()
->assertExactJson($subscription->toArray());
}
public function testSubscriptionShouldBeUpdatedByInternalUser()
{
$usr = User::factory()->create()->assignRole('internal');
$old = Subscription::factory()->create(['user_id' => $usr->id]);
$new = Subscription::factory()->make(['user_id' => $usr->id])->toArray();
$this->actingAs($usr, 'api')
->putJson(route('subscriptions.update', $old), $new)
->assertOk()
->assertJsonFragment($new);
}
public function testSubscriptionShouldNotBeCreatedByGuestUser()
{
$subscription = Subscription::factory()->make()->toArray();
$this->postJson(route('subscriptions.store', $subscription))
->assertStatus(401)
->assertJsonMissingExact($subscription)
->assertExactJson(['message' => 'Unauthenticated.']);
}
public function testSubscriptionShouldNotBeUpdatedByGuestUser()
{
$old = Subscription::factory()->create();
$new = Subscription::factory()->make()->toArray();
$this->putJson(route('subscriptions.update', $old), $new)
->assertStatus(401)
->assertExactJson(['message' => 'Unauthenticated.']);
}
public function testSubscriptionShouldNotBeUpdatedByNonInternalUser()
{
$usr = User::factory()->create()->assignRole('customer');
$old = Subscription::factory()->create(['user_id' => $usr->id]);
$new = Subscription::factory()->make(['user_id' => $usr->id])->toArray();
$this->actingAs($usr, 'api')
->putJson(route('subscriptions.update', $old), $new)
->assertForbidden()
->assertJsonMissingExact($new);
}
public function testSubscriptionShouldNotBeDeletedByGuestUser()
{
$subscription = Subscription::factory()->create();
$this->deleteJson(route('subscriptions.destroy', $subscription))
->assertStatus(401)
->assertJsonMissingExact($subscription->toArray())
->assertExactJson(['message' => 'Unauthenticated.']);
}
}
Level 104
Please or to participate in this conversation.