Add StoreAction for form

This commit is contained in:
philipp lang 2023-12-27 22:54:58 +01:00
parent 5b2a290b49
commit f1d4d3e428
9 changed files with 207 additions and 3 deletions

View File

@ -0,0 +1,43 @@
<?php
namespace App\Form\Actions;
use App\Form\Models\Form;
use App\Lib\Events\Succeeded;
use Illuminate\Http\JsonResponse;
use Lorisleiva\Actions\Concerns\AsAction;
use Lorisleiva\Actions\ActionRequest;
class FormStoreAction
{
use AsAction;
use HasValidation;
/**
* @return array<string, mixed>
*/
public function rules(): array
{
return [
...$this->globalRules(),
'description' => 'required|string',
'excerpt' => 'required|string|max:120',
];
}
/**
* @param array<string, mixed> $attributes
*/
public function handle(array $attributes): Form
{
return Form::create($attributes);
}
public function asController(ActionRequest $request): JsonResponse
{
$this->handle($request->validated());
Succeeded::message('Formular gespeichert.')->dispatch();
return response()->json([]);
}
}

View File

@ -13,6 +13,16 @@ class FormtemplateStoreAction
use AsAction;
use HasValidation;
/**
* @return array<string, mixed>
*/
public function rules(): array
{
return [
...$this->globalRules(),
];
}
/**
* @param array<string, mixed> $attributes
*/

View File

@ -19,8 +19,7 @@ class FormtemplateUpdateAction
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'config' => '',
...$this->globalRules(),
];
}

View File

@ -12,7 +12,7 @@ trait HasValidation
/**
* @return array<string, mixed>
*/
public function rules(): array
public function globalRules(): array
{
return [
'name' => 'required|string|max:255',

17
app/Form/Models/Form.php Normal file
View File

@ -0,0 +1,17 @@
<?php
namespace App\Form\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Form extends Model
{
use HasFactory;
public $guarded = [];
public $casts = [
'config' => 'json',
];
}

View File

@ -0,0 +1,31 @@
<?php
namespace Database\Factories;
use App\Form\Models\Form;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Form\Models\Form>
*/
class FormFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Form::class;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
//
];
}
}

View File

@ -19,6 +19,15 @@ return new class extends Migration
$table->json('config');
$table->timestamps();
});
Schema::create('forms', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description');
$table->text('excerpt');
$table->json('config');
$table->timestamps();
});
}
/**

View File

@ -0,0 +1,39 @@
<?php
namespace Tests\Feature\Form;
use Worksome\RequestFactories\RequestFactory;
/**
* @method self name(string $name)
*/
class FormRequest extends RequestFactory
{
/**
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => $this->faker->words(4, true),
'description' => $this->faker->text(),
'config' => ['sections' => []],
];
}
/**
* @param array<int, FormtemplateSectionRequest> $sections
*/
public function sections(array $sections): self
{
return $this->state(['config.sections' => $sections]);
}
/**
* @param mixed $args
*/
public function __call(string $method, $args): self
{
return $this->state([$method => $args[0]]);
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace Tests\Feature\Form;
use App\Form\Models\Form;
use App\Lib\Events\Succeeded;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;
use Generator;
class FormStoreActionTest extends TestCase
{
use DatabaseTransactions;
public function testItStoresForm(): void
{
Event::fake([Succeeded::class]);
$this->login()->loginNami()->withoutExceptionHandling();
FormRequest::new()
->name('formname')
->description('lala ggg')
->excerpt('avff')
->sections([FormtemplateSectionRequest::new()->name('sname')->fields([FormtemplateFieldRequest::new()])])
->fake();
$this->postJson(route('form.store'))->assertOk();
$form = Form::latest()->first();
$this->assertEquals('sname', $form->config['sections'][0]['name']);
$this->assertEquals('formname', $form->name);
$this->assertEquals('avff', $form->excerpt);
$this->assertEquals('lala ggg', $form->description);
Event::assertDispatched(Succeeded::class, fn (Succeeded $event) => $event->message === 'Formular gespeichert.');
}
public function validationDataProvider(): Generator
{
yield [FormRequest::new()->name(''), ['name' => 'Name ist erforderlich.']];
yield [FormRequest::new()->excerpt(''), ['excerpt' => 'Auszug ist erforderlich.']];
yield [FormRequest::new()->description(''), ['description' => 'Beschreibung ist erforderlich.']];
}
/**
* @dataProvider validationDataProvider
* @param array<string, string> $messages
*/
public function testItValidatesRequests(FormRequest $request, array $messages): void
{
$this->login()->loginNami();
$request->fake();
$this->postJson(route('form.store'))->assertJsonValidationErrors($messages);
}
}