- 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>
134 lines
5.3 KiB
PHP
134 lines
5.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\Api\Client;
|
|
|
|
use App\Models\Customer;
|
|
use App\Models\DnsDomain;
|
|
use App\Models\DnsManagerNS;
|
|
use App\Models\Service;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Tests\TestCase;
|
|
|
|
class DomainRecordPermissionTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
private Customer $customer;
|
|
private DnsDomain $domain;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->customer = Customer::factory()->create();
|
|
$serverId = DB::table('dns_manager_servers')->insertGetId(['ip_address' => '10.0.0.1', 'password' => 'x']);
|
|
$this->domain = DnsDomain::create(['domain_name' => 'example.vn', 'dns_manager_server_id' => $serverId, 'is_created' => 1]);
|
|
$this->domain->customer()->attach($this->customer->id);
|
|
}
|
|
|
|
private function client()
|
|
{
|
|
return $this->actingAs($this->customer, 'client')
|
|
->withHeaders(['x-access-token' => $this->buildClientAccessToken()]);
|
|
}
|
|
|
|
private function record(string $type): DnsManagerNS
|
|
{
|
|
return DnsManagerNS::create([
|
|
'dns_manager_domain_id' => $this->domain->id,
|
|
'type' => $type,
|
|
'type_valid' => $type,
|
|
'name' => 'example.vn',
|
|
'value' => 'ns1.example.net.',
|
|
'ttl' => 3600,
|
|
]);
|
|
}
|
|
|
|
public function test_customer_cannot_create_ns_record(): void
|
|
{
|
|
$this->client()
|
|
->postJson("/v1/client/client-service/domains/{$this->domain->id}/records", [
|
|
'type' => 'NS', 'name' => 'example.vn', 'value' => 'ns1.other.net.',
|
|
])
|
|
->assertStatus(422);
|
|
}
|
|
|
|
public function test_customer_cannot_update_or_delete_ns_record(): void
|
|
{
|
|
$ns = $this->record('NS');
|
|
$url = "/v1/client/client-service/domains/{$this->domain->id}/records/{$ns->id}";
|
|
|
|
$this->client()->putJson($url, ['type' => 'A', 'name' => 'www', 'value' => '1.2.3.4'])->assertStatus(403);
|
|
$this->client()->deleteJson($url)->assertStatus(403);
|
|
|
|
$this->assertDatabaseHas('dns_manager_ns', ['id' => $ns->id, 'type' => 'NS']);
|
|
}
|
|
|
|
public function test_domain_detail_exposes_only_record_fields(): void
|
|
{
|
|
$this->domain->update(['plesk_id' => 214]);
|
|
$this->record('A')->update(['plesk_id' => 3260]);
|
|
|
|
$data = $this->client()
|
|
->getJson("/v1/client/client-service/domains/{$this->domain->id}")
|
|
->assertOk()
|
|
->assertJsonPath('data.domain_name', 'example.vn')
|
|
->json('data');
|
|
|
|
$this->assertSame(['domain_name', 'records'], array_keys($data));
|
|
$this->assertSame(
|
|
['id', 'name', 'type', 'priority', 'weight', 'port', 'service_name', 'protocol', 'value', 'ttl'],
|
|
array_keys($data['records']['items'][0]),
|
|
);
|
|
}
|
|
|
|
public function test_domain_list_merges_domain_services_and_assigned_dns_zones(): void
|
|
{
|
|
$service = Service::create(['customer_id' => $this->customer->id, 'type' => 'domain', 'server_name' => 'Example.vn', 'status' => 'active']);
|
|
Service::create(['customer_id' => $this->customer->id, 'type' => 'domain', 'server_name' => 'other.vn', 'status' => 'active']);
|
|
$zone = DnsDomain::create(['domain_name' => 'zone-only.vn', 'dns_manager_server_id' => $this->domain->dns_manager_server_id, 'is_created' => 1]);
|
|
$zone->customer()->attach($this->customer->id);
|
|
|
|
$items = collect($this->client()->getJson('/v1/client/client-service/domain')->assertOk()->json('data.items'))
|
|
->keyBy('domain_name');
|
|
|
|
$this->assertCount(3, $items);
|
|
$this->assertSame($service->uuid, $items['Example.vn']['service_uuid']);
|
|
$this->assertSame($this->domain->id, $items['Example.vn']['dns_domain_id']);
|
|
$this->assertNull($items['other.vn']['dns_domain_id']);
|
|
$this->assertNull($items['zone-only.vn']['service_uuid']);
|
|
$this->assertSame($zone->id, $items['zone-only.vn']['dns_domain_id']);
|
|
}
|
|
|
|
public function test_cancelled_zone_is_listed_as_cancelled_without_dns_access(): void
|
|
{
|
|
$this->domain->update(['is_created' => DnsDomain::STATUS_CANCELLED]);
|
|
|
|
$this->client()->getJson('/v1/client/client-service/domain')
|
|
->assertOk()
|
|
->assertJsonCount(1, 'data.items')
|
|
->assertJsonPath('data.items.0.cancelled', true)
|
|
->assertJsonPath('data.items.0.dns_domain_id', null);
|
|
$this->client()->getJson("/v1/client/client-service/domains/{$this->domain->id}/records")->assertNotFound();
|
|
}
|
|
|
|
public function test_domain_service_detail_exposes_dns_zone_and_cancelled_state(): void
|
|
{
|
|
$service = Service::create(['customer_id' => $this->customer->id, 'type' => 'domain', 'server_name' => 'example.vn', 'status' => 'active']);
|
|
$url = "/v1/client/client-service/{$service->uuid}";
|
|
|
|
$this->client()->getJson($url)->assertOk()
|
|
->assertJsonPath('data.dns_domain_id', $this->domain->id)
|
|
->assertJsonPath('data.dns_cancelled', false);
|
|
|
|
$this->domain->update(['is_created' => DnsDomain::STATUS_CANCELLED]);
|
|
|
|
$this->client()->getJson($url)->assertOk()
|
|
->assertJsonPath('data.dns_domain_id', null)
|
|
->assertJsonPath('data.dns_cancelled', true);
|
|
}
|
|
}
|