diff --git a/src/Contracts/Syncable.php b/src/Contracts/Syncable.php index a481f318..f8e7fd84 100644 --- a/src/Contracts/Syncable.php +++ b/src/Contracts/Syncable.php @@ -18,4 +18,6 @@ interface Syncable /** 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). */ public function getSyncedCreationAttributes(): array|null; // todo come up with a better name + + public function shouldSync(): bool; } diff --git a/src/Database/Concerns/ResourceSyncing.php b/src/Database/Concerns/ResourceSyncing.php index fd63738d..ea9f83b4 100644 --- a/src/Database/Concerns/ResourceSyncing.php +++ b/src/Database/Concerns/ResourceSyncing.php @@ -13,8 +13,9 @@ trait ResourceSyncing public static function bootResourceSyncing(): void { static::saved(function (Syncable $model) { - /** @var ResourceSyncing $model */ - $model->triggerSyncEvent(); + if ($model->shouldSync()) { + $model->triggerSyncEvent(); + } }); static::creating(function (self $model) { @@ -37,4 +38,9 @@ trait ResourceSyncing { return null; } + + public function shouldSync(): bool + { + return true; + } } diff --git a/src/Database/Models/TenantPivot.php b/src/Database/Models/TenantPivot.php index 2c7583c1..3cc614a9 100644 --- a/src/Database/Models/TenantPivot.php +++ b/src/Database/Models/TenantPivot.php @@ -14,7 +14,7 @@ class TenantPivot extends Pivot static::saved(function (self $pivot) { $parent = $pivot->pivotParent; - if ($parent instanceof Syncable) { + if ($parent instanceof Syncable && $parent->shouldSync()) { $parent->triggerSyncEvent(); } }); diff --git a/t b/t new file mode 100755 index 00000000..3c74f2e8 --- /dev/null +++ b/t @@ -0,0 +1,3 @@ +#!/bin/bash + +docker-compose exec -T test vendor/bin/pest --no-coverage --filter "$@" diff --git a/tests/ResourceSyncingTest.php b/tests/ResourceSyncingTest.php index 430c52ef..e1586bc1 100644 --- a/tests/ResourceSyncingTest.php +++ b/tests/ResourceSyncingTest.php @@ -763,6 +763,43 @@ function creatingResourceInTenantDatabaseCreatesAndMapInCentralDatabase() expect(ResourceUser::first()->role)->toBe('commenter'); } +test('resources are synced only when sync is enabled', function (bool $enabled) { + app()->instance('_tenancy_test_shouldSync', $enabled); + + [$tenant1, $tenant2] = createTenantsAndRunMigrations(); + migrateUsersTableForTenants(); + + tenancy()->initialize($tenant1); + + TenantUserWithConditionalSync::create([ + 'global_id' => 'absd', + 'name' => 'John Doe', + 'email' => 'john@localhost', + 'password' => 'password', + 'role' => 'commenter', + ]); + + tenancy()->end(); + + expect(CentralUserWithConditionalSync::all())->toHaveCount($enabled ? 1 : 0); + expect(CentralUserWithConditionalSync::whereGlobalId('absd')->exists())->toBe($enabled); + + $centralUser = CentralUserWithConditionalSync::create([ + 'global_id' => 'acme', + 'name' => 'John Doe', + 'email' => 'john@localhost', + 'password' => 'password', + 'role' => 'commenter', + ]); + + $centralUser->tenants()->attach('t2'); + + $tenant2->run(function () use ($enabled) { + expect(TenantUserWithConditionalSync::all())->toHaveCount($enabled ? 1 : 0); + expect(TenantUserWithConditionalSync::whereGlobalId('acme')->exists())->toBe($enabled); + }); +})->with([[true], [false]]); + /** * Create two tenants and run migrations for those tenants. */ @@ -979,3 +1016,19 @@ class ResourceUserProvidingMixture extends ResourceUser ]; } } + +class CentralUserWithConditionalSync extends CentralUser +{ + public function shouldSync(): bool + { + return app('_tenancy_test_shouldSync'); + } +} + +class TenantUserWithConditionalSync extends ResourceUser +{ + public function shouldSync(): bool + { + return app('_tenancy_test_shouldSync'); + } +}