Add support for custom database drivers#627
Conversation
luceos
left a comment
There was a problem hiding this comment.
Very impressive! A few requests for changes, but all is well 👍
tests/unit-tests/Generators/Webserver/Database/DatabaseDriverFactoryTest.php
Outdated
Show resolved
Hide resolved
|
Thank you, this is very valuable 👍 |
|
@Sti3bas, how do you do your migrations and seeding with system/tenant memory dbs? |
|
@anyb1s yes, you are right. That's because // create hostnames and website here
Artisan::call('migrate', [
'--database' => 'tenant',
'--force' => true,
'--path' => config('tenancy.db.tenant-migrations-path'),
'--realpath' => true,
]); |
|
@Sti3bas Thank you very much for the response but I am still struggling to get this working. (I am definitely doing something wrong! :) In my phpunit xml I have the following: basically create My database settings: In my setup I use the website repository to create a website and a hostname attached to it and then set the environment. ` And then in my I test I do |
|
@anyb1s I've spent few evenings trying to find the best solution and here is how I've made it to work: tests/TenantAwareTestCase.php: namespace Tests;
use Hyn\Tenancy\Models\Website;
use Hyn\Tenancy\Contracts\Repositories\WebsiteRepository;
use Hyn\Tenancy\Models\Hostname;
use Hyn\Tenancy\Contracts\Repositories\HostnameRepository;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Hyn\Tenancy\Providers\Tenants\RouteProvider;
use Hyn\Tenancy\Contracts\CurrentHostname;
class TenantAwareTestCase extends TestCase
{
// turn on database transactions for both database connections
// otherwise you will get an error when you will run multiple tests
protected $connectionsToTransact = [
'system',
'tenant',
];
// refresh system database
use RefreshDatabase;
protected function setUp()
{
parent::setUp();
// register SQLite database driver (you can find the source code above)
app('tenancy.db.drivers')->put('sqlite', SqliteDriver::class);
// bypass tenant connection settings modifications
config(['tenancy.db.tenant-division-mode' => 'bypass']);
// create a website
$website = new Website;
app(WebsiteRepository::class)->create($website);
// create a hostname
$hostname = new Hostname;
$hostname->fqdn = 'test.test.test';
$hostname = app(HostnameRepository::class)->create($hostname);
app(HostnameRepository::class)->attach($hostname, $website);
// at this point, tenant conection settings is an empty array (not sure why)
// you can hack this by setting it directly
config([
'database.connections.tenant' => [
'driver' => 'sqlite',
'database' => ':memory:',
],
]);
// set current hostname
app()->singleton(CurrentHostname::class, function () use ($hostname) {
return $hostname;
});
// register tenant routes, by default web/tenants.php
(new RouteProvider(app()))->boot();
// migrate tenant database
$this->artisan('migrate', [
// this is a connection name, not a database name!!!
'--database' => 'tenant',
'--force' => true,
'--path' => config('tenancy.db.tenant-migrations-path'),
'--realpath' => true,
]);
}
}config/database.php: 'system' => [
'driver' => env('TENANCY_DRIVER', 'mysql'),
'host' => env('TENANCY_HOST', '127.0.0.1'),
'port' => env('TENANCY_PORT', '3306'),
'database' => env('TENANCY_DATABASE', 'tenancy'),
'username' => env('TENANCY_USERNAME', 'tenancy'),
'password' => env('TENANCY_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],phpunit.xml: <env name="DB_CONNECTION" value="system"/>
<env name="TENANCY_DRIVER" value="sqlite"/>
<env name="TENANCY_DATABASE" value=":memory:"/> |
|
That's brilliant mate, thank you very much!
|
|
@anyb1s works fine for me with both global and tenant routes: tests/Feature/ExampleTest.php: namespace Tests\Feature;
use Tests\TenantAwareTestCase;
class ExampleTest extends TenantAwareTestCase
{
/** @test */
public function it_works_with_tenant_routes()
{
$this->get('/tenant')
->assertStatus(200)
->assertSee('Tenant');
}
/** @test */
public function it_works_with_global_routes()
{
$this->get('/global')
->assertStatus(200)
->assertSee('Global');
}
}routes/web.php: Route::get('/global', function () {
return 'Global';
});routes/tenants.php: Route::get('/tenant', function () {
return 'Tenant';
});Both tests are passing. |
|
Thank you very much for the help!!! |
|
@anyb1s above tests runs in ~400ms each on my machine. |
|
@Sti3bas, my issue was had xdebug was enabled and reduced the number of hash rounds for the passwords and got it working around 500-800ms each. Thanks again for the help, works like charm, got it working with passport (Everything is awesome) |
|
@vpratfr Vincent please move this discussion out of this PR and/or this repository. It's too much noise. If there's something this package can do please create an issue or PR, I'll gladly look at either. |
Getting started with testing. Related to tenancy/multi-tenant#627.
This PR adds ability to add your own database drivers.
Use case:
This was the single problem I encountered when tried to use SQLite database for tests.
I can now use SQLite in-memory databases for my tests by simply adding
app('tenancy.db.drivers')->put('sqlite', \Tests\Support\SqliteDriver::class);tosetUpmethod and creating custom SQLite driver: