From 2b45a01018b10df09281a07b4b1c8f90a44b8359 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Fri, 21 Nov 2025 09:06:52 +0100 Subject: [PATCH] Move triggerRestoredEvent(), test restoring Syncables Update comments in DeleteResourceMapping to explain the detach() behavior. Move triggerRestoredEvent() from SyncMaster to Syncable interface, test restoring tenant resources. --- .../Listeners/DeleteResourceMapping.php | 4 ++-- src/ResourceSyncing/SyncMaster.php | 2 -- src/ResourceSyncing/Syncable.php | 2 ++ tests/ResourceSyncingTest.php | 11 ++++++++++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/ResourceSyncing/Listeners/DeleteResourceMapping.php b/src/ResourceSyncing/Listeners/DeleteResourceMapping.php index 319fd043..53754324 100644 --- a/src/ResourceSyncing/Listeners/DeleteResourceMapping.php +++ b/src/ResourceSyncing/Listeners/DeleteResourceMapping.php @@ -34,8 +34,8 @@ class DeleteResourceMapping extends QueueableListener // or the central resource was deleted using forceDelete() if ($event->forceDelete || ! in_array(SoftDeletes::class, class_uses_recursive($centralResource::class), true)) { Pivot::withoutEvents(function () use ($centralResource, $event) { - // $event->tenant is null when the deleted resource is a SyncMaster - all mappings are deleted in that case - // When $event->tenant is not null (= a Syncable was deleted), only delete the mapping for that tenant + // If detach() is called with null -- if $event->tenant is null -- this means a central resource was deleted and detaches all tenants. + // If detach() is called with a specific tenant, it means the resource was deleted in that tenant, and we only delete that single mapping. $centralResource->tenants()->detach($event->tenant); }); } diff --git a/src/ResourceSyncing/SyncMaster.php b/src/ResourceSyncing/SyncMaster.php index 710bc097..73af0c72 100644 --- a/src/ResourceSyncing/SyncMaster.php +++ b/src/ResourceSyncing/SyncMaster.php @@ -24,6 +24,4 @@ interface SyncMaster extends Syncable public function triggerDetachEvent(TenantWithDatabase&Model $tenant): void; public function triggerAttachEvent(TenantWithDatabase&Model $tenant): void; - - public function triggerRestoredEvent(): void; } diff --git a/src/ResourceSyncing/Syncable.php b/src/ResourceSyncing/Syncable.php index c38b02ea..ec13c485 100644 --- a/src/ResourceSyncing/Syncable.php +++ b/src/ResourceSyncing/Syncable.php @@ -18,6 +18,8 @@ interface Syncable public function triggerDeleteEvent(bool $forceDelete = false): void; + public function triggerRestoredEvent(): void; + /** * Get the attributes used for creating the *other* model (i.e. tenant if this is the central one, and central if this is the tenant one). * diff --git a/tests/ResourceSyncingTest.php b/tests/ResourceSyncingTest.php index ebd6ccfd..5687b849 100644 --- a/tests/ResourceSyncingTest.php +++ b/tests/ResourceSyncingTest.php @@ -1102,7 +1102,16 @@ test('restoring soft deleted resources works', function () { CentralUserWithSoftDeletes::withTrashed()->first()->restore(); tenancy()->runForMultiple([$tenant1, $tenant2], function () { - expect(TenantUserWithSoftDeletes::withTrashed()->first()->trashed())->toBeFalse(); + $tenantResource = TenantUserWithSoftDeletes::withTrashed()->first(); + + expect($tenantResource->trashed())->toBeFalse(); + + $tenantResource->delete(); + + // Restoring a tenant resource works as expected + $tenantResource->restore(); + + expect($tenantResource->trashed())->toBeFalse(); }); });