mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-05 15:54:03 +00:00
adjust tests
This commit is contained in:
parent
8c81ef2a8d
commit
f9dc4cb8e0
3 changed files with 53 additions and 60 deletions
|
|
@ -4,8 +4,11 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Stancl\Tenancy\Database\Concerns;
|
namespace Stancl\Tenancy\Database\Concerns;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||||
use Stancl\Tenancy\Contracts\Syncable;
|
use Stancl\Tenancy\Contracts\Syncable;
|
||||||
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
||||||
|
use Stancl\Tenancy\Database\Models\Tenant;
|
||||||
|
use Stancl\Tenancy\Database\Models\TenantPivot;
|
||||||
use Stancl\Tenancy\Events\SyncedResourceSaved;
|
use Stancl\Tenancy\Events\SyncedResourceSaved;
|
||||||
|
|
||||||
trait ResourceSyncing
|
trait ResourceSyncing
|
||||||
|
|
@ -43,4 +46,15 @@ trait ResourceSyncing
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function resources(): MorphToMany
|
||||||
|
{
|
||||||
|
return $this->morphToMany($this->getResourceTenantModelName(), 'tenant_resources', 'tenant_resources', 'resource_global_id', 'tenant_id', 'global_id')
|
||||||
|
->using(TenantPivot::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResourceTenantModelName(): string // todo better name
|
||||||
|
{
|
||||||
|
return config('tenancy.tenant_model', Tenant::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,16 +73,9 @@ test('polymorphic relationship works for every model when syncing resources from
|
||||||
// When central model provides nothing/null, the resource model will be created as a 1:1 copy of central model
|
// When central model provides nothing/null, the resource model will be created as a 1:1 copy of central model
|
||||||
$centralUser->resources()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
|
|
||||||
expect($centralUser->getSyncedCreationAttributes())->toBeNull();
|
|
||||||
$tenant1->run(function () use ($centralUser) {
|
$tenant1->run(function () use ($centralUser) {
|
||||||
$resourceUser = ResourceUserForPolymorphic::first();
|
$resourceUser = ResourceUserForPolymorphic::first()->only(['name', 'email', 'password', 'role']);
|
||||||
expect($resourceUser)->not()->toBeNull();
|
$centralUser = $centralUser->only(['name', 'email', 'password', 'role']);
|
||||||
$resourceUser = $resourceUser->toArray();
|
|
||||||
$centralUser = $centralUser->withoutRelations()->toArray();
|
|
||||||
|
|
||||||
// remove id from comparison, because we don't copy id and let target model handle it
|
|
||||||
unset($resourceUser['id']);
|
|
||||||
unset($centralUser['id']);
|
|
||||||
|
|
||||||
expect($resourceUser)->toBe($centralUser);
|
expect($resourceUser)->toBe($centralUser);
|
||||||
});
|
});
|
||||||
|
|
@ -104,16 +97,9 @@ test('polymorphic relationship works for every model when syncing resources from
|
||||||
// When central model provides nothing/null, the resource model will be created as a 1:1 copy of central model
|
// When central model provides nothing/null, the resource model will be created as a 1:1 copy of central model
|
||||||
$centralCompany->resources()->attach('t2');
|
$centralCompany->resources()->attach('t2');
|
||||||
|
|
||||||
expect($centralCompany->getSyncedCreationAttributes())->toBeNull();
|
|
||||||
$tenant2->run(function () use ($centralCompany) {
|
$tenant2->run(function () use ($centralCompany) {
|
||||||
$resourceCompany = ResourceCompanyForPolymorphic::first();
|
$resourceCompany = ResourceCompanyForPolymorphic::first()->only(['name', 'email']);
|
||||||
expect($resourceCompany)->not()->toBeNull();
|
$centralCompany = $centralCompany->only(['name', 'email']);
|
||||||
$resourceCompany = $resourceCompany->toArray();
|
|
||||||
$centralCompany = $centralCompany->withoutRelations()->toArray();
|
|
||||||
|
|
||||||
// remove id from comparison, because we don't copy id and let target model handle it
|
|
||||||
unset($resourceCompany['id']);
|
|
||||||
unset($centralCompany['id']);
|
|
||||||
|
|
||||||
expect($resourceCompany)->toBe($centralCompany);
|
expect($resourceCompany)->toBe($centralCompany);
|
||||||
});
|
});
|
||||||
|
|
@ -186,13 +172,13 @@ function migrateCompaniesTableForTenants(): void
|
||||||
|
|
||||||
class ResourceTenantForPolymorphic extends Tenant
|
class ResourceTenantForPolymorphic extends Tenant
|
||||||
{
|
{
|
||||||
public function users()
|
public function users(): MorphToMany
|
||||||
{
|
{
|
||||||
return $this->morphedByMany(CentralUserForPolymorphic::class, 'tenant_resources', 'tenant_resources', 'tenant_id', 'resource_global_id', 'id', 'global_id')
|
return $this->morphedByMany(CentralUserForPolymorphic::class, 'tenant_resources', 'tenant_resources', 'tenant_id', 'resource_global_id', 'id', 'global_id')
|
||||||
->using(TenantPivot::class);
|
->using(TenantPivot::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function companies()
|
public function companies(): MorphToMany
|
||||||
{
|
{
|
||||||
return $this->morphedByMany(CentralCompanyForPolymorphic::class, 'tenant_resources', 'tenant_resources', 'tenant_id', 'resource_global_id', 'id', 'global_id')
|
return $this->morphedByMany(CentralCompanyForPolymorphic::class, 'tenant_resources', 'tenant_resources', 'tenant_id', 'resource_global_id', 'id', 'global_id')
|
||||||
->using(TenantPivot::class);
|
->using(TenantPivot::class);
|
||||||
|
|
@ -209,10 +195,10 @@ class CentralUserForPolymorphic extends Model implements SyncMaster
|
||||||
|
|
||||||
public $table = 'users';
|
public $table = 'users';
|
||||||
|
|
||||||
public function resources(): MorphToMany
|
// override method to provide different tenant
|
||||||
|
public function getResourceTenantModelName(): string
|
||||||
{
|
{
|
||||||
return $this->morphToMany(ResourceTenantForPolymorphic::class, 'tenant_resources', 'tenant_resources', 'resource_global_id', 'tenant_id', 'global_id')
|
return ResourceTenantForPolymorphic::class;
|
||||||
->using(TenantPivot::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTenantModelName(): string
|
public function getTenantModelName(): string
|
||||||
|
|
@ -292,10 +278,10 @@ class CentralCompanyForPolymorphic extends Model implements SyncMaster
|
||||||
|
|
||||||
public $table = 'companies';
|
public $table = 'companies';
|
||||||
|
|
||||||
public function resources(): MorphToMany
|
// override method to provide different tenant
|
||||||
|
public function getResourceTenantModelName(): string
|
||||||
{
|
{
|
||||||
return $this->morphToMany(ResourceTenantForPolymorphic::class, 'tenant_resources', 'tenant_resources', 'resource_global_id', 'tenant_id', 'global_id')
|
return ResourceTenantForPolymorphic::class;
|
||||||
->using(TenantPivot::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTenantModelName(): string
|
public function getTenantModelName(): string
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||||
use Illuminate\Events\CallQueuedListener;
|
use Illuminate\Events\CallQueuedListener;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Queue;
|
use Illuminate\Support\Facades\Queue;
|
||||||
|
|
@ -149,7 +150,7 @@ test('sync resource creation works when central model provides attributes and re
|
||||||
});
|
});
|
||||||
|
|
||||||
// When central model provides the list of attributes, resource model will be created from the provided list of attributes' values
|
// When central model provides the list of attributes, resource model will be created from the provided list of attributes' values
|
||||||
$centralUser->tenants()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
|
|
||||||
$tenant1->run(function () {
|
$tenant1->run(function () {
|
||||||
$resourceUser = ResourceUserProvidingDefaultValues::all();
|
$resourceUser = ResourceUserProvidingDefaultValues::all();
|
||||||
|
|
@ -205,7 +206,7 @@ test('sync resource creation works when central model provides default values an
|
||||||
});
|
});
|
||||||
|
|
||||||
// When central model provides the list of default values, resource model will be created from the provided list of default values
|
// When central model provides the list of default values, resource model will be created from the provided list of default values
|
||||||
$centralUser->tenants()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
|
|
||||||
$tenant1->run(function () {
|
$tenant1->run(function () {
|
||||||
// Assert resource user was created using the list of default values
|
// Assert resource user was created using the list of default values
|
||||||
|
|
@ -257,7 +258,7 @@ test('sync resource creation works when central model provides mixture and resou
|
||||||
});
|
});
|
||||||
|
|
||||||
// When central model provides the list of a mixture (attributes and default values), resource model will be created from the provided list of mixture (attributes and default values)
|
// When central model provides the list of a mixture (attributes and default values), resource model will be created from the provided list of mixture (attributes and default values)
|
||||||
$centralUser->tenants()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
|
|
||||||
$tenant1->run(function () {
|
$tenant1->run(function () {
|
||||||
$resourceUser = ResourceUser::first();
|
$resourceUser = ResourceUser::first();
|
||||||
|
|
@ -284,14 +285,10 @@ test('sync resource creation works when central model provides mixture and resou
|
||||||
|
|
||||||
tenancy()->end();
|
tenancy()->end();
|
||||||
|
|
||||||
$centralUser = CentralUserProvidingMixture::whereGlobalId('acmey')->first();
|
$centralUser = CentralUserProvidingMixture::whereGlobalId('acmey')->first()->only(['name', 'email', 'password', 'role']);
|
||||||
expect($resourceUser->getSyncedCreationAttributes())->toBeNull();
|
expect($resourceUser->getSyncedCreationAttributes())->toBeNull();
|
||||||
|
|
||||||
$centralUser = $centralUser->toArray();
|
$resourceUser = $resourceUser->only(['name', 'email', 'password', 'role']);
|
||||||
$resourceUser = $resourceUser->toArray();
|
|
||||||
unset($centralUser['id']);
|
|
||||||
unset($resourceUser['id']);
|
|
||||||
|
|
||||||
// Assert central user created as 1:1 copy of resource model except "id"
|
// Assert central user created as 1:1 copy of resource model except "id"
|
||||||
expect($centralUser)->toBe($resourceUser);
|
expect($centralUser)->toBe($resourceUser);
|
||||||
});
|
});
|
||||||
|
|
@ -315,16 +312,12 @@ test('sync resource creation works when central model provides nothing and resou
|
||||||
});
|
});
|
||||||
|
|
||||||
// When central model provides nothing/null, the resource model will be created as a 1:1 copy of central model
|
// When central model provides nothing/null, the resource model will be created as a 1:1 copy of central model
|
||||||
$centralUser->tenants()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
|
|
||||||
expect($centralUser->getSyncedCreationAttributes())->toBeNull();
|
expect($centralUser->getSyncedCreationAttributes())->toBeNull();
|
||||||
$tenant1->run(function () use ($centralUser) {
|
$tenant1->run(function () use ($centralUser) {
|
||||||
$resourceUser = ResourceUserProvidingMixture::first();
|
$resourceUser = ResourceUserProvidingMixture::first()->only(['name', 'email', 'password', 'role']);
|
||||||
expect($resourceUser)->not()->toBeNull();
|
$centralUser = $centralUser->only(['name', 'email', 'password', 'role']);
|
||||||
$resourceUser = $resourceUser->toArray();
|
|
||||||
$centralUser = $centralUser->withoutRelations()->toArray();
|
|
||||||
unset($resourceUser['id']);
|
|
||||||
unset($centralUser['id']);
|
|
||||||
|
|
||||||
expect($resourceUser)->toBe($centralUser);
|
expect($resourceUser)->toBe($centralUser);
|
||||||
});
|
});
|
||||||
|
|
@ -384,7 +377,7 @@ test('attaching a tenant to the central resource triggers a pull from the tenant
|
||||||
expect(ResourceUser::all())->toHaveCount(0);
|
expect(ResourceUser::all())->toHaveCount(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
$centralUser->tenants()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
|
|
||||||
$tenant->run(function () {
|
$tenant->run(function () {
|
||||||
expect(ResourceUser::all())->toHaveCount(1);
|
expect(ResourceUser::all())->toHaveCount(1);
|
||||||
|
|
@ -440,8 +433,8 @@ test('resources are synced only to workspaces that have the resource', function
|
||||||
]);
|
]);
|
||||||
migrateUsersTableForTenants();
|
migrateUsersTableForTenants();
|
||||||
|
|
||||||
$centralUser->tenants()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
$centralUser->tenants()->attach('t2');
|
$centralUser->resources()->attach('t2');
|
||||||
// t3 is not attached
|
// t3 is not attached
|
||||||
|
|
||||||
$t1->run(function () {
|
$t1->run(function () {
|
||||||
|
|
@ -479,7 +472,7 @@ test('when a resource exists in other tenant dbs but is created in a tenant db t
|
||||||
migrateUsersTableForTenants();
|
migrateUsersTableForTenants();
|
||||||
|
|
||||||
// Copy (cascade) user to t1 DB
|
// Copy (cascade) user to t1 DB
|
||||||
$centralUser->tenants()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
|
|
||||||
$t2->run(function () {
|
$t2->run(function () {
|
||||||
// Create user with the same global ID in t2 database
|
// Create user with the same global ID in t2 database
|
||||||
|
|
@ -527,9 +520,9 @@ test('the synced columns are updated in other tenant dbs where the resource exis
|
||||||
migrateUsersTableForTenants();
|
migrateUsersTableForTenants();
|
||||||
|
|
||||||
// Copy (cascade) user to t1 DB
|
// Copy (cascade) user to t1 DB
|
||||||
$centralUser->tenants()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
$centralUser->tenants()->attach('t2');
|
$centralUser->resources()->attach('t2');
|
||||||
$centralUser->tenants()->attach('t3');
|
$centralUser->resources()->attach('t3');
|
||||||
|
|
||||||
$t3->run(function () {
|
$t3->run(function () {
|
||||||
ResourceUser::first()->update([
|
ResourceUser::first()->update([
|
||||||
|
|
@ -581,7 +574,7 @@ test('when the resource doesnt exist in the tenant db non synced columns will ca
|
||||||
|
|
||||||
migrateUsersTableForTenants();
|
migrateUsersTableForTenants();
|
||||||
|
|
||||||
$centralUser->tenants()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
|
|
||||||
$t1->run(function () {
|
$t1->run(function () {
|
||||||
expect(ResourceUser::first()->role)->toBe('employee');
|
expect(ResourceUser::first()->role)->toBe('employee');
|
||||||
|
|
@ -657,17 +650,17 @@ test('an event is fired for all touched resources', function () {
|
||||||
migrateUsersTableForTenants();
|
migrateUsersTableForTenants();
|
||||||
|
|
||||||
// Copy (cascade) user to t1 DB
|
// Copy (cascade) user to t1 DB
|
||||||
$centralUser->tenants()->attach('t1');
|
$centralUser->resources()->attach('t1');
|
||||||
Event::assertDispatched(SyncedResourceChangedInForeignDatabase::class, function (SyncedResourceChangedInForeignDatabase $event) {
|
Event::assertDispatched(SyncedResourceChangedInForeignDatabase::class, function (SyncedResourceChangedInForeignDatabase $event) {
|
||||||
return $event->tenant->getTenantKey() === 't1';
|
return $event->tenant->getTenantKey() === 't1';
|
||||||
});
|
});
|
||||||
|
|
||||||
$centralUser->tenants()->attach('t2');
|
$centralUser->resources()->attach('t2');
|
||||||
Event::assertDispatched(SyncedResourceChangedInForeignDatabase::class, function (SyncedResourceChangedInForeignDatabase $event) {
|
Event::assertDispatched(SyncedResourceChangedInForeignDatabase::class, function (SyncedResourceChangedInForeignDatabase $event) {
|
||||||
return $event->tenant->getTenantKey() === 't2';
|
return $event->tenant->getTenantKey() === 't2';
|
||||||
});
|
});
|
||||||
|
|
||||||
$centralUser->tenants()->attach('t3');
|
$centralUser->resources()->attach('t3');
|
||||||
Event::assertDispatched(SyncedResourceChangedInForeignDatabase::class, function (SyncedResourceChangedInForeignDatabase $event) {
|
Event::assertDispatched(SyncedResourceChangedInForeignDatabase::class, function (SyncedResourceChangedInForeignDatabase $event) {
|
||||||
return $event->tenant->getTenantKey() === 't3';
|
return $event->tenant->getTenantKey() === 't3';
|
||||||
});
|
});
|
||||||
|
|
@ -755,7 +748,7 @@ function creatingResourceInTenantDatabaseCreatesAndMapInCentralDatabase()
|
||||||
expect(CentralUser::first()->role)->toBe('commenter');
|
expect(CentralUser::first()->role)->toBe('commenter');
|
||||||
|
|
||||||
// Assert mapping was created
|
// Assert mapping was created
|
||||||
expect(CentralUser::first()->tenants)->toHaveCount(1);
|
expect(CentralUser::first()->resources)->toHaveCount(1);
|
||||||
|
|
||||||
// Assert role change doesn't cascade
|
// Assert role change doesn't cascade
|
||||||
CentralUser::first()->update(['role' => 'central superadmin']);
|
CentralUser::first()->update(['role' => 'central superadmin']);
|
||||||
|
|
@ -792,7 +785,7 @@ test('resources are synced only when sync is enabled', function (bool $enabled)
|
||||||
'role' => 'commenter',
|
'role' => 'commenter',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$centralUser->tenants()->attach('t2');
|
$centralUser->resources()->attach('t2');
|
||||||
|
|
||||||
$tenant2->run(function () use ($enabled) {
|
$tenant2->run(function () use ($enabled) {
|
||||||
expect(TenantUserWithConditionalSync::all())->toHaveCount($enabled ? 1 : 0);
|
expect(TenantUserWithConditionalSync::all())->toHaveCount($enabled ? 1 : 0);
|
||||||
|
|
@ -831,9 +824,9 @@ function migrateUsersTableForTenants(): void
|
||||||
|
|
||||||
class ResourceTenant extends Tenant
|
class ResourceTenant extends Tenant
|
||||||
{
|
{
|
||||||
public function users()
|
public function users(): MorphToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(CentralUser::class, 'tenant_users', 'tenant_id', 'global_user_id', 'id', 'global_id')
|
return $this->morphedByMany(CentralUserForPolymorphic::class, 'tenant_resources', 'tenant_resources', 'tenant_id', 'resource_global_id', 'id', 'global_id')
|
||||||
->using(TenantPivot::class);
|
->using(TenantPivot::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -848,10 +841,10 @@ class CentralUser extends Model implements SyncMaster
|
||||||
|
|
||||||
public $table = 'users';
|
public $table = 'users';
|
||||||
|
|
||||||
public function tenants(): BelongsToMany
|
// override method to provide different tenant
|
||||||
|
public function getResourceTenantModelName(): string
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(ResourceTenant::class, 'tenant_users', 'global_user_id', 'tenant_id', 'global_id')
|
return ResourceTenant::class;
|
||||||
->using(TenantPivot::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTenantModelName(): string
|
public function getTenantModelName(): string
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue