From 7932e53daf94ec3486d0638a3863fe7dc5220749 Mon Sep 17 00:00:00 2001 From: "bert.hausmans" Date: Tue, 14 Apr 2026 08:16:36 +0200 Subject: [PATCH] =?UTF-8?q?security:=20A01-13=20=E2=80=94=20nest=20all=20e?= =?UTF-8?q?vent=20routes=20under=20organisation=20prefix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move all authenticated organiser-facing event sub-resource routes from /events/{event}/... to /organisations/{organisation}/events/{event}/... to enforce multi-tenancy at the routing layer. Changes: - Routes: restructured api.php to nest all event sub-resources under the existing organisation prefix group - Controllers: added Organisation parameter and VerifiesOrganisationEvent trait to all 12 affected controllers (sections, time-slots, shifts, persons, crowd-lists, locations, shift-assignments, registration-fields, availabilities, field-values, section-preferences, stats) - Tests: updated all 20 feature test files with new route paths - Frontend: updated 8 API composables and 20 Vue components/pages - API.md: updated documentation to reflect new route structure Portal routes, public routes (volunteer-register), and invitation routes remain unchanged as they operate without organisation context. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Api/V1/CrowdListController.php | 25 +++- .../Controllers/Api/V1/EventController.php | 7 +- .../Api/V1/FestivalSectionController.php | 27 ++-- .../Controllers/Api/V1/LocationController.php | 16 ++- .../Controllers/Api/V1/PersonController.php | 25 +++- .../Api/V1/PersonFieldValueController.php | 10 +- .../V1/PersonSectionPreferenceController.php | 10 +- .../V1/RegistrationFormFieldController.php | 23 +++- .../Api/V1/ShiftAssignmentController.php | 22 ++- .../Controllers/Api/V1/ShiftController.php | 22 ++- .../Controllers/Api/V1/TimeSlotController.php | 16 ++- .../V1/Traits/VerifiesOrganisationEvent.php | 20 +++ .../V1/VolunteerAvailabilityController.php | 10 +- api/routes/api.php | 118 ++++++++-------- .../Feature/Api/V1/AssignablePersonsTest.php | 52 ++++---- .../Api/V1/PersonApprovalEmailTest.php | 10 +- .../Api/V1/RegistrationSettingsTest.php | 14 +- .../Api/V1/ShiftAssignmentWorkflowTest.php | 62 ++++----- api/tests/Feature/CrowdList/CrowdListTest.php | 42 +++--- api/tests/Feature/Event/EventStatsTest.php | 10 +- api/tests/Feature/Event/FestivalEventTest.php | 38 +++--- .../FestivalSection/FestivalSectionTest.php | 22 +-- api/tests/Feature/Location/LocationTest.php | 30 ++--- api/tests/Feature/Person/PersonTest.php | 18 +-- .../PersonFieldValue/PersonFieldValueTest.php | 28 ++-- .../PersonIdentityMatchTest.php | 8 +- .../PersonSectionPreferenceTest.php | 24 ++-- .../PersonTag/UserOrganisationTagTest.php | 8 +- .../RegistrationFieldTemplateTest.php | 2 +- .../RegistrationFormFieldTest.php | 34 ++--- .../Security/InputValidationSecurityTest.php | 24 ++-- .../Security/MultiTenancyIsolationTest.php | 28 ++-- api/tests/Feature/Shift/ShiftTest.php | 28 ++-- api/tests/Feature/TimeSlot/TimeSlotTest.php | 22 +-- .../AddPersonToCrowdListDialog.vue | 6 +- .../crowd-lists/CrowdListDetailPanel.vue | 9 +- .../crowd-lists/CrowdListFormDialog.vue | 4 +- .../event/ImportFromEventDialog.vue | 2 +- .../components/event/TemplatePickerDialog.vue | 2 +- .../components/events/EventMetricCards.vue | 5 +- .../components/persons/CreatePersonDialog.vue | 2 +- .../components/persons/EditPersonDialog.vue | 2 +- .../components/persons/PersonDetailPanel.vue | 5 +- .../components/sections/AssignShiftDialog.vue | 7 +- .../sections/CreateSectionDialog.vue | 2 +- .../components/sections/CreateShiftDialog.vue | 9 +- .../sections/CreateTimeSlotDialog.vue | 7 +- .../components/sections/EditSectionDialog.vue | 2 +- .../sections/SectionsShiftsPanel.vue | 13 +- .../components/shifts/AssignPersonDialog.vue | 7 +- .../components/shifts/ShiftDetailPanel.vue | 15 ++- apps/app/src/composables/api/useCrowdLists.ts | 34 ++--- apps/app/src/composables/api/useEvents.ts | 6 +- apps/app/src/composables/api/usePersons.ts | 27 ++-- .../api/useRegistrationFormFields.ts | 30 ++--- apps/app/src/composables/api/useSections.ts | 22 +-- .../composables/api/useShiftAssignments.ts | 31 ++--- apps/app/src/composables/api/useShifts.ts | 22 +-- apps/app/src/composables/api/useTimeSlots.ts | 18 +-- .../pages/events/[id]/crowd-lists/index.vue | 4 +- .../src/pages/events/[id]/persons/index.vue | 6 +- .../[id]/settings/registration-fields.vue | 10 +- .../pages/events/[id]/time-slots/index.vue | 4 +- dev-docs/API.md | 126 +++++++++--------- 64 files changed, 726 insertions(+), 568 deletions(-) create mode 100644 api/app/Http/Controllers/Api/V1/Traits/VerifiesOrganisationEvent.php diff --git a/api/app/Http/Controllers/Api/V1/CrowdListController.php b/api/app/Http/Controllers/Api/V1/CrowdListController.php index 5f9a8113..223bdb63 100644 --- a/api/app/Http/Controllers/Api/V1/CrowdListController.php +++ b/api/app/Http/Controllers/Api/V1/CrowdListController.php @@ -5,12 +5,14 @@ declare(strict_types=1); namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\AddPersonToCrowdListRequest; use App\Http\Requests\Api\V1\StoreCrowdListRequest; use App\Http\Requests\Api\V1\UpdateCrowdListRequest; use App\Http\Resources\Api\V1\CrowdListResource; use App\Models\CrowdList; use App\Models\Event; +use App\Models\Organisation; use App\Models\Person; use App\Services\CrowdListService; use App\Http\Resources\Api\V1\PersonResource; @@ -20,12 +22,15 @@ use Illuminate\Support\Facades\Gate; final class CrowdListController extends Controller { + use VerifiesOrganisationEvent; + public function __construct( private readonly CrowdListService $crowdListService, ) {} - public function index(Event $event): AnonymousResourceCollection + public function index(Organisation $organisation, Event $event): AnonymousResourceCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewAny', [CrowdList::class, $event]); $crowdLists = $event->crowdLists() @@ -36,8 +41,9 @@ final class CrowdListController extends Controller return CrowdListResource::collection($crowdLists); } - public function store(StoreCrowdListRequest $request, Event $event): JsonResponse + public function store(StoreCrowdListRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('create', [CrowdList::class, $event]); $crowdList = $this->crowdListService->create($event, $request->validated(), $request->user()); @@ -45,8 +51,9 @@ final class CrowdListController extends Controller return $this->created(new CrowdListResource($crowdList->loadCount('persons'))); } - public function update(UpdateCrowdListRequest $request, Event $event, CrowdList $crowdList): JsonResponse + public function update(UpdateCrowdListRequest $request, Organisation $organisation, Event $event, CrowdList $crowdList): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$crowdList, $event]); $crowdList = $this->crowdListService->update($crowdList, $request->validated(), $request->user()); @@ -54,8 +61,9 @@ final class CrowdListController extends Controller return $this->success(new CrowdListResource($crowdList->loadCount('persons'))); } - public function destroy(Event $event, CrowdList $crowdList): JsonResponse + public function destroy(Organisation $organisation, Event $event, CrowdList $crowdList): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('delete', [$crowdList, $event]); $this->crowdListService->delete($crowdList, request()->user()); @@ -63,8 +71,9 @@ final class CrowdListController extends Controller return response()->json(null, 204); } - public function persons(Event $event, CrowdList $crowdList): AnonymousResourceCollection + public function persons(Organisation $organisation, Event $event, CrowdList $crowdList): AnonymousResourceCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewPersons', [$crowdList, $event]); $persons = $crowdList->persons() @@ -74,8 +83,9 @@ final class CrowdListController extends Controller return PersonResource::collection($persons); } - public function addPerson(AddPersonToCrowdListRequest $request, Event $event, CrowdList $crowdList): JsonResponse + public function addPerson(AddPersonToCrowdListRequest $request, Organisation $organisation, Event $event, CrowdList $crowdList): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('managePerson', [$crowdList, $event]); $festivalEventId = $event->parent_event_id ?? $event->id; @@ -86,8 +96,9 @@ final class CrowdListController extends Controller return $this->success(new CrowdListResource($crowdList->fresh()->loadCount('persons'))); } - public function removePerson(Event $event, CrowdList $crowdList, Person $person): JsonResponse + public function removePerson(Organisation $organisation, Event $event, CrowdList $crowdList, Person $person): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('managePerson', [$crowdList, $event]); $this->crowdListService->removePerson($crowdList, $person, request()->user()); diff --git a/api/app/Http/Controllers/Api/V1/EventController.php b/api/app/Http/Controllers/Api/V1/EventController.php index 6ff9e349..b81222cd 100644 --- a/api/app/Http/Controllers/Api/V1/EventController.php +++ b/api/app/Http/Controllers/Api/V1/EventController.php @@ -146,9 +146,12 @@ final class EventController extends Controller return response()->json(['url' => $event->fresh()->{$field}]); } - public function stats(Event $event): JsonResponse + public function stats(Organisation $organisation, Event $event): JsonResponse { - Gate::authorize('view', $event); + if ($event->organisation_id !== $organisation->id) { + abort(404); + } + Gate::authorize('view', [$event, $organisation]); $personCounts = $event->persons() ->selectRaw(" diff --git a/api/app/Http/Controllers/Api/V1/FestivalSectionController.php b/api/app/Http/Controllers/Api/V1/FestivalSectionController.php index 300cdf28..b95240a6 100644 --- a/api/app/Http/Controllers/Api/V1/FestivalSectionController.php +++ b/api/app/Http/Controllers/Api/V1/FestivalSectionController.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\ReorderFestivalSectionsRequest; use App\Http\Requests\Api\V1\StoreFestivalSectionRequest; use App\Http\Requests\Api\V1\UpdateFestivalSectionRequest; @@ -12,14 +13,18 @@ use App\Http\Requests\Api\V1\UpdateRegistrationSettingsRequest; use App\Http\Resources\Api\V1\FestivalSectionResource; use App\Models\Event; use App\Models\FestivalSection; +use App\Models\Organisation; use Illuminate\Http\JsonResponse; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; use Illuminate\Support\Facades\Gate; final class FestivalSectionController extends Controller { - public function index(Event $event): AnonymousResourceCollection + use VerifiesOrganisationEvent; + + public function index(Organisation $organisation, Event $event): AnonymousResourceCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewAny', [FestivalSection::class, $event]); $sections = $event->festivalSections()->ordered()->get(); @@ -38,8 +43,9 @@ final class FestivalSectionController extends Controller return FestivalSectionResource::collection($sections); } - public function store(StoreFestivalSectionRequest $request, Event $event): JsonResponse + public function store(StoreFestivalSectionRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('create', [FestivalSection::class, $event]); $data = $request->validated(); @@ -77,8 +83,9 @@ final class FestivalSectionController extends Controller return $response; } - public function update(UpdateFestivalSectionRequest $request, Event $event, FestivalSection $section): JsonResponse + public function update(UpdateFestivalSectionRequest $request, Organisation $organisation, Event $event, FestivalSection $section): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$section, $event]); $section->update($request->validated()); @@ -86,8 +93,9 @@ final class FestivalSectionController extends Controller return $this->success(new FestivalSectionResource($section->fresh())); } - public function destroy(Event $event, FestivalSection $section): JsonResponse + public function destroy(Organisation $organisation, Event $event, FestivalSection $section): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('delete', [$section, $event]); $section->delete(); @@ -95,8 +103,9 @@ final class FestivalSectionController extends Controller return response()->json(null, 204); } - public function registrationSettings(Event $event): JsonResponse + public function registrationSettings(Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewAny', [FestivalSection::class, $event]); $sections = $this->getFestivalSections($event); @@ -118,8 +127,9 @@ final class FestivalSectionController extends Controller return response()->json(['data' => $grouped]); } - public function updateRegistrationSettings(UpdateRegistrationSettingsRequest $request, Event $event): JsonResponse + public function updateRegistrationSettings(UpdateRegistrationSettingsRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('create', [FestivalSection::class, $event]); $validated = $request->validated(); @@ -148,7 +158,7 @@ final class FestivalSectionController extends Controller ->log('section.registration_settings_updated'); // Return updated settings - return $this->registrationSettings($event); + return $this->registrationSettings($organisation, $event); } /** @@ -171,8 +181,9 @@ final class FestivalSectionController extends Controller return FestivalSection::whereIn('event_id', $eventIds)->ordered()->get(); } - public function reorder(ReorderFestivalSectionsRequest $request, Event $event): JsonResponse + public function reorder(ReorderFestivalSectionsRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('reorder', [FestivalSection::class, $event]); foreach ($request->validated('sections') as $index => $id) { diff --git a/api/app/Http/Controllers/Api/V1/LocationController.php b/api/app/Http/Controllers/Api/V1/LocationController.php index 45a506b6..61abb844 100644 --- a/api/app/Http/Controllers/Api/V1/LocationController.php +++ b/api/app/Http/Controllers/Api/V1/LocationController.php @@ -5,19 +5,24 @@ declare(strict_types=1); namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\StoreLocationRequest; use App\Http\Requests\Api\V1\UpdateLocationRequest; use App\Http\Resources\Api\V1\LocationResource; use App\Models\Event; use App\Models\Location; +use App\Models\Organisation; use Illuminate\Http\JsonResponse; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; use Illuminate\Support\Facades\Gate; final class LocationController extends Controller { - public function index(Event $event): AnonymousResourceCollection + use VerifiesOrganisationEvent; + + public function index(Organisation $organisation, Event $event): AnonymousResourceCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewAny', [Location::class, $event]); $locations = $event->locations()->orderBy('name')->get(); @@ -25,8 +30,9 @@ final class LocationController extends Controller return LocationResource::collection($locations); } - public function store(StoreLocationRequest $request, Event $event): JsonResponse + public function store(StoreLocationRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('create', [Location::class, $event]); $location = $event->locations()->create($request->validated()); @@ -34,8 +40,9 @@ final class LocationController extends Controller return $this->created(new LocationResource($location)); } - public function update(UpdateLocationRequest $request, Event $event, Location $location): JsonResponse + public function update(UpdateLocationRequest $request, Organisation $organisation, Event $event, Location $location): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$location, $event]); $location->update($request->validated()); @@ -43,8 +50,9 @@ final class LocationController extends Controller return $this->success(new LocationResource($location->fresh())); } - public function destroy(Event $event, Location $location): JsonResponse + public function destroy(Organisation $organisation, Event $event, Location $location): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('delete', [$location, $event]); $location->delete(); diff --git a/api/app/Http/Controllers/Api/V1/PersonController.php b/api/app/Http/Controllers/Api/V1/PersonController.php index 8fe617b2..393b09f0 100644 --- a/api/app/Http/Controllers/Api/V1/PersonController.php +++ b/api/app/Http/Controllers/Api/V1/PersonController.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\StorePersonRequest; use App\Http\Requests\Api\V1\UpdatePersonRequest; use App\Http\Resources\Api\V1\PersonCollection; @@ -12,6 +13,7 @@ use App\Http\Resources\Api\V1\PersonResource; use App\Mail\RegistrationApprovedMail; use App\Mail\RegistrationRejectedMail; use App\Models\Event; +use App\Models\Organisation; use App\Models\Person; use App\Services\PersonIdentityService; use App\Services\TagSyncService; @@ -22,13 +24,16 @@ use Illuminate\Support\Facades\Mail; final class PersonController extends Controller { + use VerifiesOrganisationEvent; + public function __construct( private readonly PersonIdentityService $identityService, private readonly TagSyncService $tagSyncService, ) {} - public function index(Request $request, Event $event): PersonCollection + public function index(Request $request, Organisation $organisation, Event $event): PersonCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewAny', [Person::class, $event]); $query = $event->persons()->with(['crowdType', 'pendingIdentityMatch.matchedUser']); @@ -67,8 +72,9 @@ final class PersonController extends Controller return new PersonCollection($query->get()); } - public function show(Event $event, Person $person): JsonResponse + public function show(Organisation $organisation, Event $event, Person $person): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('view', [$person, $event]); $person->load(['crowdType', 'company', 'user']); @@ -76,8 +82,9 @@ final class PersonController extends Controller return $this->success(new PersonResource($person)); } - public function store(StorePersonRequest $request, Event $event): JsonResponse + public function store(StorePersonRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('create', [Person::class, $event]); $person = $event->persons()->create($request->validated()); @@ -87,8 +94,9 @@ final class PersonController extends Controller return $this->created(new PersonResource($person->fresh()->load('crowdType'))); } - public function update(UpdatePersonRequest $request, Event $event, Person $person): JsonResponse + public function update(UpdatePersonRequest $request, Organisation $organisation, Event $event, Person $person): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$person, $event]); $person->update($request->validated()); @@ -97,8 +105,9 @@ final class PersonController extends Controller return $this->success(new PersonResource($person->fresh()->load(['crowdType', 'company']))); } - public function destroy(Event $event, Person $person): JsonResponse + public function destroy(Organisation $organisation, Event $event, Person $person): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('delete', [$person, $event]); $person->delete(); @@ -106,8 +115,9 @@ final class PersonController extends Controller return response()->json(null, 204); } - public function approve(Event $event, Person $person): JsonResponse + public function approve(Organisation $organisation, Event $event, Person $person): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('approve', [$person, $event]); $person->update(['status' => 'approved']); @@ -121,8 +131,9 @@ final class PersonController extends Controller return $this->success(new PersonResource($person->fresh()->load('crowdType'))); } - public function reject(Request $request, Event $event, Person $person): JsonResponse + public function reject(Request $request, Organisation $organisation, Event $event, Person $person): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('approve', [$person, $event]); $person->update(['status' => 'rejected']); diff --git a/api/app/Http/Controllers/Api/V1/PersonFieldValueController.php b/api/app/Http/Controllers/Api/V1/PersonFieldValueController.php index a285849d..7f340036 100644 --- a/api/app/Http/Controllers/Api/V1/PersonFieldValueController.php +++ b/api/app/Http/Controllers/Api/V1/PersonFieldValueController.php @@ -5,9 +5,11 @@ declare(strict_types=1); namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\UpsertPersonFieldValuesRequest; use App\Http\Resources\Api\V1\PersonFieldValueResource; use App\Models\Event; +use App\Models\Organisation; use App\Models\Person; use App\Services\RegistrationFormFieldService; use Illuminate\Http\JsonResponse; @@ -16,12 +18,15 @@ use Illuminate\Support\Facades\Gate; final class PersonFieldValueController extends Controller { + use VerifiesOrganisationEvent; + public function __construct( private readonly RegistrationFormFieldService $service, ) {} - public function index(Event $event, Person $person): AnonymousResourceCollection + public function index(Organisation $organisation, Event $event, Person $person): AnonymousResourceCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('view', [$person, $event]); $values = $this->service->getPersonValues($person); @@ -29,8 +34,9 @@ final class PersonFieldValueController extends Controller return PersonFieldValueResource::collection($values); } - public function upsert(UpsertPersonFieldValuesRequest $request, Event $event, Person $person): JsonResponse + public function upsert(UpsertPersonFieldValuesRequest $request, Organisation $organisation, Event $event, Person $person): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$person, $event]); $this->service->upsertPersonValues($person, $request->validated()['values']); diff --git a/api/app/Http/Controllers/Api/V1/PersonSectionPreferenceController.php b/api/app/Http/Controllers/Api/V1/PersonSectionPreferenceController.php index 478557e6..ac317142 100644 --- a/api/app/Http/Controllers/Api/V1/PersonSectionPreferenceController.php +++ b/api/app/Http/Controllers/Api/V1/PersonSectionPreferenceController.php @@ -5,9 +5,11 @@ declare(strict_types=1); namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\ReplacePersonSectionPreferencesRequest; use App\Http\Resources\Api\V1\PersonSectionPreferenceResource; use App\Models\Event; +use App\Models\Organisation; use App\Models\Person; use App\Services\PersonSectionPreferenceService; use Illuminate\Http\JsonResponse; @@ -16,12 +18,15 @@ use Illuminate\Support\Facades\Gate; final class PersonSectionPreferenceController extends Controller { + use VerifiesOrganisationEvent; + public function __construct( private readonly PersonSectionPreferenceService $service, ) {} - public function index(Event $event, Person $person): AnonymousResourceCollection + public function index(Organisation $organisation, Event $event, Person $person): AnonymousResourceCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('view', [$person, $event]); $preferences = $this->service->getPreferences($person); @@ -29,8 +34,9 @@ final class PersonSectionPreferenceController extends Controller return PersonSectionPreferenceResource::collection($preferences); } - public function replace(ReplacePersonSectionPreferencesRequest $request, Event $event, Person $person): JsonResponse + public function replace(ReplacePersonSectionPreferencesRequest $request, Organisation $organisation, Event $event, Person $person): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$person, $event]); $this->service->replacePreferences($person, $request->validated()['preferences']); diff --git a/api/app/Http/Controllers/Api/V1/RegistrationFormFieldController.php b/api/app/Http/Controllers/Api/V1/RegistrationFormFieldController.php index ac57d7dc..1cb9514c 100644 --- a/api/app/Http/Controllers/Api/V1/RegistrationFormFieldController.php +++ b/api/app/Http/Controllers/Api/V1/RegistrationFormFieldController.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\ImportFromEventRequest; use App\Http\Requests\Api\V1\ReorderRegistrationFormFieldsRequest; use App\Http\Requests\Api\V1\StoreRegistrationFormFieldRequest; @@ -23,13 +24,16 @@ use Illuminate\Support\Facades\Gate; final class RegistrationFormFieldController extends Controller { + use VerifiesOrganisationEvent; + public function __construct( private readonly RegistrationFormFieldService $service, private readonly RegistrationFieldTemplateService $templateService, ) {} - public function index(Event $event): AnonymousResourceCollection + public function index(Organisation $organisation, Event $event): AnonymousResourceCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewAny', [RegistrationFormField::class, $event]); $fields = $this->service->listForEvent($event); @@ -37,8 +41,9 @@ final class RegistrationFormFieldController extends Controller return RegistrationFormFieldResource::collection($fields); } - public function store(StoreRegistrationFormFieldRequest $request, Event $event): JsonResponse + public function store(StoreRegistrationFormFieldRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('create', [RegistrationFormField::class, $event]); $field = $this->service->createField($event, $request->validated()); @@ -48,9 +53,11 @@ final class RegistrationFormFieldController extends Controller public function update( UpdateRegistrationFormFieldRequest $request, + Organisation $organisation, Event $event, RegistrationFormField $registrationField, ): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$registrationField, $event]); $field = $this->service->updateField($registrationField, $request->validated()); @@ -58,8 +65,9 @@ final class RegistrationFormFieldController extends Controller return $this->success(new RegistrationFormFieldResource($field)); } - public function destroy(Event $event, RegistrationFormField $registrationField): JsonResponse + public function destroy(Organisation $organisation, Event $event, RegistrationFormField $registrationField): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('delete', [$registrationField, $event]); $this->service->deleteField($registrationField); @@ -67,8 +75,9 @@ final class RegistrationFormFieldController extends Controller return response()->json(null, 204); } - public function reorder(ReorderRegistrationFormFieldsRequest $request, Event $event): JsonResponse + public function reorder(ReorderRegistrationFormFieldsRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('reorder', [RegistrationFormField::class, $event]); $this->service->reorderFields($event, $request->validated()['ids']); @@ -76,8 +85,9 @@ final class RegistrationFormFieldController extends Controller return response()->json(null, 204); } - public function fromTemplate(Request $request, Event $event): JsonResponse + public function fromTemplate(Request $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('create', [RegistrationFormField::class, $event]); $request->validate([ @@ -95,8 +105,9 @@ final class RegistrationFormFieldController extends Controller return $this->created(new RegistrationFormFieldResource($field)); } - public function importFromEvent(ImportFromEventRequest $request, Event $event): JsonResponse + public function importFromEvent(ImportFromEventRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('create', [RegistrationFormField::class, $event]); $sourceEvent = Event::findOrFail($request->validated()['source_event_id']); diff --git a/api/app/Http/Controllers/Api/V1/ShiftAssignmentController.php b/api/app/Http/Controllers/Api/V1/ShiftAssignmentController.php index 2cb8a855..f512f337 100644 --- a/api/app/Http/Controllers/Api/V1/ShiftAssignmentController.php +++ b/api/app/Http/Controllers/Api/V1/ShiftAssignmentController.php @@ -7,10 +7,12 @@ namespace App\Http\Controllers\Api\V1; use App\Enums\PersonStatus; use App\Enums\ShiftAssignmentStatus; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\BulkApproveShiftAssignmentRequest; use App\Http\Requests\Api\V1\RejectShiftAssignmentRequest; use App\Http\Resources\Api\V1\ShiftAssignmentResource; use App\Models\Event; +use App\Models\Organisation; use App\Models\Person; use App\Models\Shift; use App\Models\ShiftAssignment; @@ -24,12 +26,15 @@ use Illuminate\Support\Facades\Gate; final class ShiftAssignmentController extends Controller { + use VerifiesOrganisationEvent; + public function __construct( private readonly ShiftAssignmentService $service, ) {} - public function index(Request $request, Event $event): AnonymousResourceCollection + public function index(Request $request, Organisation $organisation, Event $event): AnonymousResourceCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewAny', [ShiftAssignment::class, $event]); $query = ShiftAssignment::query() @@ -60,8 +65,9 @@ final class ShiftAssignmentController extends Controller return ShiftAssignmentResource::collection($assignments); } - public function approve(Event $event, ShiftAssignment $shiftAssignment): JsonResponse + public function approve(Organisation $organisation, Event $event, ShiftAssignment $shiftAssignment): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('approve', [$shiftAssignment, $event]); $shiftAssignment = $this->service->approve($shiftAssignment, request()->user()); @@ -69,8 +75,9 @@ final class ShiftAssignmentController extends Controller return $this->success(new ShiftAssignmentResource($shiftAssignment->load(['person', 'shift.festivalSection', 'shift.timeSlot']))); } - public function reject(RejectShiftAssignmentRequest $request, Event $event, ShiftAssignment $shiftAssignment): JsonResponse + public function reject(RejectShiftAssignmentRequest $request, Organisation $organisation, Event $event, ShiftAssignment $shiftAssignment): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('reject', [$shiftAssignment, $event]); $shiftAssignment = $this->service->reject( @@ -82,8 +89,9 @@ final class ShiftAssignmentController extends Controller return $this->success(new ShiftAssignmentResource($shiftAssignment->load(['person', 'shift.festivalSection', 'shift.timeSlot']))); } - public function cancel(Event $event, ShiftAssignment $shiftAssignment): JsonResponse + public function cancel(Organisation $organisation, Event $event, ShiftAssignment $shiftAssignment): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('cancel', [$shiftAssignment, $event]); $shiftAssignment = $this->service->cancel($shiftAssignment, request()->user()); @@ -91,8 +99,9 @@ final class ShiftAssignmentController extends Controller return $this->success(new ShiftAssignmentResource($shiftAssignment->load(['person', 'shift.festivalSection', 'shift.timeSlot']))); } - public function bulkApprove(BulkApproveShiftAssignmentRequest $request, Event $event): JsonResponse + public function bulkApprove(BulkApproveShiftAssignmentRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('bulkApprove', [ShiftAssignment::class, $event]); $assignments = ShiftAssignment::whereIn('id', $request->validated('assignment_ids')) @@ -105,8 +114,9 @@ final class ShiftAssignmentController extends Controller return $this->success($results); } - public function assignablePersons(Event $event, Shift $shift): JsonResponse + public function assignablePersons(Organisation $organisation, Event $event, Shift $shift): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewAny', [ShiftAssignment::class, $event]); $shift->load(['festivalSection', 'timeSlot']); diff --git a/api/app/Http/Controllers/Api/V1/ShiftController.php b/api/app/Http/Controllers/Api/V1/ShiftController.php index c4663d87..3633fd5a 100644 --- a/api/app/Http/Controllers/Api/V1/ShiftController.php +++ b/api/app/Http/Controllers/Api/V1/ShiftController.php @@ -6,6 +6,7 @@ namespace App\Http\Controllers\Api\V1; use App\Enums\ShiftAssignmentStatus; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\AssignShiftRequest; use App\Http\Requests\Api\V1\StoreShiftRequest; use App\Http\Requests\Api\V1\UpdateShiftRequest; @@ -13,6 +14,7 @@ use App\Http\Resources\Api\V1\ShiftAssignmentResource; use App\Http\Resources\Api\V1\ShiftResource; use App\Models\Event; use App\Models\FestivalSection; +use App\Models\Organisation; use App\Models\Person; use App\Models\Shift; use App\Services\ShiftAssignmentService; @@ -22,12 +24,15 @@ use Illuminate\Support\Facades\Gate; final class ShiftController extends Controller { + use VerifiesOrganisationEvent; + public function __construct( private readonly ShiftAssignmentService $shiftAssignmentService, ) {} - public function index(Event $event, FestivalSection $section): AnonymousResourceCollection + public function index(Organisation $organisation, Event $event, FestivalSection $section): AnonymousResourceCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewAny', [Shift::class, $event]); $shifts = $section->shifts() @@ -38,8 +43,9 @@ final class ShiftController extends Controller return ShiftResource::collection($shifts); } - public function store(StoreShiftRequest $request, Event $event, FestivalSection $section): JsonResponse + public function store(StoreShiftRequest $request, Organisation $organisation, Event $event, FestivalSection $section): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('create', [Shift::class, $event]); $shift = $section->shifts()->create($request->validated()); @@ -48,8 +54,9 @@ final class ShiftController extends Controller return $this->created(new ShiftResource($shift)); } - public function update(UpdateShiftRequest $request, Event $event, FestivalSection $section, Shift $shift): JsonResponse + public function update(UpdateShiftRequest $request, Organisation $organisation, Event $event, FestivalSection $section, Shift $shift): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$shift, $event, $section]); $shift->update($request->validated()); @@ -58,8 +65,9 @@ final class ShiftController extends Controller return $this->success(new ShiftResource($shift->fresh()->load(['timeSlot', 'location']))); } - public function destroy(Event $event, FestivalSection $section, Shift $shift): JsonResponse + public function destroy(Organisation $organisation, Event $event, FestivalSection $section, Shift $shift): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('delete', [$shift, $event, $section]); $shift->delete(); @@ -67,8 +75,9 @@ final class ShiftController extends Controller return response()->json(null, 204); } - public function assign(AssignShiftRequest $request, Event $event, FestivalSection $section, Shift $shift): JsonResponse + public function assign(AssignShiftRequest $request, Organisation $organisation, Event $event, FestivalSection $section, Shift $shift): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('assign', [$shift, $event, $section]); $festivalEventId = $event->parent_event_id ?? $event->id; @@ -78,8 +87,9 @@ final class ShiftController extends Controller return $this->created(new ShiftAssignmentResource($assignment)); } - public function claim(AssignShiftRequest $request, Event $event, FestivalSection $section, Shift $shift): JsonResponse + public function claim(AssignShiftRequest $request, Organisation $organisation, Event $event, FestivalSection $section, Shift $shift): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('claim', [$shift, $event, $section]); $festivalEventId = $event->parent_event_id ?? $event->id; diff --git a/api/app/Http/Controllers/Api/V1/TimeSlotController.php b/api/app/Http/Controllers/Api/V1/TimeSlotController.php index 209733a6..da9759a9 100644 --- a/api/app/Http/Controllers/Api/V1/TimeSlotController.php +++ b/api/app/Http/Controllers/Api/V1/TimeSlotController.php @@ -5,10 +5,12 @@ declare(strict_types=1); namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\StoreTimeSlotRequest; use App\Http\Requests\Api\V1\UpdateTimeSlotRequest; use App\Http\Resources\Api\V1\TimeSlotResource; use App\Models\Event; +use App\Models\Organisation; use App\Models\TimeSlot; use Illuminate\Http\JsonResponse; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; @@ -16,8 +18,11 @@ use Illuminate\Support\Facades\Gate; final class TimeSlotController extends Controller { - public function index(Event $event): AnonymousResourceCollection + use VerifiesOrganisationEvent; + + public function index(Organisation $organisation, Event $event): AnonymousResourceCollection { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('viewAny', [TimeSlot::class, $event]); $timeSlots = $event->timeSlots() @@ -54,8 +59,9 @@ final class TimeSlotController extends Controller return TimeSlotResource::collection($timeSlots); } - public function store(StoreTimeSlotRequest $request, Event $event): JsonResponse + public function store(StoreTimeSlotRequest $request, Organisation $organisation, Event $event): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('create', [TimeSlot::class, $event]); $timeSlot = $event->timeSlots()->create($request->validated()); @@ -63,8 +69,9 @@ final class TimeSlotController extends Controller return $this->created(new TimeSlotResource($timeSlot)); } - public function update(UpdateTimeSlotRequest $request, Event $event, TimeSlot $timeSlot): JsonResponse + public function update(UpdateTimeSlotRequest $request, Organisation $organisation, Event $event, TimeSlot $timeSlot): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$timeSlot, $event]); $timeSlot->update($request->validated()); @@ -72,8 +79,9 @@ final class TimeSlotController extends Controller return $this->success(new TimeSlotResource($timeSlot->fresh())); } - public function destroy(Event $event, TimeSlot $timeSlot): JsonResponse + public function destroy(Organisation $organisation, Event $event, TimeSlot $timeSlot): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('delete', [$timeSlot, $event]); $timeSlot->delete(); diff --git a/api/app/Http/Controllers/Api/V1/Traits/VerifiesOrganisationEvent.php b/api/app/Http/Controllers/Api/V1/Traits/VerifiesOrganisationEvent.php new file mode 100644 index 00000000..ea687ae0 --- /dev/null +++ b/api/app/Http/Controllers/Api/V1/Traits/VerifiesOrganisationEvent.php @@ -0,0 +1,20 @@ +organisation_id !== $organisation->id) { + abort(404); + } + } +} diff --git a/api/app/Http/Controllers/Api/V1/VolunteerAvailabilityController.php b/api/app/Http/Controllers/Api/V1/VolunteerAvailabilityController.php index 193e1db1..674f4054 100644 --- a/api/app/Http/Controllers/Api/V1/VolunteerAvailabilityController.php +++ b/api/app/Http/Controllers/Api/V1/VolunteerAvailabilityController.php @@ -5,8 +5,10 @@ declare(strict_types=1); namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; +use App\Http\Controllers\Api\V1\Traits\VerifiesOrganisationEvent; use App\Http\Requests\Api\V1\SyncVolunteerAvailabilityRequest; use App\Models\Event; +use App\Models\Organisation; use App\Models\Person; use App\Models\TimeSlot; use App\Models\VolunteerAvailability; @@ -16,8 +18,11 @@ use Illuminate\Validation\ValidationException; final class VolunteerAvailabilityController extends Controller { - public function index(Event $event, Person $person): JsonResponse + use VerifiesOrganisationEvent; + + public function index(Organisation $organisation, Event $event, Person $person): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('view', [$person, $event]); $availabilities = VolunteerAvailability::where('person_id', $person->id) @@ -43,8 +48,9 @@ final class VolunteerAvailabilityController extends Controller /** * @throws ValidationException */ - public function sync(SyncVolunteerAvailabilityRequest $request, Event $event, Person $person): JsonResponse + public function sync(SyncVolunteerAvailabilityRequest $request, Organisation $organisation, Event $event, Person $person): JsonResponse { + $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$person, $event]); $availabilities = $request->validated('availabilities'); diff --git a/api/routes/api.php b/api/routes/api.php index 9c0b55e8..3535b2d3 100644 --- a/api/routes/api.php +++ b/api/routes/api.php @@ -146,63 +146,73 @@ Route::middleware('auth:sanctum')->group(function () { Route::get('members', [MemberController::class, 'index']); Route::put('members/{user}', [MemberController::class, 'update']); Route::delete('members/{user}', [MemberController::class, 'destroy']); - }); - // Event-scoped resources - Route::get('events/{event}/stats', [EventController::class, 'stats']); - Route::prefix('events/{event}')->group(function () { - Route::apiResource('locations', LocationController::class) - ->except(['show']); - Route::get('sections/registration-settings', [FestivalSectionController::class, 'registrationSettings']); - Route::put('sections/registration-settings', [FestivalSectionController::class, 'updateRegistrationSettings']); - Route::apiResource('sections', FestivalSectionController::class) - ->except(['show']); - Route::post('sections/reorder', [FestivalSectionController::class, 'reorder']); - Route::apiResource('time-slots', TimeSlotController::class) - ->except(['show']); + // Event sub-resources (all nested under organisation prefix — A01-13) + Route::prefix('events/{event}')->group(function () { + // Stats + Route::get('stats', [EventController::class, 'stats']); - // Shifts nested under sections - Route::prefix('sections/{section}')->group(function () { - Route::apiResource('shifts', ShiftController::class) + // Locations + Route::apiResource('locations', LocationController::class) ->except(['show']); - Route::post('shifts/{shift}/assign', [ShiftController::class, 'assign']); - Route::post('shifts/{shift}/claim', [ShiftController::class, 'claim']); + + // Festival sections + Route::get('sections/registration-settings', [FestivalSectionController::class, 'registrationSettings']); + Route::put('sections/registration-settings', [FestivalSectionController::class, 'updateRegistrationSettings']); + Route::apiResource('sections', FestivalSectionController::class) + ->except(['show']); + Route::post('sections/reorder', [FestivalSectionController::class, 'reorder']); + + // Time slots + Route::apiResource('time-slots', TimeSlotController::class) + ->except(['show']); + + // Shifts nested under sections + Route::prefix('sections/{section}')->group(function () { + Route::apiResource('shifts', ShiftController::class) + ->except(['show']); + Route::post('shifts/{shift}/assign', [ShiftController::class, 'assign']); + Route::post('shifts/{shift}/claim', [ShiftController::class, 'claim']); + }); + + // Shift assignments (event-level) + Route::get('shift-assignments', [ShiftAssignmentController::class, 'index']); + Route::get('shifts/{shift}/assignable-persons', [ShiftAssignmentController::class, 'assignablePersons']); + Route::post('shift-assignments/{shiftAssignment}/approve', [ShiftAssignmentController::class, 'approve']); + Route::post('shift-assignments/{shiftAssignment}/reject', [ShiftAssignmentController::class, 'reject']); + Route::post('shift-assignments/{shiftAssignment}/cancel', [ShiftAssignmentController::class, 'cancel']); + Route::post('shift-assignments/bulk-approve', [ShiftAssignmentController::class, 'bulkApprove']); + + // Persons + Route::apiResource('persons', PersonController::class); + Route::post('persons/{person}/approve', [PersonController::class, 'approve']); + Route::post('persons/{person}/reject', [PersonController::class, 'reject']); + + // Volunteer availabilities + Route::get('persons/{person}/availabilities', [VolunteerAvailabilityController::class, 'index']); + Route::post('persons/{person}/availabilities/sync', [VolunteerAvailabilityController::class, 'sync']); + + // Person field values + Route::get('persons/{person}/field-values', [PersonFieldValueController::class, 'index']); + Route::put('persons/{person}/field-values', [PersonFieldValueController::class, 'upsert']); + + // Person section preferences + Route::get('persons/{person}/section-preferences', [PersonSectionPreferenceController::class, 'index']); + Route::put('persons/{person}/section-preferences', [PersonSectionPreferenceController::class, 'replace']); + + // Registration form fields (event settings) + Route::apiResource('registration-fields', RegistrationFormFieldController::class) + ->except(['show']); + Route::post('registration-fields/reorder', [RegistrationFormFieldController::class, 'reorder']); + Route::post('registration-fields/from-template', [RegistrationFormFieldController::class, 'fromTemplate']); + Route::post('registration-fields/import-from-event', [RegistrationFormFieldController::class, 'importFromEvent']); + + // Crowd lists + Route::apiResource('crowd-lists', CrowdListController::class) + ->except(['show']); + Route::get('crowd-lists/{crowdList}/persons', [CrowdListController::class, 'persons']); + Route::post('crowd-lists/{crowdList}/persons', [CrowdListController::class, 'addPerson']); + Route::delete('crowd-lists/{crowdList}/persons/{person}', [CrowdListController::class, 'removePerson']); }); - - // Shift assignments (event-level) - Route::get('shift-assignments', [ShiftAssignmentController::class, 'index']); - Route::get('shifts/{shift}/assignable-persons', [ShiftAssignmentController::class, 'assignablePersons']); - Route::post('shift-assignments/{shiftAssignment}/approve', [ShiftAssignmentController::class, 'approve']); - Route::post('shift-assignments/{shiftAssignment}/reject', [ShiftAssignmentController::class, 'reject']); - Route::post('shift-assignments/{shiftAssignment}/cancel', [ShiftAssignmentController::class, 'cancel']); - Route::post('shift-assignments/bulk-approve', [ShiftAssignmentController::class, 'bulkApprove']); - - Route::apiResource('persons', PersonController::class); - Route::post('persons/{person}/approve', [PersonController::class, 'approve']); - Route::post('persons/{person}/reject', [PersonController::class, 'reject']); - - // Volunteer availabilities - Route::get('persons/{person}/availabilities', [VolunteerAvailabilityController::class, 'index']); - Route::post('persons/{person}/availabilities/sync', [VolunteerAvailabilityController::class, 'sync']); - - // Person field values - Route::get('persons/{person}/field-values', [PersonFieldValueController::class, 'index']); - Route::put('persons/{person}/field-values', [PersonFieldValueController::class, 'upsert']); - - // Person section preferences - Route::get('persons/{person}/section-preferences', [PersonSectionPreferenceController::class, 'index']); - Route::put('persons/{person}/section-preferences', [PersonSectionPreferenceController::class, 'replace']); - - // Registration form fields (event settings) - Route::apiResource('registration-fields', RegistrationFormFieldController::class) - ->except(['show']); - Route::post('registration-fields/reorder', [RegistrationFormFieldController::class, 'reorder']); - Route::post('registration-fields/from-template', [RegistrationFormFieldController::class, 'fromTemplate']); - Route::post('registration-fields/import-from-event', [RegistrationFormFieldController::class, 'importFromEvent']); - Route::apiResource('crowd-lists', CrowdListController::class) - ->except(['show']); - Route::get('crowd-lists/{crowdList}/persons', [CrowdListController::class, 'persons']); - Route::post('crowd-lists/{crowdList}/persons', [CrowdListController::class, 'addPerson']); - Route::delete('crowd-lists/{crowdList}/persons/{person}', [CrowdListController::class, 'removePerson']); }); }); diff --git a/api/tests/Feature/Api/V1/AssignablePersonsTest.php b/api/tests/Feature/Api/V1/AssignablePersonsTest.php index de92ee7e..0905bacb 100644 --- a/api/tests/Feature/Api/V1/AssignablePersonsTest.php +++ b/api/tests/Feature/Api/V1/AssignablePersonsTest.php @@ -90,7 +90,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -118,7 +118,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift2->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift2->id}/assignable-persons", ); $response->assertOk() @@ -143,7 +143,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -163,7 +163,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -175,7 +175,7 @@ class AssignablePersonsTest extends TestCase $shift = $this->createOpenShift(); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertUnauthorized(); @@ -188,7 +188,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->outsider); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertForbidden(); @@ -212,7 +212,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift2->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift2->id}/assignable-persons", ); $response->assertOk() @@ -231,7 +231,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -259,7 +259,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->otherSection->id}/shifts/{$shift2->id}/assign", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->otherSection->id}/shifts/{$shift2->id}/assign", ['person_id' => $person->id], ); @@ -288,7 +288,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->otherSection->id}/shifts/{$shift2->id}/claim", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->otherSection->id}/shifts/{$shift2->id}/claim", ['person_id' => $person->id], ); @@ -316,7 +316,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/{$assignment->id}/cancel", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/{$assignment->id}/cancel", ); $response->assertOk() @@ -348,7 +348,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", ['person_id' => $person->id], ); @@ -379,7 +379,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", ['person_id' => $person->id], ); @@ -408,7 +408,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->otherSection->id}/shifts/{$shift2->id}/assign", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->otherSection->id}/shifts/{$shift2->id}/assign", ['person_id' => $person->id], ); @@ -436,7 +436,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -463,7 +463,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -486,7 +486,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -523,7 +523,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -542,7 +542,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -568,7 +568,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -590,7 +590,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -607,7 +607,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -627,7 +627,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -642,7 +642,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -666,7 +666,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() @@ -692,7 +692,7 @@ class AssignablePersonsTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shifts/{$shift->id}/assignable-persons", ); $response->assertOk() diff --git a/api/tests/Feature/Api/V1/PersonApprovalEmailTest.php b/api/tests/Feature/Api/V1/PersonApprovalEmailTest.php index b4789b95..21246de3 100644 --- a/api/tests/Feature/Api/V1/PersonApprovalEmailTest.php +++ b/api/tests/Feature/Api/V1/PersonApprovalEmailTest.php @@ -57,7 +57,7 @@ class PersonApprovalEmailTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons/{$person->id}/approve"); + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}/approve"); $response->assertOk(); @@ -79,7 +79,7 @@ class PersonApprovalEmailTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons/{$person->id}/reject", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}/reject", [ 'reason' => 'Geen beschikbaarheid op de juiste momenten.', ]); @@ -109,7 +109,7 @@ class PersonApprovalEmailTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons/{$person->id}/reject"); + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}/reject"); $response->assertOk(); @@ -127,7 +127,7 @@ class PersonApprovalEmailTest extends TestCase 'status' => 'pending', ]); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons/{$person->id}/approve"); + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}/approve"); $response->assertStatus(401); } @@ -146,7 +146,7 @@ class PersonApprovalEmailTest extends TestCase Sanctum::actingAs($outsider); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons/{$person->id}/approve"); + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}/approve"); $response->assertStatus(403); } diff --git a/api/tests/Feature/Api/V1/RegistrationSettingsTest.php b/api/tests/Feature/Api/V1/RegistrationSettingsTest.php index c2277987..2729355b 100644 --- a/api/tests/Feature/Api/V1/RegistrationSettingsTest.php +++ b/api/tests/Feature/Api/V1/RegistrationSettingsTest.php @@ -62,7 +62,7 @@ class RegistrationSettingsTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->festival->id}/sections/registration-settings"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/sections/registration-settings"); $response->assertOk() ->assertJsonCount(2, 'data'); @@ -92,7 +92,7 @@ class RegistrationSettingsTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->festival->id}/sections/registration-settings", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/sections/registration-settings", [ 'name' => 'Theatertent Bar', 'show_in_registration' => true, 'registration_description' => 'Bediening in de overdekte theatertent', @@ -121,7 +121,7 @@ class RegistrationSettingsTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $this->putJson("/api/v1/events/{$this->festival->id}/sections/registration-settings", [ + $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/sections/registration-settings", [ 'name' => 'EHBO', 'show_in_registration' => true, 'registration_description' => null, @@ -143,7 +143,7 @@ class RegistrationSettingsTest extends TestCase ]); // Unauthenticated - $response = $this->putJson("/api/v1/events/{$this->festival->id}/sections/registration-settings", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/sections/registration-settings", [ 'name' => 'Bar', 'show_in_registration' => true, 'registration_description' => null, @@ -156,7 +156,7 @@ class RegistrationSettingsTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->festival->id}/sections/registration-settings", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/sections/registration-settings", [ 'name' => 'Nonexistent Section', 'show_in_registration' => true, 'registration_description' => null, @@ -167,7 +167,7 @@ class RegistrationSettingsTest extends TestCase public function test_get_requires_authentication(): void { - $response = $this->getJson("/api/v1/events/{$this->festival->id}/sections/registration-settings"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/sections/registration-settings"); $response->assertUnauthorized(); } @@ -187,7 +187,7 @@ class RegistrationSettingsTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$flatEvent->id}/sections/registration-settings"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$flatEvent->id}/sections/registration-settings"); $response->assertOk() ->assertJsonCount(1, 'data') diff --git a/api/tests/Feature/Api/V1/ShiftAssignmentWorkflowTest.php b/api/tests/Feature/Api/V1/ShiftAssignmentWorkflowTest.php index 7649fc7c..102cd1c2 100644 --- a/api/tests/Feature/Api/V1/ShiftAssignmentWorkflowTest.php +++ b/api/tests/Feature/Api/V1/ShiftAssignmentWorkflowTest.php @@ -89,7 +89,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", ['person_id' => $this->person->id], ); @@ -115,7 +115,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$autoSection->id}/shifts/{$shift->id}/claim", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$autoSection->id}/shifts/{$shift->id}/claim", ['person_id' => $this->person->id], ); @@ -142,7 +142,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", ['person_id' => $this->person->id], ); @@ -162,7 +162,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", ['person_id' => $this->person->id], ); @@ -185,7 +185,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift2->id}/claim", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift2->id}/claim", ['person_id' => $this->person->id], ); @@ -208,7 +208,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift2->id}/claim", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift2->id}/claim", ['person_id' => $this->person->id], ); @@ -227,7 +227,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", ['person_id' => $pendingPerson->id], ); @@ -239,7 +239,7 @@ class ShiftAssignmentWorkflowTest extends TestCase $shift = $this->createOpenShift(); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", ['person_id' => $this->person->id], ); @@ -257,7 +257,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", ['person_id' => $this->person->id], ); @@ -282,7 +282,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", ['person_id' => $this->person->id], ); @@ -306,7 +306,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", ['person_id' => $this->person->id], ); @@ -333,7 +333,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift2->id}/assign", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift2->id}/assign", ['person_id' => $this->person->id], ); @@ -347,7 +347,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", ['person_id' => $this->person->id], ); @@ -371,7 +371,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/{$assignment->id}/approve", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/{$assignment->id}/approve", ); $response->assertOk() @@ -397,7 +397,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/{$assignment->id}/reject", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/{$assignment->id}/reject", ['reason' => 'Onvoldoende ervaring voor deze rol.'], ); @@ -418,7 +418,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/{$assignment->id}/approve", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/{$assignment->id}/approve", ); $response->assertUnprocessable(); @@ -437,7 +437,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/{$assignment->id}/cancel", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/{$assignment->id}/cancel", ); $response->assertOk() @@ -456,7 +456,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/{$assignment->id}/cancel", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/{$assignment->id}/cancel", ); $response->assertOk() @@ -480,7 +480,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->volunteer); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/{$assignment->id}/cancel", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/{$assignment->id}/cancel", ); $response->assertForbidden(); @@ -502,7 +502,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/{$assignment->id}/cancel", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/{$assignment->id}/cancel", ); $response->assertOk() @@ -530,7 +530,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/bulk-approve", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/bulk-approve", ['assignment_ids' => $assignments->pluck('id')->toArray()], ); @@ -570,7 +570,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/bulk-approve", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/bulk-approve", ['assignment_ids' => [$pending->id, $approved->id]], ); @@ -605,7 +605,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/shift-assignments"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments"); $response->assertOk(); $this->assertCount(3, $response->json('data')); @@ -633,7 +633,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/shift-assignments?status=pending_approval"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments?status=pending_approval"); $response->assertOk(); $this->assertCount(1, $response->json('data')); @@ -651,7 +651,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->outsider); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", ['person_id' => $this->person->id], ); @@ -671,7 +671,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->outsider); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/shift-assignments/{$assignment->id}/approve", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/shift-assignments/{$assignment->id}/approve", ); $response->assertForbidden(); @@ -688,7 +688,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/persons/{$this->person->id}/availabilities/sync", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/availabilities/sync", [ 'availabilities' => [ ['time_slot_id' => $this->timeSlot->id, 'preference_level' => 5], @@ -721,7 +721,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/persons/{$this->person->id}/availabilities/sync", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/availabilities/sync", [ 'availabilities' => [ ['time_slot_id' => $slot2->id, 'preference_level' => 4], @@ -752,7 +752,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/persons/{$this->person->id}/availabilities/sync", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/availabilities/sync", [ 'availabilities' => [ ['time_slot_id' => $otherSlot->id, 'preference_level' => 3], @@ -766,7 +766,7 @@ class ShiftAssignmentWorkflowTest extends TestCase public function test_unauthenticated_sync_returns_401(): void { $response = $this->postJson( - "/api/v1/events/{$this->event->id}/persons/{$this->person->id}/availabilities/sync", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/availabilities/sync", ['availabilities' => []], ); @@ -784,7 +784,7 @@ class ShiftAssignmentWorkflowTest extends TestCase Sanctum::actingAs($this->orgAdmin); $response = $this->getJson( - "/api/v1/events/{$this->event->id}/persons/{$this->person->id}/availabilities", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/availabilities", ); $response->assertOk(); diff --git a/api/tests/Feature/CrowdList/CrowdListTest.php b/api/tests/Feature/CrowdList/CrowdListTest.php index 32ad6265..8b4a6554 100644 --- a/api/tests/Feature/CrowdList/CrowdListTest.php +++ b/api/tests/Feature/CrowdList/CrowdListTest.php @@ -72,7 +72,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/crowd-lists"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists"); $response->assertOk(); $this->assertCount(3, $response->json('data')); @@ -86,7 +86,7 @@ class CrowdListTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/crowd-lists", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists", [ 'crowd_type_id' => $this->crowdType->id, 'name' => 'VIP Gastenlijst', 'type' => 'internal', @@ -116,7 +116,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/crowd-lists", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists", [ 'crowd_type_id' => $this->crowdType->id, 'name' => 'Catering Medewerkers', 'type' => 'external', @@ -132,7 +132,7 @@ class CrowdListTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/crowd-lists", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists", [ 'crowd_type_id' => $this->crowdType->id, 'name' => 'Test List', 'type' => 'invalid_type', @@ -154,7 +154,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}", [ 'name' => 'Nieuwe Naam', 'auto_approve' => true, 'max_persons' => 25, @@ -175,7 +175,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}"); $response->assertNoContent(); $this->assertDatabaseMissing('crowd_lists', ['id' => $crowdList->id]); @@ -196,7 +196,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons", [ 'person_id' => $person->id, ]); @@ -227,7 +227,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons", [ 'person_id' => $person->id, ]); @@ -258,7 +258,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); // Try to add 3rd person - $response = $this->postJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons", [ 'person_id' => $persons->last()->id, ]); @@ -283,7 +283,7 @@ class CrowdListTest extends TestCase // Add all 5 persons — no limit foreach ($persons as $person) { - $response = $this->postJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons", [ 'person_id' => $person->id, ]); $response->assertOk(); @@ -306,7 +306,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons", [ 'person_id' => $person->id, ]); @@ -336,7 +336,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons/{$person->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons/{$person->id}"); $response->assertNoContent(); @@ -370,7 +370,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/crowd-lists"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists"); $response->assertOk(); $listData = collect($response->json('data'))->firstWhere('id', $crowdList->id); @@ -400,7 +400,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons"); $response->assertOk(); $this->assertCount(3, $response->json('data')); @@ -433,7 +433,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons"); $response->assertOk(); $response->assertJsonStructure([ @@ -454,7 +454,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}/persons"); $response->assertForbidden(); } @@ -465,14 +465,14 @@ class CrowdListTest extends TestCase { Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->event->id}/crowd-lists"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists"); $response->assertForbidden(); } public function test_unauthenticated_cannot_access_crowd_lists(): void { - $response = $this->getJson("/api/v1/events/{$this->event->id}/crowd-lists"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists"); $response->assertUnauthorized(); } @@ -490,7 +490,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); // Try to update a list from event A via event B's URL - $response = $this->putJson("/api/v1/events/{$eventB->id}/crowd-lists/{$crowdList->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$eventB->id}/crowd-lists/{$crowdList->id}", [ 'name' => 'Hacked', ]); @@ -517,7 +517,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $this->deleteJson("/api/v1/events/{$this->event->id}/crowd-lists/{$crowdList->id}") + $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists/{$crowdList->id}") ->assertNoContent(); // Pivot removed (cascade) @@ -553,7 +553,7 @@ class CrowdListTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/crowd-lists"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/crowd-lists"); $response->assertOk(); $listData = collect($response->json('data'))->firstWhere('id', $crowdList->id); diff --git a/api/tests/Feature/Event/EventStatsTest.php b/api/tests/Feature/Event/EventStatsTest.php index aeea0493..b402ba4a 100644 --- a/api/tests/Feature/Event/EventStatsTest.php +++ b/api/tests/Feature/Event/EventStatsTest.php @@ -115,7 +115,7 @@ class EventStatsTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/stats"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/stats"); $response->assertOk(); $data = $response->json('data'); @@ -159,7 +159,7 @@ class EventStatsTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/stats"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/stats"); $response->assertOk(); $data = $response->json('data'); @@ -171,7 +171,7 @@ class EventStatsTest extends TestCase public function test_unauthenticated_cannot_access_stats(): void { - $response = $this->getJson("/api/v1/events/{$this->event->id}/stats"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/stats"); $response->assertUnauthorized(); } @@ -180,7 +180,7 @@ class EventStatsTest extends TestCase { Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->event->id}/stats"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/stats"); $response->assertForbidden(); } @@ -189,7 +189,7 @@ class EventStatsTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/stats"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/stats"); $response->assertOk(); $data = $response->json('data'); diff --git a/api/tests/Feature/Event/FestivalEventTest.php b/api/tests/Feature/Event/FestivalEventTest.php index e21efc5a..c746ee9d 100644 --- a/api/tests/Feature/Event/FestivalEventTest.php +++ b/api/tests/Feature/Event/FestivalEventTest.php @@ -54,7 +54,7 @@ class FestivalEventTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->festival->id}/time-slots", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/time-slots", [ 'name' => 'Opbouw Vrijdag', 'person_type' => 'CREW', 'date' => '2026-07-10', @@ -81,7 +81,7 @@ class FestivalEventTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->festival->id}/sections", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/sections", [ 'name' => 'Terreinploeg', 'sort_order' => 1, 'type' => 'standard', @@ -112,7 +112,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->festival->id}/sections/{$section->id}/shifts", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/sections/{$section->id}/shifts", [ 'time_slot_id' => $timeSlot->id, 'title' => 'Terreinmedewerker', 'slots_total' => 8, @@ -151,7 +151,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->subEvent->id}/sections"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/sections"); $response->assertOk(); @@ -181,7 +181,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->subEvent->id}/time-slots"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/time-slots"); $response->assertOk(); @@ -216,7 +216,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); // Query persons on festival level — should only return festival-level persons - $response = $this->getJson("/api/v1/events/{$this->festival->id}/persons"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/persons"); $response->assertOk(); @@ -231,7 +231,7 @@ class FestivalEventTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->subEvent->id}/sections", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/sections", [ 'name' => 'EHBO', 'type' => 'cross_event', ]); @@ -258,7 +258,7 @@ class FestivalEventTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->festival->id}/sections", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/sections", [ 'name' => 'Security', 'type' => 'cross_event', ]); @@ -283,7 +283,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$flatEvent->id}/sections", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$flatEvent->id}/sections", [ 'name' => 'EHBO', 'type' => 'cross_event', ]); @@ -298,13 +298,13 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); // Create cross_event via sub-event A → redirects to parent - $this->postJson("/api/v1/events/{$this->subEvent->id}/sections", [ + $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/sections", [ 'name' => 'Verkeersregelaars', 'type' => 'cross_event', ])->assertCreated(); // Should appear in sub-event B's section list - $response = $this->getJson("/api/v1/events/{$subEventB->id}/sections"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$subEventB->id}/sections"); $response->assertOk(); $sectionNames = collect($response->json('data'))->pluck('name')->all(); @@ -315,7 +315,7 @@ class FestivalEventTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->subEvent->id}/sections", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/sections", [ 'name' => 'Bar Schirmbar', 'type' => 'standard', ]); @@ -403,7 +403,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->subEvent->id}/time-slots?include_parent=true"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/time-slots?include_parent=true"); $response->assertOk(); @@ -439,7 +439,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); // Even with include_parent, festival parent should only return its own TS - $response = $this->getJson("/api/v1/events/{$this->festival->id}/time-slots?include_parent=true"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->festival->id}/time-slots?include_parent=true"); $response->assertOk(); @@ -461,7 +461,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->subEvent->id}/sections/{$section->id}/shifts", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/sections/{$section->id}/shifts", [ 'time_slot_id' => $festivalTimeSlot->id, 'title' => 'Opbouwshift', 'slots_total' => 4, @@ -494,7 +494,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->subEvent->id}/sections/{$section->id}/shifts", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/sections/{$section->id}/shifts", [ 'time_slot_id' => $otherTimeSlot->id, 'title' => 'Illegale shift', 'slots_total' => 1, @@ -518,7 +518,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); // include_parent has no effect on flat events - $response = $this->getJson("/api/v1/events/{$flatEvent->id}/time-slots?include_parent=true"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$flatEvent->id}/time-slots?include_parent=true"); $response->assertOk(); @@ -559,7 +559,7 @@ class FestivalEventTest extends TestCase Sanctum::actingAs($this->orgAdmin); // Assign person to the shift - $this->postJson("/api/v1/events/{$this->subEvent->id}/sections/{$section->id}/shifts/{$shift->id}/assign", [ + $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/sections/{$section->id}/shifts/{$shift->id}/assign", [ 'person_id' => $person->id, ])->assertCreated(); @@ -576,7 +576,7 @@ class FestivalEventTest extends TestCase ]); // Assigning the same person to same time_slot should fail - $response = $this->postJson("/api/v1/events/{$this->subEvent->id}/sections/{$section2->id}/shifts/{$shift2->id}/assign", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/sections/{$section2->id}/shifts/{$shift2->id}/assign", [ 'person_id' => $person->id, ]); diff --git a/api/tests/Feature/FestivalSection/FestivalSectionTest.php b/api/tests/Feature/FestivalSection/FestivalSectionTest.php index 4a6336ae..f112aec1 100644 --- a/api/tests/Feature/FestivalSection/FestivalSectionTest.php +++ b/api/tests/Feature/FestivalSection/FestivalSectionTest.php @@ -50,7 +50,7 @@ class FestivalSectionTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/sections"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections"); $response->assertOk(); $this->assertCount(3, $response->json('data')); @@ -60,7 +60,7 @@ class FestivalSectionTest extends TestCase { Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->event->id}/sections"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections"); $response->assertForbidden(); } @@ -69,7 +69,7 @@ class FestivalSectionTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections", [ 'name' => 'Bar', 'sort_order' => 1, ]); @@ -85,7 +85,7 @@ class FestivalSectionTest extends TestCase public function test_store_unauthenticated_returns_401(): void { - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections", [ 'name' => 'Bar', 'sort_order' => 1, ]); @@ -97,7 +97,7 @@ class FestivalSectionTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections", [ 'sort_order' => 1, ]); @@ -114,7 +114,7 @@ class FestivalSectionTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/sections/{$section->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$section->id}", [ 'name' => 'Bar Updated', ]); @@ -128,7 +128,7 @@ class FestivalSectionTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/sections/{$section->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$section->id}"); $response->assertNoContent(); $this->assertSoftDeleted('festival_sections', ['id' => $section->id]); @@ -140,7 +140,7 @@ class FestivalSectionTest extends TestCase Sanctum::actingAs($this->outsider); - $response = $this->putJson("/api/v1/events/{$this->event->id}/sections/{$section->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$section->id}", [ 'name' => 'Hacked', ]); @@ -153,7 +153,7 @@ class FestivalSectionTest extends TestCase Sanctum::actingAs($this->outsider); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/sections/{$section->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$section->id}"); $response->assertForbidden(); } @@ -162,7 +162,7 @@ class FestivalSectionTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections", [ 'name' => 'Tapkraan', 'category' => 'Bar', 'icon' => 'tabler-beer', @@ -237,7 +237,7 @@ class FestivalSectionTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections/reorder", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/reorder", [ 'sections' => [$sectionB->id, $sectionA->id], ]); diff --git a/api/tests/Feature/Location/LocationTest.php b/api/tests/Feature/Location/LocationTest.php index 8c4338fd..aaebd274 100644 --- a/api/tests/Feature/Location/LocationTest.php +++ b/api/tests/Feature/Location/LocationTest.php @@ -52,7 +52,7 @@ class LocationTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/locations"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations"); $response->assertOk(); $this->assertCount(3, $response->json('data')); @@ -62,7 +62,7 @@ class LocationTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/locations", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations", [ 'name' => 'Hoofdpodium', 'address' => 'Museumplein 1, 1071 DJ Amsterdam', 'lat' => 52.3580, @@ -85,7 +85,7 @@ class LocationTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/locations", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations", [ 'name' => 'Backstage Area', ]); @@ -105,7 +105,7 @@ class LocationTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/locations/{$location->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations/{$location->id}", [ 'name' => 'Bar Zuid', 'address' => 'Coolsingel 42, 3011 AD Rotterdam', 'lat' => 51.9225, @@ -130,7 +130,7 @@ class LocationTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/locations/{$location->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations/{$location->id}"); $response->assertNoContent(); $this->assertDatabaseMissing('locations', ['id' => $location->id]); @@ -142,7 +142,7 @@ class LocationTest extends TestCase { Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->event->id}/locations"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations"); $response->assertForbidden(); } @@ -151,7 +151,7 @@ class LocationTest extends TestCase { Sanctum::actingAs($this->outsider); - $response = $this->postJson("/api/v1/events/{$this->event->id}/locations", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations", [ 'name' => 'Hack Attempt', ]); @@ -166,7 +166,7 @@ class LocationTest extends TestCase Sanctum::actingAs($this->outsider); - $response = $this->putJson("/api/v1/events/{$this->event->id}/locations/{$location->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations/{$location->id}", [ 'name' => 'Hack Attempt', ]); @@ -181,14 +181,14 @@ class LocationTest extends TestCase Sanctum::actingAs($this->outsider); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/locations/{$location->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations/{$location->id}"); $response->assertForbidden(); } public function test_unauthenticated_cannot_access_locations(): void { - $response = $this->getJson("/api/v1/events/{$this->event->id}/locations"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations"); $response->assertUnauthorized(); } @@ -199,7 +199,7 @@ class LocationTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/locations", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations", [ 'address' => 'Museumplein 1, Amsterdam', ]); @@ -211,7 +211,7 @@ class LocationTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/locations", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations", [ 'name' => str_repeat('a', 256), ]); @@ -223,7 +223,7 @@ class LocationTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/locations", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations", [ 'name' => 'Ongeldige Locatie', 'lat' => 91.0, 'lng' => 181.0, @@ -244,7 +244,7 @@ class LocationTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/locations"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations"); $response->assertOk(); $this->assertCount(2, $response->json('data')); @@ -258,7 +258,7 @@ class LocationTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/locations"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/locations"); $response->assertOk(); $names = collect($response->json('data'))->pluck('name')->all(); diff --git a/api/tests/Feature/Person/PersonTest.php b/api/tests/Feature/Person/PersonTest.php index 3b36d060..a6e0a291 100644 --- a/api/tests/Feature/Person/PersonTest.php +++ b/api/tests/Feature/Person/PersonTest.php @@ -55,7 +55,7 @@ class PersonTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons"); $response->assertOk(); $this->assertCount(3, $response->json('data')); @@ -78,7 +78,7 @@ class PersonTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons?crowd_type_id={$this->crowdType->id}"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons?crowd_type_id={$this->crowdType->id}"); $response->assertOk(); $this->assertCount(2, $response->json('data')); @@ -93,7 +93,7 @@ class PersonTest extends TestCase // Outsider tries to access event from other org Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons"); $response->assertForbidden(); } @@ -107,7 +107,7 @@ class PersonTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons/{$person->id}"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}"); $response->assertOk() ->assertJsonPath('data.crowd_type.system_type', 'VOLUNTEER'); @@ -117,7 +117,7 @@ class PersonTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => $this->crowdType->id, 'first_name' => 'Jan', 'last_name' => 'de Vries', @@ -146,7 +146,7 @@ class PersonTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$person->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}", [ 'status' => 'approved', ]); @@ -164,7 +164,7 @@ class PersonTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons/{$person->id}/approve"); + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}/approve"); $response->assertOk() ->assertJsonPath('data.status', 'approved'); @@ -184,7 +184,7 @@ class PersonTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/persons/{$person->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}"); $response->assertNoContent(); $this->assertSoftDeleted('persons', ['id' => $person->id]); @@ -192,7 +192,7 @@ class PersonTest extends TestCase public function test_unauthenticated_returns_401(): void { - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons"); $response->assertUnauthorized(); } diff --git a/api/tests/Feature/PersonFieldValue/PersonFieldValueTest.php b/api/tests/Feature/PersonFieldValue/PersonFieldValueTest.php index 30e4cc9e..debd6cc5 100644 --- a/api/tests/Feature/PersonFieldValue/PersonFieldValueTest.php +++ b/api/tests/Feature/PersonFieldValue/PersonFieldValueTest.php @@ -62,7 +62,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ 'values' => [ $field->slug => 'Jan Jansen', ], @@ -85,7 +85,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ 'values' => [ $field->slug => 'M', ], @@ -108,7 +108,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ 'values' => [ $field->slug => 'XXXXL', ], @@ -125,7 +125,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ 'values' => [ $field->slug => ['Vegetarisch', 'Glutenvrij'], ], @@ -153,7 +153,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ 'values' => [ $field->slug => true, ], @@ -180,7 +180,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ 'values' => [ $field->slug => null, ], @@ -206,7 +206,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ 'values' => [ $field->slug => [$tag1->id, $tag2->id], ], @@ -230,7 +230,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ 'values' => [ $field->slug => ['01JFAKE00000000000000TAGID'], ], @@ -257,7 +257,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ 'values' => [ $field->slug => [$tag->id], ], @@ -288,7 +288,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values", [ 'values' => [ $field->slug => [$tag->id], ], @@ -316,7 +316,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values"); $response->assertOk(); $this->assertCount(1, $response->json('data')); @@ -338,7 +338,7 @@ class PersonFieldValueTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $this->deleteJson("/api/v1/events/{$this->event->id}/registration-fields/{$field->id}") + $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields/{$field->id}") ->assertNoContent(); // Value persists with FK set to null (nullOnDelete) @@ -353,14 +353,14 @@ class PersonFieldValueTest extends TestCase { Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values"); $response->assertForbidden(); } public function test_unauthenticated_returns_401(): void { - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons/{$this->person->id}/field-values"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$this->person->id}/field-values"); $response->assertUnauthorized(); } diff --git a/api/tests/Feature/PersonIdentity/PersonIdentityMatchTest.php b/api/tests/Feature/PersonIdentity/PersonIdentityMatchTest.php index bad152be..bb23d930 100644 --- a/api/tests/Feature/PersonIdentity/PersonIdentityMatchTest.php +++ b/api/tests/Feature/PersonIdentity/PersonIdentityMatchTest.php @@ -64,7 +64,7 @@ class PersonIdentityMatchTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => $this->crowdType->id, 'first_name' => 'Jan', 'last_name' => 'de Vries', @@ -92,7 +92,7 @@ class PersonIdentityMatchTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => $this->crowdType->id, 'first_name' => 'Piet', 'last_name' => 'Jansen', @@ -585,7 +585,7 @@ class PersonIdentityMatchTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons"); $response->assertOk(); @@ -608,7 +608,7 @@ class PersonIdentityMatchTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons"); $response->assertOk(); diff --git a/api/tests/Feature/PersonSectionPreference/PersonSectionPreferenceTest.php b/api/tests/Feature/PersonSectionPreference/PersonSectionPreferenceTest.php index c14dfda7..61dfacd1 100644 --- a/api/tests/Feature/PersonSectionPreference/PersonSectionPreferenceTest.php +++ b/api/tests/Feature/PersonSectionPreference/PersonSectionPreferenceTest.php @@ -82,7 +82,7 @@ class PersonSectionPreferenceTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ 'preferences' => [ ['festival_section_id' => $this->sectionA->id, 'priority' => 1], ['festival_section_id' => $this->sectionB->id, 'priority' => 2], @@ -114,7 +114,7 @@ class PersonSectionPreferenceTest extends TestCase Sanctum::actingAs($this->orgAdmin); // First: set 2 preferences - $this->putJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ + $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ 'preferences' => [ ['festival_section_id' => $this->sectionA->id, 'priority' => 1], ['festival_section_id' => $this->sectionB->id, 'priority' => 2], @@ -124,7 +124,7 @@ class PersonSectionPreferenceTest extends TestCase $this->assertEquals(2, PersonSectionPreference::where('person_id', $this->person->id)->count()); // Second: replace with 1 different preference - $this->putJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ + $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ 'preferences' => [ ['festival_section_id' => $this->sectionC->id, 'priority' => 1], ], @@ -146,7 +146,7 @@ class PersonSectionPreferenceTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ 'preferences' => [ ['festival_section_id' => $this->sectionA->id, 'priority' => 1], ['festival_section_id' => $this->sectionB->id, 'priority' => 1], @@ -161,7 +161,7 @@ class PersonSectionPreferenceTest extends TestCase Sanctum::actingAs($this->orgAdmin); // Priority 0 should fail - $response = $this->putJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ 'preferences' => [ ['festival_section_id' => $this->sectionA->id, 'priority' => 0], ], @@ -170,7 +170,7 @@ class PersonSectionPreferenceTest extends TestCase $response->assertUnprocessable(); // Priority 6 should fail - $response = $this->putJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ 'preferences' => [ ['festival_section_id' => $this->sectionA->id, 'priority' => 6], ], @@ -188,7 +188,7 @@ class PersonSectionPreferenceTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ 'preferences' => [ ['festival_section_id' => $this->sectionA->id, 'priority' => 1], ['festival_section_id' => $this->sectionB->id, 'priority' => 2], @@ -212,7 +212,7 @@ class PersonSectionPreferenceTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ 'preferences' => [ ['festival_section_id' => $otherSection->id, 'priority' => 1], ], @@ -225,7 +225,7 @@ class PersonSectionPreferenceTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences", [ 'preferences' => [ ['festival_section_id' => $this->crossEventSection->id, 'priority' => 1], ], @@ -255,7 +255,7 @@ class PersonSectionPreferenceTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences"); $response->assertOk(); $this->assertCount(2, $response->json('data')); @@ -265,14 +265,14 @@ class PersonSectionPreferenceTest extends TestCase { Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences"); $response->assertForbidden(); } public function test_unauthenticated_returns_401(): void { - $response = $this->getJson("/api/v1/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->subEvent->id}/persons/{$this->person->id}/section-preferences"); $response->assertUnauthorized(); } diff --git a/api/tests/Feature/PersonTag/UserOrganisationTagTest.php b/api/tests/Feature/PersonTag/UserOrganisationTagTest.php index f92b3519..ea093895 100644 --- a/api/tests/Feature/PersonTag/UserOrganisationTagTest.php +++ b/api/tests/Feature/PersonTag/UserOrganisationTagTest.php @@ -275,7 +275,7 @@ class UserOrganisationTagTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons/{$person->id}"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}"); $response->assertOk(); $tags = $response->json('data.tags'); @@ -306,7 +306,7 @@ class UserOrganisationTagTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons?tag={$this->tag1->id}"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons?tag={$this->tag1->id}"); $response->assertOk(); $this->assertCount(1, $response->json('data')); @@ -356,7 +356,7 @@ class UserOrganisationTagTest extends TestCase Sanctum::actingAs($this->orgAdmin); // AND filter: must have both tag1 AND tag2 - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons?tags={$this->tag1->id},{$this->tag2->id}"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons?tags={$this->tag1->id},{$this->tag2->id}"); $response->assertOk(); $this->assertCount(1, $response->json('data')); @@ -373,7 +373,7 @@ class UserOrganisationTagTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/persons/{$person->id}"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons/{$person->id}"); $response->assertOk(); $this->assertEquals([], $response->json('data.tags')); diff --git a/api/tests/Feature/RegistrationFieldTemplate/RegistrationFieldTemplateTest.php b/api/tests/Feature/RegistrationFieldTemplate/RegistrationFieldTemplateTest.php index 66128d60..037a6086 100644 --- a/api/tests/Feature/RegistrationFieldTemplate/RegistrationFieldTemplateTest.php +++ b/api/tests/Feature/RegistrationFieldTemplate/RegistrationFieldTemplateTest.php @@ -171,7 +171,7 @@ class RegistrationFieldTemplateTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$event->id}/registration-fields/from-template", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$event->id}/registration-fields/from-template", [ 'template_id' => $template->id, ]); diff --git a/api/tests/Feature/RegistrationFormField/RegistrationFormFieldTest.php b/api/tests/Feature/RegistrationFormField/RegistrationFormFieldTest.php index ba0c6e77..3283fcf1 100644 --- a/api/tests/Feature/RegistrationFormField/RegistrationFormFieldTest.php +++ b/api/tests/Feature/RegistrationFormField/RegistrationFormFieldTest.php @@ -65,7 +65,7 @@ class RegistrationFormFieldTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/registration-fields"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields"); $response->assertOk(); $this->assertCount(3, $response->json('data')); @@ -78,7 +78,7 @@ class RegistrationFormFieldTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/registration-fields", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [ 'label' => 'Shirtmaat', 'field_type' => 'select', 'options' => ['XS', 'S', 'M', 'L', 'XL'], @@ -98,7 +98,7 @@ class RegistrationFormFieldTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/registration-fields", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [ 'label' => 'Shirtmaat', 'field_type' => 'select', ]); @@ -111,7 +111,7 @@ class RegistrationFormFieldTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/registration-fields", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [ 'label' => 'Naam', 'field_type' => 'text', 'options' => ['A', 'B'], @@ -125,7 +125,7 @@ class RegistrationFormFieldTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/registration-fields", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [ 'label' => 'Vaardigheden', 'field_type' => 'tag_picker', 'tag_category' => 'Vaardigheid', @@ -139,7 +139,7 @@ class RegistrationFormFieldTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/registration-fields", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [ 'label' => 'Naam', 'field_type' => 'text', 'tag_category' => 'Vaardigheid', @@ -159,7 +159,7 @@ class RegistrationFormFieldTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/registration-fields", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [ 'label' => 'Shirtmaat', 'field_type' => 'text', ]); @@ -180,7 +180,7 @@ class RegistrationFormFieldTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$otherEvent->id}/registration-fields", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$otherEvent->id}/registration-fields", [ 'label' => 'Shirtmaat', 'field_type' => 'text', ]); @@ -199,7 +199,7 @@ class RegistrationFormFieldTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/registration-fields/{$field->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields/{$field->id}", [ 'label' => 'New Label', ]); @@ -217,7 +217,7 @@ class RegistrationFormFieldTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/registration-fields/{$field->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields/{$field->id}", [ 'field_type' => 'select', ]); @@ -237,7 +237,7 @@ class RegistrationFormFieldTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/registration-fields/{$field->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields/{$field->id}"); $response->assertNoContent(); $this->assertDatabaseMissing('registration_form_fields', [ @@ -262,7 +262,7 @@ class RegistrationFormFieldTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/registration-fields/reorder", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields/reorder", [ 'ids' => [$fieldC->id, $fieldA->id, $fieldB->id], ]); @@ -293,7 +293,7 @@ class RegistrationFormFieldTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/registration-fields/import-from-event", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields/import-from-event", [ 'source_event_id' => $sourceEvent->id, ]); @@ -315,7 +315,7 @@ class RegistrationFormFieldTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/registration-fields/import-from-event", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields/import-from-event", [ 'source_event_id' => $otherEvent->id, ]); @@ -331,7 +331,7 @@ class RegistrationFormFieldTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/registration-fields/from-template", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields/from-template", [ 'template_id' => $template->id, ]); @@ -349,14 +349,14 @@ class RegistrationFormFieldTest extends TestCase { Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->event->id}/registration-fields"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields"); $response->assertForbidden(); } public function test_unauthenticated_returns_401(): void { - $response = $this->getJson("/api/v1/events/{$this->event->id}/registration-fields"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields"); $response->assertUnauthorized(); } diff --git a/api/tests/Feature/Security/InputValidationSecurityTest.php b/api/tests/Feature/Security/InputValidationSecurityTest.php index 1c61aa99..f6adc324 100644 --- a/api/tests/Feature/Security/InputValidationSecurityTest.php +++ b/api/tests/Feature/Security/InputValidationSecurityTest.php @@ -53,7 +53,7 @@ final class InputValidationSecurityTest extends TestCase $xssPayload = ''; - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => $this->crowdType->id, 'first_name' => $xssPayload, 'last_name' => 'Normal', @@ -95,7 +95,7 @@ final class InputValidationSecurityTest extends TestCase $xssPayload = ''; - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections", [ 'name' => $xssPayload, ]); @@ -109,7 +109,7 @@ final class InputValidationSecurityTest extends TestCase { Sanctum::actingAs($this->admin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => $this->crowdType->id, 'first_name' => str_repeat('A', 256), 'last_name' => 'Normal', @@ -139,7 +139,7 @@ final class InputValidationSecurityTest extends TestCase { Sanctum::actingAs($this->admin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => $this->crowdType->id, 'first_name' => 'Test', 'last_name' => 'User', @@ -173,7 +173,7 @@ final class InputValidationSecurityTest extends TestCase { Sanctum::actingAs($this->admin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => $this->crowdType->id, 'first_name' => 'Test', 'last_name' => 'User', @@ -210,7 +210,7 @@ final class InputValidationSecurityTest extends TestCase Sanctum::actingAs($this->admin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => $otherCrowdType->id, 'first_name' => 'FK', 'last_name' => 'Test', @@ -228,7 +228,7 @@ final class InputValidationSecurityTest extends TestCase Sanctum::actingAs($this->admin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => $this->crowdType->id, 'first_name' => 'Company', 'last_name' => 'Test', @@ -250,7 +250,7 @@ final class InputValidationSecurityTest extends TestCase Sanctum::actingAs($this->admin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$section->id}/shifts", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$section->id}/shifts", [ 'time_slot_id' => $timeSlot->id, 'location_id' => $otherLocation->id, @@ -303,7 +303,7 @@ final class InputValidationSecurityTest extends TestCase Sanctum::actingAs($this->admin); $response = $this->postJson( - "/api/v1/events/{$this->event->id}/sections/{$section->id}/shifts/{$shift->id}/assign", + "/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$section->id}/shifts/{$shift->id}/assign", ['person_id' => $otherPerson->id] ); @@ -317,7 +317,7 @@ final class InputValidationSecurityTest extends TestCase { Sanctum::actingAs($this->admin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => 'not-a-valid-ulid', 'first_name' => 'Test', 'last_name' => 'User', @@ -332,7 +332,7 @@ final class InputValidationSecurityTest extends TestCase { Sanctum::actingAs($this->admin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => '01JZZZZZZZZZZZZZZZZZZZZZZ', 'first_name' => 'Test', 'last_name' => 'User', @@ -351,7 +351,7 @@ final class InputValidationSecurityTest extends TestCase $sqlPayload = "'; DROP TABLE users; --"; - $response = $this->postJson("/api/v1/events/{$this->event->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/persons", [ 'crowd_type_id' => $this->crowdType->id, 'first_name' => $sqlPayload, 'last_name' => 'Normal', diff --git a/api/tests/Feature/Security/MultiTenancyIsolationTest.php b/api/tests/Feature/Security/MultiTenancyIsolationTest.php index 91ad776a..adacd748 100644 --- a/api/tests/Feature/Security/MultiTenancyIsolationTest.php +++ b/api/tests/Feature/Security/MultiTenancyIsolationTest.php @@ -89,7 +89,7 @@ final class MultiTenancyIsolationTest extends TestCase { Sanctum::actingAs($this->adminA); - $response = $this->postJson("/api/v1/events/{$this->eventA->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/persons", [ 'crowd_type_id' => $this->crowdTypeB->id, 'first_name' => 'Test', 'last_name' => 'User', @@ -117,7 +117,7 @@ final class MultiTenancyIsolationTest extends TestCase ]); $response = $this->postJson( - "/api/v1/events/{$this->eventA->id}/sections/{$sectionA->id}/shifts/{$shiftA->id}/assign", + "/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/sections/{$sectionA->id}/shifts/{$shiftA->id}/assign", ['person_id' => $personB->id] ); @@ -142,7 +142,7 @@ final class MultiTenancyIsolationTest extends TestCase ]); $response = $this->postJson( - "/api/v1/events/{$this->eventA->id}/crowd-lists/{$crowdListA->id}/persons", + "/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/crowd-lists/{$crowdListA->id}/persons", ['person_id' => $personB->id] ); @@ -173,7 +173,7 @@ final class MultiTenancyIsolationTest extends TestCase ]); $response = $this->postJson( - "/api/v1/events/{$this->eventA->id}/shift-assignments/bulk-approve", + "/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/shift-assignments/bulk-approve", ['assignment_ids' => [$assignmentB->id]] ); @@ -207,7 +207,7 @@ final class MultiTenancyIsolationTest extends TestCase $companyB = Company::factory()->create(['organisation_id' => $this->orgB->id]); - $response = $this->postJson("/api/v1/events/{$this->eventA->id}/persons", [ + $response = $this->postJson("/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/persons", [ 'crowd_type_id' => $this->crowdTypeA->id, 'first_name' => 'Test', 'last_name' => 'User', @@ -225,7 +225,7 @@ final class MultiTenancyIsolationTest extends TestCase { Sanctum::actingAs($this->adminA); - $response = $this->postJson("/api/v1/events/{$this->eventA->id}/crowd-lists", [ + $response = $this->postJson("/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/crowd-lists", [ 'crowd_type_id' => $this->crowdTypeB->id, 'name' => 'Test List', 'type' => 'accreditation', @@ -266,7 +266,7 @@ final class MultiTenancyIsolationTest extends TestCase Sanctum::actingAs($this->adminA); - $response = $this->getJson("/api/v1/events/{$this->eventA->id}/persons"); + $response = $this->getJson("/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/persons"); $response->assertOk(); $personIds = collect($response->json('data'))->pluck('id'); @@ -280,7 +280,7 @@ final class MultiTenancyIsolationTest extends TestCase { Sanctum::actingAs($this->adminB); - $response = $this->getJson("/api/v1/events/{$this->eventA->id}/locations"); + $response = $this->getJson("/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/locations"); // Event-scoped routes: policy returns 403 (user not in org) — access is blocked $response->assertForbidden(); @@ -292,7 +292,7 @@ final class MultiTenancyIsolationTest extends TestCase { Sanctum::actingAs($this->adminB); - $response = $this->getJson("/api/v1/events/{$this->eventA->id}/sections"); + $response = $this->getJson("/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/sections"); $response->assertForbidden(); } @@ -305,7 +305,7 @@ final class MultiTenancyIsolationTest extends TestCase Sanctum::actingAs($this->adminB); - $response = $this->getJson("/api/v1/events/{$this->eventA->id}/sections/{$sectionA->id}/shifts"); + $response = $this->getJson("/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/sections/{$sectionA->id}/shifts"); $response->assertForbidden(); } @@ -316,7 +316,7 @@ final class MultiTenancyIsolationTest extends TestCase { Sanctum::actingAs($this->adminB); - $response = $this->getJson("/api/v1/events/{$this->eventA->id}/time-slots"); + $response = $this->getJson("/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/time-slots"); $response->assertForbidden(); } @@ -327,7 +327,7 @@ final class MultiTenancyIsolationTest extends TestCase { Sanctum::actingAs($this->adminB); - $response = $this->getJson("/api/v1/events/{$this->eventA->id}/registration-fields"); + $response = $this->getJson("/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/registration-fields"); $response->assertForbidden(); } @@ -338,7 +338,7 @@ final class MultiTenancyIsolationTest extends TestCase { Sanctum::actingAs($this->adminB); - $response = $this->getJson("/api/v1/events/{$this->eventA->id}/shift-assignments"); + $response = $this->getJson("/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/shift-assignments"); $response->assertForbidden(); } @@ -355,7 +355,7 @@ final class MultiTenancyIsolationTest extends TestCase ]); $response = $this->putJson( - "/api/v1/events/{$this->eventA->id}/persons/{$personA->id}", + "/api/v1/organisations/{$this->orgA->id}/events/{$this->eventA->id}/persons/{$personA->id}", ['first_name' => 'Hacked'] ); diff --git a/api/tests/Feature/Shift/ShiftTest.php b/api/tests/Feature/Shift/ShiftTest.php index 7202bfad..66eb4975 100644 --- a/api/tests/Feature/Shift/ShiftTest.php +++ b/api/tests/Feature/Shift/ShiftTest.php @@ -65,7 +65,7 @@ class ShiftTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts"); $response->assertOk(); $this->assertCount(3, $response->json('data')); @@ -75,7 +75,7 @@ class ShiftTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts", [ 'time_slot_id' => $this->timeSlot->id, 'title' => 'Tapper', 'slots_total' => 4, @@ -101,7 +101,7 @@ class ShiftTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}", [ 'title' => 'Barhoofd', 'slots_total' => 1, ]); @@ -119,7 +119,7 @@ class ShiftTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}"); $response->assertNoContent(); $this->assertSoftDeleted('shifts', ['id' => $shift->id]); @@ -129,7 +129,7 @@ class ShiftTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts", [ 'title' => 'Tapper', 'slots_total' => 4, 'slots_open_for_claiming' => 0, @@ -148,7 +148,7 @@ class ShiftTest extends TestCase Sanctum::actingAs($this->outsider); - $response = $this->putJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}", [ 'title' => 'Hacked', ]); @@ -164,7 +164,7 @@ class ShiftTest extends TestCase Sanctum::actingAs($this->outsider); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}"); $response->assertForbidden(); } @@ -185,7 +185,7 @@ class ShiftTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", [ 'person_id' => $person->id, ]); @@ -235,7 +235,7 @@ class ShiftTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift2->id}/assign", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift2->id}/assign", [ 'person_id' => $person->id, ]); @@ -277,7 +277,7 @@ class ShiftTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift2->id}/assign", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift2->id}/assign", [ 'person_id' => $person->id, ]); @@ -313,7 +313,7 @@ class ShiftTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/assign", [ 'person_id' => $person2->id, ]); @@ -342,7 +342,7 @@ class ShiftTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts/{$shift->id}/claim", [ 'person_id' => $person->id, ]); @@ -351,7 +351,7 @@ class ShiftTest extends TestCase public function test_unauthenticated_returns_401(): void { - $response = $this->getJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts"); $response->assertUnauthorized(); } @@ -360,7 +360,7 @@ class ShiftTest extends TestCase { Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->event->id}/sections/{$this->section->id}/shifts"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/sections/{$this->section->id}/shifts"); $response->assertForbidden(); } diff --git a/api/tests/Feature/TimeSlot/TimeSlotTest.php b/api/tests/Feature/TimeSlot/TimeSlotTest.php index 98f1f5e0..f1a0846d 100644 --- a/api/tests/Feature/TimeSlot/TimeSlotTest.php +++ b/api/tests/Feature/TimeSlot/TimeSlotTest.php @@ -50,7 +50,7 @@ class TimeSlotTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/time-slots"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots"); $response->assertOk(); $this->assertCount(3, $response->json('data')); @@ -98,7 +98,7 @@ class TimeSlotTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->getJson("/api/v1/events/{$this->event->id}/time-slots"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots"); $response->assertOk(); @@ -113,7 +113,7 @@ class TimeSlotTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/time-slots", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots", [ 'name' => 'Vrijdag Avond', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-10', @@ -138,7 +138,7 @@ class TimeSlotTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/time-slots", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots", [ 'name' => 'Test', 'person_type' => 'INVALID', 'date' => '2026-07-10', @@ -154,7 +154,7 @@ class TimeSlotTest extends TestCase { Sanctum::actingAs($this->orgAdmin); - $response = $this->postJson("/api/v1/events/{$this->event->id}/time-slots", [ + $response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots", [ 'name' => 'Test', 'person_type' => 'VOLUNTEER', 'date' => 'not-a-date', @@ -175,7 +175,7 @@ class TimeSlotTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->putJson("/api/v1/events/{$this->event->id}/time-slots/{$timeSlot->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots/{$timeSlot->id}", [ 'name' => 'Vrijdag Avond Updated', ]); @@ -189,7 +189,7 @@ class TimeSlotTest extends TestCase Sanctum::actingAs($this->outsider); - $response = $this->putJson("/api/v1/events/{$this->event->id}/time-slots/{$timeSlot->id}", [ + $response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots/{$timeSlot->id}", [ 'name' => 'Hacked', ]); @@ -202,7 +202,7 @@ class TimeSlotTest extends TestCase Sanctum::actingAs($this->outsider); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/time-slots/{$timeSlot->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots/{$timeSlot->id}"); $response->assertForbidden(); } @@ -213,7 +213,7 @@ class TimeSlotTest extends TestCase Sanctum::actingAs($this->orgAdmin); - $response = $this->deleteJson("/api/v1/events/{$this->event->id}/time-slots/{$timeSlot->id}"); + $response = $this->deleteJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots/{$timeSlot->id}"); $response->assertNoContent(); $this->assertDatabaseMissing('time_slots', ['id' => $timeSlot->id]); @@ -221,7 +221,7 @@ class TimeSlotTest extends TestCase public function test_unauthenticated_returns_401(): void { - $response = $this->getJson("/api/v1/events/{$this->event->id}/time-slots"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots"); $response->assertUnauthorized(); } @@ -230,7 +230,7 @@ class TimeSlotTest extends TestCase { Sanctum::actingAs($this->outsider); - $response = $this->getJson("/api/v1/events/{$this->event->id}/time-slots"); + $response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/time-slots"); $response->assertForbidden(); } diff --git a/apps/app/src/components/crowd-lists/AddPersonToCrowdListDialog.vue b/apps/app/src/components/crowd-lists/AddPersonToCrowdListDialog.vue index d8b1316d..513a529e 100644 --- a/apps/app/src/components/crowd-lists/AddPersonToCrowdListDialog.vue +++ b/apps/app/src/components/crowd-lists/AddPersonToCrowdListDialog.vue @@ -6,15 +6,17 @@ import type { Person } from '@/types/person' const props = defineProps<{ eventId: string + orgId: string crowdList: CrowdList }>() const modelValue = defineModel({ required: true }) +const orgIdRef = computed(() => props.orgId) const eventIdRef = computed(() => props.eventId) -const { data: personsResponse } = usePersonList(eventIdRef) -const { mutate: addPerson, isPending } = useAddPersonToCrowdList(eventIdRef) +const { data: personsResponse } = usePersonList(orgIdRef, eventIdRef) +const { mutate: addPerson, isPending } = useAddPersonToCrowdList(orgIdRef, eventIdRef) const selectedPersonId = ref(null) const showSuccess = ref(false) diff --git a/apps/app/src/components/crowd-lists/CrowdListDetailPanel.vue b/apps/app/src/components/crowd-lists/CrowdListDetailPanel.vue index 55908ed6..8663486f 100644 --- a/apps/app/src/components/crowd-lists/CrowdListDetailPanel.vue +++ b/apps/app/src/components/crowd-lists/CrowdListDetailPanel.vue @@ -37,12 +37,12 @@ const { isLoading: personsLoading, isError: personsError, refetch: refetchPersons, -} = useCrowdListPersons(eventIdRef, crowdListIdRef) +} = useCrowdListPersons(orgIdRef, eventIdRef, crowdListIdRef) // Mutations -const { mutate: removePerson, isPending: isRemoving } = useRemovePersonFromCrowdList(eventIdRef) -const { mutate: approvePerson } = useApprovePerson(eventIdRef) -const { mutate: approveAllPending, isPending: isApprovingAll } = useApproveAllPending(eventIdRef) +const { mutate: removePerson, isPending: isRemoving } = useRemovePersonFromCrowdList(orgIdRef, eventIdRef) +const { mutate: approvePerson } = useApprovePerson(orgIdRef, eventIdRef) +const { mutate: approveAllPending, isPending: isApprovingAll } = useApproveAllPending(orgIdRef, eventIdRef) // Resolved lookups const crowdTypeObj = computed(() => { @@ -715,6 +715,7 @@ function onApproveAllExecute() { v-if="crowdList" v-model="isAddPersonDialogOpen" :event-id="eventId" + :org-id="orgId" :crowd-list="crowdList" /> diff --git a/apps/app/src/components/crowd-lists/CrowdListFormDialog.vue b/apps/app/src/components/crowd-lists/CrowdListFormDialog.vue index 5ff2e5ad..083e6e39 100644 --- a/apps/app/src/components/crowd-lists/CrowdListFormDialog.vue +++ b/apps/app/src/components/crowd-lists/CrowdListFormDialog.vue @@ -22,8 +22,8 @@ const orgIdRef = computed(() => props.orgId) const { data: crowdTypes } = useCrowdTypeList(orgIdRef) const { data: companies } = useCompanies(orgIdRef) -const { mutate: createCrowdList, isPending: isCreating } = useCreateCrowdList(eventIdRef) -const { mutate: updateCrowdList, isPending: isUpdating } = useUpdateCrowdList(eventIdRef) +const { mutate: createCrowdList, isPending: isCreating } = useCreateCrowdList(orgIdRef, eventIdRef) +const { mutate: updateCrowdList, isPending: isUpdating } = useUpdateCrowdList(orgIdRef, eventIdRef) const isPending = computed(() => isCreating.value || isUpdating.value) diff --git a/apps/app/src/components/event/ImportFromEventDialog.vue b/apps/app/src/components/event/ImportFromEventDialog.vue index eee7f276..57713954 100644 --- a/apps/app/src/components/event/ImportFromEventDialog.vue +++ b/apps/app/src/components/event/ImportFromEventDialog.vue @@ -17,7 +17,7 @@ const orgIdRef = computed(() => props.orgId) const eventIdRef = computed(() => props.eventId) const { data: events, isLoading: isLoadingEvents } = useEventList(orgIdRef) -const { mutate: importFields, isPending } = useImportFieldsFromEvent(eventIdRef) +const { mutate: importFields, isPending } = useImportFieldsFromEvent(orgIdRef, eventIdRef) const selectedEventId = ref(null) diff --git a/apps/app/src/components/event/TemplatePickerDialog.vue b/apps/app/src/components/event/TemplatePickerDialog.vue index f9c6b6a1..cfa2c875 100644 --- a/apps/app/src/components/event/TemplatePickerDialog.vue +++ b/apps/app/src/components/event/TemplatePickerDialog.vue @@ -20,7 +20,7 @@ const orgIdRef = computed(() => props.orgId) const eventIdRef = computed(() => props.eventId) const { data: templates, isLoading } = useRegistrationFieldTemplates(orgIdRef) -const { mutate: createFromTemplate, isPending } = useCreateFieldFromTemplate(eventIdRef) +const { mutate: createFromTemplate, isPending } = useCreateFieldFromTemplate(orgIdRef, eventIdRef) const existingSlugs = computed(() => new Set(props.existingFields.map(f => f.slug)), diff --git a/apps/app/src/components/events/EventMetricCards.vue b/apps/app/src/components/events/EventMetricCards.vue index 3231e432..05dff57d 100644 --- a/apps/app/src/components/events/EventMetricCards.vue +++ b/apps/app/src/components/events/EventMetricCards.vue @@ -1,14 +1,17 @@