mirror of
https://github.com/archtechx/tenancy.git
synced 2026-08-06 05:34:04 +00:00
Correct DatabaseTenancyBootstrapperTest (#1466)
### Test for DatabaseTenancyBootstrapper throwing an exception when
`DB_URL` is set
The test meant to cover this set `central.url` before creating a tenant.
That made the `CreateDatabase` job fail with a QueryException (it tried
to use the URL host as a database name). The bootstrapper's check was
never reached, and the exception that the test intended to cover wasn't
ever thrown in the end. The test passed for the wrong reason.
Fixed by creating the tenant first, setting the url only after that, and
asserting that `tenancy()->initialize()` throws the bootstrapper's
specific exception.
### Reference env variable that Laravel uses now (`DB_URL`) instead of
`DATABASE_URL`
Changed all `DATABASE_URL` references in Tenancy to `DB_URL`. [In
Laravel
11](96508d43ec (diff-e4382b565f69d02de16eef89c8d5ca2b60a679ffca90ab8b7d85fbd78f30075bR35)),
the `DATABASE_URL` env variable got renamed to `DB_URL` in
`config/database.php`. The env var got renamed quite a while ago, so
referencing `DATABASE_URL` in Tenancy's comments and tests was a bit
confusing.
### Minor cleanup
The `harden prevents tenants from using the database of another tenant`
test now reads the central connection name from
`config('tenancy.database.central_connection')` instead of hardcoding
`'central'` for consistency with the other tests.
This commit is contained in:
parent
df4be2e060
commit
17706f8e2c
3 changed files with 14 additions and 16 deletions
|
|
@ -53,8 +53,8 @@ class DatabaseTenancyBootstrapper implements TenancyBootstrapper
|
||||||
{
|
{
|
||||||
/** @var TenantWithDatabase $tenant */
|
/** @var TenantWithDatabase $tenant */
|
||||||
if (data_get($tenant->database()->getTemplateConnection(), 'url')) {
|
if (data_get($tenant->database()->getTemplateConnection(), 'url')) {
|
||||||
// The package works with individual parts of the database connection config, so DATABASE_URL is not supported.
|
// The package works with individual parts of the database connection config, so DB_URL is not supported.
|
||||||
// When DATABASE_URL is set, this bootstrapper can silently fail i.e. keep using the template connection's database URL
|
// When DB_URL is set, this bootstrapper can silently fail i.e. keep using the template connection's database URL
|
||||||
// which takes precedence over individual segments of the connection config. This issue can be hard to debug as it can be
|
// which takes precedence over individual segments of the connection config. This issue can be hard to debug as it can be
|
||||||
// production-specific. Therefore, we throw an exception (that effectively blocks all tenant pages) to prevent incorrect DB use.
|
// production-specific. Therefore, we throw an exception (that effectively blocks all tenant pages) to prevent incorrect DB use.
|
||||||
throw new Exception('The template connection must NOT have URL defined. Specify the connection using individual parts instead of a database URL.');
|
throw new Exception('The template connection must NOT have URL defined. Specify the connection using individual parts instead of a database URL.');
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Database\QueryException;
|
|
||||||
use Stancl\Tenancy\Database\TenantDatabaseManagers\MySQLDatabaseManager;
|
use Stancl\Tenancy\Database\TenantDatabaseManagers\MySQLDatabaseManager;
|
||||||
use Stancl\Tenancy\Database\TenantDatabaseManagers\SQLiteDatabaseManager;
|
use Stancl\Tenancy\Database\TenantDatabaseManagers\SQLiteDatabaseManager;
|
||||||
use Stancl\Tenancy\Database\TenantDatabaseManagers\PostgreSQLDatabaseManager;
|
use Stancl\Tenancy\Database\TenantDatabaseManagers\PostgreSQLDatabaseManager;
|
||||||
|
|
@ -116,7 +115,9 @@ test('harden prevents tenants from using the database of another tenant', functi
|
||||||
expect(fn () => tenancy()->initialize($tenant))->toThrow(RuntimeException::class);
|
expect(fn () => tenancy()->initialize($tenant))->toThrow(RuntimeException::class);
|
||||||
|
|
||||||
// Connection should be reverted back to central
|
// Connection should be reverted back to central
|
||||||
expect(DB::connection()->getName())->toBe('central');
|
$centralConnection = config('tenancy.database.central_connection');
|
||||||
|
|
||||||
|
expect(DB::connection()->getName())->toBe($centralConnection);
|
||||||
} else {
|
} else {
|
||||||
expect(fn() => tenancy()->initialize($tenant))->not()->toThrow(Throwable::class);
|
expect(fn() => tenancy()->initialize($tenant))->not()->toThrow(Throwable::class);
|
||||||
|
|
||||||
|
|
@ -128,25 +129,22 @@ test('harden prevents tenants from using the database of another tenant', functi
|
||||||
'hardening disabled' => false,
|
'hardening disabled' => false,
|
||||||
])->with('db_managers');
|
])->with('db_managers');
|
||||||
|
|
||||||
test('database tenancy bootstrapper throws an exception if DATABASE_URL is set', function (string|null $databaseUrl) {
|
test('database tenancy bootstrapper throws an exception if DB_URL is set', function (string|null $databaseUrl) {
|
||||||
config(['database.connections.central.url' => $databaseUrl]);
|
|
||||||
|
|
||||||
config(['tenancy.bootstrappers' => [DatabaseTenancyBootstrapper::class]]);
|
config(['tenancy.bootstrappers' => [DatabaseTenancyBootstrapper::class]]);
|
||||||
|
|
||||||
Event::listen(TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) {
|
Event::listen(TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) {
|
||||||
return $event->tenant;
|
return $event->tenant;
|
||||||
})->toListener());
|
})->toListener());
|
||||||
|
|
||||||
|
$tenant = Tenant::create();
|
||||||
|
|
||||||
|
config(['database.connections.central.url' => $databaseUrl]);
|
||||||
|
|
||||||
if ($databaseUrl) {
|
if ($databaseUrl) {
|
||||||
expect(fn() => Tenant::create())->toThrow(QueryException::class);
|
expect(fn() => tenancy()->initialize($tenant))
|
||||||
|
->toThrow(Exception::class, 'The template connection must NOT have URL defined.');
|
||||||
} else {
|
} else {
|
||||||
expect(function() {
|
expect(fn() => tenancy()->initialize($tenant))->not()->toThrow(Throwable::class);
|
||||||
$tenant1 = Tenant::create();
|
|
||||||
|
|
||||||
pest()->artisan('tenants:migrate');
|
|
||||||
|
|
||||||
tenancy()->initialize($tenant1);
|
|
||||||
})->not()->toThrow(Throwable::class);
|
|
||||||
}
|
}
|
||||||
})->with(['abc.us-east-1.rds.amazonaws.com', null]);
|
})->with(['abc.us-east-1.rds.amazonaws.com', null]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
'cache.stores.apc' => ['driver' => 'apc'],
|
'cache.stores.apc' => ['driver' => 'apc'],
|
||||||
'database.connections.central' => [
|
'database.connections.central' => [
|
||||||
'driver' => 'mysql',
|
'driver' => 'mysql',
|
||||||
'url' => env('DATABASE_URL'),
|
'url' => env('DB_URL'),
|
||||||
'host' => 'mysql',
|
'host' => 'mysql',
|
||||||
'port' => env('DB_PORT', '3306'),
|
'port' => env('DB_PORT', '3306'),
|
||||||
'database' => 'main',
|
'database' => 'main',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue