Move FormTestCase in Trait
continuous-integration/drone/push Build is passing Details

This commit is contained in:
philipp lang 2025-06-15 23:29:26 +02:00
parent c3ecb9dc63
commit cff62ebc1d
14 changed files with 1425 additions and 1507 deletions

File diff suppressed because it is too large Load Diff

View File

@ -6,18 +6,153 @@ use App\Form\Enums\SpecialType;
use App\Form\Mails\ConfirmRegistrationMail; use App\Form\Mails\ConfirmRegistrationMail;
use App\Form\Models\Form; use App\Form\Models\Form;
use App\Form\Models\Participant; use App\Form\Models\Participant;
use Generator;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\RequestFactories\EditorRequestFactory; use Tests\RequestFactories\EditorRequestFactory;
use Tests\Lib\CreatesFormFields;
class FormRegisterMailTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions; beforeEach(function () {
test()->setUpForm();
});
public function testItShowsFormContent(): void dataset('blocks', fn() => [
{ fn () => [
['mode' => 'all', 'ifs' => []],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
],
fn () => [
['mode' => 'any', 'ifs' => []],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
],
fn () => [
['mode' => 'any', 'ifs' => []],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
],
fn () => [
['mode' => 'any', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
],
fn () => [
['mode' => 'any', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B']
]],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
false,
],
fn () => [
['mode' => 'any', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'],
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
],
fn () => [
['mode' => 'any', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'],
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'],
true,
],
fn () => [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'],
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'],
false,
],
fn () => [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B']
]],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'],
true,
],
fn () => [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isNotEqual', 'value' => 'A']
]],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'],
true,
],
fn () => [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isIn', 'value' => ['A']]
]],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
],
fn () => [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isNotIn', 'value' => ['B']]
]],
test()->dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
],
fn () => [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isNotIn', 'value' => ['B']]
]],
test()->radioField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
],
fn () => [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => true]
]],
test()->checkboxField('fieldkey'),
['fieldkey' => true],
true,
],
fn () => [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => false]
]],
test()->checkboxField('fieldkey'),
['fieldkey' => true],
false,
],
]);
it('testItShowsFormContent', function () {
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$participant = Participant::factory()->for( $participant = Participant::factory()->for(
@ -36,10 +171,9 @@ class FormRegisterMailTest extends FormTestCase
$mail = new ConfirmRegistrationMail($participant); $mail = new ConfirmRegistrationMail($participant);
$mail->assertSeeInText('mail top'); $mail->assertSeeInText('mail top');
$mail->assertSeeInText('mail bottom'); $mail->assertSeeInText('mail bottom');
} });
public function testItShowsParticipantGreeting(): void it('testItShowsParticipantGreeting', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$participant = Participant::factory()->for(Form::factory()->sections([ $participant = Participant::factory()->for(Form::factory()->sections([
FormtemplateSectionRequest::new()->name('Persönliches')->fields([ FormtemplateSectionRequest::new()->name('Persönliches')->fields([
@ -56,10 +190,9 @@ class FormRegisterMailTest extends FormTestCase
$mail->assertSeeInText('## Persönliches'); $mail->assertSeeInText('## Persönliches');
$mail->assertSeeInText('* Vorname: Max'); $mail->assertSeeInText('* Vorname: Max');
$mail->assertSeeInText('* Volljährig: Ja'); $mail->assertSeeInText('* Volljährig: Ja');
} });
public function testItAttachesMailAttachments(): void it('testItAttachesMailAttachments', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$participant = Participant::factory()->for( $participant = Participant::factory()->for(
Form::factory() Form::factory()
@ -76,150 +209,13 @@ class FormRegisterMailTest extends FormTestCase
$mail = new ConfirmRegistrationMail($participant); $mail = new ConfirmRegistrationMail($participant);
$mail->assertHasAttachedData('content1', 'beispiel.pdf', ['mime' => 'application/pdf']); $mail->assertHasAttachedData('content1', 'beispiel.pdf', ['mime' => 'application/pdf']);
$mail->assertHasAttachedData('content2', 'beispiel2.pdf', ['mime' => 'application/pdf']); $mail->assertHasAttachedData('content2', 'beispiel2.pdf', ['mime' => 'application/pdf']);
} });
public static function blockDataProvider(): Generator
{
yield [
['mode' => 'all', 'ifs' => []],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
];
yield [
['mode' => 'any', 'ifs' => []],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
];
yield [
['mode' => 'any', 'ifs' => []],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
];
yield [
['mode' => 'any', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
];
yield [
['mode' => 'any', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B']
]],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
false,
];
yield [
['mode' => 'any', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'],
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
];
yield [
['mode' => 'any', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'],
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'],
true,
];
yield [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'],
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'],
false,
];
yield [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B']
]],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'],
true,
];
yield [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isNotEqual', 'value' => 'A']
]],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'],
true,
];
yield [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isIn', 'value' => ['A']]
]],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
];
yield [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isNotIn', 'value' => ['B']]
]],
static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
];
yield [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isNotIn', 'value' => ['B']]
]],
static::radioField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'],
true,
];
yield [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => true]
]],
static::checkboxField('fieldkey'),
['fieldkey' => true],
true,
];
yield [
['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => false]
]],
static::checkboxField('fieldkey'),
['fieldkey' => true],
false,
];
}
/** /**
* @param array<string, mixed> $conditions * @param array<string, mixed> $conditions
* @param array<string, mixed> $participantValues * @param array<string, mixed> $participantValues
*/ */
#[DataProvider('blockDataProvider')] it('testItFiltersForBlockConditions', function (array $conditions, FormtemplateFieldRequest $field, array $participantValues, bool $result) {
public function testItFiltersForBlockConditions(array $conditions, FormtemplateFieldRequest $field, array $participantValues, bool $result): void
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$participant = Participant::factory()->for( $participant = Participant::factory()->for(
@ -240,15 +236,13 @@ class FormRegisterMailTest extends FormTestCase
} else { } else {
$mail->assertDontSeeInText('::content::'); $mail->assertDontSeeInText('::content::');
} }
} })->with('blocks');
/** /**
* @param array<string, mixed> $conditions * @param array<string, mixed> $conditions
* @param array<string, mixed> $participantValues * @param array<string, mixed> $participantValues
*/ */
#[DataProvider('blockDataProvider')] it('testItFiltersForAttachments', function (array $conditions, FormtemplateFieldRequest $field, array $participantValues, bool $result) {
public function testItFiltersForAttachments(array $conditions, FormtemplateFieldRequest $field, array $participantValues, bool $result): void
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$participant = Participant::factory()->for( $participant = Participant::factory()->for(
@ -270,5 +264,4 @@ class FormRegisterMailTest extends FormTestCase
} else { } else {
$this->assertFalse($mail->hasAttachedData('content', 'beispiel.pdf', ['mime' => 'application/pdf'])); $this->assertFalse($mail->hasAttachedData('content', 'beispiel.pdf', ['mime' => 'application/pdf']));
} }
} })->with('blocks');
}

