106 lines
4.1 KiB
PHP
106 lines
4.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\Api\Admin\Customer;
|
|
|
|
use App\Models\Customer;
|
|
use App\Models\DomainPricing;
|
|
use App\Models\Product;
|
|
use App\Models\Service;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Spatie\Permission\Models\Role;
|
|
use Tests\TestCase;
|
|
|
|
class CreateDomainServicePricingTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
private User $admin;
|
|
|
|
private Customer $customer;
|
|
|
|
private Product $product;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
Role::firstOrCreate(['name' => 'Full Administrator', 'guard_name' => 'admin']);
|
|
$this->admin = User::factory()->create();
|
|
$this->admin->assignRole('Full Administrator');
|
|
$this->customer = Customer::factory()->create();
|
|
$this->product = Product::factory()->create(['product_type' => 'domain']);
|
|
|
|
DomainPricing::query()->delete();
|
|
DomainPricing::create(['type' => 'domain', 'tld' => '.vn', 'setup_fee' => '100000', 'first_year' => 400_000, 'recurring_fee' => '350000', 'is_active' => true]);
|
|
DomainPricing::create(['type' => 'domain', 'tld' => '.com.vn', 'setup_fee' => 'Miễn phí', 'first_year' => 300_000, 'recurring_fee' => '300000', 'is_active' => true]);
|
|
}
|
|
|
|
private function createService(array $data)
|
|
{
|
|
return $this->actingAs($this->admin, 'admin')->postJson(
|
|
"/api/v1/administrator/customers/{$this->customer->uuid}/services",
|
|
['product_id' => $this->product->id, 'payment_method' => 'transfer', 'billing_cycle' => 'biennially', ...$data],
|
|
);
|
|
}
|
|
|
|
public function test_domain_service_uses_domain_pricing_for_matched_tld(): void
|
|
{
|
|
$this->createService(['server_name' => 'Example.COM.vn'])->assertCreated();
|
|
$this->createService(['server_name' => 'example.vn'])->assertCreated();
|
|
|
|
$this->assertDatabaseHas('order_items', ['domain_name' => 'Example.COM.vn', 'price' => 600_000]);
|
|
$this->assertDatabaseHas('order_items', ['domain_name' => 'example.vn', 'price' => 850_000]);
|
|
}
|
|
|
|
public function test_domain_without_pricing_requires_amount(): void
|
|
{
|
|
$this->createService(['server_name' => 'example.xyz'])->assertStatus(422);
|
|
$this->assertSame(0, Service::count());
|
|
|
|
$this->createService(['server_name' => 'example.xyz', 'price' => 250_000])->assertCreated();
|
|
$this->assertDatabaseHas('order_items', ['domain_name' => 'example.xyz', 'price' => 250_000]);
|
|
}
|
|
|
|
public function test_saving_price_on_service_without_order_creates_unpaid_order_and_invoice(): void
|
|
{
|
|
$service = Service::create([
|
|
'customer_id' => $this->customer->id,
|
|
'product_id' => $this->product->id,
|
|
'server_name' => 'example.vn',
|
|
'status' => 'active',
|
|
]);
|
|
$url = "/api/v1/administrator/customers/{$this->customer->uuid}/services/{$service->id}";
|
|
|
|
$this->actingAs($this->admin, 'admin')->putJson($url, ['price' => 500_000, 'billing_cycle' => 'annually'])->assertOk();
|
|
|
|
$service->refresh();
|
|
$this->assertSame(500_000, (int) $service->orderItem->price);
|
|
$this->assertSame(1, (int) $service->invoice->status);
|
|
$this->assertSame(500_000, (int) $service->invoice->total);
|
|
|
|
$this->actingAs($this->admin, 'admin')->putJson($url, ['price' => 450_000])->assertOk();
|
|
|
|
$this->assertSame(450_000, (int) $service->invoice->fresh()->total);
|
|
$this->assertSame(450_000, (int) $service->invoice->invoiceItems()->value('total_price'));
|
|
$this->assertDatabaseCount('invoices', 1);
|
|
}
|
|
|
|
public function test_domain_quote_endpoint(): void
|
|
{
|
|
$url = '/api/v1/administrator/services/domain-quote';
|
|
|
|
$this->actingAs($this->admin, 'admin')->getJson("{$url}?domain=abc.vn&billing_cycle=triennially")
|
|
->assertOk()
|
|
->assertJsonPath('data.tld', '.vn')
|
|
->assertJsonPath('data.years', 3)
|
|
->assertJsonPath('data.price', 1_200_000);
|
|
|
|
$this->actingAs($this->admin, 'admin')->getJson("{$url}?domain=abc.xyz")
|
|
->assertOk()
|
|
->assertJsonPath('data', null);
|
|
}
|
|
}
|