Remove ValidateAction

This commit is contained in:
philipp lang 2025-06-20 01:02:43 +02:00
parent af13bb1cde
commit e396714d31
8 changed files with 69 additions and 71 deletions

View File

@ -6,7 +6,7 @@ use App\Contribution\Contracts\HasContributionData;
use App\Contribution\ContributionFactory;
use App\Contribution\Requests\GenerateRequest;
use App\Rules\JsonBase64Rule;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\JsonResponse;
use Lorisleiva\Actions\Concerns\AsAction;
use Zoomyboy\Tex\BaseCompiler;
use Zoomyboy\Tex\Tex;
@ -20,13 +20,14 @@ class GenerateAction
return Tex::compile($request->type()::fromPayload($request));
}
public function asController(GenerateRequest $request): BaseCompiler
public function asController(GenerateRequest $request): BaseCompiler|JsonResponse
{
$type = $request->type();
ValidateAction::validateType($type);
Validator::make($request->payload(), app(ContributionFactory::class)->rules($type))->validate();
app(ContributionFactory::class)->validateType($request);
app(ContributionFactory::class)->validatePayload($request);
return $this->handle($request);
return $request->input('validate')
? response()->json([])
: $this->handle($request);
}
/**

View File

@ -3,6 +3,7 @@
namespace App\Contribution\Actions;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\ContributionFactory;
use App\Contribution\Requests\GenerateApiRequest;
use Lorisleiva\Actions\Concerns\AsAction;
use Zoomyboy\Tex\BaseCompiler;
@ -22,8 +23,7 @@ class GenerateApiAction
public function asController(GenerateApiRequest $request): BaseCompiler
{
$type = $request->type();
ValidateAction::validateType($type);
app(ContributionFactory::class)->validateType($request);
return $this->handle($request);
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Contribution\Actions;
use App\Contribution\ContributionFactory;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Validator;
use Lorisleiva\Actions\ActionRequest;
use Lorisleiva\Actions\Concerns\AsAction;
class ValidateAction
{
use AsAction;
public function asController(): JsonResponse
{
return response()->json(['valid' => true]);
}
/**
* @return array<string, mixed>
*/
public function rules(): array
{
return app(ContributionFactory::class)->rules(request()->type);
}
public function prepareForValidation(ActionRequest $request): void
{
static::validateType($request->input('type'));
}
public static function validateType(?string $type = null): void
{
Validator::make(['type' => $type], app(ContributionFactory::class)->typeRule())->validate();
}
}

View File

@ -25,4 +25,6 @@ interface HasContributionData {
public function members(): Collection;
public function country(): ?Country;
public function payload(): array;
}

View File

@ -2,6 +2,7 @@
namespace App\Contribution;
use App\Contribution\Contracts\HasContributionData;
use App\Contribution\Documents\BdkjHesse;
use App\Contribution\Documents\ContributionDocument;
use App\Contribution\Documents\RdpNrwDocument;
@ -10,6 +11,7 @@ use App\Contribution\Documents\CitySolingenDocument;
use App\Contribution\Documents\CityFrankfurtMainDocument;
use App\Contribution\Documents\WuppertalDocument;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
class ContributionFactory
@ -59,4 +61,12 @@ class ContributionFactory
...$type::rules(),
];
}
public function validateType(HasContributionData $request) {
Validator::make(['type' => $request->type()], $this->typeRule())->validate();
}
public function validatePayload(HasContributionData $request) {
Validator::make($request->payload(), $this->rules($request->type()))->validate();
}
}

View File

@ -1,32 +1,31 @@
<template>
<page-layout>
<form target="_BLANK" class="max-w-4xl w-full mx-auto gap-6 grid-cols-2 grid p-6">
<f-text id="eventName" v-model="values.eventName" class="col-span-2" label="Veranstaltungs-Name" required></f-text>
<f-text id="dateFrom" v-model="values.dateFrom" type="date" label="Datum von" required></f-text>
<f-text id="dateUntil" v-model="values.dateUntil" type="date" label="Datum bis" required></f-text>
<f-text id="eventName" v-model="values.eventName" class="col-span-2" label="Veranstaltungs-Name" required />
<f-text id="dateFrom" v-model="values.dateFrom" type="date" label="Datum von" required />
<f-text id="dateUntil" v-model="values.dateUntil" type="date" label="Datum bis" required />
<f-text id="zipLocation" v-model="values.zipLocation" label="PLZ / Ort" required></f-text>
<f-select id="country" v-model="values.country" :options="countries" name="country" label="Land" required></f-select>
<f-text id="zipLocation" v-model="values.zipLocation" label="PLZ / Ort" required />
<f-select id="country" v-model="values.country" :options="countries" name="country" label="Land" required />
<div class="border-gray-200 shadow shadow-primary-700 p-3 shadow-[0_0_4px_gray] col-span-2">
<f-text id="search_text" ref="searchInput" v-model="searchString" class="col-span-2" label="Suchen …" size="sm" @keypress.enter.prevent="onSubmitFirstMemberResult"></f-text>
<f-text id="search_text" ref="searchInput" v-model="searchString" class="col-span-2" label="Suchen …" size="sm" @keypress.enter.prevent="onSubmitFirstMemberResult" />
<div class="mt-2 grid grid-cols-[repeat(auto-fill,minmax(180px,1fr))] gap-2 col-span-2">
<f-switch
v-for="member in results.hits"
:id="`members-${member.id}`"
:key="member.id"
v-model="values.members"
:label="member.fullname"
name="members[]"
:value="member.id"
size="sm"
inline
@keypress.enter.prevent="onSubmitMemberResult(member)"
></f-switch>
<f-switch v-for="member in results.hits"
:id="`members-${member.id}`"
:key="member.id"
v-model="values.members"
:label="member.fullname"
name="members[]"
:value="member.id"
size="sm"
inline
@keypress.enter.prevent="onSubmitMemberResult(member)"
/>
</div>
</div>
<button v-for="(compiler, index) in compilers" :key="index" class="btn btn-primary mt-3 inline-block" @click.prevent="submit(compiler.class)" v-text="compiler.title"></button>
<button v-for="(compiler, index) in compilers" :key="index" class="btn btn-primary mt-3 inline-block" @click.prevent="submit(compiler.class)" v-text="compiler.title" />
</form>
</page-layout>
</template>
@ -58,8 +57,8 @@ const values = ref({
async function submit(compiler) {
values.value.type = compiler;
await axios.post('/contribution-validate', values.value);
var payload = btoa(encodeURIComponent(JSON.stringify(values.value)));
const payload = btoa(encodeURIComponent(JSON.stringify(values.value)));
await axios.get(`/contribution-generate?payload=${payload}&validate=1`);
window.open(`/contribution-generate?payload=${payload}`);
}
function onSubmitMemberResult(selected) {

View File

@ -11,7 +11,6 @@ use App\Activity\Api\SubactivityStoreAction;
use App\Activity\Api\SubactivityUpdateAction;
use App\Contribution\Actions\FormAction as ContributionFormAction;
use App\Contribution\Actions\GenerateAction as ContributionGenerateAction;
use App\Contribution\Actions\ValidateAction as ContributionValidateAction;
use App\Course\Actions\CourseDestroyAction;
use App\Course\Actions\CourseIndexAction;
use App\Course\Actions\CourseStoreAction;
@ -70,7 +69,6 @@ use App\Member\Actions\MemberResyncAction;
use App\Member\Actions\MemberShowAction;
use App\Member\Actions\SearchAction;
use App\Member\MemberController;
use App\Membership\Actions\IndexAction as MembershipIndexAction;
use App\Membership\Actions\ListForGroupAction;
use App\Membership\Actions\MassListAction;
use App\Membership\Actions\MassStoreAction;
@ -112,7 +110,6 @@ Route::group(['middleware' => 'auth:web'], function (): void {
// ------------------------------- Contributions -------------------------------
Route::get('/contribution', ContributionFormAction::class)->name('contribution.form');
Route::get('/contribution-generate', ContributionGenerateAction::class)->name('contribution.generate');
Route::post('/contribution-validate', ContributionValidateAction::class)->name('contribution.validate');
// ----------------------------------- mail ------------------------------------
Route::post('/api/mailgateway', StoreAction::class)->name('mailgateway.store');

View File

@ -39,6 +39,30 @@ it('compiles documents via base64 param', function (string $type, array $bodyChe
Tex::assertCompiled($type, fn ($document) => $document->hasAllContent($bodyChecks));
})->with('contribution-assertions');
it('only validates', function (string $type) {
$this->withoutExceptionHandling();
Tex::spy();
$this->login()->loginNami();
$member1 = Member::factory()->defaults()->male()->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Max', 'lastname' => 'Muster']);
$member2 = Member::factory()->defaults()->female()->create(['address' => 'Maxstr 44', 'zip' => '42719', 'firstname' => 'Jane', 'lastname' => 'Muster']);
$response = $this->call('GET', '/contribution-generate', [
'validate' => '1',
'payload' => ContributionRequestFactory::new()->type($type)->state([
'dateFrom' => '1991-06-15',
'dateUntil' => '1991-06-16',
'eventName' => 'Super tolles Lager',
'members' => [$member1->id, $member2->id],
'type' => $type,
'zipLocation' => '42777 SG',
])->toBase64(),
]);
$response->assertSessionDoesntHaveErrors();
$response->assertOk();
Tex::assertNotCompiled($type);
})->with('contribution-assertions');
it('testItCompilesGroupNameInSolingenDocument', function () {
$this->withoutExceptionHandling()->login()->loginNami();
Tex::spy();
@ -91,8 +115,10 @@ it('testItValidatesInput', function (array $input, string $documentClass, string
Country::factory()->create();
Member::factory()->defaults()->create();
$this->postJson('/contribution-validate', ContributionRequestFactory::new()->type($documentClass)->state($input)->create())
->assertJsonValidationErrors($errorField);
$this->json('GET', '/contribution-generate?'.http_build_query([
'payload' => ContributionRequestFactory::new()->type($documentClass)->state($input)->toBase64(),
'validate' => '1'
]))->assertJsonValidationErrors($errorField);
})->with('contribution-validation');
it('testItValidatesInputBeforeGeneration', function (array $input, string $documentClass, string $errorField) {