View File

@ -9,17 +9,17 @@ use App\Form\Models\Form;
use App\Lib\Events\Succeeded; use App\Lib\Events\Succeeded;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Generator;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\RequestFactories\EditorRequestFactory; use Tests\RequestFactories\EditorRequestFactory;
use Tests\Lib\CreatesFormFields;
class FormStoreActionTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions; beforeEach(function() {
test()->setUpForm();
});
public function testItStoresForm(): void it('testItStoresForm', function () {
{
Event::fake([Succeeded::class]); Event::fake([Succeeded::class]);
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$description = EditorRequestFactory::new()->text(10, 'Lorem'); $description = EditorRequestFactory::new()->text(10, 'Lorem');
@ -57,10 +57,9 @@ class FormStoreActionTest extends FormTestCase
$this->assertEquals('formname.jpg', $form->getMedia('headerImage')->first()->file_name); $this->assertEquals('formname.jpg', $form->getMedia('headerImage')->first()->file_name);
Event::assertDispatched(Succeeded::class, fn(Succeeded $event) => $event->message === 'Veranstaltung gespeichert.'); Event::assertDispatched(Succeeded::class, fn(Succeeded $event) => $event->message === 'Veranstaltung gespeichert.');
$this->assertFrontendCacheCleared(); $this->assertFrontendCacheCleared();
} });
public function testItStoresDefaultSorting(): void it('testItStoresDefaultSorting', function () {
{
Event::fake([Succeeded::class]); Event::fake([Succeeded::class]);
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
FormRequest::new()->fields([$this->textField()])->fake(); FormRequest::new()->fields([$this->textField()])->fake();
@ -70,10 +69,9 @@ class FormStoreActionTest extends FormTestCase
$form = Form::latest()->first(); $form = Form::latest()->first();
$this->assertEquals('id', $form->meta['sorting']['by']); $this->assertEquals('id', $form->meta['sorting']['by']);
$this->assertFalse(false, $form->meta['sorting']['direction']); $this->assertFalse(false, $form->meta['sorting']['direction']);
} });
public function testRegistrationDatesCanBeNull(): void it('testRegistrationDatesCanBeNull', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$this->postJson(route('form.store'), FormRequest::new()->registrationFrom(null)->registrationUntil(null)->create())->assertOk(); $this->postJson(route('form.store'), FormRequest::new()->registrationFrom(null)->registrationUntil(null)->create())->assertOk();
@ -82,38 +80,32 @@ class FormStoreActionTest extends FormTestCase
'registration_until' => null, 'registration_until' => null,
'registration_from' => null, 'registration_from' => null,
]); ]);
} });
public function testItStoresExport(): void it('testItStoresExport', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$this->postJson(route('form.store'), FormRequest::new()->export(ExportData::from(['root' => FileshareResourceData::from(['connection_id' => 2, 'resource' => '/dir']), 'group_by' => 'lala', 'to_group_field' => 'abc']))->create())->assertOk(); $this->postJson(route('form.store'), FormRequest::new()->export(ExportData::from(['root' => FileshareResourceData::from(['connection_id' => 2, 'resource' => '/dir']), 'group_by' => 'lala', 'to_group_field' => 'abc']))->create())->assertOk();
$form = Form::first(); $form = Form::first();
$this->assertEquals(2, $form->export->root->connectionId); $this->assertEquals(2, $form->export->root->connectionId);
} });
public static function validationDataProvider(): Generator
{
yield [FormRequest::new()->name(''), ['name' => 'Name ist erforderlich.']];
yield [FormRequest::new()->excerpt(''), ['excerpt' => 'Auszug ist erforderlich.']];
yield [FormRequest::new()->description(null), ['description.blocks' => 'Beschreibung ist erforderlich.']];
yield [FormRequest::new()->state(['from' => null]), ['from' => 'Start ist erforderlich']];
yield [FormRequest::new()->state(['to' => null]), ['to' => 'Ende ist erforderlich']];
yield [FormRequest::new()->state(['header_image' => null]), ['header_image' => 'Bild ist erforderlich']];
}
/** /**
* @param array<string, string> $messages * @param array<string, string> $messages
*/ */
#[DataProvider('validationDataProvider')] it('testItValidatesRequests', function (FormRequest $request, array $messages) {
public function testItValidatesRequests(FormRequest $request, array $messages): void
{
$this->login()->loginNami(); $this->login()->loginNami();
$request->fake(); $request->fake();
$this->postJson(route('form.store'))->assertJsonValidationErrors($messages); $this->postJson(route('form.store'))->assertJsonValidationErrors($messages);
} })->with([
} [FormRequest::new()->name(''), ['name' => 'Name ist erforderlich.']],
[FormRequest::new()->excerpt(''), ['excerpt' => 'Auszug ist erforderlich.']],
[FormRequest::new()->description(null), ['description.blocks' => 'Beschreibung ist erforderlich.']],
[FormRequest::new()->state(['from' => null]), ['from' => 'Start ist erforderlich']],
[FormRequest::new()->state(['to' => null]), ['to' => 'Ende ist erforderlich']],
[FormRequest::new()->state(['header_image' => null]), ['header_image' => 'Bild ist erforderlich']],
]);

View File

@ -1,36 +0,0 @@
<?php
namespace Tests\Feature\Form;
use App\Form\FormSettings;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
use Tests\Lib\CreatesFormFields;
class FormTestCase extends TestCase
{
use CreatesFormFields;
private string $clearCacheUrl = 'http://event.com/clear-cache';
protected function setUp(): void
{
parent::setUp();
app(FormSettings::class)->fill(['clearCacheUrl' => 'http://event.com/clear-cache'])->save();
Http::fake(function ($request) {
if ($request->url() === $this->clearCacheUrl) {
return Http::response('', 200);
}
});
Storage::fake('temp');
}
protected function assertFrontendCacheCleared(): void
{
Http::assertSent(fn ($request) => $request->url() === $this->clearCacheUrl && $request->method() === 'GET');
}
}

View File

@ -7,14 +7,16 @@ use App\Form\Data\ExportData;
use App\Form\Models\Form; use App\Form\Models\Form;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\RequestFactories\EditorRequestFactory; use Tests\RequestFactories\EditorRequestFactory;
use Tests\Lib\CreatesFormFields;
class FormUpdateActionTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions; beforeEach(function () {
test()->setUpForm();
});
public function testItSetsCustomAttributesOfFields(): void it('testItSetsCustomAttributesOfFields', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->create(); $form = Form::factory()->create();
$payload = FormRequest::new()->fields([ $payload = FormRequest::new()->fields([
@ -27,10 +29,9 @@ class FormUpdateActionTest extends FormTestCase
$form = $form->fresh(); $form = $form->fresh();
$this->assertTrue($form->config->sections->get(0)->fields->get(0)->maxToday); $this->assertTrue($form->config->sections->get(0)->fields->get(0)->maxToday);
} });
public function testItSetsRegistrationDates(): void it('testItSetsRegistrationDates', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->create(); $form = Form::factory()->create();
$payload = FormRequest::new()->registrationFrom('2023-05-04 01:00:00')->registrationUntil('2023-07-07 01:00:00')->create(); $payload = FormRequest::new()->registrationFrom('2023-05-04 01:00:00')->registrationUntil('2023-07-07 01:00:00')->create();
@ -41,10 +42,9 @@ class FormUpdateActionTest extends FormTestCase
$this->assertEquals('2023-05-04 01:00', $form->registration_from->format('Y-m-d H:i')); $this->assertEquals('2023-05-04 01:00', $form->registration_from->format('Y-m-d H:i'));
$this->assertEquals('2023-07-07 01:00', $form->registration_until->format('Y-m-d H:i')); $this->assertEquals('2023-07-07 01:00', $form->registration_until->format('Y-m-d H:i'));
} });
public function testItSetsTexts(): void it('testItSetsTexts', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->create(); $form = Form::factory()->create();
$payload = FormRequest::new()->fields([]) $payload = FormRequest::new()->fields([])
@ -59,30 +59,27 @@ class FormUpdateActionTest extends FormTestCase
$this->assertEquals('lala', $form->fresh()->mail_top->blocks[0]['data']['text']); $this->assertEquals('lala', $form->fresh()->mail_top->blocks[0]['data']['text']);
$this->assertEquals('lalab', $form->fresh()->mail_bottom->blocks[0]['data']['text']); $this->assertEquals('lalab', $form->fresh()->mail_bottom->blocks[0]['data']['text']);
$this->assertEquals('desc', $form->fresh()->description->blocks[0]['data']['text']); $this->assertEquals('desc', $form->fresh()->description->blocks[0]['data']['text']);
} });
public function testItClearsFrontendCacheWhenFormUpdated(): void it('testItClearsFrontendCacheWhenFormUpdated', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->create(); $form = Form::factory()->create();
$this->patchJson(route('form.update', ['form' => $form]), FormRequest::new()->create()); $this->patchJson(route('form.update', ['form' => $form]), FormRequest::new()->create());
$this->assertFrontendCacheCleared(); $this->assertFrontendCacheCleared();
} });
public function testItUpdatesExport(): void it('testItUpdatesExport', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->create(); $form = Form::factory()->create();
$this->patchJson(route('form.update', ['form' => $form]), FormRequest::new()->export(ExportData::from(['root' => FileshareResourceData::from(['connection_id' => 2, 'resource' => '/dir']), 'group_by' => 'lala', 'to_group_field' => 'abc']))->create()); $this->patchJson(route('form.update', ['form' => $form]), FormRequest::new()->export(ExportData::from(['root' => FileshareResourceData::from(['connection_id' => 2, 'resource' => '/dir']), 'group_by' => 'lala', 'to_group_field' => 'abc']))->create());
$this->assertEquals(2, $form->fresh()->export->root->connectionId); $this->assertEquals(2, $form->fresh()->export->root->connectionId);
} });
public function testItUpdatesActiveColumnsWhenFieldRemoved(): void it('testItUpdatesActiveColumnsWhenFieldRemoved', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->fields([ $form = Form::factory()->fields([
$this->textField('firstname'), $this->textField('firstname'),
@ -96,10 +93,9 @@ class FormUpdateActionTest extends FormTestCase
$this->patchJson(route('form.update', ['form' => $form]), $payload)->assertSessionDoesntHaveErrors()->assertOk(); $this->patchJson(route('form.update', ['form' => $form]), $payload)->assertSessionDoesntHaveErrors()->assertOk();
$this->assertEquals(['firstname'], $form->fresh()->meta['active_columns']); $this->assertEquals(['firstname'], $form->fresh()->meta['active_columns']);
} });
public function testItUpdatesIntroOfSections(): void it('testItUpdatesIntroOfSections', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory() $form = Form::factory()
->sections([FormtemplateSectionRequest::new()->intro('aaa')]) ->sections([FormtemplateSectionRequest::new()->intro('aaa')])
@ -110,10 +106,9 @@ class FormUpdateActionTest extends FormTestCase
$this->patchJson(route('form.update', ['form' => $form]), $payload)->assertSessionDoesntHaveErrors()->assertOk(); $this->patchJson(route('form.update', ['form' => $form]), $payload)->assertSessionDoesntHaveErrors()->assertOk();
$this->assertEquals('aaa', $form->fresh()->config->sections[0]->intro); $this->assertEquals('aaa', $form->fresh()->config->sections[0]->intro);
} });
public function testItUpdatesActiveState(): void it('testItUpdatesActiveState', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->create(); $form = Form::factory()->create();
@ -121,10 +116,9 @@ class FormUpdateActionTest extends FormTestCase
$this->assertFalse($form->fresh()->is_active); $this->assertFalse($form->fresh()->is_active);
$this->patchJson(route('form.update', ['form' => $form]), FormRequest::new()->isActive(true)->create())->assertSessionDoesntHaveErrors()->assertOk(); $this->patchJson(route('form.update', ['form' => $form]), FormRequest::new()->isActive(true)->create())->assertSessionDoesntHaveErrors()->assertOk();
$this->assertTrue($form->fresh()->is_active); $this->assertTrue($form->fresh()->is_active);
} });
public function testItUpdatesPrivateState(): void it('testItUpdatesPrivateState', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->create(); $form = Form::factory()->create();
@ -132,10 +126,9 @@ class FormUpdateActionTest extends FormTestCase
$this->assertFalse($form->fresh()->is_private); $this->assertFalse($form->fresh()->is_private);
$this->patchJson(route('form.update', ['form' => $form]), FormRequest::new()->isPrivate(true)->create())->assertSessionDoesntHaveErrors()->assertOk(); $this->patchJson(route('form.update', ['form' => $form]), FormRequest::new()->isPrivate(true)->create())->assertSessionDoesntHaveErrors()->assertOk();
$this->assertTrue($form->fresh()->is_private); $this->assertTrue($form->fresh()->is_private);
} });
public function testItUpdatesActiveColumnsWhenFieldsAdded(): void it('testItUpdatesActiveColumnsWhenFieldsAdded', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory() $form = Form::factory()
->fields([]) ->fields([])
@ -148,10 +141,9 @@ class FormUpdateActionTest extends FormTestCase
$this->patchJson(route('form.update', ['form' => $form]), $payload)->assertSessionDoesntHaveErrors()->assertOk(); $this->patchJson(route('form.update', ['form' => $form]), $payload)->assertSessionDoesntHaveErrors()->assertOk();
$this->assertEquals(['firstname', 'geb', 'lastname'], $form->fresh()->meta['active_columns']); $this->assertEquals(['firstname', 'geb', 'lastname'], $form->fresh()->meta['active_columns']);
} });
public function testItUpdatesPrevention(): void it('testItUpdatesPrevention', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->create(); $form = Form::factory()->create();
$payload = FormRequest::new() $payload = FormRequest::new()
@ -163,5 +155,4 @@ class FormUpdateActionTest extends FormTestCase
$this->assertTrue($form->fresh()->needs_prevention); $this->assertTrue($form->fresh()->needs_prevention);
$this->assertEquals('lorem ipsum', $form->fresh()->prevention_text->blocks[0]['data']['text']); $this->assertEquals('lorem ipsum', $form->fresh()->prevention_text->blocks[0]['data']['text']);
$this->assertEquals(['mode' => 'all', 'ifs' => [['field' => 'vorname', 'value' => 'Max', 'comparator' => 'isEqual']]], $form->fresh()->prevention_conditions->toArray()); $this->assertEquals(['mode' => 'all', 'ifs' => [['field' => 'vorname', 'value' => 'Max', 'comparator' => 'isEqual']]], $form->fresh()->prevention_conditions->toArray());
} });
}

View File

@ -4,14 +4,16 @@ namespace Tests\Feature\Form;
use App\Form\Models\Form; use App\Form\Models\Form;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\Lib\CreatesFormFields;
class FormUpdateMetaActionTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions; beforeEach(function () {
test()->setUpForm();
});
public function testItUpdatesMetaOfForm(): void it('testItUpdatesMetaOfForm', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory() $form = Form::factory()
->sections([FormtemplateSectionRequest::new()->fields([ ->sections([FormtemplateSectionRequest::new()->fields([
@ -29,10 +31,9 @@ class FormUpdateMetaActionTest extends FormTestCase
$form = Form::latest()->first(); $form = Form::latest()->first();
$this->assertEquals(['by' => 'textone', 'direction' => false], $form->meta['sorting']); $this->assertEquals(['by' => 'textone', 'direction' => false], $form->meta['sorting']);
$this->assertEquals(['textone'], $form->meta['active_columns']); $this->assertEquals(['textone'], $form->meta['active_columns']);
} });
public function testItCanSetCreatedAtMeta(): void it('testItCanSetCreatedAtMeta', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->create(); $form = Form::factory()->create();
@ -44,5 +45,4 @@ class FormUpdateMetaActionTest extends FormTestCase
$form = Form::latest()->first(); $form = Form::latest()->first();
$this->assertEquals(['by' => 'textone', 'direction' => false], $form->fresh()->meta['sorting']); $this->assertEquals(['by' => 'textone', 'direction' => false], $form->fresh()->meta['sorting']);
$this->assertEquals(['created_at'], $form->fresh()->meta['active_columns']); $this->assertEquals(['created_at'], $form->fresh()->meta['active_columns']);
} });
}

View File

@ -9,17 +9,13 @@ use App\Form\Models\Formtemplate;
use App\Lib\Events\Succeeded; use App\Lib\Events\Succeeded;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Generator; use Tests\Lib\CreatesFormFields;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\RequestFactories\EditorRequestFactory; use Tests\RequestFactories\EditorRequestFactory;
class FormtemplateStoreActionTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions; it('testItStoresTemplates', function () {
public function testItStoresTemplates(): void
{
Event::fake([Succeeded::class]); Event::fake([Succeeded::class]);
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$payload = FormtemplateRequest::new()->name('testname')->sections([ $payload = FormtemplateRequest::new()->name('testname')->sections([
@ -50,42 +46,36 @@ class FormtemplateStoreActionTest extends FormTestCase
$this->assertEquals('lblb', $formtemplate->mail_bottom->blocks[0]['data']['text']); $this->assertEquals('lblb', $formtemplate->mail_bottom->blocks[0]['data']['text']);
$this->assertFalse($formtemplate->config->sections->get(0)->fields->get(0)->required); $this->assertFalse($formtemplate->config->sections->get(0)->fields->get(0)->required);
Event::assertDispatched(Succeeded::class, fn(Succeeded $event) => $event->message === 'Vorlage gespeichert.'); Event::assertDispatched(Succeeded::class, fn(Succeeded $event) => $event->message === 'Vorlage gespeichert.');
} });
public static function validationDataProvider(): Generator
{
yield [FormtemplateRequest::new()->name(''), ['name' => 'Name ist erforderlich.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->name('')]), ['config.sections.0.name' => 'Sektionsname ist erforderlich.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
static::textField()->name(''),
])]), ['config.sections.0.fields.0.name' => 'Feldname ist erforderlich.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
FormtemplateFieldRequest::type('')
])]), ['config.sections.0.fields.0.type' => 'Feldtyp ist erforderlich.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
FormtemplateFieldRequest::type('aaaaa'),
])]), ['config.sections.0.fields.0.type' => 'Feldtyp ist ungültig.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
static::textField(''),
])]), ['config.sections.0.fields.0.key' => 'Feldkey ist erforderlich.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
static::textField('a b'),
])]), ['config.sections.0.fields.0.key' => 'Feldkey Format ist ungültig.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
static::textField()->required('la')
])]), ['config.sections.0.fields.0.required' => 'Erforderlich muss ein Wahrheitswert sein.']];
}
/** /**
* @param array<string, string> $messages * @param array<string, string> $messages
*/ */
#[DataProvider('validationDataProvider')] it('testItValidatesRequests', function (FormtemplateRequest $request, array $messages) {
public function testItValidatesRequests(FormtemplateRequest $request, array $messages): void
{
$this->login()->loginNami(); $this->login()->loginNami();
$request->fake(); $request->fake();
$this->postJson(route('formtemplate.store')) $this->postJson(route('formtemplate.store'))
->assertJsonValidationErrors($messages); ->assertJsonValidationErrors($messages);
} })->with([
} fn () => [FormtemplateRequest::new()->name(''), ['name' => 'Name ist erforderlich.']],
fn () => [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->name('')]), ['config.sections.0.name' => 'Sektionsname ist erforderlich.']],
fn () => [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
test()->textField()->name(''),
])]), ['config.sections.0.fields.0.name' => 'Feldname ist erforderlich.']],
fn () => [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
FormtemplateFieldRequest::type('')
])]), ['config.sections.0.fields.0.type' => 'Feldtyp ist erforderlich.']],
fn () => [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
FormtemplateFieldRequest::type('aaaaa'),
])]), ['config.sections.0.fields.0.type' => 'Feldtyp ist ungültig.']],
fn () => [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
test()->textField(''),
])]), ['config.sections.0.fields.0.key' => 'Feldkey ist erforderlich.']],
fn () => [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
test()->textField('a b'),
])]), ['config.sections.0.fields.0.key' => 'Feldkey Format ist ungültig.']],
fn () => [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
test()->textField()->required('la')
])]), ['config.sections.0.fields.0.required' => 'Erforderlich muss ein Wahrheitswert sein.']],
]);

View File

@ -4,13 +4,16 @@ namespace Tests\Feature\Form;
use App\Form\Models\Form; use App\Form\Models\Form;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\Lib\CreatesFormFields;
class IsDirtyActionTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions;
public function testItChecksIfFormIsDirty(): void beforeEach(function () {
{ test()->setUpForm();
});
it('testItChecksIfFormIsDirty', function () {
$this->login()->loginNami(); $this->login()->loginNami();
$form = Form::factory()->fields([ $form = Form::factory()->fields([
$this->textField(), $this->textField(),
@ -21,5 +24,4 @@ class IsDirtyActionTest extends FormTestCase
$modifiedConfig = $form->config->toArray(); $modifiedConfig = $form->config->toArray();
data_set($modifiedConfig, 'sections.0.name', 'mod'); data_set($modifiedConfig, 'sections.0.name', 'mod');
$this->postJson(route('form.is-dirty', ['form' => $form]), ['config' => $modifiedConfig])->assertJsonPath('result', true); $this->postJson(route('form.is-dirty', ['form' => $form]), ['config' => $modifiedConfig])->assertJsonPath('result', true);
} });
}

View File

@ -5,14 +5,16 @@ namespace Tests\Feature\Form;
use App\Form\Models\Form; use App\Form\Models\Form;
use App\Form\Models\Participant; use App\Form\Models\Participant;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\Lib\CreatesFormFields;
class ParticipantDestroyActionTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions; beforeEach(function () {
test()->setUpForm();
});
public function testItCanDestroyAParticipant(): void it('testItCanDestroyAParticipant', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory() $form = Form::factory()
->has(Participant::factory()) ->has(Participant::factory())
@ -23,5 +25,4 @@ class ParticipantDestroyActionTest extends FormTestCase
->assertOk(); ->assertOk();
$this->assertDatabaseCount('participants', 0); $this->assertDatabaseCount('participants', 0);
} });
}

