feat: integrate Spatie Media Library (#4)
- Added Spatie Media Library - Added media library configuration file - Updated Entry model to support media handling - Added featured image upload with gallery selection and preview - Added login tests with Dusk for user authentication - Added Dusk test for featured image selection Co-authored-by: jon brookes <marshyon@gmail.com> Reviewed-on: https://codeberg.org/headshed/share-lt/pulls/4
This commit is contained in:
parent
6cf8d5dfd4
commit
56607285bd
38 changed files with 2200 additions and 16 deletions
60
tests/Browser/001_LoginDashAdminTest.php
Normal file
60
tests/Browser/001_LoginDashAdminTest.php
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Browser;
|
||||
|
||||
use Illuminate\Foundation\Testing\DatabaseTruncation;
|
||||
use Laravel\Dusk\Browser;
|
||||
use Tests\Browser\Concerns\AuthenticatesUsers;
|
||||
use Tests\DuskTestCase;
|
||||
|
||||
class LoginTest extends DuskTestCase
|
||||
{
|
||||
use DatabaseTruncation;
|
||||
use AuthenticatesUsers;
|
||||
|
||||
public function test_login(): void
|
||||
{
|
||||
$user = $this->createTestUser("login-test@example.com");
|
||||
|
||||
$this->browse(function (Browser $browser) use ($user) {
|
||||
$this->loginUser($browser, $user);
|
||||
$this->assertWithDebugPause($browser, fn($b) =>
|
||||
$b->assertPathIs('/dashboard'),
|
||||
1000 // Custom pause time for this test
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function test_invalid_login(): void
|
||||
{
|
||||
$user = $this->createTestUser("invalid-email@example.com");
|
||||
|
||||
$this->browse(function (Browser $browser) use ($user) {
|
||||
$this->loginUser($browser, $user);
|
||||
$this->assertWithDebugPause($browser, fn($b) =>
|
||||
$b->visit('/admin')
|
||||
->waitForLocation('/admin')
|
||||
->assertPathIs('/admin')
|
||||
->assertSee('FORBIDDEN'),
|
||||
1000 // Custom pause time for this test
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
$this->assertWithDebugPause($browser, fn($b) =>
|
||||
$b->visit('/admin')
|
||||
->waitForLocation('/admin')
|
||||
->assertPathIs('/admin')
|
||||
->assertTitleContains('Dashboard')
|
||||
->assertDontSee('FORBIDDEN'),
|
||||
1000 // Custom pause time for this test
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
46
tests/Browser/002_UploadImageAdminTest.php
Normal file
46
tests/Browser/002_UploadImageAdminTest.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?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_image_upload_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'),
|
||||
1000 // Custom pause time for this test
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
74
tests/Browser/003_CreateEntryAdminTest.php
Normal file
74
tests/Browser/003_CreateEntryAdminTest.php
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Browser;
|
||||
|
||||
use Illuminate\Foundation\Testing\DatabaseTruncation;
|
||||
use Laravel\Dusk\Browser;
|
||||
use Tests\Browser\Concerns\AuthenticatesUsers;
|
||||
use Tests\DuskTestCase;
|
||||
|
||||
class CreateEntryAdminTest 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')
|
||||
->waitForText('Edit TEST ENTRY')
|
||||
->pause(2000)
|
||||
->waitForText('Featured Image')
|
||||
->click('#featured-picker-button')
|
||||
->waitForText('Select an existing image')
|
||||
->click('.fi-select-input-btn')
|
||||
->pause(2000)
|
||||
->click('li:first-child')
|
||||
->waitForText('Submit')
|
||||
->clickAtXPath('//button[contains(., "Submit")]')
|
||||
|
||||
->waitForText('Edit TEST ENTRY')
|
||||
->click('#key-bindings-1'),
|
||||
// ->pause(20000),
|
||||
1000 // Custom pause time for this test
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
38
tests/Browser/Concerns/AuthenticatesUsers.php
Normal file
38
tests/Browser/Concerns/AuthenticatesUsers.php
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
tests/Browser/console/.gitignore
vendored
Normal file
2
tests/Browser/console/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
||||
BIN
tests/Browser/fixtures/robot.webp
Normal file
BIN
tests/Browser/fixtures/robot.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
2
tests/Browser/screenshots/.gitignore
vendored
Normal file
2
tests/Browser/screenshots/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
||||
2
tests/Browser/source/.gitignore
vendored
Normal file
2
tests/Browser/source/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
||||
Loading…
Add table
Add a link
Reference in a new issue