API Feature (#334)

This commit is contained in:
Saeed Vaziry
2024-11-01 16:49:57 +01:00
committed by GitHub
parent da7b24640e
commit 417bf73e44
143 changed files with 36520 additions and 586 deletions

View File

@ -0,0 +1,79 @@
<?php
namespace Tests\Feature\API;
use App\Enums\CronjobStatus;
use App\Facades\SSH;
use App\Models\CronJob;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class CronjobTest extends TestCase
{
use RefreshDatabase;
public function test_see_cronjobs_list()
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var CronJob $cronjob */
$cronjob = CronJob::factory()->create([
'server_id' => $this->server->id,
]);
$this->json('GET', route('api.projects.servers.cron-jobs', [
'project' => $this->server->project,
'server' => $this->server,
]))
->assertSuccessful()
->assertJsonFragment([
'command' => $cronjob->command,
'frequency' => $cronjob->frequency,
]);
}
public function test_create_cronjob()
{
SSH::fake();
Sanctum::actingAs($this->user, ['read', 'write']);
$this->json('POST', route('api.projects.servers.cron-jobs.create', [
'project' => $this->server->project,
'server' => $this->server,
]), [
'command' => 'ls -la',
'user' => 'vito',
'frequency' => '* * * * *',
])
->assertSuccessful()
->assertJsonFragment([
'command' => 'ls -la',
'user' => 'vito',
'frequency' => '* * * * *',
'status' => CronjobStatus::READY,
]);
}
public function test_delete_cronjob()
{
SSH::fake();
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var CronJob $cronjob */
$cronjob = CronJob::factory()->create([
'server_id' => $this->server->id,
'user' => 'vito',
]);
$this->json('DELETE', route('api.projects.servers.cron-jobs.delete', [
'project' => $this->server->project,
'server' => $this->server,
'cronJob' => $cronjob,
]))
->assertSuccessful()
->assertNoContent();
}
}

View File

@ -0,0 +1,93 @@
<?php
namespace Tests\Feature\API;
use App\Enums\DatabaseStatus;
use App\Facades\SSH;
use App\Models\Database;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class DatabaseTest extends TestCase
{
use RefreshDatabase;
public function test_create_database(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
SSH::fake();
$this->json('POST', route('api.projects.servers.databases.create', [
'project' => $this->server->project,
'server' => $this->server,
]), [
'name' => 'database',
])
->assertSuccessful()
->assertJsonFragment([
'name' => 'database',
'status' => DatabaseStatus::READY,
]);
}
public function test_show_database(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var Database $database */
$database = Database::factory()->create([
'server_id' => $this->server,
]);
$this->json('GET', route('api.projects.servers.databases.show', [
'project' => $this->server->project,
'server' => $this->server,
'database' => $database,
]))
->assertSuccessful()
->assertJsonFragment([
'name' => $database->name,
]);
}
public function test_see_databases_list(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var Database $database */
$database = Database::factory()->create([
'server_id' => $this->server,
]);
$this->json('GET', route('api.projects.servers.databases', [
'project' => $this->server->project,
'server' => $this->server,
]))
->assertSuccessful()
->assertJsonFragment([
'name' => $database->name,
]);
}
public function test_delete_database(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
SSH::fake();
/** @var Database $database */
$database = Database::factory()->create([
'server_id' => $this->server,
]);
$this->json('DELETE', route('api.projects.servers.databases.delete', [
'project' => $this->server->project,
'server' => $this->server,
'database' => $database,
]))
->assertSuccessful()
->assertNoContent();
}
}

View File

