1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-12 22:54:03 +00:00

Merge branch 'master' of github.com:archtechx/tenancy

This commit is contained in:
Samuel Štancl 2023-01-04 03:27:04 +01:00
commit a0256fd5f3
20 changed files with 285 additions and 34 deletions

View file

@ -3,6 +3,7 @@
declare(strict_types=1);
use Illuminate\Support\Str;
use Illuminate\Mail\MailManager;
use Illuminate\Support\Facades\DB;
use Stancl\JobPipeline\JobPipeline;
use Illuminate\Support\Facades\File;
@ -23,6 +24,7 @@ use Stancl\Tenancy\Jobs\RemoveStorageSymlinks;
use Stancl\Tenancy\Listeners\BootstrapTenancy;
use Stancl\Tenancy\Listeners\DeleteTenantStorage;
use Stancl\Tenancy\Listeners\RevertToCentralContext;
use Stancl\Tenancy\Bootstrappers\MailTenancyBootstrapper;
use Stancl\Tenancy\Bootstrappers\CacheTenancyBootstrapper;
use Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper;
use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
@ -326,20 +328,55 @@ test('local storage public urls are generated correctly', function() {
expect(File::isDirectory($tenantStoragePath))->toBeFalse();
});
test('MailTenancyBootstrapper maps tenant mail credentials to config as specified in the $credentialsMap property and makes the mailer use tenant credentials', function() {
MailTenancyBootstrapper::$credentialsMap = [
'mail.mailers.smtp.username' => 'smtp_username',
'mail.mailers.smtp.password' => 'smtp_password'
];
config([
'mail.default' => 'smtp',
'mail.mailers.smtp.username' => $defaultUsername = 'default username',
'mail.mailers.smtp.password' => 'no password'
]);
$tenant = Tenant::create(['smtp_password' => $password = 'testing password']);
tenancy()->initialize($tenant);
expect(array_key_exists('smtp_password', tenant()->getAttributes()))->toBeTrue();
expect(array_key_exists('smtp_host', tenant()->getAttributes()))->toBeFalse();
expect(config('mail.mailers.smtp.username'))->toBe($defaultUsername);
expect(config('mail.mailers.smtp.password'))->toBe(tenant()->smtp_password);
// Assert that the current mailer uses tenant's smtp_password
assertMailerTransportUsesPassword($password);
});
test('MailTenancyBootstrapper reverts the config and mailer credentials to default when tenancy ends', function() {
MailTenancyBootstrapper::$credentialsMap = ['mail.mailers.smtp.password' => 'smtp_password'];
config(['mail.default' => 'smtp', 'mail.mailers.smtp.password' => $defaultPassword = 'no password']);
tenancy()->initialize(Tenant::create(['smtp_password' => $tenantPassword = 'testing password']));
expect(config('mail.mailers.smtp.password'))->toBe($tenantPassword);
assertMailerTransportUsesPassword($tenantPassword);
tenancy()->end();
expect(config('mail.mailers.smtp.password'))->toBe($defaultPassword);
// Assert that the current mailer uses the default SMTP password
assertMailerTransportUsesPassword($defaultPassword);
});
function getDiskPrefix(string $disk): string
{
/** @var FilesystemAdapter $disk */
$disk = Storage::disk($disk);
$adapter = $disk->getAdapter();
$prefix = invade(invade($adapter)->prefixer)->prefix;
$prefixer = (new ReflectionObject($adapter))->getProperty('prefixer');
$prefixer->setAccessible(true);
// reflection -> instance
$prefixer = $prefixer->getValue($adapter);
$prefix = (new ReflectionProperty($prefixer, 'prefix'));
$prefix->setAccessible(true);
return $prefix->getValue($prefixer);
return $prefix;
}

View file

@ -372,7 +372,7 @@ function runCommandWorks(): void
Artisan::call('tenants:migrate', ['--tenants' => [$id]]);
pest()->artisan("tenants:run --tenants=$id 'foo foo --b=bar --c=xyz' ")
->expectsOutput("User's name is Test command")
->expectsOutput("User's name is Test user")
->expectsOutput('foo')
->expectsOutput('xyz');
}

View file

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Tests\Etc\Console;
use Illuminate\Support\Str;
use Illuminate\Console\Command;
class ExampleCommand extends Command
@ -22,14 +23,13 @@ class ExampleCommand extends Command
*/
public function handle()
{
User::create([
'id' => 999,
'name' => 'Test command',
'email' => 'test@command.com',
$id = User::create([
'name' => 'Test user',
'email' => Str::random(8) . '@example.com',
'password' => bcrypt('password'),
]);
])->id;
$this->line("User's name is " . User::find(999)->name);
$this->line("User's name is " . User::find($id)->name);
$this->line($this->argument('a'));
$this->line($this->option('c'));
}

72
tests/MailTest.php Normal file
View file

@ -0,0 +1,72 @@
<?php
declare(strict_types=1);
use Illuminate\Mail\MailManager;
use Illuminate\Support\Facades\Event;
use Stancl\Tenancy\Events\TenancyEnded;
use Stancl\Tenancy\Events\TenancyInitialized;
use Stancl\Tenancy\Listeners\BootstrapTenancy;
use Stancl\Tenancy\Listeners\RevertToCentralContext;
use Stancl\Tenancy\Bootstrappers\MailTenancyBootstrapper;
beforeEach(function() {
config(['mail.default' => 'smtp']);
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
});
// Initialize tenancy as $tenant and assert that the smtp mailer's transport has the correct password
function assertMailerTransportUsesPassword(string|null $password) {
$manager = app(MailManager::class);
$mailer = invade($manager)->get('smtp');
$mailerPassword = invade($mailer->getSymfonyTransport())->password;
expect($mailerPassword)->toBe((string) $password);
};
test('mailer transport uses the correct credentials', function() {
config(['mail.default' => 'smtp', 'mail.mailers.smtp.password' => $defaultPassword = 'DEFAULT']);
MailTenancyBootstrapper::$credentialsMap = ['mail.mailers.smtp.password' => 'smtp_password'];
tenancy()->initialize($tenant = Tenant::create());
assertMailerTransportUsesPassword($defaultPassword); // $tenant->smtp_password is not set, so the default password should be used
tenancy()->end();
// Assert mailer uses the updated password
$tenant->update(['smtp_password' => $newPassword = 'changed']);
tenancy()->initialize($tenant);
assertMailerTransportUsesPassword($newPassword);
tenancy()->end();
// Assert mailer uses the correct password after switching to a different tenant
tenancy()->initialize(Tenant::create(['smtp_password' => $newTenantPassword = 'updated']));
assertMailerTransportUsesPassword($newTenantPassword);
tenancy()->end();
// Assert mailer uses the default password after tenancy ends
assertMailerTransportUsesPassword($defaultPassword);
});
test('initializing and ending tenancy binds a fresh MailManager instance without cached mailers', function() {
$mailers = fn() => invade(app(MailManager::class))->mailers;
app(MailManager::class)->mailer('smtp');
expect($mailers())->toHaveCount(1);
tenancy()->initialize(Tenant::create());
expect($mailers())->toHaveCount(0);
app(MailManager::class)->mailer('smtp');
expect($mailers())->toHaveCount(1);
tenancy()->end();
expect($mailers())->toHaveCount(0);
});

View file

@ -83,6 +83,19 @@ test('tenant user can be impersonated on a tenant domain', function () {
pest()->get('http://foo.localhost/dashboard')
->assertSuccessful()
->assertSee('You are logged in as Joe');
expect(UserImpersonation::isImpersonating())->toBeTrue();
expect(session('tenancy_impersonating'))->toBeTrue();
// Leave impersonation
UserImpersonation::leave();
expect(UserImpersonation::isImpersonating())->toBeFalse();
expect(session('tenancy_impersonating'))->toBeNull();
// Assert can't access the tenant dashboard
pest()->get('http://foo.localhost/dashboard')
->assertRedirect('http://foo.localhost/login');
});
test('tenant user can be impersonated on a tenant path', function () {
@ -116,6 +129,19 @@ test('tenant user can be impersonated on a tenant path', function () {
pest()->get('/acme/dashboard')
->assertSuccessful()
->assertSee('You are logged in as Joe');
expect(UserImpersonation::isImpersonating())->toBeTrue();
expect(session('tenancy_impersonating'))->toBeTrue();
// Leave impersonation
UserImpersonation::leave();
expect(UserImpersonation::isImpersonating())->toBeFalse();
expect(session('tenancy_impersonating'))->toBeNull();
// Assert can't access the tenant dashboard
pest()->get('/acme/dashboard')
->assertRedirect('/login');
});
test('tokens have a limited ttl', function () {

View file

@ -14,6 +14,7 @@ use Stancl\Tenancy\Facades\GlobalCache;
use Stancl\Tenancy\Facades\Tenancy;
use Stancl\Tenancy\TenancyServiceProvider;
use Stancl\Tenancy\Tests\Etc\Tenant;
use Stancl\Tenancy\Bootstrappers\MailTenancyBootstrapper;
abstract class TestCase extends \Orchestra\Testbench\TestCase
{
@ -104,6 +105,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
'--force' => true,
],
'tenancy.bootstrappers.redis' => RedisTenancyBootstrapper::class, // todo1 change this to []? two tests in TenantDatabaseManagerTest are failing with that
'tenancy.bootstrappers.mail' => MailTenancyBootstrapper::class,
'queue.connections.central' => [
'driver' => 'sync',
'central' => true,
@ -113,6 +115,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
]);
$app->singleton(RedisTenancyBootstrapper::class); // todo (Samuel) use proper approach eg config for singleton registration
$app->singleton(MailTenancyBootstrapper::class);
}
protected function getPackageProviders($app)