'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(); } }