View File

@ -6,14 +6,16 @@ use App\Form\Models\Form;
use App\Form\Models\Participant; use App\Form\Models\Participant;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Tests\Lib\CreatesFormFields;
class ParticipantExportActionTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions; beforeEach(function () {
test()->setUpForm();
});
public function testItShowsParticipantsAndColumns(): void it('testItShowsParticipantsAndColumns', function () {
{
Storage::fake('temp'); Storage::fake('temp');
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory() $form = Form::factory()
@ -35,5 +37,4 @@ class ParticipantExportActionTest extends FormTestCase
$this->assertExcelContent('Pfadfinder', $contents); $this->assertExcelContent('Pfadfinder', $contents);
$this->assertExcelContent('Stufe', $contents); $this->assertExcelContent('Stufe', $contents);
$this->assertExcelContent('Abcselect', $contents); $this->assertExcelContent('Abcselect', $contents);
} });
}

View File

@ -5,14 +5,16 @@ namespace Tests\Feature\Form;
use App\Form\Models\Form; use App\Form\Models\Form;
use App\Form\Models\Participant; use App\Form\Models\Participant;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\Lib\CreatesFormFields;
class ParticipantFieldsActionTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions; beforeEach(function () {
test()->setUpForm();
});
public function testItShowsParticipantsFields(): void it('testItShowsParticipantsFields', function () {
{
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$participant = Participant::factory()->data(['vorname' => 'Max', 'select' => ['A', 'B']]) $participant = Participant::factory()->data(['vorname' => 'Max', 'select' => ['A', 'B']])
->for(Form::factory()->sections([ ->for(Form::factory()->sections([
@ -32,5 +34,4 @@ class ParticipantFieldsActionTest extends FormTestCase
->assertJsonPath('data.config.sections.0.fields.0.value', 'Max') ->assertJsonPath('data.config.sections.0.fields.0.value', 'Max')
->assertJsonPath('data.config.sections.0.fields.1.key', 'select') ->assertJsonPath('data.config.sections.0.fields.1.key', 'select')
->assertJsonPath('data.config.sections.0.fields.1.value', ['A', 'B']); ->assertJsonPath('data.config.sections.0.fields.1.value', ['A', 'B']);
} });
}

View File

@ -6,14 +6,16 @@ use App\Form\Actions\ExportSyncAction;
use App\Form\Models\Form; use App\Form\Models\Form;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Queue; use Illuminate\Support\Facades\Queue;
use Tests\Lib\CreatesFormFields;
class ParticipantStoreActionTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions; beforeEach(function () {
test()->setUpForm();
});
public function testItStoresParticipant(): void it('testItStoresParticipant', function () {
{
Queue::fake(); Queue::fake();
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->fields([ $form = Form::factory()->fields([
@ -26,10 +28,9 @@ class ParticipantStoreActionTest extends FormTestCase
$this->assertEquals('Jane', $form->participants->first()->data['vorname']); $this->assertEquals('Jane', $form->participants->first()->data['vorname']);
ExportSyncAction::assertPushed(); ExportSyncAction::assertPushed();
} });
public function testItHasValidation(): void it('testItHasValidation', function () {
{
Queue::fake(); Queue::fake();
$this->login()->loginNami(); $this->login()->loginNami();
$form = Form::factory()->fields([ $form = Form::factory()->fields([
@ -39,5 +40,4 @@ class ParticipantStoreActionTest extends FormTestCase
$this->postJson(route('form.participant.store', ['form' => $form->id]), ['vorname' => '']) $this->postJson(route('form.participant.store', ['form' => $form->id]), ['vorname' => ''])
->assertJsonValidationErrors(['vorname' => 'Vorname ist erforderlich.']); ->assertJsonValidationErrors(['vorname' => 'Vorname ist erforderlich.']);
} });
}

View File

@ -7,14 +7,16 @@ use App\Form\Models\Form;
use App\Form\Models\Participant; use App\Form\Models\Participant;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Queue; use Illuminate\Support\Facades\Queue;
use Tests\Lib\CreatesFormFields;
class ParticipantUpdateActionTest extends FormTestCase uses(DatabaseTransactions::class);
{ uses(CreatesFormFields::class);
use DatabaseTransactions; beforeEach(function () {
test()->setUpForm();
});
public function testItUpdatesParticipant(): void it('testItUpdatesParticipant', function () {
{
Queue::fake(); Queue::fake();
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$participant = Participant::factory()->data(['vorname' => 'Max']) $participant = Participant::factory()->data(['vorname' => 'Max'])
@ -28,10 +30,9 @@ class ParticipantUpdateActionTest extends FormTestCase
$this->assertEquals('Jane', $participant->fresh()->data['vorname']); $this->assertEquals('Jane', $participant->fresh()->data['vorname']);
ExportSyncAction::assertPushed(); ExportSyncAction::assertPushed();
} });
public function testItHasValidation(): void it('testItHasValidation', function () {
{
$this->login()->loginNami(); $this->login()->loginNami();
$participant = Participant::factory()->data(['vorname' => 'Max', 'select' => ['A', 'B']]) $participant = Participant::factory()->data(['vorname' => 'Max', 'select' => ['A', 'B']])
->for(Form::factory()->fields([ ->for(Form::factory()->fields([
@ -41,5 +42,4 @@ class ParticipantUpdateActionTest extends FormTestCase
$this->patchJson(route('participant.update', ['participant' => $participant->id]), ['vorname' => '']) $this->patchJson(route('participant.update', ['participant' => $participant->id]), ['vorname' => ''])
->assertJsonValidationErrors(['vorname' => 'Vorname ist erforderlich.']); ->assertJsonValidationErrors(['vorname' => 'Vorname ist erforderlich.']);
} });
}

View File

@ -13,11 +13,54 @@ use App\Form\Fields\NumberField;
use App\Form\Fields\RadioField; use App\Form\Fields\RadioField;
use App\Form\Fields\TextareaField; use App\Form\Fields\TextareaField;
use App\Form\Fields\TextField; use App\Form\Fields\TextField;
use Faker\Generator; use App\Form\FormSettings;
use App\Form\Models\Form;
use App\Member\Member;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use Illuminate\Testing\TestResponse;
use Tests\Feature\Form\FormtemplateFieldRequest; use Tests\Feature\Form\FormtemplateFieldRequest;
trait CreatesFormFields trait CreatesFormFields
{ {
/**
* @param array<string, mixed> $attributes
*/
public function createMember(array $attributes, ?callable $factoryCallback = null): Member
{
return call_user_func($factoryCallback ?: fn ($factory) => $factory, Member::factory()->defaults())
->create($attributes);
}
/**
* @param array<string, mixed> $payload
*/
public function register(Form $form, array $payload): TestResponse
{
return $this->postJson(route('form.register', ['form' => $form]), $payload);
}
public function setUpForm() {
app(FormSettings::class)->fill(['clearCacheUrl' => 'http://event.com/clear-cache'])->save();
Http::fake(function ($request) {
if ($request->url() === 'http://event.com/clear-cache') {
return Http::response('', 200);
}
});
Storage::fake('temp');
}
protected function assertFrontendCacheCleared(): void
{
Http::assertSent(fn ($request) => $request->url() === 'http://event.com/clear-cache'
&& $request->method() === 'GET'
);
}
protected static function namiField(?string $key = null): FormtemplateFieldRequest protected static function namiField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(NamiField::class)->key($key ?? static::randomKey()); return FormtemplateFieldRequest::type(NamiField::class)->key($key ?? static::randomKey());