In this episode, we're going to take FilamentPHP a step further.
But first, we're going to set up our testing environment.
To do this, we're going to use PestPHP. PestPHP is already present because it was installed at the same time as Laravel.
To get to grips with Pest, we're going to create two very simple tests. Once we have the basics down, we can develop the rest of our application based on the tests.
What we'll be looking at today :
- Prior configuration of Pest
- Checking the administration home page
- Testing the user profile
- a user can see the list of links associated with them
- Conclusion
Prior configuration of Pest
Using SQLite for testing
In order to separate your application's database from the one used for testing, we're going to modify the phpunit.xml
file located at the root of your project.
Simply uncomment the following two lines:
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
This will allow Pest, which is a PHPUnit overlay, to use SQLite as its database engine and use it directly in memory.
Refresh the database for each test
Load a default account before each test
We're going to be doing a lot of work with FilamentPHP administration. So to avoid repeating for each test that we want to connect with a registered user, we'll simply tell Pest that for each test, it will act as if it were connected with the user with id #1.
To make this user ex
To do this, we'll edit the tests\TestCase.php
file and add the following setUp
function:
protected function setUp(): void
{
parent::setUp();
$this->actingAs(User::find(1));
}
So before each test is run, the actingAs
function will define the user with id #1 as the logged-in user. Here it's my HappyToDev account.
Remove the tests provided by default by PestPHP
When you install Pest, it provides you with two default tests:
- tests\Feature\ExampleTest.php
- tests\Unit\ExampleTest.php
You can delete them or keep them for inspiration.
Checking the administration home page
In this test, we'll go to the /admin
page to check that
- an HTTP 200 code is received
- we can see 'Dashboard' on the page
- we can see the name of our application 'LinKeeper' on the page
We'll start by creating a test file using Artisan.
php artisan pest:test GeneralAdminPageTest
By default, the tests created will be stored directly in the tests\Feature
directory.
Here are the contents of the file :
<?php
use Illuminate\Support\Facades\Config;
it('can view admin page', function () {
$response = $this->get('/admin');
$response
->assertStatus(200)
->assertSee('Dashboard')
->assertSee(Config('APP_NAME'));
});
Explanation:
We ask for get access to the /admin
page and we get the response.
In this response, we check that we do indeed have an HTTP 200 code, that in the HTML code returned we do indeed have the word Dashboard
and that we do indeed see the name of the application defined in our .env
file, in this case LinKeeper
. To do this, use the config()
helper.
Running the test
To run the test, at the root of your project, run the following command:
./vendor/bin/pest
Normally you should get a 403 error, so your test will not pass.
Correct the 403 error
To correct this, you need to read the FilamentPHP documentation which indicates that when you go into production, you need to modify the User
model to avoid hitting a wall with the 403 error.
I'll leave it to you to implement the necessary changes so that your test can pass.
If you encounter the slightest difficulty, let me know in the comments.
Run the test again
If you have correctly made the changes requested in the documentation, you should get this result when you run your tests.
Testing the user profile
We saw in lesson 2 that we normally have access to the user's profile. Let's set up a test to check this.
php artisan pest:test UserProfileTest
and add the following code:
it('has user profile page', function () {
actingAs(User::find(1))->get('/admin/profile')
->assertStatus(200)
->assertSee('Profile')
->assertSee('Save changes');
});
This will allow us to check that when I'm logged in with the user with id #1 (my user) I do indeed get an HTTP 200 code when I go to the /admin/profile
page and I can see the words: 'Profile' and 'Save changes'.
This is a very simple test, but it validates that the user does indeed have access to this page.
Run the tests
As before, run the appropriate command in your terminal:
./vendor/bin/pest
and you should get the following result:
Now that we've taken our first steps with tests, we'll be able to take a test-driven development approach using PestPHP throughout this project.
a user can see the list of links associated with them
This is the next stage in the development of our application.
As we are using FilamentPHP for the backend, a number of features are being developed by the FilamentPHP teams and the aim here will not be to test how well Filament works as I have no doubt that this has been tested extensively.
To view the list of links, the user will have a Links
link in the dashboard menu and this link, by FilamentPHP convention, will lead to an admin/links
address.
Let's create our tests for the Links page
Let's create a new test, using artisan :
php artisan pest:test PageLinksTest
First of all, we want to make sure that the page is accessible.
To do this, we're going to add the following code to our PageLinksTest
file:
it("can access the user's links page and see 'Links' on the page", function () {
$response = $this->get('/admin/links');
$response
->assertOk()
->assertSeeText('Links');
});
This code will ask PestPHP to load the /admin/links
page and to check firstly that the page returns the HTTP code 200 and then to ensure that the word 'Links' is present in the page.
You can run the tests with the --filter
option to execute only the test that matches the regex passed in parameter (see doc). For example with :
./vendor/bin/pest --filter "links page"
PestPHP will only run our last test because 'links page' is present in its description.
This avoids having to run all the tests each time, especially when you have to iterate several times when setting up your test.
The test fails and that's normal because the Links page doesn't exist at the moment.
But now that the test is here and has failed, it tells us exactly what to do:
Expected response status code [200] but received 404.
We were expecting an HTTP 200 code and instead we get a 404, which means that the requested page doesn't exist.
We simply need to create it.
Let's create the Links page
The 'Links' page will be a FilamentPHP administration page. It will therefore be a resource.
If I take the definition from the tutorial provided with PestPHP :
In Filament, resources are static classes used to build CRUD interfaces for your Eloquent models. They describe how administrators can interact with data from your panel using tables and forms.
We therefore understand that each Eloquent model will be associated with a resource in FilamentPHP.
It is therefore time to create our resource associated with our Link model, which is itself linked to our 'links' table in our database.
php artisan make:filament-resource Link
In our application tree, under app/Filament/Resources
, we can see a LinkResource
directory and a LinkResource.php
file.
The LinkResource
directory itself has a Pages
sub-directory which contains the CreateLink.php
, EditLink.php
and ListLinks.php
files. We'll talk about these later in this tutorial, so don't worry about these extra files for now.
FilamentPHP, via this Artisan command, will generate the following skeleton for you:
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\LinkResource\Pages;
use App\Filament\Resources\LinkResource\RelationManagers;
use App\Models\Link;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class LinkResource extends Resource
{
protected static ?string $model = Link::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
public static function form(Form $form): Form
{
return $form
->schema([
//
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
//
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListLinks::route('/'),
'create' => Pages\CreateLink::route('/create'),
'edit' => Pages\EditLink::route('/{record}/edit'),
];
}
}
Let's not worry about that for the moment. But let's run our test again:
./vendor/bin/pest --filter "links page"
We can see that this time our test is green.
If we go to the admin/links
page, we can see that the page does exist (HTTP code 200) and that it does indeed say 'Links'. This is why our test turns green.
However, we soon realise that something isn't quite right. There seem to be records but nothing is visible in the table that shows us the links.
This is normal, we'll need to configure our resource file.
Conclusion
We'll stop here for episode 3.
In this chapter, we started doing TDD for our application development and touched on resources in FilamentPHP.
In the next episode, we'll continue our testing strategy with PestPHP and get to know FilamentPHP's resources better.
As usual, I look forward to your comments below.
See you soon.
Top comments (0)