diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7b64d2d..cc8ad985 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,11 @@ jobs: strategy: matrix: - php: ["7.4", "8.0"] - laravel: ["^6.0", "^8.0"] + php: ["7.3", "8.0"] + laravel: ["^6.0", "^8.0", "^9.0"] + exclude: + - laravel: "^9.0" + php: "7.3" steps: - uses: actions/checkout@v2 diff --git a/.gitignore b/.gitignore index b3223156..f470ba75 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ phpunit_var_*.xml coverage/ clover.xml tests/Etc/tmp/queuetest.json +docker-compose.override.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7dce1b82..a5a6ec3f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,3 +9,16 @@ StyleCI will flag code style violations in your pull requests. Run `docker-compose up -d` to start the containers. Then run `./test` to run the tests. When you're done testing, run `docker-compose down` to shut down the containers. + +### Docker on M1 + +You can add: +```yaml +services: + mysql: + platform: linux/amd64 + mysql2: + platform: linux/amd64 +``` + +to `docker-compose.override.yml` to make `docker-compose up-d` work on M1. diff --git a/Dockerfile b/Dockerfile index 06d97aea..36f52d6a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,7 +30,7 @@ RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ # && if [ "${PHP_VERSION}" = "7.4" ]; then docker-php-ext-configure gd --with-freetype --with-jpeg; else docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/; fi \ && docker-php-ext-install -j$(nproc) gd pdo pdo_mysql pdo_pgsql pdo_sqlite pgsql zip gmp bcmath pcntl ldap sysvmsg exif \ # install the redis php extension - && pecl install redis-5.3.2 \ + && pecl install redis-5.3.7 \ && docker-php-ext-enable redis \ # install the pcov extention && pecl install pcov \ diff --git a/README.md b/README.md index f4d28288..95fb7c60 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@
-
+
diff --git a/composer.json b/composer.json
index bf66e1f2..88bfea29 100644
--- a/composer.json
+++ b/composer.json
@@ -11,16 +11,16 @@
],
"require": {
"ext-json": "*",
- "illuminate/support": "^6.0|^7.0|^8.0",
+ "illuminate/support": "^6.0|^7.0|^8.0|^9.0",
"facade/ignition-contracts": "^1.0",
"ramsey/uuid": "^3.7|^4.0",
"stancl/jobpipeline": "^1.0",
"stancl/virtualcolumn": "^1.0"
},
"require-dev": {
- "laravel/framework": "^6.0|^7.0|^8.0",
- "orchestra/testbench-browser-kit": "^4.0|^5.0|^6.0",
- "league/flysystem-aws-s3-v3": "~1.0",
+ "laravel/framework": "^6.0|^7.0|^8.0|^9.0",
+ "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0",
+ "league/flysystem-aws-s3-v3": "^1.0|^3.0",
"doctrine/dbal": "^2.10",
"spatie/valuestore": "^1.2.5"
},
diff --git a/src/Bootstrappers/FilesystemTenancyBootstrapper.php b/src/Bootstrappers/FilesystemTenancyBootstrapper.php
index 33d98030..346892b3 100644
--- a/src/Bootstrappers/FilesystemTenancyBootstrapper.php
+++ b/src/Bootstrappers/FilesystemTenancyBootstrapper.php
@@ -5,7 +5,6 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Bootstrappers;
use Illuminate\Contracts\Foundation\Application;
-use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Facades\Storage;
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
use Stancl\Tenancy\Contracts\Tenant;
@@ -54,22 +53,22 @@ class FilesystemTenancyBootstrapper implements TenancyBootstrapper
}
// Storage facade
- foreach ($this->app['config']['tenancy.filesystem.disks'] as $disk) {
- /** @var FilesystemAdapter $filesystemDisk */
- $filesystemDisk = Storage::disk($disk);
- $this->originalPaths['disks'][$disk] = $filesystemDisk->getAdapter()->getPathPrefix();
- $subject = $this->app['config']["tenancy.filesystem.root_override.{$disk}"] ?? '';
+ Storage::forgetDisk($this->app['config']['tenancy.filesystem.disks']);
- if ($root = str_replace(
- '%storage_path%',
- storage_path(),
- $subject
- )) {
- $root = str_replace('%tenant%', $suffix, $root);
- $filesystemDisk->getAdapter()->setPathPrefix($finalPrefix = $root);
- } else {
- $root = $this->app['config']["filesystems.disks.{$disk}.root"];
- $filesystemDisk->getAdapter()->setPathPrefix($finalPrefix = $root . "/{$suffix}");
+ foreach ($this->app['config']['tenancy.filesystem.disks'] as $disk) {
+ $originalRoot = $this->app['config']["filesystems.disks.{$disk}.root"];
+ $this->originalPaths['disks'][$disk] = $originalRoot;
+
+ $finalPrefix = str_replace(
+ ['%storage_path%', '%tenant%'],
+ [storage_path(), $tenant->getTenantKey()],
+ $this->app['config']["tenancy.filesystem.root_override.{$disk}"] ?? '',
+ );
+
+ if (! $finalPrefix) {
+ $finalPrefix = $originalRoot
+ ? rtrim($originalRoot, '/') . '/'. $suffix
+ : $suffix;
}
$this->app['config']["filesystems.disks.{$disk}.root"] = $finalPrefix;
@@ -86,14 +85,9 @@ class FilesystemTenancyBootstrapper implements TenancyBootstrapper
$this->app['url']->setAssetRoot($this->app['config']['app.asset_url']);
// Storage facade
+ Storage::forgetDisk($this->app['config']['tenancy.filesystem.disks']);
foreach ($this->app['config']['tenancy.filesystem.disks'] as $disk) {
- /** @var FilesystemAdapter $filesystemDisk */
- $filesystemDisk = Storage::disk($disk);
-
- $root = $this->originalPaths['disks'][$disk];
-
- $filesystemDisk->getAdapter()->setPathPrefix($root);
- $this->app['config']["filesystems.disks.{$disk}.root"] = $root;
+ $this->app['config']["filesystems.disks.{$disk}.root"] = $this->originalPaths['disks'][$disk];
}
}
}
diff --git a/src/Bootstrappers/QueueTenancyBootstrapper.php b/src/Bootstrappers/QueueTenancyBootstrapper.php
index 6a88f701..790e1344 100644
--- a/src/Bootstrappers/QueueTenancyBootstrapper.php
+++ b/src/Bootstrappers/QueueTenancyBootstrapper.php
@@ -30,8 +30,10 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
*
* This is useful when you're changing the tenant's state (e.g. properties in the `data` column) and want the next job to initialize tenancy again
* with the new data. Features like the Tenant Config are only executed when tenancy is initialized, so the re-initialization is needed in some cases.
+ *
+ * @var bool
*/
- public static bool $forceRefresh = false;
+ public static $forceRefresh = false;
/**
* The normal constructor is only executed after tenancy is bootstrapped.
@@ -61,8 +63,8 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
static::initializeTenancyForQueue($event->job->payload()['tenant_id'] ?? null);
});
- if (Str::startsWith(app()->version(), '8')) {
- // JobRetryRequested only exists since Laravel 8
+ if (version_compare(app()->version(), '8.64', '>=')) {
+ // JobRetryRequested only exists since Laravel 8.64
$dispatcher->listen(JobRetryRequested::class, function ($event) use (&$previousTenant) {
$previousTenant = tenant();
diff --git a/src/Commands/Migrate.php b/src/Commands/Migrate.php
index bf92dfcd..c67d3598 100644
--- a/src/Commands/Migrate.php
+++ b/src/Commands/Migrate.php
@@ -8,32 +8,26 @@ use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Database\Console\Migrations\MigrateCommand;
use Illuminate\Database\Migrations\Migrator;
use Stancl\Tenancy\Concerns\DealsWithMigrations;
+use Stancl\Tenancy\Concerns\ExtendsLaravelCommand;
use Stancl\Tenancy\Concerns\HasATenantsOption;
use Stancl\Tenancy\Events\DatabaseMigrated;
use Stancl\Tenancy\Events\MigratingDatabase;
class Migrate extends MigrateCommand
{
- use HasATenantsOption, DealsWithMigrations;
+ use HasATenantsOption, DealsWithMigrations, ExtendsLaravelCommand;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Run migrations for tenant(s)';
- /**
- * Create a new command instance.
- *
- * @param Migrator $migrator
- * @param Dispatcher $dispatcher
- */
+ protected static function getTenantCommandName(): string
+ {
+ return 'tenants:migrate';
+ }
+
public function __construct(Migrator $migrator, Dispatcher $dispatcher)
{
parent::__construct($migrator, $dispatcher);
- $this->setName('tenants:migrate');
$this->specifyParameters();
}
diff --git a/src/Commands/MigrateFresh.php b/src/Commands/MigrateFresh.php
index 4d003db0..283d70b0 100644
--- a/src/Commands/MigrateFresh.php
+++ b/src/Commands/MigrateFresh.php
@@ -23,7 +23,7 @@ final class MigrateFresh extends Command
public function __construct()
{
parent::__construct();
-
+
$this->addOption('--drop-views', null, InputOption::VALUE_NONE, 'Drop views along with tenant tables.', null);
$this->setName('tenants:migrate-fresh');
diff --git a/src/Commands/Rollback.php b/src/Commands/Rollback.php
index 081872c8..e60d974b 100644
--- a/src/Commands/Rollback.php
+++ b/src/Commands/Rollback.php
@@ -7,13 +7,19 @@ namespace Stancl\Tenancy\Commands;
use Illuminate\Database\Console\Migrations\RollbackCommand;
use Illuminate\Database\Migrations\Migrator;
use Stancl\Tenancy\Concerns\DealsWithMigrations;
+use Stancl\Tenancy\Concerns\ExtendsLaravelCommand;
use Stancl\Tenancy\Concerns\HasATenantsOption;
use Stancl\Tenancy\Events\DatabaseRolledBack;
use Stancl\Tenancy\Events\RollingBackDatabase;
class Rollback extends RollbackCommand
{
- use HasATenantsOption, DealsWithMigrations;
+ use HasATenantsOption, DealsWithMigrations, ExtendsLaravelCommand;
+
+ protected static function getTenantCommandName(): string
+ {
+ return 'tenants:rollback';
+ }
/**
* The console command description.
@@ -31,8 +37,7 @@ class Rollback extends RollbackCommand
{
parent::__construct($migrator);
- $this->setName('tenants:rollback');
- $this->specifyParameters();
+ $this->specifyTenantSignature();
}
/**
diff --git a/src/Concerns/ExtendsLaravelCommand.php b/src/Concerns/ExtendsLaravelCommand.php
new file mode 100644
index 00000000..bdafc8f7
--- /dev/null
+++ b/src/Concerns/ExtendsLaravelCommand.php
@@ -0,0 +1,23 @@
+specifyParameters();
+ }
+
+ public function getName(): ?string
+ {
+ return static::getTenantCommandName();
+ }
+
+ public static function getDefaultName(): ?string
+ {
+ return static::getTenantCommandName();
+ }
+
+ abstract protected static function getTenantCommandName(): string;
+}
diff --git a/src/Database/DatabaseManager.php b/src/Database/DatabaseManager.php
index e85fd659..6242ffa9 100644
--- a/src/Database/DatabaseManager.php
+++ b/src/Database/DatabaseManager.php
@@ -7,10 +7,12 @@ namespace Stancl\Tenancy\Database;
use Illuminate\Config\Repository;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Database\DatabaseManager as BaseDatabaseManager;
+use Stancl\Tenancy\Contracts\ManagesDatabaseUsers;
use Stancl\Tenancy\Contracts\TenantCannotBeCreatedException;
use Stancl\Tenancy\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Exceptions\DatabaseManagerNotRegisteredException;
use Stancl\Tenancy\Exceptions\TenantDatabaseAlreadyExistsException;
+use Stancl\Tenancy\Exceptions\TenantDatabaseUserAlreadyExistsException;
/**
* @internal Class is subject to breaking changes in minor and patch versions.
@@ -90,8 +92,14 @@ class DatabaseManager
*/
public function ensureTenantCanBeCreated(TenantWithDatabase $tenant): void
{
- if ($tenant->database()->manager()->databaseExists($database = $tenant->database()->getName())) {
+ $manager = $tenant->database()->manager();
+
+ if ($manager->databaseExists($database = $tenant->database()->getName())) {
throw new TenantDatabaseAlreadyExistsException($database);
}
+
+ if ($manager instanceof ManagesDatabaseUsers && $manager->userExists($username = $tenant->database()->getUsername())) {
+ throw new TenantDatabaseUserAlreadyExistsException($username);
+ }
}
}
diff --git a/src/Jobs/CreateDatabase.php b/src/Jobs/CreateDatabase.php
index 3a74534d..3cb2a6b4 100644
--- a/src/Jobs/CreateDatabase.php
+++ b/src/Jobs/CreateDatabase.php
@@ -36,8 +36,8 @@ class CreateDatabase implements ShouldQueue
return false;
}
- $databaseManager->ensureTenantCanBeCreated($this->tenant);
$this->tenant->database()->makeCredentials();
+ $databaseManager->ensureTenantCanBeCreated($this->tenant);
$this->tenant->database()->manager()->createDatabase($this->tenant);
event(new DatabaseCreated($this->tenant));
diff --git a/src/Middleware/CheckTenantForMaintenanceMode.php b/src/Middleware/CheckTenantForMaintenanceMode.php
index 5554663f..8e29a31e 100644
--- a/src/Middleware/CheckTenantForMaintenanceMode.php
+++ b/src/Middleware/CheckTenantForMaintenanceMode.php
@@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Middleware;
use Closure;
-use Illuminate\Foundation\Http\Exceptions\MaintenanceModeException;
+use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode;
use Stancl\Tenancy\Exceptions\TenancyNotInitializedException;
use Symfony\Component\HttpFoundation\IpUtils;
@@ -29,7 +29,12 @@ class CheckTenantForMaintenanceMode extends CheckForMaintenanceMode
return $next($request);
}
- throw new MaintenanceModeException($data['time'], $data['retry'], $data['message']);
+ throw new HttpException(
+ 503,
+ 'Service Unavailable',
+ null,
+ isset($data['retry']) ? ['Retry-After' => $data['retry']] : []
+ );
}
return $next($request);
diff --git a/src/TenantDatabaseManagers/PermissionControlledMySQLDatabaseManager.php b/src/TenantDatabaseManagers/PermissionControlledMySQLDatabaseManager.php
index f8bedc97..918601a8 100644
--- a/src/TenantDatabaseManagers/PermissionControlledMySQLDatabaseManager.php
+++ b/src/TenantDatabaseManagers/PermissionControlledMySQLDatabaseManager.php
@@ -7,7 +7,6 @@ namespace Stancl\Tenancy\TenantDatabaseManagers;
use Stancl\Tenancy\Concerns\CreatesDatabaseUsers;
use Stancl\Tenancy\Contracts\ManagesDatabaseUsers;
use Stancl\Tenancy\DatabaseConfig;
-use Stancl\Tenancy\Exceptions\TenantDatabaseUserAlreadyExistsException;
class PermissionControlledMySQLDatabaseManager extends MySQLDatabaseManager implements ManagesDatabaseUsers
{
@@ -26,10 +25,6 @@ class PermissionControlledMySQLDatabaseManager extends MySQLDatabaseManager impl
$hostname = $databaseConfig->connection()['host'];
$password = $databaseConfig->getPassword();
- if ($this->userExists($username)) {
- throw new TenantDatabaseUserAlreadyExistsException($username);
- }
-
$this->database()->statement("CREATE USER `{$username}`@`%` IDENTIFIED BY '{$password}'");
$grants = implode(', ', static::$grants);
diff --git a/src/TenantDatabaseManagers/PostgreSQLSchemaManager.php b/src/TenantDatabaseManagers/PostgreSQLSchemaManager.php
index 9d815b25..55f049d0 100644
--- a/src/TenantDatabaseManagers/PostgreSQLSchemaManager.php
+++ b/src/TenantDatabaseManagers/PostgreSQLSchemaManager.php
@@ -46,7 +46,11 @@ class PostgreSQLSchemaManager implements TenantDatabaseManager
public function makeConnectionConfig(array $baseConfig, string $databaseName): array
{
- $baseConfig['schema'] = $databaseName;
+ if (version_compare(app()->version(), '9.0', '>=')) {
+ $baseConfig['search_path'] = $databaseName;
+ } else {
+ $baseConfig['schema'] = $databaseName;
+ }
return $baseConfig;
}
diff --git a/tests/BootstrapperTest.php b/tests/BootstrapperTest.php
index 1b0c880d..588fadd8 100644
--- a/tests/BootstrapperTest.php
+++ b/tests/BootstrapperTest.php
@@ -4,23 +4,27 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Tests;
-use Illuminate\Support\Facades\Cache;
+use Illuminate\Filesystem\FilesystemAdapter;
+use ReflectionObject;
+use ReflectionProperty;
+use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
+use Stancl\JobPipeline\JobPipeline;
+use Stancl\Tenancy\Tests\Etc\Tenant;
+use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
-use Stancl\JobPipeline\JobPipeline;
-use Stancl\Tenancy\Bootstrappers\CacheTenancyBootstrapper;
-use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
-use Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper;
-use Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper;
use Stancl\Tenancy\Events\TenancyEnded;
-use Stancl\Tenancy\Events\TenancyInitialized;
-use Stancl\Tenancy\Events\TenantCreated;
use Stancl\Tenancy\Jobs\CreateDatabase;
+use Stancl\Tenancy\Events\TenantCreated;
+use Stancl\Tenancy\Events\TenancyInitialized;
use Stancl\Tenancy\Listeners\BootstrapTenancy;
use Stancl\Tenancy\Listeners\RevertToCentralContext;
-use Stancl\Tenancy\Tests\Etc\Tenant;
+use Stancl\Tenancy\Bootstrappers\CacheTenancyBootstrapper;
+use Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper;
+use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
+use Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper;
class BootstrapperTest extends TestCase
{
@@ -165,6 +169,7 @@ class BootstrapperTest extends TestCase
$tenant2 = Tenant::create();
tenancy()->initialize($tenant1);
+
Storage::disk('public')->put('foo', 'bar');
$this->assertSame('bar', Storage::disk('public')->get('foo'));
@@ -184,30 +189,38 @@ class BootstrapperTest extends TestCase
$this->assertFalse(Storage::disk('public')->exists('foo'));
$this->assertFalse(Storage::disk('public')->exists('abc'));
+ $expected_storage_path = $old_storage_path . '/tenant' . tenant('id'); // /tenant = suffix base
+
+ // Check that disk prefixes respect the root_override logic
+ $this->assertSame($expected_storage_path . '/app/', $this->getDiskPrefix('local'));
+ $this->assertSame($expected_storage_path . '/app/public/', $this->getDiskPrefix('public'));
+ $this->assertSame('tenant' . tenant('id') . '/', $this->getDiskPrefix('s3'), '/');
+
// Check suffixing logic
$new_storage_path = storage_path();
- $this->assertEquals($old_storage_path . '/' . config('tenancy.filesystem.suffix_base') . tenant('id'), $new_storage_path);
+ $this->assertEquals($expected_storage_path, $new_storage_path);
+ }
- foreach (config('tenancy.filesystem.disks') as $disk) {
- $suffix = config('tenancy.filesystem.suffix_base') . tenant('id');
+ protected function getDiskPrefix(string $disk): string
+ {
+ /** @var FilesystemAdapter $disk */
+ $disk = Storage::disk($disk);
+ $adapter = $disk->getAdapter();
- /** @var FilesystemAdapter $filesystemDisk */
- $filesystemDisk = Storage::disk($disk);
-
- $current_path_prefix = $filesystemDisk->getAdapter()->getPathPrefix();
-
- if ($override = config("tenancy.filesystem.root_override.{$disk}")) {
- $correct_path_prefix = str_replace('%storage_path%', storage_path(), $override);
- } else {
- if ($base = $old_storage_facade_roots[$disk]) {
- $correct_path_prefix = $base . "/$suffix/";
- } else {
- $correct_path_prefix = "$suffix/";
- }
- }
-
- $this->assertSame($correct_path_prefix, $current_path_prefix);
+ if (! Str::startsWith(app()->version(), '9.')) {
+ return $adapter->getPathPrefix();
}
+
+ $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);
}
// for queues see QueueTest
diff --git a/tests/DatabaseUsersTest.php b/tests/DatabaseUsersTest.php
index 0b095024..344239d1 100644
--- a/tests/DatabaseUsersTest.php
+++ b/tests/DatabaseUsersTest.php
@@ -10,6 +10,7 @@ use Illuminate\Support\Str;
use Stancl\JobPipeline\JobPipeline;
use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
use Stancl\Tenancy\Contracts\ManagesDatabaseUsers;
+use Stancl\Tenancy\Events\DatabaseCreated;
use Stancl\Tenancy\Events\TenancyInitialized;
use Stancl\Tenancy\Events\TenantCreated;
use Stancl\Tenancy\Exceptions\TenantDatabaseUserAlreadyExistsException;
@@ -67,14 +68,18 @@ class DatabaseUsersTest extends TestCase
$this->assertTrue($manager->databaseExists($tenant->database()->getName()));
$this->expectException(TenantDatabaseUserAlreadyExistsException::class);
+ Event::fake([DatabaseCreated::class]);
+
$tenant2 = Tenant::create([
'tenancy_db_username' => $username,
]);
/** @var ManagesDatabaseUsers $manager */
- $manager = $tenant2->database()->manager();
+ $manager2 = $tenant2->database()->manager();
+
// database was not created because of DB transaction
- $this->assertFalse($manager->databaseExists($tenant2->database()->getName()));
+ $this->assertFalse($manager2->databaseExists($tenant2->database()->getName()));
+ Event::assertNotDispatched(DatabaseCreated::class);
}
/** @test */
diff --git a/tests/Etc/ConsoleKernel.php b/tests/Etc/ConsoleKernel.php
index 1bc66365..9d37d3c6 100644
--- a/tests/Etc/ConsoleKernel.php
+++ b/tests/Etc/ConsoleKernel.php
@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Tests\Etc;
-use Orchestra\Testbench\Console\Kernel;
+use Orchestra\Testbench\Foundation\Console\Kernel;
class ConsoleKernel extends Kernel
{
diff --git a/tests/Etc/tmp/queuetest.json b/tests/Etc/tmp/queuetest.json
deleted file mode 100644
index e69de29b..00000000
diff --git a/tests/MaintenanceModeTest.php b/tests/MaintenanceModeTest.php
index a8ecb064..4a8d8d0c 100644
--- a/tests/MaintenanceModeTest.php
+++ b/tests/MaintenanceModeTest.php
@@ -4,12 +4,14 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Tests;
+use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Http\Exceptions\MaintenanceModeException;
use Illuminate\Support\Facades\Route;
use Stancl\Tenancy\Database\Concerns\MaintenanceMode;
use Stancl\Tenancy\Middleware\CheckTenantForMaintenanceMode;
use Stancl\Tenancy\Middleware\InitializeTenancyByDomain;
use Stancl\Tenancy\Tests\Etc\Tenant;
+use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
class MaintenanceModeTest extends TestCase
{
@@ -32,7 +34,7 @@ class MaintenanceModeTest extends TestCase
$tenant->putDownForMaintenance();
- $this->expectException(MaintenanceModeException::class);
+ $this->expectException(HttpException::class);
$this->withoutExceptionHandling()
->get('http://acme.localhost/foo');
}
diff --git a/tests/QueueTest.php b/tests/QueueTest.php
index afe64fea..a3df9cd7 100644
--- a/tests/QueueTest.php
+++ b/tests/QueueTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Tests;
+use Closure;
use Exception;
use Illuminate\Support\Str;
use Illuminate\Bus\Queueable;
@@ -24,6 +25,7 @@ use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
+use PDO;
use Stancl\Tenancy\Events\TenancyInitialized;
use Stancl\Tenancy\Listeners\BootstrapTenancy;
use Stancl\Tenancy\Listeners\RevertToCentralContext;
@@ -52,7 +54,7 @@ class QueueTest extends TestCase
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
- $this->valuestore = Valuestore::make(__DIR__ . '/Etc/tmp/queuetest.json')->flush();
+ $this->createValueStore();
}
public function tearDown(): void
@@ -60,6 +62,22 @@ class QueueTest extends TestCase
$this->valuestore->flush();
}
+ protected function createValueStore(): void
+ {
+ $valueStorePath = __DIR__ . '/Etc/tmp/queuetest.json';
+
+ if (! file_exists($valueStorePath)) {
+ // The directory sometimes goes missing as well when the file is deleted in git
+ if (! is_dir(__DIR__ . '/Etc/tmp')) {
+ mkdir(__DIR__ . '/Etc/tmp');
+ }
+
+ file_put_contents($valueStorePath, '');
+ }
+
+ $this->valuestore = Valuestore::make($valueStorePath)->flush();
+ }
+
protected function withFailedJobs()
{
Schema::connection('central')->create('failed_jobs', function (Blueprint $table) {
diff --git a/tests/TenantDatabaseManagerTest.php b/tests/TenantDatabaseManagerTest.php
index f64770b1..3d45d96f 100644
--- a/tests/TenantDatabaseManagerTest.php
+++ b/tests/TenantDatabaseManagerTest.php
@@ -194,7 +194,11 @@ class TenantDatabaseManagerTest extends TestCase
]);
tenancy()->initialize($tenant);
- $this->assertSame($tenant->database()->getName(), config('database.connections.' . config('database.default') . '.schema'));
+ $schemaConfig = version_compare(app()->version(), '9.0', '>=') ?
+ config('database.connections.' . config('database.default') . '.search_path') :
+ config('database.connections.' . config('database.default') . '.schema');
+
+ $this->assertSame($tenant->database()->getName(), $schemaConfig);
$this->assertSame($originalDatabaseName, config(['database.connections.pgsql.database']));
}
diff --git a/tests/TestCase.php b/tests/TestCase.php
index d3e42ea1..cea669a1 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -87,6 +87,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
'public',
's3',
],
+ 'filesystems.disks.s3.bucket' => 'foo',
'tenancy.redis.tenancy' => env('TENANCY_TEST_REDIS_TENANCY', true),
'database.redis.client' => env('TENANCY_TEST_REDIS_CLIENT', 'phpredis'),
'tenancy.redis.prefixed_connections' => ['default'],