Add prevention_text to form

This commit is contained in:
philipp lang 2024-07-06 15:08:13 +02:00
parent c9ccebc8f3
commit 3dacfb3e54
14 changed files with 105 additions and 3 deletions

View File

@ -36,6 +36,7 @@ class FormStoreAction
'is_private' => 'boolean', 'is_private' => 'boolean',
'export' => 'nullable|array', 'export' => 'nullable|array',
'needs_prevention' => 'present|boolean', 'needs_prevention' => 'present|boolean',
'prevention_text' => 'array',
]; ];
} }

View File

@ -35,6 +35,7 @@ class FormUpdateAction
'is_private' => 'boolean', 'is_private' => 'boolean',
'export' => 'nullable|array', 'export' => 'nullable|array',
'needs_prevention' => 'present|boolean', 'needs_prevention' => 'present|boolean',
'prevention_text' => 'array',
]; ];
} }

View File

@ -28,7 +28,8 @@ class PreventionRememberAction
} }
$body = app(PreventionSettings::class)->formmail $body = app(PreventionSettings::class)->formmail
->placeholder('formname', $participant->form->name); ->placeholder('formname', $participant->form->name)
->append($participant->form->prevention_text);
if ($participant->getFields()->getMailRecipient() === null) { if ($participant->getFields()->getMailRecipient() === null) {
continue; continue;

View File

@ -5,6 +5,7 @@ namespace App\Form\Models;
use App\Form\Data\ExportData; use App\Form\Data\ExportData;
use App\Form\Data\FieldCollection; use App\Form\Data\FieldCollection;
use App\Form\Data\FormConfigData; use App\Form\Data\FormConfigData;
use App\Lib\Editor\EditorData;
use Cviebrock\EloquentSluggable\Sluggable; use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@ -37,6 +38,7 @@ class Form extends Model implements HasMedia
'is_private' => 'boolean', 'is_private' => 'boolean',
'export' => ExportData::class, 'export' => ExportData::class,
'needs_prevention' => 'boolean', 'needs_prevention' => 'boolean',
'prevention_text' => EditorData::class,
]; ];
/** @var array<int, string> */ /** @var array<int, string> */

View File

@ -11,6 +11,7 @@ use App\Form\Scopes\FormFilterScope;
use App\Form\Models\Form; use App\Form\Models\Form;
use App\Form\Models\Formtemplate; use App\Form\Models\Formtemplate;
use App\Group; use App\Group;
use App\Lib\Editor\EditorData;
use App\Lib\HasMeta; use App\Lib\HasMeta;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;
@ -94,6 +95,7 @@ class FormResource extends JsonResource
'config' => null, 'config' => null,
'header_image' => null, 'header_image' => null,
'mailattachments' => [], 'mailattachments' => [],
'prevention_text' => EditorData::default(),
'id' => null, 'id' => null,
'export' => ExportData::from([]), 'export' => ExportData::from([]),
], ],

View File

@ -5,7 +5,7 @@ namespace App\Lib\Editor;
use Spatie\LaravelData\Data; use Spatie\LaravelData\Data;
/** @todo replace blocks with actual block data classes */ /** @todo replace blocks with actual block data classes */
class EditorData extends Data class EditorData extends Data implements Editorable
{ {
public function __construct( public function __construct(
@ -31,6 +31,22 @@ class EditorData extends Data
return collect($wanted)->first(fn ($search) => !str(json_encode($this->blocks))->contains($search)) === null; return collect($wanted)->first(fn ($search) => !str(json_encode($this->blocks))->contains($search)) === null;
} }
public static function default(): self
{
return static::from([
'version' => '1.0',
'blocks' => [],
'time' => 0,
]);
}
public function append(Editorable $editorable): self
{
$this->blocks = array_merge($this->blocks, $editorable->toEditorData()->blocks);
return $this;
}
public function replaceWithList(string $blockContent, array $replacements): self public function replaceWithList(string $blockContent, array $replacements): self
{ {
$this->blocks = collect($this->blocks)->map(function ($block) use ($blockContent, $replacements) { $this->blocks = collect($this->blocks)->map(function ($block) use ($blockContent, $replacements) {
@ -56,6 +72,11 @@ class EditorData extends Data
})->toArray(); })->toArray();
return $this;
}
public function toEditorData(): EditorData
{
return $this; return $this;
} }
} }

View File

@ -0,0 +1,8 @@
<?php
namespace App\Lib\Editor;
interface Editorable
{
public function toEditorData(): EditorData;
}

View File

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Tests\RequestFactories\EditorRequestFactory;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('forms', function (Blueprint $table) {
$table->json('prevention_text')->after('description')->default(json_encode(EditorRequestFactory::new()->empty()->create()));
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('forms', function (Blueprint $table) {
$table->dropColumn('prevention_text');
});
}
};

View File

@ -61,6 +61,7 @@ class FormIndexActionTest extends FormTestCase
->assertInertiaPath('data.meta.templates.0.name', 'tname') ->assertInertiaPath('data.meta.templates.0.name', 'tname')
->assertInertiaPath('data.meta.templates.0.config.sections.0.name', 'sname') ->assertInertiaPath('data.meta.templates.0.config.sections.0.name', 'sname')
->assertInertiaPath('data.meta.default.name', '') ->assertInertiaPath('data.meta.default.name', '')
->assertInertiaPath('data.meta.default.prevention_text.version', '1.0')
->assertInertiaPath('data.meta.default.description', []) ->assertInertiaPath('data.meta.default.description', [])
->assertInertiaPath('data.meta.default.excerpt', '') ->assertInertiaPath('data.meta.default.excerpt', '')
->assertInertiaPath('data.meta.default.is_active', true) ->assertInertiaPath('data.meta.default.is_active', true)

View File

@ -50,6 +50,7 @@ class FormRequest extends RequestFactory
'mailattachments' => [], 'mailattachments' => [],
'export' => ExportData::from([])->toArray(), 'export' => ExportData::from([])->toArray(),
'needs_prevention' => $this->faker->boolean(), 'needs_prevention' => $this->faker->boolean(),
'prevention_text' => EditorRequestFactory::new()->create(),
]; ];
} }

View File

@ -26,6 +26,7 @@ class FormStoreActionTest extends FormTestCase
->name('formname') ->name('formname')
->description($description) ->description($description)
->excerpt('avff') ->excerpt('avff')
->preventionText(EditorRequestFactory::new()->paragraphs(['lorem ipsum']))
->registrationFrom('2023-05-04 01:00:00')->registrationUntil('2023-07-07 01:00:00')->from('2023-07-07')->to('2023-07-08') ->registrationFrom('2023-05-04 01:00:00')->registrationUntil('2023-07-07 01:00:00')->from('2023-07-07')->to('2023-07-08')
->mailTop(EditorRequestFactory::new()->text(11, 'lala')) ->mailTop(EditorRequestFactory::new()->text(11, 'lala'))
->mailBottom(EditorRequestFactory::new()->text(12, 'lalab')) ->mailBottom(EditorRequestFactory::new()->text(12, 'lalab'))
@ -38,6 +39,7 @@ class FormStoreActionTest extends FormTestCase
$form = Form::latest()->first(); $form = Form::latest()->first();
$this->assertEquals('sname', $form->config->sections->get(0)->name); $this->assertEquals('sname', $form->config->sections->get(0)->name);
$this->assertEquals('formname', $form->name); $this->assertEquals('formname', $form->name);
$this->assertEquals('lorem ipsum', $form->prevention_text->blocks[0]['data']['text']);
$this->assertEquals('avff', $form->excerpt); $this->assertEquals('avff', $form->excerpt);
$this->assertEquals($description->paragraphBlock(10, 'Lorem'), $form->description); $this->assertEquals($description->paragraphBlock(10, 'Lorem'), $form->description);
$this->assertEquals(json_decode('{"time":1,"blocks":[{"id":11,"type":"paragraph","data":{"text":"lala"},"tunes":{"condition":{"mode":"all","ifs":[]}}}],"version":"1.0"}', true), $form->mail_top); $this->assertEquals(json_decode('{"time":1,"blocks":[{"id":11,"type":"paragraph","data":{"text":"lala"},"tunes":{"condition":{"mode":"all","ifs":[]}}}],"version":"1.0"}', true), $form->mail_top);
@ -88,6 +90,7 @@ class FormStoreActionTest extends FormTestCase
yield [FormRequest::new()->state(['header_image' => null]), ['header_image' => 'Bild ist erforderlich']]; yield [FormRequest::new()->state(['header_image' => null]), ['header_image' => 'Bild ist erforderlich']];
} }
/** /**
* @dataProvider validationDataProvider * @dataProvider validationDataProvider
* @param array<string, string> $messages * @param array<string, string> $messages

View File

@ -5,7 +5,9 @@ namespace Tests\Feature\Form;
use App\Fileshare\Data\FileshareResourceData; use App\Fileshare\Data\FileshareResourceData;
use App\Form\Data\ExportData; use App\Form\Data\ExportData;
use App\Form\Models\Form; use App\Form\Models\Form;
use App\Lib\Editor\EditorData;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\RequestFactories\EditorRequestFactory;
class FormUpdateActionTest extends FormTestCase class FormUpdateActionTest extends FormTestCase
{ {
@ -128,9 +130,13 @@ class FormUpdateActionTest extends FormTestCase
{ {
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
$form = Form::factory()->create(); $form = Form::factory()->create();
$payload = FormRequest::new()->state(['needs_prevention' => true])->create(); $payload = FormRequest::new()
->preventionText(EditorRequestFactory::new()->text(10, 'lorem ipsum')->create())
->state(['needs_prevention' => true])
->create();
$this->patchJson(route('form.update', ['form' => $form]), $payload); $this->patchJson(route('form.update', ['form' => $form]), $payload);
$this->assertTrue($form->fresh()->needs_prevention); $this->assertTrue($form->fresh()->needs_prevention);
$this->assertEquals('lorem ipsum', $form->fresh()->prevention_text->blocks[0]['data']['text']);
} }
} }

View File

@ -200,6 +200,23 @@ class PreventionTest extends TestCase
])); ]));
} }
public function testItAppendsTextOfForm(): void
{
Mail::fake();
app(PreventionSettings::class)->fake([
'formmail' => EditorRequestFactory::new()->paragraphs(["::first::"])->toData()
])->save();
$form = $this->createForm();
$form->update(['prevention_text' => EditorRequestFactory::new()->paragraphs(['event'])->toData()]);
$this->createParticipant($form);
PreventionRememberAction::run();
Mail::assertSent(PreventionRememberMail::class, fn ($mail) => $mail->bodyText->hasAll([
'event'
]));
}
public function testItDisplaysBodyTextInMail(): void public function testItDisplaysBodyTextInMail(): void
{ {
$form = $this->createForm(); $form = $this->createForm();

View File

@ -21,6 +21,11 @@ class EditorRequestFactory extends RequestFactory
]; ];
} }
public function empty(): self
{
return $this->state(['blocks' => []]);
}
/** /**
* @param array<string, mixed> $conditions * @param array<string, mixed> $conditions
*/ */