customer = Customer::factory()->create(); $this->product = Product::factory()->create([ 'product_type' => 'hosting', 'is_active' => true, ]); } private function actingAsCustomer(): static { return $this->actingAs($this->customer, 'client') ->withHeaders(['x-access-token' => $this->buildClientAccessToken()]); } /** Encrypts the shared secret the same way ClientAccessTokenCheck expects, for test requests. */ private function buildClientAccessToken(): string { $key = hex2bin((string) config('services.client_api.key')); $secret = (string) config('services.client_api.secret'); $iv = random_bytes(16); $ciphertext = openssl_encrypt($secret, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); return base64_encode($iv . $ciphertext); } private function createServiceWithOldPrice(int $oldPrice): Service { $order = Order::create([ 'order_num' => 'ORD-' . uniqid(), 'customer_id' => $this->customer->id, 'sub_total' => $oldPrice, 'total' => $oldPrice, 'status' => OrderStatus::ACTIVE->value, ]); $orderItem = OrderItem::create([ 'order_id' => $order->id, 'product_id' => $this->product->id, 'billing_cycle' => 'monthly', 'months' => 1, 'quantity' => 1, 'price' => $oldPrice, ]); return Service::create([ 'customer_id' => $this->customer->id, 'product_id' => $this->product->id, 'order_item_id' => $orderItem->id, 'status' => 'active', 'server_name' => 'test-server', ]); } public function test_renew_uses_current_catalog_price_not_the_original_order_price(): void { $service = $this->createServiceWithOldPrice(90_000); // Giá sản phẩm hiện tại đã tăng lên 100.000 kể từ lúc khách đặt mua. ProductPricings::create([ 'product_id' => $this->product->id, 'billing_cycle' => 'monthly', 'price' => 100_000, 'is_active' => true, ]); $response = $this->actingAsCustomer()->postJson( "/v1/client/dich-vu/{$service->id}/renew", ['months' => 2], ); $response->assertOk(); $response->assertJsonPath('data.total', 200_000); $this->assertDatabaseHas('invoices', [ 'id' => $response->json('data.invoice_id'), 'total' => 200_000, ]); } public function test_renew_fails_when_product_pricing_is_no_longer_active(): void { $service = $this->createServiceWithOldPrice(90_000); ProductPricings::create([ 'product_id' => $this->product->id, 'billing_cycle' => 'monthly', 'price' => 100_000, 'is_active' => false, ]); $response = $this->actingAsCustomer()->postJson( "/v1/client/dich-vu/{$service->id}/renew", ['months' => 1], ); $response->assertStatus(400); $this->assertSame(0, Invoice::where('customer_id', $this->customer->id)->count()); } }