mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-05 22:44:05 +00:00
Add readied tenants
Add config for readied tenants Add `create` and `clear` command Add Readied scope and static functions Add tests
This commit is contained in:
parent
f08e33afd8
commit
065e74c9be
12 changed files with 526 additions and 2 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -35,6 +35,37 @@ return [
|
||||||
// Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper::class, // Note: phpredis is needed
|
// Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper::class, // Note: phpredis is needed
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Readied tenancy config.
|
||||||
|
* This is useful if you're looking for a way to always have a tenant ready to be used.
|
||||||
|
*/
|
||||||
|
'readied' => [
|
||||||
|
/**
|
||||||
|
* If disabled, readied tenants will be excluded from all tenant queries. Unless if
|
||||||
|
* told otherwise with ::withReadied() or ::onlyReadied().
|
||||||
|
* Note: when disabled, this will also ignore tenants when runnings any tenants commands (migration, seed, etc.)
|
||||||
|
*/
|
||||||
|
'include_in_scope' => true,
|
||||||
|
/**
|
||||||
|
* Defines how many tenants you want to be in a readied state.
|
||||||
|
* This value should be changed depending on how often a new tenant is created
|
||||||
|
* and how often you run the `tenancy:readied` command via the scheduler.
|
||||||
|
*/
|
||||||
|
'count' => env('TENANCY_READIED_COUNT', 5),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If needed, you can define a time limite after when an unused readied tenant
|
||||||
|
* will automatically be deleted.
|
||||||
|
* For this to work automatically, make sure to call the `tenancy:readied-clear` command in the scheduler.
|
||||||
|
*
|
||||||
|
* If both values are set to null, not time limit will be set and all readied tenants will be deleted.
|
||||||
|
*/
|
||||||
|
'older_than_days' => env('TENANCY_READIED_OLDER_THAN_DAYS', null),
|
||||||
|
|
||||||
|
'older_than_hours' => env('TENANCY_READIED_OLDER_THAN_HOURS', null),
|
||||||
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database tenancy config. Used by DatabaseTenancyBootstrapper.
|
* Database tenancy config. Used by DatabaseTenancyBootstrapper.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
67
src/Commands/ClearReadiedTenants.php
Normal file
67
src/Commands/ClearReadiedTenants.php
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
|
class ClearReadiedTenants extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'tenants:readied-clear
|
||||||
|
{--all : Override the default settings and deletes all readied tenants}
|
||||||
|
{--older-days= : Deletes all readied older than the amount of days}
|
||||||
|
{--older-hours= : Deletes all readied older than the amount of hours}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Removes any readied tenants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$this->info('Cleaning readied tenants.');
|
||||||
|
|
||||||
|
$expireDate = now();
|
||||||
|
// At the end, we will check if the value has been changed by comparing the two dates
|
||||||
|
$savedExpiredDate = $expireDate->copy()->toImmutable();
|
||||||
|
|
||||||
|
// If the all option is given, skip the expiry date configuration
|
||||||
|
if (! $this->option('all')) {
|
||||||
|
if ($olderThanDays = $this->option('older-days') ?? config('tenancy.readied.older_than_days')) {
|
||||||
|
$expireDate->subDays($olderThanDays);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($olderThanHours = $this->option('older-hours') ?? config('tenancy.readied.older_than_hours')) {
|
||||||
|
$expireDate->subHours($olderThanHours);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$readiedTenantsDeletedCount = tenancy()
|
||||||
|
->query()
|
||||||
|
->onlyReadied()
|
||||||
|
->when($savedExpiredDate->notEqualTo($expireDate), function (Builder $query) use ($expireDate) {
|
||||||
|
$query->where('data->readied', '<', $expireDate->timestamp);
|
||||||
|
})
|
||||||
|
->get()
|
||||||
|
->each // This makes sure the events or triggered on the model
|
||||||
|
->delete()
|
||||||
|
->count();
|
||||||
|
|
||||||
|
$this->info("$readiedTenantsDeletedCount readied tenant(s) deleted.");
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/Commands/CreateReadiedTenants.php
Normal file
62
src/Commands/CreateReadiedTenants.php
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class CreateReadiedTenants extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'tenants:readied {--count= The number of tenant to be in a readied state}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Deploy tenants until the readied count is achieved.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$this->info('Deploying readied tenants.');
|
||||||
|
|
||||||
|
$readiedCountObjectif = (int)config('tenancy.readied.count');
|
||||||
|
|
||||||
|
$readiedTenantCount = $this->getReadiedTenantCount();
|
||||||
|
|
||||||
|
$deployedCount = 0;
|
||||||
|
while ($readiedTenantCount < $readiedCountObjectif) {
|
||||||
|
tenancy()->model()::createReadied();
|
||||||
|
// We update the number of readied tenant every time with a query to get a live count.
|
||||||
|
// this prevents to deploy too many tenants if readied tenants have been deployed
|
||||||
|
// while this command is running.
|
||||||
|
$readiedTenantCount = $this->getReadiedTenantCount();
|
||||||
|
$deployedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info("$deployedCount tenants deployed, $readiedCountObjectif tenant(s) are ready to be used.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the number of readied tenants currently deployed
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function getReadiedTenantCount(): int
|
||||||
|
{
|
||||||
|
return tenancy()
|
||||||
|
->query()
|
||||||
|
->onlyReadied()
|
||||||
|
->count();
|
||||||
|
}
|
||||||
|
}
|
||||||
95
src/Database/Concerns/ReadiedScope.php
Normal file
95
src/Database/Concerns/ReadiedScope.php
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Database\Concerns;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Scope;
|
||||||
|
|
||||||
|
class ReadiedScope implements Scope
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All of the extensions to be added to the builder.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $extensions = ['WithReadied', 'WithoutReadied', 'OnlyReadied'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the scope to a given Eloquent query builder.
|
||||||
|
*
|
||||||
|
* @param Builder $builder
|
||||||
|
* @param Model $model
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function apply(Builder $builder, Model $model)
|
||||||
|
{
|
||||||
|
$builder->when(!config('tenancy.readied.include_in_scope'), function (Builder $builder){
|
||||||
|
$builder->whereNull('data->readied');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend the query builder with the needed functions.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function extend(Builder $builder)
|
||||||
|
{
|
||||||
|
foreach ($this->extensions as $extension) {
|
||||||
|
$this->{"add{$extension}"}($builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Add the with-readied extension to the builder.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function addWithReadied(Builder $builder)
|
||||||
|
{
|
||||||
|
$builder->macro('withReadied', function (Builder $builder, $withReadied = true) {
|
||||||
|
if (! $withReadied) {
|
||||||
|
return $builder->withoutReadied();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $builder->withoutGlobalScope($this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the without-readied extension to the builder.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function addWithoutReadied(Builder $builder)
|
||||||
|
{
|
||||||
|
$builder->macro('withoutReadied', function (Builder $builder) {
|
||||||
|
|
||||||
|
$builder->withoutGlobalScope($this)->whereNull('data->readied');
|
||||||
|
|
||||||
|
return $builder;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the only-readied extension to the builder.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function addOnlyReadied(Builder $builder)
|
||||||
|
{
|
||||||
|
$builder->macro('onlyReadied', function (Builder $builder) {
|
||||||
|
|
||||||
|
$builder->withoutGlobalScope($this)->whereNotNull('data->readied');
|
||||||
|
|
||||||
|
return $builder;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
79
src/Database/Concerns/WithReadied.php
Normal file
79
src/Database/Concerns/WithReadied.php
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Database\Concerns;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Stancl\Tenancy\Contracts\Tenant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property null|Carbon $readied
|
||||||
|
*
|
||||||
|
* @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withReadied(bool $withReadied = true)
|
||||||
|
* @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder onlyReadied()
|
||||||
|
* @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withoutReadied()
|
||||||
|
*/
|
||||||
|
trait WithReadied
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Boot the readied trait for a model.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function bootWithReadied()
|
||||||
|
{
|
||||||
|
static::addGlobalScope(new ReadiedScope());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the readied trait for an instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function initializeSoftDeletes()
|
||||||
|
{
|
||||||
|
$this->casts['readied'] = 'datetime';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the model instance is in a readied state.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function readied()
|
||||||
|
{
|
||||||
|
return !is_null($this->readied);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function createReadied($attributes = []): void
|
||||||
|
{
|
||||||
|
$tenant = static::create($attributes);
|
||||||
|
|
||||||
|
// We add the readied value only after the model has then been created.
|
||||||
|
// this ensures the model is not marked as readied until the migrations, seeders, etc. are done
|
||||||
|
$tenant->update([
|
||||||
|
'readied' => now()->timestamp
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function pullReadiedTenant(bool $firstOrCreate = false): ?Tenant
|
||||||
|
{
|
||||||
|
if (!static::onlyReadied()->exists()) {
|
||||||
|
if (!$firstOrCreate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
static::createReadied();
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point we can guarantee a readied tenant is free and can be called
|
||||||
|
$tenant = static::onlyReadied()->first();
|
||||||
|
|
||||||
|
$tenant->update([
|
||||||
|
'readied' => null
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $tenant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,7 +26,8 @@ class Tenant extends Model implements Contracts\Tenant
|
||||||
Concerns\HasDataColumn,
|
Concerns\HasDataColumn,
|
||||||
Concerns\HasInternalKeys,
|
Concerns\HasInternalKeys,
|
||||||
Concerns\TenantRun,
|
Concerns\TenantRun,
|
||||||
Concerns\InvalidatesResolverCache;
|
Concerns\InvalidatesResolverCache,
|
||||||
|
Concerns\WithReadied;
|
||||||
|
|
||||||
protected $table = 'tenants';
|
protected $table = 'tenants';
|
||||||
protected $primaryKey = 'id';
|
protected $primaryKey = 'id';
|
||||||
|
|
|
||||||
28
src/Jobs/ClearReadiedTenants.php
Normal file
28
src/Jobs/ClearReadiedTenants.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Jobs;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
||||||
|
|
||||||
|
class ClearReadiedTenants implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
Artisan::call('tenants:readied-clear');
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/Jobs/CreateReadiedTenants.php
Normal file
28
src/Jobs/CreateReadiedTenants.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Jobs;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
||||||
|
|
||||||
|
class CreateReadiedTenants implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
Artisan::call('tenants:readied');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -89,6 +89,8 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
Commands\Rollback::class,
|
Commands\Rollback::class,
|
||||||
Commands\TenantList::class,
|
Commands\TenantList::class,
|
||||||
Commands\MigrateFresh::class,
|
Commands\MigrateFresh::class,
|
||||||
|
Commands\CreateReadiedTenants::class,
|
||||||
|
Commands\ClearReadiedTenants::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->publishes([
|
$this->publishes([
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,10 @@ namespace Stancl\Tenancy\Tests\Etc;
|
||||||
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
||||||
use Stancl\Tenancy\Database\Concerns\HasDatabase;
|
use Stancl\Tenancy\Database\Concerns\HasDatabase;
|
||||||
use Stancl\Tenancy\Database\Concerns\HasDomains;
|
use Stancl\Tenancy\Database\Concerns\HasDomains;
|
||||||
|
use Stancl\Tenancy\Database\Concerns\WithReadied;
|
||||||
use Stancl\Tenancy\Database\Models;
|
use Stancl\Tenancy\Database\Models;
|
||||||
|
|
||||||
class Tenant extends Models\Tenant implements TenantWithDatabase
|
class Tenant extends Models\Tenant implements TenantWithDatabase
|
||||||
{
|
{
|
||||||
use HasDatabase, HasDomains;
|
use HasDatabase, HasDomains, WithReadied;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
130
tests/ReadiedTenantsTest.php
Normal file
130
tests/ReadiedTenantsTest.php
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Tests;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
use Stancl\Tenancy\Commands\ClearReadiedTenants;
|
||||||
|
use Stancl\Tenancy\Commands\CreateReadiedTenants;
|
||||||
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
|
|
||||||
|
class ReadiedTenantsTest extends TestCase
|
||||||
|
{
|
||||||
|
public function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function a_tenant_is_correctly_identified_as_readied()
|
||||||
|
{
|
||||||
|
Tenant::createReadied();
|
||||||
|
|
||||||
|
$this->assertCount(1, Tenant::onlyReadied()->get());
|
||||||
|
|
||||||
|
Tenant::onlyReadied()->first()->update([
|
||||||
|
'readied' => null
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertCount(0, Tenant::onlyReadied()->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function readied_tenants_are_created_and_deleted_from_the_commands()
|
||||||
|
{
|
||||||
|
config(['tenancy.readied.count' => 4]);
|
||||||
|
|
||||||
|
Artisan::call(CreateReadiedTenants::class);
|
||||||
|
|
||||||
|
$this->assertCount(4, Tenant::onlyReadied()->get());
|
||||||
|
|
||||||
|
Artisan::call(ClearReadiedTenants::class);
|
||||||
|
|
||||||
|
$this->assertCount(0, Tenant::onlyReadied()->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function clear_readied_tenants_command_only_delete_readied_tenants_older_than()
|
||||||
|
{
|
||||||
|
config(['tenancy.readied.count' => 2]);
|
||||||
|
|
||||||
|
Artisan::call(CreateReadiedTenants::class);
|
||||||
|
|
||||||
|
config(['tenancy.readied.older_than_days' => 4]);
|
||||||
|
|
||||||
|
tenancy()->model()->query()->onlyReadied()->first()->update([
|
||||||
|
'readied' => now()->subDays()
|
||||||
|
]);
|
||||||
|
|
||||||
|
Artisan::call(ClearReadiedTenants::class);
|
||||||
|
|
||||||
|
$this->assertCount(1, Tenant::onlyReadied()->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function clear_readied_tenants_command_all_option_overrides_config()
|
||||||
|
{
|
||||||
|
Tenant::createReadied();
|
||||||
|
Tenant::createReadied();
|
||||||
|
|
||||||
|
tenancy()->model()->query()->onlyReadied()->first()->update([
|
||||||
|
'readied' => now()->subDays(10)
|
||||||
|
]);
|
||||||
|
|
||||||
|
config(['tenancy.readied.older_than_days' => 4]);
|
||||||
|
|
||||||
|
Artisan::call(ClearReadiedTenants::class, [
|
||||||
|
'--all' => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertCount(0, Tenant::onlyReadied()->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function tenancy_can_check_for_readied_tenants()
|
||||||
|
{
|
||||||
|
Tenant::query()->delete();
|
||||||
|
|
||||||
|
$this->assertFalse(Tenant::onlyReadied()->exists());
|
||||||
|
|
||||||
|
Tenant::createReadied();
|
||||||
|
|
||||||
|
$this->assertTrue(Tenant::onlyReadied()->exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function tenancy_can_pull_a_readied_tenant()
|
||||||
|
{
|
||||||
|
$this->assertNull(Tenant::pullReadiedTenant());
|
||||||
|
|
||||||
|
Tenant::createReadied();
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Tenant::class, Tenant::pullReadiedTenant(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function tenancy_can_create_if_none_are_readied()
|
||||||
|
{
|
||||||
|
$this->assertDatabaseCount(Tenant::class, 0);
|
||||||
|
|
||||||
|
Tenant::pullReadiedTenant(true);
|
||||||
|
|
||||||
|
$this->assertDatabaseCount(Tenant::class, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function readied_tenants_global_scope_config_can_include_or_exclude()
|
||||||
|
{
|
||||||
|
Tenant::createReadied();
|
||||||
|
|
||||||
|
config(['tenancy.readied.include_in_scope' => false]);
|
||||||
|
|
||||||
|
$this->assertCount(0, Tenant::all());
|
||||||
|
|
||||||
|
config(['tenancy.readied.include_in_scope' => true]);
|
||||||
|
|
||||||
|
$this->assertCount(1, Tenant::all());
|
||||||
|
Tenant::all();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue