mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-02 22:46:16 +00:00
@ -184,4 +184,70 @@ public function test_update_env_file(): void
|
||||
|
||||
SSH::assertExecutedContains('echo "APP_ENV=production" | tee /home/vito/'.$this->site->domain.'/.env');
|
||||
}
|
||||
|
||||
public function test_git_hook_deployment(): void
|
||||
{
|
||||
SSH::fake();
|
||||
Http::fake([
|
||||
'github.com/*' => Http::response([
|
||||
'sha' => '123',
|
||||
'commit' => [
|
||||
'message' => 'test commit message',
|
||||
'name' => 'test commit name',
|
||||
'email' => 'user@example.com',
|
||||
'url' => 'https://github.com',
|
||||
],
|
||||
], 200),
|
||||
]);
|
||||
|
||||
$hook = GitHook::factory()->create([
|
||||
'site_id' => $this->site->id,
|
||||
'source_control_id' => $this->site->source_control_id,
|
||||
'secret' => 'secret',
|
||||
'events' => ['push'],
|
||||
'actions' => ['deploy'],
|
||||
]);
|
||||
|
||||
$this->site->deploymentScript->update([
|
||||
'content' => 'git pull',
|
||||
]);
|
||||
|
||||
$this->post(route('git-hooks'), [
|
||||
'secret' => 'secret',
|
||||
])->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('deployments', [
|
||||
'site_id' => $this->site->id,
|
||||
'deployment_script_id' => $this->site->deploymentScript->id,
|
||||
'status' => DeploymentStatus::FINISHED,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_git_hook_deployment_invalid_secret(): void
|
||||
{
|
||||
SSH::fake();
|
||||
Http::fake();
|
||||
|
||||
$hook = GitHook::factory()->create([
|
||||
'site_id' => $this->site->id,
|
||||
'source_control_id' => $this->site->source_control_id,
|
||||
'secret' => 'secret',
|
||||
'events' => ['push'],
|
||||
'actions' => ['deploy'],
|
||||
]);
|
||||
|
||||
$this->site->deploymentScript->update([
|
||||
'content' => 'git pull',
|
||||
]);
|
||||
|
||||
$this->post(route('git-hooks'), [
|
||||
'secret' => 'invalid-secret',
|
||||
])->assertNotFound();
|
||||
|
||||
$this->assertDatabaseMissing('deployments', [
|
||||
'site_id' => $this->site->id,
|
||||
'deployment_script_id' => $this->site->deploymentScript->id,
|
||||
'status' => DeploymentStatus::FINISHED,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -37,4 +37,11 @@ public function test_users_can_not_authenticate_with_invalid_password(): void
|
||||
|
||||
$this->assertGuest();
|
||||
}
|
||||
|
||||
public function test_redirect_if_not_authenticated(): void
|
||||
{
|
||||
$response = $this->get('/servers');
|
||||
|
||||
$response->assertRedirect('/login');
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Actions\Database\RunBackup;
|
||||
use App\Enums\BackupFileStatus;
|
||||
use App\Enums\BackupStatus;
|
||||
use App\Facades\SSH;
|
||||
@ -9,6 +10,7 @@
|
||||
use App\Models\Database;
|
||||
use App\Models\StorageProvider;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Bus;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Tests\TestCase;
|
||||
|
||||
@ -48,6 +50,34 @@ public function test_create_backup(): void
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_create_custom_interval_backup(): void
|
||||
{
|
||||
Bus::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$database = Database::factory()->create([
|
||||
'server_id' => $this->server,
|
||||
]);
|
||||
|
||||
$storage = StorageProvider::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'provider' => \App\Enums\StorageProvider::DROPBOX,
|
||||
]);
|
||||
|
||||
$this->post(route('servers.databases.backups.store', $this->server), [
|
||||
'backup_database' => $database->id,
|
||||
'backup_storage' => $storage->id,
|
||||
'backup_interval' => 'custom',
|
||||
'backup_custom' => '* * * * *',
|
||||
'backup_keep' => '10',
|
||||
])->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('backups', [
|
||||
'status' => BackupStatus::RUNNING,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_see_backups_list(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
@ -97,4 +127,43 @@ public function test_delete_backup(): void
|
||||
'id' => $backup->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_restore_backup(): void
|
||||
{
|
||||
Http::fake();
|
||||
SSH::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$database = Database::factory()->create([
|
||||
'server_id' => $this->server,
|
||||
]);
|
||||
|
||||
$storage = StorageProvider::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'provider' => \App\Enums\StorageProvider::DROPBOX,
|
||||
]);
|
||||
|
||||
$backup = Backup::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'database_id' => $database->id,
|
||||
'storage_id' => $storage->id,
|
||||
]);
|
||||
|
||||
$backupFile = app(RunBackup::class)->run($backup);
|
||||
|
||||
$this->post(route('servers.databases.backups.files.restore', [
|
||||
'server' => $this->server,
|
||||
'backup' => $backup,
|
||||
'backupFile' => $backupFile,
|
||||
]), [
|
||||
'database' => $database->id,
|
||||
])
|
||||
->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('backup_files', [
|
||||
'id' => $backupFile->id,
|
||||
'status' => BackupFileStatus::RESTORED,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Enums\DatabaseStatus;
|
||||
use App\Enums\DatabaseUserStatus;
|
||||
use App\Facades\SSH;
|
||||
use App\Models\Database;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
@ -28,6 +29,34 @@ public function test_create_database(): void
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_create_database_with_user(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
SSH::fake();
|
||||
|
||||
$this->post(route('servers.databases.store', $this->server), [
|
||||
'name' => 'database',
|
||||
'user' => 'on',
|
||||
'username' => 'user',
|
||||
'password' => 'password',
|
||||
'remote' => 'on',
|
||||
'host' => '%',
|
||||
])->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('databases', [
|
||||
'name' => 'database',
|
||||
'status' => DatabaseStatus::READY,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('database_users', [
|
||||
'username' => 'user',
|
||||
'databases' => json_encode(['database']),
|
||||
'host' => '%',
|
||||
'status' => DatabaseUserStatus::READY,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_see_databases_list(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
@ -29,6 +29,26 @@ public function test_create_database_user(): void
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_create_database_user_with_remote(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
SSH::fake();
|
||||
|
||||
$this->post(route('servers.databases.users.store', $this->server), [
|
||||
'username' => 'user',
|
||||
'password' => 'password',
|
||||
'remote' => 'on',
|
||||
'host' => '%',
|
||||
])->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('database_users', [
|
||||
'username' => 'user',
|
||||
'host' => '%',
|
||||
'status' => DatabaseUserStatus::READY,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_see_database_users_list(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
@ -58,4 +78,26 @@ public function test_delete_database_user(): void
|
||||
'id' => $databaseUser->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_unlink_database(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
SSH::fake();
|
||||
|
||||
$databaseUser = DatabaseUser::factory()->create([
|
||||
'server_id' => $this->server,
|
||||
]);
|
||||
|
||||
$this->post(route('servers.databases.users.link', [
|
||||
'server' => $this->server,
|
||||
'databaseUser' => $databaseUser,
|
||||
]), [])
|
||||
->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('database_users', [
|
||||
'username' => $databaseUser->username,
|
||||
'databases' => json_encode([]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -26,12 +26,35 @@ public function test_add_email_channel(): void
|
||||
/** @var \App\Models\NotificationChannel $channel */
|
||||
$channel = \App\Models\NotificationChannel::query()
|
||||
->where('provider', NotificationChannel::EMAIL)
|
||||
->where('label', 'Email')
|
||||
->first();
|
||||
|
||||
$this->assertEquals('email@example.com', $channel->data['email']);
|
||||
$this->assertTrue($channel->connected);
|
||||
}
|
||||
|
||||
public function test_cannot_add_email_channel(): void
|
||||
{
|
||||
config()->set('mail.default', 'smtp');
|
||||
config()->set('mail.mailers.smtp.host', '127.0.0.1'); // invalid host
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->post(route('notification-channels.add'), [
|
||||
'provider' => NotificationChannel::EMAIL,
|
||||
'email' => 'email@example.com',
|
||||
'label' => 'Email',
|
||||
])->assertSessionHasErrors();
|
||||
|
||||
/** @var \App\Models\NotificationChannel $channel */
|
||||
$channel = \App\Models\NotificationChannel::query()
|
||||
->where('provider', NotificationChannel::EMAIL)
|
||||
->where('label', 'Email')
|
||||
->first();
|
||||
|
||||
$this->assertNull($channel);
|
||||
}
|
||||
|
||||
public function test_add_slack_channel(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
@ -53,6 +76,28 @@ public function test_add_slack_channel(): void
|
||||
$this->assertTrue($channel->connected);
|
||||
}
|
||||
|
||||
public function test_cannot_add_slack_channel(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
Http::fake([
|
||||
'slack.com/*' => Http::response(['ok' => false], 401),
|
||||
]);
|
||||
|
||||
$this->post(route('notification-channels.add'), [
|
||||
'provider' => NotificationChannel::SLACK,
|
||||
'webhook_url' => 'https://hooks.slack.com/services/123/token',
|
||||
'label' => 'Slack',
|
||||
])->assertSessionHasErrors();
|
||||
|
||||
/** @var \App\Models\NotificationChannel $channel */
|
||||
$channel = \App\Models\NotificationChannel::query()
|
||||
->where('provider', NotificationChannel::SLACK)
|
||||
->first();
|
||||
|
||||
$this->assertNull($channel);
|
||||
}
|
||||
|
||||
public function test_add_discord_channel(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
@ -74,9 +119,27 @@ public function test_add_discord_channel(): void
|
||||
$this->assertTrue($channel->connected);
|
||||
}
|
||||
|
||||
/*
|
||||
* @TODO fix json comparison
|
||||
*/
|
||||
public function test_cannot_add_discord_channel(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
Http::fake([
|
||||
'discord.com/*' => Http::response(['ok' => false], 401),
|
||||
]);
|
||||
|
||||
$this->post(route('notification-channels.add'), [
|
||||
'provider' => NotificationChannel::DISCORD,
|
||||
'webhook_url' => 'https://discord.com/api/webhooks/123/token',
|
||||
'label' => 'Discord',
|
||||
])->assertSessionHasErrors();
|
||||
|
||||
/** @var \App\Models\NotificationChannel $channel */
|
||||
$channel = \App\Models\NotificationChannel::query()
|
||||
->where('provider', NotificationChannel::DISCORD)
|
||||
->first();
|
||||
|
||||
$this->assertNull($channel);
|
||||
}
|
||||
|
||||
public function test_add_telegram_channel(): void
|
||||
{
|
||||
@ -101,6 +164,29 @@ public function test_add_telegram_channel(): void
|
||||
$this->assertTrue($channel->connected);
|
||||
}
|
||||
|
||||
public function test_cannot_add_telegram_channel(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
Http::fake([
|
||||
'api.telegram.org/*' => Http::response(['ok' => false], 401),
|
||||
]);
|
||||
|
||||
$this->post(route('notification-channels.add'), [
|
||||
'provider' => NotificationChannel::TELEGRAM,
|
||||
'bot_token' => 'token',
|
||||
'chat_id' => '123',
|
||||
'label' => 'Telegram',
|
||||
])->assertSessionHasErrors();
|
||||
|
||||
/** @var \App\Models\NotificationChannel $channel */
|
||||
$channel = \App\Models\NotificationChannel::query()
|
||||
->where('provider', NotificationChannel::TELEGRAM)
|
||||
->first();
|
||||
|
||||
$this->assertNull($channel);
|
||||
}
|
||||
|
||||
public function test_see_channels_list(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
@ -135,4 +135,32 @@ public function test_extension_already_installed(): void
|
||||
'extension' => 'gmp',
|
||||
]))->assertSessionHasErrors();
|
||||
}
|
||||
|
||||
public function test_get_php_ini(): void
|
||||
{
|
||||
SSH::fake('[PHP ini]');
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->get(route('servers.php.get-ini', [
|
||||
'server' => $this->server,
|
||||
'version' => '8.2',
|
||||
]))->assertSessionHas('ini');
|
||||
}
|
||||
|
||||
public function test_update_php_ini(): void
|
||||
{
|
||||
SSH::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->post(route('servers.php.update-ini', [
|
||||
'server' => $this->server,
|
||||
'version' => '8.2',
|
||||
'ini' => 'new ini',
|
||||
]))
|
||||
->assertSessionDoesntHaveErrors()
|
||||
->assertSessionHas('toast.type', 'success')
|
||||
->assertSessionHas('toast.message', 'PHP ini updated!');
|
||||
}
|
||||
}
|
||||
|
@ -68,4 +68,16 @@ public function test_edit_project(): void
|
||||
'name' => 'new-name',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_cannot_delete_last_project(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->delete(route('projects.delete', [
|
||||
'project' => $this->user->currentProject,
|
||||
]))
|
||||
->assertSessionDoesntHaveErrors()
|
||||
->assertSessionHas('toast.type', 'error')
|
||||
->assertSessionHas('toast.message', 'Cannot delete the last project.');
|
||||
}
|
||||
}
|
||||
|
@ -86,4 +86,85 @@ public function test_create_queue()
|
||||
'status' => QueueStatus::RUNNING,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_start_queue(): void
|
||||
{
|
||||
SSH::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$queue = Queue::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'site_id' => $this->site->id,
|
||||
'status' => QueueStatus::STOPPED,
|
||||
]);
|
||||
|
||||
$this->post(
|
||||
route('servers.sites.queues.action', [
|
||||
'action' => 'start',
|
||||
'server' => $this->server,
|
||||
'site' => $this->site,
|
||||
'queue' => $queue,
|
||||
])
|
||||
)->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('queues', [
|
||||
'id' => $queue->id,
|
||||
'status' => QueueStatus::RUNNING,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_stop_queue(): void
|
||||
{
|
||||
SSH::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$queue = Queue::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'site_id' => $this->site->id,
|
||||
'status' => QueueStatus::RUNNING,
|
||||
]);
|
||||
|
||||
$this->post(
|
||||
route('servers.sites.queues.action', [
|
||||
'action' => 'stop',
|
||||
'server' => $this->server,
|
||||
'site' => $this->site,
|
||||
'queue' => $queue,
|
||||
])
|
||||
)->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('queues', [
|
||||
'id' => $queue->id,
|
||||
'status' => QueueStatus::STOPPED,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_restart_queue(): void
|
||||
{
|
||||
SSH::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$queue = Queue::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'site_id' => $this->site->id,
|
||||
'status' => QueueStatus::RUNNING,
|
||||
]);
|
||||
|
||||
$this->post(
|
||||
route('servers.sites.queues.action', [
|
||||
'action' => 'restart',
|
||||
'server' => $this->server,
|
||||
'site' => $this->site,
|
||||
'queue' => $queue,
|
||||
])
|
||||
)->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('queues', [
|
||||
'id' => $queue->id,
|
||||
'status' => QueueStatus::RUNNING,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -11,20 +11,52 @@ class ServerProvidersTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_connect_hetzner(): void
|
||||
/**
|
||||
* @dataProvider data
|
||||
*/
|
||||
public function test_connect_provider(string $provider, array $input): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
Http::fake();
|
||||
|
||||
$this->post(route('server-providers.connect'), [
|
||||
'provider' => ServerProvider::HETZNER,
|
||||
'name' => 'profile',
|
||||
'token' => 'token',
|
||||
])->assertSessionDoesntHaveErrors();
|
||||
$data = array_merge(
|
||||
[
|
||||
'provider' => $provider,
|
||||
'name' => 'profile',
|
||||
],
|
||||
$input
|
||||
);
|
||||
$this->post(route('server-providers.connect'), $data)->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('server_providers', [
|
||||
'provider' => ServerProvider::HETZNER,
|
||||
'provider' => $provider,
|
||||
'profile' => 'profile',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data
|
||||
*/
|
||||
public function test_cannot_connect_to_provider(string $provider, array $input): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
Http::fake([
|
||||
'*' => Http::response([], 401),
|
||||
]);
|
||||
|
||||
$data = array_merge(
|
||||
[
|
||||
'provider' => $provider,
|
||||
'name' => 'profile',
|
||||
],
|
||||
$input
|
||||
);
|
||||
$this->post(route('server-providers.connect'), $data)->assertSessionHasErrors();
|
||||
|
||||
$this->assertDatabaseMissing('server_providers', [
|
||||
'provider' => $provider,
|
||||
'profile' => 'profile',
|
||||
]);
|
||||
}
|
||||
@ -41,19 +73,86 @@ public function test_see_providers_list(): void
|
||||
->assertSee($provider->profile);
|
||||
}
|
||||
|
||||
public function test_delete_provider(): void
|
||||
/**
|
||||
* @dataProvider data
|
||||
*/
|
||||
public function test_delete_provider(string $provider): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$provider = \App\Models\ServerProvider::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'provider' => $provider,
|
||||
]);
|
||||
|
||||
$this->delete(route('server-providers.delete', $provider->id))
|
||||
$this->delete(route('server-providers.delete', $provider))
|
||||
->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseMissing('server_providers', [
|
||||
'id' => $provider->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data
|
||||
*/
|
||||
public function test_cannot_delete_provider(string $provider): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$provider = \App\Models\ServerProvider::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'provider' => $provider,
|
||||
]);
|
||||
|
||||
$this->server->update([
|
||||
'provider_id' => $provider->id,
|
||||
]);
|
||||
|
||||
$this->delete(route('server-providers.delete', $provider))
|
||||
->assertSessionDoesntHaveErrors()
|
||||
->assertSessionHas('toast.type', 'error')
|
||||
->assertSessionHas('toast.message', 'This server provider is being used by a server.');
|
||||
|
||||
$this->assertDatabaseHas('server_providers', [
|
||||
'id' => $provider->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public static function data(): array
|
||||
{
|
||||
return [
|
||||
// [
|
||||
// ServerProvider::AWS,
|
||||
// [
|
||||
// 'key' => 'key',
|
||||
// 'secret' => 'secret',
|
||||
// ],
|
||||
// ],
|
||||
[
|
||||
ServerProvider::LINODE,
|
||||
[
|
||||
'token' => 'token',
|
||||
],
|
||||
],
|
||||
[
|
||||
ServerProvider::DIGITALOCEAN,
|
||||
[
|
||||
'token' => 'token',
|
||||
],
|
||||
],
|
||||
[
|
||||
ServerProvider::VULTR,
|
||||
[
|
||||
'token' => 'token',
|
||||
],
|
||||
],
|
||||
[
|
||||
ServerProvider::HETZNER,
|
||||
[
|
||||
'token' => 'token',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -10,17 +10,17 @@
|
||||
use App\Enums\ServiceStatus;
|
||||
use App\Enums\Webserver;
|
||||
use App\Facades\SSH;
|
||||
use App\NotificationChannels\Email\NotificationMail;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @TODO add more tests
|
||||
*/
|
||||
class ServerTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_create_custom_server(): void
|
||||
public function test_create_regular_server(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
@ -76,6 +76,62 @@ public function test_create_custom_server(): void
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_create_database_server(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
SSH::fake('Active: active'); // fake output for service installations
|
||||
|
||||
$this->post(route('servers.create'), [
|
||||
'type' => ServerType::DATABASE,
|
||||
'provider' => ServerProvider::CUSTOM,
|
||||
'name' => 'test',
|
||||
'ip' => '2.2.2.2',
|
||||
'port' => '22',
|
||||
'os' => OperatingSystem::UBUNTU22,
|
||||
'database' => Database::MYSQL80,
|
||||
])->assertSessionDoesntHaveErrors();
|
||||
|
||||
$server = \App\Models\Server::query()->where('ip', '2.2.2.2')->first();
|
||||
|
||||
$this->assertDatabaseHas('servers', [
|
||||
'name' => 'test',
|
||||
'ip' => '2.2.2.2',
|
||||
'status' => ServerStatus::READY,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseMissing('services', [
|
||||
'server_id' => $server->id,
|
||||
'type' => 'php',
|
||||
'version' => '8.2',
|
||||
'status' => ServiceStatus::READY,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseMissing('services', [
|
||||
'server_id' => $server->id,
|
||||
'type' => 'webserver',
|
||||
'name' => 'nginx',
|
||||
'version' => 'latest',
|
||||
'status' => ServiceStatus::READY,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('services', [
|
||||
'server_id' => $server->id,
|
||||
'type' => 'database',
|
||||
'name' => 'mysql',
|
||||
'version' => '8.0',
|
||||
'status' => ServiceStatus::READY,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('services', [
|
||||
'server_id' => $server->id,
|
||||
'type' => 'firewall',
|
||||
'name' => 'ufw',
|
||||
'version' => 'latest',
|
||||
'status' => ServiceStatus::READY,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_delete_server(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
@ -89,4 +145,139 @@ public function test_delete_server(): void
|
||||
'id' => $this->server->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_cannot_delete_on_provider(): void
|
||||
{
|
||||
Mail::fake();
|
||||
Http::fake([
|
||||
'*' => Http::response([], 401),
|
||||
]);
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$provider = \App\Models\ServerProvider::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'provider' => ServerProvider::HETZNER,
|
||||
'credentials' => [
|
||||
'token' => 'token',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->server->update([
|
||||
'provider' => ServerProvider::HETZNER,
|
||||
'provider_id' => $provider->id,
|
||||
'provider_data' => [
|
||||
'hetzner_id' => 1,
|
||||
'ssh_key_id' => 1,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->delete(route('servers.delete', $this->server))
|
||||
->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseMissing('servers', [
|
||||
'id' => $this->server->id,
|
||||
]);
|
||||
|
||||
Mail::assertSent(NotificationMail::class);
|
||||
}
|
||||
|
||||
public function test_check_connection_is_ready(): void
|
||||
{
|
||||
SSH::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->server->update(['status' => ServerStatus::DISCONNECTED]);
|
||||
|
||||
$this->post(route('servers.settings.check-connection', $this->server))
|
||||
->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('servers', [
|
||||
'id' => $this->server->id,
|
||||
'status' => ServerStatus::READY,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_connection_failed(): void
|
||||
{
|
||||
SSH::fake()->connectionWillFail();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->server->update(['status' => ServerStatus::READY]);
|
||||
|
||||
$this->post(route('servers.settings.check-connection', $this->server))
|
||||
->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('servers', [
|
||||
'id' => $this->server->id,
|
||||
'status' => ServerStatus::DISCONNECTED,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_reboot_server(): void
|
||||
{
|
||||
SSH::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->post(route('servers.settings.reboot', $this->server))
|
||||
->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('servers', [
|
||||
'id' => $this->server->id,
|
||||
'status' => ServerStatus::DISCONNECTED,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_edit_server(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->post(route('servers.settings.edit', $this->server), [
|
||||
'name' => 'new-name',
|
||||
])->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('servers', [
|
||||
'id' => $this->server->id,
|
||||
'name' => 'new-name',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_edit_server_ip_address(): void
|
||||
{
|
||||
SSH::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->post(route('servers.settings.edit', $this->server), [
|
||||
'ip' => '2.2.2.2',
|
||||
])->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('servers', [
|
||||
'id' => $this->server->id,
|
||||
'ip' => '2.2.2.2',
|
||||
'status' => ServerStatus::READY,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_edit_server_ip_address_and_disconnect(): void
|
||||
{
|
||||
SSH::fake()->connectionWillFail();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->post(route('servers.settings.edit', $this->server), [
|
||||
'ip' => '2.2.2.2',
|
||||
'port' => 2222,
|
||||
])->assertSessionDoesntHaveErrors();
|
||||
|
||||
$this->assertDatabaseHas('servers', [
|
||||
'id' => $this->server->id,
|
||||
'ip' => '2.2.2.2',
|
||||
'port' => 2222,
|
||||
'status' => ServerStatus::DISCONNECTED,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -160,4 +160,16 @@ public static function create_data(): array
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function test_see_logs(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$this->get(route('servers.sites.logs', [
|
||||
'server' => $this->server,
|
||||
'site' => $this->site,
|
||||
]))
|
||||
->assertOk()
|
||||
->assertSee('Logs');
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
use App\Models\SourceControl;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use JsonException;
|
||||
use Tests\TestCase;
|
||||
|
||||
class SourceControlsTest extends TestCase
|
||||
@ -14,8 +13,6 @@ class SourceControlsTest extends TestCase
|
||||
|
||||
/**
|
||||
* @dataProvider data
|
||||
*
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function test_connect_provider(string $provider, ?string $customUrl): void
|
||||
{
|
||||
@ -43,8 +40,6 @@ public function test_connect_provider(string $provider, ?string $customUrl): voi
|
||||
|
||||
/**
|
||||
* @dataProvider data
|
||||
*
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function test_delete_provider(string $provider): void
|
||||
{
|
||||
@ -64,6 +59,33 @@ public function test_delete_provider(string $provider): void
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data
|
||||
*/
|
||||
public function test_cannot_delete_provider(string $provider): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
/** @var SourceControl $sourceControl */
|
||||
$sourceControl = SourceControl::factory()->create([
|
||||
'provider' => $provider,
|
||||
'profile' => 'test',
|
||||
]);
|
||||
|
||||
$this->site->update([
|
||||
'source_control_id' => $sourceControl->id,
|
||||
]);
|
||||
|
||||
$this->delete(route('source-controls.delete', $sourceControl->id))
|
||||
->assertSessionDoesntHaveErrors()
|
||||
->assertSessionHas('toast.type', 'error')
|
||||
->assertSessionHas('toast.message', 'This source control is being used by a site.');
|
||||
|
||||
$this->assertDatabaseHas('source_controls', [
|
||||
'id' => $sourceControl->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public static function data(): array
|
||||
{
|
||||
return [
|
||||
|
@ -3,6 +3,8 @@
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Enums\StorageProvider;
|
||||
use App\Models\Backup;
|
||||
use App\Models\Database;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Tests\TestCase;
|
||||
@ -57,4 +59,32 @@ public function test_delete_provider(): void
|
||||
'id' => $provider->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_cannot_delete_provider(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$database = Database::factory()->create([
|
||||
'server_id' => $this->server,
|
||||
]);
|
||||
|
||||
$provider = \App\Models\StorageProvider::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
Backup::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'database_id' => $database->id,
|
||||
'storage_id' => $provider->id,
|
||||
]);
|
||||
|
||||
$this->delete(route('storage-providers.delete', $provider->id))
|
||||
->assertSessionDoesntHaveErrors()
|
||||
->assertSessionHas('toast.type', 'error')
|
||||
->assertSessionHas('toast.message', 'This storage provider is being used by a backup.');
|
||||
|
||||
$this->assertDatabaseHas('storage_providers', [
|
||||
'id' => $provider->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user