mirror of
https://github.com/linuxserver/Heimdall.git
synced 2026-08-07 07:16:13 +00:00
Run tests against in-memory sqlite and refuse real databases
The :memory: overrides in phpunit.xml had been commented out since 2024, so RefreshDatabase ran migrate:fresh against the real .env database and wiped it on every local test run. Enable the overrides, let the special :memory: identifier bypass database_path() resolution and the boot-time touch(), and add a TestCase guard that aborts the suite unless it is pointed at in-memory sqlite. ItemExportTest only ever passed by reading the populated dev database; seed the root dashboard item it depends on so it passes on a fresh DB.
This commit is contained in:
@@ -150,9 +150,10 @@ class AppServiceProvider extends ServiceProvider
|
||||
$db_type = config()->get('database.default');
|
||||
|
||||
if ($db_type == 'sqlite') {
|
||||
$db_file = database_path(env('DB_DATABASE', 'app.sqlite'));
|
||||
$db_file = config()->get('database.connections.sqlite.database');
|
||||
Log::debug('SQLite Database Path: ' . $db_file);
|
||||
if (! is_file($db_file)) {
|
||||
// Do not create a file for the in-memory database identifier.
|
||||
if ($db_file !== ':memory:' && ! is_file($db_file)) {
|
||||
touch($db_file);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -7,7 +7,11 @@ return [
|
||||
'connections' => [
|
||||
'sqlite' => [
|
||||
'driver' => 'sqlite',
|
||||
'database' => database_path(env('DB_DATABASE', 'app.sqlite')), // Make sure to use the correct path
|
||||
// Use the correct path, but let the special in-memory identifier
|
||||
// pass through untouched so tests can run against ':memory:'.
|
||||
'database' => env('DB_DATABASE', 'app.sqlite') === ':memory:'
|
||||
? ':memory:'
|
||||
: database_path(env('DB_DATABASE', 'app.sqlite')),
|
||||
'prefix' => '',
|
||||
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), // Enable foreign key constraints
|
||||
],
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||
<env name="CACHE_STORE" value="array"/>
|
||||
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
|
||||
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
|
||||
<env name="DB_CONNECTION" value="sqlite"/>
|
||||
<env name="DB_DATABASE" value=":memory:"/>
|
||||
<env name="MAIL_MAILER" value="array"/>
|
||||
<env name="PULSE_ENABLED" value="false"/>
|
||||
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Tests\Feature;
|
||||
use App\Item;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ItemExportTest extends TestCase
|
||||
@@ -39,6 +40,18 @@ class ItemExportTest extends TestCase
|
||||
|
||||
public function test_exports_assigned_tag_titles_excluding_the_root_tag(): void
|
||||
{
|
||||
// Mirror the root/default dashboard row that production seeds (id 0),
|
||||
// so the item_tag pivot's foreign key to items.id is satisfied on a
|
||||
// fresh in-memory database.
|
||||
DB::table('items')->insert([
|
||||
'id' => 0,
|
||||
'title' => 'app.dashboard',
|
||||
'url' => '',
|
||||
'type' => 1,
|
||||
'user_id' => 0,
|
||||
'pinned' => 0,
|
||||
]);
|
||||
|
||||
$item = Item::factory()
|
||||
->create([
|
||||
'title' => 'Tagged Item',
|
||||
|
||||
+38
-1
@@ -6,5 +6,42 @@ use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||
|
||||
abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
//
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->guardAgainstRealDatabase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refuse to run the test suite against anything other than an
|
||||
* in-memory SQLite database.
|
||||
*
|
||||
* The suite uses RefreshDatabase (migrate:fresh), which would wipe
|
||||
* whatever database it is pointed at. The only supported test
|
||||
* configuration for this repo is sqlite + ':memory:'. Any other
|
||||
* connection (a real sqlite file, mysql, pgsql, ...) is rejected so
|
||||
* we can never destroy real data.
|
||||
*/
|
||||
private function guardAgainstRealDatabase(): void
|
||||
{
|
||||
$default = config('database.default');
|
||||
$driver = config("database.connections.{$default}.driver");
|
||||
$database = config("database.connections.{$default}.database");
|
||||
|
||||
if ($driver === 'sqlite' && $database === ':memory:') {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Refusing to run tests: the default database connection (%s) is '
|
||||
. 'driver "%s" pointing at "%s". Tests only run against an '
|
||||
. 'in-memory SQLite database (driver "sqlite", database ":memory:") '
|
||||
. 'to avoid wiping real data via RefreshDatabase. Check phpunit.xml '
|
||||
. 'DB_CONNECTION/DB_DATABASE overrides.',
|
||||
$default,
|
||||
$driver,
|
||||
is_scalar($database) ? (string) $database : gettype($database)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user