| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- <?php
- namespace Tests\Unit;
- use App\Enums\CartStatusEnum;
- use App\Http\Requests\CartRequest;
- use App\Models\Cart;
- use App\Models\Provider;
- use App\Models\Schedule;
- use App\Services\CartService;
- use App\Services\Pagarme\PagarmePaymentService;
- use App\Services\PaymentService;
- use Illuminate\Validation\ValidationException;
- use Tests\TestCase;
- class CartProviderInvariantTest extends TestCase
- {
- public function test_request_rejects_schedules_from_different_providers(): void
- {
- $request = CartRequest::create('/cart/me', 'POST', [
- 'schedules' => [
- ['provider_id' => 10],
- ['provider_id' => 20],
- ],
- ]);
- $validator = validator([], []);
- foreach ($request->after() as $callback) {
- $callback($validator);
- }
- $this->assertSame(
- 'Todos os agendamentos do carrinho precisam ser do mesmo prestador.',
- $validator->errors()->first('schedules'),
- );
- }
- public function test_request_accepts_schedules_from_the_same_provider(): void
- {
- $request = CartRequest::create('/cart/me', 'POST', [
- 'provider_id' => 10,
- 'schedules' => [
- ['date' => '2026-08-01'],
- ['provider_id' => 10, 'date' => '2026-08-02'],
- ],
- ]);
- $validator = validator([], []);
- foreach ($request->after() as $callback) {
- $callback($validator);
- }
- $this->assertFalse($validator->errors()->has('schedules'));
- }
- public function test_service_defensively_rejects_mixed_providers(): void
- {
- $method = new \ReflectionMethod(CartService::class, 'singleProviderId');
- $this->expectException(ValidationException::class);
- $method->invoke(new CartService, [], [
- ['provider_id' => 10],
- ['provider_id' => 20],
- ]);
- }
- public function test_checkout_rejects_a_cart_with_a_schedule_from_another_provider(): void
- {
- $cart = $this->cart(providerId: 10);
- $schedules = collect([
- $this->schedule(id: 1, providerId: 10),
- $this->schedule(id: 2, providerId: 20),
- ]);
- $method = new \ReflectionMethod(PaymentService::class, 'validateCartForPayment');
- $this->expectException(\InvalidArgumentException::class);
- $this->expectExceptionMessage('Todos os agendamentos do carrinho precisam ser do mesmo prestador.');
- $method->invoke(new PaymentService(new PagarmePaymentService), $cart, $schedules);
- }
- public function test_checkout_waits_until_every_schedule_is_accepted(): void
- {
- $cart = $this->cart(providerId: 10);
- $schedules = collect([
- $this->schedule(id: 1, providerId: 10),
- $this->schedule(id: 2, providerId: 10, status: 'pending'),
- ]);
- $method = new \ReflectionMethod(PaymentService::class, 'validateCartForPayment');
- $this->expectException(\InvalidArgumentException::class);
- $this->expectExceptionMessage('Agendamento 2 precisa estar aceito para o carrinho ser pago.');
- $method->invoke(new PaymentService(new PagarmePaymentService), $cart, $schedules);
- }
- private function cart(int $providerId): Cart
- {
- $provider = new Provider;
- $provider->forceFill([
- 'id' => $providerId,
- 'recipient_id' => 'rp_test',
- ]);
- $cart = new Cart;
- $cart->forceFill([
- 'id' => 1,
- 'client_id' => 30,
- 'provider_id' => $providerId,
- 'status' => CartStatusEnum::OPEN->value,
- ]);
- $cart->setRelation('provider', $provider);
- return $cart;
- }
- private function schedule(int $id, int $providerId, string $status = 'accepted'): Schedule
- {
- $schedule = new Schedule;
- $schedule->forceFill([
- 'id' => $id,
- 'client_id' => 30,
- 'provider_id' => $providerId,
- 'status' => $status,
- 'total_amount' => 100,
- ]);
- return $schedule;
- }
- }
|