[DatabaseTenancyBootstrapper::class], ]); DatabaseTenancyBootstrapper::$harden = $harden; Event::listen(TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) { return $event->tenant; })->toListener()); $tenant = Tenant::create(); $tenant->update([ 'tenancy_db_name' => config('database.connections.central.database'), // Central database name ]); if ($harden) { // Harden blocks initialization for tenants that use central database expect(fn () => tenancy()->initialize($tenant))->toThrow(RuntimeException::class); // Connection should be reverted back to central expect(DB::connection()->getName())->toBe('central'); } else { expect(fn() => tenancy()->initialize($tenant))->not()->toThrow(Throwable::class); // Connection not reverted to central expect(DB::connection()->getName())->toBe('tenant'); } })->with([ 'hardening enabled' => true, 'hardening disabled' => false, ]); test('harden prevents tenants from using a database of another tenant', function ($harden) { config([ 'tenancy.bootstrappers' => [DatabaseTenancyBootstrapper::class], ]); DatabaseTenancyBootstrapper::$harden = $harden; Event::listen(TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) { return $event->tenant; })->toListener()); $tenant = Tenant::create(); Tenant::create([ 'tenancy_db_name' => $tenantDbName = 'foo' . Str::random(8), ]); $tenant->update([ 'tenancy_db_name' => $tenantDbName, // Database of another tenant ]); if ($harden) { // Harden blocks initialization for tenants that use a database of another tenant expect(fn () => tenancy()->initialize($tenant))->toThrow(RuntimeException::class); // Connection should be reverted back to central expect(DB::connection()->getName())->toBe('central'); } else { expect(fn() => tenancy()->initialize($tenant))->not()->toThrow(Throwable::class); // Connection not reverted to central expect(DB::connection()->getName())->toBe('tenant'); } })->with([ 'hardening enabled' => true, 'hardening disabled' => false, ]); test('database tenancy bootstrapper throws an exception if DATABASE_URL is set', function (string|null $databaseUrl) { config(['database.connections.central.url' => $databaseUrl]); if ($databaseUrl) { pest()->expectException(Exception::class); } config(['tenancy.bootstrappers' => [DatabaseTenancyBootstrapper::class]]); Event::listen(TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) { return $event->tenant; })->toListener()); $tenant1 = Tenant::create(); pest()->artisan('tenants:migrate'); tenancy()->initialize($tenant1); expect(true)->toBe(true); })->with(['abc.us-east-1.rds.amazonaws.com', null]);