Files
Investidor-V2/tests/TestCase.php
T
nala 6ddafc95ba
tests / ci (push) Canceled after 0s
oportunidades 4
2026-10-10 07:03:59 +02:00

88 lines
4.5 KiB
PHP

<?php
namespace Tests;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Testing\RefreshDatabaseState;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Laravel\Fortify\Features;
abstract class TestCase extends BaseTestCase
{
/** @var array<string, resource> Locks held until this test process exits. */
private static array $qaDatabaseLocks = [];
public function createApplication(): Application
{
$app = parent::createApplication();
$connectionName = $app->make('config')->get('database.default');
$connection = $app->make('config')->get('database.connections.'.$connectionName, []);
// Never let a test runner silently fall back to the developer/application database.
// Keep this check before RefreshDatabase or any schema cleanup can open a connection.
if ($app->environment('testing') && ($connection['driver'] ?? null) === 'pgsql') {
$database = strtolower((string) ($connection['database'] ?? ''));
$host = strtolower((string) ($connection['host'] ?? ''));
$url = $connection['url'] ?? null;
if ($database === 'investemoz'
|| ! str_ends_with($database, '_test')
|| ! in_array($host, ['127.0.0.1', 'localhost'], true)
|| ! in_array($url, [null, ''], true)) {
throw new \LogicException('PHPUnit PostgreSQL target rejected: configure an explicit loopback *_test database with no DB_URL.');
}
// Two test processes must not migrate/clean the same isolated database concurrently.
$lockKey = hash('sha256', $host.':'.($connection['port'] ?? '').':'.$database);
if (! isset(self::$qaDatabaseLocks[$lockKey])) {
$handle = fopen($app->storagePath('framework/qa-database-'.$lockKey.'.lock'), 'c');
if ($handle === false) {
throw new \LogicException('QA database execution lock unavailable.');
}
if (! flock($handle, LOCK_EX | LOCK_NB)) {
fclose($handle);
throw new \LogicException('Another test process owns this QA database; run suites sequentially or use separate *_test databases.');
}
self::$qaDatabaseLocks[$lockKey] = $handle;
}
}
// migrate:fresh only clears the connection's public search path. This module owns a separate schema.
if (! RefreshDatabaseState::$migrated && $app->environment('testing')) {
$db = $app->make('db')->connection();
if ($db->getDriverName() === 'pgsql'
&& in_array($db->getDatabaseName(), ['portal_services_test', 'investmoz_test', 'investmoz_browser_e2e_test', 'investmoz_guidance_20261008_test', 'investmoz_v2_20261008_test'], true)
&& (string) $db->getConfig('port') === '55441'
&& in_array($db->getConfig('host'), ['127.0.0.1', 'localhost'], true)) {
$db->statement('DROP SCHEMA IF EXISTS skills_edu CASCADE');
if ($db->selectOne("SELECT to_regclass('public.complementary_project_links') AS id")->id !== null) {
$db->statement('DROP TRIGGER IF EXISTS project_dependency_check ON public.complementary_project_links');
$db->statement('DROP TRIGGER IF EXISTS project_dependency_lock ON public.complementary_project_links');
}
$db->statement('DROP FUNCTION IF EXISTS public.check_project_dependency_graph() RESTRICT');
$db->statement('DROP FUNCTION IF EXISTS public.lock_project_dependency_graph() RESTRICT');
if ($db->selectOne("SELECT to_regclass('public.existing_business_locations') AS id")->id !== null) {
$db->statement('DROP TRIGGER IF EXISTS existing_business_locations_hierarchy_trigger ON public.existing_business_locations');
}
$db->statement('DROP FUNCTION IF EXISTS public.enforce_existing_business_location_hierarchy() RESTRICT');
}
}
return $app;
}
protected function setUp(): void
{
parent::setUp();
// HTTP feature tests must not depend on the developer's Vite SSR server.
config(['inertia.ssr.enabled' => false]);
}
protected function skipUnlessFortifyHas(string $feature, ?string $message = null): void
{
if (! Features::enabled($feature)) {
$this->markTestSkipped($message ?? "Fortify feature [{$feature}] is not enabled.");
}
}
}