actingAs($customer, 'client') ->withHeaders(['x-access-token' => $this->buildClientAccessToken()]); } public function test_pay_order_hides_unknown_exception_message(): void { $customer = Customer::factory()->create(); $order = Order::create([ 'order_num' => 'ORD-TEST-' . uniqid(), 'customer_id' => $customer->id, 'sub_total' => 100000, 'discount_amount' => 0, 'total' => 100000, 'status' => OrderStatus::PENDING->value, ]); $mock = \Mockery::mock(OrderService::class); $mock->shouldReceive('pay') ->once() ->andThrow(new \RuntimeException('leaking internal DB connection string secret')); $this->app->instance(OrderService::class, $mock); $response = $this->actingAsCustomer($customer)->postJson("/v1/orders/{$order->order_num}/pay", [ 'payment_method' => 'balance', ]); $response->assertStatus(500); $response->assertJsonPath('success', false); $this->assertStringNotContainsString('leaking internal', (string) $response->getContent()); $this->assertSame('Có lỗi xảy ra, vui lòng thử lại', $response->json('message')); } public function test_pay_order_keeps_business_message_for_invalid_argument(): void { $customer = Customer::factory()->create(['total' => 0]); $order = Order::create([ 'order_num' => 'ORD-TEST-' . uniqid(), 'customer_id' => $customer->id, 'sub_total' => 100000, 'discount_amount' => 0, 'total' => 100000, 'status' => OrderStatus::PENDING->value, ]); $response = $this->actingAsCustomer($customer)->postJson("/v1/orders/{$order->order_num}/pay", [ 'payment_method' => 'balance', ]); $response->assertStatus(422); $response->assertJsonPath('success', false); $this->assertStringContainsString('Số dư không đủ', (string) $response->json('message')); } }