Files
ladill-servers/tests/Feature/HostingPricingDisplayTest.php
T
isaaccladandCursor b6c8ac343f Extract Ladill Servers as standalone app at servers.ladill.com.
VPS and dedicated server ordering, managed panels, SSO, billing, and launcher integration — forked from hosting infrastructure with server-focused routes and dashboard.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 19:18:30 +00:00

780 lines
30 KiB
PHP

<?php
namespace Tests\Feature;
use App\Http\Controllers\Hosting\HostingProductController;
use App\Jobs\ProvisionHostingOrderJob;
use App\Models\CustomerHostingOrder;
use App\Models\HostingProduct;
use App\Models\ProvisioningQueueItem;
use App\Models\User;
use App\Services\ExchangeRateService;
use App\Services\Hosting\HostingResourcePolicyService;
use App\Services\Hosting\NodeCapacityService;
use App\Services\Hosting\Providers\ContaboProvider;
use App\Services\Hosting\Providers\SharedNodeProvider;
use App\Services\Hosting\ServerAgentBootstrapService;
use App\Services\Hosting\ServerAgentInstallerService;
use App\Services\Hosting\ServerOrderService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Request;
use Tests\TestCase;
class HostingPricingDisplayTest extends TestCase
{
use RefreshDatabase;
private function mockContaboImages(): void
{
$provider = \Mockery::mock(ContaboProvider::class);
$provider->shouldReceive('getAvailableImages')->andReturn([
[
'id' => 'ubuntu-24-image',
'name' => 'Ubuntu 24.04',
'description' => 'Ubuntu',
'os_type' => 'linux',
'standard_image' => true,
],
[
'id' => 'ubuntu-image',
'name' => 'Ubuntu 22.04',
'description' => 'Ubuntu',
'os_type' => 'linux',
'standard_image' => true,
],
[
'id' => 'win-image',
'name' => 'Windows Server 2022',
'description' => 'Windows',
'os_type' => 'windows',
'standard_image' => true,
],
]);
$provider->shouldReceive('getAvailableProducts')->andReturn([
['id' => 'V91', 'name' => 'Cloud VPS 10 NVMe', 'cpu' => 3, 'ram_gb' => 8, 'disk_gb' => 75, 'price_monthly' => 4.99],
['id' => 'V45', 'name' => 'VPS S SSD', 'cpu' => 4, 'ram_gb' => 8, 'disk_gb' => 200, 'price_monthly' => 6.99],
]);
$this->app->instance(ContaboProvider::class, $provider);
}
public function test_vps_page_renders_dynamic_ghs_price_instead_of_stored_zero_value(): void
{
$user = User::factory()->create();
$this->mockContaboImages();
$this->mock(ExchangeRateService::class, function ($mock): void {
$mock->shouldReceive('getUsdToGhs')->andReturn(15.50);
});
HostingProduct::create([
'name' => 'VPS S',
'slug' => 'vps-s-test',
'description' => 'Dynamic VPS pricing test',
'category' => 'vps',
'type' => 'vps',
'price_monthly' => 0,
'price_quarterly' => 0,
'price_yearly' => 0,
'currency' => 'USD',
'cpu_cores' => 4,
'ram_mb' => 8192,
'disk_gb' => 200,
'contabo_product_id' => 'V45',
'is_active' => true,
'is_visible' => true,
]);
$request = Request::create('http://localhost/hosting/vps', 'GET');
$request->setUserResolver(fn (): User => $user);
$view = $this->app->make(HostingProductController::class)->vps($request);
$html = $view->render();
$this->assertStringContainsString('GHS 140.00', $html);
$this->assertStringNotContainsString('$0.00', $html);
}
public function test_vps_page_lists_install_later_and_multiple_live_images(): void
{
$user = User::factory()->create();
$this->mockContaboImages();
$this->mock(ExchangeRateService::class, function ($mock): void {
$mock->shouldReceive('getUsdToGhs')->andReturn(15.50);
});
HostingProduct::create([
'name' => 'VPS S',
'slug' => 'vps-s-install-later-test',
'description' => 'Dynamic VPS pricing test',
'category' => 'vps',
'type' => 'vps',
'price_monthly' => 0,
'price_quarterly' => 0,
'price_yearly' => 0,
'currency' => 'USD',
'cpu_cores' => 4,
'ram_mb' => 8192,
'disk_gb' => 200,
'contabo_product_id' => 'V45',
'is_active' => true,
'is_visible' => true,
]);
$request = Request::create('http://localhost/hosting/vps', 'GET');
$request->setUserResolver(fn (): User => $user);
$view = $this->app->make(HostingProductController::class)->vps($request);
$html = $view->render();
$this->assertStringContainsString('Install Later', $html);
$this->assertStringContainsString('Ubuntu 24.04', $html);
$this->assertStringContainsString('Ubuntu 22.04', $html);
}
public function test_server_orders_use_display_currency_for_dynamic_products(): void
{
$user = User::factory()->create();
$this->mockContaboImages();
$this->mock(ExchangeRateService::class, function ($mock): void {
$mock->shouldReceive('getUsdToGhs')->andReturn(15.50);
});
$product = HostingProduct::create([
'name' => 'VPS S',
'slug' => 'vps-s-order-test',
'description' => 'Dynamic VPS order test',
'category' => 'vps',
'type' => 'vps',
'price_monthly' => 0,
'price_quarterly' => 0,
'price_yearly' => 0,
'currency' => 'USD',
'cpu_cores' => 4,
'ram_mb' => 8192,
'disk_gb' => 200,
'contabo_product_id' => 'V45',
'is_active' => true,
'is_visible' => true,
]);
$response = $this->actingAs($user)->postJson(route('hosting.servers.store'), [
'product_id' => $product->id,
'server_name' => 'pricing-test-server',
'billing_cycle' => 'monthly',
'region' => 'EU',
'image' => 'ubuntu-image',
'license' => 'none',
'application' => 'none',
'default_user' => 'root',
'additional_ip' => 'none',
'private_networking' => 'disabled',
'storage_type' => 'included',
'object_storage' => 'none',
'server_password' => 'Secure123!!',
'server_password_confirmation' => 'Secure123!!',
]);
$response->assertOk();
$order = CustomerHostingOrder::query()->firstOrFail();
$this->assertSame('GHS', $order->currency);
$this->assertSame('140.00', number_format((float) $order->amount_paid, 2, '.', ''));
}
public function test_server_orders_persist_selected_options_password_and_semiannual_term_pricing(): void
{
$user = User::factory()->create();
$this->mockContaboImages();
$this->mock(ExchangeRateService::class, function ($mock): void {
$mock->shouldReceive('getUsdToGhs')->andReturn(15.50);
});
$product = HostingProduct::create([
'name' => 'VPS S',
'slug' => 'vps-s-semiannual-test',
'description' => 'Dynamic VPS order test',
'category' => 'vps',
'type' => 'vps',
'price_monthly' => 0,
'price_quarterly' => 0,
'price_yearly' => 0,
'currency' => 'USD',
'cpu_cores' => 4,
'ram_mb' => 8192,
'disk_gb' => 200,
'contabo_product_id' => 'V45',
'is_active' => true,
'is_visible' => true,
]);
$response = $this->actingAs($user)->postJson(route('hosting.servers.store'), [
'product_id' => $product->id,
'server_name' => 'semiannual-configured-server',
'billing_cycle' => 'semiannual',
'region' => 'EU',
'image' => 'win-image',
'license' => 'plesk_windows',
'application' => 'none',
'default_user' => 'administrator',
'additional_ip' => 'none',
'private_networking' => 'disabled',
'storage_type' => 'included',
'object_storage' => 'eu_250',
'server_password' => 'Abc123!!',
'server_password_confirmation' => 'Abc123!!',
]);
$response->assertOk();
$order = CustomerHostingOrder::query()->firstOrFail();
$this->assertSame('semiannual', $order->billing_cycle);
$this->assertSame('4985.36', number_format((float) $order->amount_paid, 2, '.', ''));
$this->assertSame('win-image', data_get($order->meta, 'server_order.selection.image'));
$this->assertSame('administrator', data_get($order->meta, 'server_order.selection.default_user'));
$this->assertSame(
['250 GB Object Storage (EU)'],
data_get($order->meta, 'server_order.quote.manual_follow_up')
);
$this->assertSame('Abc123!!', decrypt((string) data_get($order->meta, 'server_order.server_password_encrypted')));
$this->assertSame('Windows Server 2022', data_get($order->meta, 'server_order.selection_summary.0.value'));
}
public function test_server_orders_allow_install_later_with_remote_login_only(): void
{
$user = User::factory()->create();
$this->mockContaboImages();
$this->mock(ExchangeRateService::class, function ($mock): void {
$mock->shouldReceive('getUsdToGhs')->andReturn(15.50);
});
$product = HostingProduct::create([
'name' => 'VPS S',
'slug' => 'vps-s-install-later-order-test',
'description' => 'Dynamic VPS order test',
'category' => 'vps',
'type' => 'vps',
'price_monthly' => 0,
'price_quarterly' => 0,
'price_yearly' => 0,
'currency' => 'USD',
'cpu_cores' => 4,
'ram_mb' => 8192,
'disk_gb' => 200,
'contabo_product_id' => 'V45',
'is_active' => true,
'is_visible' => true,
]);
$response = $this->actingAs($user)->postJson(route('hosting.servers.store'), [
'product_id' => $product->id,
'server_name' => 'install-later-server',
'billing_cycle' => 'monthly',
'region' => 'EU',
'image' => '__install_later__',
'license' => 'none',
'application' => 'none',
'default_user' => 'root',
'additional_ip' => 'none',
'private_networking' => 'disabled',
'storage_type' => 'included',
'object_storage' => 'none',
'server_password' => 'Secure123!!',
'server_password_confirmation' => 'Secure123!!',
]);
$response->assertOk();
$order = CustomerHostingOrder::query()->firstOrFail();
$this->assertSame('__install_later__', data_get($order->meta, 'server_order.selection.image'));
$this->assertSame('none', data_get($order->meta, 'server_order.selection.license'));
$this->assertSame('none', data_get($order->meta, 'server_order.selection.application'));
$this->assertSame('140.00', number_format((float) $order->amount_paid, 2, '.', ''));
}
public function test_vps_10_monthly_orders_include_one_time_setup_fee_but_yearly_orders_do_not(): void
{
$user = User::factory()->create();
$this->mockContaboImages();
$this->mock(ExchangeRateService::class, function ($mock): void {
$mock->shouldReceive('getUsdToGhs')->andReturn(15.50);
});
$product = HostingProduct::create([
'name' => 'VPS 10',
'slug' => 'vps-10-setup-fee-test',
'description' => 'Dynamic VPS setup fee test',
'category' => 'vps',
'type' => 'vps',
'price_monthly' => 0,
'price_quarterly' => 0,
'price_yearly' => 0,
'currency' => 'GHS',
'cpu_cores' => 3,
'ram_mb' => 8192,
'disk_gb' => 75,
'contabo_product_id' => 'V91',
'is_active' => true,
'is_visible' => true,
]);
$this->actingAs($user)->postJson(route('hosting.servers.store'), [
'product_id' => $product->id,
'server_name' => 'monthly-setup-fee-server',
'billing_cycle' => 'monthly',
'region' => 'EU',
'image' => '__install_later__',
'license' => 'none',
'application' => 'none',
'default_user' => 'root',
'additional_ip' => 'none',
'private_networking' => 'disabled',
'storage_type' => 'included',
'object_storage' => 'none',
'server_password' => 'Secure123!!',
'server_password_confirmation' => 'Secure123!!',
])->assertOk();
$monthlyOrder = CustomerHostingOrder::query()->latest('id')->firstOrFail();
$this->assertSame('200.00', number_format((float) $monthlyOrder->amount_paid, 2, '.', ''));
$this->assertSame('100.00', number_format((float) collect(data_get($monthlyOrder->meta, 'server_order.quote.line_items', []))->firstWhere('code', 'setup_fee')['amount'], 2, '.', ''));
$this->actingAs($user)->postJson(route('hosting.servers.store'), [
'product_id' => $product->id,
'server_name' => 'yearly-no-setup-fee-server',
'billing_cycle' => 'yearly',
'region' => 'EU',
'image' => '__install_later__',
'license' => 'none',
'application' => 'none',
'default_user' => 'root',
'additional_ip' => 'none',
'private_networking' => 'disabled',
'storage_type' => 'included',
'object_storage' => 'none',
'server_password' => 'Secure123!!',
'server_password_confirmation' => 'Secure123!!',
])->assertOk();
$yearlyOrder = CustomerHostingOrder::query()->latest('id')->firstOrFail();
$this->assertSame('960.00', number_format((float) $yearlyOrder->amount_paid, 2, '.', ''));
$this->assertNull(collect(data_get($yearlyOrder->meta, 'server_order.quote.line_items', []))->firstWhere('code', 'setup_fee'));
}
public function test_provisioning_job_uses_selected_server_options_for_contabo(): void
{
$user = User::factory()->create();
$this->mock(ExchangeRateService::class, function ($mock): void {
$mock->shouldReceive('getUsdToGhs')->andReturn(15.50);
});
$provider = \Mockery::mock(ContaboProvider::class);
$provider->shouldReceive('getAvailableImages')->once()->andReturn([
[
'id' => 'win-image',
'name' => 'Windows Server 2022',
'description' => 'Windows',
'os_type' => 'windows',
'standard_image' => true,
],
]);
$provider->shouldReceive('createInstance')
->once()
->withArgs(function (array $config): bool {
$this->assertSame('V45', $config['product_id']);
$this->assertSame('win-image', $config['image_id']);
$this->assertSame('US-west', $config['region']);
$this->assertSame('administrator', $config['default_user']);
$this->assertSame('PleskHost', $config['license']);
$this->assertSame(6, $config['period']);
$this->assertSame('Abc123!!', $config['root_password']);
$this->assertArrayHasKey('additionalIps', $config['add_ons']);
$this->assertArrayHasKey('privateNetworking', $config['add_ons']);
return true;
})
->andReturn([
'instance_id' => 'instance-123',
'ip_address' => '203.0.113.10',
]);
$this->app->instance(ContaboProvider::class, $provider);
$product = HostingProduct::create([
'name' => 'VPS S',
'slug' => 'vps-s-provisioning-test',
'description' => 'Dynamic VPS provisioning test',
'category' => 'vps',
'type' => 'vps',
'price_monthly' => 0,
'price_quarterly' => 0,
'price_yearly' => 0,
'currency' => 'USD',
'cpu_cores' => 4,
'ram_mb' => 8192,
'disk_gb' => 200,
'contabo_product_id' => 'V45',
'contabo_region' => 'EU',
'is_active' => true,
'is_visible' => true,
]);
$order = CustomerHostingOrder::create([
'user_id' => $user->id,
'hosting_product_id' => $product->id,
'domain_name' => 'job-provisioned-server',
'billing_cycle' => 'semiannual',
'amount_paid' => 0,
'currency' => 'GHS',
'status' => CustomerHostingOrder::STATUS_APPROVED,
'meta' => [
'region' => 'US-west',
'server_order' => [
'selection' => [
'image' => 'win-image',
'region' => 'US-west',
'license' => 'plesk_host',
'application' => 'none',
'default_user' => 'administrator',
'additional_ip' => 'one_extra',
'private_networking' => 'enabled',
'storage_type' => 'included',
'object_storage' => 'none',
],
'server_password_encrypted' => encrypt('Abc123!!'),
],
],
]);
$capacityService = \Mockery::mock(NodeCapacityService::class);
$sharedProvider = \Mockery::mock(SharedNodeProvider::class);
$serverOrders = $this->app->make(ServerOrderService::class);
$bootstrap = \Mockery::mock(ServerAgentBootstrapService::class);
$bootstrap->shouldReceive('ensureBootstrap')->andReturn(['token' => 'bootstrap-token']);
$installer = \Mockery::mock(ServerAgentInstallerService::class);
$installer->shouldReceive('augmentProvisioningConfig')->andReturnUsing(
fn ($freshOrder, array $config, array $bootstrapConfig): array => $config
);
(new ProvisionHostingOrderJob($order))->handle(
$capacityService,
app(HostingResourcePolicyService::class),
$sharedProvider,
$provider,
$serverOrders,
$bootstrap,
$installer,
);
$order->refresh();
$this->assertSame(CustomerHostingOrder::STATUS_ACTIVE, $order->status);
$this->assertSame('203.0.113.10', $order->server_ip);
$this->assertSame('administrator', $order->server_username);
$this->assertSame('instance-123', data_get($order->meta, 'contabo_instance_id'));
$this->assertDatabaseHas('provisioning_queue', [
'customer_hosting_order_id' => $order->id,
'status' => ProvisioningQueueItem::STATUS_COMPLETED,
]);
}
public function test_ladill_control_panel_selection_sets_internal_panel_url_after_provisioning(): void
{
$user = User::factory()->create();
$this->mock(ExchangeRateService::class, function ($mock): void {
$mock->shouldReceive('getUsdToGhs')->andReturn(15.50);
});
$provider = \Mockery::mock(ContaboProvider::class);
$provider->shouldReceive('getAvailableImages')->once()->andReturn([
[
'id' => 'ubuntu-image',
'name' => 'Ubuntu 22.04',
'description' => 'Ubuntu',
'os_type' => 'linux',
'standard_image' => true,
],
]);
$provider->shouldReceive('createInstance')
->once()
->withArgs(function (array $config): bool {
$this->assertNull($config['license']);
$this->assertSame('ladill', $config['panel']);
return true;
})
->andReturn([
'instance_id' => 'instance-panel-123',
'ip_address' => '203.0.113.20',
'status' => 'running',
'region' => 'EU',
'datacenter' => 'MUC1',
'image' => 'ubuntu-image',
]);
$this->app->instance(ContaboProvider::class, $provider);
$product = HostingProduct::create([
'name' => 'VPS S',
'slug' => 'vps-s-ladill-panel-test',
'description' => 'Dynamic VPS provisioning test',
'category' => 'vps',
'type' => 'vps',
'price_monthly' => 0,
'price_quarterly' => 0,
'price_yearly' => 0,
'currency' => 'USD',
'cpu_cores' => 4,
'ram_mb' => 8192,
'disk_gb' => 200,
'contabo_product_id' => 'V45',
'contabo_region' => 'EU',
'is_active' => true,
'is_visible' => true,
]);
$order = CustomerHostingOrder::create([
'user_id' => $user->id,
'hosting_product_id' => $product->id,
'domain_name' => 'ladill-panel-server',
'billing_cycle' => 'monthly',
'amount_paid' => 0,
'currency' => 'GHS',
'status' => CustomerHostingOrder::STATUS_APPROVED,
'meta' => [
'region' => 'EU',
'server_order' => [
'selection' => [
'image' => 'ubuntu-image',
'region' => 'EU',
'license' => 'ladill_panel',
'application' => 'none',
'default_user' => 'root',
'additional_ip' => 'none',
'private_networking' => 'disabled',
'storage_type' => 'included',
'object_storage' => 'none',
],
'selection_summary' => [
['label' => 'License', 'value' => 'Ladill Control Panel'],
],
'server_password_encrypted' => encrypt('Root123!!'),
],
],
]);
$capacityService = \Mockery::mock(NodeCapacityService::class);
$sharedProvider = \Mockery::mock(SharedNodeProvider::class);
$serverOrders = $this->app->make(ServerOrderService::class);
$bootstrap = \Mockery::mock(ServerAgentBootstrapService::class);
$bootstrap->shouldReceive('ensureBootstrap')->andReturn(['token' => 'bootstrap-token']);
$installer = \Mockery::mock(ServerAgentInstallerService::class);
$installer->shouldReceive('augmentProvisioningConfig')->andReturnUsing(
fn ($freshOrder, array $config, array $bootstrapConfig): array => $config
);
(new ProvisionHostingOrderJob($order))->handle(
$capacityService,
app(HostingResourcePolicyService::class),
$sharedProvider,
$provider,
$serverOrders,
$bootstrap,
$installer,
);
$order->refresh();
$this->assertSame(route('hosting.server-panel.show', $order), $order->control_panel_url);
$this->assertSame('ladill', data_get($order->meta, 'server_panel.panel'));
$this->assertSame('instance-panel-123', data_get($order->meta, 'contabo_instance_id'));
}
public function test_ladill_server_panel_page_and_power_action_work_for_selected_orders(): void
{
$user = User::factory()->create();
$product = HostingProduct::create([
'name' => 'VPS S',
'slug' => 'vps-s-panel-route-test',
'description' => 'Dynamic VPS provisioning test',
'category' => 'vps',
'type' => 'vps',
'price_monthly' => 0,
'price_quarterly' => 0,
'price_yearly' => 0,
'currency' => 'USD',
'cpu_cores' => 4,
'ram_mb' => 8192,
'disk_gb' => 200,
'contabo_product_id' => 'V45',
'is_active' => true,
'is_visible' => true,
]);
$order = CustomerHostingOrder::create([
'user_id' => $user->id,
'hosting_product_id' => $product->id,
'domain_name' => 'panel-route-server',
'billing_cycle' => 'monthly',
'amount_paid' => 0,
'currency' => 'GHS',
'status' => CustomerHostingOrder::STATUS_ACTIVE,
'server_ip' => '203.0.113.50',
'server_username' => 'root',
'control_panel_url' => 'http://localhost/hosting/orders/1/panel',
'meta' => [
'contabo_instance_id' => 'instance-route-123',
'server_order' => [
'selection' => [
'license' => 'ladill_panel',
'application' => 'none',
],
'selection_summary' => [
['label' => 'License', 'value' => 'Ladill Control Panel'],
],
],
'server_panel' => [
'panel' => 'ladill',
'power_status' => 'on',
'instance_status' => 'running',
],
],
]);
$provider = \Mockery::mock(ContaboProvider::class);
$provider->shouldReceive('startInstance')->once()->with('instance-route-123')->andReturn(true);
$this->app->instance(ContaboProvider::class, $provider);
$this->actingAs($user)
->get(route('hosting.server-panel.show', $order))
->assertOk()
->assertSee('Ladill Control Panel')
->assertSee('panel-route-server');
$this->actingAs($user)
->post(route('hosting.server-panel.power', [$order, 'start']))
->assertRedirect();
}
public function test_provisioning_uses_cloud_init_for_webmin_profile(): void
{
$user = User::factory()->create();
$this->mock(ExchangeRateService::class, function ($mock): void {
$mock->shouldReceive('getUsdToGhs')->andReturn(15.50);
});
$provider = \Mockery::mock(ContaboProvider::class);
$provider->shouldReceive('getAvailableImages')->once()->andReturn([
[
'id' => 'ubuntu-image',
'name' => 'Ubuntu 22.04',
'description' => 'Ubuntu',
'os_type' => 'linux',
'standard_image' => true,
],
]);
$provider->shouldReceive('generateCloudInit')->once()->andReturn('#cloud-config webmin');
$provider->shouldReceive('createInstance')
->once()
->withArgs(function (array $config): bool {
$this->assertSame('ubuntu-image', $config['image_id']);
$this->assertSame('#cloud-config webmin', $config['user_data']);
$this->assertNull($config['license']);
$this->assertNull($config['application_id']);
return true;
})
->andReturn([
'instance_id' => 'instance-webmin-123',
'ip_address' => '203.0.113.30',
]);
$this->app->instance(ContaboProvider::class, $provider);
$product = HostingProduct::create([
'name' => 'VPS S',
'slug' => 'vps-s-webmin-test',
'description' => 'Dynamic VPS provisioning test',
'category' => 'vps',
'type' => 'vps',
'price_monthly' => 0,
'price_quarterly' => 0,
'price_yearly' => 0,
'currency' => 'USD',
'cpu_cores' => 4,
'ram_mb' => 8192,
'disk_gb' => 200,
'contabo_product_id' => 'V45',
'contabo_region' => 'EU',
'is_active' => true,
'is_visible' => true,
]);
$order = CustomerHostingOrder::create([
'user_id' => $user->id,
'hosting_product_id' => $product->id,
'domain_name' => 'webmin-server',
'billing_cycle' => 'monthly',
'amount_paid' => 0,
'currency' => 'GHS',
'status' => CustomerHostingOrder::STATUS_APPROVED,
'meta' => [
'region' => 'EU',
'server_order' => [
'selection' => [
'image' => 'ubuntu-image',
'region' => 'EU',
'license' => 'none',
'application' => 'webmin',
'default_user' => 'root',
'additional_ip' => 'none',
'private_networking' => 'disabled',
'storage_type' => 'included',
'object_storage' => 'none',
],
'server_password_encrypted' => encrypt('Root123!!'),
],
],
]);
$capacityService = \Mockery::mock(NodeCapacityService::class);
$sharedProvider = \Mockery::mock(SharedNodeProvider::class);
$serverOrders = $this->app->make(ServerOrderService::class);
$bootstrap = \Mockery::mock(ServerAgentBootstrapService::class);
$bootstrap->shouldReceive('ensureBootstrap')->andReturn(['token' => 'bootstrap-token']);
$installer = \Mockery::mock(ServerAgentInstallerService::class);
$installer->shouldReceive('augmentProvisioningConfig')->andReturnUsing(
fn ($freshOrder, array $config, array $bootstrapConfig): array => $config
);
(new ProvisionHostingOrderJob($order))->handle(
$capacityService,
app(HostingResourcePolicyService::class),
$sharedProvider,
$provider,
$serverOrders,
$bootstrap,
$installer,
);
$this->assertDatabaseHas('provisioning_queue', [
'customer_hosting_order_id' => $order->id,
'status' => ProvisioningQueueItem::STATUS_COMPLETED,
]);
}
}