mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 13:54:03 +00:00
Change default tenant model, write more tests, cleanup
This commit is contained in:
parent
c32f229dd5
commit
de53b81c0e
33 changed files with 210 additions and 90 deletions
|
|
@ -2,11 +2,12 @@
|
||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use Stancl\Tenancy\Contracts\Tenant;
|
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
use Stancl\Tenancy\Listeners\JobPipeline;
|
||||||
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
use Stancl\Tenancy\Events\DatabaseCreated;
|
use Stancl\Tenancy\Events\DatabaseCreated;
|
||||||
use Stancl\Tenancy\Events\DatabaseDeleted;
|
use Stancl\Tenancy\Events\DatabaseDeleted;
|
||||||
use Stancl\Tenancy\Events\DatabaseMigrated;
|
use Stancl\Tenancy\Events\DatabaseMigrated;
|
||||||
|
|
@ -20,7 +21,6 @@ use Stancl\Tenancy\Events\RevertedToCentralContext;
|
||||||
use Stancl\Tenancy\Events\TenancyBootstrapped;
|
use Stancl\Tenancy\Events\TenancyBootstrapped;
|
||||||
use Stancl\Tenancy\Events\TenancyEnded;
|
use Stancl\Tenancy\Events\TenancyEnded;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Events\TenantDeleted;
|
use Stancl\Tenancy\Events\TenantDeleted;
|
||||||
use Stancl\Tenancy\Events\TenantSaved;
|
use Stancl\Tenancy\Events\TenantSaved;
|
||||||
|
|
@ -29,9 +29,6 @@ use Stancl\Tenancy\Jobs\CreateDatabase;
|
||||||
use Stancl\Tenancy\Jobs\DeleteDatabase;
|
use Stancl\Tenancy\Jobs\DeleteDatabase;
|
||||||
use Stancl\Tenancy\Jobs\MigrateDatabase;
|
use Stancl\Tenancy\Jobs\MigrateDatabase;
|
||||||
use Stancl\Tenancy\Jobs\SeedDatabase;
|
use Stancl\Tenancy\Jobs\SeedDatabase;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
|
||||||
use Stancl\Tenancy\Tenancy;
|
|
||||||
|
|
||||||
class TenancyServiceProvider extends ServiceProvider
|
class TenancyServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
|
|
@ -49,7 +46,7 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
])->send(function (TenantCreated $event) {
|
])->send(function (TenantCreated $event) {
|
||||||
return $event->tenant;
|
return $event->tenant;
|
||||||
})->queue(false), // `false` by default, but you probably want to make this `true` for production.
|
})->shouldBeQueued(false), // `false` by default, but you probably want to make this `true` for production.
|
||||||
],
|
],
|
||||||
TenantSaved::class => [],
|
TenantSaved::class => [],
|
||||||
TenantUpdated::class => [],
|
TenantUpdated::class => [],
|
||||||
|
|
@ -58,7 +55,7 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
DeleteDatabase::class,
|
DeleteDatabase::class,
|
||||||
])->send(function (TenantDeleted $event) {
|
])->send(function (TenantDeleted $event) {
|
||||||
return $event->tenant;
|
return $event->tenant;
|
||||||
})->queue(false), // `false` by default, but you probably want to make this `true` for production.
|
})->shouldBeQueued(false), // `false` by default, but you probably want to make this `true` for production.
|
||||||
],
|
],
|
||||||
|
|
||||||
DomainCreated::class => [],
|
DomainCreated::class => [],
|
||||||
|
|
@ -87,30 +84,7 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
public function register()
|
public function register()
|
||||||
{
|
{
|
||||||
// Make sure Tenancy is stateful.
|
//
|
||||||
$this->app->singleton(Tenancy::class);
|
|
||||||
|
|
||||||
// Make sure features are bootstrapped as soon as Tenancy is instantiated.
|
|
||||||
$this->app->extend(Tenancy::class, function (Tenancy $tenancy) {
|
|
||||||
foreach ($this->app['config']['tenancy.features'] as $feature) {
|
|
||||||
$this->app[$feature]->bootstrap($tenancy);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $tenancy;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Make it possible to inject the current tenant by typehinting the Tenant contract.
|
|
||||||
$this->app->bind(Tenant::class, function ($app) {
|
|
||||||
return $app[Tenancy::class]->tenant;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Make sure bootstrappers are stateful (singletons).
|
|
||||||
foreach ($this->app['config']['tenancy.bootstrappers'] as $bootstrapper) {
|
|
||||||
$this->app->singleton($bootstrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind the class in the tenancy.id_generator config to the UniqueIdentifierGenerator abstract.
|
|
||||||
$this->app->bind(UniqueIdentifierGenerator::class, $this->app['config']['tenancy.id_generator']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function boot()
|
public function boot()
|
||||||
|
|
@ -138,8 +112,7 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
$this->app->booted(function () {
|
$this->app->booted(function () {
|
||||||
if (file_exists(base_path('routes/tenant.php'))) {
|
if (file_exists(base_path('routes/tenant.php'))) {
|
||||||
Route::middleware(['web'])
|
Route::namespace($this->app['config']['tenancy.tenant_route_namespace'] ?? 'App\Http\Controllers')
|
||||||
->namespace($this->app['config']['tenancy.tenant_route_namespace'] ?? 'App\Http\Controllers')
|
|
||||||
->group(base_path('routes/tenant.php'));
|
->group(base_path('routes/tenant.php'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Stancl\Tenancy\Middleware\InitializeTenancyByDomain;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Tenant Routes
|
| Tenant Routes
|
||||||
|
|
@ -14,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::group([
|
Route::group([
|
||||||
'middleware' => InitializeTenancyByDomain::class,
|
'middleware' => ['web', InitializeTenancyByDomain::class],
|
||||||
'prefix' => '/app',
|
'prefix' => '/app',
|
||||||
], function () {
|
], function () {
|
||||||
Route::get('/', function () {
|
Route::get('/', function () {
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@ class Install extends Command
|
||||||
$this->info('Found routes/tenant.php.');
|
$this->info('Found routes/tenant.php.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo tenancy SP stub
|
$this->callSilent('vendor:publish', [
|
||||||
|
'--provider' => 'Stancl\Tenancy\TenancyServiceProvider',
|
||||||
|
'--tag' => 'provider',
|
||||||
|
]);
|
||||||
|
$this->info('✔️ Created TenancyServiceProvider.php');
|
||||||
|
|
||||||
$this->callSilent('vendor:publish', [
|
$this->callSilent('vendor:publish', [
|
||||||
'--provider' => 'Stancl\Tenancy\TenancyServiceProvider',
|
'--provider' => 'Stancl\Tenancy\TenancyServiceProvider',
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Stancl\Tenancy\Database\Concerns;
|
namespace Stancl\Tenancy\Database\Concerns;
|
||||||
|
|
||||||
trait HasADataColumn
|
trait HasDataColumn
|
||||||
{
|
{
|
||||||
public static $priorityListeners = [];
|
public static $priorityListeners = [];
|
||||||
|
|
||||||
|
|
@ -13,9 +13,9 @@ trait HasADataColumn
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $dataEncodingStatus = 'decoded'; // todo write tests for this
|
public $dataEncodingStatus = 'decoded';
|
||||||
|
|
||||||
public static function bootHasADataColumn()
|
public static function bootHasDataColumn()
|
||||||
{
|
{
|
||||||
$encode = function (self $model) {
|
$encode = function (self $model) {
|
||||||
if ($model->dataEncodingStatus === 'encoded') {
|
if ($model->dataEncodingStatus === 'encoded') {
|
||||||
16
src/Database/Concerns/HasDatabase.php
Normal file
16
src/Database/Concerns/HasDatabase.php
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Database\Concerns;
|
||||||
|
|
||||||
|
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
||||||
|
use Stancl\Tenancy\DatabaseConfig;
|
||||||
|
|
||||||
|
trait HasDatabase
|
||||||
|
{
|
||||||
|
public function database(): DatabaseConfig
|
||||||
|
{
|
||||||
|
/** @var TenantWithDatabase $this */
|
||||||
|
|
||||||
|
return new DatabaseConfig($this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,6 @@ namespace Stancl\Tenancy\Database\Models;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Stancl\Tenancy\DatabaseConfig;
|
|
||||||
use Stancl\Tenancy\Events;
|
use Stancl\Tenancy\Events;
|
||||||
use Stancl\Tenancy\Contracts;
|
use Stancl\Tenancy\Contracts;
|
||||||
use Stancl\Tenancy\Database\Concerns;
|
use Stancl\Tenancy\Database\Concerns;
|
||||||
|
|
@ -15,14 +14,13 @@ use Stancl\Tenancy\Database\Concerns;
|
||||||
* @property Carbon $updated_at
|
* @property Carbon $updated_at
|
||||||
* @property array $data
|
* @property array $data
|
||||||
*/
|
*/
|
||||||
class Tenant extends Model implements Contracts\TenantWithDatabase // todo base model that isn't TenantWithDatabase & domains
|
class Tenant extends Model implements Contracts\Tenant
|
||||||
{
|
{
|
||||||
use Concerns\CentralConnection,
|
use Concerns\CentralConnection,
|
||||||
Concerns\HasADataColumn,
|
Concerns\HasDataColumn,
|
||||||
Concerns\GeneratesIds,
|
Concerns\GeneratesIds,
|
||||||
Concerns\HasADataColumn,
|
Concerns\HasDataColumn {
|
||||||
Concerns\HasDomains {
|
Concerns\HasDataColumn::getCasts as dataColumnCasts;
|
||||||
Concerns\HasADataColumn::getCasts as dataColumnCasts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $table = 'tenants';
|
protected $table = 'tenants';
|
||||||
|
|
@ -69,11 +67,6 @@ class Tenant extends Model implements Contracts\TenantWithDatabase // todo base
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function database(): DatabaseConfig
|
|
||||||
{
|
|
||||||
return new DatabaseConfig($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function run(callable $callback)
|
public function run(callable $callback)
|
||||||
{
|
{
|
||||||
$originalTenant = tenant();
|
$originalTenant = tenant();
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,17 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Stancl\Tenancy;
|
namespace Stancl\Tenancy;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Stancl\Tenancy\Contracts\ManagesDatabaseUsers;
|
use Stancl\Tenancy\Contracts\ManagesDatabaseUsers;
|
||||||
use Stancl\Tenancy\Contracts\TenantDatabaseManager;
|
use Stancl\Tenancy\Contracts\TenantDatabaseManager;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
|
||||||
use Stancl\Tenancy\Exceptions\DatabaseManagerNotRegisteredException;
|
use Stancl\Tenancy\Exceptions\DatabaseManagerNotRegisteredException;
|
||||||
|
use Stancl\Tenancy\Contracts\TenantWithDatabase as Tenant;
|
||||||
|
|
||||||
class DatabaseConfig
|
class DatabaseConfig
|
||||||
{
|
{
|
||||||
/** @var Tenant */
|
/** @var Tenant|Model */
|
||||||
public $tenant;
|
public $tenant;
|
||||||
|
|
||||||
/** @var callable */
|
/** @var callable */
|
||||||
|
|
@ -90,6 +91,10 @@ class DatabaseConfig
|
||||||
$this->tenant->setInternal('db_username', $this->getUsername() ?? (static::$usernameGenerator)($this->tenant));
|
$this->tenant->setInternal('db_username', $this->getUsername() ?? (static::$usernameGenerator)($this->tenant));
|
||||||
$this->tenant->setInternal('db_password', $this->getPassword() ?? (static::$passwordGenerator)($this->tenant));
|
$this->tenant->setInternal('db_password', $this->getPassword() ?? (static::$passwordGenerator)($this->tenant));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->tenant->exists) {
|
||||||
|
$this->tenant->save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTemplateConnectionName(): string
|
public function getTemplateConnectionName(): string
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class DatabaseManager
|
||||||
* @throws DatabaseManagerNotRegisteredException
|
* @throws DatabaseManagerNotRegisteredException
|
||||||
* @throws TenantDatabaseAlreadyExistsException
|
* @throws TenantDatabaseAlreadyExistsException
|
||||||
*/
|
*/
|
||||||
public function ensureTenantCanBeCreated(TenantWithDatabase $tenant): void // todo do we need this?
|
public function ensureTenantCanBeCreated(TenantWithDatabase $tenant): void
|
||||||
{
|
{
|
||||||
if ($tenant->database()->manager()->databaseExists($database = $tenant->database()->getName())) {
|
if ($tenant->database()->manager()->databaseExists($database = $tenant->database()->getName())) {
|
||||||
throw new TenantDatabaseAlreadyExistsException($database);
|
throw new TenantDatabaseAlreadyExistsException($database);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
||||||
use Stancl\Tenancy\Contracts\Tenant;
|
use Stancl\Tenancy\Contracts\Tenant;
|
||||||
|
use Stancl\Tenancy\DatabaseManager;
|
||||||
use Stancl\Tenancy\Events\DatabaseCreated;
|
use Stancl\Tenancy\Events\DatabaseCreated;
|
||||||
|
|
||||||
class CreateDatabase implements ShouldQueue
|
class CreateDatabase implements ShouldQueue
|
||||||
|
|
@ -26,9 +27,10 @@ class CreateDatabase implements ShouldQueue
|
||||||
$this->tenant = $tenant;
|
$this->tenant = $tenant;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle()
|
public function handle(DatabaseManager $databaseManager)
|
||||||
{
|
{
|
||||||
if ($this->tenant->getInternal('create_database') !== false) {
|
if ($this->tenant->getInternal('create_database') !== false) {
|
||||||
|
$databaseManager->ensureTenantCanBeCreated($this->tenant);
|
||||||
$this->tenant->database()->makeCredentials();
|
$this->tenant->database()->makeCredentials();
|
||||||
$this->tenant->database()->manager()->createDatabase($this->tenant);
|
$this->tenant->database()->manager()->createDatabase($this->tenant);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
class JobPipeline implements ShouldQueue
|
class JobPipeline implements ShouldQueue
|
||||||
{
|
{
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
public static $queueByDefault = false;
|
public static $shouldBeQueuedByDefault = false;
|
||||||
|
|
||||||
/** @var callable[]|string[] */
|
/** @var callable[]|string[] */
|
||||||
public $jobs;
|
public $jobs;
|
||||||
|
|
@ -22,16 +22,16 @@ class JobPipeline implements ShouldQueue
|
||||||
public $passable;
|
public $passable;
|
||||||
|
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
public $queue;
|
public $shouldBeQueued;
|
||||||
|
|
||||||
public function __construct($jobs, callable $send = null, bool $queue = null)
|
public function __construct($jobs, callable $send = null, bool $shouldBeQueued = null)
|
||||||
{
|
{
|
||||||
$this->jobs = $jobs;
|
$this->jobs = $jobs;
|
||||||
$this->send = $send ?? function ($event) {
|
$this->send = $send ?? function ($event) {
|
||||||
// If no $send callback is set, we'll just pass the event through the jobs.
|
// If no $send callback is set, we'll just pass the event through the jobs.
|
||||||
return $event;
|
return $event;
|
||||||
};
|
};
|
||||||
$this->queue = $queue ?? static::$queueByDefault;
|
$this->shouldBeQueued = $shouldBeQueued ?? static::$shouldBeQueuedByDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param callable[]|string[] $jobs */
|
/** @param callable[]|string[] $jobs */
|
||||||
|
|
@ -47,9 +47,9 @@ class JobPipeline implements ShouldQueue
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function queue(bool $queue)
|
public function shouldBeQueued(bool $shouldBeQueued)
|
||||||
{
|
{
|
||||||
$this->queue = $queue;
|
$this->shouldBeQueued = $shouldBeQueued;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +69,7 @@ class JobPipeline implements ShouldQueue
|
||||||
return function (...$args) {
|
return function (...$args) {
|
||||||
$executable = $this->executable($args);
|
$executable = $this->executable($args);
|
||||||
|
|
||||||
if ($this->queue) {
|
if ($this->shouldBeQueued) {
|
||||||
dispatch($executable);
|
dispatch($executable);
|
||||||
} else {
|
} else {
|
||||||
dispatch_now($executable);
|
dispatch_now($executable);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy;
|
namespace Stancl\Tenancy;
|
||||||
|
|
||||||
use Illuminate\Cache\CacheManager;
|
use Illuminate\Cache\CacheManager;
|
||||||
use Illuminate\Queue\Events\JobProcessing;
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Stancl\Tenancy\TenancyBootstrappers\FilesystemTenancyBootstrapper;
|
use Stancl\Tenancy\TenancyBootstrappers\FilesystemTenancyBootstrapper;
|
||||||
use Stancl\Tenancy\Contracts\Tenant;
|
use Stancl\Tenancy\Contracts\Tenant;
|
||||||
|
|
@ -23,6 +22,31 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
$this->app->singleton(DatabaseManager::class);
|
$this->app->singleton(DatabaseManager::class);
|
||||||
|
|
||||||
|
// Make sure Tenancy is stateful.
|
||||||
|
$this->app->singleton(Tenancy::class);
|
||||||
|
|
||||||
|
// Make sure features are bootstrapped as soon as Tenancy is instantiated.
|
||||||
|
$this->app->extend(Tenancy::class, function (Tenancy $tenancy) {
|
||||||
|
foreach ($this->app['config']['tenancy.features'] as $feature) {
|
||||||
|
$this->app[$feature]->bootstrap($tenancy);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tenancy;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make it possible to inject the current tenant by typehinting the Tenant contract.
|
||||||
|
$this->app->bind(Tenant::class, function ($app) {
|
||||||
|
return $app[Tenancy::class]->tenant;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make sure bootstrappers are stateful (singletons).
|
||||||
|
foreach ($this->app['config']['tenancy.bootstrappers'] as $bootstrapper) {
|
||||||
|
$this->app->singleton($bootstrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind the class in the tenancy.id_generator config to the UniqueIdentifierGenerator abstract.
|
||||||
|
$this->app->bind(Contracts\UniqueIdentifierGenerator::class, $this->app['config']['tenancy.id_generator']);
|
||||||
|
|
||||||
$this->app->singleton(Commands\Migrate::class, function ($app) {
|
$this->app->singleton(Commands\Migrate::class, function ($app) {
|
||||||
return new Commands\Migrate($app['migrator'], $app[DatabaseManager::class]);
|
return new Commands\Migrate($app['migrator'], $app[DatabaseManager::class]);
|
||||||
});
|
});
|
||||||
|
|
@ -63,6 +87,10 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
__DIR__ . '/../assets/migrations/' => database_path('migrations'),
|
__DIR__ . '/../assets/migrations/' => database_path('migrations'),
|
||||||
], 'migrations');
|
], 'migrations');
|
||||||
|
|
||||||
|
$this->publishes([
|
||||||
|
__DIR__ . '/../assets/TenancyServiceProvider.stub.php' => app_path('Providers/TenancyServiceProvider.php'),
|
||||||
|
], 'migrations');
|
||||||
|
|
||||||
$this->loadRoutesFrom(__DIR__ . '/routes.php');
|
$this->loadRoutesFrom(__DIR__ . '/routes.php');
|
||||||
|
|
||||||
$this->app->singleton('globalUrl', function ($app) {
|
$this->app->singleton('globalUrl', function ($app) {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ class SQLiteDatabaseManager implements TenantDatabaseManager
|
||||||
public function createDatabase(TenantWithDatabase $tenant): bool
|
public function createDatabase(TenantWithDatabase $tenant): bool
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return fclose(fopen(database_path($tenant->database()->getName()), 'w'));
|
return file_put_contents(database_path($tenant->database()->getName()), '');
|
||||||
} catch (\Throwable $th) {
|
} catch (\Throwable $th) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ namespace Stancl\Tenancy\Tests;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
|
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
use Stancl\Tenancy\Events\TenancyEnded;
|
use Stancl\Tenancy\Events\TenancyEnded;
|
||||||
|
|
@ -74,12 +74,12 @@ class AutomaticModeTest extends TestCase
|
||||||
|
|
||||||
class MyBootstrapper implements TenancyBootstrapper
|
class MyBootstrapper implements TenancyBootstrapper
|
||||||
{
|
{
|
||||||
public function start(\Stancl\Tenancy\Contracts\Tenant $tenant)
|
public function bootstrap(\Stancl\Tenancy\Contracts\Tenant $tenant)
|
||||||
{
|
{
|
||||||
app()->instance('tenancy_initialized_for_tenant', $tenant->getTenantKey());
|
app()->instance('tenancy_initialized_for_tenant', $tenant->getTenantKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function end()
|
public function revert()
|
||||||
{
|
{
|
||||||
app()->instance('tenancy_ended', true);
|
app()->instance('tenancy_ended', true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Redis;
|
use Illuminate\Support\Facades\Redis;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\Tenancy\Listeners\JobPipeline;
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy\Tests;
|
namespace Stancl\Tenancy\Tests;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\TenancyBootstrappers\CacheTenancyBootstrapper;
|
use Stancl\Tenancy\TenancyBootstrappers\CacheTenancyBootstrapper;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
use Stancl\Tenancy\Tests\Etc\ExampleSeeder;
|
use Stancl\Tenancy\Tests\Etc\ExampleSeeder;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\Tenancy\Listeners\JobPipeline;
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
|
|
@ -154,6 +154,7 @@ class CommandsTest extends TestCase
|
||||||
$this->artisan('tenancy:install');
|
$this->artisan('tenancy:install');
|
||||||
$this->assertFileExists(base_path('routes/tenant.php'));
|
$this->assertFileExists(base_path('routes/tenant.php'));
|
||||||
$this->assertFileExists(base_path('config/tenancy.php'));
|
$this->assertFileExists(base_path('config/tenancy.php'));
|
||||||
|
$this->assertFileExists(app_path('Providers/TenancyServiceProvider.php'));
|
||||||
$this->assertFileExists(database_path('migrations/2019_09_15_000010_create_tenants_table.php'));
|
$this->assertFileExists(database_path('migrations/2019_09_15_000010_create_tenants_table.php'));
|
||||||
$this->assertFileExists(database_path('migrations/2019_09_15_000020_create_domains_table.php'));
|
$this->assertFileExists(database_path('migrations/2019_09_15_000020_create_domains_table.php'));
|
||||||
$this->assertDirectoryExists(database_path('migrations/tenant'));
|
$this->assertDirectoryExists(database_path('migrations/tenant'));
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use Illuminate\Foundation\Auth\User as Authenticable;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\Tenancy\Listeners\JobPipeline;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Jobs\CreateDatabase;
|
use Stancl\Tenancy\Jobs\CreateDatabase;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use Stancl\Tenancy\Contracts\ManagesDatabaseUsers;
|
||||||
use Stancl\Tenancy\Exceptions\TenantDatabaseUserAlreadyExistsException;
|
use Stancl\Tenancy\Exceptions\TenantDatabaseUserAlreadyExistsException;
|
||||||
use Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager;
|
use Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager;
|
||||||
use Stancl\Tenancy\TenantDatabaseManagers\PermissionControlledMySQLDatabaseManager;
|
use Stancl\Tenancy\TenantDatabaseManagers\PermissionControlledMySQLDatabaseManager;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\Tenancy\Listeners\JobPipeline;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
|
|
|
||||||
13
tests/Etc/Tenant.php
Normal file
13
tests/Etc/Tenant.php
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Tests\Etc;
|
||||||
|
|
||||||
|
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
||||||
|
use Stancl\Tenancy\Database\Concerns\HasDatabase;
|
||||||
|
use Stancl\Tenancy\Database\Concerns\HasDomains;
|
||||||
|
use Stancl\Tenancy\Database\Models;
|
||||||
|
|
||||||
|
class Tenant extends Models\Tenant implements TenantWithDatabase
|
||||||
|
{
|
||||||
|
use HasDatabase, HasDomains;
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Stancl\Tenancy\Tests;
|
||||||
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;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\QueueableListener;
|
use Stancl\Tenancy\Listeners\QueueableListener;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Tests\TestCase;
|
use Stancl\Tenancy\Tests\TestCase;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ namespace Stancl\Tenancy\Tests\Features;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Stancl\Tenancy\Features\CrossDomainRedirect;
|
use Stancl\Tenancy\Features\CrossDomainRedirect;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Tests\TestCase;
|
use Stancl\Tenancy\Tests\TestCase;
|
||||||
|
|
||||||
class RedirectTest extends TestCase
|
class RedirectTest extends TestCase
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy\Tests\Features;
|
namespace Stancl\Tenancy\Tests\Features;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Events\TenancyEnded;
|
use Stancl\Tenancy\Events\TenancyEnded;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Features\TenantConfig;
|
use Stancl\Tenancy\Features\TenantConfig;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ namespace Stancl\Tenancy\Tests;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Stancl\Tenancy\Facades\GlobalCache;
|
use Stancl\Tenancy\Facades\GlobalCache;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\TenancyBootstrappers\CacheTenancyBootstrapper;
|
use Stancl\Tenancy\TenancyBootstrappers\CacheTenancyBootstrapper;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Stancl\Tenancy\Tests;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Queue;
|
use Illuminate\Support\Facades\Queue;
|
||||||
use Spatie\Valuestore\Valuestore;
|
use Spatie\Valuestore\Valuestore;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\Tenancy\Listeners\JobPipeline;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Tests\TestCase;
|
use Stancl\Tenancy\Tests\TestCase;
|
||||||
|
|
@ -51,7 +51,7 @@ class JobPipelineTest extends TestCase
|
||||||
FooJob::class,
|
FooJob::class,
|
||||||
])->send(function () {
|
])->send(function () {
|
||||||
return $this->valuestore;
|
return $this->valuestore;
|
||||||
})->queue(true)->toListener());
|
})->shouldBeQueued(true)->toListener());
|
||||||
|
|
||||||
Queue::assertNothingPushed();
|
Queue::assertNothingPushed();
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ class JobPipelineTest extends TestCase
|
||||||
FooJob::class,
|
FooJob::class,
|
||||||
])->send(function () {
|
])->send(function () {
|
||||||
return $this->valuestore;
|
return $this->valuestore;
|
||||||
})->queue(true)->toListener());
|
})->shouldBeQueued(true)->toListener());
|
||||||
|
|
||||||
$this->assertFalse($this->valuestore->has('foo'));
|
$this->assertFalse($this->valuestore->has('foo'));
|
||||||
Tenant::create();
|
Tenant::create();
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
namespace Stancl\Tenancy\Tests;
|
namespace Stancl\Tenancy\Tests;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Exceptions\RouteIsMissingTenantParameterException;
|
use Stancl\Tenancy\Exceptions\RouteIsMissingTenantParameterException;
|
||||||
use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedByPathException;
|
use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedByPathException;
|
||||||
use Stancl\Tenancy\Middleware\InitializeTenancyByPath;
|
use Stancl\Tenancy\Middleware\InitializeTenancyByPath;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Spatie\Valuestore\Valuestore;
|
use Spatie\Valuestore\Valuestore;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\TenancyBootstrappers\QueueTenancyBootstrapper;
|
use Stancl\Tenancy\TenancyBootstrappers\QueueTenancyBootstrapper;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy\Tests;
|
namespace Stancl\Tenancy\Tests;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Middleware\InitializeTenancyByRequestData;
|
use Stancl\Tenancy\Middleware\InitializeTenancyByRequestData;
|
||||||
use Stancl\Tenancy\Tests\TestCase;
|
use Stancl\Tenancy\Tests\TestCase;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ use Stancl\Tenancy\Contracts\Syncable;
|
||||||
use Stancl\Tenancy\Contracts\SyncMaster;
|
use Stancl\Tenancy\Contracts\SyncMaster;
|
||||||
use Stancl\Tenancy\Database\Concerns\CentralConnection;
|
use Stancl\Tenancy\Database\Concerns\CentralConnection;
|
||||||
use Stancl\Tenancy\Database\Concerns\ResourceSyncing;
|
use Stancl\Tenancy\Database\Concerns\ResourceSyncing;
|
||||||
use Stancl\Tenancy\Database\Models;
|
|
||||||
use Stancl\Tenancy\Database\Models\TenantPivot;
|
use Stancl\Tenancy\Database\Models\TenantPivot;
|
||||||
|
use Stancl\Tenancy\DatabaseConfig;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\Tenancy\Listeners\JobPipeline;
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
|
|
@ -25,7 +25,9 @@ use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Exceptions\ModelNotSyncMaster;
|
use Stancl\Tenancy\Exceptions\ModelNotSyncMaster;
|
||||||
use Stancl\Tenancy\Jobs\CreateDatabase;
|
use Stancl\Tenancy\Jobs\CreateDatabase;
|
||||||
use Stancl\Tenancy\TenancyBootstrappers\DatabaseTenancyBootstrapper;
|
use Stancl\Tenancy\TenancyBootstrappers\DatabaseTenancyBootstrapper;
|
||||||
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Tests\TestCase;
|
use Stancl\Tenancy\Tests\TestCase;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class ResourceSyncingTest extends TestCase
|
class ResourceSyncingTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
@ -41,6 +43,10 @@ class ResourceSyncingTest extends TestCase
|
||||||
return $event->tenant;
|
return $event->tenant;
|
||||||
})->toListener());
|
})->toListener());
|
||||||
|
|
||||||
|
DatabaseConfig::generateDatabaseNamesUsing(function () {
|
||||||
|
return 'db' . Str::random(16);
|
||||||
|
});
|
||||||
|
|
||||||
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
|
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
|
||||||
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
|
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
|
||||||
|
|
||||||
|
|
@ -568,7 +574,7 @@ class ResourceSyncingTest extends TestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResourceTenant extends Models\Tenant
|
class ResourceTenant extends Tenant
|
||||||
{
|
{
|
||||||
public function users()
|
public function users()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,10 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy\Tests;
|
namespace Stancl\Tenancy\Tests;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Stancl\Tenancy\Controllers\TenantAssetsController;
|
use Stancl\Tenancy\Controllers\TenantAssetsController;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Middleware\InitializeTenancyByDomain;
|
use Stancl\Tenancy\Middleware\InitializeTenancyByDomain;
|
||||||
|
|
@ -17,6 +18,19 @@ use Stancl\Tenancy\Tests\TestCase;
|
||||||
|
|
||||||
class TenantAssetTest extends TestCase
|
class TenantAssetTest extends TestCase
|
||||||
{
|
{
|
||||||
|
public function getEnvironmentSetUp($app)
|
||||||
|
{
|
||||||
|
parent::getEnvironmentSetUp($app);
|
||||||
|
|
||||||
|
$app->booted(function () {
|
||||||
|
if (file_exists(base_path('routes/tenant.php'))) {
|
||||||
|
Route::middleware(['web'])
|
||||||
|
->namespace($this->app['config']['tenancy.tenant_route_namespace'] ?? 'App\Http\Controllers')
|
||||||
|
->group(base_path('routes/tenant.php'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public function setUp(): void
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ namespace Stancl\Tenancy\Tests;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Tests\TestCase;
|
use Stancl\Tenancy\Tests\TestCase;
|
||||||
|
|
||||||
class TenantAwareCommandTest extends TestCase
|
class TenantAwareCommandTest extends TestCase
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,13 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy\Tests;
|
namespace Stancl\Tenancy\Tests;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\DatabaseManager;
|
use Stancl\Tenancy\DatabaseManager;
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
use Stancl\Tenancy\Listeners\JobPipeline;
|
use Stancl\Tenancy\Listeners\JobPipeline;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
|
use Stancl\Tenancy\Exceptions\TenantDatabaseAlreadyExistsException;
|
||||||
use Stancl\Tenancy\Jobs\CreateDatabase;
|
use Stancl\Tenancy\Jobs\CreateDatabase;
|
||||||
use Stancl\Tenancy\TenancyBootstrappers\DatabaseTenancyBootstrapper;
|
use Stancl\Tenancy\TenancyBootstrappers\DatabaseTenancyBootstrapper;
|
||||||
use Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager;
|
use Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager;
|
||||||
|
|
@ -19,6 +20,7 @@ use Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLDatabaseManager;
|
||||||
use Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLSchemaManager;
|
use Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLSchemaManager;
|
||||||
use Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager;
|
use Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager;
|
||||||
use Stancl\Tenancy\Tests\TestCase;
|
use Stancl\Tenancy\Tests\TestCase;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class TenantDatabaseManagerTest extends TestCase
|
class TenantDatabaseManagerTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
@ -60,8 +62,7 @@ class TenantDatabaseManagerTest extends TestCase
|
||||||
return $event->tenant;
|
return $event->tenant;
|
||||||
})->toListener());
|
})->toListener());
|
||||||
|
|
||||||
// todo if the prefix is _tenancy_, this blows up. write a tenantmodel test that the prefix can be _tenancy_
|
config(['tenancy.internal_prefix' => 'tenancy_']);
|
||||||
config(['tenancy.internal_prefix' => 'tenancy_',]);
|
|
||||||
|
|
||||||
$database = 'db' . $this->randomString();
|
$database = 'db' . $this->randomString();
|
||||||
|
|
||||||
|
|
@ -141,4 +142,25 @@ class TenantDatabaseManagerTest extends TestCase
|
||||||
$this->assertSame($tenant->database()->getName(), config('database.connections.' . config('database.default') . '.schema'));
|
$this->assertSame($tenant->database()->getName(), config('database.connections.' . config('database.default') . '.schema'));
|
||||||
$this->assertSame($originalDatabaseName, config(['database.connections.pgsql.database']));
|
$this->assertSame($originalDatabaseName, config(['database.connections.pgsql.database']));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function a_tenants_database_cannot_be_created_when_the_database_already_exists()
|
||||||
|
{
|
||||||
|
Event::listen(TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) {
|
||||||
|
return $event->tenant;
|
||||||
|
})->toListener());
|
||||||
|
|
||||||
|
$name = 'foo' . Str::random(8);
|
||||||
|
$tenant = Tenant::create([
|
||||||
|
'tenancy_db_name' => $name,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$manager = $tenant->database()->manager();
|
||||||
|
$this->assertTrue($manager->databaseExists($tenant->database()->getName()));
|
||||||
|
|
||||||
|
$this->expectException(TenantDatabaseAlreadyExistsException::class);
|
||||||
|
$tenant2 = Tenant::create([
|
||||||
|
'tenancy_db_name' => $name,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,18 @@ use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Tests\TestCase;
|
use Stancl\Tenancy\Tests\TestCase;
|
||||||
use Stancl\Tenancy\UniqueIDGenerators\UUIDGenerator;
|
use Stancl\Tenancy\UniqueIDGenerators\UUIDGenerator;
|
||||||
use Stancl\Tenancy\Contracts;
|
use Stancl\Tenancy\Contracts;
|
||||||
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
||||||
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
|
use Stancl\Tenancy\Jobs\CreateDatabase;
|
||||||
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
|
use Stancl\Tenancy\Listeners\JobPipeline;
|
||||||
|
use Stancl\Tenancy\TenancyBootstrappers\DatabaseTenancyBootstrapper;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class TenantModelTest extends TestCase
|
class TenantModelTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
@ -132,7 +138,40 @@ class TenantModelTest extends TestCase
|
||||||
$this->assertTrue(tenant() instanceof AnotherTenant);
|
$this->assertTrue(tenant() instanceof AnotherTenant);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo test that tenant can be created even in another DB context - that the central trait works
|
/** @test */
|
||||||
|
public function tenant_can_be_created_even_when_we_are_in_another_tenants_context()
|
||||||
|
{
|
||||||
|
config(['tenancy.bootstrappers' => [
|
||||||
|
DatabaseTenancyBootstrapper::class
|
||||||
|
]]);
|
||||||
|
|
||||||
|
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
|
||||||
|
Event::listen(TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function ($event) {
|
||||||
|
return $event->tenant;
|
||||||
|
})->toListener());
|
||||||
|
|
||||||
|
$tenant1 = Tenant::create([
|
||||||
|
'id' => 'foo',
|
||||||
|
'tenancy_db_name' => 'db' . Str::random(16),
|
||||||
|
]);
|
||||||
|
|
||||||
|
tenancy()->initialize($tenant1);
|
||||||
|
|
||||||
|
$tenant2 = Tenant::create([
|
||||||
|
'id' => 'bar',
|
||||||
|
'tenancy_db_name' => 'db' . Str::random(16),
|
||||||
|
]);
|
||||||
|
|
||||||
|
tenancy()->end();
|
||||||
|
|
||||||
|
$this->assertSame(2, Tenant::count());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function data_is_never_encoded_or_decoded_twice()
|
||||||
|
{
|
||||||
|
// todo. tests for registerPriorityListener
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyTenant extends Tenant
|
class MyTenant extends Tenant
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ namespace Stancl\Tenancy\Tests;
|
||||||
use Illuminate\Support\Facades\Redis;
|
use Illuminate\Support\Facades\Redis;
|
||||||
use Illuminate\Testing\Assert as PHPUnit;
|
use Illuminate\Testing\Assert as PHPUnit;
|
||||||
use Illuminate\Testing\TestResponse;
|
use Illuminate\Testing\TestResponse;
|
||||||
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
|
|
||||||
abstract class TestCase extends \Orchestra\Testbench\TestCase
|
abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
{
|
{
|
||||||
|
|
@ -83,6 +84,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
'central' => true,
|
'central' => true,
|
||||||
],
|
],
|
||||||
'tenancy.seeder_parameters' => [],
|
'tenancy.seeder_parameters' => [],
|
||||||
|
'tenancy.tenant_model' => Tenant::class, // Use test tenant w/ DBs & domains
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$app->singleton(\Stancl\Tenancy\TenancyBootstrappers\RedisTenancyBootstrapper::class);
|
$app->singleton(\Stancl\Tenancy\TenancyBootstrappers\RedisTenancyBootstrapper::class);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue