Skip to content

Commit

Permalink
chore: Few more tests and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ollieread committed Sep 9, 2024
1 parent 07fb4dc commit 45c358b
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 11 deletions.
8 changes: 0 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,13 @@
![Packagist Version](https://img.shields.io/packagist/v/sprout/sprout)
![Packagist PHP Version Support](https://img.shields.io/packagist/php-v/sprout/sprout)
![GitHub](https://img.shields.io/github/license/sprout-laravel/sprout)
![Psalm Level](https://shepherd.dev/github/sprout-laravel/sprout/level.svg)
![Laravel](https://img.shields.io/badge/laravel-10.x-red.svg)

Main:

[![codecov](https://codecov.io/gh/sprout-laravel/sprout/branch/main/graph/badge.svg?token=FHJ41NQMTA)](https://codecov.io/gh/sprout-laravel/sprout)
[![CircleCI](https://circleci.com/gh/sprout-laravel/sprout/tree/main.svg?style=shield)](https://circleci.com/gh/sprout-laravel/sprout/tree/main)
[![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fsmplphp%2Fcore%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/sprout-laravel/sprout/main)

Develop:

[![codecov](https://codecov.io/gh/sprout-laravel/sprout/branch/develop/graph/badge.svg?token=FHJ41NQMTA)](https://codecov.io/gh/sprout-laravel/sprout)
[![CircleCI](https://circleci.com/gh/sprout-laravel/sprout/tree/develop.svg?style=shield)](https://circleci.com/gh/sprout-laravel/sprout/tree/develop)
[![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fsmplphp%2Fcore%2Fdevelop)](https://dashboard.stryker-mutator.io/reports/github.com/sprout-laravel/sprout/develop)

# Sprout for Laravel
### A flexible, seamless and easy to use multitenancy solution for Laravel

Expand Down
11 changes: 10 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"require-dev" : {
"phpunit/phpunit" : "^11.0.1",
"orchestra/testbench": "^9.4",
"larastan/larastan" : "^2.9"
"larastan/larastan" : "^2.9",
"infection/infection": "^0.29.6"
},
"license" : "MIT",
"autoload" : {
Expand Down Expand Up @@ -60,6 +61,9 @@
],
"test" : [
"@php vendor/bin/phpunit"
],
"mutation" : [
"@php vendor/bin/infection"
]
},
"extra" : {
Expand All @@ -68,5 +72,10 @@
"Sprout\\SproutServiceProvider"
]
}
},
"config" : {
"allow-plugins": {
"infection/extension-installer": true
}
}
}
14 changes: 14 additions & 0 deletions infection.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "vendor/infection/infection/resources/schema.json",
"source": {
"directories": [
"src"
]
},
"logs": {
"text": "build/infection.log"
},
"mutators": {
"@default": true
}
}
8 changes: 8 additions & 0 deletions src/Database/Eloquent/Concerns/IsTenantModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ trait IsTenantModel
* Retrieve the identifier used to publicly identify the tenant.
*
* @return string
*
* @infection-ignore-all
*/
public function getTenantIdentifier(): string
{
Expand All @@ -29,6 +31,8 @@ public function getTenantIdentifier(): string
* Used primarily by {@see \Sprout\Contracts\TenantProvider}.
*
* @return string
*
* @infection-ignore-all
*/
public function getTenantIdentifierName(): string
{
Expand All @@ -41,6 +45,8 @@ public function getTenantIdentifierName(): string
* Retrieve the key used to identify a tenant internally.
*
* @return int|string
*
* @infection-ignore-all
*/
public function getTenantKey(): int|string
{
Expand All @@ -55,6 +61,8 @@ public function getTenantKey(): int|string
* Used primarily by {@see \Sprout\Contracts\TenantProvider}.
*
* @return string
*
* @infection-ignore-all
*/
public function getTenantKeyName(): string
{
Expand Down
4 changes: 2 additions & 2 deletions src/Sprout.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __construct(Application $app)
$this->app = $app;
}

public function config(string $key, mixed $default): mixed
public function config(string $key, mixed $default = null): mixed
{
return $this->app->make('config')->get('sprout.' . $key, $default);
}
Expand Down Expand Up @@ -89,7 +89,7 @@ public function contextKey(Tenancy $tenancy): string

public function contextValue(Tenant $tenant): int|string
{
return $this->config('context.user', 'key') === 'key'
return $this->config('context.use', 'key') === 'key'
? $tenant->getTenantKey()
: $tenant->getTenantIdentifier();
}
Expand Down
7 changes: 7 additions & 0 deletions src/SproutServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Sprout\Listeners\PerformIdentityResolverSetup;
use Sprout\Managers\IdentityResolverManager;
use Sprout\Managers\ProviderManager;
use Sprout\Managers\TenancyManager;

class SproutServiceProvider extends ServiceProvider
{
Expand Down Expand Up @@ -55,9 +56,15 @@ private function registerManagers(): void
return new IdentityResolverManager($app);
});

// Register the tenancy manager
$this->app->singleton(TenancyManager::class, function ($app) {
return new TenancyManager($app, $app->make(ProviderManager::class));
});

// Alias the managers with simple names
$this->app->alias(ProviderManager::class, 'sprout.providers');
$this->app->alias(IdentityResolverManager::class, 'sprout.resolvers');
$this->app->alias(TenancyManager::class, 'sprout.tenancies');
}

private function registerMiddleware(): void
Expand Down
111 changes: 111 additions & 0 deletions tests/Core/ServiceProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php
declare(strict_types=1);

namespace Sprout\Tests\Core;

use Illuminate\Support\ServiceProvider;
use Orchestra\Testbench\Concerns\WithWorkbench;
use Orchestra\Testbench\TestCase;
use PHPUnit\Framework\Attributes\Test;
use Sprout\Managers\IdentityResolverManager;
use Sprout\Managers\ProviderManager;
use Sprout\Managers\TenancyManager;
use Sprout\Sprout;
use Sprout\SproutServiceProvider;

class ServiceProviderTest extends TestCase
{
use WithWorkbench;

protected $enablesPackageDiscoveries = true;

#[Test]
public function serviceProviderIsRegistered(): void
{
$this->assertTrue(app()->providerIsLoaded(SproutServiceProvider::class));
}

#[Test]
public function sproutIsRegistered(): void
{
$this->assertTrue(app()->has(Sprout::class));
$this->assertTrue(app()->has('sprout'));
$this->assertTrue(app()->isShared(Sprout::class));
$this->assertFalse(app()->isShared('sprout'));

$this->assertSame(app()->make(Sprout::class), app()->make(Sprout::class));
$this->assertSame(app()->make('sprout'), app()->make('sprout'));
$this->assertSame(app()->make(Sprout::class), app()->make('sprout'));
$this->assertSame(app()->make('sprout'), app()->make(Sprout::class));
}

#[Test]
public function coreSproutConfigExists(): void
{
$this->assertTrue(app()['config']->has('sprout'));
$this->assertIsArray(app()['config']->get('sprout'));
$this->assertTrue(app()['config']->has('sprout.listen_for_routing'));
$this->assertTrue(app()['config']->has('sprout.context'));
$this->assertTrue(app()['config']->has('sprout.context.key'));
$this->assertTrue(app()['config']->has('sprout.context.use'));
}

#[Test]
public function providerManagerIsRegistered(): void
{
$this->assertTrue(app()->has(ProviderManager::class));
$this->assertTrue(app()->has('sprout.providers'));
$this->assertTrue(app()->isShared(ProviderManager::class));
$this->assertFalse(app()->isShared('sprout.providers'));

$this->assertSame(app()->make(ProviderManager::class), app()->make(ProviderManager::class));
$this->assertSame(app()->make('sprout.providers'), app()->make('sprout.providers'));
$this->assertSame(app()->make(ProviderManager::class), app()->make('sprout.providers'));
$this->assertSame(app()->make('sprout.providers'), app()->make(ProviderManager::class));
$this->assertSame(app()->make(Sprout::class)->providers(), app()->make('sprout.providers'));
$this->assertSame(app()->make(Sprout::class)->providers(), app()->make(ProviderManager::class));
}

#[Test]
public function identityResolverManagerIsRegistered(): void
{
$this->assertTrue(app()->has(IdentityResolverManager::class));
$this->assertTrue(app()->has('sprout.resolvers'));
$this->assertTrue(app()->isShared(IdentityResolverManager::class));
$this->assertFalse(app()->isShared('sprout.resolvers'));

$this->assertSame(app()->make(IdentityResolverManager::class), app()->make(IdentityResolverManager::class));
$this->assertSame(app()->make('sprout.resolvers'), app()->make('sprout.resolvers'));
$this->assertSame(app()->make(IdentityResolverManager::class), app()->make('sprout.resolvers'));
$this->assertSame(app()->make('sprout.resolvers'), app()->make(IdentityResolverManager::class));
$this->assertSame(app()->make(Sprout::class)->resolvers(), app()->make('sprout.resolvers'));
$this->assertSame(app()->make(Sprout::class)->resolvers(), app()->make(IdentityResolverManager::class));
}

#[Test]
public function tenancyManagerIsRegistered(): void
{
$this->assertTrue(app()->has(TenancyManager::class));
$this->assertTrue(app()->has('sprout.tenancies'));
$this->assertTrue(app()->isShared(TenancyManager::class));
$this->assertFalse(app()->isShared('sprout.tenancies'));

$this->assertSame(app()->make(TenancyManager::class), app()->make(TenancyManager::class));
$this->assertSame(app()->make('sprout.tenancies'), app()->make('sprout.tenancies'));
$this->assertSame(app()->make(TenancyManager::class), app()->make('sprout.tenancies'));
$this->assertSame(app()->make('sprout.tenancies'), app()->make(TenancyManager::class));
$this->assertSame(app()->make(Sprout::class)->tenancies(), app()->make('sprout.tenancies'));
$this->assertSame(app()->make(Sprout::class)->tenancies(), app()->make(TenancyManager::class));
}

#[Test]
public function publishesConfig(): void
{
$paths = ServiceProvider::pathsToPublish(SproutServiceProvider::class, 'config');

$key = realpath(__DIR__ . '/../../src');

$this->assertArrayHasKey($key . '/../resources/config/multitenancy.php', $paths);
$this->assertContains(config_path('multitenancy.php'), $paths);
}
}
113 changes: 113 additions & 0 deletions tests/Core/SproutTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php
declare(strict_types=1);

namespace Sprout\Tests\Core;

use Illuminate\Config\Repository;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Orchestra\Testbench\Concerns\WithWorkbench;
use Orchestra\Testbench\TestCase;
use PHPUnit\Framework\Attributes\Test;
use Sprout\Sprout;
use Workbench\App\Models\TenantModel;

class SproutTest extends TestCase
{
use WithWorkbench, RefreshDatabase;

protected $enablesPackageDiscoveries = true;

protected function defineEnvironment($app): void
{
tap($app['config'], static function (Repository $config) {
$config->set('multitenancy.providers.tenants.model', TenantModel::class);
});
}

#[Test]
public function makesCoreConfigAccessible(): void
{
$sprout = app()->make(Sprout::class);

$this->assertTrue($sprout->config('listen_for_routing'));
$this->assertTrue(config('sprout.listen_for_routing'));
$this->assertNotNull($sprout->config('context'));
$this->assertNotNull(config('sprout.context'));

app()['config']->set('sprout.listen_for_routing', false);

$this->assertFalse($sprout->config('listen_for_routing'));
$this->assertFalse(config('sprout.listen_for_routing'));
}

#[Test]
public function hasHelperForListeningToRoutingEvents(): void
{
$sprout = app()->make(Sprout::class);

app()['config']->set('sprout.listen_for_routing', false);

$this->assertFalse($sprout->config('listen_for_routing'));
$this->assertFalse(config('sprout.listen_for_routing'));
$this->assertFalse($sprout->shouldListenForRouting());

app()['config']->set('sprout.listen_for_routing', true);

$this->assertTrue($sprout->config('listen_for_routing'));
$this->assertTrue(config('sprout.listen_for_routing'));
$this->assertTrue($sprout->shouldListenForRouting());
}

#[Test]
public function canProvideContextKeyForTenancy(): void
{
$sprout = app()->make(Sprout::class);
$tenancy = $sprout->tenancies()->get('tenants');

app()['config']->set('sprout.context.key', '{tenancy}_key');

$this->assertSame('tenants_key', $sprout->contextKey($tenancy));

app()['config']->set('sprout.context.key', 'the_key_for_the_{tenancy}');

$this->assertSame('the_key_for_the_tenants', $sprout->contextKey($tenancy));
}

#[Test]
public function canProvideContextValueForTenant(): void
{
$sprout = app()->make(Sprout::class);
$tenant = TenantModel::first();

app()['config']->set('sprout.context.use', 'key');

$this->assertSame($tenant->getTenantKey(), $sprout->contextValue($tenant));

app()['config']->set('sprout.context.use', 'identifier');

$this->assertSame($tenant->getTenantIdentifier(), $sprout->contextValue($tenant));
}

#[Test]
public function keepsTrackOfCurrentTenancies(): void
{
$sprout = app()->make(Sprout::class);

$this->assertFalse($sprout->hasCurrentTenancy());
$this->assertNull($sprout->getCurrentTenancy());
$this->assertEmpty($sprout->getAllCurrentTenancies());

$tenancy = $sprout->tenancies()->get('tenants');
$sprout->setCurrentTenancy($tenancy);

$this->assertTrue($sprout->hasCurrentTenancy());
$this->assertNotNull($sprout->getCurrentTenancy());
$this->assertSame($tenancy, $sprout->getCurrentTenancy());
$this->assertNotEmpty($sprout->getAllCurrentTenancies());
$this->assertCount(1, $sprout->getAllCurrentTenancies());

$sprout->setCurrentTenancy($tenancy);

$this->assertCount(1, $sprout->getAllCurrentTenancies());
}
}

0 comments on commit 45c358b

Please sign in to comment.