From b0e70a2054c13e6b5845d8425a7d105c636043a5 Mon Sep 17 00:00:00 2001 From: Eleazar Resendez Date: Fri, 16 Jan 2026 11:31:04 -0600 Subject: [PATCH] delete notifications tied to case on delete and add test --- .../Api/Actions/Cases/DeleteCase.php | 1 + .../Api/Actions/Cases/DeletesCaseRecords.php | 21 ++++++ tests/Feature/Api/CaseDeleteTest.php | 65 +++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php index d98f39e703..6d34bcf7b7 100644 --- a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php +++ b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php @@ -35,6 +35,7 @@ public function __invoke(string $caseNumber): void $this->deleteTaskDraftMedia($draftIds); $this->deleteTaskDrafts($tokenIds); $this->deleteComments($caseNumber, $requestIds, $tokenIds); + $this->deleteNotifications($requestIds); $this->deleteRequestMedia($requestIds); $this->deleteCaseNumbers($requestIds); $this->deleteCasesStarted($caseNumber); diff --git a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeletesCaseRecords.php b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeletesCaseRecords.php index d8b3493ccf..f59850a67b 100644 --- a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeletesCaseRecords.php +++ b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeletesCaseRecords.php @@ -11,6 +11,7 @@ use ProcessMaker\Models\InboxRule; use ProcessMaker\Models\InboxRuleLog; use ProcessMaker\Models\Media; +use ProcessMaker\Models\Notification; use ProcessMaker\Models\ProcessAbeRequestToken; use ProcessMaker\Models\ProcessRequest; use ProcessMaker\Models\ProcessRequestLock; @@ -199,4 +200,24 @@ private function deleteComments(string $caseNumber, array $requestIds, array $to }) ->delete(); } + + private function deleteNotifications(array $requestIds): void + { + if ($requestIds === []) { + return; + } + + $notificationTypes = [ + 'COMMENT', + 'FILE_SHARED', + 'TASK_CREATED', + 'TASK_COMPLETED', + 'TASK_REASSIGNED', + ]; + + Notification::query() + ->whereIn('data->request_id', $requestIds) + ->whereIn('data->type', $notificationTypes) + ->delete(); + } } diff --git a/tests/Feature/Api/CaseDeleteTest.php b/tests/Feature/Api/CaseDeleteTest.php index 3673ed926f..01d205e39b 100644 --- a/tests/Feature/Api/CaseDeleteTest.php +++ b/tests/Feature/Api/CaseDeleteTest.php @@ -12,6 +12,7 @@ use ProcessMaker\Models\InboxRule; use ProcessMaker\Models\InboxRuleLog; use ProcessMaker\Models\Media; +use ProcessMaker\Models\Notification; use ProcessMaker\Models\ProcessAbeRequestToken; use ProcessMaker\Models\ProcessRequest; use ProcessMaker\Models\ProcessRequestLock; @@ -152,6 +153,70 @@ public function testDeleteCaseRemovesDependentRecords(): void } } + public function testDeleteCaseRemovesCaseNotifications(): void + { + $caseNumber = 13579; + $request = ProcessRequest::factory() + ->withCaseNumber($caseNumber) + ->create(); + $otherRequest = ProcessRequest::factory() + ->withCaseNumber($caseNumber + 1) + ->create(); + + $notificationTypes = [ + 'COMMENT', + 'FILE_SHARED', + 'TASK_CREATED', + 'TASK_COMPLETED', + 'TASK_REASSIGNED', + ]; + + $deletedNotificationIds = []; + foreach ($notificationTypes as $type) { + $deletedNotificationIds[] = Notification::factory()->create([ + 'notifiable_type' => get_class($this->user), + 'notifiable_id' => $this->user->getKey(), + 'data' => json_encode([ + 'type' => $type, + 'request_id' => $request->id, + 'url' => "/requests/{$request->id}", + ]), + 'url' => "/requests/{$request->id}", + ])->id; + } + + $keptDifferentRequest = Notification::factory()->create([ + 'notifiable_type' => get_class($this->user), + 'notifiable_id' => $this->user->getKey(), + 'data' => json_encode([ + 'type' => 'TASK_CREATED', + 'request_id' => $otherRequest->id, + 'url' => "/requests/{$otherRequest->id}", + ]), + 'url' => "/requests/{$otherRequest->id}", + ]); + + $keptDifferentType = Notification::factory()->create([ + 'notifiable_type' => get_class($this->user), + 'notifiable_id' => $this->user->getKey(), + 'data' => json_encode([ + 'type' => 'MESSAGE', + 'request_id' => $request->id, + 'url' => "/requests/{$request->id}", + ]), + 'url' => "/requests/{$request->id}", + ]); + + $response = $this->apiCall('DELETE', route('api.cases.destroy', ['case_number' => $caseNumber])); + + $response->assertStatus(204); + foreach ($deletedNotificationIds as $notificationId) { + $this->assertDatabaseMissing('notifications', ['id' => $notificationId]); + } + $this->assertDatabaseHas('notifications', ['id' => $keptDifferentRequest->id]); + $this->assertDatabaseHas('notifications', ['id' => $keptDifferentType->id]); + } + public function testDeleteCaseReturnsNotFoundWhenMissing(): void { $caseNumber = 99999;