From db827bbb8cb4e92efcb2901d638fa51c8b14667e Mon Sep 17 00:00:00 2001 From: "Fabian @ Blax Software" Date: Wed, 3 Jun 2026 09:49:12 +0200 Subject: [PATCH] feat(enums): add SERVICE product type; fix flaky multi-product checkout test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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. --- README.md | 4 ++-- src/Enums/ProductType.php | 8 ++++++++ tests/Feature/Checkout/CartCheckoutSessionTest.php | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 24bf6a6..65c31ea 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/Enums/ProductType.php b/src/Enums/ProductType.php index fc1c0ce..91f9805 100644 --- a/src/Enums/ProductType.php +++ b/src/Enums/ProductType.php @@ -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', }; } } diff --git a/tests/Feature/Checkout/CartCheckoutSessionTest.php b/tests/Feature/Checkout/CartCheckoutSessionTest.php index cdb7f17..bce344b 100644 --- a/tests/Feature/Checkout/CartCheckoutSessionTest.php +++ b/tests/Feature/Checkout/CartCheckoutSessionTest.php @@ -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);