- Gửi email theo template cho 1 khách, tab lịch sử email, nhắc gia hạn dịch vụ hàng loạt - Mail lưu from/bcc/sent_by; mẫu MARKETING và mẫu cũ trong TemplateSeeder - Gói hosting: giới hạn, trạng thái, lấy plan Plesk qua CLI gateway - Backfill payment_method và ngày đơn hàng còn thiếu - Bổ sung field CPU/RAM/Disk/Băng thông cho loại sản phẩm vps và cloud Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
124 lines
4.3 KiB
PHP
124 lines
4.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\Api\Admin\Hosting;
|
|
|
|
use App\Models\DnsServer;
|
|
use App\Models\ServicePlan;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Crypt;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Spatie\Permission\Models\Role;
|
|
use Tests\TestCase;
|
|
|
|
class ServicePlanTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
private User $admin;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
Role::firstOrCreate(['name' => 'Full Administrator', 'guard_name' => 'admin']);
|
|
$this->admin = User::factory()->create();
|
|
$this->admin->assignRole('Full Administrator');
|
|
}
|
|
|
|
private function server(string $type = 'hosting'): DnsServer
|
|
{
|
|
return DnsServer::create([
|
|
'name' => 'plesk-01',
|
|
'ip_address' => '10.0.0.5',
|
|
'username' => 'admin',
|
|
'password' => Crypt::encryptString('secret'),
|
|
'status' => 'activated',
|
|
'type' => $type,
|
|
]);
|
|
}
|
|
|
|
public function test_store_and_update_persist_limits_features_and_plesk_mapping(): void
|
|
{
|
|
$payload = [
|
|
'title' => 'Hosting Basic',
|
|
'description' => 'Cho website nhỏ',
|
|
'vcpu' => 1,
|
|
'ram' => 1,
|
|
'disk' => 10,
|
|
'domain' => 1,
|
|
'bandwidth' => null,
|
|
'databases' => 2,
|
|
'mailboxes' => 5,
|
|
'mailbox_quota' => 1024,
|
|
'features' => ['SSL miễn phí', 'Backup hàng ngày'],
|
|
'is_active' => false,
|
|
'sort_order' => 3,
|
|
'plesk_plan_name' => 'basic',
|
|
];
|
|
|
|
$id = $this->actingAs($this->admin, 'admin')
|
|
->postJson('/api/v1/administrator/service-plans', $payload)
|
|
->assertCreated()
|
|
->assertJsonPath('data.features', ['SSL miễn phí', 'Backup hàng ngày'])
|
|
->assertJsonPath('data.is_active', false)
|
|
->assertJsonPath('data.plesk.plesk_plan_name', 'basic')
|
|
->json('data.id');
|
|
|
|
$plan = ServicePlan::findOrFail($id);
|
|
$this->assertNull($plan->bandwidth);
|
|
$this->assertSame(5, $plan->mailboxes);
|
|
|
|
$this->actingAs($this->admin, 'admin')
|
|
->putJson("/api/v1/administrator/service-plans/{$id}", [...$payload, 'is_active' => true, 'plesk_plan_name' => null])
|
|
->assertOk()
|
|
->assertJsonPath('data.is_active', true)
|
|
->assertJsonPath('data.plesk', null);
|
|
}
|
|
|
|
public function test_rejects_negative_limits_and_duplicate_features(): void
|
|
{
|
|
$this->actingAs($this->admin, 'admin')
|
|
->postJson('/api/v1/administrator/service-plans', [
|
|
'title' => 'X', 'vcpu' => 1, 'ram' => 1, 'disk' => 1, 'domain' => 1,
|
|
'databases' => -1,
|
|
'features' => ['SSH', 'SSH'],
|
|
])
|
|
->assertStatus(422)
|
|
->assertJsonValidationErrors(['databases', 'features.0']);
|
|
}
|
|
|
|
public function test_lists_plesk_plan_names_from_cli_gateway(): void
|
|
{
|
|
$server = $this->server();
|
|
Http::fake([
|
|
'https://10.0.0.5:8443/api/v2/cli/service_plan/call' => Http::response([
|
|
'code' => 0, 'stdout' => "Default Domain\r\nbasic\n\nbasic\n", 'stderr' => '',
|
|
]),
|
|
]);
|
|
|
|
$this->actingAs($this->admin, 'admin')
|
|
->getJson("/api/v1/administrator/service-plans/plesk-plans/{$server->id}")
|
|
->assertOk()
|
|
->assertExactJson(['error' => false, 'data' => ['Default Domain', 'basic']]);
|
|
|
|
Http::assertSent(fn ($request) => $request['params'] === ['--list']);
|
|
}
|
|
|
|
public function test_plesk_plans_fails_for_cli_error_and_non_hosting_server(): void
|
|
{
|
|
$server = $this->server();
|
|
Http::fake(['*' => Http::response(['code' => 1, 'stdout' => '', 'stderr' => 'denied'])]);
|
|
|
|
$this->actingAs($this->admin, 'admin')
|
|
->getJson("/api/v1/administrator/service-plans/plesk-plans/{$server->id}")
|
|
->assertStatus(502);
|
|
|
|
$this->actingAs($this->admin, 'admin')
|
|
->getJson('/api/v1/administrator/service-plans/plesk-plans/' . $this->server('domain')->id)
|
|
->assertNotFound();
|
|
}
|
|
}
|