count())->toBe(1); Tenant::onlyPending()->first()->update([ 'pending_since' => null ]); expect(Tenant::onlyPending()->count())->toBe(0); }); test('pending trait adds query scopes', function () { Tenant::createPending(); Tenant::create(); Tenant::create(); expect(Tenant::onlyPending()->count())->toBe(1) ->and(Tenant::withPending(true)->count())->toBe(3) ->and(Tenant::withPending(false)->count())->toBe(2) ->and(Tenant::withoutPending()->count())->toBe(2); }); test('pending tenants can be created and deleted using commands', function () { config(['tenancy.pending.count' => 4]); Artisan::call(CreatePendingTenants::class); expect(Tenant::onlyPending()->count())->toBe(4); Artisan::call(ClearPendingTenants::class); expect(Tenant::onlyPending()->count())->toBe(0); }); test('CreatePendingTenants command can have an older than constraint', function () { config(['tenancy.pending.count' => 2]); Artisan::call(CreatePendingTenants::class); tenancy()->model()->query()->onlyPending()->first()->update([ 'pending_since' => now()->subDays(5)->timestamp ]); Artisan::call('tenants:pending-clear --older-than-days=2'); expect(Tenant::onlyPending()->count())->toBe(1); }); test('CreatePendingTenants command cannot run with both time constraints', function () { pest()->artisan('tenants:pending-clear --older-than-days=2 --older-than-hours=2') ->assertFailed(); }); test('CreatePendingTenants commands all option overrides any config constraints', function () { Tenant::createPending(); Tenant::createPending(); tenancy()->model()->query()->onlyPending()->first()->update([ 'pending_since' => now()->subDays(10) ]); config(['tenancy.pending.older_than_days' => 4]); Artisan::call(ClearPendingTenants::class, [ '--all' => true ]); expect(Tenant::onlyPending()->count())->toBe(0); }); test('tenancy can check for pending tenants', function () { Tenant::query()->delete(); expect(Tenant::onlyPending()->exists())->toBeFalse(); Tenant::createPending(); expect(Tenant::onlyPending()->exists())->toBeTrue(); }); test('tenancy can pull a pending tenant', function () { expect(Tenant::pullPendingTenant())->toBeNull(); Tenant::createPending(); expect(Tenant::pullPendingTenant(true))->toBeInstanceOf(Tenant::class); }); test('tenancy can create if none are pending', function () { expect(Tenant::all()->count())->toBe(0); Tenant::pullPendingTenant(true); expect(Tenant::all()->count())->toBe(1); }); test('the include in queries global scope can include pending tenants in all queries', function () { Tenant::createPending(); config(['tenancy.pending.include_in_queries' => false]); expect(Tenant::all()->count())->toBe(0); config(['tenancy.pending.include_in_queries' => true]); expect(Tenant::all()->count())->toBe(1); Tenant::all(); }); test('pending events are dispatched', function () { Event::fake([ CreatingPendingTenant::class, PendingTenantCreated::class, PullingPendingTenant::class, PendingTenantPulled::class, ]); Tenant::createPending(); Event::assertDispatched(CreatingPendingTenant::class); Event::assertDispatched(PendingTenantCreated::class); Tenant::pullPendingTenant(); Event::assertDispatched(PullingPendingTenant::class); Event::assertDispatched(PendingTenantPulled::class); });