From d5b01219fd6fbf79b991d624b20eb1fbbc488883 Mon Sep 17 00:00:00 2001 From: Chris Brown Date: Thu, 17 Oct 2019 13:25:30 -0400 Subject: [PATCH] [2.x] Allow automatic seeding after automatic migrations (#160) --- assets/config.php | 4 +++ src/Jobs/QueuedTenantDatabaseSeeder.php | 42 +++++++++++++++++++++++++ src/TenantManager.php | 31 ++++++++++++++---- tests/TenantManagerTest.php | 42 +++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 src/Jobs/QueuedTenantDatabaseSeeder.php diff --git a/assets/config.php b/assets/config.php index a6b84e68..8c504d63 100644 --- a/assets/config.php +++ b/assets/config.php @@ -91,6 +91,10 @@ return [ 'home_url' => '/app', 'queue_database_creation' => false, 'migrate_after_creation' => false, // run migrations after creating a tenant + 'seed_after_migration' => false, // should the seeder run after automatic migration + 'seeder_parameters' => [ + '--class' => 'DatabaseSeeder', // root seeder class to run after automatic migrations, eg: 'DatabaseSeeder' + ], 'queue_database_deletion' => false, 'delete_database_after_tenant_deletion' => false, // delete the tenant's database after deleting the tenant 'unique_id_generator' => Stancl\Tenancy\UniqueIDGenerators\UUIDGenerator::class, diff --git a/src/Jobs/QueuedTenantDatabaseSeeder.php b/src/Jobs/QueuedTenantDatabaseSeeder.php new file mode 100644 index 00000000..656ae956 --- /dev/null +++ b/src/Jobs/QueuedTenantDatabaseSeeder.php @@ -0,0 +1,42 @@ +tenantId = $tenant->id; + $this->seederParameters = $seederParameters; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + Artisan::call('tenants:seed', [ + '--tenants' => [$this->tenantId], + ] + $this->seederParameters); + } +} diff --git a/src/TenantManager.php b/src/TenantManager.php index 16030245..9144d2f4 100644 --- a/src/TenantManager.php +++ b/src/TenantManager.php @@ -10,6 +10,7 @@ use Illuminate\Support\Collection; use Stancl\Tenancy\Contracts\TenantCannotBeCreatedException; use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedException; use Stancl\Tenancy\Jobs\QueuedTenantDatabaseMigrator; +use Stancl\Tenancy\Jobs\QueuedTenantDatabaseSeeder; /** * @internal Class is subject to breaking changes in minor and patch versions. @@ -67,15 +68,23 @@ class TenantManager $afterCreating = []; if ($this->shouldMigrateAfterCreation()) { - $afterCreating += $this->databaseCreationQueued() ? [ - new QueuedTenantDatabaseMigrator($tenant), - ] : [ - function () use ($tenant) { + $afterCreating[] = $this->databaseCreationQueued() + ? new QueuedTenantDatabaseMigrator($tenant) + : function () use ($tenant) { $this->artisan->call('tenants:migrate', [ '--tenants' => [$tenant['id']], ]); - }, - ]; + }; + } + + if ($this->shouldSeedAfterMigration()) { + $afterCreating[] = $this->databaseCreationQueued() + ? new QueuedTenantDatabaseSeeder($tenant, $this->getSeederParameters()) + : function () use ($tenant) { + $this->artisan->call('tenants:seed', [ + '--tenants' => [$tenant['id']], + ] + $this->getSeederParameters()); + }; } $this->database->createDatabase($tenant, $afterCreating); @@ -321,6 +330,11 @@ class TenantManager return $this->app['config']['tenancy.migrate_after_creation'] ?? false; } + public function shouldSeedAfterMigration(): bool + { + return $this->shouldMigrateAfterCreation() && $this->app['config']['tenancy.seed_after_migration'] ?? false; + } + public function databaseCreationQueued(): bool { return $this->app['config']['tenancy.queue_database_creation'] ?? false; @@ -331,6 +345,11 @@ class TenantManager return $this->app['config']['tenancy.delete_database_after_tenant_deletion'] ?? false; } + public function getSeederParameters() + { + return $this->app['config']['tenancy.seeder_parameters'] ?? []; + } + /** * Add an event listener. * diff --git a/tests/TenantManagerTest.php b/tests/TenantManagerTest.php index 64a7ac5a..f469972a 100644 --- a/tests/TenantManagerTest.php +++ b/tests/TenantManagerTest.php @@ -12,8 +12,10 @@ use Stancl\Tenancy\Exceptions\TenantDoesNotExistException; use Stancl\Tenancy\Exceptions\TenantWithThisIdAlreadyExistsException; use Stancl\Tenancy\Jobs\QueuedTenantDatabaseCreator; use Stancl\Tenancy\Jobs\QueuedTenantDatabaseMigrator; +use Stancl\Tenancy\Jobs\QueuedTenantDatabaseSeeder; use Stancl\Tenancy\Tenant; use Stancl\Tenancy\TenantManager; +use Stancl\Tenancy\Tests\Etc\ExampleSeeder; class TenantManagerTest extends TestCase { @@ -237,6 +239,27 @@ class TenantManagerTest extends TestCase $this->assertTrue(\Schema::hasTable('users')); } + /** @test */ + public function automatic_seeding_works() + { + config(['tenancy.migrate_after_creation' => true]); + + $tenant = Tenant::create(['foo.localhost']); + tenancy()->initialize($tenant); + $this->assertSame(0, \DB::table('users')->count()); + + config([ + 'tenancy.seed_after_migration' => true, + 'tenancy.seeder_parameters' => [ + '--class' => ExampleSeeder::class, + ], + ]); + + $tenant2 = Tenant::create(['bar.localhost']); + tenancy()->initialize($tenant2); + $this->assertSame(1, \DB::table('users')->count()); + } + /** @test */ public function ensureTenantCanBeCreated_works() { @@ -272,6 +295,25 @@ class TenantManagerTest extends TestCase // $this->assertTrue(\Schema::hasTable('users')); } + /** @test */ + public function autoseeding_is_queued_when_db_creation_is_queued() + { + Queue::fake(); + + config([ + 'tenancy.queue_database_creation' => true, + 'tenancy.migrate_after_creation' => true, + 'tenancy.seed_after_migration' => true, + ]); + + Tenant::new()->save(); + + Queue::assertPushedWithChain(QueuedTenantDatabaseCreator::class, [ + QueuedTenantDatabaseMigrator::class, + QueuedTenantDatabaseSeeder::class, + ]); + } + /** @test */ public function TenantDoesNotExistException_is_thrown_when_find_is_called_on_an_id_that_does_not_belong_to_any_tenant() {