|
5 | 5 | use Filament\Resources\Events\RecordCreated; |
6 | 6 | use Filament\Resources\Events\RecordSaved; |
7 | 7 | use Filament\Tests\Fixtures\Models\Post; |
| 8 | +use Filament\Tests\Fixtures\Models\Ticket; |
| 9 | +use Filament\Tests\Fixtures\Models\User; |
8 | 10 | use Filament\Tests\Fixtures\Policies\TicketPolicy; |
9 | 11 | use Filament\Tests\Fixtures\Resources\Posts\Pages\CreateAnotherPreservingDataPost; |
10 | 12 | use Filament\Tests\Fixtures\Resources\Posts\Pages\CreateAnotherPreservingRepeaterPost; |
|
16 | 18 | use Filament\Tests\Fixtures\Resources\Tickets\TicketResource; |
17 | 19 | use Filament\Tests\Panels\Resources\TestCase; |
18 | 20 | use Illuminate\Auth\Access\Response; |
| 21 | +use Illuminate\Support\Facades\Artisan; |
19 | 22 | use Illuminate\Support\Facades\Event; |
20 | 23 |
|
21 | 24 | use function Filament\Tests\livewire; |
|
409 | 412 | app()->bind(TicketPolicy::class . '::create', fn (): bool => true); |
410 | 413 | }); |
411 | 414 |
|
| 415 | +it('blocks duplicate creation attempts while `$isCreating` after a successful creation', function (): void { |
| 416 | + $component = livewire(CreateTicket::class) |
| 417 | + ->call('create') |
| 418 | + ->assertRedirect(); |
| 419 | + |
| 420 | + expect(Ticket::count())->toBe(1); |
| 421 | + |
| 422 | + $component->call('create'); |
| 423 | + |
| 424 | + expect(Ticket::count())->toBe(1); |
| 425 | +}); |
| 426 | + |
| 427 | +it('can reset `$isCreating` from the client to release the duplicate creation guard when the page is restored from the browser history cache', function (): void { |
| 428 | + $component = livewire(CreateTicket::class) |
| 429 | + ->call('create') |
| 430 | + ->assertRedirect(); |
| 431 | + |
| 432 | + expect(Ticket::count())->toBe(1); |
| 433 | + |
| 434 | + $component |
| 435 | + ->set('isCreating', false) |
| 436 | + ->call('create') |
| 437 | + ->assertRedirect(); |
| 438 | + |
| 439 | + expect(Ticket::count())->toBe(2); |
| 440 | +}); |
| 441 | + |
| 442 | +it('can create a record again in the browser after navigating back to a create page restored from the history cache', function (): void { |
| 443 | + retry(10, function (): void { |
| 444 | + Artisan::call('filament:assets'); |
| 445 | + |
| 446 | + Ticket::query()->delete(); |
| 447 | + |
| 448 | + $this->actingAs(User::factory()->create()); |
| 449 | + |
| 450 | + visit(TicketResource::getUrl('create', panel: 'spa')) |
| 451 | + ->assertSee('Create Ticket') |
| 452 | + ->click('.fi-sc-form button[type="submit"]') |
| 453 | + ->waitForText('View Ticket') |
| 454 | + ->assertPathIs('/spa/tickets/*') |
| 455 | + ->back() |
| 456 | + ->waitForText('Create Ticket') |
| 457 | + ->assertPathIs('/spa/tickets/create') |
| 458 | + ->wait(1) |
| 459 | + ->click('.fi-sc-form button[type="submit"]') |
| 460 | + ->waitForText('View Ticket') |
| 461 | + ->assertPathIs('/spa/tickets/*'); |
| 462 | + |
| 463 | + expect(Ticket::count())->toBe(2); |
| 464 | + }); |
| 465 | +}); |
| 466 | + |
412 | 467 | it('re-authorizes viewAny on Livewire updates after the initial mount of a create page', function (): void { |
413 | 468 | app()->bind(TicketPolicy::class . '::viewAny', fn (): bool => true); |
414 | 469 |
|
|
0 commit comments