From a21189ad8077bba250625d4ca5ef87893f948e7c Mon Sep 17 00:00:00 2001 From: Ollie Read Date: Tue, 19 Nov 2024 12:56:49 +0000 Subject: [PATCH] test: Add unit test for the database tenant provider --- tests/Unit/Providers/DatabaseProviderTest.php | 120 ++++++++++++++++ workbench/app/CustomTenantEntity.php | 131 ++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 tests/Unit/Providers/DatabaseProviderTest.php create mode 100644 workbench/app/CustomTenantEntity.php diff --git a/tests/Unit/Providers/DatabaseProviderTest.php b/tests/Unit/Providers/DatabaseProviderTest.php new file mode 100644 index 0000000..3ac615e --- /dev/null +++ b/tests/Unit/Providers/DatabaseProviderTest.php @@ -0,0 +1,120 @@ +set('multitenancy.providers.tenants.driver', 'database'); + $config->set('multitenancy.providers.tenants.table', 'tenants'); + }); + } + + protected function withCustomTenantEntity($app): void + { + tap($app['config'], static function ($config) { + $config->set('multitenancy.providers.tenants.entity', CustomTenantEntity::class); + }); + } + + #[Test] + public function hasARegisteredName(): void + { + $provider = provider('tenants'); + + $this->assertInstanceOf(DatabaseTenantProvider::class, $provider); + $this->assertSame('tenants', $provider->getName()); + } + + #[Test] + public function hasATable(): void + { + $provider = provider('tenants'); + + $this->assertInstanceOf(DatabaseTenantProvider::class, $provider); + $this->assertSame('tenants', $provider->getTable()); + } + + #[Test] + public function hasATenantEntity(): void + { + $provider = provider('tenants'); + + $this->assertInstanceOf(DatabaseTenantProvider::class, $provider); + $this->assertSame(GenericTenant::class, $provider->getEntityClass()); + } + + #[Test] + public function retrievesTenantsByTheirIdentifier(): void + { + $provider = provider('tenants'); + + $tenantData = [ + 'name' => 'Test Tenant', + 'identifier' => 'tenant-test', + 'active' => true, + ]; + + $tenantData['id'] = DB::table('tenants')->insertGetId($tenantData); + + $found = $provider->retrieveByIdentifier($tenantData['identifier']); + + $this->assertNotNull($found); + $this->assertInstanceOf(GenericTenant::class, $found); + $this->assertSame($tenantData['identifier'], $found->getTenantIdentifier()); + $this->assertSame($tenantData['id'], $found->getTenantKey()); + + $this->assertNull($provider->retrieveByIdentifier('fake-identifier')); + } + + #[Test] + public function retrievesTenantsByTheirKey(): void + { + $provider = provider('tenants'); + + $tenantData = [ + 'name' => 'Test Tenant', + 'identifier' => 'tenant-test', + 'active' => true, + ]; + + $tenantData['id'] = DB::table('tenants')->insertGetId($tenantData); + + $found = $provider->retrieveByKey($tenantData['id']); + + $this->assertNotNull($found); + $this->assertInstanceOf(GenericTenant::class, $found); + $this->assertSame($tenantData['identifier'], $found->getTenantIdentifier()); + $this->assertSame($tenantData['id'], $found->getTenantKey()); + + $this->assertNull($provider->retrieveByKey(-999)); + } + + #[Test, DefineEnvironment('withCustomTenantEntity')] + public function canHaveCustomTenantEntity(): void + { + // This is necessary as the provider has already been resolved + sprout()->providers()->flushResolved(); + + $provider = provider('tenants'); + + $this->assertInstanceOf(DatabaseTenantProvider::class, $provider); + $this->assertSame(CustomTenantEntity::class, $provider->getEntityClass()); + } +} diff --git a/workbench/app/CustomTenantEntity.php b/workbench/app/CustomTenantEntity.php new file mode 100644 index 0000000..a566c7a --- /dev/null +++ b/workbench/app/CustomTenantEntity.php @@ -0,0 +1,131 @@ + + */ + protected array $attributes; + + /** + * Create a new generic User object. + * + * @param array $attributes + * + * @return void + */ + public function __construct(array $attributes = []) + { + $this->attributes = $attributes; + } + + /** + * Get the tenant identifier + * + * Retrieve the identifier used to publicly identify the tenant. + * + * @return string + */ + public function getTenantIdentifier(): string + { + /** @phpstan-ignore-next-line */ + return $this->attributes[$this->getTenantIdentifierName()]; + } + + /** + * Get the name of the tenant identifier + * + * Retrieve the storage name for the tenant identifier, whether that's an + * attribute, column name, array key or something else. + * Used primarily by {@see \Sprout\Contracts\TenantProvider}. + * + * @return string + */ + public function getTenantIdentifierName(): string + { + return 'identifier'; + } + + /** + * Get the tenant key + * + * Retrieve the key used to identify a tenant internally. + * + * @return int|string + */ + public function getTenantKey(): int|string + { + /** @phpstan-ignore-next-line */ + return $this->attributes[$this->getTenantKeyName()]; + } + + /** + * Get the name of the tenant key + * + * Retrieve the storage name for the tenant key, whether that's an + * attribute, column name, array key or something else. + * Used primarily by {@see \Sprout\Contracts\TenantProvider}. + * + * @return string + */ + public function getTenantKeyName(): string + { + return 'id'; + } + + /** + * Dynamically access the tenant's attributes. + * + * @param string $key + * + * @return mixed + */ + public function __get(string $key): mixed + { + return $this->attributes[$key]; + } + + /** + * Dynamically set an attribute on the tenant. + * + * @param string $key + * @param mixed $value + * + * @return void + */ + public function __set(string $key, mixed $value): void + { + $this->attributes[$key] = $value; + } + + /** + * Dynamically check if a value is set on the tenant. + * + * @param string $key + * + * @return bool + */ + public function __isset(string $key): bool + { + return isset($this->attributes[$key]); + } + + /** + * Dynamically unset a value on the tenant. + * + * @param string $key + * + * @return void + */ + public function __unset(string $key): void + { + unset($this->attributes[$key]); + } +}