mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-05 03:54:04 +00:00
Use models with UUID in the tests (wip)
This commit is contained in:
parent
c41559fd3d
commit
fb042a0671
1 changed files with 86 additions and 17 deletions
|
|
@ -4,19 +4,20 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Stancl\Tenancy\Tests\Etc\Post;
|
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Stancl\Tenancy\Events\TenancyEnded;
|
use Stancl\Tenancy\Events\TenancyEnded;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Stancl\Tenancy\Bootstrappers\Integrations\PostgresTenancyBootstrapper;
|
|
||||||
use Stancl\Tenancy\Tests\Etc\ScopedComment;
|
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Jobs\DeleteTenantsPostgresUser;
|
use Stancl\Tenancy\Jobs\DeleteTenantsPostgresUser;
|
||||||
use Stancl\Tenancy\Jobs\CreatePostgresUserForTenant;
|
use Stancl\Tenancy\Jobs\CreatePostgresUserForTenant;
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
|
use Stancl\Tenancy\Database\Concerns\BelongsToPrimaryModel;
|
||||||
|
use Stancl\Tenancy\Bootstrappers\Integrations\PostgresTenancyBootstrapper;
|
||||||
|
use Stancl\Tenancy\Database\Concerns\BelongsToTenant;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
DB::purge('central');
|
DB::purge('central');
|
||||||
|
|
@ -30,8 +31,8 @@ beforeEach(function () {
|
||||||
config(['tenancy.models.tenant_key_column' => 'tenant_id']);
|
config(['tenancy.models.tenant_key_column' => 'tenant_id']);
|
||||||
config(['tenancy.models.tenant' => $tenantClass = Tenant::class]);
|
config(['tenancy.models.tenant' => $tenantClass = Tenant::class]);
|
||||||
config(['tenancy.models.rls' => [
|
config(['tenancy.models.rls' => [
|
||||||
$primaryModelClass = Post::class, // Primary model (directly belongs to tenant)
|
$primaryModelClass = UuidPost::class, // Primary model (directly belongs to tenant)
|
||||||
$secondaryModelClass = ScopedComment::class, // Secondary model (belongs to tenant through a primary model)
|
$secondaryModelClass = UuidScopedComment::class, // Secondary model (belongs to tenant through a primary model)
|
||||||
]]);
|
]]);
|
||||||
|
|
||||||
$tenantModel = new $tenantClass;
|
$tenantModel = new $tenantClass;
|
||||||
|
|
@ -48,7 +49,8 @@ beforeEach(function () {
|
||||||
Schema::dropIfExists($secondaryModel->getTable());
|
Schema::dropIfExists($secondaryModel->getTable());
|
||||||
Schema::dropIfExists($primaryModel->getTable());
|
Schema::dropIfExists($primaryModel->getTable());
|
||||||
Schema::dropIfExists('domains');
|
Schema::dropIfExists('domains');
|
||||||
Schema::dropIfExists($tenantTable);
|
//Schema::dropIfExists($tenantTable);
|
||||||
|
DB::statement("DROP TABLE IF EXISTS $tenantTable CASCADE");
|
||||||
|
|
||||||
// todo1 The Post/Comment models have non-UUID primary keys
|
// todo1 The Post/Comment models have non-UUID primary keys
|
||||||
Schema::create($tenantTable, function (Blueprint $table) {
|
Schema::create($tenantTable, function (Blueprint $table) {
|
||||||
|
|
@ -60,19 +62,23 @@ beforeEach(function () {
|
||||||
Schema::create($primaryModel->getTable(), function (Blueprint $table) {
|
Schema::create($primaryModel->getTable(), function (Blueprint $table) {
|
||||||
$table->uuid('id')->default(Str::uuid()->toString())->nullable(false)->primary();
|
$table->uuid('id')->default(Str::uuid()->toString())->nullable(false)->primary();
|
||||||
$table->string('text');
|
$table->string('text');
|
||||||
$table->foreignUuid('tenant_id')->constrained('tenants')->onUpdate('cascade')->onDelete('cascade');;
|
|
||||||
|
$table->timestamps();
|
||||||
|
$table->foreignUuid('tenant_id')->constrained('tenants')->onUpdate('cascade')->onDelete('cascade');
|
||||||
});
|
});
|
||||||
|
|
||||||
Schema::create($secondaryModel->getTable(), function (Blueprint $table) use ($primaryModel) {
|
Schema::create($secondaryModel->getTable(), function (Blueprint $table) use ($primaryModel) {
|
||||||
$table->uuid('id')->default(Str::uuid()->toString())->nullable(false)->primary();
|
$table->uuid('id')->default(Str::uuid()->toString())->nullable(false)->primary();
|
||||||
$table->string('text');
|
$table->string('text');
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
$table->foreignUuid($primaryModel->getForeignKey())->constrained($primaryModel->getTable())->onUpdate('cascade')->onDelete('cascade');
|
$table->foreignUuid($primaryModel->getForeignKey())->constrained($primaryModel->getTable())->onUpdate('cascade')->onDelete('cascade');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
Schema::dropIfExists('comments');
|
Schema::dropIfExists('uuid_comments');
|
||||||
Schema::dropIfExists('posts');
|
Schema::dropIfExists('uuid_posts');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('postgres user can get created using the job', function() {
|
test('postgres user can get created using the job', function() {
|
||||||
|
|
@ -144,15 +150,15 @@ test('queries are correctly scoped using RLS', function() {
|
||||||
// Create posts and comments for both tenants
|
// Create posts and comments for both tenants
|
||||||
tenancy()->initialize($tenant);
|
tenancy()->initialize($tenant);
|
||||||
|
|
||||||
$post1 = Post::create(['text' => 'first post']);
|
$post1 = UuidPost::create(['text' => 'first post']);
|
||||||
$post1Comment = $post1->scoped_comments()->create(['text' => 'first comment']);
|
$post1Comment = $post1->uuid_scoped_comments()->create(['text' => 'first comment']);
|
||||||
|
|
||||||
tenancy()->end();
|
tenancy()->end();
|
||||||
|
|
||||||
tenancy()->initialize($secondTenant);
|
tenancy()->initialize($secondTenant);
|
||||||
|
|
||||||
$post2 = Post::create(['text' => 'second post']);
|
$post2 = UuidPost::create(['text' => 'second post']);
|
||||||
$post2Comment = $post2->scoped_comments()->create(['text' => 'second comment']);
|
$post2Comment = $post2->uuid_scoped_comments()->create(['text' => 'second comment']);
|
||||||
|
|
||||||
tenancy()->end();
|
tenancy()->end();
|
||||||
|
|
||||||
|
|
@ -160,11 +166,11 @@ test('queries are correctly scoped using RLS', function() {
|
||||||
// Ensure RLS scopes the queries – expect that tenants cannot access the records (posts and comments) of other tenants
|
// Ensure RLS scopes the queries – expect that tenants cannot access the records (posts and comments) of other tenants
|
||||||
tenancy()->initialize($tenant);
|
tenancy()->initialize($tenant);
|
||||||
|
|
||||||
expect(Post::all()->pluck('text'))
|
expect(UuidPost::all()->pluck('text'))
|
||||||
->toContain($post1->text)
|
->toContain($post1->text)
|
||||||
->not()->toContain($post2->text);
|
->not()->toContain($post2->text);
|
||||||
|
|
||||||
expect(ScopedComment::all()->pluck('text'))
|
expect(UuidScopedComment::all()->pluck('text'))
|
||||||
->toContain($post1Comment->text)
|
->toContain($post1Comment->text)
|
||||||
->not()->toContain($post2Comment->text);
|
->not()->toContain($post2Comment->text);
|
||||||
|
|
||||||
|
|
@ -172,8 +178,71 @@ test('queries are correctly scoped using RLS', function() {
|
||||||
|
|
||||||
tenancy()->initialize($secondTenant);
|
tenancy()->initialize($secondTenant);
|
||||||
|
|
||||||
expect(Post::all()->pluck('text'))->toContain($post2->text)->not()->toContain($post1->text);
|
expect(UuidPost::all()->pluck('text'))->toContain($post2->text)->not()->toContain($post1->text);
|
||||||
expect(ScopedComment::all()->pluck('text'))->toContain($post2Comment->text)->not()->toContain($post1Comment->text);
|
expect(UuidScopedComment::all()->pluck('text'))->toContain($post2Comment->text)->not()->toContain($post1Comment->text);
|
||||||
|
|
||||||
tenancy()->end();
|
tenancy()->end();
|
||||||
})->group('test');
|
})->group('test');
|
||||||
|
|
||||||
|
trait UsesUuidAsPrimaryKey
|
||||||
|
{
|
||||||
|
protected static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
static::creating(function ($model) {
|
||||||
|
$uuid = Str::uuid()->toString();
|
||||||
|
|
||||||
|
if (empty($model->{$model->getKeyName()})) {
|
||||||
|
$model->{$model->getKeyName()} = $uuid;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class UuidPost extends Model
|
||||||
|
{
|
||||||
|
use BelongsToTenant;
|
||||||
|
|
||||||
|
public $incrementing = false;
|
||||||
|
public $table = 'uuid_posts';
|
||||||
|
protected $guarded = [];
|
||||||
|
protected $keyType = 'string';
|
||||||
|
|
||||||
|
public function uuid_comments()
|
||||||
|
{
|
||||||
|
return $this->hasMany(UuidComment::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function uuid_scoped_comments()
|
||||||
|
{
|
||||||
|
return $this->hasMany(UuidComment::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UuidScopedComment extends UuidComment
|
||||||
|
{
|
||||||
|
use BelongsToPrimaryModel;
|
||||||
|
|
||||||
|
protected $guarded = [];
|
||||||
|
|
||||||
|
public function getRelationshipToPrimaryModel(): string
|
||||||
|
{
|
||||||
|
return 'uuid_post';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UuidComment extends Model
|
||||||
|
{
|
||||||
|
protected $guarded = [];
|
||||||
|
protected $keyType = 'string';
|
||||||
|
|
||||||
|
public $incrementing = false;
|
||||||
|
public $table = 'uuid_comments';
|
||||||
|
|
||||||
|
public function uuid_post()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(UuidPost::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue