Add later registration backend
continuous-integration/drone/push Build is failing Details

This commit is contained in:
philipp lang 2025-08-14 23:55:50 +02:00
parent e6526ee326
commit dafda4883d
3 changed files with 59 additions and 6 deletions

View File

@ -7,6 +7,8 @@ use App\Form\Models\Form;
use App\Form\Models\Participant;
use App\Member\Member;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Lorisleiva\Actions\ActionRequest;
use Lorisleiva\Actions\Concerns\AsAction;
@ -20,13 +22,9 @@ class RegisterAction
*/
public function handle(Form $form, array $input): Participant
{
if (!$form->canRegister()) {
throw ValidationException::withMessages(['event' => 'Anmeldung zzt nicht möglich.']);
}
$memberQuery = FieldCollection::fromRequest($form, $input)
->withNamiType()
->reduce(fn ($query, $field) => $field->namiType->performQuery($query, $field->value), (new Member())->newQuery());
->reduce(fn($query, $field) => $field->namiType->performQuery($query, $field->value), (new Member())->newQuery());
$member = $form->getFields()->withNamiType()->count() && $memberQuery->count() === 1 ? $memberQuery->first() : null;
$participant = $form->participants()->create([
@ -34,7 +32,7 @@ class RegisterAction
'member_id' => $member?->id,
]);
$form->getFields()->each(fn ($field) => $field->afterRegistration($form, $participant, $input));
$form->getFields()->each(fn($field) => $field->afterRegistration($form, $participant, $input));
$participant->sendConfirmationMail();
ExportSyncAction::dispatch($form->id);
@ -77,8 +75,26 @@ class RegisterAction
public function asController(ActionRequest $request, Form $form): JsonResponse
{
if (!$form->canRegister() && !$this->isRegisteringLater($request)) {
throw ValidationException::withMessages(['event' => 'Anmeldung zzt nicht möglich.']);
}
$participant = $this->handle($form, $request->validated());
return response()->json($participant);
}
public function isRegisteringLater(ActionRequest $request): bool {
if (!is_array($request->query())) {
return false;
}
$validator = Validator::make($request->query(), [
'later' => 'required|numeric|in:1',
'id' => 'required|string|uuid:4',
'signature' => 'required|string',
]);
return URL::hasValidSignature($request) && $validator->passes();
}
}

View File

@ -735,3 +735,23 @@ it('testItSetsRegionIfMemberIsDirectRegionMember', function () {
$this->register($form, ['bezirk' => $bezirk->id, 'members' => [['id' => '5505']]])->assertOk();
$this->assertEquals($bezirk->id, $form->participants->get(1)->data['bezirk']);
});
it('registers via later link', function () {
$this->login()->loginNami();
$form = Form::factory()->fields([])
->registrationUntil(now()->subDay())
->create();
$this->registerLater($form, [], str()->uuid())->assertOk();
$this->assertDatabaseCount('participants', 1);
});
it('checks signature of later link', function () {
$this->login()->loginNami();
$form = Form::factory()->fields([])
->registrationUntil(now()->subDay())
->create();
$this->registerLaterWithWrongSignature($form, [], str()->uuid())->assertStatus(422);
$this->assertDatabaseCount('participants', 0);
});

View File

@ -18,6 +18,7 @@ use App\Form\Models\Form;
use App\Member\Member;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use Illuminate\Testing\TestResponse;
use Tests\Feature\Form\FormtemplateFieldRequest;
@ -42,6 +43,22 @@ trait CreatesFormFields
return $this->postJson(route('form.register', ['form' => $form]), $payload);
}
/**
* @param array<string, mixed> $payload
*/
public function registerLater(Form $form, array $payload, string $laterId): TestResponse
{
return $this->postJson(URL::signedRoute('form.register', ['form' => $form, 'later' => '1', 'id' => $laterId]), $payload);
}
/**
* @param array<string, mixed> $payload
*/
public function registerLaterWithWrongSignature(Form $form, array $payload, string $laterId): TestResponse
{
return $this->postJson(route('form.register', ['form' => $form, 'later' => '1', 'id' => $laterId, 'signature' => '-1']), $payload);
}
public function setUpForm() {
app(FormSettings::class)->fill(['clearCacheUrl' => 'http://event.com/clear-cache'])->save();