@ -0,0 +1,146 @@
<?php
namespace Tests\Feature\API;
use App\Enums\DatabaseUserStatus;
use App\Facades\SSH;
use App\Models\Database;
use App\Models\DatabaseUser;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class DatabaseUserTest extends TestCase
{
use RefreshDatabase;
public function test_create_database_user(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
SSH::fake();
$this->json('POST', route('api.projects.servers.database-users.create', [
'project' => $this->server->project,
'server' => $this->server,
]), [
'username' => 'user',
'password' => 'password',
])
->assertSuccessful()
->assertJsonFragment([
'username' => 'user',
'status' => DatabaseUserStatus::READY,
]);
}
public function test_create_database_user_with_remote(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
SSH::fake();
$this->json('POST', route('api.projects.servers.database-users.create', [
'project' => $this->server->project,
'server' => $this->server,
]), [
'username' => 'user',
'password' => 'password',
'host' => '%',
])
->assertSuccessful()
->assertJsonFragment([
'username' => 'user',
'host' => '%',
'status' => DatabaseUserStatus::READY,
]);
}
public function test_see_database_users_list(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var DatabaseUser $databaseUser */
$databaseUser = DatabaseUser::factory()->create([
'server_id' => $this->server,
]);
$this->json('GET', route('api.projects.servers.database-users', [
'project' => $this->server->project,
'server' => $this->server,
]))
->assertSuccessful()
->assertJsonFragment([
'username' => $databaseUser->username,
]);
}
public function test_show_database_user(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var DatabaseUser $databaseUser */
$databaseUser = DatabaseUser::factory()->create([
'server_id' => $this->server,
]);
$this->json('GET', route('api.projects.servers.database-users.show', [
'project' => $this->server->project,
'server' => $this->server,
'databaseUser' => $databaseUser,
]))
->assertSuccessful()
->assertJsonFragment([
'username' => $databaseUser->username,
]);
}
public function test_link_database(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
SSH::fake();
/** @var Database $database */
$database = Database::factory()->create([
'server_id' => $this->server,
]);
/** @var DatabaseUser $databaseUser */
$databaseUser = DatabaseUser::factory()->create([
'server_id' => $this->server,
]);
$this->json('POST', route('api.projects.servers.database-users.link', [
'project' => $this->server->project,
'server' => $this->server,
'databaseUser' => $databaseUser,
]), [
'databases' => [$database->name],
])
->assertSuccessful()
->assertJsonFragment([
'username' => $databaseUser->username,
'databases' => [$database->name],
]);
}
public function test_delete_database_user(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
SSH::fake();
/** @var DatabaseUser $databaseUser */
$databaseUser = DatabaseUser::factory()->create([
'server_id' => $this->server,
]);
$this->json('DELETE', route('api.projects.servers.database-users.delete', [
'project' => $this->server->project,
'server' => $this->server,
'databaseUser' => $databaseUser,
]))
->assertNoContent();
}
}

View File

@ -0,0 +1,77 @@
<?php
namespace Tests\Feature\API;
use App\Enums\FirewallRuleStatus;
use App\Facades\SSH;
use App\Models\FirewallRule;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class FirewallTest extends TestCase
{
use RefreshDatabase;
public function test_create_firewall_rule(): void
{
SSH::fake();
Sanctum::actingAs($this->user, ['read', 'write']);
$this->json('POST', route('api.projects.servers.firewall-rules.create', [
'project' => $this->server->project,
'server' => $this->server,
]), [
'type' => 'allow',
'protocol' => 'tcp',
'port' => '1234',
'source' => '0.0.0.0',
'mask' => '0',
])
->assertSuccessful()
->assertJsonFragment([
'port' => 1234,
'status' => FirewallRuleStatus::READY,
]);
}
public function test_see_firewall_rules(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var FirewallRule $rule */
$rule = FirewallRule::factory()->create([
'server_id' => $this->server->id,
]);
$this->json('GET', route('api.projects.servers.firewall-rules', [
'project' => $this->server->project,
'server' => $this->server,
]))
->assertSuccessful()
->assertJsonFragment([
'source' => $rule->source,
'port' => $rule->port,
]);
}
public function test_delete_firewall_rule(): void
{
SSH::fake();
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var FirewallRule $rule */
$rule = FirewallRule::factory()->create([
'server_id' => $this->server->id,
]);
$this->json('DELETE', route('api.projects.servers.firewall-rules.delete', [
'project' => $this->server->project,
'server' => $this->server,
'firewallRule' => $rule,
]))
->assertNoContent();
}
}

View File

@ -0,0 +1,94 @@
<?php
namespace Tests\Feature\API;
use App\Models\Project;
use App\Web\Pages\Settings\Projects\Settings;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Livewire\Livewire;
use Tests\TestCase;
class ProjectsTest extends TestCase
{
use RefreshDatabase;
public function test_create_project(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$this->json('POST', '/api/projects', [
'name' => 'test',
])
->assertSuccessful();
$this->assertDatabaseHas('projects', [
'name' => 'test',
]);
}
public function test_see_projects_list(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$project = Project::factory()->create();
$this->user->projects()->attach($project);
$this->json('GET', '/api/projects')
->assertSuccessful()
->assertJsonFragment([
'name' => $project->name,
]);
}
public function test_delete_project(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$project = Project::factory()->create();
$this->user->projects()->attach($project);
Livewire::test(Settings::class, [
'project' => $project,
])
->callAction('delete')
->assertSuccessful();
$this->assertDatabaseMissing('projects', [
'id' => $project->id,
]);
}
public function test_edit_project(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$project = Project::factory()->create();
$this->user->projects()->attach($project);
$this->json('PUT', "/api/projects/{$project->id}", [
'name' => 'new-name',
])
->assertSuccessful();
$this->assertDatabaseHas('projects', [
'id' => $project->id,
'name' => 'new-name',
]);
}
public function test_cannot_delete_last_project(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$this->json('DELETE', "/api/projects/{$this->user->currentProject->id}")
->assertJsonValidationErrorFor('project');
$this->assertDatabaseHas('projects', [
'id' => $this->user->currentProject->id,
]);
}
}

View File

@ -0,0 +1,174 @@
<?php
namespace Tests\Feature\API;
use App\Enums\ServerProvider;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class ServerProvidersTest extends TestCase
{
use RefreshDatabase;
/**
* @dataProvider data
*/
public function test_connect_provider(string $provider, array $input): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
Http::fake();
$data = array_merge(
[
'provider' => $provider,
'name' => 'profile',
],
$input
);
$this->json('POST', route('api.projects.server-providers.create', [
'project' => $this->user->current_project_id,
]), $data)
->assertSuccessful()
->assertJsonFragment([
'provider' => $provider,
'name' => 'profile',
'project_id' => isset($input['global']) ? null : $this->user->current_project_id,
]);
}
/**
* @dataProvider data
*/
public function test_cannot_connect_to_provider(string $provider, array $input): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
Http::fake([
'*' => Http::response([], 401),
]);
$data = array_merge(
[
'provider' => $provider,
'name' => 'profile',
],
$input
);
$this->json('POST', route('api.projects.server-providers.create', [
'project' => $this->user->current_project_id,
]), $data)
->assertJsonValidationErrorFor('provider');
}
public function test_see_providers_list(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var \App\Models\ServerProvider $provider */
$provider = \App\Models\ServerProvider::factory()->create([
'user_id' => $this->user->id,
]);
$this->json('GET', route('api.projects.server-providers', [
'project' => $this->user->current_project_id,
]))
->assertSuccessful()
->assertJsonFragment([
'id' => $provider->id,
'provider' => $provider->provider,
]);
}
/**
* @dataProvider data
*/
public function test_delete_provider(string $provider): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var \App\Models\ServerProvider $provider */
$provider = \App\Models\ServerProvider::factory()->create([
'user_id' => $this->user->id,
'provider' => $provider,
]);
$this->json('DELETE', route('api.projects.server-providers.delete', [
'project' => $this->user->current_project_id,
'serverProvider' => $provider->id,
]))
->assertNoContent();
}
/**
* @dataProvider data
*/
public function test_cannot_delete_provider(string $provider): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var \App\Models\ServerProvider $provider */
$provider = \App\Models\ServerProvider::factory()->create([
'user_id' => $this->user->id,
'provider' => $provider,
]);
$this->server->update([
'provider_id' => $provider->id,
]);
$this->json('DELETE', route('api.projects.server-providers.delete', [
'project' => $this->user->current_project_id,
'serverProvider' => $provider->id,
]))
->assertJsonValidationErrors([
'provider' => 'This server provider is being used by a server.',
]);
}
public static function data(): array
{
return [
// [
// ServerProvider::AWS,
// [
// 'key' => 'key',
// 'secret' => 'secret',
// ],
// ],
[
ServerProvider::LINODE,
[
'token' => 'token',
],
],
[
ServerProvider::LINODE,
[
'token' => 'token',
'global' => 1,
],
],
[
ServerProvider::DIGITALOCEAN,
[
'token' => 'token',
],
],
[
ServerProvider::VULTR,
[
'token' => 'token',
],
],
[
ServerProvider::HETZNER,
[
'token' => 'token',
],
],
];
}
}

View File

@ -0,0 +1,109 @@
<?php
namespace Tests\Feature\API;
use App\Enums\SshKeyStatus;
use App\Facades\SSH;
use App\Models\SshKey;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class ServerSshKeysTest extends TestCase
{
use RefreshDatabase;
public function test_see_server_keys()
{
Sanctum::actingAs($this->user, ['read', 'write']);
$sshKey = SshKey::factory()->create([
'user_id' => $this->user->id,
'name' => 'My first key',
'public_key' => 'public-key-content',
]);
$this->server->sshKeys()->attach($sshKey, [
'status' => SshKeyStatus::ADDED,
]);
$this->json('GET', route('api.projects.servers.ssh-keys', [
'project' => $this->server->project,
'server' => $this->server,
]))
->assertSuccessful()
->assertJsonFragment([
'name' => 'My first key',
]);
}
public function test_add_new_ssh_key()
{
SSH::fake();
Sanctum::actingAs($this->user, ['read', 'write']);
$this->json('POST', route('api.projects.servers.ssh-keys.create', [
'project' => $this->server->project,
'server' => $this->server,
]), [
'name' => 'My first key',
'public_key' => 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3CCnyBbpCgOJ0AWUSfBZ+mYAsYzcQDegPkBx1kyE0bXT1yX4+6uYx1Jh6NxWgLyaU0BaP4nsClrK1u5FojQHd8J7ycc0N3H8B+v2NPzj1Q6bFnl40saastONVm+d4edbCg9BowGAafLcf9ALsognqqOWQbK/QOpAhg25IAe47eiY3IjDGMHlsvaZkMtkDhT4t1mK8ZLjxw5vjyVYgINJefR981bIxMFrXy+0xBCsYOZxMIoAJsgCkrAGlI4kQHKv0SQVccSyTE1eziIZa5b3QUlXj8ogxMfK/EOD7Aoqinw652k4S5CwFs/LLmjWcFqCKDM6CSggWpB78DZ729O6zFvQS9V99/9SsSV7Qc5ML7B0DKzJ/tbHkaAE8xdZnQnZFVUegUMtUmjvngMaGlYsxkAZrUKsFRoh7xfXVkDyRBaBSslRNe8LFsXw9f7Q+3jdZ5vhGhmp+TBXTlgxApwR023411+ABE9y0doCx8illya3m2olEiiMZkRclgqsWFSk=',
])
->assertSuccessful()
->assertJsonFragment([
'name' => 'My first key',
]);
}
public function test_add_existing_key()
{
SSH::fake();
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var SshKey $sshKey */
$sshKey = SshKey::factory()->create([
'user_id' => $this->user->id,
'name' => 'My first key',
'public_key' => 'public-key-content',
]);
$this->json('POST', route('api.projects.servers.ssh-keys.create', [
'project' => $this->server->project,
'server' => $this->server,
]), [
'key_id' => $sshKey->id,
])
->assertSuccessful()
->assertJsonFragment([
'name' => 'My first key',
]);
}
public function test_delete_ssh_key()
{
SSH::fake();
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var SshKey $sshKey */
$sshKey = SshKey::factory()->create([
'user_id' => $this->user->id,
'name' => 'My first key',
'public_key' => 'public-key-content',
]);
$this->server->sshKeys()->attach($sshKey, [
'status' => SshKeyStatus::ADDED,
]);
$this->json('DELETE', route('api.projects.servers.ssh-keys.delete', [
'project' => $this->server->project,
'server' => $this->server,
'sshKey' => $sshKey,
]))
->assertSuccessful()
->assertNoContent();
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Tests\Feature\API;
use App\Enums\Database;
use App\Enums\OperatingSystem;
use App\Enums\ServerProvider;
use App\Enums\ServerType;
use App\Enums\Webserver;
use App\Facades\SSH;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class ServerTest extends TestCase
{
use RefreshDatabase;
public function test_get_servers(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$this->json('GET', route('api.projects.servers', [
'project' => $this->user->current_project_id,
]))
->assertSuccessful()
->assertJsonFragment([
'name' => $this->server->name,
]);
}
public function test_get_server(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$this->json('GET', route('api.projects.servers.show', [
'project' => $this->user->current_project_id,
'server' => $this->server,
]))
->assertSuccessful()
->assertJsonFragment([
'name' => $this->server->name,
]);
}
/**
* @dataProvider createData
*/
public function test_create_server(string $type): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
SSH::fake('Active: active'); // fake output for service installations
$this->json('POST', route('api.projects.servers.create', [
'project' => $this->user->current_project_id,
]), [
'type' => $type,
'provider' => ServerProvider::CUSTOM,
'name' => 'test',
'ip' => '1.1.1.1',
'port' => '22',
'os' => OperatingSystem::UBUNTU22,
'webserver' => Webserver::NGINX,
'database' => Database::MYSQL80,
'php' => '8.2',
])
->assertSuccessful()
->assertJsonFragment([
'name' => 'test',
'type' => $type,
]);
}
public function test_delete_server(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
SSH::fake();
$this->json('DELETE', route('api.projects.servers.delete', [
'project' => $this->server->project_id,
'server' => $this->server->id,
]))
->assertNoContent();
}
public function test_reboot_server(): void
{
SSH::fake();
Sanctum::actingAs($this->user, ['read', 'write']);
$this->json('POST', route('api.projects.servers.reboot', [
'project' => $this->server->project_id,
'server' => $this->server->id,
]))
->assertNoContent();
}
public function test_upgrade_server(): void
{
SSH::fake('Available updates:0');
Sanctum::actingAs($this->user, ['read', 'write']);
$this->json('POST', route('api.projects.servers.upgrade', [
'project' => $this->server->project_id,
'server' => $this->server->id,
]))
->assertNoContent();
}
public static function createData(): array
{
return [
[ServerType::REGULAR],
[ServerType::DATABASE],
];
}
}

View File

@ -0,0 +1,125 @@
<?php
namespace Tests\Feature\API;
use App\Enums\ServiceStatus;
use App\Facades\SSH;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class ServicesTest extends TestCase
{
use RefreshDatabase;
public function test_see_services_list(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$this->json('GET', route('api.projects.servers.services', [
'project' => $this->server->project,
'server' => $this->server,
]))
->assertSuccessful()
->assertJsonFragment([
'name' => 'mysql',
])
->assertJsonFragment([
'name' => 'nginx',
])
->assertJsonFragment([
'name' => 'php',
])
->assertJsonFragment([
'name' => 'supervisor',
])
->assertJsonFragment([
'name' => 'redis',
])
->assertJsonFragment([
'name' => 'ufw',
]);
}
public function test_show_service(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$service = $this->server->services()->firstOrFail();
$this->json('GET', route('api.projects.servers.services.show', [
'project' => $this->server->project,
'server' => $this->server,
'service' => $service,
]))
->assertSuccessful()
->assertJsonFragment([
'name' => $service->name,
]);
}
/**
* @dataProvider data
*/
public function test_manage_service(string $action): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$service = $this->server->services()->firstOrFail();
$service->status = ServiceStatus::STOPPED;
$service->save();
SSH::fake('Active: active');
$this->json('POST', route('api.projects.servers.services.'.$action, [
'project' => $this->server->project,
'server' => $this->server,
'service' => $service,
]))
->assertSuccessful()
->assertNoContent();
}
public function test_uninstall_service(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$service = $this->server->services()->where('type', 'process_manager')->firstOrFail();
SSH::fake();
$this->json('DELETE', route('api.projects.servers.services.uninstall', [
'project' => $this->server->project,
'server' => $this->server,
'service' => $service,
]))
->assertSuccessful()
->assertNoContent();
}
public function test_cannot_uninstall_service_because_it_is_being_used(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
$service = $this->server->services()->where('type', 'webserver')->firstOrFail();
SSH::fake();
$this->json('DELETE', route('api.projects.servers.services.uninstall', [
'project' => $this->server->project,
'server' => $this->server,
'service' => $service,
]))
->assertJsonValidationErrorFor('service');
}
public static function data(): array
{
return [
['start'],
['stop'],
['restart'],
['enable'],
['disable'],
];
}
}

View File

@ -0,0 +1,92 @@
<?php
namespace Tests\Feature\API;
use App\Enums\SourceControl;
use App\Facades\SSH;
use App\Models\Site;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class SitesTest extends TestCase
{
use RefreshDatabase;
/**
* @dataProvider create_data
*/
public function test_create_site(array $inputs): void
{
SSH::fake();
Http::fake([
'https://api.github.com/repos/*' => Http::response([
], 201),
]);
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var \App\Models\SourceControl $sourceControl */
$sourceControl = \App\Models\SourceControl::factory()->create([
'provider' => SourceControl::GITHUB,
]);
$inputs['source_control'] = $sourceControl->id;
$this->json('POST', route('api.projects.servers.sites.create', [
'project' => $this->server->project,
'server' => $this->server,
]), $inputs)
->assertSuccessful()
->assertJsonFragment([
'domain' => $inputs['domain'],
'aliases' => $inputs['aliases'] ?? [],
]);
}
public function test_see_sites_list(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var Site $site */
$site = Site::factory()->create([
'server_id' => $this->server->id,
]);
$this->json('GET', route('api.projects.servers.sites', [
'project' => $this->server->project,
'server' => $this->server,
]))
->assertSuccessful()
->assertJsonFragment([
'domain' => $site->domain,
]);
}
public function test_delete_site(): void
{
SSH::fake();
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var Site $site */
$site = Site::factory()->create([
'server_id' => $this->server->id,
]);
$this->json('DELETE', route('api.projects.servers.sites.delete', [
'project' => $this->server->project,
'server' => $this->server,
'site' => $site,
]))
->assertSuccessful()
->assertNoContent();
}
public static function create_data(): array
{
return \Tests\Feature\SitesTest::create_data();
}
}

