Back to Course |
Testing in Laravel 9 For Beginners: PHPUnit, Pest, TDD

Auth Test: Does user have access to the page?

Now, let's see how we can test the users and the access of logged-in users.


First, we must add a Middleware to the route.

routes/web.php:

Route::re('/', function () {
return view('home');
})->name('home');
 
Route::resource('products', ProductController::class)->middleware('auth');

After running the tests, we have three failed featured tests. The two passed tests are unit tests.

auth tests failed

We need to create a user using factories for each test function and perform the server request using that user. To achieve that there is method called actingAs which accepts the User Model.

tests/Feature/ProductsTest.php:

use App\Models\User;
 
class ProductsTest extends TestCase
{
use RefreshDatabase;
 
public function test_homepage_contains_empty_table(): void
{
$user = User::factory()->create();
 
$response = $this->get('/products');
$response = $this->actingAs($user)->get('/products');
 
$response->assertStatus(200);
$response->assertSee(__('No products found'));
}
 
public function test_homepage_contains_non_empty_table(): void
{
$product = Product::create([
'name' => 'Product 1',
'price' => 123,
]);
 
$user = User::factory()->create();
 
$response = $this->get('/products');
$response = $this->actingAs($user)->get('/products');
 
$response->assertStatus(200);
$response->assertDontSee(__('No products found'));
$response->assertSee('Product 1');
$response->assertViewHas('products', function (LengthAwarePaginator $collection) use ($product) {
return $collection->contains($product);
});
}
 
public function test_paginated_products_table_doesnt_contain_11th_record()
{
$products = Product::factory(11)->create();
$lastProduct = $products->last();
 
$user = User::factory()->create();
 
$response = $this->get('/products');
$response = $this->actingAs($user)->get('/products');
 
$response->assertStatus(200);
$response->assertViewHas('products', function (LengthAwarePaginator $collection) use ($lastProduct) {
return $collection->doesntContain($lastProduct);
});
}
}

Now we have all tests green again.

auth tests passed


Until now, we have tested one scenario in which logged-in users can access the page. We also need to test that unauthenticated users cannot access this page and also, after successful login, to redirect to the products page.

For this, let's create a general auth test.

php artisan make:test AuthTest

In this test class, we need to go to the /products page without any user and assert that the status code is 302, redirect, and that the user is redirected to the /login URL.

tests/Feature/AuthTest.php:

class AuthTest extends TestCase
{
public function test_unauthenticated_user_cannot_access_product()
{
$response = $this->get('/products');
 
$response->assertStatus(302);
$response->assertRedirect('login');
}
}

Now, we have six tests passed.

guest cannon access test

In the final test for this lesson, we will test a login form.

In this test, first, we must create a new user. Then, instead of a GET request, we will send a POST request and pass parameters as an array as in the form. Finally, assert the response status and redirect URL.

tests/Feature/AuthTest.php:

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
 
class AuthTest extends TestCase
{
use RefreshDatabase;
 
public function test_login_redirects_to_products()
{
User::create([
'name' => 'User',
'email' => 'user@user.com',
'password' => bcrypt('password123')
]);
 
$response = $this->post('/login', [
'email' => 'user@user.com',
'password' => 'password123'
]);
 
$response->assertStatus(302);
$response->assertRedirect('products');
}
 
// ...
}

By default, Breeze redirects to the / URL after successful authentication. This value is changed in the RouteServiceProvider.

app/Provides/RouteServiceProvider.php:

class RouteServiceProvider extends ServiceProvider
{
public const HOME = '/';
public const HOME = '/products';
 
// ...
}

And we have seven green tests.

login redirects to products test


Commit for this lesson