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.
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.
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.
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.