diff --git a/app/Lib/Data/DateData.php b/app/Lib/Data/DateData.php new file mode 100644 index 00000000..27cec2db --- /dev/null +++ b/app/Lib/Data/DateData.php @@ -0,0 +1,29 @@ +> + */ + public static function normalizers(): array + { + return [ + DateNormalizer::class, + ]; + } +} diff --git a/app/Lib/Data/RecordData.php b/app/Lib/Data/RecordData.php new file mode 100644 index 00000000..d5bb628f --- /dev/null +++ b/app/Lib/Data/RecordData.php @@ -0,0 +1,14 @@ + + */ + public function normalize(mixed $value): ?array + { + if (!$value instanceof Carbon) { + return null; + } + + return [ + 'raw' => $value, + 'human' => $value->format('d.m.Y'), + ]; + } +} diff --git a/app/Lib/Transformers/DateTransformer.php b/app/Lib/Transformers/DateTransformer.php new file mode 100644 index 00000000..472b0f47 --- /dev/null +++ b/app/Lib/Transformers/DateTransformer.php @@ -0,0 +1,16 @@ +format('Y-m-d'); + } +} diff --git a/app/Member/Data/MembershipData.php b/app/Member/Data/MembershipData.php new file mode 100644 index 00000000..c563cbc8 --- /dev/null +++ b/app/Member/Data/MembershipData.php @@ -0,0 +1,41 @@ +withoutMagicalCreation()->from([ + 'id' => $membership->id, + 'activity' => $membership->activity, + 'subactivity' => $membership->subactivity, + 'isActive' => $membership->isActive(), + 'from' => $membership->from, + 'group' => $membership->group, + 'promisedAt' => $membership->promised_at, + 'links' => [ + 'update' => route('membership.update', $membership), + 'destroy' => route('membership.destroy', $membership), + ] + ]); + } + +} diff --git a/app/Membership/Actions/IndexAction.php b/app/Membership/Actions/MemberIndexAction.php similarity index 96% rename from app/Membership/Actions/IndexAction.php rename to app/Membership/Actions/MemberIndexAction.php index 86919cf0..d09b17ef 100644 --- a/app/Membership/Actions/IndexAction.php +++ b/app/Membership/Actions/MemberIndexAction.php @@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\Collection; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; use Lorisleiva\Actions\Concerns\AsAction; -class IndexAction +class MemberIndexAction { use AsAction; diff --git a/app/Membership/Actions/MembershipIndexAction.php b/app/Membership/Actions/MembershipIndexAction.php new file mode 100644 index 00000000..641f820a --- /dev/null +++ b/app/Membership/Actions/MembershipIndexAction.php @@ -0,0 +1,23 @@ +paginate(20), PaginatedDataCollection::class)->wrap('data') + ); + } +} diff --git a/routes/web.php b/routes/web.php index a103aa71..7da88809 100644 --- a/routes/web.php +++ b/routes/web.php @@ -73,7 +73,9 @@ use App\Membership\Actions\IndexAction as MembershipIndexAction; use App\Membership\Actions\ListForGroupAction; use App\Membership\Actions\MassListAction; use App\Membership\Actions\MassStoreAction; +use App\Membership\Actions\MemberIndexAction; use App\Membership\Actions\MembershipDestroyAction; +use App\Membership\Actions\MembershipIndexAction as ActionsMembershipIndexAction; use App\Membership\Actions\MembershipStoreAction; use App\Membership\Actions\MembershipUpdateAction; use App\Payment\SubscriptionController; @@ -140,13 +142,14 @@ Route::group(['middleware' => 'auth:web'], function (): void { Route::get('/member/{member}/invoice-position', PaymentPositionIndexAction::class)->name('member.invoice-position.index'); // --------------------------------- membership -------------------------------- - Route::get('/member/{member}/membership', MembershipIndexAction::class)->name('member.membership.index'); + Route::get('/member/{member}/membership', MemberIndexAction::class)->name('member.membership.index'); Route::post('/member/{member}/membership', MembershipStoreAction::class)->name('member.membership.store'); Route::patch('/membership/{membership}', MembershipUpdateAction::class)->name('membership.update'); Route::delete('/membership/{membership}', MembershipDestroyAction::class)->name('membership.destroy'); Route::post('/api/membership/member-list', ListForGroupAction::class)->name('membership.member-list'); Route::post('/api/membership/masslist', MassStoreAction::class)->name('membership.masslist.store'); Route::get('/membership/masslist', MassListAction::class)->name('membership.masslist.index'); + Route::get('/membership', ActionsMembershipIndexAction::class)->name('membership.index'); // ----------------------------------- group ---------------------------------- Route::get('/group', GroupIndexAction::class)->name('group.index'); diff --git a/tests/EndToEnd/MassstoreActionTest.php b/tests/EndToEnd/MassstoreActionTest.php index aac486f3..3066327d 100644 --- a/tests/EndToEnd/MassstoreActionTest.php +++ b/tests/EndToEnd/MassstoreActionTest.php @@ -63,7 +63,7 @@ it('cannot create membership when activity and subactivity doesnt belong togethe ])->assertJsonValidationErrors(['activity_id' => 'Tätigkeit ist nicht vorhanden.']); }); -it('testItDeletesAMembership', function() { +it('deletes a membership', function() { MembershipDestroyAction::partialMock()->shouldReceive('handle')->once(); MembershipStoreAction::partialMock()->shouldReceive('handle')->never(); ResyncAction::partialMock()->shouldReceive('handle')->once(); @@ -73,7 +73,7 @@ it('testItDeletesAMembership', function() { MassStoreAction::run($member->memberships->first()->group, $member->memberships->first()->activity, $member->memberships->first()->subactivity, []); }); -it('testItRollsbackWhenDeletionFails', function() { +it('rolls back when deletion fails', function() { app(MembershipFake::class) ->shows(3, ['id' => 55]) ->shows(3, ['id' => 56]) diff --git a/tests/Feature/Membership/ManageTest.php b/tests/Feature/Membership/ManageTest.php new file mode 100644 index 00000000..791d9913 --- /dev/null +++ b/tests/Feature/Membership/ManageTest.php @@ -0,0 +1,49 @@ +login()->loginNami()->withoutExceptionHandling(); + $activity = Activity::factory() + ->hasAttached(Subactivity::factory()->name('SubAct')) + ->name('Act') + ->create(); + $group = Group::factory()->name('GG')->create(); + $member = Member::factory()->defaults() + ->for($group) + ->has(Membership::factory()->for($activity)->for($activity->subactivities->first())->for($group)) + ->male() + ->name('Max Muster') + ->create(); + + $activity->subactivities()->first(); + $this->callFilter('membership.index', []) + ->assertInertia(fn(Assert $page) => $page + ->has('data.0', fn(Assert $page) => $page + ->where('activity.name', 'Act') + ->where('subactivity.name', 'SubAct') + ->where('group.name', 'GG') + ->where('promisedAt', null) + ->where('links.update', route('membership.update', $member->memberships->first())) + ->where('links.destroy', route('membership.destroy', $member->memberships->first())) + ->etc() + )->has('meta', fn (Assert $page) => $page + ->where('current_page', 1) + ->etc() + ) + ); +}); +