- ProvisionDnsDomainJob/SuspendDnsDomainJob: tạo domain admin lên Plesk, huỷ = suspend (is_created=3) - Khách xem zone DNS được gán ở /dich-vu/domain, quản lý bản ghi A/AAAA/CNAME/TXT/MX/SRV - send-mail hoá đơn đẩy SendInvoiceMailJob, preview + sửa nội dung, ghi mail.order_id - invoice_attachments.type (payment_proof/deployment) - CacheService xoá theo SCAN pattern, Redis không persistent mặc định - Backfill transactions.public_code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
168 lines
6.2 KiB
PHP
168 lines
6.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\Api\Admin\DnsManager;
|
|
|
|
use App\Jobs\DnsManager\ProvisionDnsDomainJob;
|
|
use App\Jobs\DnsManager\SuspendDnsDomainJob;
|
|
use App\Models\DnsDomain;
|
|
use App\Models\User;
|
|
use App\Services\Plesk\PleskDomainService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Mockery;
|
|
use Spatie\Permission\Models\Role;
|
|
use Tests\TestCase;
|
|
|
|
class ProvisionDnsDomainTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
private int $serverId;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->serverId = DB::table('dns_manager_servers')->insertGetId(['ip_address' => '10.0.0.1', 'password' => 'x']);
|
|
}
|
|
|
|
private function domain(): DnsDomain
|
|
{
|
|
return DnsDomain::create(['domain_name' => 'example.vn', 'dns_manager_server_id' => $this->serverId, 'is_created' => 0]);
|
|
}
|
|
|
|
private function admin(): User
|
|
{
|
|
Role::firstOrCreate(['name' => 'Full Administrator', 'guard_name' => 'admin']);
|
|
$admin = User::factory()->create();
|
|
$admin->assignRole('Full Administrator');
|
|
|
|
return $admin;
|
|
}
|
|
|
|
public function test_destroy_cancels_domain_and_queues_plesk_suspend(): void
|
|
{
|
|
Queue::fake();
|
|
$domain = $this->domain();
|
|
$domain->update(['plesk_id' => 55, 'is_created' => DnsDomain::STATUS_CREATED]);
|
|
$customerId = \App\Models\Customer::factory()->create()->id;
|
|
$domain->customer()->attach($customerId);
|
|
|
|
$this->actingAs($this->admin(), 'admin')
|
|
->deleteJson("/api/v1/administrator/domains/{$domain->id}")
|
|
->assertOk();
|
|
|
|
$this->assertDatabaseHas('dns_manager_domain', ['id' => $domain->id, 'is_created' => DnsDomain::STATUS_CANCELLED]);
|
|
$this->assertDatabaseHas('dns_domain_user', ['domain_id' => $domain->id, 'user_id' => $customerId]);
|
|
Queue::assertPushed(SuspendDnsDomainJob::class, fn ($job) => $job->domainId === $domain->id);
|
|
}
|
|
|
|
public function test_destroy_without_plesk_domain_only_cancels(): void
|
|
{
|
|
Queue::fake();
|
|
$domain = $this->domain();
|
|
|
|
$this->actingAs($this->admin(), 'admin')
|
|
->deleteJson("/api/v1/administrator/domains/{$domain->id}")
|
|
->assertOk();
|
|
|
|
$this->assertDatabaseHas('dns_manager_domain', ['id' => $domain->id, 'is_created' => DnsDomain::STATUS_CANCELLED]);
|
|
Queue::assertNotPushed(SuspendDnsDomainJob::class);
|
|
}
|
|
|
|
public function test_suspend_job_calls_plesk_for_cancelled_domain(): void
|
|
{
|
|
$domain = $this->domain();
|
|
$domain->update(['is_created' => DnsDomain::STATUS_CANCELLED]);
|
|
$plesk = Mockery::mock(PleskDomainService::class);
|
|
$plesk->shouldReceive('suspend')->once()->with(Mockery::any(), 'example.vn')->andReturn(true);
|
|
|
|
(new SuspendDnsDomainJob($domain->id))->handle($plesk);
|
|
}
|
|
|
|
public function test_suspend_job_skips_domain_reactivated_before_it_ran(): void
|
|
{
|
|
$domain = $this->domain();
|
|
$plesk = Mockery::mock(PleskDomainService::class);
|
|
$plesk->shouldNotReceive('suspend');
|
|
|
|
(new SuspendDnsDomainJob($domain->id))->handle($plesk);
|
|
$this->addToAssertionCount(1);
|
|
}
|
|
|
|
public function test_store_queues_provisioning_on_selected_server(): void
|
|
{
|
|
Queue::fake();
|
|
|
|
$id = $this->actingAs($this->admin(), 'admin')
|
|
->postJson('/api/v1/administrator/domains', ['domain_name' => 'example.vn', 'dns_manager_server_id' => $this->serverId])
|
|
->assertCreated()
|
|
->assertJsonPath('data.provisioning_queued', true)
|
|
->json('data.id');
|
|
|
|
Queue::assertPushed(ProvisionDnsDomainJob::class, fn ($job) => $job->domainId === $id);
|
|
}
|
|
|
|
public function test_job_creates_domain_on_plesk_when_missing(): void
|
|
{
|
|
$domain = $this->domain();
|
|
$plesk = Mockery::mock(PleskDomainService::class);
|
|
$plesk->shouldReceive('getDomainInfo')->once()->andReturn(false);
|
|
$plesk->shouldReceive('createDomain')->once()->with(Mockery::any(), ['domain_name' => 'example.vn'])->andReturn(['id' => 55, 'guid' => 'g']);
|
|
|
|
(new ProvisionDnsDomainJob($domain->id))->handle($plesk);
|
|
|
|
$this->assertDatabaseHas('dns_manager_domain', ['id' => $domain->id, 'plesk_id' => 55, 'is_created' => 1]);
|
|
}
|
|
|
|
public function test_job_links_existing_plesk_domain_without_creating(): void
|
|
{
|
|
$domain = $this->domain();
|
|
$plesk = Mockery::mock(PleskDomainService::class);
|
|
$plesk->shouldReceive('getDomainInfo')->once()->andReturn(['id' => 77, 'name' => 'example.vn']);
|
|
$plesk->shouldNotReceive('createDomain');
|
|
|
|
(new ProvisionDnsDomainJob($domain->id))->handle($plesk);
|
|
|
|
$this->assertDatabaseHas('dns_manager_domain', ['id' => $domain->id, 'plesk_id' => 77, 'is_created' => 1]);
|
|
}
|
|
|
|
public function test_job_fails_and_keeps_domain_uncreated_when_plesk_rejects(): void
|
|
{
|
|
$domain = $this->domain();
|
|
$plesk = Mockery::mock(PleskDomainService::class);
|
|
$plesk->shouldReceive('getDomainInfo')->andReturn(false);
|
|
$plesk->shouldReceive('createDomain')->andReturn(false);
|
|
$plesk->shouldReceive('getLastError')->andReturn('boom');
|
|
|
|
$this->expectExceptionMessage('boom');
|
|
try {
|
|
(new ProvisionDnsDomainJob($domain->id))->handle($plesk);
|
|
} finally {
|
|
$this->assertDatabaseHas('dns_manager_domain', ['id' => $domain->id, 'plesk_id' => null, 'is_created' => 0]);
|
|
}
|
|
}
|
|
|
|
public function test_provision_endpoint_requeues_only_uncreated_active_domains(): void
|
|
{
|
|
Queue::fake();
|
|
$admin = $this->admin();
|
|
$domain = $this->domain();
|
|
$url = "/api/v1/administrator/domains/{$domain->id}/provision";
|
|
|
|
$this->actingAs($admin, 'admin')->postJson($url)->assertOk();
|
|
Queue::assertPushed(ProvisionDnsDomainJob::class, 1);
|
|
|
|
$domain->update(['plesk_id' => 9]);
|
|
$this->actingAs($admin, 'admin')->postJson($url)->assertStatus(422);
|
|
|
|
$domain->update(['plesk_id' => null, 'is_created' => DnsDomain::STATUS_CANCELLED]);
|
|
$this->actingAs($admin, 'admin')->postJson($url)->assertStatus(422);
|
|
|
|
Queue::assertPushed(ProvisionDnsDomainJob::class, 1);
|
|
}
|
|
}
|