diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index f874300..3a6e787 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -85,6 +85,15 @@ public function deliveries(Request $request): Response $query->where('endpoint_id', $request->endpoint_id); } + $filteredEvent = null; + + if ($request->has('event_id') && $request->event_id) { + $query->where('event_id', $request->event_id); + + $filteredEvent = $request->user()->events() + ->find($request->event_id, ['id', 'name']); + } + $deliveries = $query->latest()->paginate(20); // Get filter options @@ -93,7 +102,8 @@ public function deliveries(Request $request): Response return Inertia::render('Deliveries/Index', [ 'deliveries' => $deliveries, 'endpoints' => $endpoints, - 'filters' => $request->only(['status', 'endpoint_id']), + 'filters' => $request->only(['status', 'endpoint_id', 'event_id']), + 'filteredEvent' => $filteredEvent, ]); } } diff --git a/resources/js/Pages/Deliveries/Index.vue b/resources/js/Pages/Deliveries/Index.vue index 60ecc56..d4893a1 100644 --- a/resources/js/Pages/Deliveries/Index.vue +++ b/resources/js/Pages/Deliveries/Index.vue @@ -80,6 +80,16 @@ + +
+ + Filtered by event: {{ filteredEvent.name }} + + +
+
@@ -377,6 +387,7 @@ const props = defineProps({ deliveries: Object, endpoints: Array, filters: Object, + filteredEvent: Object, }) // State @@ -386,6 +397,7 @@ const retryProcessing = ref(false) const filters = ref({ status: props.filters?.status || '', endpoint_id: props.filters?.endpoint_id || '', + event_id: props.filters?.event_id || '', event_name: props.filters?.event_name || '', from_date: props.filters?.from_date || '', to_date: props.filters?.to_date || '', @@ -405,8 +417,8 @@ const pendingCount = computed(() => { }) const hasFilters = computed(() => { - return filters.value.status || filters.value.endpoint_id || filters.value.event_name - || filters.value.from_date || filters.value.to_date + return filters.value.status || filters.value.endpoint_id || filters.value.event_id + || filters.value.event_name || filters.value.from_date || filters.value.to_date }) // Methods @@ -478,10 +490,16 @@ function clearFilters() { filters.value = { status: '', endpoint_id: '', + event_id: '', event_name: '', from_date: '', to_date: '', } applyFilters() } + +function clearEventFilter() { + filters.value.event_id = '' + applyFilters() +} diff --git a/tests/Feature/DashboardDeliveriesEventFilterTest.php b/tests/Feature/DashboardDeliveriesEventFilterTest.php new file mode 100644 index 0000000..71b6215 --- /dev/null +++ b/tests/Feature/DashboardDeliveriesEventFilterTest.php @@ -0,0 +1,85 @@ +withPersonalTeam()->create(); + $endpoint = Endpoint::factory()->for($user)->create(); + + $targetEvent = Event::factory()->for($user)->create(['name' => 'user.created']); + $otherEvent = Event::factory()->for($user)->create(['name' => 'user.deleted']); + + $targetDelivery = Delivery::factory()->for($targetEvent)->for($endpoint)->create(); + Delivery::factory()->for($otherEvent)->for($endpoint)->create(); + + $response = $this->actingAs($user)->get(route('deliveries', ['event_id' => $targetEvent->id])); + + $response->assertOk(); + $response->assertInertia( + fn ($page) => $page + ->component('Deliveries/Index') + ->has('deliveries.data', 1) + ->where('deliveries.data.0.id', $targetDelivery->id) + ->where('filters.event_id', (string) $targetEvent->id) + ->where('filteredEvent.id', $targetEvent->id) + ->where('filteredEvent.name', $targetEvent->name) + ); + } + + public function test_without_event_id_filter_all_of_the_users_deliveries_are_returned(): void + { + $user = User::factory()->withPersonalTeam()->create(); + $endpoint = Endpoint::factory()->for($user)->create(); + + $eventOne = Event::factory()->for($user)->create(); + $eventTwo = Event::factory()->for($user)->create(); + + Delivery::factory()->for($eventOne)->for($endpoint)->create(); + Delivery::factory()->for($eventTwo)->for($endpoint)->create(); + + $response = $this->actingAs($user)->get(route('deliveries')); + + $response->assertOk(); + $response->assertInertia( + fn ($page) => $page + ->component('Deliveries/Index') + ->has('deliveries.data', 2) + ->where('filteredEvent', null) + ); + } + + public function test_event_id_filter_cannot_be_used_to_view_another_users_event_deliveries(): void + { + $user = User::factory()->withPersonalTeam()->create(); + $endpoint = Endpoint::factory()->for($user)->create(); + $ownEvent = Event::factory()->for($user)->create(); + Delivery::factory()->for($ownEvent)->for($endpoint)->create(); + + $otherUser = User::factory()->withPersonalTeam()->create(); + $otherEvent = Event::factory()->for($otherUser)->create(); + $otherEndpoint = Endpoint::factory()->for($otherUser)->create(); + Delivery::factory()->for($otherEvent)->for($otherEndpoint)->create(); + + $response = $this->actingAs($user)->get(route('deliveries', ['event_id' => $otherEvent->id])); + + $response->assertOk(); + $response->assertInertia( + fn ($page) => $page + ->component('Deliveries/Index') + ->has('deliveries.data', 0) + ->where('filteredEvent', null) + ); + } +}