feat(enums): add SERVICE product type; fix flaky multi-product checkout test

- ProductType::SERVICE for intangible/served products (subscriptions, licences,
  consulting) — no stock, behaves like SIMPLE for cart purposes. Lets hosts
  whose catalogue includes services adopt the package without a value clash.
- it_creates_separate_line_items_for_multiple_products pinned its two prices to
  one_time; without a type the factory randomised it and could mix recurring +
  one-time, tripping MixedCheckoutModeException intermittently.
This commit is contained in:
Fabian @ Blax Software 2026-06-03 09:49:12 +02:00
parent d4ae9339ac
commit db827bbb8c
3 changed files with 12 additions and 2 deletions

View File

@ -4,7 +4,7 @@
[![Tests](https://github.com/blax-software/laravel-shop/actions/workflows/tests.yml/badge.svg)](https://github.com/blax-software/laravel-shop/actions/workflows/tests.yml)
[![Tests Count](https://img.shields.io/badge/tests-1409%20passing-success?style=flat-square)](#testing)
[![Assertions](https://img.shields.io/badge/assertions-3772-blue?style=flat-square)](#testing)
[![Assertions](https://img.shields.io/badge/assertions-3773-blue?style=flat-square)](#testing)
[![Latest Version](https://img.shields.io/packagist/v/blax-software/laravel-shop.svg?style=flat-square)](https://packagist.org/packages/blax-software/laravel-shop)
[![License](https://img.shields.io/packagist/l/blax-software/laravel-shop.svg?style=flat-square)](https://packagist.org/packages/blax-software/laravel-shop)
[![PHP Version](https://img.shields.io/packagist/php-v/blax-software/laravel-shop.svg?style=flat-square)](https://packagist.org/packages/blax-software/laravel-shop)
@ -192,7 +192,7 @@ booking, Stripe sync and the event surface — so host applications can lean
on the behaviour with confidence.
```
Tests: 1409, Assertions: 3772
Tests: 1409, Assertions: 3773
```
CI runs the full suite on every push (see the badge above). To run it

View File

@ -19,6 +19,13 @@ enum ProductType: string
* the borrow extend return flow.
*/
case LOANABLE = 'loanable';
/**
* Service: an intangible/served product (subscriptions, access licences,
* consulting) with no physical stock. Behaves like SIMPLE for cart/stock
* purposes; the distinct type just lets hosts and reporting tell goods
* from services apart.
*/
case SERVICE = 'service';
public function label(): string
{
@ -31,6 +38,7 @@ enum ProductType: string
self::VARIATION => 'Variation',
self::POOL => 'Pool',
self::LOANABLE => 'Loanable',
self::SERVICE => 'Service',
};
}
}

View File

@ -234,6 +234,7 @@ class CartCheckoutSessionTest extends TestCase
'unit_amount' => 1000,
'currency' => 'USD',
'is_default' => true,
'type' => 'one_time',
]);
ProductPrice::factory()->create([
@ -242,6 +243,7 @@ class CartCheckoutSessionTest extends TestCase
'unit_amount' => 2000,
'currency' => 'USD',
'is_default' => true,
'type' => 'one_time',
]);
$this->cart->addToCart($product1, 2);