From e011b52534969a83d20ad9fe475b705505b7b997 Mon Sep 17 00:00:00 2001 From: philipp lang Date: Fri, 12 Jan 2024 22:52:42 +0100 Subject: [PATCH] Add form api to display event overview on website --- app/Form/Actions/FormApiListAction.php | 29 +++++++++++ app/Form/FilterScope.php | 40 ++++++++++++++ app/Form/Models/Form.php | 21 ++++++++ app/Form/Resources/FormApiResource.php | 46 ++++++++++++++++ .../factories/Form/Models/FormFactory.php | 4 +- ...2_21_235228_create_formtemplates_table.php | 2 + routes/web.php | 2 + tests/Feature/Form/FormApiListActionTest.php | 52 +++++++++++++++++++ 8 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 app/Form/Actions/FormApiListAction.php create mode 100644 app/Form/FilterScope.php create mode 100644 app/Form/Resources/FormApiResource.php create mode 100644 tests/Feature/Form/FormApiListActionTest.php diff --git a/app/Form/Actions/FormApiListAction.php b/app/Form/Actions/FormApiListAction.php new file mode 100644 index 00000000..9cfb13ce --- /dev/null +++ b/app/Form/Actions/FormApiListAction.php @@ -0,0 +1,29 @@ + + */ + public function handle(FilterScope $filter): Collection + { + return Form::withFilter($filter)->get(); + } + + public function asController(ActionRequest $request): AnonymousResourceCollection + { + return FormApiResource::collection($this->handle(FilterScope::fromRequest($request->input('filter', '')))); + } +} diff --git a/app/Form/FilterScope.php b/app/Form/FilterScope.php new file mode 100644 index 00000000..5d654050 --- /dev/null +++ b/app/Form/FilterScope.php @@ -0,0 +1,40 @@ + + */ +#[MapInputName(SnakeCaseMapper::class)] +#[MapOutputName(SnakeCaseMapper::class)] +class FilterScope extends Filter +{ + public function __construct() + { + } + + /** + * {@inheritdoc} + */ + public function locks(): array + { + return []; + } + + /** + * @param Builder
$query + * + * @return Builder + */ + public function apply(Builder $query): Builder + { + return $query; + } +} diff --git a/app/Form/Models/Form.php b/app/Form/Models/Form.php index f9b58303..71eaed87 100644 --- a/app/Form/Models/Form.php +++ b/app/Form/Models/Form.php @@ -2,12 +2,16 @@ namespace App\Form\Models; +use App\Form\FilterScope; +use Cviebrock\EloquentSluggable\Sluggable; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Form extends Model { use HasFactory; + use Sluggable; public $guarded = []; @@ -15,6 +19,23 @@ class Form extends Model 'config' => 'json', ]; + public function sluggable(): array + { + return [ + 'slug' => ['source' => ['name']], + ]; + } + /** @var array */ public $dates = ['from', 'to', 'registration_from', 'registration_until']; + + /** + * @param Builder $query + * + * @return Builder + */ + public function scopeWithFilter(Builder $query, FilterScope $filter): Builder + { + return $filter->apply($query); + } } diff --git a/app/Form/Resources/FormApiResource.php b/app/Form/Resources/FormApiResource.php new file mode 100644 index 00000000..8872a1f3 --- /dev/null +++ b/app/Form/Resources/FormApiResource.php @@ -0,0 +1,46 @@ + + */ + public function toArray($request) + { + return [ + 'id' => $this->id, + 'name' => $this->name, + 'from_human' => $this->from->format('d.m.Y'), + 'to_human' => $this->to->format('d.m.Y'), + 'excerpt' => $this->excerpt, + 'description' => $this->description, + 'config' => $this->config, + 'slug' => $this->slug, + 'dates' => $this->from->equalTo($this->to) ? $this->from->format('d.m.Y') : $this->from->format('d.m.Y') . ' - ' . $this->to->format('d.m.Y'), + ]; + } + + /** + * @return array + */ + public static function meta(): array + { + return [ + 'base_url' => url(''), + ]; + } +} diff --git a/database/factories/Form/Models/FormFactory.php b/database/factories/Form/Models/FormFactory.php index e7d3d8fb..f2908ac8 100644 --- a/database/factories/Form/Models/FormFactory.php +++ b/database/factories/Form/Models/FormFactory.php @@ -41,8 +41,8 @@ class FormFactory extends Factory 'config' => ['sections' => []], 'from' => $this->faker->dateTime()->format('Y-m-d H:i:s'), 'to' => $this->faker->dateTime()->format('Y-m-d H:i:s'), - 'registration_from' => $this->faker->dateTime()->format('Y-m-d H:i:s'), - 'registration_until' => $this->faker->dateTime()->format('Y-m-d H:i:s'), + 'registration_from' => $this->faker->dateTimeBetween('-2 weeks', 'now')->format('Y-m-d H:i:s'), + 'registration_until' => $this->faker->dateTimeBetween('now', '+2 weeks')->format('Y-m-d H:i:s'), 'mail_top' => $this->faker->text(), 'mail_bottom' => $this->faker->text(), ]; diff --git a/database/migrations/2023_12_21_235228_create_formtemplates_table.php b/database/migrations/2023_12_21_235228_create_formtemplates_table.php index 3dae7501..605c86cd 100644 --- a/database/migrations/2023_12_21_235228_create_formtemplates_table.php +++ b/database/migrations/2023_12_21_235228_create_formtemplates_table.php @@ -23,6 +23,7 @@ return new class extends Migration Schema::create('forms', function (Blueprint $table) { $table->id(); $table->string('name'); + $table->string('slug'); $table->text('description'); $table->text('excerpt'); $table->json('config'); @@ -44,5 +45,6 @@ return new class extends Migration public function down() { Schema::dropIfExists('formtemplates'); + Schema::dropIfExists('forms'); } }; diff --git a/routes/web.php b/routes/web.php index cf298b0f..76e38e61 100644 --- a/routes/web.php +++ b/routes/web.php @@ -19,6 +19,7 @@ use App\Invoice\Actions\InvoiceStoreAction; use App\Course\Actions\CourseUpdateAction; use App\Dashboard\Actions\IndexAction as DashboardIndexAction; use App\Efz\ShowEfzDocumentAction; +use App\Form\Actions\FormApiListAction; use App\Form\Actions\FormDestroyAction; use App\Form\Actions\FormIndexAction; use App\Group\Actions\GroupApiIndexAction; @@ -158,3 +159,4 @@ Route::group(['middleware' => 'auth:web'], function (): void { }); Route::get('/api/group/{group?}', GroupApiIndexAction::class)->name('api.group'); +Route::get('/api/form', FormApiListAction::class)->name('api.form.index'); diff --git a/tests/Feature/Form/FormApiListActionTest.php b/tests/Feature/Form/FormApiListActionTest.php new file mode 100644 index 00000000..14b6115e --- /dev/null +++ b/tests/Feature/Form/FormApiListActionTest.php @@ -0,0 +1,52 @@ +loginNami()->withoutExceptionHandling(); + Formtemplate::factory()->name('tname')->sections([FormtemplateSectionRequest::new()->name('sname')])->create(); + $form = Form::factory() + ->name('lala 2') + ->excerpt('fff') + ->description('desc') + ->from('2023-05-05') + ->to('2023-06-07') + ->sections([FormtemplateSectionRequest::new()->name('sname')->fields([FormtemplateFieldRequest::new()])]) + ->create(); + + $this->get('/api/form') + ->assertOk() + ->assertJsonPath('data.0.name', 'lala 2') + ->assertJsonPath('data.0.config.sections.0.name', 'sname') + ->assertJsonPath('data.0.id', $form->id) + ->assertJsonPath('data.0.excerpt', 'fff') + ->assertJsonPath('data.0.description', 'desc') + ->assertJsonPath('data.0.slug', 'lala-2') + ->assertJsonPath('data.0.dates', '05.05.2023 - 07.06.2023') + ->assertJsonPath('data.0.from_human', '05.05.2023') + ->assertJsonPath('data.0.to_human', '07.06.2023'); + } + + public function testItDisplaysDailyForms(): void + { + $this->loginNami()->withoutExceptionHandling(); + Form::factory() + ->from('2023-05-05') + ->to('2023-05-05') + ->create(); + + $this->get('/api/form') + ->assertJsonPath('data.0.dates', '05.05.2023'); + } +}