View File

@ -0,0 +1,134 @@
<?php
namespace Tests\Feature\API;
use App\Models\SourceControl;
use App\Web\Pages\Settings\SourceControls\Widgets\SourceControlsList;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Laravel\Sanctum\Sanctum;
use Livewire\Livewire;
use Tests\TestCase;
class SourceControlsTest extends TestCase
{
use RefreshDatabase;
/**
* @dataProvider data
*/
public function test_connect_provider(string $provider, array $input): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
Http::fake();
$input = array_merge([
'name' => 'test',
'provider' => $provider,
], $input);
$this->json('POST', route('api.projects.source-controls.create', [
'project' => $this->user->current_project_id,
]), $input)
->assertSuccessful()
->assertJsonFragment([
'provider' => $provider,
'name' => 'test',
]);
}
/**
* @dataProvider data
*/
public function test_delete_provider(string $provider): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var SourceControl $sourceControl */
$sourceControl = SourceControl::factory()->create([
'provider' => $provider,
'profile' => 'test',
]);
$this->json('DELETE', route('api.projects.source-controls.delete', [
'project' => $this->user->current_project_id,
'sourceControl' => $sourceControl->id,
]))
->assertSuccessful()
->assertNoContent();
}
/**
* @dataProvider data
*/
public function test_cannot_delete_provider(string $provider): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var SourceControl $sourceControl */
$sourceControl = SourceControl::factory()->create([
'provider' => $provider,
'profile' => 'test',
]);
$this->site->update([
'source_control_id' => $sourceControl->id,
]);
Livewire::test(SourceControlsList::class)
->callTableAction('delete', $sourceControl->id)
->assertNotified('This source control is being used by a site.');
$this->assertNotSoftDeleted('source_controls', [
'id' => $sourceControl->id,
]);
}
/**
* @dataProvider data
*/
public function test_edit_source_control(string $provider, array $input): void
{
Http::fake();
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var SourceControl $sourceControl */
$sourceControl = SourceControl::factory()->create([
'provider' => $provider,
'profile' => 'old-name',
'url' => $input['url'] ?? null,
]);
$this->json('PUT', route('api.projects.source-controls.update', [
'project' => $this->user->current_project_id,
'sourceControl' => $sourceControl->id,
]), array_merge([
'name' => 'new-name',
], $input))
->assertSuccessful()
->assertJsonFragment([
'provider' => $provider,
'name' => 'new-name',
]);
$sourceControl->refresh();
$this->assertEquals('new-name', $sourceControl->profile);
if (isset($input['url'])) {
$this->assertEquals($input['url'], $sourceControl->url);
}
}
public static function data(): array
{
return [
['github', ['token' => 'test']],
['github', ['token' => 'test', 'global' => '1']],
['gitlab', ['token' => 'test']],
['gitlab', ['token' => 'test', 'url' => 'https://git.example.com/']],
['bitbucket', ['username' => 'test', 'password' => 'test']],
];
}
}

View File

@ -0,0 +1,173 @@
<?php
namespace Tests\Feature\API;
use App\Enums\StorageProvider;
use App\Facades\FTP;
use App\Models\Backup;
use App\Models\Database;
use App\Models\StorageProvider as StorageProviderModel;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class StorageProvidersTest extends TestCase
{
use RefreshDatabase;
/**
* @dataProvider createData
*/
public function test_create(array $input): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
if ($input['provider'] === StorageProvider::DROPBOX) {
Http::fake();
}
if ($input['provider'] === StorageProvider::FTP) {
FTP::fake();
}
$this->json('POST', route('api.projects.storage-providers.create', [
'project' => $this->user->current_project_id,
]), $input)
->assertSuccessful()
->assertJsonFragment([
'provider' => $input['provider'],
'name' => $input['name'],
]);
}
public function test_see_providers_list(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var StorageProviderModel $provider */
$provider = StorageProviderModel::factory()->create([
'user_id' => $this->user->id,
'provider' => StorageProvider::DROPBOX,
]);
$this->json('GET', route('api.projects.storage-providers', [
'project' => $this->user->current_project_id,
]))
->assertSuccessful()
->assertJsonFragment([
'provider' => $provider->provider,
'name' => $provider->profile,
]);
}
public function test_delete_provider(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var StorageProviderModel $provider */
$provider = StorageProviderModel::factory()->create([
'user_id' => $this->user->id,
]);
$this->json('DELETE', route('api.projects.storage-providers.delete', [
'project' => $this->user->current_project_id,
'storageProvider' => $provider->id,
]))
->assertSuccessful()
->assertNoContent();
}
public function test_cannot_delete_provider(): void
{
Sanctum::actingAs($this->user, ['read', 'write']);
/** @var Database $database */
$database = Database::factory()->create([
'server_id' => $this->server,
]);
/** @var StorageProviderModel $provider */
$provider = StorageProviderModel::factory()->create([
'user_id' => $this->user->id,
]);
Backup::factory()->create([
'server_id' => $this->server->id,
'database_id' => $database->id,
'storage_id' => $provider->id,
]);
$this->json('DELETE', route('api.projects.storage-providers.delete', [
'project' => $this->user->current_project_id,
'storageProvider' => $provider->id,
]))
->assertJsonValidationErrorFor('provider');
}
/**
* @TODO: complete FTP tests
*/
public static function createData(): array
{
return [
[
[
'provider' => StorageProvider::LOCAL,
'name' => 'local-test',
'path' => '/home/vito/backups',
],
],
[
[
'provider' => StorageProvider::LOCAL,
'name' => 'local-test',
'path' => '/home/vito/backups',
'global' => 1,
],
],
[
[
'provider' => StorageProvider::FTP,
'name' => 'ftp-test',
'host' => '1.2.3.4',
'port' => '22',
'path' => '/home/vito',
'username' => 'username',
'password' => 'password',
'ssl' => 1,
'passive' => 1,
],
],
[
[
'provider' => StorageProvider::FTP,
'name' => 'ftp-test',
'host' => '1.2.3.4',
'port' => '22',
'path' => '/home/vito',
'username' => 'username',
'password' => 'password',
'ssl' => 1,
'passive' => 1,
'global' => 1,
],
],
[
[
'provider' => StorageProvider::DROPBOX,
'name' => 'dropbox-test',
'token' => 'token',
],
],
[
[
'provider' => StorageProvider::DROPBOX,
'name' => 'dropbox-test',
'token' => 'token',
'global' => 1,
],
],
];
}
}

View File

@ -302,12 +302,6 @@ public static function data(): array
{
return [
['nginx'],
['php'],
['supervisor'],
['redis'],
['ufw'],
['php'],
['mysql'],
];
}