feat: implement user authentication traits

and tests for admin panel image uploads
This commit is contained in:
jon brookes 2026-01-05 16:37:06 +00:00
parent 4cb9d078b1
commit bef3ae7f41
5 changed files with 106 additions and 104 deletions

View file

@ -0,0 +1,38 @@
<?php
namespace Tests\Browser\Concerns;
use App\Models\User;
use Laravel\Dusk\Browser;
trait AuthenticatesUsers
{
private function createTestUser(string $email): User
{
return User::factory()->create([
'email' => $email,
'password' => bcrypt('password'),
'two_factor_secret' => null,
'two_factor_recovery_codes' => null,
]);
}
private function loginUser(Browser $browser, User $user): void
{
$browser->visit('/login')
->type('email', $user->email)
->type('password', 'password')
->press('Log in')
->waitForLocation('/dashboard');
}
private function assertWithDebugPause(Browser $browser, callable $assertions, int $pauseMs = 10000): void
{
try {
$assertions($browser);
} catch (\Exception $e) {
$browser->pause($pauseMs);
throw $e;
}
}
}

View file

@ -0,0 +1,61 @@
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseTruncation;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\AuthenticatesUsers;
use Tests\DuskTestCase;
class UploadImageAdminTest extends DuskTestCase
{
use DatabaseTruncation;
use AuthenticatesUsers;
public function test_create_entry_admin_panel(): void
{
$user = $this->createTestUser("login-test@example.com");
$filePath = base_path('tests/Browser/fixtures/robot.webp');
$this->browse(function (Browser $browser) use ($user, $filePath) {
$this->loginUser($browser, $user);
$this->assertWithDebugPause(
$browser,
fn($b) =>
$b->visit('/admin/media')
->waitForLocation('/admin/media')
->assertPathIs('/admin/media')
->assertTitleContains('Media')
->clickLink('New media')
->waitForText('Create Media')
->type('#form\\.name', 'test image')
->assertVisible('.filepond--drop-label')
->attach('.filepond--browser', $filePath)
->pause(7000)
->waitForText('Create')
->waitFor('#key-bindings-1:not([disabled])')
->click('#key-bindings-1')
->assertSee('Collection name')
->pause(5000)
->visit('/admin/entries')
->waitForLocation('/admin/entries')
->assertPathIs('/admin/entries')
->assertTitleContains('Entries')
->clickLink('New entry')
->waitForText('Create Entry')
->type('#form\\.title', 'TEST ENTRY')
->keys('#form\\.title', '{tab}')
->waitForText('Create')
->click('#key-bindings-1')
->waitForText('Updated at')
->assertSee('Updated at')
->visit('/admin/entries/1/edit')
->pause(10000),
1000 // Custom pause time for this test
);
});
}
}

View file

@ -1,98 +0,0 @@
<?php
namespace Tests\Browser;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTruncation;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
class LoginTest extends DuskTestCase
{
use DatabaseTruncation;
/**
* Dusk test panel.
*/
private function createTestUser(string $email): User
{
return User::factory()->create([
'email' => $email,
'password' => bcrypt('password'),
'two_factor_secret' => null,
'two_factor_recovery_codes' => null,
]);
}
private function loginUser(Browser $browser, User $user): void
{
$browser->visit('/login')
->type('email', $user->email)
->type('password', 'password')
->press('Log in')
->waitForLocation('/dashboard');
}
public function test_login(): void
{
$user = $this->createTestUser("login-test@example.com");
$this->browse(function (Browser $browser) use ($user) {
$this->loginUser($browser, $user);
try {
$browser->assertPathIs('/dashboard'); // Or wherever successful login redirects
} catch (\Exception $e) {
$browser->pause(10000); // Pause for 10 seconds on failure to debug
throw $e;
}
});
}
/*
public function test_invalid_login(): void
{
$user = $this->createTestUser("invalid-email@example.com");
$this->browse(function (Browser $browser) use ($user) {
$this->loginUser($browser, $user);
try {
$browser->visit('/admin')
->waitForLocation('/admin')
->assertPathIs('/admin')
->assertTitleContains('Dashboard')
->assertDontSee('Forbidden')
->pause(1000);
} catch (\Exception $e) {
$browser->pause(1000); // Pause for 1 second on failure to debug
throw $e;
}
});
}
*/
public function test_access_admin_panel(): void
{
$user = $this->createTestUser("login-test@example.com");
$this->browse(function (Browser $browser) use ($user) {
$this->loginUser($browser, $user);
try {
$browser->visit('/admin')
->waitForLocation('/admin')
->assertPathIs('/admin')
->assertTitleContains('Dashboard')
->assertDontSee('Forbidden')
->pause(1000);
} catch (\Exception $e) {
$browser->pause(1000); // Pause for 1 second on failure to debug
throw $e;
}
});
}
}

View file

@ -7,7 +7,7 @@ use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\AuthenticatesUsers; use Tests\Browser\Concerns\AuthenticatesUsers;
use Tests\DuskTestCase; use Tests\DuskTestCase;
class LoginTest extends DuskTestCase class UploadImageAdminTest extends DuskTestCase
{ {
use DatabaseTruncation; use DatabaseTruncation;
use AuthenticatesUsers; use AuthenticatesUsers;
@ -31,13 +31,14 @@ class LoginTest extends DuskTestCase
->assertTitleContains('Media') ->assertTitleContains('Media')
->clickLink('New media') ->clickLink('New media')
->waitForText('Create Media') ->waitForText('Create Media')
->pause(1000) ->type('#form\\.name', 'test image')
->assertVisible('.filepond--drop-label') ->assertVisible('.filepond--drop-label')
->attach('.filepond--browser', $filePath) ->attach('.filepond--browser', $filePath)
->waitforText('Create') ->pause(7000)
->clickLink('Create') ->waitForText('Create')
// ->assertSee('Upload successful') ->waitFor('#key-bindings-1:not([disabled])')
->pause(10000), ->click('#key-bindings-1')
->assertSee('Collection name'),
1000 // Custom pause time for this test 1000 // Custom pause time for this test
); );
}); });

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB