Skip to content

Commit

Permalink
test: Add unit test for the database tenant provider
Browse files Browse the repository at this point in the history
  • Loading branch information
ollieread committed Nov 19, 2024
1 parent dc25c65 commit a21189a
Show file tree
Hide file tree
Showing 2 changed files with 251 additions and 0 deletions.
120 changes: 120 additions & 0 deletions tests/Unit/Providers/DatabaseProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php
declare(strict_types=1);

namespace Sprout\Tests\Unit\Providers;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Orchestra\Testbench\Attributes\DefineEnvironment;
use PHPUnit\Framework\Attributes\Test;
use Sprout\Providers\DatabaseTenantProvider;
use Sprout\Support\GenericTenant;
use Sprout\Tests\Unit\UnitTestCase;
use Workbench\App\CustomTenantEntity;
use function Sprout\provider;
use function Sprout\sprout;

class DatabaseProviderTest extends UnitTestCase
{
use RefreshDatabase;

protected function defineEnvironment($app): void
{
tap($app['config'], static function ($config) {
$config->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());
}
}
131 changes: 131 additions & 0 deletions workbench/app/CustomTenantEntity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php
declare(strict_types=1);

namespace Workbench\App;

use Sprout\Contracts\Tenant;

class CustomTenantEntity implements Tenant
{
/**
* All the tenant's attributes.
*
* @var array<string, mixed>
*/
protected array $attributes;

/**
* Create a new generic User object.
*
* @param array<string, mixed> $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]);
}
}

0 comments on commit a21189a

Please sign in to comment.