mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-app.git
synced 2026-06-20 05:30:30 +00:00
✅ Update MeetupController to use pivot memberships for "My Meetups" in both listing and detail views
- ✏️ Adjust `mine` method to fetch meetups based on dashboard selections (`meetup_user` pivot). - ✏️ Add `viewMine` policy to control access to individual meetups for pivot members. - 🧪 Update feature tests to reflect pivot-based logic for "My Meetups."
This commit is contained in:
@@ -106,14 +106,15 @@ class MeetupController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Eigene Meetups auflisten
|
* Eigene Meetups auflisten
|
||||||
*
|
*
|
||||||
* Liefert alle vom authentifizierten Nutzer erstellten Meetups, alphabetisch sortiert.
|
* Liefert die im Dashboard ausgewählten Meetups des authentifizierten Nutzers
|
||||||
|
* (meetup_user-Pivot, „Meine Meetups"), alphabetisch sortiert.
|
||||||
*/
|
*/
|
||||||
public function mine(Request $request): AnonymousResourceCollection
|
public function mine(Request $request): AnonymousResourceCollection
|
||||||
{
|
{
|
||||||
Gate::authorize('viewAny', Meetup::class);
|
Gate::authorize('viewAny', Meetup::class);
|
||||||
|
|
||||||
$meetups = Meetup::query()
|
$meetups = $request->user()
|
||||||
->where('created_by', $request->user()->id)
|
->meetups()
|
||||||
->orderBy('name')
|
->orderBy('name')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
@@ -123,12 +124,12 @@ class MeetupController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Eigenes Meetup anzeigen
|
* Eigenes Meetup anzeigen
|
||||||
*
|
*
|
||||||
* Zeigt ein einzelnes, vom authentifizierten Nutzer erstelltes Meetup.
|
* Zeigt ein einzelnes der im Dashboard ausgewählten Meetups (meetup_user-Pivot).
|
||||||
*/
|
*/
|
||||||
#[Response(status: 403, description: 'Nur der Ersteller oder ein Super-Admin darf das Meetup sehen.')]
|
#[Response(status: 403, description: 'Nur der Ersteller oder ein Mitglied (meetup_user-Pivot) darf das Meetup sehen.')]
|
||||||
public function mineShow(Meetup $meetup): MeetupResource
|
public function mineShow(Meetup $meetup): MeetupResource
|
||||||
{
|
{
|
||||||
Gate::authorize('view', $meetup);
|
Gate::authorize('viewMine', $meetup);
|
||||||
|
|
||||||
return MeetupResource::make($meetup);
|
return MeetupResource::make($meetup);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,17 @@ class MeetupPolicy
|
|||||||
return $this->owns($user, $meetup);
|
return $this->owns($user, $meetup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sichtbarkeit der „Meine Meetups"-Detailansicht: Neben dem Ersteller darf
|
||||||
|
* jedes Mitglied der meetup_user-Pivot („Meine Meetups" im Dashboard) das
|
||||||
|
* abonnierte Meetup über die REST-API ansehen. Spiegelt die Listen-Semantik
|
||||||
|
* von MeetupController::mine(), die ebenfalls die Pivot-Mitgliedschaft nutzt.
|
||||||
|
*/
|
||||||
|
public function viewMine(User $user, Meetup $meetup): bool
|
||||||
|
{
|
||||||
|
return $this->owns($user, $meetup) || $meetup->hasMember($user);
|
||||||
|
}
|
||||||
|
|
||||||
public function create(User $user): bool
|
public function create(User $user): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -70,23 +70,36 @@ it('forbids updating as a pivot member who is not the creator', function () {
|
|||||||
])->assertForbidden();
|
])->assertForbidden();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns only own in mine index', function () {
|
it('returns the dashboard-selected meetups in mine index', function () {
|
||||||
Sanctum::actingAs($user = User::factory()->create());
|
Sanctum::actingAs($user = User::factory()->create());
|
||||||
$other = User::factory()->create();
|
|
||||||
|
|
||||||
Meetup::factory()->count(2)->create(['created_by' => $user->id]);
|
$selected = Meetup::factory()->count(2)->create();
|
||||||
Meetup::factory()->create(['created_by' => $other->id]);
|
$unselected = Meetup::factory()->create();
|
||||||
|
|
||||||
|
$user->meetups()->attach($selected);
|
||||||
|
|
||||||
$response = $this->getJson('/api/my-meetups');
|
$response = $this->getJson('/api/my-meetups');
|
||||||
|
|
||||||
$response->assertSuccessful();
|
$response->assertSuccessful();
|
||||||
expect($response->json('data'))->toHaveCount(2);
|
expect($response->json('data'))->toHaveCount(2);
|
||||||
collect($response->json('data'))->each(
|
|
||||||
fn ($meetup) => expect($meetup['created_by'])->toBe($user->id)
|
$ids = collect($response->json('data'))->pluck('id')->all();
|
||||||
);
|
expect($ids)
|
||||||
|
->toContain(...$selected->pluck('id')->all())
|
||||||
|
->not->toContain($unselected->id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('forbids viewing someone elses in mine show', function () {
|
it('lets a pivot member view in mine show', function () {
|
||||||
|
Sanctum::actingAs($user = User::factory()->create());
|
||||||
|
$meetup = Meetup::factory()->create();
|
||||||
|
$user->meetups()->attach($meetup);
|
||||||
|
|
||||||
|
$this->getJson('/api/my-meetups/'.$meetup->id)
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertJsonPath('data.id', $meetup->id);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('forbids viewing a meetup the user has not selected in mine show', function () {
|
||||||
$owner = User::factory()->create();
|
$owner = User::factory()->create();
|
||||||
$meetup = Meetup::factory()->create(['created_by' => $owner->id]);
|
$meetup = Meetup::factory()->create(['created_by' => $owner->id]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user