test: setup database for upcoming tests

This commit is contained in:
Andras Bacsai
2024-12-04 12:43:52 +01:00
parent 51ed798789
commit 15ac12e131
8 changed files with 196 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ namespace App\Models;
use App\Enums\ApplicationDeploymentStatus; use App\Enums\ApplicationDeploymentStatus;
use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Process\InvokedProcess; use Illuminate\Process\InvokedProcess;
@@ -104,7 +105,7 @@ use Visus\Cuid2\Cuid2;
class Application extends BaseModel class Application extends BaseModel
{ {
use SoftDeletes; use HasFactory, SoftDeletes;
private static $parserVersion = '4'; private static $parserVersion = '4';

View File

@@ -11,6 +11,7 @@ use App\Notifications\Server\Reachable;
use App\Notifications\Server\Unreachable; use App\Notifications\Server\Unreachable;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -48,7 +49,7 @@ use Symfony\Component\Yaml\Yaml;
class Server extends BaseModel class Server extends BaseModel
{ {
use SchemalessAttributesTrait, SoftDeletes; use HasFactory, SchemalessAttributesTrait, SoftDeletes;
public static $batch_counter = 0; public static $batch_counter = 0;

View File

@@ -49,6 +49,22 @@ return [
'search_path' => 'public', 'search_path' => 'public',
'sslmode' => 'prefer', 'sslmode' => 'prefer',
], ],
'testing' => [
'driver' => 'pgsql',
'url' => env('DATABASE_TEST_URL'),
'host' => env('DB_TEST_HOST', 'postgres'),
'port' => env('DB_TEST_PORT', '5432'),
'database' => env('DB_TEST_DATABASE', 'coolify_test'),
'username' => env('DB_TEST_USERNAME', 'coolify'),
'password' => env('DB_TEST_PASSWORD', 'password'),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'search_path' => 'public',
'sslmode' => 'prefer',
],
], ],
/* /*

View File

@@ -0,0 +1,22 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class ApplicationFactory extends Factory
{
public function definition(): array
{
return [
'name' => fake()->unique()->name(),
'destination_id' => 1,
'git_repository' => fake()->url(),
'git_branch' => fake()->word(),
'build_pack' => 'nixpacks',
'ports_exposes' => '3000',
'environment_id' => 1,
'destination_id' => 1,
];
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class ServerFactory extends Factory
{
public function definition(): array
{
return [
'name' => fake()->unique()->name(),
'ip' => fake()->unique()->ipv4(),
'private_key_id' => 1,
];
}
}

View File

@@ -13,8 +13,8 @@
<env name="APP_ENV" value="testing"/> <env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/> <env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/> <env name="CACHE_DRIVER" value="array"/>
<!-- <env name="DB_CONNECTION" value="sqlite"/> --> <env name="DB_CONNECTION" value="testing"/>
<!-- <env name="DB_DATABASE" value=":memory:"/> --> <env name="DB_TEST_DATABASE" value="coolify_test"/>
<env name="MAIL_MAILER" value="array"/> <env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/> <env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/>

View File

@@ -0,0 +1,57 @@
<?php
namespace Tests\Feature;
use App\Models\Application;
use App\Models\Server;
use App\Models\User;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
use Tests\Traits\HandlesTestDatabase;
class ExecuteContainerCommandTest extends TestCase
{
use HandlesTestDatabase;
private $user;
private $team;
private $server;
private $application;
protected function setUp(): void
{
parent::setUp();
// Only set up database for tests that need it
if ($this->shouldSetUpDatabase()) {
$this->setUpTestDatabase();
}
// Create test data
$this->user = User::factory()->create();
$this->team = $this->user->teams()->first();
$this->server = Server::factory()->create(['team_id' => $this->team->id]);
$this->application = Application::factory()->create();
// Login the user
$this->actingAs($this->user);
}
protected function tearDown(): void
{
if ($this->shouldSetUpDatabase()) {
$this->tearDownTestDatabase();
}
parent::tearDown();
}
private function shouldSetUpDatabase(): bool
{
return in_array($this->name(), [
'it_allows_valid_container_access',
'it_prevents_cross_server_container_access',
]);
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Tests\Traits;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
trait HandlesTestDatabase
{
protected function setUpTestDatabase(): void
{
try {
// Create test database if it doesn't exist
$database = config('database.connections.testing.database');
$this->createTestDatabase($database);
// Run migrations
Artisan::call('migrate:fresh', [
'--database' => 'testing',
'--seed' => false,
]);
} catch (\Exception $e) {
$this->tearDownTestDatabase();
throw $e;
}
}
protected function tearDownTestDatabase(): void
{
try {
// Drop test database
$database = config('database.connections.testing.database');
$this->dropTestDatabase($database);
} catch (\Exception $e) {
// Log error but don't throw
error_log('Failed to tear down test database: '.$e->getMessage());
}
}
protected function createTestDatabase($database)
{
try {
// Connect to postgres database to create/drop test database
config(['database.connections.pgsql.database' => 'postgres']);
DB::purge('pgsql');
DB::reconnect('pgsql');
// Drop if exists and create new database
DB::connection('pgsql')->statement("DROP DATABASE IF EXISTS $database WITH (FORCE);");
DB::connection('pgsql')->statement("CREATE DATABASE $database;");
// Switch back to testing connection
DB::disconnect('pgsql');
DB::reconnect('testing');
} catch (\Exception $e) {
$this->tearDownTestDatabase();
throw new \Exception('Could not create test database: '.$e->getMessage());
}
}
protected function dropTestDatabase($database)
{
try {
// Connect to postgres database to drop test database
config(['database.connections.pgsql.database' => 'postgres']);
DB::purge('pgsql');
DB::reconnect('pgsql');
// Drop the test database
DB::connection('pgsql')->statement("DROP DATABASE IF EXISTS $database WITH (FORCE);");
DB::disconnect('pgsql');
} catch (\Exception $e) {
// Log error but don't throw
error_log('Failed to drop test database: '.$e->getMessage());
}
}
}