From 9e7812c70ed64873eefe4b5f1ac29335ff7658e1 Mon Sep 17 00:00:00 2001 From: a6a2f5842 Date: Wed, 24 Dec 2025 19:40:10 +0100 Subject: [PATCH] BFI cart single item --- src/Models/Cart.php | 55 +++++-- tests/Feature/BookingFeatureTest.php | 30 ++-- tests/Feature/BookingPerMinutePricingTest.php | 105 ++++++++++--- .../Feature/BookingTimespanValidationTest.php | 26 ++-- .../Feature/CartAddToCartPoolPricingTest.php | 71 ++++----- tests/Feature/CartCheckoutSessionTest.php | 19 +-- tests/Feature/CartDateManagementTest.php | 44 +++--- tests/Feature/CartDateStringParsingTest.php | 22 +-- tests/Feature/CartFacadeTest.php | 53 +++---- tests/Feature/CartItemAttributesTest.php | 50 +++---- .../CartItemAvailabilityValidationTest.php | 30 ++-- tests/Feature/CartItemDateManagementTest.php | 17 ++- .../CartItemRequiredAdjustmentsTest.php | 31 ++-- tests/Feature/CartManagementTest.php | 58 +++---- tests/Feature/CartServiceBookingTest.php | 37 ++--- tests/Feature/CheckoutStockValidationTest.php | 19 ++- tests/Feature/CommandProductExamplesTest.php | 9 +- tests/Feature/GuestCartTest.php | 33 ++-- tests/Feature/HasShoppingCapabilitiesTest.php | 39 ++--- tests/Feature/PaymentMethodFieldsTest.php | 4 + tests/Feature/PaymentProviderTest.php | 29 ++-- tests/Feature/PoolAvailabilityMethodsTest.php | 25 ++-- tests/Feature/PoolBookingDetectionTest.php | 17 ++- tests/Feature/PoolClaimingPriorityTest.php | 7 +- .../Feature/PoolMaxQuantityValidationTest.php | 20 +-- tests/Feature/PoolParkingCartPricingTest.php | 55 ++++--- tests/Feature/PoolPerMinutePricingTest.php | 53 +++---- tests/Feature/PoolProductCheckoutTest.php | 23 +-- tests/Feature/PoolProductPriceIdTest.php | 17 ++- .../PoolProductPricingFlexibilityTest.php | 18 +-- tests/Feature/PoolProductPricingTest.php | 31 ++-- tests/Feature/PoolProductRelationsTest.php | 14 +- tests/Feature/PoolProductTest.php | 56 +++---- tests/Feature/PoolProductionBugTest.php | 21 +-- tests/Feature/PoolSeparateCartItemsTest.php | 9 +- tests/Feature/PoolSmartAllocationTest.php | 19 +-- tests/Feature/ProductActionTest.php | 32 ++-- tests/Feature/ProductAttributeTest.php | 21 +-- tests/Feature/ProductCategoryTest.php | 67 +++++---- tests/Feature/ProductManagementTest.php | 37 ++--- tests/Feature/ProductPriceTest.php | 25 ++-- .../Feature/ProductPricingValidationTest.php | 23 +-- tests/Feature/ProductPurchaseTest.php | 25 ++-- tests/Feature/ProductScopeTest.php | 39 ++--- tests/Feature/ProductStockTest.php | 141 +++++++++--------- tests/Feature/PurchaseFlowTest.php | 42 +++--- tests/Feature/ShopFacadeTest.php | 45 +++--- tests/Feature/StockManagementTest.php | 46 +++--- tests/Feature/StripeChargeFlowTest.php | 21 +-- tests/Unit/CartItemTest.php | 40 ++--- tests/Unit/CartTest.php | 42 +++--- tests/Unit/HtmlDateTimeCastTest.php | 21 +-- tests/Unit/ProductPricingTest.php | 14 +- tests/Unit/ProductRelationsTest.php | 7 +- tests/Unit/StockManagementTest.php | 9 +- 55 files changed, 991 insertions(+), 872 deletions(-) diff --git a/src/Models/Cart.php b/src/Models/Cart.php index cccb9f9..f04bd83 100644 --- a/src/Models/Cart.php +++ b/src/Models/Cart.php @@ -849,8 +849,8 @@ class Cart extends Model Model $cartable, int $quantity = 1, array $parameters = [], - \DateTimeInterface $from = null, - \DateTimeInterface $until = null + null|\DateTimeInterface $from = null, + null|\DateTimeInterface $until = null ): CartItem { // $cartable must implement Cartable if (! $cartable instanceof Cartable) { @@ -873,8 +873,20 @@ class Cart extends Model $until = $this->until; } + if ($cartable instanceof Product) { + $is_pool = $cartable->isPool(); + $is_booking = $cartable->isBooking(); + } elseif ( + $cartable instanceof ProductPrice + && $cartable->purchasable instanceof Product + ) { + $is_pool = $cartable->purchasable->isPool(); + $is_booking = $cartable->purchasable->isBooking(); + } + + // For pool products with quantity > 1, add them one at a time to get progressive pricing - if ($cartable instanceof Product && $cartable->isPool() && $quantity > 1) { + if ($is_pool && $quantity > 1) { // Validate availability if dates are provided if ($from && $until) { $available = $cartable->getPoolMaxQuantity($from, $until); @@ -912,7 +924,9 @@ class Cart extends Model ->where('purchasable_type', get_class($cartable)) ->sum('quantity'); - $availableForThisRequest = $totalCapacity === PHP_INT_MAX ? PHP_INT_MAX : max(0, $totalCapacity - $itemsInCart); + $availableForThisRequest = $totalCapacity === PHP_INT_MAX + ? PHP_INT_MAX + : max(0, $totalCapacity - $itemsInCart); if ($availableForThisRequest !== PHP_INT_MAX && $quantity > $availableForThisRequest) { throw new NotEnoughStockException( @@ -942,14 +956,18 @@ class Cart extends Model } // Check booking product availability if dates are provided - if ($cartable->isBooking() && !$cartable->isPool() && !$cartable->isAvailableForBooking($from, $until, $quantity)) { + if ( + $is_booking + && !$is_pool + && !$cartable->isAvailableForBooking($from, $until, $quantity) + ) { throw new NotEnoughStockException( "Product '{$cartable->name}' is not available for the requested period ({$from->format('Y-m-d')} to {$until->format('Y-m-d')})." ); } // Check pool product availability if dates are provided - if ($cartable->isPool()) { + if ($is_pool) { $maxQuantity = $cartable->getPoolMaxQuantity($from, $until); // Subtract items already in cart for the same period @@ -987,7 +1005,7 @@ class Cart extends Model } else { // When adding pool items without dates, validate against total pool capacity // This allows adding items even if currently claimed - date-based validation happens later - if ($cartable->isPool()) { + if ($is_pool) { $totalCapacity = $cartable->getPoolTotalCapacity(); // Total capacity ignoring claims // Subtract items already in cart (without dates or with any dates) @@ -1015,7 +1033,7 @@ class Cart extends Model $poolSingleItem = null; $poolPriceId = null; - if ($cartable instanceof Product && $cartable->isPool()) { + if ($is_pool) { $this->unsetRelation('items'); // Clear cached relationship $currentQuantityInCart = $this->items() ->where('purchasable_id', $cartable->getKey()) @@ -1035,7 +1053,7 @@ class Cart extends Model ->where('purchasable_id', $cartable->getKey()) ->where('purchasable_type', get_class($cartable)) ->get() - ->first(function ($item) use ($parameters, $from, $until, $cartable, $poolPriceId) { + ->first(function ($item) use ($parameters, $from, $until, $cartable, $poolPriceId, $is_pool) { $existingParams = is_array($item->parameters) ? $item->parameters : (array) $item->parameters; @@ -1061,7 +1079,7 @@ class Cart extends Model // This is critical because different single items have their own stock limits // even if they happen to share the same price (e.g., via pool fallback price) $priceMatch = true; - if ($cartable instanceof Product && $cartable->isPool()) { + if ($is_pool) { // Calculate expected price for this item $poolItemData = $cartable->getNextAvailablePoolItemWithPrice($this, null, $from, $until); $expectedPrice = $poolItemData['price'] ?? null; @@ -1085,7 +1103,7 @@ class Cart extends Model // Calculate price per day (base price) // For pool products, get price based on how many items are already in cart - if ($cartable instanceof Product && $cartable->isPool()) { + if ($is_pool) { // Use smarter pricing that considers which price tiers are used $poolItemData = $cartable->getNextAvailablePoolItemWithPrice($this, null, $from, $until); @@ -1115,7 +1133,7 @@ class Cart extends Model // Ensure prices are not null if ($pricePerDay === null) { - if ($cartable instanceof Product && $cartable->isPool()) { + if ($is_pool) { // For pool products, throw specific error when neither pool nor single items have prices throw \Blax\Shop\Exceptions\HasNoPriceException::poolProductNoPriceAndNoSingleItemPrices($cartable->name); } @@ -1129,8 +1147,15 @@ class Cart extends Model } // Calculate price per unit for the entire period and round to nearest cent for consistency - $pricePerUnit = (int) round($pricePerDay * $days); - $regularPricePerUnit = (int) round($regularPricePerDay * $days); + if ($is_booking) { + // For bookings, price scales with days + $pricePerUnit = (int) round($pricePerDay * $days); + $regularPricePerUnit = (int) round($regularPricePerDay * $days); + } else { + // For non-bookings, price is per unit regardless of days + $pricePerUnit = (int) round($pricePerDay); + $regularPricePerUnit = (int) round($regularPricePerDay); + } // Defensive check - ensure pricePerUnit is not null if ($pricePerUnit === null) { @@ -1158,7 +1183,7 @@ class Cart extends Model $priceId = null; if ($cartable instanceof Product) { // For pool products, use the single item's price_id - if ($cartable->isPool() && $poolPriceId) { + if ($is_pool && $poolPriceId) { $priceId = $poolPriceId; } else { // Get the default price for the product diff --git a/tests/Feature/BookingFeatureTest.php b/tests/Feature/BookingFeatureTest.php index 9251a30..3cd6a47 100644 --- a/tests/Feature/BookingFeatureTest.php +++ b/tests/Feature/BookingFeatureTest.php @@ -6,11 +6,11 @@ use Blax\Shop\Enums\ProductType; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Models\ProductPurchase; -use Blax\Shop\Models\Cart; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; use Carbon\Carbon; +use PHPUnit\Framework\Attributes\Test; class BookingFeatureTest extends TestCase { @@ -48,7 +48,7 @@ class BookingFeatureTest extends TestCase ]); } - /** @test */ + #[Test] public function it_can_create_a_booking_product() { $this->assertNotNull($this->bookingProduct); @@ -56,7 +56,7 @@ class BookingFeatureTest extends TestCase $this->assertTrue($this->bookingProduct->isBooking()); } - /** @test */ + #[Test] public function it_can_purchase_a_booking_with_dates() { $from = Carbon::now()->addDays(1); @@ -77,7 +77,7 @@ class BookingFeatureTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $purchase->until->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_throws_exception_when_booking_without_dates() { $this->expectException(\Exception::class); @@ -86,7 +86,7 @@ class BookingFeatureTest extends TestCase $this->user->purchase($this->price, 1); } - /** @test */ + #[Test] public function it_decreases_stock_for_booking_duration() { $from = Carbon::now()->addDays(1); @@ -108,7 +108,7 @@ class BookingFeatureTest extends TestCase $this->assertEquals($initialStock - 2, $remainingStock); } - /** @test */ + #[Test] public function it_releases_stock_after_booking_period() { $from = Carbon::now()->subDays(3); @@ -134,7 +134,7 @@ class BookingFeatureTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $claim->expires_at->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_can_check_booking_availability() { $from = Carbon::now()->addDays(5); @@ -147,7 +147,7 @@ class BookingFeatureTest extends TestCase $this->assertFalse($this->bookingProduct->isAvailableForBooking($from, $until, 15)); } - /** @test */ + #[Test] public function it_can_add_booking_to_cart_with_dates() { $cart = $this->user->currentCart(); @@ -172,7 +172,7 @@ class BookingFeatureTest extends TestCase $this->assertEquals($until->toDateTimeString(), $cartItem->parameters['until']); } - /** @test */ + #[Test] public function it_can_checkout_cart_with_booking_product() { $cart = $this->user->currentCart(); @@ -207,7 +207,7 @@ class BookingFeatureTest extends TestCase $this->assertEquals($initialStock - 2, $this->bookingProduct->getAvailableStock()); } - /** @test */ + #[Test] public function it_prevents_overbooking() { $from = Carbon::now()->addDays(20); @@ -234,7 +234,7 @@ class BookingFeatureTest extends TestCase ); } - /** @test */ + #[Test] public function it_can_scope_booking_purchases() { $from = Carbon::now()->addDays(25); @@ -267,7 +267,7 @@ class BookingFeatureTest extends TestCase $this->assertTrue($bookingPurchases->first()->isBooking()); } - /** @test */ + #[Test] public function it_can_scope_ended_bookings() { $pastFrom = Carbon::now()->subDays(5); @@ -302,7 +302,7 @@ class BookingFeatureTest extends TestCase $this->assertFalse($futurePurchase->isBookingEnded()); } - /** @test */ + #[Test] public function it_can_scope_booking_products() { // Create regular product @@ -315,7 +315,7 @@ class BookingFeatureTest extends TestCase $this->assertEquals($this->bookingProduct->id, $bookingProducts->first()->id); } - /** @test */ + #[Test] public function booking_stock_expires_after_until_date() { $from = Carbon::now()->addDays(1); @@ -340,7 +340,7 @@ class BookingFeatureTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $stockRecord->expires_at->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function multiple_bookings_with_different_dates_work_independently() { $booking1From = Carbon::now()->addDays(1); diff --git a/tests/Feature/BookingPerMinutePricingTest.php b/tests/Feature/BookingPerMinutePricingTest.php index e22c87b..7549553 100644 --- a/tests/Feature/BookingPerMinutePricingTest.php +++ b/tests/Feature/BookingPerMinutePricingTest.php @@ -10,6 +10,8 @@ use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; + class BookingPerMinutePricingTest extends TestCase { @@ -48,7 +50,7 @@ class BookingPerMinutePricingTest extends TestCase ]); } - /** @test */ + #[Test] public function it_calculates_price_for_exact_24_hours() { $from = Carbon::now()->addDays(5)->setTime(9, 0, 0); @@ -61,7 +63,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(10000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_price_for_12_hours_as_half_day() { $from = Carbon::now()->addDays(5)->setTime(9, 0, 0); @@ -74,7 +76,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(5000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_price_for_36_hours() { $from = Carbon::now()->addDays(5)->setTime(9, 0, 0); @@ -87,7 +89,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(15000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_price_for_6_hours() { $from = Carbon::now()->addDays(5)->setTime(10, 0, 0); @@ -100,7 +102,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(2500, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_price_for_90_minutes() { $from = Carbon::now()->addDays(5)->setTime(14, 0, 0); @@ -114,7 +116,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(625, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_price_for_2_days_and_3_hours() { $from = Carbon::now()->addDays(5)->setTime(9, 0, 0); @@ -128,7 +130,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(21250, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_price_with_quantity_for_fractional_days() { $from = Carbon::now()->addDays(5)->setTime(10, 0, 0); @@ -142,7 +144,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(15000, $cartItem->subtotal); // total for 3 units } - /** @test */ + #[Test] public function it_recalculates_price_when_dates_are_updated() { $from = Carbon::now()->addDays(5)->setTime(9, 0, 0); @@ -162,7 +164,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(7500, $cartItem->fresh()->subtotal); } - /** @test */ + #[Test] public function it_calculates_price_for_45_minutes() { $from = Carbon::now()->addDays(5)->setTime(14, 0, 0); @@ -175,7 +177,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(313, round($cartItem->price, 2)); // Rounded due to decimal precision } - /** @test */ + #[Test] public function it_purchases_booking_with_per_minute_pricing() { $from = Carbon::now()->addDays(5)->setTime(14, 0, 0); @@ -197,7 +199,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(8, $this->bookingProduct->getAvailableStock()); } - /** @test */ + #[Test] public function it_updates_cart_item_from_date_recalculates_per_minute_price() { $from = Carbon::now()->addDays(5)->setTime(12, 0, 0); @@ -220,7 +222,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(12500, $cartItem->fresh()->price); } - /** @test */ + #[Test] public function it_updates_cart_item_until_date_recalculates_per_minute_price() { $from = Carbon::now()->addDays(5)->setTime(10, 0, 0); @@ -243,7 +245,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(7500, $cartItem->fresh()->price); } - /** @test */ + #[Test] public function it_calculates_price_for_weekend_booking_friday_to_monday() { // Friday 6pm to Monday 10am = 64 hours = 2.666... days @@ -258,7 +260,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals($expectedPrice, $cartItem->price); } - /** @test */ + #[Test] public function it_handles_multiple_bookings_with_different_durations() { $cart = \Blax\Shop\Models\Cart::factory()->create([ @@ -283,7 +285,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(7500, $cart->getTotal()); } - /** @test */ + #[Test] public function it_calculates_precise_price_for_irregular_time_spans() { // Test various odd time spans @@ -312,7 +314,7 @@ class BookingPerMinutePricingTest extends TestCase } } - /** @test */ + #[Test] public function it_handles_booking_removal_and_readdition() { $from = Carbon::now()->addDays(5)->setTime(10, 0, 0); @@ -339,7 +341,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(7500, $cartItem2->subtotal); } - /** @test */ + #[Test] public function it_calculates_price_for_half_hour_increments() { $testCases = [ @@ -366,7 +368,7 @@ class BookingPerMinutePricingTest extends TestCase } } - /** @test */ + #[Test] public function it_handles_exact_hour_boundaries() { // Test exact hour boundaries from 1-10 hours @@ -389,7 +391,7 @@ class BookingPerMinutePricingTest extends TestCase } } - /** @test */ + #[Test] public function it_maintains_price_consistency_across_cart_operations() { $from = Carbon::now()->addDays(5)->setTime(14, 0, 0); @@ -416,7 +418,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(5000, $cart->getTotal()); } - /** @test */ + #[Test] public function it_handles_very_long_booking_periods() { // 7 days = 168 hours @@ -430,7 +432,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals(70000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_price_for_7_hour_30_minute_booking() { $from = Carbon::now()->addDays(5)->setTime(9, 0, 0); @@ -442,7 +444,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals('3125', $cartItem->price); } - /** @test */ + #[Test] public function it_handles_booking_crossing_midnight() { // 11 PM to 3 AM = 4 hours @@ -455,7 +457,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertEquals('1667', $cartItem->price); } - /** @test */ + #[Test] public function it_validates_minimum_price_for_very_short_bookings() { // 2 minutes @@ -471,7 +473,7 @@ class BookingPerMinutePricingTest extends TestCase $this->assertLessThan(100, (float)$cartItem->price); } - /** @test */ + #[Test] public function it_handles_15_minute_interval_bookings() { $intervals = [15, 30, 45, 60, 75, 90, 105, 120]; @@ -494,4 +496,59 @@ class BookingPerMinutePricingTest extends TestCase $cartItem->delete(); } } + + #[Test] + public function it_does_only_adjust_price_for_booking_not_for_other_products() + { + // 2 minutes + $from = Carbon::now()->addDays(5)->setTime(10, 0, 0); + $until = Carbon::now()->addDays(6)->setTime(10, 2, 0); + + $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); + $cart = Cart::current(); + + $cart->setDates($from, $until); + + $cart->refresh(); + + // 2 minutes = 0.001389 days, $100 * 0.001389 = $0.1389, rounds to $0.14 + $this->assertEquals(10014, $cartItem->price); + + $single_product = Product::factory() + ->withStocks(5) + ->withPrices(1, 5000) // $50.00 + ->create([ + 'name' => 'Wine Bottle', + 'slug' => 'wine-bottle', + 'type' => ProductType::SIMPLE, + 'manage_stock' => true, + ]); + + $this->assertEquals(5, $single_product->getAvailableStock()); + $this->assertEquals(5000, $single_product->getCurrentPrice()); + + $this->assertEquals(1, $cart->items()->count()); + $this->assertEquals(10014, $cart->getTotal()); + + $cart->addToCart($single_product, 1); + + $this->assertEquals(2, $cart->items()->count()); + $this->assertEquals(15014, $cart->getTotal()); + + $cart->addToCart($single_product, 1); + + $this->assertEquals(2, $cart->items()->count()); + $this->assertEquals(20014, $cart->getTotal()); + + + $until = $until->copy()->addDays(10); + + $cart->setDates($from, $until); + + $cart->refresh(); + + $this->assertEquals(110014, $cartItem->fresh()->price); + $this->assertEquals(5000, $single_product->getCurrentPrice()); + $this->assertEquals(120014, $cart->getTotal()); + } } diff --git a/tests/Feature/BookingTimespanValidationTest.php b/tests/Feature/BookingTimespanValidationTest.php index a4b9503..585c826 100644 --- a/tests/Feature/BookingTimespanValidationTest.php +++ b/tests/Feature/BookingTimespanValidationTest.php @@ -5,7 +5,6 @@ namespace Blax\Shop\Tests\Feature; use Blax\Shop\Enums\ProductRelationType; use Blax\Shop\Enums\ProductType; use Blax\Shop\Exceptions\NotPurchasable; -use Blax\Shop\Models\Cart; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Services\CartService; @@ -13,6 +12,7 @@ use Workbench\App\Models\User; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class BookingTimespanValidationTest extends TestCase { @@ -47,7 +47,7 @@ class BookingTimespanValidationTest extends TestCase $this->cartService = new CartService(); } - /** @test */ + #[Test] public function it_rejects_booking_when_from_is_after_until() { $from = now()->addDays(5); @@ -64,7 +64,7 @@ class BookingTimespanValidationTest extends TestCase ); } - /** @test */ + #[Test] public function it_rejects_booking_when_from_equals_until() { $from = now()->addDays(3); @@ -81,7 +81,7 @@ class BookingTimespanValidationTest extends TestCase ); } - /** @test */ + #[Test] public function it_rejects_booking_when_from_is_in_the_past() { $from = now()->subDays(2); @@ -98,7 +98,7 @@ class BookingTimespanValidationTest extends TestCase ); } - /** @test */ + #[Test] public function it_accepts_booking_when_from_is_exactly_now() { $from = now()->addSeconds(1); // Very slightly in the future to avoid timing issues @@ -113,7 +113,7 @@ class BookingTimespanValidationTest extends TestCase $this->assertNotNull($cartItem->until); } - /** @test */ + #[Test] public function it_validates_timespan_availability_across_date_range() { // Create a pool product with 1 single item @@ -169,7 +169,7 @@ class BookingTimespanValidationTest extends TestCase ); } - /** @test */ + #[Test] public function it_allows_back_to_back_bookings_without_overlap() { // Create a pool product with 2 single items so both bookings can succeed @@ -245,7 +245,7 @@ class BookingTimespanValidationTest extends TestCase $this->assertCount(1, $newUser->currentCart()->items); } - /** @test */ + #[Test] public function it_detects_overlap_when_new_booking_ends_during_existing_booking() { // Book days 5-10 @@ -276,7 +276,7 @@ class BookingTimespanValidationTest extends TestCase ); } - /** @test */ + #[Test] public function it_detects_overlap_when_new_booking_starts_during_existing_booking() { // Book days 5-10 @@ -307,7 +307,7 @@ class BookingTimespanValidationTest extends TestCase ); } - /** @test */ + #[Test] public function it_detects_overlap_when_new_booking_completely_contains_existing_booking() { // Book days 6-8 @@ -338,7 +338,7 @@ class BookingTimespanValidationTest extends TestCase ); } - /** @test */ + #[Test] public function it_detects_overlap_when_new_booking_is_completely_contained_by_existing_booking() { // Book days 5-10 @@ -369,7 +369,7 @@ class BookingTimespanValidationTest extends TestCase ); } - /** @test */ + #[Test] public function it_handles_timezone_aware_timespan_validation() { Carbon::setTestNow(now('America/New_York')); @@ -388,7 +388,7 @@ class BookingTimespanValidationTest extends TestCase $this->assertTrue($cartItem->from->lessThan($cartItem->until)); } - /** @test */ + #[Test] public function it_allows_same_product_multiple_non_overlapping_timespans() { // Create pool with 2 single items diff --git a/tests/Feature/CartAddToCartPoolPricingTest.php b/tests/Feature/CartAddToCartPoolPricingTest.php index cc57538..c7bd117 100644 --- a/tests/Feature/CartAddToCartPoolPricingTest.php +++ b/tests/Feature/CartAddToCartPoolPricingTest.php @@ -12,6 +12,7 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class CartAddToCartPoolPricingTest extends TestCase { @@ -62,7 +63,7 @@ class CartAddToCartPoolPricingTest extends TestCase ]); } - /** @test */ + #[Test] public function it_adds_pool_with_direct_price_to_cart_without_dates() { // Set direct price on pool @@ -85,7 +86,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertNull($cartItem->until); } - /** @test */ + #[Test] public function it_adds_pool_with_inherited_price_to_cart_without_dates() { // Set prices on single items (20€ and 50€) @@ -118,7 +119,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(3500, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_adds_pool_with_direct_price_to_cart_with_booking_dates() { // Set direct price on pool @@ -145,7 +146,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $cartItem->until->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_adds_pool_with_inherited_price_to_cart_with_booking_dates() { // Set prices on single items (20€ and 50€) @@ -184,7 +185,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $cartItem->until->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_calculates_price_for_multiple_pool_items_with_booking_dates() { // Set direct price on pool @@ -213,7 +214,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(25000, $this->cart->fresh()->getTotal()); // 125.00 × 2 units = 250.00 } - /** @test */ + #[Test] public function it_uses_lowest_pricing_strategy_with_mixed_single_item_prices() { // Set prices on single items (20€ and 50€) @@ -242,7 +243,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(2000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_uses_highest_pricing_strategy_with_mixed_single_item_prices() { // Set prices on single items (20€ and 50€) @@ -271,7 +272,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(5000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_uses_lowest_pricing_strategy_with_booking_dates() { // Set prices on single items (20€ and 50€) @@ -303,7 +304,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(6000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_adds_regular_product_to_cart_without_dates() { $regularProduct = Product::factory()->create([ @@ -330,7 +331,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertNull($cartItem->until); } - /** @test */ + #[Test] public function it_creates_separate_items_when_adding_same_pool_product_with_same_dates() { ProductPrice::factory()->create([ @@ -360,7 +361,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(12000, $this->cart->fresh()->getTotal()); // 6000 × 2 = 12000 } - /** @test */ + #[Test] public function it_creates_separate_cart_items_for_same_pool_with_different_dates() { ProductPrice::factory()->create([ @@ -386,7 +387,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(2, $this->cart->items()->count()); } - /** @test */ + #[Test] public function it_calculates_correct_total_for_cart_with_multiple_pool_items() { ProductPrice::factory()->create([ @@ -409,7 +410,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(15000, $total); } - /** @test */ + #[Test] public function it_handles_pool_with_sale_price() { ProductPrice::factory()->create([ @@ -436,7 +437,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(10000, $cartItem->regular_price); // 50.00 × 2 days (regular price) } - /** @test */ + #[Test] public function it_handles_pool_with_inherited_sale_price() { ProductPrice::factory()->create([ @@ -482,7 +483,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(6000, $cartItem->regular_price); } - /** @test */ + #[Test] public function it_handles_zero_days_as_one_day_minimum() { ProductPrice::factory()->create([ @@ -503,7 +504,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals('5.00', $cartItem->price); } - /** @test */ + #[Test] public function it_throws_exception_when_adding_pool_without_any_pricing() { // Pool with no direct price and single items with no prices @@ -528,7 +529,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($pool, 1); } - /** @test */ + #[Test] public function it_throws_exception_when_pool_not_available_for_booking_period() { ProductPrice::factory()->create([ @@ -552,7 +553,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($this->poolProduct, 1, [], $from, $until); } - /** @test */ + #[Test] public function it_throws_exception_when_booking_product_not_available_for_period() { $bookingProduct = Product::factory()->create([ @@ -582,7 +583,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($bookingProduct, 1, [], $from, $until); } - /** @test */ + #[Test] public function it_throws_exception_when_only_from_date_provided() { ProductPrice::factory()->create([ @@ -600,7 +601,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($this->poolProduct, 1, [], $from, null); } - /** @test */ + #[Test] public function it_throws_exception_when_only_until_date_provided() { ProductPrice::factory()->create([ @@ -618,7 +619,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($this->poolProduct, 1, [], null, $until); } - /** @test */ + #[Test] public function it_throws_exception_when_from_is_after_until() { ProductPrice::factory()->create([ @@ -637,7 +638,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($this->poolProduct, 1, [], $from, $until); } - /** @test */ + #[Test] public function it_throws_exception_when_from_equals_until() { ProductPrice::factory()->create([ @@ -655,7 +656,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($this->poolProduct, 1, [], $date, $date); } - /** @test */ + #[Test] public function it_creates_separate_items_for_same_product_same_dates_different_parameters() { ProductPrice::factory()->create([ @@ -678,7 +679,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(['zone' => 'B'], $cartItem2->parameters); } - /** @test */ + #[Test] public function it_throws_exception_when_pool_quantity_exceeds_available_items() { ProductPrice::factory()->create([ @@ -698,7 +699,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($this->poolProduct, 3, [], $from, $until); } - /** @test */ + #[Test] public function it_handles_partial_pool_availability() { ProductPrice::factory()->create([ @@ -724,7 +725,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($this->poolProduct, 2, [], $from, $until); } - /** @test */ + #[Test] public function it_throws_exception_for_regular_product_without_price() { $regularProduct = Product::factory()->create([ @@ -738,7 +739,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($regularProduct, 1); } - /** @test */ + #[Test] public function it_allows_adding_booking_product_without_dates() { $bookingProduct = Product::factory()->create([ @@ -766,7 +767,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(5000, $cartItem->price); // 1 day default } - /** @test */ + #[Test] public function it_allows_adding_pool_product_without_dates() { ProductPrice::factory()->create([ @@ -787,7 +788,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(3000, $cartItem->price); // 1 day default } - /** @test */ + #[Test] public function it_allows_updating_cart_item_dates_later() { ProductPrice::factory()->create([ @@ -820,7 +821,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(6000, $cartItem->price); } - /** @test */ + #[Test] public function it_limits_pool_in_cart_quantity_by_single_products() { // Set price on pool @@ -857,7 +858,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->cart->addToCart($this->poolProduct, 1, [], $from, $until); } - /** @test */ + #[Test] public function it_counts_single_item_stock_quantities_in_pool_availability() { // Create a pool with multiple single items having different stock quantities @@ -929,7 +930,7 @@ class CartAddToCartPoolPricingTest extends TestCase $cart->addToCart($pool, 1, [], $from, $until); } - /** @test */ + #[Test] public function it_counts_available_stock_with_booking_dates() { // Create pool with single items having stock @@ -983,7 +984,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(5, $cart->fresh()->items->sum('quantity')); } - /** @test */ + #[Test] public function it_allows_unlimited_pool_when_single_items_dont_manage_stock() { // Create pool with single items that don't manage stock @@ -1037,7 +1038,7 @@ class CartAddToCartPoolPricingTest extends TestCase $this->assertEquals(500, $cartItem2->quantity); } - /** @test */ + #[Test] public function it_picks_correct_price_for_pool_and_items_and_respects_stocks() { $this->actingAs($this->user); @@ -1182,7 +1183,7 @@ class CartAddToCartPoolPricingTest extends TestCase ); } - /** @test */ + #[Test] public function it_picks_correct_price_respects_stocks_respects_timespan_for_price() { $this->actingAs($this->user); diff --git a/tests/Feature/CartCheckoutSessionTest.php b/tests/Feature/CartCheckoutSessionTest.php index 811f3b5..e114908 100644 --- a/tests/Feature/CartCheckoutSessionTest.php +++ b/tests/Feature/CartCheckoutSessionTest.php @@ -9,6 +9,7 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class CartCheckoutSessionTest extends TestCase { @@ -28,7 +29,7 @@ class CartCheckoutSessionTest extends TestCase ]); } - /** @test */ + #[Test] public function it_throws_exception_when_stripe_is_disabled() { config(['shop.stripe.enabled' => false]); @@ -50,7 +51,7 @@ class CartCheckoutSessionTest extends TestCase $this->cart->checkoutSession(); } - /** @test */ + #[Test] public function it_builds_checkout_session_with_simple_product_without_stripe_api() { // Enable Stripe but don't actually call the API @@ -87,7 +88,7 @@ class CartCheckoutSessionTest extends TestCase $this->assertEquals('mock_session_id', $session->id); } - /** @test */ + #[Test] public function it_uses_short_description_for_product_name_if_available() { config(['shop.stripe.enabled' => true]); @@ -127,7 +128,7 @@ class CartCheckoutSessionTest extends TestCase $this->assertEquals('Short Name', $sessionParams['line_items'][0]['price_data']['product_data']['name']); } - /** @test */ + #[Test] public function it_includes_booking_dates_in_product_name() { config(['shop.stripe.enabled' => true]); @@ -174,7 +175,7 @@ class CartCheckoutSessionTest extends TestCase $this->assertStringContainsString('to', $productName); } - /** @test */ + #[Test] public function it_calculates_correct_unit_amount_in_cents() { config(['shop.stripe.enabled' => true]); @@ -210,7 +211,7 @@ class CartCheckoutSessionTest extends TestCase $this->assertEquals(2550, $sessionParams['line_items'][0]['price_data']['unit_amount']); } - /** @test */ + #[Test] public function it_handles_booking_with_fractional_days() { config(['shop.stripe.enabled' => true]); @@ -258,7 +259,7 @@ class CartCheckoutSessionTest extends TestCase $this->assertEquals($cartItem->price, $sessionParams['line_items'][0]['price_data']['unit_amount']); } - /** @test */ + #[Test] public function it_creates_separate_line_items_for_multiple_products() { config(['shop.stripe.enabled' => true]); @@ -305,7 +306,7 @@ class CartCheckoutSessionTest extends TestCase $this->assertEquals(1, $sessionParams['line_items'][1]['quantity']); } - /** @test */ + #[Test] public function it_uses_configured_currency() { config(['shop.stripe.enabled' => true]); @@ -341,7 +342,7 @@ class CartCheckoutSessionTest extends TestCase $this->assertEquals('eur', $sessionParams['line_items'][0]['price_data']['currency']); } - /** @test */ + #[Test] public function it_stores_session_id_in_cart_meta() { config(['shop.stripe.enabled' => true]); diff --git a/tests/Feature/CartDateManagementTest.php b/tests/Feature/CartDateManagementTest.php index d605de9..1ba450e 100644 --- a/tests/Feature/CartDateManagementTest.php +++ b/tests/Feature/CartDateManagementTest.php @@ -3,7 +3,6 @@ namespace Blax\Shop\Tests\Feature; use Blax\Shop\Exceptions\InvalidDateRangeException; -use Blax\Shop\Exceptions\NotEnoughAvailableInTimespanException; use Blax\Shop\Models\Cart; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; @@ -11,10 +10,11 @@ use Blax\Shop\Enums\ProductType; use Blax\Shop\Enums\PriceType; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; +use PHPUnit\Framework\Attributes\Test; class CartDateManagementTest extends TestCase { - /** @test */ + #[Test] public function it_can_set_cart_dates() { $cart = Cart::factory()->create(); @@ -28,7 +28,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($until->toDateTimeString(), $cart->until->toDateTimeString()); } - /** @test */ + #[Test] public function it_stores_dates_as_provided_even_if_backwards() { $cart = Cart::factory()->create(); @@ -44,7 +44,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($until->toDateTimeString(), $cart->until->toDateTimeString()); } - /** @test */ + #[Test] public function it_can_set_from_date_individually() { $cart = Cart::factory()->create(); @@ -56,7 +56,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($from->toDateTimeString(), $cart->from->toDateTimeString()); } - /** @test */ + #[Test] public function it_can_set_until_date_individually() { $cart = Cart::factory()->create(); @@ -68,7 +68,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($until->toDateTimeString(), $cart->until->toDateTimeString()); } - /** @test */ + #[Test] public function it_stores_from_date_even_if_after_existing_until_date() { $until = Carbon::now()->addDays(2); @@ -85,7 +85,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($until->toDateTimeString(), $cart->until->toDateTimeString()); } - /** @test */ + #[Test] public function it_stores_until_date_even_if_before_existing_from_date() { $from = Carbon::now()->addDays(3); @@ -102,7 +102,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($until->toDateTimeString(), $cart->until->toDateTimeString()); } - /** @test */ + #[Test] public function cart_item_uses_own_dates_when_set() { $product = Product::factory()->create([ @@ -133,7 +133,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($itemUntilDate->toDateString(), $item->getEffectiveUntilDate()->toDateString()); } - /** @test */ + #[Test] public function cart_item_falls_back_to_cart_dates_when_no_own_dates() { $product = Product::factory()->create([ @@ -163,7 +163,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($cartUntilDate->toDateString(), $item->getEffectiveUntilDate()->toDateString()); } - /** @test */ + #[Test] public function cart_item_returns_null_when_no_dates_available() { $product = Product::factory()->create([ @@ -187,7 +187,7 @@ class CartDateManagementTest extends TestCase $this->assertFalse($item->hasEffectiveDates()); } - /** @test */ + #[Test] public function cart_item_has_effective_dates_returns_true_when_dates_are_set() { $product = Product::factory()->create([ @@ -213,7 +213,7 @@ class CartDateManagementTest extends TestCase $this->assertTrue($item->hasEffectiveDates()); } - /** @test */ + #[Test] public function apply_dates_to_items_sets_dates_on_items_without_dates() { $product = Product::factory()->create([ @@ -248,7 +248,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($untilDate->toDateString(), $item->until->toDateString()); } - /** @test */ + #[Test] public function apply_dates_to_items_does_not_override_existing_item_dates() { $product = Product::factory()->create([ @@ -283,7 +283,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($itemUntilDate->toDateString(), $item->until->toDateString()); } - /** @test */ + #[Test] public function apply_dates_to_items_overwrites_when_overwrite_is_true() { $product = Product::factory()->create([ @@ -318,7 +318,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($cartUntilDate->toDateString(), $item->until->toDateString()); } - /** @test */ + #[Test] public function apply_dates_to_items_fills_only_null_from_date_when_overwrite_false() { $product = Product::factory()->create([ @@ -354,7 +354,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($itemUntilDate->toDateString(), $item->until->toDateString()); } - /** @test */ + #[Test] public function apply_dates_to_items_fills_only_null_until_date_when_overwrite_false() { $product = Product::factory()->create([ @@ -390,7 +390,7 @@ class CartDateManagementTest extends TestCase $this->assertEquals($cartUntilDate->toDateString(), $item->until->toDateString()); } - /** @test */ + #[Test] public function is_ready_to_checkout_uses_cart_fallback_dates() { $product = Product::factory()->create([ @@ -417,7 +417,7 @@ class CartDateManagementTest extends TestCase $this->assertTrue($item->is_ready_to_checkout); } - /** @test */ + #[Test] public function cart_item_set_from_date_throws_invalid_date_range_exception() { $product = Product::factory()->create([ @@ -442,7 +442,7 @@ class CartDateManagementTest extends TestCase $item->setFromDate(Carbon::now()->addDays(3)); } - /** @test */ + #[Test] public function cart_item_set_until_date_throws_invalid_date_range_exception() { $product = Product::factory()->create([ @@ -467,7 +467,7 @@ class CartDateManagementTest extends TestCase $item->setUntilDate(Carbon::now()->addDays(2)); } - /** @test */ + #[Test] public function validate_date_availability_marks_items_unavailable_when_product_not_available() { $product = Product::factory()->create([ @@ -499,7 +499,7 @@ class CartDateManagementTest extends TestCase $this->assertFalse($item->is_ready_to_checkout, 'Unavailable item should not be ready for checkout'); } - /** @test */ + #[Test] public function apply_dates_to_items_marks_items_unavailable_when_product_not_available() { $product = Product::factory()->create([ @@ -538,7 +538,7 @@ class CartDateManagementTest extends TestCase $this->assertFalse($item->is_ready_to_checkout, 'Unavailable item should not be ready for checkout'); } - /** @test */ + #[Test] public function can_skip_validation_when_setting_dates() { $product = Product::factory()->create([ diff --git a/tests/Feature/CartDateStringParsingTest.php b/tests/Feature/CartDateStringParsingTest.php index a1a6c6b..bb1b993 100644 --- a/tests/Feature/CartDateStringParsingTest.php +++ b/tests/Feature/CartDateStringParsingTest.php @@ -3,13 +3,13 @@ namespace Blax\Shop\Tests\Feature; use Blax\Shop\Models\Cart; -use Blax\Shop\Models\CartItem; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Enums\ProductType; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class CartDateStringParsingTest extends TestCase { @@ -46,7 +46,7 @@ class CartDateStringParsingTest extends TestCase ]); } - /** @test */ + #[Test] public function cart_set_dates_accepts_string_dates() { $cart = $this->cart->setDates('2025-12-20', '2025-12-25', false); @@ -57,7 +57,7 @@ class CartDateStringParsingTest extends TestCase $this->assertEquals('2025-12-25', $cart->until->format('Y-m-d')); } - /** @test */ + #[Test] public function cart_set_dates_accepts_datetime_objects() { $from = Carbon::parse('2025-12-20'); @@ -69,7 +69,7 @@ class CartDateStringParsingTest extends TestCase $this->assertEquals('2025-12-25', $cart->until->format('Y-m-d')); } - /** @test */ + #[Test] public function cart_set_from_date_accepts_string() { $cart = $this->cart->setFromDate('2025-12-20', false); @@ -78,7 +78,7 @@ class CartDateStringParsingTest extends TestCase $this->assertEquals('2025-12-20', $cart->from->format('Y-m-d')); } - /** @test */ + #[Test] public function cart_set_until_date_accepts_string() { $this->cart->update(['from' => Carbon::parse('2025-12-20')]); @@ -88,7 +88,7 @@ class CartDateStringParsingTest extends TestCase $this->assertEquals('2025-12-25', $cart->until->format('Y-m-d')); } - /** @test */ + #[Test] public function cart_set_dates_parses_various_string_formats() { // Test different date string formats that Carbon can parse @@ -112,7 +112,7 @@ class CartDateStringParsingTest extends TestCase } } - /** @test */ + #[Test] public function cart_item_set_from_date_accepts_string() { $cartItem = $this->cart->addToCart( @@ -128,7 +128,7 @@ class CartDateStringParsingTest extends TestCase $this->assertEquals('2025-12-21', $cartItem->from->format('Y-m-d')); } - /** @test */ + #[Test] public function cart_item_set_until_date_accepts_string() { $cartItem = $this->cart->addToCart( @@ -144,7 +144,7 @@ class CartDateStringParsingTest extends TestCase $this->assertEquals('2025-12-26', $cartItem->until->format('Y-m-d')); } - /** @test */ + #[Test] public function cart_item_update_dates_accepts_string_dates() { $cartItem = $this->cart->addToCart( @@ -165,7 +165,7 @@ class CartDateStringParsingTest extends TestCase $this->assertEquals($expectedPrice, $cartItem->price); } - /** @test */ + #[Test] public function cart_item_update_dates_accepts_mixed_string_and_datetime() { $cartItem = $this->cart->addToCart( @@ -183,7 +183,7 @@ class CartDateStringParsingTest extends TestCase $this->assertEquals('2025-12-27', $cartItem->until->format('Y-m-d')); } - /** @test */ + #[Test] public function cart_item_date_parsing_works_with_now_relative_strings() { $cartItem = $this->cart->addToCart( diff --git a/tests/Feature/CartFacadeTest.php b/tests/Feature/CartFacadeTest.php index fe51312..d0589f5 100644 --- a/tests/Feature/CartFacadeTest.php +++ b/tests/Feature/CartFacadeTest.php @@ -9,6 +9,7 @@ use Blax\Shop\Models\CartItem; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class CartFacadeTest extends TestCase { @@ -20,7 +21,7 @@ class CartFacadeTest extends TestCase $this->actingAs(User::factory()->create()); } - /** @test */ + #[Test] public function it_can_get_current_cart() { $cart = Cart::current(); @@ -28,7 +29,7 @@ class CartFacadeTest extends TestCase $this->assertInstanceOf(CartModel::class, $cart); } - /** @test */ + #[Test] public function it_can_get_cart_for_specific_user() { $user = User::factory()->create(); @@ -39,7 +40,7 @@ class CartFacadeTest extends TestCase $this->assertEquals($user->id, $cart->customer_id); } - /** @test */ + #[Test] public function it_can_find_cart_by_id() { $user = User::factory()->create(); @@ -51,7 +52,7 @@ class CartFacadeTest extends TestCase $this->assertEquals($cart->id, $foundCart->id); } - /** @test */ + #[Test] public function it_returns_null_for_nonexistent_cart() { $cart = Cart::find('nonexistent-id'); @@ -59,7 +60,7 @@ class CartFacadeTest extends TestCase $this->assertNull($cart); } - /** @test */ + #[Test] public function it_can_add_item_to_cart() { $product = Product::factory()->withStocks(50)->withPrices()->create(); @@ -71,7 +72,7 @@ class CartFacadeTest extends TestCase $this->assertCount(1, Cart::current()->items); } - /** @test */ + #[Test] public function it_can_add_item_with_parameters() { $product = Product::factory()->withStocks(50)->withPrices()->create(); @@ -86,7 +87,7 @@ class CartFacadeTest extends TestCase $this->assertEquals('blue', $cartItem->parameters['color']); } - /** @test */ + #[Test] public function it_can_remove_item_from_cart() { $product = Product::factory()->withStocks(50)->withPrices()->create(); @@ -98,7 +99,7 @@ class CartFacadeTest extends TestCase $this->assertEquals(2, $cartItem->quantity); } - /** @test */ + #[Test] public function it_can_completely_remove_item_from_cart() { $product = Product::factory()->withStocks(50)->withPrices()->create(); @@ -109,7 +110,7 @@ class CartFacadeTest extends TestCase $this->assertCount(0, Cart::current()->items); } - /** @test */ + #[Test] public function it_can_update_cart_item_quantity() { $product = Product::factory()->withStocks(50)->withPrices(1, 100)->create(); @@ -120,7 +121,7 @@ class CartFacadeTest extends TestCase $this->assertEquals(5, $updated->quantity); } - /** @test */ + #[Test] public function it_can_clear_cart() { $product1 = Product::factory()->withStocks(50)->withPrices()->create(); @@ -134,7 +135,7 @@ class CartFacadeTest extends TestCase $this->assertCount(0, Cart::current()->items); } - /** @test */ + #[Test] public function it_can_checkout_cart() { $product = Product::factory()->withStocks(50)->withPrices(1, 100)->create(); @@ -145,7 +146,7 @@ class CartFacadeTest extends TestCase $this->assertNotEmpty($purchases); } - /** @test */ + #[Test] public function it_can_get_cart_total() { $product1 = Product::factory()->withStocks(50)->withPrices(1, 100)->create(); @@ -158,7 +159,7 @@ class CartFacadeTest extends TestCase $this->assertEquals(200.00, $total); } - /** @test */ + #[Test] public function it_can_get_cart_item_count() { $product1 = Product::factory()->withStocks(50)->withPrices()->create(); @@ -171,7 +172,7 @@ class CartFacadeTest extends TestCase $this->assertEquals(5, $count); } - /** @test */ + #[Test] public function it_can_get_cart_items() { $product1 = Product::factory()->withStocks(50)->withPrices()->create(); @@ -184,7 +185,7 @@ class CartFacadeTest extends TestCase $this->assertCount(2, $items); } - /** @test */ + #[Test] public function it_can_check_if_cart_is_empty() { $this->assertTrue(Cart::isEmpty()); @@ -195,7 +196,7 @@ class CartFacadeTest extends TestCase $this->assertFalse(Cart::isEmpty()); } - /** @test */ + #[Test] public function it_can_check_if_cart_is_expired() { $cart = Cart::current(); @@ -204,13 +205,13 @@ class CartFacadeTest extends TestCase $this->assertFalse($cart->isExpired()); } - /** @test */ + #[Test] public function it_can_check_if_cart_is_converted() { $this->assertFalse(Cart::isConverted()); } - /** @test */ + #[Test] public function it_can_get_unpaid_amount() { $product = Product::factory()->withStocks(50)->withPrices(1, 100)->create(); @@ -221,7 +222,7 @@ class CartFacadeTest extends TestCase $this->assertEquals(200.00, $unpaid); } - /** @test */ + #[Test] public function it_can_get_paid_amount() { $product = Product::factory()->withStocks(50)->withPrices(1, 100)->create(); @@ -232,21 +233,21 @@ class CartFacadeTest extends TestCase $this->assertEquals(0.00, $paid); } - /** @test */ + #[Test] public function it_throws_exception_when_trying_to_add_without_user() { // Skip this test - logging out is complex in tests $this->assertTrue(true); } - /** @test */ + #[Test] public function it_throws_exception_when_trying_to_remove_without_user() { // Skip this test - logging out is complex in tests $this->assertTrue(true); } - /** @test */ + #[Test] public function it_can_add_multiple_quantities_of_same_product() { $product = Product::factory()->withStocks(50)->withPrices()->create(); @@ -258,7 +259,7 @@ class CartFacadeTest extends TestCase $this->assertEquals(5, $items[0]->quantity); } - /** @test */ + #[Test] public function it_can_add_same_product_with_different_parameters() { $product = Product::factory()->withStocks(50)->withPrices()->create(); @@ -269,7 +270,7 @@ class CartFacadeTest extends TestCase $this->assertCount(2, $items); } - /** @test */ + #[Test] public function it_maintains_separate_carts_for_different_users() { // Verify separate carts exist for different users @@ -280,7 +281,7 @@ class CartFacadeTest extends TestCase $this->assertEquals(1, $count1); } - /** @test */ + #[Test] public function it_can_get_total_with_multiple_items() { $p1 = Product::factory()->withStocks(50)->withPrices(1, 50)->create(); @@ -294,7 +295,7 @@ class CartFacadeTest extends TestCase $this->assertEquals(275.00, Cart::total()); } - /** @test */ + #[Test] public function it_updates_total_after_removing_items() { $product = Product::factory()->withStocks(50)->withPrices(1, 100)->create(); diff --git a/tests/Feature/CartItemAttributesTest.php b/tests/Feature/CartItemAttributesTest.php index 1242517..0a2a8bd 100644 --- a/tests/Feature/CartItemAttributesTest.php +++ b/tests/Feature/CartItemAttributesTest.php @@ -10,13 +10,13 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; -use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class CartItemAttributesTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function cart_item_has_is_booking_attribute_for_booking_products() { $bookingProduct = Product::factory() @@ -29,7 +29,7 @@ class CartItemAttributesTest extends TestCase $this->assertTrue($cartItem->is_booking); } - /** @test */ + #[Test] public function cart_item_has_is_booking_false_for_regular_products() { $regularProduct = Product::factory() @@ -42,7 +42,7 @@ class CartItemAttributesTest extends TestCase $this->assertFalse($cartItem->is_booking); } - /** @test */ + #[Test] public function cart_item_is_booking_works_via_price_id() { $bookingProduct = Product::factory() @@ -60,7 +60,7 @@ class CartItemAttributesTest extends TestCase $this->assertTrue($reloadedItem->is_booking); } - /** @test */ + #[Test] public function cart_is_full_booking_is_true_when_all_items_are_bookings() { $booking1 = Product::factory() @@ -78,7 +78,7 @@ class CartItemAttributesTest extends TestCase $this->assertTrue($cart->is_full_booking); } - /** @test */ + #[Test] public function cart_is_full_booking_is_false_when_mixed_products() { $booking = Product::factory() @@ -96,7 +96,7 @@ class CartItemAttributesTest extends TestCase $this->assertFalse($cart->is_full_booking); } - /** @test */ + #[Test] public function cart_is_full_booking_is_false_when_empty() { $cart = Cart::create(); @@ -104,7 +104,7 @@ class CartItemAttributesTest extends TestCase $this->assertFalse($cart->is_full_booking); } - /** @test */ + #[Test] public function cart_booking_items_returns_correct_count() { $booking1 = Product::factory() @@ -127,7 +127,7 @@ class CartItemAttributesTest extends TestCase $this->assertEquals(2, $cart->bookingItems()); } - /** @test */ + #[Test] public function cart_booking_items_returns_zero_when_no_bookings() { $regular = Product::factory() @@ -140,7 +140,7 @@ class CartItemAttributesTest extends TestCase $this->assertEquals(0, $cart->bookingItems()); } - /** @test */ + #[Test] public function price_id_is_automatically_assigned_when_adding_product_to_cart() { $product = Product::factory() @@ -156,7 +156,7 @@ class CartItemAttributesTest extends TestCase $this->assertInstanceOf(ProductPrice::class, $cartItem->price()->first()); } - /** @test */ + #[Test] public function price_id_is_assigned_when_adding_product_price_to_cart() { $product = Product::factory()->create(); @@ -176,7 +176,7 @@ class CartItemAttributesTest extends TestCase $this->assertInstanceOf(ProductPrice::class, $cartItem->price()->first()); } - /** @test */ + #[Test] public function cart_stripe_price_ids_returns_array_of_stripe_price_ids() { $product1 = Product::factory()->create(); @@ -208,7 +208,7 @@ class CartItemAttributesTest extends TestCase $this->assertContains('price_456', $stripePriceIds); } - /** @test */ + #[Test] public function cart_stripe_price_ids_returns_nulls_for_items_without_stripe_price_id() { $product1 = Product::factory()->create(); @@ -240,7 +240,7 @@ class CartItemAttributesTest extends TestCase $this->assertNull($stripePriceIds[1]); } - /** @test */ + #[Test] public function cart_item_is_ready_to_checkout_is_true_for_regular_products() { $product = Product::factory() @@ -253,7 +253,7 @@ class CartItemAttributesTest extends TestCase $this->assertTrue($cartItem->is_ready_to_checkout); } - /** @test */ + #[Test] public function cart_item_is_ready_to_checkout_is_false_for_booking_without_dates() { $bookingProduct = Product::factory() @@ -266,7 +266,7 @@ class CartItemAttributesTest extends TestCase $this->assertFalse($cartItem->is_ready_to_checkout); } - /** @test */ + #[Test] public function cart_item_is_ready_to_checkout_is_true_for_booking_with_valid_dates() { $bookingProduct = Product::factory() @@ -283,7 +283,7 @@ class CartItemAttributesTest extends TestCase $this->assertTrue($cartItem->is_ready_to_checkout); } - /** @test */ + #[Test] public function cart_item_is_ready_to_checkout_is_false_for_booking_with_invalid_date_range() { $bookingProduct = Product::factory() @@ -303,7 +303,7 @@ class CartItemAttributesTest extends TestCase $this->assertFalse($cartItem->fresh()->is_ready_to_checkout); } - /** @test */ + #[Test] public function cart_is_ready_to_checkout_is_true_when_all_items_are_ready() { $product1 = Product::factory() @@ -321,7 +321,7 @@ class CartItemAttributesTest extends TestCase $this->assertTrue($cart->is_ready_to_checkout); } - /** @test */ + #[Test] public function cart_is_ready_to_checkout_is_false_when_at_least_one_item_not_ready() { $regularProduct = Product::factory() @@ -339,7 +339,7 @@ class CartItemAttributesTest extends TestCase $this->assertFalse($cart->is_ready_to_checkout); } - /** @test */ + #[Test] public function cart_allows_adding_items_without_dates_that_require_them() { $bookingProduct = Product::factory() @@ -358,7 +358,7 @@ class CartItemAttributesTest extends TestCase $this->assertFalse($cartItem->is_ready_to_checkout); } - /** @test */ + #[Test] public function update_dates_allows_setting_any_dates() { $bookingProduct = Product::factory() @@ -382,7 +382,7 @@ class CartItemAttributesTest extends TestCase $this->assertTrue($cartItem->fresh()->is_ready_to_checkout); } - /** @test */ + #[Test] public function cart_calculates_correctly_when_dates_are_adjusted() { $bookingProduct = Product::factory() @@ -409,7 +409,7 @@ class CartItemAttributesTest extends TestCase $this->assertEquals(500.00, $cartItem->fresh()->subtotal); } - /** @test */ + #[Test] public function set_from_date_recalculates_pricing_when_both_dates_set() { $bookingProduct = Product::factory() @@ -434,7 +434,7 @@ class CartItemAttributesTest extends TestCase $this->assertEquals(400.00, $cartItem->fresh()->price); } - /** @test */ + #[Test] public function set_until_date_recalculates_pricing_when_both_dates_set() { $bookingProduct = Product::factory() @@ -459,7 +459,7 @@ class CartItemAttributesTest extends TestCase $this->assertEquals(400.00, $cartItem->fresh()->price); } - /** @test */ + #[Test] public function is_ready_to_checkout_checks_stock_for_regular_products_with_stock_management() { $product = Product::factory() diff --git a/tests/Feature/CartItemAvailabilityValidationTest.php b/tests/Feature/CartItemAvailabilityValidationTest.php index 6a264ae..54d3aae 100644 --- a/tests/Feature/CartItemAvailabilityValidationTest.php +++ b/tests/Feature/CartItemAvailabilityValidationTest.php @@ -7,8 +7,8 @@ use Blax\Shop\Models\Cart; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; -use Carbon\Carbon; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; /** * Tests for cart item validation when dates change and items become unavailable. @@ -84,7 +84,7 @@ class CartItemAvailabilityValidationTest extends TestCase return $pool; } - /** @test */ + #[Test] public function cart_item_with_null_price_is_not_ready_for_checkout() { $pool = $this->createPoolWithLimitedSingles(3); @@ -105,7 +105,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->assertFalse($this->cart->fresh()->is_ready_to_checkout, 'Cart with null-price item should not be ready'); } - /** @test */ + #[Test] public function cart_item_with_zero_price_is_not_ready_for_checkout() { $pool = $this->createPoolWithLimitedSingles(3); @@ -126,7 +126,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->assertFalse($this->cart->fresh()->is_ready_to_checkout, 'Cart with 0-price item should not be ready'); } - /** @test */ + #[Test] public function unallocated_pool_item_with_null_price_is_not_ready_for_checkout() { $pool = $this->createPoolWithLimitedSingles(3); @@ -158,7 +158,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->assertFalse($this->cart->fresh()->is_ready_to_checkout, 'Cart with unavailable item should not be ready'); } - /** @test */ + #[Test] public function setDates_does_not_throw_when_items_become_unavailable() { $pool = $this->createPoolWithLimitedSingles(3); @@ -195,7 +195,7 @@ class CartItemAvailabilityValidationTest extends TestCase ); } - /** @test */ + #[Test] public function partial_availability_marks_some_items_unavailable() { $pool = $this->createPoolWithLimitedSingles(3); @@ -244,7 +244,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->assertFalse($this->cart->is_ready_to_checkout, 'Cart with unavailable items should not be ready'); } - /** @test */ + #[Test] public function cart_item_without_allocated_single_for_pool_is_not_ready() { $pool = $this->createPoolWithLimitedSingles(3); @@ -266,7 +266,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->assertTrue($this->cart->fresh()->is_ready_to_checkout); } - /** @test */ + #[Test] public function removing_unavailable_items_makes_cart_ready() { $pool = $this->createPoolWithLimitedSingles(3); @@ -293,7 +293,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->assertTrue($this->cart->fresh()->is_ready_to_checkout); } - /** @test */ + #[Test] public function getItemsRequiringAdjustments_includes_null_price_items() { $pool = $this->createPoolWithLimitedSingles(3); @@ -330,7 +330,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->assertEquals('unavailable', $adjustments['price']); } - /** @test */ + #[Test] public function changing_dates_to_available_period_makes_items_available_again() { $pool = $this->createPoolWithLimitedSingles(3); @@ -371,7 +371,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->assertTrue($this->cart->is_ready_to_checkout, 'Cart should be ready after changing to available dates'); } - /** @test */ + #[Test] public function checkout_throws_when_items_are_unavailable() { $pool = $this->createPoolWithLimitedSingles(3); @@ -388,7 +388,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->cart->checkout(); } - /** @test */ + #[Test] public function checkoutSessionLink_throws_when_items_have_null_price() { $pool = $this->createPoolWithLimitedSingles(3); @@ -408,7 +408,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->cart->checkoutSessionLink(); } - /** @test */ + #[Test] public function checkoutSessionLink_throws_when_items_have_zero_price() { $pool = $this->createPoolWithLimitedSingles(3); @@ -428,7 +428,7 @@ class CartItemAvailabilityValidationTest extends TestCase $this->cart->checkoutSessionLink(); } - /** @test */ + #[Test] public function pool_items_maintain_consistent_pricing_after_date_changes() { $pool = $this->createPoolWithLimitedSingles(3); @@ -460,7 +460,7 @@ class CartItemAvailabilityValidationTest extends TestCase ); } - /** @test */ + #[Test] public function price_zero_is_treated_as_unavailable() { $pool = $this->createPoolWithLimitedSingles(3); diff --git a/tests/Feature/CartItemDateManagementTest.php b/tests/Feature/CartItemDateManagementTest.php index 449cda9..9b93c9e 100644 --- a/tests/Feature/CartItemDateManagementTest.php +++ b/tests/Feature/CartItemDateManagementTest.php @@ -9,6 +9,7 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class CartItemDateManagementTest extends TestCase { @@ -26,7 +27,7 @@ class CartItemDateManagementTest extends TestCase ]); } - /** @test */ + #[Test] public function it_can_update_dates_on_cart_item() { $product = Product::factory()->create([ @@ -60,7 +61,7 @@ class CartItemDateManagementTest extends TestCase $this->assertEquals(15000, $updated->subtotal); // 150.00 × 1 quantity } - /** @test */ + #[Test] public function it_recalculates_price_when_updating_dates() { $product = Product::factory()->create([ @@ -94,7 +95,7 @@ class CartItemDateManagementTest extends TestCase $this->assertEquals(100000, $updated->subtotal); // 500 × 2 quantity } - /** @test */ + #[Test] public function it_can_set_from_date_individually() { $product = Product::factory()->create([ @@ -120,7 +121,7 @@ class CartItemDateManagementTest extends TestCase $this->assertNull($updated->until); } - /** @test */ + #[Test] public function it_can_set_until_date_individually() { $product = Product::factory()->create([ @@ -146,7 +147,7 @@ class CartItemDateManagementTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $updated->until->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_recalculates_when_both_dates_are_set() { $product = Product::factory()->create([ @@ -180,7 +181,7 @@ class CartItemDateManagementTest extends TestCase $this->assertEquals(32000, $updated->subtotal); } - /** @test */ + #[Test] public function it_throws_exception_when_from_is_after_until() { $product = Product::factory()->create([ @@ -207,7 +208,7 @@ class CartItemDateManagementTest extends TestCase $cartItem->updateDates($from, $until); } - /** @test */ + #[Test] public function it_validates_dates_at_checkout_for_booking_products() { $product = Product::factory()->create([ @@ -233,7 +234,7 @@ class CartItemDateManagementTest extends TestCase $this->cart->checkout(); } - /** @test */ + #[Test] public function it_allows_checkout_when_dates_are_set() { $product = Product::factory()->create([ diff --git a/tests/Feature/CartItemRequiredAdjustmentsTest.php b/tests/Feature/CartItemRequiredAdjustmentsTest.php index b36668b..a44d3d7 100644 --- a/tests/Feature/CartItemRequiredAdjustmentsTest.php +++ b/tests/Feature/CartItemRequiredAdjustmentsTest.php @@ -11,6 +11,7 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class CartItemRequiredAdjustmentsTest extends TestCase { @@ -28,7 +29,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase ]); } - /** @test */ + #[Test] public function it_returns_empty_array_for_simple_product() { $product = Product::factory()->create([ @@ -51,7 +52,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase $this->assertEmpty($adjustments); } - /** @test */ + #[Test] public function it_returns_from_and_until_for_booking_product_without_dates() { $product = Product::factory()->create([ @@ -78,7 +79,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase ], $adjustments); } - /** @test */ + #[Test] public function it_returns_only_until_for_booking_product_with_from_date() { $product = Product::factory()->create([ @@ -107,7 +108,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase ], $adjustments); } - /** @test */ + #[Test] public function it_returns_only_from_for_booking_product_with_until_date() { $product = Product::factory()->create([ @@ -136,7 +137,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase ], $adjustments); } - /** @test */ + #[Test] public function it_returns_empty_array_for_booking_product_with_both_dates() { $product = Product::factory()->create([ @@ -164,7 +165,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase $this->assertEmpty($adjustments); } - /** @test */ + #[Test] public function it_returns_dates_for_pool_with_booking_single_items_without_dates() { // Create pool product @@ -222,7 +223,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase ], $adjustments); } - /** @test */ + #[Test] public function it_returns_empty_array_for_pool_with_booking_items_with_dates() { // Create pool product @@ -263,7 +264,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase $this->assertEmpty($adjustments); } - /** @test */ + #[Test] public function it_returns_empty_array_for_pool_with_simple_single_items() { // Create pool product @@ -318,7 +319,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase $this->assertEmpty($adjustments); } - /** @test */ + #[Test] public function it_returns_dates_for_pool_with_mixed_single_items_containing_bookings() { // Create pool product @@ -378,7 +379,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase ], $adjustments); } - /** @test */ + #[Test] public function it_returns_empty_array_for_non_product_purchasable() { // Create a cart item with a non-product purchasable @@ -396,7 +397,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase $this->assertEmpty($adjustments); } - /** @test */ + #[Test] public function it_handles_null_purchasable_gracefully() { // Create a cart item with invalid purchasable_id @@ -414,7 +415,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase $this->assertEmpty($adjustments); } - /** @test */ + #[Test] public function it_can_validate_entire_cart_before_checkout() { // Create mixed cart with booking and simple products @@ -456,7 +457,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase $this->assertEquals($bookingProduct->id, $itemsNeedingAdjustments->first()->purchasable_id); } - /** @test */ + #[Test] public function cart_can_get_items_requiring_adjustments() { $simpleProduct = Product::factory()->create([ @@ -492,7 +493,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase $this->assertEquals($bookingProduct->id, $incompleteItems->first()->purchasable_id); } - /** @test */ + #[Test] public function cart_is_not_ready_for_checkout_when_items_need_adjustments() { $bookingProduct = Product::factory()->create([ @@ -512,7 +513,7 @@ class CartItemRequiredAdjustmentsTest extends TestCase $this->assertFalse($this->cart->isReadyForCheckout()); } - /** @test */ + #[Test] public function cart_is_ready_for_checkout_when_all_items_complete() { $simpleProduct = Product::factory()->create([ diff --git a/tests/Feature/CartManagementTest.php b/tests/Feature/CartManagementTest.php index d43f1ca..15f7481 100644 --- a/tests/Feature/CartManagementTest.php +++ b/tests/Feature/CartManagementTest.php @@ -5,16 +5,16 @@ namespace Blax\Shop\Tests\Feature; use Blax\Shop\Models\Cart; use Blax\Shop\Models\CartItem; use Blax\Shop\Models\Product; -use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class CartManagementTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_create_a_cart() { $user = User::factory()->create(); @@ -33,7 +33,7 @@ class CartManagementTest extends TestCase $this->assertNotNull($cart->id); } - /** @test */ + #[Test] public function it_automatically_generates_uuid() { $cart = Cart::create(); @@ -42,7 +42,7 @@ class CartManagementTest extends TestCase $this->assertIsString($cart->id); } - /** @test */ + #[Test] public function it_can_add_items_to_cart() { $product = Product::factory()->withPrices()->create(); @@ -56,7 +56,7 @@ class CartManagementTest extends TestCase $this->assertEquals(2, $cart->items->first()->quantity); } - /** @test */ + #[Test] public function it_can_update_cart_item_quantity() { $cart = Cart::create(); @@ -69,7 +69,7 @@ class CartManagementTest extends TestCase $this->assertEquals(3, $cartItem->fresh()->quantity); } - /** @test */ + #[Test] public function it_can_remove_items_from_cart() { $cart = Cart::create(); @@ -85,7 +85,7 @@ class CartManagementTest extends TestCase $this->assertCount(0, $cart->refresh()->items); } - /** @test */ + #[Test] public function it_calculates_cart_total_correctly() { $cart = Cart::create(); @@ -103,7 +103,7 @@ class CartManagementTest extends TestCase $this->assertEquals(130.00, $total); // (50 * 2) + (30 * 1) } - /** @test */ + #[Test] public function it_calculates_total_items_correctly() { $cart = Cart::create(); @@ -121,7 +121,7 @@ class CartManagementTest extends TestCase $this->assertEquals(5, $totalItems); // 3 + 2 } - /** @test */ + #[Test] public function it_can_check_if_cart_is_expired() { $expiredCart = Cart::create([ @@ -136,7 +136,7 @@ class CartManagementTest extends TestCase $this->assertFalse($activeCart->isExpired()); } - /** @test */ + #[Test] public function it_can_check_if_cart_is_converted() { $convertedCart = Cart::create([ @@ -151,7 +151,7 @@ class CartManagementTest extends TestCase $this->assertFalse($activeCart->isConverted()); } - /** @test */ + #[Test] public function it_can_scope_active_carts() { Cart::create([ @@ -174,7 +174,7 @@ class CartManagementTest extends TestCase $this->assertCount(1, $activeCarts); } - /** @test */ + #[Test] public function it_can_scope_carts_for_user() { $user = User::factory()->create(); @@ -189,7 +189,7 @@ class CartManagementTest extends TestCase $this->assertCount(2, $userCarts); } - /** @test */ + #[Test] public function it_belongs_to_a_user() { $user = User::factory()->create(); @@ -198,7 +198,7 @@ class CartManagementTest extends TestCase $this->assertEquals($user->id, $cart->user->id); } - /** @test */ + #[Test] public function cart_items_have_correct_relationships() { $cart = Cart::create(); @@ -211,7 +211,7 @@ class CartManagementTest extends TestCase $this->assertEquals($productPrice->id, $cartItem->purchasable_id); } - /** @test */ + #[Test] public function it_calculates_cart_item_subtotal() { $cart = Cart::create(); @@ -223,7 +223,7 @@ class CartManagementTest extends TestCase $this->assertEquals(100.00, $cartItem->getSubtotal()); // 25 * 4 } - /** @test */ + #[Test] public function it_can_store_cart_item_attributes() { $cart = Cart::create(); @@ -243,7 +243,7 @@ class CartManagementTest extends TestCase $this->assertEquals('large', $cartItem->parameters['size']); } - /** @test */ + #[Test] public function it_can_have_multiple_items_of_same_product_with_different_attributes() { $cart = Cart::create(); @@ -266,7 +266,7 @@ class CartManagementTest extends TestCase $this->assertEquals($productPrice->unit_amount * 3, $cart->getTotal()); } - /** @test */ + #[Test] public function it_deletes_cart_items_when_cart_is_deleted() { $cart = Cart::create(); @@ -285,7 +285,7 @@ class CartManagementTest extends TestCase $this->assertDatabaseMissing('cart_items', ['id' => $cartItemId]); } - /** @test */ + #[Test] public function it_calculats_unpaid_and_paid_and_can_scope() { $user = User::factory()->create(); @@ -304,7 +304,7 @@ class CartManagementTest extends TestCase $this->assertEquals($user->currentCart()->id, Cart::unpaid()->first()->id, 'Unpaid cart scope should return the current cart.'); } - /** @test */ + #[Test] public function it_can_create_cart_with_factory() { $cart = Cart::factory()->create(); @@ -336,7 +336,7 @@ class CartManagementTest extends TestCase $this->assertEquals((150.00 * 2) + (120 * 2), $cartWithProduct->getTotal()); } - /** @test */ + #[Test] public function it_can_remove_entire_cart_item() { $cart = Cart::create(); @@ -352,7 +352,7 @@ class CartManagementTest extends TestCase $this->assertTrue(true); // Item was deleted } - /** @test */ + #[Test] public function it_can_decrease_cart_item_quantity() { $cart = Cart::create(); @@ -369,7 +369,7 @@ class CartManagementTest extends TestCase $this->assertEquals(75.00 * 3, $updatedItem->subtotal); } - /** @test */ + #[Test] public function it_updates_subtotal_correctly_when_decreasing_quantity() { $cart = Cart::create(); @@ -385,7 +385,7 @@ class CartManagementTest extends TestCase $this->assertEquals(300.00, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_respects_parameters_when_removing_from_cart() { $cart = Cart::create(); @@ -415,7 +415,7 @@ class CartManagementTest extends TestCase $this->assertEquals(3, $cart->items->first()->quantity); } - /** @test */ + #[Test] public function it_decreases_only_matching_parameters_when_removing() { $cart = Cart::create(); @@ -435,7 +435,7 @@ class CartManagementTest extends TestCase $this->assertEquals('large', $cartItem->parameters['size']); } - /** @test */ + #[Test] public function it_returns_cart_item_when_quantity_is_decreased() { $cart = Cart::create(); @@ -450,7 +450,7 @@ class CartManagementTest extends TestCase $this->assertEquals(3, $result->quantity); } - /** @test */ + #[Test] public function it_handles_removing_nonexistent_item_gracefully() { $cart = Cart::create(); @@ -464,7 +464,7 @@ class CartManagementTest extends TestCase $this->assertCount(0, $cart->items); } - /** @test */ + #[Test] public function it_updates_cart_total_after_removing_items() { $cart = Cart::create(); @@ -479,7 +479,7 @@ class CartManagementTest extends TestCase $this->assertEquals(150.00, $cart->refresh()->getTotal()); } - /** @test */ + #[Test] public function it_can_remove_from_cart_with_multiple_items() { $cart = Cart::create(); diff --git a/tests/Feature/CartServiceBookingTest.php b/tests/Feature/CartServiceBookingTest.php index 60e89aa..2aeab1a 100644 --- a/tests/Feature/CartServiceBookingTest.php +++ b/tests/Feature/CartServiceBookingTest.php @@ -11,6 +11,7 @@ use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class CartServiceBookingTest extends TestCase { @@ -84,7 +85,7 @@ class CartServiceBookingTest extends TestCase ]); } - /** @test */ + #[Test] public function validate_bookings_returns_error_for_booking_product_without_timespan() { $cart = $this->user->currentCart(); @@ -104,7 +105,7 @@ class CartServiceBookingTest extends TestCase $this->assertStringContainsString('Hotel Room', $errors[0]); } - /** @test */ + #[Test] public function validate_bookings_returns_error_for_pool_product_without_timespan_when_single_items_are_bookings() { $cart = $this->user->currentCart(); @@ -124,7 +125,7 @@ class CartServiceBookingTest extends TestCase $this->assertStringContainsString('Parking Spaces', $errors[0]); } - /** @test */ + #[Test] public function validate_bookings_validates_stock_availability_correctly() { $cart = $this->user->currentCart(); @@ -150,7 +151,7 @@ class CartServiceBookingTest extends TestCase $this->assertStringContainsString('not available for the selected period', $errors[0]); } - /** @test */ + #[Test] public function validate_bookings_handles_pool_products_with_individual_timespans_in_meta() { $cart = $this->user->currentCart(); @@ -170,7 +171,7 @@ class CartServiceBookingTest extends TestCase $this->assertEmpty($errors); } - /** @test */ + #[Test] public function has_valid_bookings_returns_true_when_all_bookings_are_valid() { $cart = $this->user->currentCart(); @@ -189,7 +190,7 @@ class CartServiceBookingTest extends TestCase $this->assertTrue(Cart::hasValidBookings()); } - /** @test */ + #[Test] public function has_valid_bookings_returns_false_when_bookings_are_invalid() { $cart = $this->user->currentCart(); @@ -205,7 +206,7 @@ class CartServiceBookingTest extends TestCase $this->assertFalse(Cart::hasValidBookings()); } - /** @test */ + #[Test] public function add_booking_successfully_adds_booking_product_with_timespan() { $from = Carbon::now()->addDays(1); @@ -220,7 +221,7 @@ class CartServiceBookingTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $cartItem->until->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function add_booking_successfully_adds_pool_product_with_timespan() { $from = Carbon::now()->addDays(1); @@ -235,7 +236,7 @@ class CartServiceBookingTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $cartItem->until->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function add_booking_calculates_price_correctly_based_on_days() { $from = Carbon::now()->addDays(1)->startOfDay(); @@ -253,7 +254,7 @@ class CartServiceBookingTest extends TestCase $this->assertEquals($expectedTotal, $cartItem->subtotal); } - /** @test */ + #[Test] public function add_booking_throws_exception_when_product_is_not_booking_or_pool_type() { $simpleProduct = Product::factory()->create([ @@ -277,7 +278,7 @@ class CartServiceBookingTest extends TestCase Cart::addBooking($simpleProduct, 1, $from, $until); } - /** @test */ + #[Test] public function add_booking_throws_exception_when_insufficient_stock_available_for_booking_period() { $from = Carbon::now()->addDays(1); @@ -292,7 +293,7 @@ class CartServiceBookingTest extends TestCase Cart::addBooking($this->bookingProduct, 5, $from, $until); } - /** @test */ + #[Test] public function add_booking_throws_exception_when_pool_quantity_exceeds_available_single_items() { $from = Carbon::now()->addDays(1); @@ -305,7 +306,7 @@ class CartServiceBookingTest extends TestCase Cart::addBooking($this->poolProduct, 5, $from, $until); } - /** @test */ + #[Test] public function add_booking_creates_cart_item_with_correct_from_until_timestamps() { $from = Carbon::now()->addDays(5)->setTime(14, 30, 0); @@ -317,7 +318,7 @@ class CartServiceBookingTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $cartItem->until->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function add_booking_stores_regular_price_correctly() { $from = Carbon::now()->addDays(1); @@ -329,7 +330,7 @@ class CartServiceBookingTest extends TestCase $this->assertEquals($this->bookingProduct->getCurrentPrice(), $cartItem->regular_price); } - /** @test */ + #[Test] public function validate_bookings_returns_error_when_pool_quantity_exceeds_available_single_items() { $cart = $this->user->currentCart(); @@ -354,7 +355,7 @@ class CartServiceBookingTest extends TestCase $this->assertStringContainsString('Parking Spaces', $errors[0]); } - /** @test */ + #[Test] public function validate_bookings_passes_with_valid_pool_product_and_timespan() { $cart = $this->user->currentCart(); @@ -375,7 +376,7 @@ class CartServiceBookingTest extends TestCase $this->assertEmpty($errors); } - /** @test */ + #[Test] public function validate_bookings_handles_multiple_booking_products_in_cart() { $cart = $this->user->currentCart(); @@ -407,7 +408,7 @@ class CartServiceBookingTest extends TestCase $this->assertEmpty($errors); } - /** @test */ + #[Test] public function add_booking_with_parameters_stores_them_correctly() { $from = Carbon::now()->addDays(1); diff --git a/tests/Feature/CheckoutStockValidationTest.php b/tests/Feature/CheckoutStockValidationTest.php index 2342d3a..f336802 100644 --- a/tests/Feature/CheckoutStockValidationTest.php +++ b/tests/Feature/CheckoutStockValidationTest.php @@ -3,15 +3,14 @@ namespace Blax\Shop\Tests\Feature; use Blax\Shop\Enums\ProductType; -use Blax\Shop\Enums\PurchaseStatus; use Blax\Shop\Exceptions\NotEnoughStockException; use Blax\Shop\Models\Cart; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; -use Blax\Shop\Models\ProductPurchase; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; /** * Test stock validation during checkout process. @@ -89,7 +88,7 @@ class CheckoutStockValidationTest extends TestCase ]); } - /** @test */ + #[Test] public function validate_for_checkout_checks_stock_availability() { $this->createPoolWithManagedStock(); @@ -113,7 +112,7 @@ class CheckoutStockValidationTest extends TestCase $this->assertFalse($this->cart->fresh()->validateForCheckout(false)); } - /** @test */ + #[Test] public function validate_for_checkout_fails_for_out_of_stock_items() { $this->createPoolWithManagedStock(); @@ -134,7 +133,7 @@ class CheckoutStockValidationTest extends TestCase $this->assertFalse($this->cart->validateForCheckout(false)); } - /** @test */ + #[Test] public function validate_for_checkout_fails_for_converted_cart() { $this->createPoolWithManagedStock(); @@ -152,7 +151,7 @@ class CheckoutStockValidationTest extends TestCase $this->assertFalse($this->cart->fresh()->validateForCheckout(false)); } - /** @test */ + #[Test] public function checkout_session_link_returns_null_for_converted_cart() { $this->createPoolWithManagedStock(); @@ -170,7 +169,7 @@ class CheckoutStockValidationTest extends TestCase $this->assertFalse($this->cart->fresh()->validateForCheckout(false)); } - /** @test */ + #[Test] public function checkout_session_link_returns_null_for_out_of_stock() { $this->createPoolWithManagedStock(); @@ -190,7 +189,7 @@ class CheckoutStockValidationTest extends TestCase $this->assertFalse($this->cart->fresh()->validateForCheckout(false)); } - /** @test */ + #[Test] public function different_date_ranges_allow_booking_same_items() { $this->createPoolWithManagedStock(); @@ -215,7 +214,7 @@ class CheckoutStockValidationTest extends TestCase $this->assertTrue($cart2->validateForCheckout(false)); } - /** @test */ + #[Test] public function overlapping_dates_block_double_booking() { $this->createPoolWithManagedStock(); @@ -245,7 +244,7 @@ class CheckoutStockValidationTest extends TestCase $cart2->addToCart($this->pool, 1, [], $from2, $until2); } - /** @test */ + #[Test] public function partial_stock_allows_partial_booking() { $this->createPoolWithManagedStock(); diff --git a/tests/Feature/CommandProductExamplesTest.php b/tests/Feature/CommandProductExamplesTest.php index 91265e2..56f28aa 100644 --- a/tests/Feature/CommandProductExamplesTest.php +++ b/tests/Feature/CommandProductExamplesTest.php @@ -3,17 +3,16 @@ namespace Blax\Shop\Tests\Feature; use Blax\Shop\Console\Commands\ShopAddExampleProducts; -use Blax\Shop\Models\Cart; use Blax\Shop\Models\Product; -use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class CommandProductExamplesTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_creates_example_products_and_related_data(): void { $this->artisan(ShopAddExampleProducts::class, ['--clean' => true, '--count' => 2]) @@ -42,7 +41,7 @@ class CommandProductExamplesTest extends TestCase $this->assertNotEmpty(Product::first()->getLocalized('name')); } - /** @test */ + #[Test] public function it_cleans_existing_examples_when_option_provided(): void { // Seed examples @@ -57,7 +56,7 @@ class CommandProductExamplesTest extends TestCase $this->assertEquals(6, \Blax\Shop\Models\ProductCategory::where('slug', 'like', 'example-%')->count()); } - /** @test */ + #[Test] public function it_honors_the_count_option_for_each_type(): void { $this->artisan(ShopAddExampleProducts::class, ['--clean' => true, '--count' => 3]) diff --git a/tests/Feature/GuestCartTest.php b/tests/Feature/GuestCartTest.php index c1c489d..2540542 100644 --- a/tests/Feature/GuestCartTest.php +++ b/tests/Feature/GuestCartTest.php @@ -8,12 +8,13 @@ use Blax\Shop\Models\Cart as CartModel; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class GuestCartTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_create_a_guest_cart() { $guestCart = Cart::guest(); @@ -24,7 +25,7 @@ class GuestCartTest extends TestCase $this->assertNull($guestCart->customer_type); } - /** @test */ + #[Test] public function it_can_create_a_guest_cart_with_specific_session_id() { $sessionId = 'test-session-123'; @@ -35,7 +36,7 @@ class GuestCartTest extends TestCase $this->assertNull($guestCart->customer_id); } - /** @test */ + #[Test] public function it_retrieves_same_guest_cart_for_same_session() { $sessionId = 'persistent-session-456'; @@ -55,7 +56,7 @@ class GuestCartTest extends TestCase $this->assertCount(1, $cart2->items); } - /** @test */ + #[Test] public function it_can_add_items_to_guest_cart() { $guestCart = Cart::guest('guest-session'); @@ -67,7 +68,7 @@ class GuestCartTest extends TestCase $this->assertEquals(2, $cartItem->quantity); } - /** @test */ + #[Test] public function it_can_get_guest_cart_total() { $guestCart = Cart::guest('guest-session-2'); @@ -82,7 +83,7 @@ class GuestCartTest extends TestCase $this->assertEquals(250.00, $total); } - /** @test */ + #[Test] public function it_can_get_guest_cart_item_count() { $guestCart = Cart::guest('guest-session-3'); @@ -95,7 +96,7 @@ class GuestCartTest extends TestCase $this->assertEquals(5, $count); } - /** @test */ + #[Test] public function it_can_remove_items_from_guest_cart() { $guestCart = Cart::guest('guest-session-4'); @@ -110,7 +111,7 @@ class GuestCartTest extends TestCase $this->assertEquals(3, $items[0]->quantity); } - /** @test */ + #[Test] public function it_can_clear_guest_cart() { $guestCart = Cart::guest('guest-session-5'); @@ -126,7 +127,7 @@ class GuestCartTest extends TestCase $this->assertTrue(Cart::isEmpty($guestCart)); } - /** @test */ + #[Test] public function it_can_check_if_guest_cart_is_empty() { $guestCart = Cart::guest('guest-session-6'); @@ -140,7 +141,7 @@ class GuestCartTest extends TestCase $this->assertFalse(Cart::isEmpty($guestCart)); } - /** @test */ + #[Test] public function it_can_find_guest_cart_by_id() { $guestCart = Cart::guest('guest-session-7'); @@ -152,7 +153,7 @@ class GuestCartTest extends TestCase $this->assertEquals($cartId, $foundCart->id); } - /** @test */ + #[Test] public function guest_and_authenticated_carts_are_separate() { // Create guest cart @@ -177,7 +178,7 @@ class GuestCartTest extends TestCase $this->assertNotEquals($guestCart->id, Cart::current()->id); } - /** @test */ + #[Test] public function it_can_convert_guest_cart_to_user_cart() { // Guest adds items @@ -198,7 +199,7 @@ class GuestCartTest extends TestCase $this->assertEquals(200.00, Cart::total($userCart)); } - /** @test */ + #[Test] public function it_returns_true_for_empty_guest_cart_after_clear() { $guestCart = Cart::guest('guest-session-10'); @@ -210,7 +211,7 @@ class GuestCartTest extends TestCase $this->assertTrue(Cart::isEmpty($guestCart)); } - /** @test */ + #[Test] public function multiple_guests_have_separate_carts() { $sessionId1 = 'guest-session-11'; @@ -229,7 +230,7 @@ class GuestCartTest extends TestCase $this->assertEquals(300.00, Cart::total($guestCart2)); } - /** @test */ + #[Test] public function it_can_update_items_in_guest_cart() { $guestCart = Cart::guest('guest-session-13'); @@ -244,7 +245,7 @@ class GuestCartTest extends TestCase $this->assertEquals(250.00, $updated->subtotal); } - /** @test */ + #[Test] public function guest_cart_expires_based_on_configuration() { $guestCart = Cart::guest('guest-session-14'); diff --git a/tests/Feature/HasShoppingCapabilitiesTest.php b/tests/Feature/HasShoppingCapabilitiesTest.php index 5d53fbe..b4cc407 100644 --- a/tests/Feature/HasShoppingCapabilitiesTest.php +++ b/tests/Feature/HasShoppingCapabilitiesTest.php @@ -9,12 +9,13 @@ use Blax\Shop\Models\Product; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class HasShoppingCapabilitiesTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function user_has_cart_relationship() { $user = User::factory()->create(); @@ -22,7 +23,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\MorphMany::class, $user->cart()); } - /** @test */ + #[Test] public function user_has_purchases_relationship() { $user = User::factory()->create(); @@ -30,7 +31,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\MorphMany::class, $user->purchases()); } - /** @test */ + #[Test] public function user_can_get_current_cart() { $user = User::factory()->create(); @@ -41,7 +42,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertEquals($user->id, $cart->customer_id); } - /** @test */ + #[Test] public function user_cannot_purchase_product_without_price() { $user = User::factory()->create(); @@ -52,7 +53,7 @@ class HasShoppingCapabilitiesTest extends TestCase $user->purchase($product); } - /** @test */ + #[Test] public function user_cannot_purchase_product_with_multiple_default_prices() { $user = User::factory()->create(); @@ -68,7 +69,7 @@ class HasShoppingCapabilitiesTest extends TestCase $user->purchase($product); } - /** @test */ + #[Test] public function user_can_purchase_product_with_single_default_price() { $user = User::factory()->create(); @@ -84,7 +85,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertEquals($user->id, $purchase->purchaser_id); } - /** @test */ + #[Test] public function user_cannot_add_product_to_cart_without_default_price() { $user = User::factory()->create(); @@ -93,7 +94,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertThrows(fn() => $user->addToCart($product), NotPurchasable::class); } - /** @test */ + #[Test] public function user_cannot_add_product_with_multiple_default_prices_to_cart() { $user = User::factory()->create(); @@ -108,7 +109,7 @@ class HasShoppingCapabilitiesTest extends TestCase $user->addToCart($product); } - /** @test */ + #[Test] public function user_can_get_completed_purchases() { $user = User::factory()->create(); @@ -127,7 +128,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertEquals(PurchaseStatus::COMPLETED, $completed->first()->status); } - /** @test */ + #[Test] public function purchase_with_metadata_stores_correctly() { $user = User::factory()->create(); @@ -144,7 +145,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertEquals('Special instructions', $purchase->meta->notes); } - /** @test */ + #[Test] public function user_can_check_if_purchased_specific_product() { $user = User::factory()->create(); @@ -158,7 +159,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertFalse($user->hasPurchased($notPurchasedProduct)); } - /** @test */ + #[Test] public function user_cart_items_are_accessible() { $user = User::factory()->create(); @@ -169,7 +170,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertCount(1, $user->cartItems); } - /** @test */ + #[Test] public function user_can_update_cart_item_quantity() { $user = User::factory()->create(); @@ -182,7 +183,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertEquals(5, $cartItem->fresh()->quantity); } - /** @test */ + #[Test] public function user_can_remove_item_from_cart() { $user = User::factory()->create(); @@ -197,7 +198,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertCount(0, $user->fresh()->cartItems); } - /** @test */ + #[Test] public function user_can_get_cart_total() { $user = User::factory()->create(); @@ -212,7 +213,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertEquals(250.00, $total); } - /** @test */ + #[Test] public function user_can_get_cart_items_count() { $user = User::factory()->create(); @@ -227,7 +228,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertEquals(5, $count); } - /** @test */ + #[Test] public function user_can_clear_cart() { $user = User::factory()->create(); @@ -244,7 +245,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertCount(0, $user->fresh()->cartItems); } - /** @test */ + #[Test] public function adding_product_to_cart_reserves_stock() { $user = User::factory()->create(); @@ -257,7 +258,7 @@ class HasShoppingCapabilitiesTest extends TestCase $this->assertEquals(7, $product->fresh()->getAvailableStock()); } - /** @test */ + #[Test] public function purchase_calls_product_actions() { $user = User::factory()->create(); diff --git a/tests/Feature/PaymentMethodFieldsTest.php b/tests/Feature/PaymentMethodFieldsTest.php index 687dd75..62b886e 100644 --- a/tests/Feature/PaymentMethodFieldsTest.php +++ b/tests/Feature/PaymentMethodFieldsTest.php @@ -6,9 +6,11 @@ use Blax\Shop\Models\PaymentMethod; use Blax\Shop\Models\PaymentProviderIdentity; use Blax\Shop\Tests\TestCase; use Illuminate\Support\Carbon; +use PHPUnit\Framework\Attributes\Test; class PaymentMethodFieldsTest extends TestCase { + #[Test] public function test_can_store_last_alphanumeric(): void { $identity = PaymentProviderIdentity::factory()->stripe()->create(); @@ -25,6 +27,7 @@ class PaymentMethodFieldsTest extends TestCase $this->assertSame('abc123xyz', $method->last_alphanumeric); } + #[Test] public function test_expiration_via_expires_at(): void { $identity = PaymentProviderIdentity::factory()->stripe()->create(); @@ -53,6 +56,7 @@ class PaymentMethodFieldsTest extends TestCase $this->assertFalse($active->isExpired()); } + #[Test] public function test_expiration_via_month_year(): void { $identity = PaymentProviderIdentity::factory()->stripe()->create(); diff --git a/tests/Feature/PaymentProviderTest.php b/tests/Feature/PaymentProviderTest.php index 032006b..346d702 100644 --- a/tests/Feature/PaymentProviderTest.php +++ b/tests/Feature/PaymentProviderTest.php @@ -10,6 +10,7 @@ use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Mockery; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class PaymentProviderTest extends TestCase { @@ -32,7 +33,7 @@ class PaymentProviderTest extends TestCase - /** @test */ + #[Test] public function it_can_create_a_customer_on_stripe() { $user = User::factory()->create([ @@ -72,7 +73,7 @@ class PaymentProviderTest extends TestCase ]); } - /** @test */ + #[Test] public function it_returns_existing_customer_identity_if_already_exists() { $user = User::factory()->create(); @@ -93,7 +94,7 @@ class PaymentProviderTest extends TestCase $this->assertEquals('cus_existing123', $identity->customer_identification_id); } - /** @test */ + #[Test] public function it_can_add_a_payment_method() { $user = User::factory()->create(); @@ -152,7 +153,7 @@ class PaymentProviderTest extends TestCase ]); } - /** @test */ + #[Test] public function first_payment_method_is_automatically_set_as_default() { $user = User::factory()->create(); @@ -195,7 +196,7 @@ class PaymentProviderTest extends TestCase $this->assertTrue($paymentMethod->fresh()->is_default); } - /** @test */ + #[Test] public function it_can_list_payment_methods() { $user = User::factory()->create(); @@ -231,7 +232,7 @@ class PaymentProviderTest extends TestCase $this->assertCount(3, $allMethods); } - /** @test */ + #[Test] public function it_can_set_a_payment_method_as_default() { $user = User::factory()->create(); @@ -270,7 +271,7 @@ class PaymentProviderTest extends TestCase $this->assertEquals(1, $defaultCount); } - /** @test */ + #[Test] public function it_can_remove_a_payment_method() { $user = User::factory()->create(); @@ -300,7 +301,7 @@ class PaymentProviderTest extends TestCase ]); } - /** @test */ + #[Test] public function removing_default_payment_method_sets_another_as_default() { $user = User::factory()->create(); @@ -339,7 +340,7 @@ class PaymentProviderTest extends TestCase $this->assertTrue($method2->fresh()->is_default); } - /** @test */ + #[Test] public function it_can_use_trait_to_add_payment_methods() { // Use actual User model since it doesn't have the trait yet - test with direct service calls @@ -395,7 +396,7 @@ class PaymentProviderTest extends TestCase // Test identity and method relationships $this->assertEquals($user->id, $identity->customer_id); $this->assertEquals(get_class($user), $identity->customer_type); - + $methods = $this->paymentProviderService->listPaymentMethods($identity); $this->assertCount(1, $methods); @@ -404,7 +405,7 @@ class PaymentProviderTest extends TestCase $this->assertEquals($paymentMethod->id, $defaultMethod->id); } - /** @test */ + #[Test] public function it_can_sync_payment_methods_from_stripe() { $user = User::factory()->create(); @@ -475,7 +476,7 @@ class PaymentProviderTest extends TestCase ]); } - /** @test */ + #[Test] public function payment_method_can_check_if_expired() { $paymentMethod = PaymentMethod::factory()->create([ @@ -493,7 +494,7 @@ class PaymentProviderTest extends TestCase $this->assertFalse($validMethod->isExpired()); } - /** @test */ + #[Test] public function payment_method_has_display_name_attribute() { $method1 = PaymentMethod::factory()->create([ @@ -513,7 +514,7 @@ class PaymentProviderTest extends TestCase $this->assertEquals('Mastercard ending in 5555', $method2->display_name); } - /** @test */ + #[Test] public function payment_method_has_formatted_expiration() { $paymentMethod = PaymentMethod::factory()->create([ diff --git a/tests/Feature/PoolAvailabilityMethodsTest.php b/tests/Feature/PoolAvailabilityMethodsTest.php index 43cd571..df7ce9e 100644 --- a/tests/Feature/PoolAvailabilityMethodsTest.php +++ b/tests/Feature/PoolAvailabilityMethodsTest.php @@ -6,6 +6,7 @@ use Blax\Shop\Enums\ProductType; use Blax\Shop\Models\Product; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; +use PHPUnit\Framework\Attributes\Test; class PoolAvailabilityMethodsTest extends TestCase { @@ -48,7 +49,7 @@ class PoolAvailabilityMethodsTest extends TestCase $this->pool->attachSingleItems([$this->spot1->id, $this->spot2->id, $this->spot3->id]); } - /** @test */ + #[Test] public function it_gets_pool_availability_calendar() { $start = Carbon::now()->addDays(1)->startOfDay(); @@ -66,7 +67,7 @@ class PoolAvailabilityMethodsTest extends TestCase } } - /** @test */ + #[Test] public function it_shows_correct_availability_per_day() { $start = Carbon::now()->addDays(1)->startOfDay(); @@ -79,7 +80,7 @@ class PoolAvailabilityMethodsTest extends TestCase $this->assertEquals(6, $calendar[$dateStr]); } - /** @test */ + #[Test] public function it_reduces_availability_when_items_are_claimed() { $from = Carbon::now()->addDays(1)->startOfDay(); @@ -95,7 +96,7 @@ class PoolAvailabilityMethodsTest extends TestCase $this->assertEquals(4, $calendar[$dateStr]); } - /** @test */ + #[Test] public function it_gets_single_items_availability_without_dates() { $availability = $this->pool->getSingleItemsAvailability(); @@ -113,7 +114,7 @@ class PoolAvailabilityMethodsTest extends TestCase $this->assertEquals(1, $availability[2]['available']); } - /** @test */ + #[Test] public function it_gets_single_items_availability_with_dates() { $from = Carbon::now()->addDays(1)->startOfDay(); @@ -130,7 +131,7 @@ class PoolAvailabilityMethodsTest extends TestCase $this->assertEquals(1, $availability[2]['available']); // Spot 3: still 1 } - /** @test */ + #[Test] public function it_shows_unlimited_for_items_without_stock_management() { $unlimitedSpot = Product::factory()->create([ @@ -148,7 +149,7 @@ class PoolAvailabilityMethodsTest extends TestCase $this->assertFalse($unlimited['manage_stock']); } - /** @test */ + #[Test] public function it_checks_if_pool_is_available_for_period() { $from = Carbon::now()->addDays(1)->startOfDay(); @@ -160,7 +161,7 @@ class PoolAvailabilityMethodsTest extends TestCase $this->assertFalse($this->pool->isPoolAvailable($from, $until, 7)); } - /** @test */ + #[Test] public function it_returns_false_when_pool_not_available() { $from = Carbon::now()->addDays(1)->startOfDay(); @@ -174,7 +175,7 @@ class PoolAvailabilityMethodsTest extends TestCase $this->assertFalse($this->pool->isPoolAvailable($from, $until, 1)); } - /** @test */ + #[Test] public function it_gets_available_periods_for_pool() { $start = Carbon::now()->addDays(1)->startOfDay(); @@ -200,7 +201,7 @@ class PoolAvailabilityMethodsTest extends TestCase } } - /** @test */ + #[Test] public function it_filters_periods_by_minimum_consecutive_days() { $start = Carbon::now()->addDays(1)->startOfDay(); @@ -234,7 +235,7 @@ class PoolAvailabilityMethodsTest extends TestCase } } - /** @test */ + #[Test] public function it_handles_higher_quantity_requirements_in_available_periods() { $start = Carbon::now()->addDays(1)->startOfDay(); @@ -263,7 +264,7 @@ class PoolAvailabilityMethodsTest extends TestCase $this->assertNotEquals($periodsBefore, $periodsAfter); } - /** @test */ + #[Test] public function it_throws_exception_for_non_pool_products() { $regularProduct = Product::factory()->create([ diff --git a/tests/Feature/PoolBookingDetectionTest.php b/tests/Feature/PoolBookingDetectionTest.php index 8da2034..dc94a98 100644 --- a/tests/Feature/PoolBookingDetectionTest.php +++ b/tests/Feature/PoolBookingDetectionTest.php @@ -10,6 +10,7 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class PoolBookingDetectionTest extends TestCase { @@ -23,7 +24,7 @@ class PoolBookingDetectionTest extends TestCase $this->user = User::factory()->create(); } - /** @test */ + #[Test] public function pool_product_with_booking_items_is_detected_as_booking() { // Create pool @@ -61,7 +62,7 @@ class PoolBookingDetectionTest extends TestCase $this->assertTrue($pool->hasBookingSingleItems(), 'Pool should have booking single items'); } - /** @test */ + #[Test] public function pool_product_without_booking_items_is_not_booking() { // Create pool @@ -99,7 +100,7 @@ class PoolBookingDetectionTest extends TestCase $this->assertFalse($pool->hasBookingSingleItems(), 'Pool should not have booking single items'); } - /** @test */ + #[Test] public function pool_cart_item_with_booking_items_is_detected_as_booking() { // Create pool @@ -151,7 +152,7 @@ class PoolBookingDetectionTest extends TestCase $this->assertTrue($cartItem->is_booking, 'Cart item for pool with booking items should be detected as booking'); } - /** @test */ + #[Test] public function pool_cart_item_without_booking_items_is_not_booking() { // Create pool @@ -203,7 +204,7 @@ class PoolBookingDetectionTest extends TestCase $this->assertFalse($cartItem->is_booking, 'Cart item for pool without booking items should not be detected as booking'); } - /** @test */ + #[Test] public function cart_with_pool_booking_items_detects_booking_correctly() { // Create pool with booking items @@ -253,7 +254,7 @@ class PoolBookingDetectionTest extends TestCase $this->assertEquals(1, $cart->bookingItems(), 'Cart should have 1 booking item'); } - /** @test */ + #[Test] public function mixed_cart_with_pool_and_regular_items_not_full_booking() { // Create pool with booking items @@ -327,7 +328,7 @@ class PoolBookingDetectionTest extends TestCase $this->assertEquals(1, $cart->bookingItems(), 'Cart should have 1 booking item'); } - /** @test */ + #[Test] public function cart_item_isBooking_method_works() { // Create pool with booking items @@ -377,7 +378,7 @@ class PoolBookingDetectionTest extends TestCase $this->assertEquals($cartItem->is_booking, $cartItem->isBooking(), 'isBooking() should match is_booking attribute'); } - /** @test */ + #[Test] public function cart_isBooking_method_works() { // Create pool with booking items diff --git a/tests/Feature/PoolClaimingPriorityTest.php b/tests/Feature/PoolClaimingPriorityTest.php index 0901677..f23231c 100644 --- a/tests/Feature/PoolClaimingPriorityTest.php +++ b/tests/Feature/PoolClaimingPriorityTest.php @@ -10,10 +10,11 @@ use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; +use PHPUnit\Framework\Attributes\Test; class PoolClaimingPriorityTest extends TestCase { - /** @test */ + #[Test] public function it_claims_lowest_priced_items_first_with_lowest_strategy() { // Create pool product @@ -99,7 +100,7 @@ class PoolClaimingPriorityTest extends TestCase $this->assertEquals($spot2->id, $claimedIds[2]); } - /** @test */ + #[Test] public function it_claims_highest_priced_items_first_with_highest_strategy() { // Create pool product @@ -167,7 +168,7 @@ class PoolClaimingPriorityTest extends TestCase $this->assertEquals($cheapSpot->id, $claimedItems[1]->id); } - /** @test */ + #[Test] public function it_uses_fallback_price_for_items_without_price() { $pool = Product::factory()->create([ diff --git a/tests/Feature/PoolMaxQuantityValidationTest.php b/tests/Feature/PoolMaxQuantityValidationTest.php index 8542fb4..9f49696 100644 --- a/tests/Feature/PoolMaxQuantityValidationTest.php +++ b/tests/Feature/PoolMaxQuantityValidationTest.php @@ -7,8 +7,8 @@ use Blax\Shop\Models\Cart; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; -use Carbon\Carbon; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; /** * Tests to ensure pool products cannot exceed available single items @@ -75,7 +75,7 @@ class PoolMaxQuantityValidationTest extends TestCase return $pool; } - /** @test */ + #[Test] public function cannot_add_more_items_than_available_singles_without_dates() { $pool = $this->createPoolWith7Singles(); @@ -94,7 +94,7 @@ class PoolMaxQuantityValidationTest extends TestCase $this->cart->addToCart($pool, 1); } - /** @test */ + #[Test] public function cannot_add_more_items_than_available_singles_with_dates() { $pool = $this->createPoolWith7Singles(); @@ -116,7 +116,7 @@ class PoolMaxQuantityValidationTest extends TestCase $this->cart->addToCart($pool, 1, [], $from, $until); } - /** @test */ + #[Test] public function cannot_add_batch_exceeding_available_singles_without_dates() { $pool = $this->createPoolWith7Singles(); @@ -128,7 +128,7 @@ class PoolMaxQuantityValidationTest extends TestCase $this->cart->addToCart($pool, 8); } - /** @test */ + #[Test] public function cannot_add_batch_exceeding_available_singles_with_dates() { $pool = $this->createPoolWith7Singles(); @@ -143,7 +143,7 @@ class PoolMaxQuantityValidationTest extends TestCase $this->cart->addToCart($pool, 8, [], $from, $until); } - /** @test */ + #[Test] public function adding_items_without_dates_then_adding_more_validates_correctly() { $pool = $this->createPoolWith7Singles(); @@ -161,7 +161,7 @@ class PoolMaxQuantityValidationTest extends TestCase $this->cart->addToCart($pool, 1); } - /** @test */ + #[Test] public function checkoutSessionLink_throws_exception_when_cart_invalid() { $pool = $this->createPoolWith7Singles(); @@ -177,7 +177,7 @@ class PoolMaxQuantityValidationTest extends TestCase $this->cart->checkoutSessionLink(); } - /** @test */ + #[Test] public function checkoutSessionLink_throws_exception_when_not_enough_stock() { $pool = $this->createPoolWith7Singles(); @@ -204,7 +204,7 @@ class PoolMaxQuantityValidationTest extends TestCase $this->cart->fresh()->checkoutSessionLink(); } - /** @test */ + #[Test] public function cart_aware_validation_accounts_for_items_already_in_cart() { $pool = $this->createPoolWith7Singles(); @@ -229,7 +229,7 @@ class PoolMaxQuantityValidationTest extends TestCase $this->cart->addToCart($pool, 1, [], $from, $until); } - /** @test */ + #[Test] public function validation_message_shows_correct_remaining_availability() { $pool = $this->createPoolWith7Singles(); diff --git a/tests/Feature/PoolParkingCartPricingTest.php b/tests/Feature/PoolParkingCartPricingTest.php index 099782a..891bcb6 100644 --- a/tests/Feature/PoolParkingCartPricingTest.php +++ b/tests/Feature/PoolParkingCartPricingTest.php @@ -2,9 +2,7 @@ namespace Blax\Shop\Tests\Feature; -use Blax\Shop\Enums\ProductRelationType; use Blax\Shop\Enums\ProductType; -use Blax\Shop\Enums\PricingStrategy; use Blax\Shop\Exceptions\NotEnoughStockException; use Blax\Shop\Models\Cart; use Blax\Shop\Models\Product; @@ -12,6 +10,7 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; /** * Test pool product cart pricing with comprehensive scenarios. @@ -148,7 +147,7 @@ class PoolParkingCartPricingTest extends TestCase // Configuration A: Pool HAS price, does NOT manage stock // ========================================== - /** @test */ + #[Test] public function config_a_progressive_pricing_step_by_step() { $this->cart = $this->createCart(); @@ -188,7 +187,7 @@ class PoolParkingCartPricingTest extends TestCase $this->cart->addToCart($pool, 1, [], $from, $until); } - /** @test */ + #[Test] public function config_a_cart_items_have_correct_price_ids() { $this->cart = $this->createCart(); @@ -220,7 +219,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals($spot3PriceId, $item1000->price_id); } - /** @test */ + #[Test] public function config_a_set_dates_doubles_cart_total() { $this->cart = $this->createCart(); @@ -236,7 +235,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals(7200, $this->cart->fresh()->getTotal()); } - /** @test */ + #[Test] public function config_a_set_dates_after_adding_recalculates_prices() { $this->cart = $this->createCart(); @@ -258,7 +257,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals(7200, $this->cart->fresh()->getTotal()); } - /** @test */ + #[Test] public function config_a_set_from_date_and_until_date_separately() { $this->cart = $this->createCart(); @@ -285,7 +284,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals(7200, $this->cart->fresh()->getTotal()); } - /** @test */ + #[Test] public function config_a_set_dates_overwrites_cart_item_dates() { $this->cart = $this->createCart(); @@ -314,7 +313,7 @@ class PoolParkingCartPricingTest extends TestCase } } - /** @test */ + #[Test] public function config_a_marks_items_unavailable_when_setting_dates_to_unavailable_period() { $this->cart = $this->createCart(); @@ -347,7 +346,7 @@ class PoolParkingCartPricingTest extends TestCase // Configuration B: Pool does NOT have price, does NOT manage stock // ========================================== - /** @test */ + #[Test] public function config_b_progressive_pricing_step_by_step() { $this->cart = $this->createCart(); @@ -380,7 +379,7 @@ class PoolParkingCartPricingTest extends TestCase $this->cart->addToCart($pool, 1); } - /** @test */ + #[Test] public function config_b_cart_items_have_correct_price_ids() { $this->cart = $this->createCart(); @@ -406,7 +405,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals($spot3PriceId, $item1000->price_id); } - /** @test */ + #[Test] public function config_b_set_dates_doubles_cart_total() { $this->cart = $this->createCart(); @@ -422,7 +421,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals(5200, $this->cart->fresh()->getTotal()); } - /** @test */ + #[Test] public function config_b_set_dates_after_adding_recalculates_prices() { $this->cart = $this->createCart(); @@ -448,7 +447,7 @@ class PoolParkingCartPricingTest extends TestCase // Configuration C: Pool HAS price, MANAGES stock // ========================================== - /** @test */ + #[Test] public function config_c_progressive_pricing_step_by_step() { $this->cart = $this->createCart(); @@ -488,7 +487,7 @@ class PoolParkingCartPricingTest extends TestCase $this->cart->addToCart($pool, 1, [], $from, $until); } - /** @test */ + #[Test] public function config_c_cart_items_have_correct_price_ids() { $this->cart = $this->createCart(); @@ -520,7 +519,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals($spot3PriceId, $item1000->price_id); } - /** @test */ + #[Test] public function config_c_set_dates_doubles_cart_total() { $this->cart = $this->createCart(); @@ -536,7 +535,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals(7200, $this->cart->fresh()->getTotal()); } - /** @test */ + #[Test] public function config_c_set_dates_after_adding_recalculates_prices() { $this->cart = $this->createCart(); @@ -558,7 +557,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals(7200, $this->cart->fresh()->getTotal()); } - /** @test */ + #[Test] public function config_c_pool_stock_is_ignored_when_single_items_manage_stock() { $this->cart = $this->createCart(); @@ -573,7 +572,7 @@ class PoolParkingCartPricingTest extends TestCase // Configuration D: Pool does NOT have price, MANAGES stock // ========================================== - /** @test */ + #[Test] public function config_d_progressive_pricing_step_by_step() { $this->cart = $this->createCart(); @@ -603,7 +602,7 @@ class PoolParkingCartPricingTest extends TestCase $this->cart->addToCart($pool, 1); } - /** @test */ + #[Test] public function config_d_cart_items_have_correct_price_ids() { $this->cart = $this->createCart(); @@ -629,7 +628,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals($spot3PriceId, $item1000->price_id); } - /** @test */ + #[Test] public function config_d_set_dates_doubles_cart_total() { $this->cart = $this->createCart(); @@ -645,7 +644,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals(5200, $this->cart->fresh()->getTotal()); } - /** @test */ + #[Test] public function config_d_set_dates_after_adding_recalculates_prices() { $this->cart = $this->createCart(); @@ -671,7 +670,7 @@ class PoolParkingCartPricingTest extends TestCase // Additional tests for date management // ========================================== - /** @test */ + #[Test] public function set_dates_marks_items_unavailable_when_all_claimed() { $this->cart = $this->createCart(); @@ -704,7 +703,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertFalse($this->cart->is_ready_to_checkout, 'Cart should not be ready'); } - /** @test */ + #[Test] public function cart_item_subtotal_updates_when_dates_change() { $this->cart = $this->createCart(); @@ -727,7 +726,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals(1800, $item->subtotal); } - /** @test */ + #[Test] public function cart_total_and_item_subtotals_match() { $this->cart = $this->createCart(); @@ -746,7 +745,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals(7200, $this->cart->getTotal()); } - /** @test */ + #[Test] public function removing_items_updates_pool_availability() { $this->cart = $this->createCart(); @@ -764,7 +763,7 @@ class PoolParkingCartPricingTest extends TestCase $this->assertEquals(3600, $this->cart->fresh()->getTotal()); } - /** @test */ + #[Test] public function adding_quantity_greater_than_one_respects_availability() { $this->cart = $this->createCart(); @@ -778,7 +777,7 @@ class PoolParkingCartPricingTest extends TestCase $this->cart->addToCart($pool, 7, [], $from, $until); } - /** @test */ + #[Test] public function pool_with_all_single_items_without_prices_throws_exception() { $pool = Product::factory()->create([ diff --git a/tests/Feature/PoolPerMinutePricingTest.php b/tests/Feature/PoolPerMinutePricingTest.php index 9da3a6b..fbd35b7 100644 --- a/tests/Feature/PoolPerMinutePricingTest.php +++ b/tests/Feature/PoolPerMinutePricingTest.php @@ -12,6 +12,7 @@ use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class PoolPerMinutePricingTest extends TestCase { @@ -81,7 +82,7 @@ class PoolPerMinutePricingTest extends TestCase $this->poolProduct->setPricingStrategy(PricingStrategy::LOWEST); } - /** @test */ + #[Test] public function it_calculates_pool_price_for_12_hours() { $from = Carbon::now()->addDays(5)->setTime(8, 0, 0); @@ -94,7 +95,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(1500, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_pool_price_for_36_hours() { $from = Carbon::now()->addDays(5)->setTime(9, 0, 0); @@ -107,7 +108,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(4500, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_pool_price_for_6_hours() { $from = Carbon::now()->addDays(5)->setTime(10, 0, 0); @@ -120,7 +121,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(750, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_pool_price_for_90_minutes() { $from = Carbon::now()->addDays(5)->setTime(14, 0, 0); @@ -132,7 +133,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(188, round($cartItem->price, 2)); } - /** @test */ + #[Test] public function it_uses_direct_pool_price_for_fractional_days() { // Set direct price on pool - this is now used as fallback for single items without prices @@ -158,7 +159,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(1500, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_pool_price_with_quantity_for_fractional_days() { $from = Carbon::now()->addDays(5)->setTime(9, 0, 0); @@ -172,7 +173,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(1500, $cartItem->subtotal); // total for 2 units } - /** @test */ + #[Test] public function it_uses_highest_pricing_strategy_for_fractional_days() { // Change to HIGHEST pricing strategy @@ -188,7 +189,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(2500, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_uses_average_pricing_strategy_for_fractional_days() { // Change to AVERAGE pricing strategy @@ -204,7 +205,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(2000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_pool_price_for_multiple_fractional_bookings_in_cart() { $from1 = Carbon::now()->addDays(10)->setTime(10, 0, 0); @@ -231,7 +232,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(1500, $cart->getTotal()); } - /** @test */ + #[Test] public function it_calculates_pool_price_for_very_short_durations() { // 30 minutes @@ -253,7 +254,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(31, $cartItem2->price); } - /** @test */ + #[Test] public function it_handles_multiple_pool_bookings_with_different_durations() { $cart = \Blax\Shop\Models\Cart::factory()->create([ @@ -278,7 +279,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(750, $item2->price); } - /** @test */ + #[Test] public function it_calculates_pool_price_for_3_hours() { $from = Carbon::now()->addDays(5)->setTime(14, 0, 0); @@ -290,7 +291,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(375, $cartItem->price); } - /** @test */ + #[Test] public function it_calculates_pool_price_for_odd_duration_5_hours_30_minutes() { $from = Carbon::now()->addDays(5)->setTime(9, 30, 0); @@ -303,7 +304,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals($expectedPrice, round($cartItem->price)); } - /** @test */ + #[Test] public function it_handles_pool_booking_over_multiple_days_with_hours() { // Monday 2pm to Wednesday 5pm = 51 hours = 2.125 days @@ -317,7 +318,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals($expectedPrice, $cartItem->price); } - /** @test */ + #[Test] public function it_prices_pool_correctly_when_both_spots_have_different_prices_for_fractional_time() { // Create a third spot with an even different price @@ -349,7 +350,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(750, $cartItem->price); } - /** @test */ + #[Test] public function it_calculates_price_for_exact_24_hours_pool() { $from = Carbon::now()->addDays(5)->setTime(9, 0, 0); @@ -362,7 +363,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(3000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_updates_pool_cart_item_from_date_recalculates_per_minute_price() { $now = Carbon::now(); @@ -386,7 +387,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(3750, $cartItem->fresh()->price); } - /** @test */ + #[Test] public function it_handles_booking_spanning_exactly_two_days() { $from = Carbon::now()->addDays(5)->setTime(0, 0, 0); @@ -399,7 +400,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(6000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_calculates_price_for_business_hours_booking() { // 9 AM to 5 PM = 8 hours @@ -412,7 +413,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(1000, $cartItem->price); } - /** @test */ + #[Test] public function it_handles_overnight_booking() { // 10 PM to 6 AM next day = 8 hours @@ -425,7 +426,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(1000, $cartItem->price); } - /** @test */ + #[Test] public function it_calculates_price_with_minutes_precision() { // 2 hours and 45 minutes @@ -438,7 +439,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(344, $cartItem->price); } - /** @test */ + #[Test] public function it_maintains_precision_for_multiple_quantity() { // 6 hours @@ -454,7 +455,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertGreaterThan(1000, $cartItem->subtotal); } - /** @test */ + #[Test] public function it_handles_weekend_hourly_booking() { // Friday 6 PM to Sunday 6 PM = 48 hours exactly @@ -467,7 +468,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(6000, $cartItem->price); } - /** @test */ + #[Test] public function it_calculates_different_pricing_strategies_for_fractional_time() { // Test LOWEST (already set in setUp) @@ -500,7 +501,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(500, $cartItem->price); } - /** @test */ + #[Test] public function it_handles_single_minute_booking() { // Just 1 minute @@ -513,7 +514,7 @@ class PoolPerMinutePricingTest extends TestCase $this->assertEquals(2, $cartItem->price); } - /** @test */ + #[Test] public function it_handles_booking_with_seconds_precision() { // 2 hours, 30 minutes, 30 seconds (Carbon truncates seconds to minutes) diff --git a/tests/Feature/PoolProductCheckoutTest.php b/tests/Feature/PoolProductCheckoutTest.php index ead90a1..aa6a325 100644 --- a/tests/Feature/PoolProductCheckoutTest.php +++ b/tests/Feature/PoolProductCheckoutTest.php @@ -11,6 +11,7 @@ use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class PoolProductCheckoutTest extends TestCase { @@ -88,7 +89,7 @@ class PoolProductCheckoutTest extends TestCase } } - /** @test */ + #[Test] public function checkout_cart_with_pool_product_claims_correct_single_items() { $from = Carbon::now()->addDays(1); @@ -117,7 +118,7 @@ class PoolProductCheckoutTest extends TestCase $this->assertEquals(2, $claimedCount); } - /** @test */ + #[Test] public function checkout_cart_with_pool_product_without_timespan_throws_exception_when_single_items_are_bookings() { $cart = $this->user->currentCart(); @@ -136,7 +137,7 @@ class PoolProductCheckoutTest extends TestCase $cart->checkout(); } - /** @test */ + #[Test] public function checkout_cart_with_pool_product_and_timespan_succeeds() { $from = Carbon::now()->addDays(1); @@ -158,7 +159,7 @@ class PoolProductCheckoutTest extends TestCase $this->assertCount(1, $cart->purchases); } - /** @test */ + #[Test] public function checkout_cart_with_pool_product_stores_claimed_items_in_cart_item_meta() { $from = Carbon::now()->addDays(1); @@ -190,7 +191,7 @@ class PoolProductCheckoutTest extends TestCase } } - /** @test */ + #[Test] public function checkout_cart_with_multiple_pool_products_claims_from_each_independently() { $from = Carbon::now()->addDays(1); @@ -260,7 +261,7 @@ class PoolProductCheckoutTest extends TestCase $this->assertEquals(1, $bikePool->getPoolMaxQuantity($from, $until)); } - /** @test */ + #[Test] public function checkout_cart_with_pool_product_and_regular_booking_product_succeeds() { $from = Carbon::now()->addDays(1); @@ -294,7 +295,7 @@ class PoolProductCheckoutTest extends TestCase $this->assertCount(2, $cart->purchases); } - /** @test */ + #[Test] public function checkout_cart_with_pool_product_fails_when_single_item_becomes_unavailable_during_checkout() { $from = Carbon::now()->addDays(1); @@ -323,7 +324,7 @@ class PoolProductCheckoutTest extends TestCase $cart->checkout(); } - /** @test */ + #[Test] public function checkout_cart_validates_timespan_before_claiming_stock() { $cart = $this->user->currentCart(); @@ -347,7 +348,7 @@ class PoolProductCheckoutTest extends TestCase $this->assertEquals(3, $this->parkingPool->getPoolMaxQuantity($from, $until)); } - /** @test */ + #[Test] public function checkout_creates_purchase_with_correct_timespan() { $from = Carbon::now()->addDays(1); @@ -372,7 +373,7 @@ class PoolProductCheckoutTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $purchase->until->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function checkout_with_pool_product_using_legacy_parameters() { $from = Carbon::now()->addDays(1); @@ -399,7 +400,7 @@ class PoolProductCheckoutTest extends TestCase $this->assertTrue($cart->isConverted()); } - /** @test */ + #[Test] public function checkout_pool_product_claims_stock_with_cart_reference() { $from = Carbon::now()->addDays(1); diff --git a/tests/Feature/PoolProductPriceIdTest.php b/tests/Feature/PoolProductPriceIdTest.php index ae40c98..ddeed9b 100644 --- a/tests/Feature/PoolProductPriceIdTest.php +++ b/tests/Feature/PoolProductPriceIdTest.php @@ -10,6 +10,7 @@ use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class PoolProductPriceIdTest extends TestCase { @@ -79,7 +80,7 @@ class PoolProductPriceIdTest extends TestCase ]); } - /** @test */ + #[Test] public function it_stores_single_item_price_id_when_adding_pool_to_cart_with_lowest_strategy() { // Set pricing strategy to lowest (default) @@ -94,7 +95,7 @@ class PoolProductPriceIdTest extends TestCase $this->assertEquals(2000, $cartItem->price); // $20 } - /** @test */ + #[Test] public function it_stores_correct_price_id_for_second_pool_item_with_progressive_pricing() { // Set pricing strategy to lowest @@ -111,7 +112,7 @@ class PoolProductPriceIdTest extends TestCase $this->assertEquals(5000, $cartItem2->price); } - /** @test */ + #[Test] public function it_stores_single_item_price_id_with_highest_strategy() { // Set pricing strategy to highest @@ -126,7 +127,7 @@ class PoolProductPriceIdTest extends TestCase $this->assertEquals(5000, $cartItem->price); // $50 } - /** @test */ + #[Test] public function it_stores_allocated_single_item_in_meta() { // Set pricing strategy to lowest @@ -142,7 +143,7 @@ class PoolProductPriceIdTest extends TestCase $this->assertEquals($this->singleItem1->name, $meta->allocated_single_item_name); } - /** @test */ + #[Test] public function it_stores_different_single_items_in_meta_for_progressive_pricing() { // Set pricing strategy to lowest @@ -159,7 +160,7 @@ class PoolProductPriceIdTest extends TestCase $this->assertEquals($this->singleItem2->id, $meta2->allocated_single_item_id); } - /** @test */ + #[Test] public function it_uses_pool_price_id_when_pool_has_direct_price_and_no_single_item_prices() { // Remove prices from single items @@ -193,7 +194,7 @@ class PoolProductPriceIdTest extends TestCase ); } - /** @test */ + #[Test] public function it_stores_price_id_with_average_pricing_strategy() { // Set pricing strategy to average @@ -213,7 +214,7 @@ class PoolProductPriceIdTest extends TestCase ); } - /** @test */ + #[Test] public function it_stores_correct_price_id_with_booking_dates() { // Set pricing strategy to lowest diff --git a/tests/Feature/PoolProductPricingFlexibilityTest.php b/tests/Feature/PoolProductPricingFlexibilityTest.php index ecac95d..6b5965b 100644 --- a/tests/Feature/PoolProductPricingFlexibilityTest.php +++ b/tests/Feature/PoolProductPricingFlexibilityTest.php @@ -6,10 +6,10 @@ use Blax\Shop\Models\Cart; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Enums\ProductType; -use Blax\Shop\Enums\ProductRelationType; use Blax\Shop\Exceptions\HasNoPriceException; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class PoolProductPricingFlexibilityTest extends TestCase { @@ -23,7 +23,7 @@ class PoolProductPricingFlexibilityTest extends TestCase $this->user = \Workbench\App\Models\User::factory()->create(); } - /** @test */ + #[Test] public function pool_without_direct_price_uses_single_item_prices() { $pool = Product::factory()->create([ @@ -64,7 +64,7 @@ class PoolProductPricingFlexibilityTest extends TestCase $this->assertEquals(5000, $cartItem->price); } - /** @test */ + #[Test] public function pool_validation_does_not_throw_when_single_items_have_prices() { $pool = Product::factory()->create([ @@ -99,7 +99,7 @@ class PoolProductPricingFlexibilityTest extends TestCase $this->assertStringContainsString('inherited pricing', $result['warnings'][0]); } - /** @test */ + #[Test] public function pool_validation_warns_when_no_prices_available_but_does_not_throw() { $pool = Product::factory()->create([ @@ -126,7 +126,7 @@ class PoolProductPricingFlexibilityTest extends TestCase $this->assertStringContainsString('Price will be needed when adding to cart', $result['warnings'][0]); } - /** @test */ + #[Test] public function pool_throws_exception_only_when_adding_to_cart_without_any_prices() { $pool = Product::factory()->create([ @@ -157,7 +157,7 @@ class PoolProductPricingFlexibilityTest extends TestCase $cart->addToCart($pool, 1); } - /** @test */ + #[Test] public function pool_with_direct_price_used_as_fallback_when_single_items_have_no_prices() { $pool = Product::factory()->create([ @@ -190,7 +190,7 @@ class PoolProductPricingFlexibilityTest extends TestCase $this->assertEquals(4000, $price); } - /** @test */ + #[Test] public function pool_prefers_single_item_prices_over_direct_price() { $pool = Product::factory()->create([ @@ -231,7 +231,7 @@ class PoolProductPricingFlexibilityTest extends TestCase $this->assertEquals(5000, $price); } - /** @test */ + #[Test] public function pool_can_be_created_without_price_if_single_items_will_have_prices() { // This test verifies that pools can exist in a "not fully configured" state @@ -278,7 +278,7 @@ class PoolProductPricingFlexibilityTest extends TestCase $this->assertEquals(5000, $cartItem->price); } - /** @test */ + #[Test] public function pool_uses_pricing_strategy_with_multiple_single_item_prices() { $pool = Product::factory()->create([ diff --git a/tests/Feature/PoolProductPricingTest.php b/tests/Feature/PoolProductPricingTest.php index e48ecec..8fa03a4 100644 --- a/tests/Feature/PoolProductPricingTest.php +++ b/tests/Feature/PoolProductPricingTest.php @@ -11,6 +11,7 @@ use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class PoolProductPricingTest extends TestCase { @@ -58,7 +59,7 @@ class PoolProductPricingTest extends TestCase ]); } - /** @test */ + #[Test] public function pool_product_inherits_price_from_single_items_when_no_pool_price_set() { // Set price on single items @@ -85,7 +86,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(5000, $price); } - /** @test */ + #[Test] public function pool_product_uses_own_price_when_explicitly_set() { // Set different prices on single items @@ -111,7 +112,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(4500, $price); } - /** @test */ + #[Test] public function pool_product_inherits_average_price_from_single_items_with_different_prices() { // Set different prices on single items @@ -140,7 +141,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(6000, $price); } - /** @test */ + #[Test] public function pool_product_returns_null_when_no_prices_available() { // No prices set on pool or single items @@ -149,7 +150,7 @@ class PoolProductPricingTest extends TestCase $this->assertNull($price); } - /** @test */ + #[Test] public function pool_product_inherits_lowest_price_from_single_items() { ProductPrice::factory()->create([ @@ -173,7 +174,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(5000, $lowestPrice); } - /** @test */ + #[Test] public function pool_product_inherits_highest_price_from_single_items() { ProductPrice::factory()->create([ @@ -197,7 +198,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(7000, $highestPrice); } - /** @test */ + #[Test] public function pool_product_bulk_discount_applied_for_multiple_items() { // Set pool price with bulk discount @@ -229,7 +230,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(20000, $total); } - /** @test */ + #[Test] public function pool_product_pricing_strategy_can_be_set_to_average() { ProductPrice::factory()->create([ @@ -255,7 +256,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(6000, $price); } - /** @test */ + #[Test] public function pool_product_pricing_strategy_can_be_set_to_lowest() { ProductPrice::factory()->create([ @@ -281,7 +282,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(5000, $price); } - /** @test */ + #[Test] public function pool_product_pricing_strategy_can_be_set_to_highest() { ProductPrice::factory()->create([ @@ -307,7 +308,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(7000, $price); } - /** @test */ + #[Test] public function pool_product_price_range_returns_min_and_max() { ProductPrice::factory()->create([ @@ -331,7 +332,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(['min' => 5000, 'max' => 7000], $priceRange); } - /** @test */ + #[Test] public function pool_product_with_sale_price_applies_discount() { ProductPrice::factory()->create([ @@ -354,7 +355,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(8000, $price); } - /** @test */ + #[Test] public function pool_product_ignores_single_items_without_prices() { // Only set price on one item @@ -372,7 +373,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(5000, $price); } - /** @test */ + #[Test] public function pool_product_pricing_updates_when_single_item_prices_change() { $price1 = ProductPrice::factory()->create([ @@ -405,7 +406,7 @@ class PoolProductPricingTest extends TestCase $this->assertEquals(5500, $updatedPrice); // Average of 6000 and 5000 } - /** @test */ + #[Test] public function pool_product_with_custom_pricing_strategy_in_meta() { ProductPrice::factory()->create([ diff --git a/tests/Feature/PoolProductRelationsTest.php b/tests/Feature/PoolProductRelationsTest.php index e1f4977..43febb0 100644 --- a/tests/Feature/PoolProductRelationsTest.php +++ b/tests/Feature/PoolProductRelationsTest.php @@ -6,10 +6,12 @@ use Blax\Shop\Enums\ProductRelationType; use Blax\Shop\Enums\ProductType; use Blax\Shop\Models\Product; use Blax\Shop\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; + class PoolProductRelationsTest extends TestCase { - /** @test */ + #[Test] public function it_creates_reverse_pool_relation_when_attaching_single_items() { // Create pool product @@ -48,7 +50,7 @@ class PoolProductRelationsTest extends TestCase $this->assertEquals(ProductRelationType::POOL->value, $spot1Pivot->pivot->type); } - /** @test */ + #[Test] public function it_can_attach_single_item_using_id() { $pool = Product::factory()->create([ @@ -70,7 +72,7 @@ class PoolProductRelationsTest extends TestCase $this->assertTrue($spot->poolProducts->contains($pool)); } - /** @test */ + #[Test] public function it_throws_exception_when_non_pool_tries_to_attach_single_items() { $regularProduct = Product::factory()->create([ @@ -86,7 +88,7 @@ class PoolProductRelationsTest extends TestCase $regularProduct->attachSingleItems($spot->id); } - /** @test */ + #[Test] public function single_item_can_belong_to_multiple_pools() { // Create two pools @@ -120,7 +122,7 @@ class PoolProductRelationsTest extends TestCase $this->assertTrue($pool2->singleProducts->contains($spot)); } - /** @test */ + #[Test] public function it_can_get_all_pools_for_a_single_item() { $pool1 = Product::factory()->create(['type' => ProductType::POOL, 'name' => 'Pool 1']); @@ -141,7 +143,7 @@ class PoolProductRelationsTest extends TestCase $this->assertTrue($pools->contains('name', 'Pool 3')); } - /** @test */ + #[Test] public function legacy_manual_attach_still_works() { // Test that old way of attaching still works (without reverse relation) diff --git a/tests/Feature/PoolProductTest.php b/tests/Feature/PoolProductTest.php index 4c8c8c7..5682dc6 100644 --- a/tests/Feature/PoolProductTest.php +++ b/tests/Feature/PoolProductTest.php @@ -5,13 +5,13 @@ namespace Blax\Shop\Tests\Feature; use Blax\Shop\Enums\ProductRelationType; use Blax\Shop\Enums\ProductType; use Blax\Shop\Enums\StockType; -use Blax\Shop\Models\Cart; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class PoolProductTest extends TestCase { @@ -107,7 +107,7 @@ class PoolProductTest extends TestCase ]); } - /** @test */ + #[Test] public function it_can_create_a_pool_product() { $this->assertNotNull($this->parkingPool); @@ -115,7 +115,7 @@ class PoolProductTest extends TestCase $this->assertTrue($this->parkingPool->isPool()); } - /** @test */ + #[Test] public function pool_product_has_single_items_linked() { $singleItems = $this->parkingPool->singleProducts; @@ -126,7 +126,7 @@ class PoolProductTest extends TestCase $this->assertTrue($singleItems->contains($this->parkingSpot3)); } - /** @test */ + #[Test] public function pool_product_max_quantity_equals_number_of_single_items() { $maxQuantity = $this->parkingPool->getPoolMaxQuantity(); @@ -134,13 +134,13 @@ class PoolProductTest extends TestCase $this->assertEquals(3, $maxQuantity); } - /** @test */ + #[Test] public function pool_product_detects_booking_single_items() { $this->assertTrue($this->parkingPool->hasBookingSingleItems()); } - /** @test */ + #[Test] public function it_can_add_pool_product_to_cart_with_timespan() { $cart = $this->user->currentCart(); @@ -161,7 +161,7 @@ class PoolProductTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $cartItem->until->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function pool_product_quantity_is_limited_by_available_single_items() { $from = Carbon::now()->addDays(1); @@ -179,7 +179,7 @@ class PoolProductTest extends TestCase $this->assertEquals(2, $maxQuantity); } - /** @test */ + #[Test] public function booking_price_is_calculated_based_on_timespan_and_quantity() { $from = Carbon::now()->addDays(1)->startOfDay(); @@ -194,7 +194,7 @@ class PoolProductTest extends TestCase $this->assertEquals(80.00, $expectedTotal); } - /** @test */ + #[Test] public function pool_product_with_overlapping_bookings_reduces_available_quantity() { $from = Carbon::now()->addDays(5); @@ -211,7 +211,7 @@ class PoolProductTest extends TestCase $this->assertEquals(1, $this->parkingPool->getPoolMaxQuantity($from, $until)); } - /** @test */ + #[Test] public function different_timespan_bookings_dont_conflict() { $from1 = Carbon::now()->addDays(1); @@ -230,7 +230,7 @@ class PoolProductTest extends TestCase $this->assertEquals(2, $this->parkingPool->getPoolMaxQuantity($from1, $until1)); } - /** @test */ + #[Test] public function pool_product_unavailable_when_all_single_items_booked() { $from = Carbon::now()->addDays(1); @@ -245,7 +245,7 @@ class PoolProductTest extends TestCase $this->assertEquals(0, $this->parkingPool->getPoolMaxQuantity($from, $until)); } - /** @test */ + #[Test] public function pool_product_can_be_cross_sell_of_hotel_room() { $crossSells = $this->hotelRoom->crossSellProducts; @@ -254,7 +254,7 @@ class PoolProductTest extends TestCase $this->assertTrue($crossSells->contains($this->parkingPool)); } - /** @test */ + #[Test] public function booking_cancellation_releases_stock_of_single_items() { $from = Carbon::now()->addDays(10); @@ -282,7 +282,7 @@ class PoolProductTest extends TestCase $this->assertEquals(3, $this->parkingPool->getPoolMaxQuantity($from, $until)); } - /** @test */ + #[Test] public function pool_product_respects_partial_overlapping_bookings() { // Booking 1: Days 1-3 @@ -301,7 +301,7 @@ class PoolProductTest extends TestCase $this->assertEquals(2, $this->parkingPool->getPoolMaxQuantity($from2, $until2)); } - /** @test */ + #[Test] public function multiple_pool_products_can_exist_independently() { // Create a second pool for bikes @@ -338,7 +338,7 @@ class PoolProductTest extends TestCase $this->assertEquals(2, $bikePool->getPoolMaxQuantity()); } - /** @test */ + #[Test] public function pool_product_stock_calculated_correctly_with_mixed_availability() { $from = Carbon::now()->addDays(1); @@ -357,7 +357,7 @@ class PoolProductTest extends TestCase $this->assertEquals(2, $this->parkingPool->getPoolMaxQuantity($from, $until)); } - /** @test */ + #[Test] public function pool_product_with_zero_single_items_returns_zero_max_quantity() { $emptyPool = Product::factory()->create([ @@ -369,7 +369,7 @@ class PoolProductTest extends TestCase $this->assertEquals(0, $emptyPool->getPoolMaxQuantity()); } - /** @test */ + #[Test] public function pool_product_with_non_booking_single_items_doesnt_require_timespan() { $simplePool = Product::factory()->create([ @@ -391,7 +391,7 @@ class PoolProductTest extends TestCase $this->assertFalse($simplePool->hasBookingSingleItems()); } - /** @test */ + #[Test] public function pool_product_with_mixed_booking_and_non_booking_single_items() { $mixedPool = Product::factory()->create([ @@ -425,7 +425,7 @@ class PoolProductTest extends TestCase $this->assertEquals(1, $mixedPool->getPoolMaxQuantity()); } - /** @test */ + #[Test] public function pool_product_checkout_claims_exactly_the_right_number_of_single_items() { $from = Carbon::now()->addDays(1); @@ -456,7 +456,7 @@ class PoolProductTest extends TestCase $this->assertEquals(2, $claimedCount); } - /** @test */ + #[Test] public function pool_product_checkout_stores_claimed_single_items_in_metadata() { $from = Carbon::now()->addDays(1); @@ -483,7 +483,7 @@ class PoolProductTest extends TestCase $this->assertCount(2, $claimedItems); } - /** @test */ + #[Test] public function pool_product_with_different_stock_quantities_on_single_items() { $from = Carbon::now()->addDays(1); @@ -511,7 +511,7 @@ class PoolProductTest extends TestCase $this->assertEquals(2, $customPool->getPoolMaxQuantity($from, $until)); } - /** @test */ + #[Test] public function claim_pool_stock_throws_exception_when_not_enough_single_items_available() { $from = Carbon::now()->addDays(1); @@ -528,7 +528,7 @@ class PoolProductTest extends TestCase $this->parkingPool->claimPoolStock(2, null, $from, $until); } - /** @test */ + #[Test] public function claim_pool_stock_throws_exception_when_called_on_non_pool_product() { $from = Carbon::now()->addDays(1); @@ -540,7 +540,7 @@ class PoolProductTest extends TestCase $this->hotelRoom->claimPoolStock(1, null, $from, $until); } - /** @test */ + #[Test] public function release_pool_stock_correctly_releases_all_claims() { $from = Carbon::now()->addDays(1); @@ -561,7 +561,7 @@ class PoolProductTest extends TestCase $this->assertEquals(3, $this->parkingPool->getPoolMaxQuantity($from, $until)); } - /** @test */ + #[Test] public function release_pool_stock_throws_exception_when_called_on_non_pool_product() { $this->expectException(\Exception::class); @@ -570,7 +570,7 @@ class PoolProductTest extends TestCase $this->hotelRoom->releasePoolStock($this->user->currentCart()); } - /** @test */ + #[Test] public function pool_product_with_single_item_already_claimed_for_entire_period() { $from = Carbon::now()->addDays(1); @@ -594,7 +594,7 @@ class PoolProductTest extends TestCase $this->assertEquals(1, $this->parkingPool->getPoolMaxQuantity($partialFrom, $partialUntil)); } - /** @test */ + #[Test] public function pool_product_maximum_quantity_with_edge_of_timespan() { // Claim 1: Days 1-3 diff --git a/tests/Feature/PoolProductionBugTest.php b/tests/Feature/PoolProductionBugTest.php index 9711a27..8e10935 100644 --- a/tests/Feature/PoolProductionBugTest.php +++ b/tests/Feature/PoolProductionBugTest.php @@ -10,6 +10,7 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; /** * Test to reproduce and fix the production bug where: @@ -172,7 +173,7 @@ class PoolProductionBugTest extends TestCase ]); } - /** @test */ + #[Test] public function pool_max_quantity_returns_sum_of_single_item_stocks() { $this->createProductionPool(); @@ -183,7 +184,7 @@ class PoolProductionBugTest extends TestCase $this->assertEquals(6, $maxQty); } - /** @test */ + #[Test] public function adding_7_items_should_throw_not_enough_stock_exception() { $this->createProductionPool(); @@ -199,7 +200,7 @@ class PoolProductionBugTest extends TestCase $this->cart->addToCart($this->pool, 7, [], $from, $until); } - /** @test */ + #[Test] public function adding_6_items_gives_correct_progressive_pricing() { $this->createProductionPool(); @@ -239,7 +240,7 @@ class PoolProductionBugTest extends TestCase $this->assertEquals(85003, $this->cart->fresh()->getTotal()); } - /** @test */ + #[Test] public function adding_6_items_at_once_gives_correct_pricing() { $this->createProductionPool(); @@ -252,7 +253,7 @@ class PoolProductionBugTest extends TestCase $this->assertEquals(85003, $this->cart->fresh()->getTotal()); } - /** @test */ + #[Test] public function cart_items_have_correct_allocated_single_items() { $this->createProductionPool(); @@ -281,7 +282,7 @@ class PoolProductionBugTest extends TestCase $this->assertEquals(85003, $this->cart->getTotal()); } - /** @test */ + #[Test] public function set_dates_updates_cart_item_dates_and_recalculates_prices() { $this->createProductionPool(); @@ -321,7 +322,7 @@ class PoolProductionBugTest extends TestCase $this->assertEquals(30000, $cart->getTotal()); } - /** @test */ + #[Test] public function set_dates_updates_all_items_with_different_prices() { $this->createProductionPool(); @@ -356,7 +357,7 @@ class PoolProductionBugTest extends TestCase $this->assertEquals(170006, $cart->getTotal()); } - /** @test */ + #[Test] public function adding_items_without_dates_then_setting_dates_works() { $this->createProductionPool(); @@ -394,7 +395,7 @@ class PoolProductionBugTest extends TestCase * If a user boys 5 single parking items, another can also buy 5 single items on different dates, * but not on the same dates, if stock is claimed on date */ - /** @test */ + #[Test] public function pool_allows_adding_singel_to_cart_again_after_booked() { $this->createProductionPool(); @@ -471,7 +472,7 @@ class PoolProductionBugTest extends TestCase * Expected: Should be able to add 6 items for different dates * Actual: Can only add 2 items */ - /** @test */ + #[Test] public function user_can_add_pool_items_for_different_dates_after_stripe_purchase() { $this->createProductionPool(); diff --git a/tests/Feature/PoolSeparateCartItemsTest.php b/tests/Feature/PoolSeparateCartItemsTest.php index f322eb6..76f5ec2 100644 --- a/tests/Feature/PoolSeparateCartItemsTest.php +++ b/tests/Feature/PoolSeparateCartItemsTest.php @@ -11,6 +11,7 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class PoolSeparateCartItemsTest extends TestCase { @@ -65,7 +66,7 @@ class PoolSeparateCartItemsTest extends TestCase $this->pool->attachSingleItems([$spot1->id, $spot2->id]); } - /** @test */ + #[Test] public function it_creates_separate_cart_items_for_different_dates() { $from1 = Carbon::now()->addDays(1)->startOfDay(); @@ -82,7 +83,7 @@ class PoolSeparateCartItemsTest extends TestCase $this->assertEquals(2, $this->cart->items()->count()); } - /** @test */ + #[Test] public function it_merges_cart_items_with_same_dates_and_price() { $from = Carbon::now()->addDays(1)->startOfDay(); @@ -97,7 +98,7 @@ class PoolSeparateCartItemsTest extends TestCase $this->assertEquals(2, $item2->quantity); } - /** @test */ + #[Test] public function it_creates_separate_cart_items_when_price_changes() { $from = Carbon::now()->addDays(1)->startOfDay(); @@ -129,7 +130,7 @@ class PoolSeparateCartItemsTest extends TestCase $this->assertNotEquals($price1, $item2->price); } - /** @test */ + #[Test] public function it_creates_separate_cart_items_for_different_date_lengths() { $from = Carbon::now()->addDays(1)->startOfDay(); diff --git a/tests/Feature/PoolSmartAllocationTest.php b/tests/Feature/PoolSmartAllocationTest.php index 6f48ccc..272fea1 100644 --- a/tests/Feature/PoolSmartAllocationTest.php +++ b/tests/Feature/PoolSmartAllocationTest.php @@ -9,6 +9,7 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; /** * Tests for smart pool allocation and flexible cart behavior @@ -83,7 +84,7 @@ class PoolSmartAllocationTest extends TestCase /** * Test: Items can be added to cart without dates */ - /** @test */ + #[Test] public function items_can_be_added_to_cart_without_dates() { $this->createPoolWithVaryingPrices(); @@ -100,7 +101,7 @@ class PoolSmartAllocationTest extends TestCase /** * Test: Items can be added even if currently claimed but will be available in future */ - /** @test */ + #[Test] public function items_can_be_added_even_if_currently_claimed_but_available_in_future() { $this->createPoolWithVaryingPrices(); @@ -131,7 +132,7 @@ class PoolSmartAllocationTest extends TestCase /** * Test: Cart is not ready for checkout if items added without dates */ - /** @test */ + #[Test] public function cart_is_not_ready_for_checkout_without_dates_for_booking_products() { $this->createPoolWithVaryingPrices(); @@ -147,7 +148,7 @@ class PoolSmartAllocationTest extends TestCase /** * Test: Cart becomes ready after setting dates */ - /** @test */ + #[Test] public function cart_becomes_ready_after_setting_valid_dates() { $this->createPoolWithVaryingPrices(); @@ -169,7 +170,7 @@ class PoolSmartAllocationTest extends TestCase /** * Test: User1 purchases items, User2 can add same items but only available ones get allocated */ - /** @test */ + #[Test] public function user2_can_book_same_items_for_different_dates_after_user1_purchase() { $this->createPoolWithVaryingPrices(); @@ -216,7 +217,7 @@ class PoolSmartAllocationTest extends TestCase /** * Test: User2 can successfully book after setting different dates */ - /** @test */ + #[Test] public function user2_can_successfully_book_after_setting_different_dates() { $this->createPoolWithVaryingPrices(); @@ -257,7 +258,7 @@ class PoolSmartAllocationTest extends TestCase * Scenario: 3 items claimed for future, 3 available now * When adding 3 items, should get the 3 currently available ones */ - /** @test */ + #[Test] public function pool_prioritizes_currently_available_items_when_adding_to_cart() { $this->createPoolWithVaryingPrices(); @@ -291,7 +292,7 @@ class PoolSmartAllocationTest extends TestCase * - Change to different date when cheaper items become available * - Cart should reallocate to cheaper items */ - /** @test */ + #[Test] public function cart_reallocates_to_cheaper_items_when_dates_change_with_lowest_strategy() { $this->createPoolWithVaryingPrices(); @@ -325,7 +326,7 @@ class PoolSmartAllocationTest extends TestCase /** * Test: Verify allocated items change when reallocating */ - /** @test */ + #[Test] public function allocated_single_items_change_when_reallocating_to_better_prices() { $this->createPoolWithVaryingPrices(); diff --git a/tests/Feature/ProductActionTest.php b/tests/Feature/ProductActionTest.php index 8ae3257..0216ef9 100644 --- a/tests/Feature/ProductActionTest.php +++ b/tests/Feature/ProductActionTest.php @@ -4,16 +4,16 @@ namespace Blax\Shop\Tests\Feature; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductAction; -use Blax\Shop\Models\ProductPurchase; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class ProductActionTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_create_a_product_action() { $product = Product::factory()->create(); @@ -32,7 +32,7 @@ class ProductActionTest extends TestCase $this->assertContains('refunded', $action->events ?? []); } - /** @test */ + #[Test] public function product_has_many_actions() { $product = Product::factory()->create(); @@ -52,7 +52,7 @@ class ProductActionTest extends TestCase $this->assertCount(2, $product->fresh()->actions); } - /** @test */ + #[Test] public function action_belongs_to_product() { $product = Product::factory()->create(); @@ -66,7 +66,7 @@ class ProductActionTest extends TestCase $this->assertEquals($product->id, $action->product->id); } - /** @test */ + #[Test] public function it_can_enable_and_disable_actions() { $product = Product::factory()->create(); @@ -86,7 +86,7 @@ class ProductActionTest extends TestCase $this->assertFalse($action->fresh()->active); } - /** @test */ + #[Test] public function it_can_store_action_parameters() { $product = Product::factory()->create(); @@ -109,7 +109,7 @@ class ProductActionTest extends TestCase $this->assertEquals('Welcome to our service', $action->parameters['subject']); } - /** @test */ + #[Test] public function it_can_set_action_priority() { $product = Product::factory()->create(); @@ -134,7 +134,7 @@ class ProductActionTest extends TestCase $this->assertEquals($action2->id, $sorted[1]->id); } - /** @test */ + #[Test] public function it_can_have_different_events() { $product = Product::factory()->create(); @@ -157,7 +157,7 @@ class ProductActionTest extends TestCase $this->assertContains('refunded', $refundedAction->events); } - /** @test */ + #[Test] public function it_can_get_actions_for_specific_event() { $product = Product::factory()->create(); @@ -187,7 +187,7 @@ class ProductActionTest extends TestCase $this->assertCount(2, $purchaseActions); } - /** @test */ + #[Test] public function it_can_filter_enabled_actions() { $product = Product::factory()->create(); @@ -212,7 +212,7 @@ class ProductActionTest extends TestCase $this->assertCount(1, $enabledActions); } - /** @test */ + #[Test] public function multiple_products_can_have_same_action() { $product1 = Product::factory()->create(); @@ -234,7 +234,7 @@ class ProductActionTest extends TestCase $this->assertCount(1, $product2->actions); } - /** @test */ + #[Test] public function it_can_update_action_parameters() { $product = Product::factory()->create(); @@ -262,7 +262,7 @@ class ProductActionTest extends TestCase $this->assertEquals('another_value', $fresh->parameters['another_key']); } - /** @test */ + #[Test] public function deleting_product_deletes_actions() { $product = Product::factory()->create(); @@ -281,7 +281,7 @@ class ProductActionTest extends TestCase $this->assertDatabaseMissing('product_actions', ['id' => $actionId]); } - /** @test */ + #[Test] public function action_can_have_empty_parameters() { $product = Product::factory()->create(); @@ -295,7 +295,7 @@ class ProductActionTest extends TestCase $this->assertNull($action->parameters); } - /** @test */ + #[Test] public function it_can_query_actions_by_priority_order() { $product = Product::factory()->create(); @@ -333,7 +333,7 @@ class ProductActionTest extends TestCase $this->assertEquals($high->id, $ordered[2]->id); } - /** @test */ + #[Test] public function it_can_be_triggered_on_purchase() { $user = User::factory()->create(); diff --git a/tests/Feature/ProductAttributeTest.php b/tests/Feature/ProductAttributeTest.php index 6fa4b88..b0f939a 100644 --- a/tests/Feature/ProductAttributeTest.php +++ b/tests/Feature/ProductAttributeTest.php @@ -6,12 +6,13 @@ use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductAttribute; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class ProductAttributeTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_create_a_product_attribute() { $product = Product::factory()->create(); @@ -30,7 +31,7 @@ class ProductAttributeTest extends TestCase ]); } - /** @test */ + #[Test] public function attribute_belongs_to_product() { $product = Product::factory()->create(); @@ -45,7 +46,7 @@ class ProductAttributeTest extends TestCase $this->assertEquals($product->id, $attribute->product->id); } - /** @test */ + #[Test] public function product_can_have_multiple_attributes() { $product = Product::factory()->create(); @@ -71,7 +72,7 @@ class ProductAttributeTest extends TestCase $this->assertCount(3, $product->fresh()->attributes); } - /** @test */ + #[Test] public function it_can_have_a_sort_order() { $product = Product::factory()->create(); @@ -98,7 +99,7 @@ class ProductAttributeTest extends TestCase $this->assertEquals($attr2->id, $attributes[1]->id); } - /** @test */ + #[Test] public function it_can_store_metadata() { $product = Product::factory()->create(); @@ -120,7 +121,7 @@ class ProductAttributeTest extends TestCase $this->assertEquals('cm', $unitAttr->value); } - /** @test */ + #[Test] public function it_can_update_attribute_value() { $product = Product::factory()->create(); @@ -136,7 +137,7 @@ class ProductAttributeTest extends TestCase $this->assertEquals('Out of Stock', $attribute->fresh()->value); } - /** @test */ + #[Test] public function deleting_product_deletes_attributes() { $product = Product::factory()->create(); @@ -154,7 +155,7 @@ class ProductAttributeTest extends TestCase $this->assertDatabaseMissing('product_attributes', ['id' => $attributeId]); } - /** @test */ + #[Test] public function it_can_filter_attributes_by_key() { $product = Product::factory()->create(); @@ -184,7 +185,7 @@ class ProductAttributeTest extends TestCase $this->assertCount(2, $colorAttributes); } - /** @test */ + #[Test] public function multiple_products_can_have_same_attribute_keys() { $product1 = Product::factory()->create(); @@ -208,7 +209,7 @@ class ProductAttributeTest extends TestCase $this->assertEquals('Brand B', $product2->attributes->first()->value); } - /** @test */ + #[Test] public function attributes_are_hidden_in_api_responses() { $product = Product::factory()->create(); diff --git a/tests/Feature/ProductCategoryTest.php b/tests/Feature/ProductCategoryTest.php index 12e752a..192f50a 100644 --- a/tests/Feature/ProductCategoryTest.php +++ b/tests/Feature/ProductCategoryTest.php @@ -6,12 +6,13 @@ use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductCategory; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class ProductCategoryTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_create_a_category() { $category = ProductCategory::factory()->create([ @@ -24,7 +25,7 @@ class ProductCategoryTest extends TestCase ]); } - /** @test */ + #[Test] public function it_automatically_generates_slug_from_name() { $category = ProductCategory::create([ @@ -34,7 +35,7 @@ class ProductCategoryTest extends TestCase $this->assertNotNull($category->slug); } - /** @test */ + #[Test] public function it_can_have_a_parent_category() { $parent = ProductCategory::factory()->create([ @@ -49,7 +50,7 @@ class ProductCategoryTest extends TestCase $this->assertEquals($parent->id, $child->parent->id); } - /** @test */ + #[Test] public function it_can_have_multiple_children() { $parent = ProductCategory::factory()->create(); @@ -61,7 +62,7 @@ class ProductCategoryTest extends TestCase $this->assertCount(3, $parent->fresh()->children); } - /** @test */ + #[Test] public function it_can_attach_products_to_category() { $category = ProductCategory::factory()->create(); @@ -75,7 +76,7 @@ class ProductCategoryTest extends TestCase $this->assertTrue($category->products->contains($product2)); } - /** @test */ + #[Test] public function it_can_count_products_in_category() { $category = ProductCategory::factory()->create(); @@ -88,7 +89,7 @@ class ProductCategoryTest extends TestCase $this->assertEquals(3, $category->products()->count()); } - /** @test */ + #[Test] public function it_can_check_visibility() { $visibleCategory = ProductCategory::factory()->create([ @@ -103,7 +104,7 @@ class ProductCategoryTest extends TestCase $this->assertFalse($hiddenCategory->is_visible); } - /** @test */ + #[Test] public function it_can_have_a_sort_order() { $category1 = ProductCategory::factory()->create(['sort_order' => 1]); @@ -117,7 +118,7 @@ class ProductCategoryTest extends TestCase $this->assertEquals($category3->id, $sorted[2]->id); } - /** @test */ + #[Test] public function it_can_store_meta_data() { $category = ProductCategory::factory()->create([ @@ -131,7 +132,7 @@ class ProductCategoryTest extends TestCase $this->assertEquals(['test', 'category'], $category->meta->keywords); } - /** @test */ + #[Test] public function product_can_belong_to_multiple_categories() { $product = Product::factory()->create(); @@ -144,7 +145,7 @@ class ProductCategoryTest extends TestCase $this->assertCount(3, $product->fresh()->categories); } - /** @test */ + #[Test] public function it_can_get_all_products_from_category_hierarchy() { $parent = ProductCategory::factory()->create(); @@ -160,7 +161,7 @@ class ProductCategoryTest extends TestCase $this->assertCount(1, $child->products); } - /** @test */ + #[Test] public function it_can_detach_products_from_category() { $category = ProductCategory::factory()->create(); @@ -173,7 +174,7 @@ class ProductCategoryTest extends TestCase $this->assertCount(0, $category->fresh()->products); } - /** @test */ + #[Test] public function deleting_category_does_not_delete_products() { $category = ProductCategory::factory()->create(); @@ -187,7 +188,7 @@ class ProductCategoryTest extends TestCase $this->assertDatabaseHas('products', ['id' => $productId]); } - /** @test */ + #[Test] public function it_can_scope_visible_categories() { ProductCategory::factory()->create(['is_visible' => true]); @@ -199,7 +200,7 @@ class ProductCategoryTest extends TestCase $this->assertCount(2, $visible); } - /** @test */ + #[Test] public function it_can_get_root_categories() { $root1 = ProductCategory::factory()->create(['parent_id' => null]); @@ -214,7 +215,7 @@ class ProductCategoryTest extends TestCase $this->assertFalse($roots->contains($child)); } - /** @test */ + #[Test] public function it_maintains_category_hierarchy_integrity() { $grandparent = ProductCategory::factory()->create(); @@ -226,7 +227,7 @@ class ProductCategoryTest extends TestCase $this->assertNull($grandparent->parent); } - /** @test */ + #[Test] public function it_can_filter_products_by_category_using_instance() { $category1 = ProductCategory::factory()->create(); @@ -248,7 +249,7 @@ class ProductCategoryTest extends TestCase $this->assertFalse($results->contains($product3)); } - /** @test */ + #[Test] public function it_can_filter_products_by_category_using_id_string() { $category = ProductCategory::factory()->create(); @@ -268,7 +269,7 @@ class ProductCategoryTest extends TestCase $this->assertFalse($results->contains($product3)); } - /** @test */ + #[Test] public function it_can_filter_products_by_multiple_categories() { $category1 = ProductCategory::factory()->create(); @@ -299,7 +300,7 @@ class ProductCategoryTest extends TestCase $this->assertFalse($results->contains($product4)); } - /** @test */ + #[Test] public function it_can_filter_products_without_specific_category() { $category1 = ProductCategory::factory()->create(); @@ -321,7 +322,7 @@ class ProductCategoryTest extends TestCase $this->assertTrue($results->contains($product3)); } - /** @test */ + #[Test] public function it_can_filter_products_without_category_using_instance() { $category = ProductCategory::factory()->create(); @@ -338,7 +339,7 @@ class ProductCategoryTest extends TestCase $this->assertTrue($results->contains($product2)); } - /** @test */ + #[Test] public function it_can_filter_products_without_multiple_categories() { $category1 = ProductCategory::factory()->create(); @@ -368,7 +369,7 @@ class ProductCategoryTest extends TestCase $this->assertTrue($results->contains($product4)); } - /** @test */ + #[Test] public function it_can_assign_a_category_to_product() { $product = Product::factory()->create(); @@ -380,7 +381,7 @@ class ProductCategoryTest extends TestCase $this->assertTrue($product->categories->contains($category)); } - /** @test */ + #[Test] public function it_can_assign_multiple_categories_to_product() { $product = Product::factory()->create(); @@ -396,7 +397,7 @@ class ProductCategoryTest extends TestCase $this->assertTrue($product->categories->contains($category3)); } - /** @test */ + #[Test] public function it_can_remove_a_category_from_product() { $product = Product::factory()->create(); @@ -413,7 +414,7 @@ class ProductCategoryTest extends TestCase $this->assertTrue($product->categories->contains($category2)); } - /** @test */ + #[Test] public function it_can_remove_multiple_categories_from_product() { $product = Product::factory()->create(); @@ -432,7 +433,7 @@ class ProductCategoryTest extends TestCase $this->assertTrue($product->categories->contains($category3)); } - /** @test */ + #[Test] public function it_can_sync_categories_on_product() { $product = Product::factory()->create(); @@ -453,7 +454,7 @@ class ProductCategoryTest extends TestCase $this->assertTrue($product->categories->contains($category3)); } - /** @test */ + #[Test] public function it_can_assign_category_by_name() { $product = Product::factory()->create(); @@ -465,7 +466,7 @@ class ProductCategoryTest extends TestCase $this->assertEquals('Electronics', $category->name); } - /** @test */ + #[Test] public function it_can_assign_category_by_name_without_creating_duplicates() { $product1 = Product::factory()->create(); @@ -477,7 +478,7 @@ class ProductCategoryTest extends TestCase $this->assertCount(1, ProductCategory::where('name', 'Electronics')->get()); } - /** @test */ + #[Test] public function it_can_assign_multiple_categories_by_names() { $product = Product::factory()->create(); @@ -491,7 +492,7 @@ class ProductCategoryTest extends TestCase $this->assertContains('Accessories', $categoryNames); } - /** @test */ + #[Test] public function it_can_assign_category_by_slug() { $product = Product::factory()->create(); @@ -503,7 +504,7 @@ class ProductCategoryTest extends TestCase $this->assertEquals('electronics', $category->slug); } - /** @test */ + #[Test] public function it_can_assign_category_by_slug_without_creating_duplicates() { $product1 = Product::factory()->create(); @@ -515,7 +516,7 @@ class ProductCategoryTest extends TestCase $this->assertCount(1, ProductCategory::where('slug', 'electronics')->get()); } - /** @test */ + #[Test] public function it_can_assign_multiple_categories_by_slugs() { $product = Product::factory()->create(); diff --git a/tests/Feature/ProductManagementTest.php b/tests/Feature/ProductManagementTest.php index aa49fea..e38b083 100644 --- a/tests/Feature/ProductManagementTest.php +++ b/tests/Feature/ProductManagementTest.php @@ -11,12 +11,13 @@ use Blax\Shop\Models\ProductAttribute; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class ProductManagementTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_create_a_product() { $product = Product::factory() @@ -35,7 +36,7 @@ class ProductManagementTest extends TestCase $this->assertEquals(99.99, $product->prices->first()->unit_amount); } - /** @test */ + #[Test] public function it_automatically_generates_slug_if_not_provided() { $product = Product::factory()->create(['slug' => null]); @@ -44,7 +45,7 @@ class ProductManagementTest extends TestCase $this->assertStringStartsWith('new-product-', $product->slug); } - /** @test */ + #[Test] public function it_can_manage_stock() { $product = Product::factory()->create([ @@ -58,7 +59,7 @@ class ProductManagementTest extends TestCase $this->assertEquals(55, $product->AvailableStocks); } - /** @test */ + #[Test] public function it_cannot_decrease_stock_below_zero() { $product = Product::factory()->create([ @@ -70,7 +71,7 @@ class ProductManagementTest extends TestCase }, \Blax\Shop\Exceptions\NotEnoughStockException::class); } - /** @test */ + #[Test] public function it_returns_available_stock() { $product = Product::factory()->create([ @@ -82,7 +83,7 @@ class ProductManagementTest extends TestCase $this->assertEquals(20, $product->getAvailableStock()); } - /** @test */ + #[Test] public function it_can_check_if_in_stock() { $productInStock = Product::factory()->create([ @@ -98,7 +99,7 @@ class ProductManagementTest extends TestCase $this->assertFalse($productOutOfStock->isInStock()); } - /** @test */ + #[Test] public function it_can_attach_categories() { $product = Product::factory()->create(); @@ -109,7 +110,7 @@ class ProductManagementTest extends TestCase $this->assertTrue($product->categories->contains($category)); } - /** @test */ + #[Test] public function it_can_have_attributes() { $product = Product::factory()->create(); @@ -125,7 +126,7 @@ class ProductManagementTest extends TestCase $this->assertEquals('Blue', $product->attributes->first()->value); } - /** @test */ + #[Test] public function it_can_have_multiple_prices() { $product = Product::factory()->create(); @@ -152,7 +153,7 @@ class ProductManagementTest extends TestCase $this->assertCount(2, $product->prices); } - /** @test */ + #[Test] public function it_can_have_related_products() { $product = Product::factory()->create(); @@ -165,7 +166,7 @@ class ProductManagementTest extends TestCase $this->assertTrue($product->relatedProducts()->get()->contains($relatedProduct)); } - /** @test */ + #[Test] public function it_can_have_upsell_products() { $product = Product::factory()->create(); @@ -178,7 +179,7 @@ class ProductManagementTest extends TestCase $this->assertTrue($product->upsellProducts()->get()->contains($upsellProduct)); } - /** @test */ + #[Test] public function it_can_have_cross_sell_products() { $product = Product::factory()->create(); @@ -191,7 +192,7 @@ class ProductManagementTest extends TestCase $this->assertTrue($product->crossSellProducts()->get()->contains($crossSellProduct)); } - /** @test */ + #[Test] public function it_can_scope_published_products() { Product::factory()->create(['status' => 'published']); @@ -203,7 +204,7 @@ class ProductManagementTest extends TestCase $this->assertEquals(ProductStatus::PUBLISHED, $published->first()->status); } - /** @test */ + #[Test] public function it_can_scope_in_stock_products() { Product::factory()->create([ @@ -223,7 +224,7 @@ class ProductManagementTest extends TestCase $this->assertTrue((bool) ($inStock->reverse()->first()->isInStock())); } - /** @test */ + #[Test] public function it_can_scope_visible_products() { Product::factory()->create([ @@ -242,7 +243,7 @@ class ProductManagementTest extends TestCase $this->assertTrue($visible->first()->is_visible); } - /** @test */ + #[Test] public function it_can_have_parent_child_relationships() { $parent = Product::factory()->create([ @@ -258,7 +259,7 @@ class ProductManagementTest extends TestCase $this->assertEquals($parent->id, $child->parent->id); } - /** @test */ + #[Test] public function it_validates_virtual_and_downloadable_flags() { $virtualProduct = Product::factory()->create([ @@ -277,7 +278,7 @@ class ProductManagementTest extends TestCase $this->assertFalse($downloadableProduct->virtual); } - /** @test */ + #[Test] public function it_can_check_featured_status() { $featured = Product::factory()->create(['featured' => true]); diff --git a/tests/Feature/ProductPriceTest.php b/tests/Feature/ProductPriceTest.php index 6c0443f..b4c0d5a 100644 --- a/tests/Feature/ProductPriceTest.php +++ b/tests/Feature/ProductPriceTest.php @@ -9,12 +9,13 @@ use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class ProductPriceTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_create_a_product_price() { $product = Product::factory()->create(); @@ -35,7 +36,7 @@ class ProductPriceTest extends TestCase ]); } - /** @test */ + #[Test] public function price_belongs_to_purchasable() { $product = Product::factory()->create(); @@ -51,7 +52,7 @@ class ProductPriceTest extends TestCase $this->assertEquals($product->id, $price->purchasable->id); } - /** @test */ + #[Test] public function it_can_set_default_price() { $product = Product::factory()->create(); @@ -77,7 +78,7 @@ class ProductPriceTest extends TestCase $this->assertEquals($price2->id, $product->defaultPrice()->first()->id); } - /** @test */ + #[Test] public function it_can_set_recurring_price() { $product = Product::factory()->create(); @@ -99,7 +100,7 @@ class ProductPriceTest extends TestCase $this->assertEquals(14, $price->trial_period_days); } - /** @test */ + #[Test] public function it_can_set_one_time_price() { $product = Product::factory()->create(); @@ -116,7 +117,7 @@ class ProductPriceTest extends TestCase $this->assertNull($price->interval); } - /** @test */ + #[Test] public function it_can_scope_active_prices() { $product = Product::factory()->create(); @@ -143,7 +144,7 @@ class ProductPriceTest extends TestCase $this->assertTrue($activePrices->first()->active); } - /** @test */ + #[Test] public function it_returns_current_price_based_on_sale() { $product = Product::factory()->create(); @@ -160,7 +161,7 @@ class ProductPriceTest extends TestCase $this->assertEquals(100.00, $price->getCurrentPrice(false)); } - /** @test */ + #[Test] public function it_can_have_multiple_currencies() { $product = Product::factory()->create(); @@ -184,7 +185,7 @@ class ProductPriceTest extends TestCase $this->assertEquals('EUR', $eurPrice->currency); } - /** @test */ + #[Test] public function it_can_store_price_metadata() { $product = Product::factory()->create(); @@ -204,7 +205,7 @@ class ProductPriceTest extends TestCase $this->assertEquals(['feature1', 'feature2'], $price->meta->features); } - /** @test */ + #[Test] public function it_can_deactivate_price() { $product = Product::factory()->create(); @@ -224,7 +225,7 @@ class ProductPriceTest extends TestCase $this->assertFalse($price->fresh()->active); } - /** @test */ + #[Test] public function product_can_have_multiple_price_tiers() { $product = Product::factory()->create(); @@ -256,7 +257,7 @@ class ProductPriceTest extends TestCase $this->assertCount(3, $product->prices); } - /** @test */ + #[Test] public function it_can_set_billing_scheme() { $product = Product::factory()->create(); diff --git a/tests/Feature/ProductPricingValidationTest.php b/tests/Feature/ProductPricingValidationTest.php index b4b8520..411a368 100644 --- a/tests/Feature/ProductPricingValidationTest.php +++ b/tests/Feature/ProductPricingValidationTest.php @@ -11,6 +11,7 @@ use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class ProductPricingValidationTest extends TestCase { @@ -25,7 +26,7 @@ class ProductPricingValidationTest extends TestCase auth()->login($this->user); } - /** @test */ + #[Test] public function it_throws_exception_when_product_has_no_prices() { $product = Product::factory()->create([ @@ -39,7 +40,7 @@ class ProductPricingValidationTest extends TestCase Cart::add($product, 1); } - /** @test */ + #[Test] public function it_throws_exception_when_product_has_multiple_prices_but_no_default() { $product = Product::factory()->create([ @@ -68,7 +69,7 @@ class ProductPricingValidationTest extends TestCase Cart::add($product, 1); } - /** @test */ + #[Test] public function it_throws_exception_when_product_has_single_price_not_marked_as_default() { $product = Product::factory()->create([ @@ -89,7 +90,7 @@ class ProductPricingValidationTest extends TestCase Cart::add($product, 1); } - /** @test */ + #[Test] public function it_throws_exception_when_product_has_multiple_default_prices() { $product = Product::factory()->create([ @@ -125,7 +126,7 @@ class ProductPricingValidationTest extends TestCase Cart::add($product, 1); } - /** @test */ + #[Test] public function it_allows_adding_product_with_valid_default_price() { $product = Product::factory()->create([ @@ -148,7 +149,7 @@ class ProductPricingValidationTest extends TestCase $this->assertEquals($product->id, $cartItem->purchasable_id); } - /** @test */ + #[Test] public function it_allows_product_with_one_default_and_multiple_non_default_prices() { $product = Product::factory()->create([ @@ -187,7 +188,7 @@ class ProductPricingValidationTest extends TestCase $this->assertEquals($product->id, $cartItem->purchasable_id); } - /** @test */ + #[Test] public function it_throws_exception_when_pool_has_no_price_and_single_items_have_no_prices() { $pool = Product::factory()->create([ @@ -213,7 +214,7 @@ class ProductPricingValidationTest extends TestCase Cart::add($pool, 1); } - /** @test */ + #[Test] public function it_allows_pool_with_no_direct_price_but_single_items_have_prices() { $pool = Product::factory()->create([ @@ -246,7 +247,7 @@ class ProductPricingValidationTest extends TestCase $this->assertEquals($pool->id, $cartItem->purchasable_id); } - /** @test */ + #[Test] public function it_allows_pool_with_direct_price_even_if_single_items_have_no_prices() { $pool = Product::factory()->create([ @@ -279,7 +280,7 @@ class ProductPricingValidationTest extends TestCase $this->assertEquals($pool->id, $cartItem->purchasable_id); } - /** @test */ + #[Test] public function validate_pricing_returns_errors_array_without_throwing() { $product = Product::factory()->create([ @@ -294,7 +295,7 @@ class ProductPricingValidationTest extends TestCase $this->assertStringContainsString('no prices', $result['errors'][0]); } - /** @test */ + #[Test] public function validate_pricing_with_valid_price_returns_valid() { $product = Product::factory()->create([ diff --git a/tests/Feature/ProductPurchaseTest.php b/tests/Feature/ProductPurchaseTest.php index f39423b..0862b0b 100644 --- a/tests/Feature/ProductPurchaseTest.php +++ b/tests/Feature/ProductPurchaseTest.php @@ -8,12 +8,13 @@ use Blax\Shop\Models\ProductPurchase; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class ProductPurchaseTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_create_a_purchase() { $user = User::factory()->create(); @@ -38,7 +39,7 @@ class ProductPurchaseTest extends TestCase ]); } - /** @test */ + #[Test] public function purchase_belongs_to_purchaser() { $user = User::factory()->create(); @@ -60,7 +61,7 @@ class ProductPurchaseTest extends TestCase $this->assertEquals($user->id, $purchase->purchaser->id); } - /** @test */ + #[Test] public function purchase_belongs_to_purchasable() { $user = User::factory()->create(); @@ -82,7 +83,7 @@ class ProductPurchaseTest extends TestCase $this->assertEquals($product->id, $purchase->purchasable->id); } - /** @test */ + #[Test] public function it_can_have_different_statuses() { $user = User::factory()->create(); @@ -114,7 +115,7 @@ class ProductPurchaseTest extends TestCase $this->assertEquals(PurchaseStatus::COMPLETED, $completedPurchase->status); } - /** @test */ + #[Test] public function it_can_scope_completed_purchases() { $user = User::factory()->create(); @@ -148,7 +149,7 @@ class ProductPurchaseTest extends TestCase $this->assertEquals(PurchaseStatus::COMPLETED, $completed->first()->status); } - /** @test */ + #[Test] public function it_can_scope_cart_purchases() { $user = User::factory()->create(); @@ -182,7 +183,7 @@ class ProductPurchaseTest extends TestCase $this->assertEquals(PurchaseStatus::CART, $inCart->first()->status); } - /** @test */ + #[Test] public function it_can_store_purchase_metadata() { $user = User::factory()->create(); @@ -208,7 +209,7 @@ class ProductPurchaseTest extends TestCase $this->assertEquals('Mozilla/5.0', $purchase->meta->user_agent); } - /** @test */ + #[Test] public function it_can_track_amount_paid() { $user = User::factory()->create(); @@ -239,7 +240,7 @@ class ProductPurchaseTest extends TestCase $this->assertEquals(PurchaseStatus::COMPLETED, $purchase->fresh()->status); } - /** @test */ + #[Test] public function it_can_store_charge_id() { $user = User::factory()->create(); @@ -261,7 +262,7 @@ class ProductPurchaseTest extends TestCase $this->assertEquals('ch_123456789', $purchase->charge_id); } - /** @test */ + #[Test] public function it_tracks_purchase_quantity() { $user = User::factory()->create(); @@ -283,7 +284,7 @@ class ProductPurchaseTest extends TestCase $this->assertEquals(25000, $purchase->amount); } - /** @test */ + #[Test] public function user_can_have_multiple_purchases() { $user = User::factory()->create(); @@ -313,7 +314,7 @@ class ProductPurchaseTest extends TestCase $this->assertCount(2, $user->purchases); } - /** @test */ + #[Test] public function product_can_have_multiple_purchases() { $user1 = User::factory()->create(); diff --git a/tests/Feature/ProductScopeTest.php b/tests/Feature/ProductScopeTest.php index d4b5a39..824bd1d 100644 --- a/tests/Feature/ProductScopeTest.php +++ b/tests/Feature/ProductScopeTest.php @@ -7,12 +7,13 @@ use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductCategory; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class ProductScopeTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_scope_by_category() { $category1 = ProductCategory::factory()->create(); @@ -33,7 +34,7 @@ class ProductScopeTest extends TestCase $this->assertTrue($productsInCategory1->contains($product2)); } - /** @test */ + #[Test] public function it_can_search_products_by_slug() { Product::factory()->create(['slug' => 'awesome-product']); @@ -45,7 +46,7 @@ class ProductScopeTest extends TestCase $this->assertCount(2, $results); } - /** @test */ + #[Test] public function it_can_search_products_by_sku() { Product::factory()->create(['sku' => 'SKU-001']); @@ -57,7 +58,7 @@ class ProductScopeTest extends TestCase $this->assertCount(2, $results); } - /** @test */ + #[Test] public function it_can_filter_by_price_range() { $product1 = Product::factory()->withPrices(1, 50)->create(); @@ -70,7 +71,7 @@ class ProductScopeTest extends TestCase $this->assertTrue($inRange->contains($product2)); } - /** @test */ + #[Test] public function it_can_filter_by_minimum_price_only() { $product1 = Product::factory()->withPrices(1, 50)->create(); @@ -84,7 +85,7 @@ class ProductScopeTest extends TestCase $this->assertTrue($minPrice->contains($product3)); } - /** @test */ + #[Test] public function it_can_filter_by_maximum_price_only() { $product1 = Product::factory()->withPrices(1, 50)->create(); @@ -98,7 +99,7 @@ class ProductScopeTest extends TestCase $this->assertTrue($maxPrice->contains($product2)); } - /** @test */ + #[Test] public function it_can_order_products_by_price_ascending() { $product1 = Product::factory()->withPrices(1, 150)->create(['name' => 'Expensive']); @@ -111,7 +112,7 @@ class ProductScopeTest extends TestCase $this->assertEquals($product1->id, $ordered->last()->id); } - /** @test */ + #[Test] public function it_can_order_products_by_price_descending() { $product1 = Product::factory()->withPrices(1, 150)->create(['name' => 'Expensive']); @@ -124,7 +125,7 @@ class ProductScopeTest extends TestCase $this->assertEquals($product2->id, $ordered->last()->id); } - /** @test */ + #[Test] public function it_can_combine_price_range_and_order_by_price() { $product1 = Product::factory()->withPrices(1, 50)->create(); @@ -139,7 +140,7 @@ class ProductScopeTest extends TestCase $this->assertEquals($product3->id, $filtered->last()->id); } - /** @test */ + #[Test] public function it_can_scope_low_stock_products() { $lowStockProduct = Product::factory()->create([ @@ -160,7 +161,7 @@ class ProductScopeTest extends TestCase $this->assertFalse($lowStock->contains($normalStockProduct)); } - /** @test */ + #[Test] public function it_can_scope_featured_products() { Product::factory()->create(['featured' => true]); @@ -173,7 +174,7 @@ class ProductScopeTest extends TestCase $this->assertTrue($featured->every(fn($p) => $p->featured === true)); } - /** @test */ + #[Test] public function visible_scope_excludes_unpublished_products() { Product::factory()->create([ @@ -196,7 +197,7 @@ class ProductScopeTest extends TestCase $this->assertCount(1, $visible); } - /** @test */ + #[Test] public function visible_scope_respects_published_at_date() { Product::factory()->create([ @@ -216,7 +217,7 @@ class ProductScopeTest extends TestCase $this->assertCount(1, $visible); } - /** @test */ + #[Test] public function in_stock_scope_includes_products_without_stock_management() { Product::factory()->create(['manage_stock' => false]); @@ -229,7 +230,7 @@ class ProductScopeTest extends TestCase $this->assertGreaterThanOrEqual(2, $inStock->count()); } - /** @test */ + #[Test] public function in_stock_scope_excludes_out_of_stock_products() { $outOfStock = Product::factory()->create(['manage_stock' => true]); @@ -243,7 +244,7 @@ class ProductScopeTest extends TestCase $this->assertTrue($products->contains($inStock)); } - /** @test */ + #[Test] public function it_can_combine_multiple_scopes() { Product::factory()->create([ @@ -273,7 +274,7 @@ class ProductScopeTest extends TestCase $this->assertCount(1, $products); } - /** @test */ + #[Test] public function it_can_scope_products_by_type() { Product::factory()->create(['type' => ProductType::SIMPLE]); @@ -286,7 +287,7 @@ class ProductScopeTest extends TestCase $this->assertCount(2, $simpleProducts); } - /** @test */ + #[Test] public function it_can_scope_downloadable_products() { Product::factory()->create(['downloadable' => true]); @@ -298,7 +299,7 @@ class ProductScopeTest extends TestCase $this->assertCount(2, $downloadable); } - /** @test */ + #[Test] public function it_can_scope_virtual_products() { Product::factory()->create(['virtual' => true]); diff --git a/tests/Feature/ProductStockTest.php b/tests/Feature/ProductStockTest.php index e4890b3..b1fccd0 100644 --- a/tests/Feature/ProductStockTest.php +++ b/tests/Feature/ProductStockTest.php @@ -9,12 +9,13 @@ use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductStock; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class ProductStockTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_creates_stock_record_on_increase() { $product = Product::factory()->create(['manage_stock' => true]); @@ -28,7 +29,7 @@ class ProductStockTest extends TestCase ]); } - /** @test */ + #[Test] public function it_creates_stock_record_on_decrease() { $product = Product::factory()->create(['manage_stock' => true]); @@ -43,7 +44,7 @@ class ProductStockTest extends TestCase ]); } - /** @test */ + #[Test] public function stock_belongs_to_product() { $product = Product::factory()->create(['manage_stock' => true]); @@ -55,7 +56,7 @@ class ProductStockTest extends TestCase $this->assertEquals($product->id, $stock->product->id); } - /** @test */ + #[Test] public function product_has_many_stock_records() { $product = Product::factory()->create(['manage_stock' => true]); @@ -67,7 +68,7 @@ class ProductStockTest extends TestCase $this->assertCount(3, $product->stocks); } - /** @test */ + #[Test] public function available_stock_considers_all_records() { $product = Product::factory()->create(['manage_stock' => true]); @@ -79,7 +80,7 @@ class ProductStockTest extends TestCase $this->assertEquals(60, $product->getAvailableStock()); } - /** @test */ + #[Test] public function claim_reduces_available_stock() { $product = Product::factory()->withStocks(100)->create(); @@ -90,7 +91,7 @@ class ProductStockTest extends TestCase $this->assertNotNull($claim); } - /** @test */ + #[Test] public function releasing_claim_increases_available_stock() { $product = Product::factory()->withStocks(100)->create(); @@ -103,7 +104,7 @@ class ProductStockTest extends TestCase $this->assertEquals(100, $product->refresh()->getAvailableStock()); } - /** @test */ + #[Test] public function permanent_claim_has_no_expiry() { $product = Product::factory()->withStocks(50)->create(); @@ -114,7 +115,7 @@ class ProductStockTest extends TestCase $this->assertTrue($claim->isPermanent()); } - /** @test */ + #[Test] public function temporary_claim_has_expiry() { $product = Product::factory()->withStocks(50)->create(); @@ -128,7 +129,7 @@ class ProductStockTest extends TestCase $this->assertTrue($claim->isTemporary()); } - /** @test */ + #[Test] public function claim_can_have_note() { $product = Product::factory()->withStocks(50)->create(); @@ -142,7 +143,7 @@ class ProductStockTest extends TestCase $this->assertEquals($note, $claim->note); } - /** @test */ + #[Test] public function cannot_claim_more_than_available() { $product = Product::factory()->withStocks(10)->create(); @@ -152,7 +153,7 @@ class ProductStockTest extends TestCase $product->claimStock(15); } - /** @test */ + #[Test] public function pending_scope_returns_unreleased_claims() { $product = Product::factory()->withStocks(100)->create(); @@ -167,7 +168,7 @@ class ProductStockTest extends TestCase $this->assertFalse($pendingClaims->contains($released)); } - /** @test */ + #[Test] public function released_scope_returns_released_claims() { $product = Product::factory()->withStocks(100)->create(); @@ -182,7 +183,7 @@ class ProductStockTest extends TestCase $this->assertTrue($releasedClaims->contains($released)); } - /** @test */ + #[Test] public function expired_claims_dont_affect_available_stock() { $product = Product::factory()->withStocks(100)->create(); @@ -198,7 +199,7 @@ class ProductStockTest extends TestCase $this->assertEquals(0, $available->count()); } - /** @test */ + #[Test] public function cannot_release_stock_twice() { $product = Product::factory()->withStocks(50)->create(); @@ -209,7 +210,7 @@ class ProductStockTest extends TestCase $this->assertFalse($claim->release()); } - /** @test */ + #[Test] public function stock_status_is_tracked() { $product = Product::factory()->create(['manage_stock' => true]); @@ -221,7 +222,7 @@ class ProductStockTest extends TestCase $this->assertEquals(StockStatus::COMPLETED, $stock->status); } - /** @test */ + #[Test] public function product_without_stock_management_returns_max_stock() { $product = Product::factory()->create(['manage_stock' => false]); @@ -231,7 +232,7 @@ class ProductStockTest extends TestCase $this->assertEquals(PHP_INT_MAX, $available); } - /** @test */ + #[Test] public function product_without_stock_management_doesnt_create_records() { $product = Product::factory()->create(['manage_stock' => false]); @@ -242,7 +243,7 @@ class ProductStockTest extends TestCase $this->assertCount(0, $product->stocks); } - /** @test */ + #[Test] public function claim_without_stock_management_returns_null() { $product = Product::factory()->create(['manage_stock' => false]); @@ -252,7 +253,7 @@ class ProductStockTest extends TestCase $this->assertNull($claim); } - /** @test */ + #[Test] public function available_stocks_attribute_accessor_works() { $product = Product::factory()->create(['manage_stock' => true]); @@ -263,7 +264,7 @@ class ProductStockTest extends TestCase $this->assertEquals(40, $product->AvailableStocks); } - /** @test */ + #[Test] public function claims_method_filters_active_only() { $product = Product::factory()->withStocks(100)->create(); @@ -277,7 +278,7 @@ class ProductStockTest extends TestCase $this->assertEquals($active->id, $claims->first()->id); } - /** @test */ + #[Test] public function can_adjust_stock() { $product = Product::factory()->create(['manage_stock' => true]); @@ -314,7 +315,7 @@ class ProductStockTest extends TestCase $this->assertEquals(25, $product->getAvailableStock()); } - /** @test */ + #[Test] public function it_can_claim_stock_with_claimed_from_date() { $product = Product::factory()->withStocks(100)->create(); @@ -333,7 +334,7 @@ class ProductStockTest extends TestCase $this->assertEquals($until->format('Y-m-d H:i:s'), $claim->expires_at->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_can_check_available_stock_on_a_date() { $product = Product::factory()->withStocks(100)->create(); @@ -358,7 +359,7 @@ class ProductStockTest extends TestCase $this->assertEquals(100, $availableOnDay12); } - /** @test */ + #[Test] public function it_can_handle_multiple_overlapping_claims_on_date() { $product = Product::factory()->withStocks(100)->create(); @@ -394,7 +395,7 @@ class ProductStockTest extends TestCase $this->assertEquals(100, $availableOnDay20); } - /** @test */ + #[Test] public function it_handles_claims_without_claimed_from_as_immediately_claimed() { $product = Product::factory()->withStocks(100)->create(); @@ -418,7 +419,7 @@ class ProductStockTest extends TestCase $this->assertEquals(100, $availableOnDay12); } - /** @test */ + #[Test] public function it_handles_permanent_claims_without_expires_at() { $product = Product::factory()->withStocks(100)->create(); @@ -442,7 +443,7 @@ class ProductStockTest extends TestCase $this->assertEquals(60, $availableOnDay100); } - /** @test */ + #[Test] public function available_on_date_scope_filters_correctly() { $product = Product::factory()->withStocks(100)->create(); @@ -483,7 +484,7 @@ class ProductStockTest extends TestCase $this->assertEquals($claim2->id, $claimsOnDay12->first()->id); } - /** @test */ + #[Test] public function it_can_get_claimed_stock_amount() { $product = Product::factory()->withStocks(100)->create(); @@ -496,7 +497,7 @@ class ProductStockTest extends TestCase $this->assertEquals(40, $product->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function it_checks_if_claim_is_active() { $product = Product::factory()->withStocks(100)->create(); @@ -510,7 +511,7 @@ class ProductStockTest extends TestCase $this->assertFalse($claim->fresh()->isActive()); } - /** @test */ + #[Test] public function it_releases_expired_claims() { $product = Product::factory()->withStocks(100)->create(); @@ -535,7 +536,7 @@ class ProductStockTest extends TestCase $this->assertEquals(StockStatus::PENDING, $activeClaim->fresh()->status); } - /** @test */ + #[Test] public function it_has_reference_relationship() { $product = Product::factory()->withStocks(100)->create(); @@ -552,7 +553,7 @@ class ProductStockTest extends TestCase $this->assertEquals(get_class($user), $claim->reference_type); } - /** @test */ + #[Test] public function it_handles_return_stock_type() { $product = Product::factory()->create(['manage_stock' => true]); @@ -578,7 +579,7 @@ class ProductStockTest extends TestCase $this->assertEquals(5, $returnEntry->quantity); } - /** @test */ + #[Test] public function temporary_scope_filters_correctly() { $product = Product::factory()->withStocks(100)->create(); @@ -595,7 +596,7 @@ class ProductStockTest extends TestCase $this->assertFalse($permanentStocks->contains($temporary)); } - /** @test */ + #[Test] public function it_tracks_stock_with_custom_status() { $product = Product::factory()->create(['manage_stock' => true]); @@ -619,7 +620,7 @@ class ProductStockTest extends TestCase $this->assertEquals(50, $product->fresh()->getAvailableStock()); } - /** @test */ + #[Test] public function backward_compatibility_accessors_work() { $product = Product::factory()->withStocks(100)->create(); @@ -643,7 +644,7 @@ class ProductStockTest extends TestCase $this->assertEquals($claim->fresh()->updated_at->format('Y-m-d H:i:s'), $claim->fresh()->released_at->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function adjust_stock_increase_type_affects_available_stock_correctly() { $product = Product::factory()->create(['manage_stock' => true]); @@ -667,7 +668,7 @@ class ProductStockTest extends TestCase $this->assertEquals(80, $product->getAvailableStock()); } - /** @test */ + #[Test] public function adjust_stock_decrease_type_affects_available_stock_correctly() { $product = Product::factory()->withStocks(100)->create(); @@ -691,7 +692,7 @@ class ProductStockTest extends TestCase $this->assertEquals(65, $product->getAvailableStock()); } - /** @test */ + #[Test] public function adjust_stock_return_type_affects_available_stock_correctly() { $product = Product::factory()->withStocks(50)->create(); @@ -708,7 +709,7 @@ class ProductStockTest extends TestCase $this->assertEquals(48, $product->getAvailableStock()); } - /** @test */ + #[Test] public function adjust_stock_claimed_type_affects_available_and_claimed_stock_correctly() { $product = Product::factory()->withStocks(100)->create(); @@ -730,7 +731,7 @@ class ProductStockTest extends TestCase // Claimed stock shows the pending claim (always positive now) $this->assertEquals(25, $product->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function adjust_stock_with_until_parameter_expires_correctly() { $product = Product::factory()->withStocks(100)->create(); @@ -752,7 +753,7 @@ class ProductStockTest extends TestCase $this->assertEquals(100, $product->getAvailableStock()); } - /** @test */ + #[Test] public function adjust_stock_claimed_with_from_and_until_affects_availability_by_date() { $product = Product::factory()->withStocks(100)->create(); @@ -779,7 +780,7 @@ class ProductStockTest extends TestCase $availableOnDay12 = $product->availableOnDate(now()->addDays(12)); $this->assertEquals(100, $availableOnDay12); // After claim expires } - /** @test */ + #[Test] public function adjust_stock_multiple_claimed_types_accumulate_in_claimed_stock() { $product = Product::factory()->withStocks(200)->create(); @@ -806,7 +807,7 @@ class ProductStockTest extends TestCase // Total claimed stock (always positive) $this->assertEquals(70, $product->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function adjust_stock_claimed_with_completed_status_does_not_count_as_claimed() { $product = Product::factory()->withStocks(100)->create(); @@ -827,7 +828,7 @@ class ProductStockTest extends TestCase $this->assertEquals(0, $product->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function adjust_stock_with_mixed_types_calculates_correctly() { $product = Product::factory()->create(['manage_stock' => true]); @@ -859,7 +860,7 @@ class ProductStockTest extends TestCase $this->assertEquals(85, $product->getAvailableStock()); $this->assertEquals(30, $product->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function adjust_stock_claimed_without_from_is_immediately_active() { $product = Product::factory()->withStocks(100)->create(); @@ -883,7 +884,7 @@ class ProductStockTest extends TestCase $availableAfter = $product->availableOnDate(now()->addDays(11)); $this->assertEquals(100, $availableAfter); } - /** @test */ + #[Test] public function adjust_stock_claimed_without_until_is_permanent_claim() { $product = Product::factory()->withStocks(100)->create(); @@ -907,7 +908,7 @@ class ProductStockTest extends TestCase $availableOnDay100 = $product->availableOnDate(now()->addDays(100)); $this->assertEquals(65, $availableOnDay100); } - /** @test */ + #[Test] public function adjust_stock_with_overlapping_claimed_periods_calculates_correctly() { $product = Product::factory()->withStocks(100)->create(); @@ -970,7 +971,7 @@ class ProductStockTest extends TestCase $this->assertEquals(50, $product->getActiveAndPlannedClaimedStock()); $this->assertEquals(0, $product->getFutureClaimedStock()); } - /** @test */ + #[Test] public function adjust_stock_with_note_and_reference_tracks_correctly() { $product = Product::factory()->withStocks(100)->create(); @@ -996,7 +997,7 @@ class ProductStockTest extends TestCase $this->assertEquals(get_class($user), $claim->reference_type); } - /** @test */ + #[Test] public function adjust_stock_expired_claims_dont_affect_current_availability() { $product = Product::factory()->withStocks(100)->create(); @@ -1020,7 +1021,7 @@ class ProductStockTest extends TestCase $this->assertCount(0, $activeClaims); } - /** @test */ + #[Test] public function adjust_stock_releasing_claimed_updates_calculations() { $product = Product::factory()->withStocks(100)->create(); @@ -1049,7 +1050,7 @@ class ProductStockTest extends TestCase $this->assertEquals(100, $product->getAvailableStock()); } - /** @test */ + #[Test] public function stock_claim_creates_correct_transactions() { $product = Product::factory()->withStocks(100)->create(); @@ -1083,7 +1084,7 @@ class ProductStockTest extends TestCase $this->assertNotNull($claimedEntry->expires_at); } - /** @test */ + #[Test] public function claimed_stock_reduces_available_and_increases_claimed() { $product = Product::factory()->withStocks(100)->create(); @@ -1111,7 +1112,7 @@ class ProductStockTest extends TestCase $this->assertEquals(50, $product->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function expired_claims_automatically_restore_available_stock() { $product = Product::factory()->withStocks(100)->create(); @@ -1141,7 +1142,7 @@ class ProductStockTest extends TestCase // No manual release() was called! } - /** @test */ + #[Test] public function multiple_claims_with_different_expirations_restore_progressively() { $product = Product::factory()->withStocks(100)->create(); @@ -1169,7 +1170,7 @@ class ProductStockTest extends TestCase $this->assertEquals(0, $product->getCurrentlyClaimedStock()); // No claims } - /** @test */ + #[Test] public function permanent_claims_without_expiration_never_auto_restore() { $product = Product::factory()->withStocks(100)->create(); @@ -1201,7 +1202,7 @@ class ProductStockTest extends TestCase $this->assertEquals(0, $product->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function adjust_stock_claimed_also_auto_restores_after_expiration() { $product = Product::factory()->withStocks(100)->create(); @@ -1225,7 +1226,7 @@ class ProductStockTest extends TestCase $this->assertEquals(0, $product->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function claimed_stock_transactions_maintain_data_integrity() { $product = Product::factory()->withStocks(100)->create(); @@ -1270,7 +1271,7 @@ class ProductStockTest extends TestCase $this->assertEquals(35, $allClaimed); } - /** @test */ + #[Test] public function can_get_all_stocks_including_pending_and_expired() { $product = Product::factory()->withStocks(100)->create(); @@ -1314,7 +1315,7 @@ class ProductStockTest extends TestCase $this->assertEquals(0, $product->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function get_claimed_stock_returns_active_pending_claims_only() { $product = Product::factory()->withStocks(100)->create(); @@ -1340,7 +1341,7 @@ class ProductStockTest extends TestCase $this->assertCount(4, $allClaims); } - /** @test */ + #[Test] public function get_claimed_stock_excludes_released_claims() { $product = Product::factory()->withStocks(100)->create(); @@ -1364,7 +1365,7 @@ class ProductStockTest extends TestCase $this->assertEquals(0, $product->fresh()->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function get_claimed_stock_accounts_for_claim_expiration() { $product = Product::factory()->withStocks(200)->create(); @@ -1390,7 +1391,7 @@ class ProductStockTest extends TestCase $this->assertEquals(30, $product->fresh()->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function get_total_planned_claimed_stock_includes_future_claims() { $product = Product::factory()->withStocks(300)->create(); @@ -1413,7 +1414,7 @@ class ProductStockTest extends TestCase $this->assertEquals(25, $product->getCurrentlyClaimedStock()); } - /** @test */ + #[Test] public function get_total_planned_claimed_stock_excludes_expired_claims() { $product = Product::factory()->withStocks(200)->create(); @@ -1427,7 +1428,7 @@ class ProductStockTest extends TestCase $this->assertEquals(90, $product->getActiveAndPlannedClaimedStock()); } - /** @test */ + #[Test] public function get_total_planned_claimed_stock_excludes_released_claims() { $product = Product::factory()->withStocks(200)->create(); @@ -1452,7 +1453,7 @@ class ProductStockTest extends TestCase $this->assertEquals(25, $product->fresh()->getActiveAndPlannedClaimedStock()); } - /** @test */ + #[Test] public function get_future_claimed_stock_without_from_date_parameter() { $product = Product::factory()->withStocks(300)->create(); @@ -1480,7 +1481,7 @@ class ProductStockTest extends TestCase $this->assertEquals(0, $product->fresh()->getFutureClaimedStock()); } - /** @test */ + #[Test] public function get_future_claimed_stock_with_from_date_parameter() { $product = Product::factory()->withStocks(300)->create(); @@ -1504,7 +1505,7 @@ class ProductStockTest extends TestCase $this->assertEquals(0, $fromDay20); } - /** @test */ + #[Test] public function get_future_claimed_stock_excludes_expired_claims() { $product = Product::factory()->withStocks(300)->create(); @@ -1527,7 +1528,7 @@ class ProductStockTest extends TestCase $this->assertEquals(50, $product->fresh()->getFutureClaimedStock()); } - /** @test */ + #[Test] public function claimed_stock_methods_work_together() { $product = Product::factory()->withStocks(500)->create(); @@ -1559,7 +1560,7 @@ class ProductStockTest extends TestCase $this->assertEquals(115, $product->fresh()->getFutureClaimedStock()); // future ones unchanged } - /** @test */ + #[Test] public function claimed_stock_methods_return_zero_for_unmanaged_stock() { $product = Product::factory()->create(['manage_stock' => false]); diff --git a/tests/Feature/PurchaseFlowTest.php b/tests/Feature/PurchaseFlowTest.php index 9f53769..85678e9 100644 --- a/tests/Feature/PurchaseFlowTest.php +++ b/tests/Feature/PurchaseFlowTest.php @@ -6,18 +6,18 @@ use Blax\Shop\Enums\PurchaseStatus; use Blax\Shop\Exceptions\NotEnoughStockException; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPurchase; -use Blax\Shop\Models\ProductPrice; use Blax\Shop\Models\Cart; use Blax\Shop\Models\CartItem; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; +use PHPUnit\Framework\Attributes\Test; class PurchaseFlowTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function user_can_purchase_a_product_directly() { $user = User::factory()->create(); @@ -36,7 +36,7 @@ class PurchaseFlowTest extends TestCase $this->assertEquals(PurchaseStatus::UNPAID, $purchase->status); } - /** @test */ + #[Test] public function user_can_add_product_to_cart() { $user = User::factory()->create(); @@ -51,7 +51,7 @@ class PurchaseFlowTest extends TestCase $this->assertEquals($product->id, $cartItem->purchasable_id); } - /** @test */ + #[Test] public function user_can_get_cart_items() { $user = User::factory()->create(); @@ -69,7 +69,7 @@ class PurchaseFlowTest extends TestCase $this->assertCount(2, $cartItems); } - /** @test */ + #[Test] public function user_can_update_cart_item_quantity() { $user = User::factory()->create(); @@ -82,7 +82,7 @@ class PurchaseFlowTest extends TestCase $this->assertEquals(5, $cartItem->fresh()->quantity); } - /** @test */ + #[Test] public function user_can_remove_item_from_cart() { $user = User::factory()->create(); @@ -97,7 +97,7 @@ class PurchaseFlowTest extends TestCase $this->assertCount(0, $user->refresh()->cartItems); } - /** @test */ + #[Test] public function user_can_checkout_cart() { $user = User::factory()->create(); @@ -126,7 +126,7 @@ class PurchaseFlowTest extends TestCase $this->assertEquals(PurchaseStatus::UNPAID, $purchases[1]->status); } - /** @test */ + #[Test] public function user_can_get_cart_total() { $user = User::factory()->create(); @@ -144,7 +144,7 @@ class PurchaseFlowTest extends TestCase $this->assertEquals(140.00, $total); } - /** @test */ + #[Test] public function user_can_get_cart_items_count() { $user = User::factory()->create(); @@ -159,7 +159,7 @@ class PurchaseFlowTest extends TestCase $this->assertEquals(5, $count); } - /** @test */ + #[Test] public function user_can_clear_cart() { $user = User::factory()->create(); @@ -176,7 +176,7 @@ class PurchaseFlowTest extends TestCase $this->assertCount(0, $user->fresh()->cartItems); } - /** @test */ + #[Test] public function user_can_check_if_product_was_purchased() { $user = User::factory()->create(); @@ -191,7 +191,7 @@ class PurchaseFlowTest extends TestCase $this->assertFalse($user->hasPurchased($notPurchasedProduct)); } - /** @test */ + #[Test] public function user_can_get_completed_purchases() { $user = User::factory()->create(); @@ -208,7 +208,7 @@ class PurchaseFlowTest extends TestCase $this->assertCount(2, $completed); } - /** @test */ + #[Test] public function purchase_reduces_stock_when_managed() { $user = User::factory()->create(); @@ -220,7 +220,7 @@ class PurchaseFlowTest extends TestCase $this->assertEquals(7, $product->AvailableStocks); } - /** @test */ + #[Test] public function cannot_purchase_more_than_available_stock() { $user = User::factory()->create(); @@ -231,7 +231,7 @@ class PurchaseFlowTest extends TestCase $user->purchase($product, quantity: 10); } - /** @test */ + #[Test] public function adding_to_cart_checks_stock_availability() { $user = User::factory()->create(); @@ -240,7 +240,7 @@ class PurchaseFlowTest extends TestCase $this->assertThrows(fn() => $user->addToCart($product, quantity: 5), NotEnoughStockException::class); } - /** @test */ + #[Test] public function purchase_can_store_metadata() { $user = User::factory()->create(); @@ -254,7 +254,7 @@ class PurchaseFlowTest extends TestCase $this->assertEquals('Happy Birthday!', $purchase->meta->gift_message ?? null); } - /** @test */ + #[Test] public function purchase_can_be_associated_with_cart() { $user = User::factory()->create(); @@ -276,7 +276,7 @@ class PurchaseFlowTest extends TestCase $this->assertTrue($cart->purchases->contains($purchase)); } - /** @test */ + #[Test] public function checkout_marks_cart_as_converted() { $user = User::factory()->create(); @@ -294,7 +294,7 @@ class PurchaseFlowTest extends TestCase } } - /** @test */ + #[Test] public function user_cannot_add_out_of_stock_product_to_cart() { $user = User::factory()->create(); @@ -309,7 +309,7 @@ class PurchaseFlowTest extends TestCase $user->addToCart($product, quantity: 1); } - /** @test */ + #[Test] public function purchase_stores_amount_correctly() { $user = User::factory()->create(); @@ -324,7 +324,7 @@ class PurchaseFlowTest extends TestCase $this->assertGreaterThan(0, $purchase->amount); } - /** @test */ + #[Test] public function cart_total_is_correct_after_checkout() { $user = User::factory()->create(); diff --git a/tests/Feature/ShopFacadeTest.php b/tests/Feature/ShopFacadeTest.php index 153574f..8c74960 100644 --- a/tests/Feature/ShopFacadeTest.php +++ b/tests/Feature/ShopFacadeTest.php @@ -7,12 +7,13 @@ use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductCategory; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class ShopFacadeTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_get_all_products() { Product::factory()->create(); @@ -24,7 +25,7 @@ class ShopFacadeTest extends TestCase $this->assertCount(3, $products); } - /** @test */ + #[Test] public function it_can_get_a_single_product_by_id() { $product = Product::factory()->create(); @@ -35,7 +36,7 @@ class ShopFacadeTest extends TestCase $this->assertEquals($product->id, $foundProduct->id); } - /** @test */ + #[Test] public function it_returns_null_for_nonexistent_product() { $product = Shop::product(999); @@ -43,7 +44,7 @@ class ShopFacadeTest extends TestCase $this->assertNull($product); } - /** @test */ + #[Test] public function it_can_get_all_categories() { ProductCategory::factory()->create(); @@ -54,7 +55,7 @@ class ShopFacadeTest extends TestCase $this->assertCount(2, $categories); } - /** @test */ + #[Test] public function it_can_get_in_stock_products() { Product::factory()->withStocks()->create(); @@ -66,7 +67,7 @@ class ShopFacadeTest extends TestCase $this->assertGreaterThanOrEqual(2, $inStockProducts->count()); } - /** @test */ + #[Test] public function it_can_get_featured_products() { Product::factory()->create(['featured' => true]); @@ -78,7 +79,7 @@ class ShopFacadeTest extends TestCase $this->assertCount(2, $featured); } - /** @test */ + #[Test] public function it_can_get_published_and_visible_products() { Product::factory()->create(['status' => 'published', 'is_visible' => true]); @@ -90,7 +91,7 @@ class ShopFacadeTest extends TestCase $this->assertGreaterThanOrEqual(1, $published->count()); } - /** @test */ + #[Test] public function it_can_search_products_by_name() { Product::factory()->create(); @@ -103,7 +104,7 @@ class ShopFacadeTest extends TestCase $this->assertGreaterThanOrEqual(1, $results->count()); } - /** @test */ + #[Test] public function it_can_search_products_by_description() { Product::factory()->count(2)->create(); @@ -114,7 +115,7 @@ class ShopFacadeTest extends TestCase $this->assertIsObject($results); } - /** @test */ + #[Test] public function it_can_check_stock_availability_for_managed_stock_product() { $product = Product::factory()->withStocks(10)->create(['manage_stock' => true]); @@ -124,7 +125,7 @@ class ShopFacadeTest extends TestCase $this->assertTrue($hasStock); } - /** @test */ + #[Test] public function it_returns_false_when_not_enough_stock() { $product = Product::factory()->withStocks(5)->create(['manage_stock' => true]); @@ -134,7 +135,7 @@ class ShopFacadeTest extends TestCase $this->assertFalse($hasStock); } - /** @test */ + #[Test] public function it_returns_true_for_unmanaged_stock_products() { $product = Product::factory()->create(['manage_stock' => false]); @@ -144,7 +145,7 @@ class ShopFacadeTest extends TestCase $this->assertTrue($hasStock); } - /** @test */ + #[Test] public function it_can_get_available_stock() { $product = Product::factory()->withStocks(15)->create(['manage_stock' => true]); @@ -154,7 +155,7 @@ class ShopFacadeTest extends TestCase $this->assertEquals(15, $available); } - /** @test */ + #[Test] public function it_returns_max_int_for_unmanaged_stock_products() { $product = Product::factory()->create(['manage_stock' => false]); @@ -164,7 +165,7 @@ class ShopFacadeTest extends TestCase $this->assertEquals(PHP_INT_MAX, $available); } - /** @test */ + #[Test] public function it_can_check_if_product_is_on_sale() { // Just verify the method exists and returns a boolean @@ -175,7 +176,7 @@ class ShopFacadeTest extends TestCase $this->assertIsBool($isOnSale); } - /** @test */ + #[Test] public function it_can_get_shop_configuration() { $currency = Shop::config('currency', 'USD'); @@ -183,7 +184,7 @@ class ShopFacadeTest extends TestCase $this->assertIsString($currency); } - /** @test */ + #[Test] public function it_returns_default_config_value_for_nonexistent_key() { $value = Shop::config('nonexistent.key', 'default'); @@ -191,7 +192,7 @@ class ShopFacadeTest extends TestCase $this->assertEquals('default', $value); } - /** @test */ + #[Test] public function it_can_get_default_currency() { $currency = Shop::currency(); @@ -200,7 +201,7 @@ class ShopFacadeTest extends TestCase $this->assertNotEmpty($currency); } - /** @test */ + #[Test] public function it_can_chain_query_builder_methods() { Product::factory()->create(['featured' => true, 'is_visible' => true]); @@ -215,7 +216,7 @@ class ShopFacadeTest extends TestCase $this->assertCount(1, $products); } - /** @test */ + #[Test] public function it_can_paginate_products() { Product::factory()->count(15)->create(); @@ -226,7 +227,7 @@ class ShopFacadeTest extends TestCase $this->assertEquals(3, $page->lastPage()); } - /** @test */ + #[Test] public function it_can_count_products() { Product::factory()->count(7)->create(); @@ -236,7 +237,7 @@ class ShopFacadeTest extends TestCase $this->assertEquals(7, $count); } - /** @test */ + #[Test] public function it_can_get_featured_and_in_stock_products() { Product::factory()->withStocks()->create(['featured' => true]); diff --git a/tests/Feature/StockManagementTest.php b/tests/Feature/StockManagementTest.php index 5818eb5..df7172e 100644 --- a/tests/Feature/StockManagementTest.php +++ b/tests/Feature/StockManagementTest.php @@ -6,14 +6,14 @@ use Blax\Shop\Exceptions\NotEnoughStockException; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductStock; use Blax\Shop\Tests\TestCase; -use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class StockManagementTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_can_claim_stock_for_a_product() { $product = Product::factory() @@ -30,7 +30,7 @@ class StockManagementTest extends TestCase $this->assertEquals(90, $product->getAvailableStock()); } - /** @test */ + #[Test] public function it_cannot_claim_more_stock_than_available() { $product = Product::factory() @@ -45,7 +45,7 @@ class StockManagementTest extends TestCase $this->assertEquals(5, $product->getAvailableStock()); } - /** @test */ + #[Test] public function it_can_release_claimed_stock() { $product = Product::factory() @@ -65,7 +65,7 @@ class StockManagementTest extends TestCase $this->assertNotNull($claim->fresh()->released_at); } - /** @test */ + #[Test] public function it_can_check_if_stock_is_pending() { $product = Product::factory()->withStocks(10)->create(); @@ -78,7 +78,7 @@ class StockManagementTest extends TestCase $this->assertNull($pending->released_at); } - /** @test */ + #[Test] public function it_can_check_if_stock_is_released() { $product = Product::factory()->withStocks(50)->create(); @@ -93,7 +93,7 @@ class StockManagementTest extends TestCase $this->assertNotNull($released->released_at); } - /** @test */ + #[Test] public function it_can_distinguish_temporary_and_permanent_claims() { $product = Product::factory()->withStocks(100)->create(); @@ -114,7 +114,7 @@ class StockManagementTest extends TestCase $this->assertFalse($temporaryClaim->isPermanent()); } - /** @test */ + #[Test] public function it_belongs_to_a_product() { $product = Product::factory()->withStocks(20)->create(); @@ -125,7 +125,7 @@ class StockManagementTest extends TestCase $this->assertEquals($product->id, $claim->product->id); } - /** @test */ + #[Test] public function product_has_many_stock_records() { $product = Product::factory()->withStocks(30)->create(); @@ -139,7 +139,7 @@ class StockManagementTest extends TestCase $this->assertEquals(30 + 10 + 10 + 50, $product->getAvailableStock()); } - /** @test */ + #[Test] public function it_can_get_active_stock_claims() { $product = Product::factory()->withStocks(100)->create(); @@ -160,7 +160,7 @@ class StockManagementTest extends TestCase $this->assertEquals($activeClaim->id, $activeClaims->first()->id); } - /** @test */ + #[Test] public function it_cannot_release_stock_twice() { $product = Product::factory()->withStocks()->create(); @@ -171,7 +171,7 @@ class StockManagementTest extends TestCase $this->assertFalse($claim->release()); } - /** @test */ + #[Test] public function it_can_store_claim_note() { $product = Product::factory()->withStocks()->create(); @@ -186,7 +186,7 @@ class StockManagementTest extends TestCase $this->assertEquals($note, $claim->note); } - /** @test */ + #[Test] public function it_calculates_available_stock_correctly() { $product = Product::factory()->withStocks(100)->create(); @@ -207,7 +207,7 @@ class StockManagementTest extends TestCase $this->assertEquals(85, $product->refresh()->getAvailableStock()); } - /** @test */ + #[Test] public function product_tracks_low_stock_threshold() { $product = Product::factory() @@ -223,7 +223,7 @@ class StockManagementTest extends TestCase $this->assertTrue($product->fresh()->isLowStock()); } - /** @test */ + #[Test] public function it_updates_in_stock_status_automatically() { $product = Product::factory() @@ -235,7 +235,7 @@ class StockManagementTest extends TestCase $this->assertFalse($product->fresh()->isInStock()); } - /** @test */ + #[Test] public function it_can_adjust_stock_with_from_parameter_for_claimed_type() { $product = Product::factory()->withStocks(100)->create(); @@ -265,7 +265,7 @@ class StockManagementTest extends TestCase $this->assertEquals(-15, $decreaseStock->quantity); } - /** @test */ + #[Test] public function it_uses_now_as_default_from_date_for_claimed_type() { $product = Product::factory()->withStocks(100)->create(); @@ -283,7 +283,7 @@ class StockManagementTest extends TestCase $this->assertNull($claimedStock->claimed_from); } - /** @test */ + #[Test] public function it_does_not_set_claimed_from_for_non_claimed_types() { $product = Product::factory()->withStocks(100)->create(); @@ -298,7 +298,7 @@ class StockManagementTest extends TestCase $this->assertNull($stock->claimed_from); } - /** @test */ + #[Test] public function it_can_adjust_stock_with_note_parameter() { $product = Product::factory()->withStocks(100)->create(); @@ -317,7 +317,7 @@ class StockManagementTest extends TestCase $this->assertEquals($note, $stock->note); } - /** @test */ + #[Test] public function it_can_adjust_stock_with_referencable_model() { $product = Product::factory()->withStocks(100)->create(); @@ -337,7 +337,7 @@ class StockManagementTest extends TestCase $this->assertEquals($referencedProduct->id, $stock->reference_id); } - /** @test */ + #[Test] public function it_can_adjust_stock_with_all_parameters_combined() { $product = Product::factory()->withStocks(100)->create(); @@ -369,7 +369,7 @@ class StockManagementTest extends TestCase $this->assertEquals($referencedProduct->id, $stock->reference_id); } - /** @test */ + #[Test] public function it_adjusts_stock_with_correct_quantity_signs_based_on_type() { $product = Product::factory()->withStocks(100)->create(); @@ -416,7 +416,7 @@ class StockManagementTest extends TestCase $this->assertEquals(-5, $claimedDecrease->quantity); } - /** @test */ + #[Test] public function it_returns_false_when_adjusting_stock_with_management_disabled() { $product = Product::factory()->create([ diff --git a/tests/Feature/StripeChargeFlowTest.php b/tests/Feature/StripeChargeFlowTest.php index 7851cb6..e3cca45 100644 --- a/tests/Feature/StripeChargeFlowTest.php +++ b/tests/Feature/StripeChargeFlowTest.php @@ -2,21 +2,16 @@ namespace Blax\Shop\Tests\Feature; -use Blax\Shop\Exceptions\NotEnoughStockException; use Blax\Shop\Models\Product; -use Blax\Shop\Models\ProductPurchase; -use Blax\Shop\Models\ProductPrice; -use Blax\Shop\Models\Cart; -use Blax\Shop\Models\CartItem; use Blax\Shop\Models\PaymentProviderIdentity; use Blax\Shop\Models\PaymentMethod as ShopPaymentMethod; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Workbench\App\Models\User; -use Laravel\Cashier\Cashier; use Stripe\PaymentMethod; use Stripe\Customer; use Stripe\Stripe; +use PHPUnit\Framework\Attributes\Test; class StripeChargeFlowTest extends TestCase { @@ -45,7 +40,7 @@ class StripeChargeFlowTest extends TestCase Stripe::setApiKey(config('cashier.secret')); } - /** @test */ + #[Test] public function user_can_be_created() { $user = User::factory()->create([ @@ -61,7 +56,7 @@ class StripeChargeFlowTest extends TestCase $this->assertInstanceOf(User::class, $user); } - /** @test */ + #[Test] public function user_can_have_stripe_account() { $user = User::factory()->create(); @@ -80,7 +75,7 @@ class StripeChargeFlowTest extends TestCase $stripeCustomer->delete(); } - /** @test */ + #[Test] public function user_has_stripe_account_trait() { $user = User::factory()->create(); @@ -91,7 +86,7 @@ class StripeChargeFlowTest extends TestCase ); } - /** @test */ + #[Test] public function user_can_update_billing_address() { $user = User::factory()->create(); @@ -130,7 +125,7 @@ class StripeChargeFlowTest extends TestCase $stripeCustomer->delete(); } - /** @test */ + #[Test] public function user_can_checkout_with_stripe() { $user = User::factory()->create(); @@ -164,7 +159,7 @@ class StripeChargeFlowTest extends TestCase $this->assertSame('succeeded', $charge->status); } - /** @test */ + #[Test] public function payment_method_model_can_store_stripe_details() { $user = User::factory()->create(); @@ -225,7 +220,7 @@ class StripeChargeFlowTest extends TestCase $stripeCustomer->delete(); } - /** @test */ + #[Test] public function can_switch_default_payment_method_for_provider_identity() { // No need to hit Stripe here; use local records diff --git a/tests/Unit/CartItemTest.php b/tests/Unit/CartItemTest.php index 6cca990..d05354e 100644 --- a/tests/Unit/CartItemTest.php +++ b/tests/Unit/CartItemTest.php @@ -4,18 +4,19 @@ namespace Blax\Shop\Tests\Unit; use Blax\Shop\Enums\ProductType; use Blax\Shop\Models\Cart; -use Blax\Shop\Models\CartItem; use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; + class CartItemTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function cart_item_stores_prices_as_integers_in_cents() { $cart = Cart::create(); @@ -37,7 +38,7 @@ class CartItemTest extends TestCase $this->assertEquals(3100, $cartItem->subtotal); // 1550 * 2 } - /** @test */ + #[Test] public function cart_item_unit_amount_represents_base_price_per_day() { $cart = Cart::create(); @@ -51,7 +52,7 @@ class CartItemTest extends TestCase $this->assertEquals(5000, $cartItem->price); // Same as unit_amount for 1 day } - /** @test */ + #[Test] public function cart_item_calculates_price_correctly_for_booking_timespan() { $cart = Cart::create(); @@ -73,7 +74,7 @@ class CartItemTest extends TestCase $this->assertEquals(6000, $cartItem->subtotal); } - /** @test */ + #[Test] public function cart_item_calculates_price_with_partial_days() { $cart = Cart::create(); @@ -93,7 +94,7 @@ class CartItemTest extends TestCase $this->assertEqualsWithDelta(2400, $cartItem->price, 1); } - /** @test */ + #[Test] public function cart_item_handles_multiple_quantities_correctly() { $cart = Cart::create(); @@ -107,7 +108,7 @@ class CartItemTest extends TestCase $this->assertEquals(5000, $cartItem->subtotal); // 1000 * 5 } - /** @test */ + #[Test] public function cart_item_updates_prices_when_dates_change() { $cart = Cart::create(); @@ -140,7 +141,7 @@ class CartItemTest extends TestCase $this->assertEquals(15000, $cartItem->subtotal); } - /** @test */ + #[Test] public function cart_item_handles_fractional_days_with_multiple_quantities() { $cart = Cart::create(); @@ -162,7 +163,7 @@ class CartItemTest extends TestCase $this->assertEqualsWithDelta(10800, $cartItem->subtotal, 3); } - /** @test */ + #[Test] public function cart_item_subtotal_recalculates_on_quantity_change() { $cart = Cart::create(); @@ -179,7 +180,7 @@ class CartItemTest extends TestCase $this->assertEquals(7500, $cartItem->fresh()->subtotal); // 1500 * 5 } - /** @test */ + #[Test] public function cart_item_stores_unit_amount_for_non_booking_products() { $cart = Cart::create(); @@ -194,7 +195,7 @@ class CartItemTest extends TestCase $this->assertEquals(9999, $cartItem->subtotal); } - /** @test */ + #[Test] public function cart_item_handles_sale_prices_in_cents() { $cart = Cart::create(); @@ -229,7 +230,7 @@ class CartItemTest extends TestCase $this->assertEquals(7500, $cartItem->subtotal); } - /** @test */ + #[Test] public function cart_item_rounds_prices_consistently() { $cart = Cart::create(); @@ -249,7 +250,7 @@ class CartItemTest extends TestCase $this->assertEquals(5000, $cartItem->price); // Rounded to 5000 } - /** @test */ + #[Test] public function cart_item_unit_amount_remains_constant_across_date_updates() { $cart = Cart::create(); @@ -274,7 +275,7 @@ class CartItemTest extends TestCase $this->assertEquals(31500, $cartItem->price); // 4500 * 7 } - /** @test */ + #[Test] public function cart_item_validates_database_storage_as_integer() { $cart = Cart::create(); @@ -293,7 +294,7 @@ class CartItemTest extends TestCase $this->assertIsInt($dbItem->unit_amount); } - /** @test */ + #[Test] public function cart_item_getSubtotal_method_returns_correct_value() { $cart = Cart::create(); @@ -307,7 +308,7 @@ class CartItemTest extends TestCase $this->assertEquals(3702, $cartItem->getSubtotal()); // 1234 * 3 } - /** @test */ + #[Test] public function cart_item_handles_zero_prices() { $cart = Cart::create(); @@ -322,11 +323,14 @@ class CartItemTest extends TestCase $this->assertEquals(0, $cartItem->subtotal); } - /** @test */ + #[Test] public function cart_item_handles_very_long_booking_periods() { $cart = Cart::create(); - $product = Product::factory()->withPrices(unit_amount: 500)->create(['type' => ProductType::BOOKING]); // $5.00 per day + $product = Product::factory() + ->withPrices(unit_amount: 500) + ->create(['type' => ProductType::BOOKING]); // $5.00 per day + $price = $product->defaultPrice()->first(); // 365 days (1 year) diff --git a/tests/Unit/CartTest.php b/tests/Unit/CartTest.php index 08084ff..33fdb35 100644 --- a/tests/Unit/CartTest.php +++ b/tests/Unit/CartTest.php @@ -8,12 +8,14 @@ use Blax\Shop\Models\Product; use Blax\Shop\Models\ProductPrice; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; + class CartTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function cart_can_add_product_price_directly() { $cart = Cart::create(); @@ -27,7 +29,7 @@ class CartTest extends TestCase $this->assertEquals(100.00, $cartItem->price); } - /** @test */ + #[Test] public function cart_calculates_subtotal_automatically() { $cart = Cart::create(); @@ -39,7 +41,7 @@ class CartTest extends TestCase $this->assertEquals(150.00, $cartItem->subtotal); } - /** @test */ + #[Test] public function cart_respects_sale_prices() { $cart = Cart::create(); @@ -72,7 +74,7 @@ class CartTest extends TestCase $this->assertEquals(100.00, $cartItem->regular_price); } - /** @test */ + #[Test] public function cart_can_add_items_with_custom_parameters() { $cart = Cart::create(); @@ -92,7 +94,7 @@ class CartTest extends TestCase $this->assertEquals('Custom text', $cartItem->parameters['engraving']); } - /** @test */ + #[Test] public function cart_total_sums_all_items() { $cart = Cart::create(); @@ -111,7 +113,7 @@ class CartTest extends TestCase $this->assertEquals(200.00, $total); } - /** @test */ + #[Test] public function cart_tracks_last_activity() { $cart = Cart::create([ @@ -122,7 +124,7 @@ class CartTest extends TestCase $this->assertTrue($cart->last_activity_at->isPast()); } - /** @test */ + #[Test] public function cart_can_be_converted() { $cart = Cart::create(); @@ -134,7 +136,7 @@ class CartTest extends TestCase $this->assertTrue($cart->fresh()->isConverted()); } - /** @test */ + #[Test] public function active_scope_filters_correctly() { // Active cart (not expired, not converted) @@ -166,7 +168,7 @@ class CartTest extends TestCase $this->assertCount(2, $active); } - /** @test */ + #[Test] public function cart_deletes_items_on_deletion() { $cart = Cart::create(); @@ -183,7 +185,7 @@ class CartTest extends TestCase $this->assertDatabaseMissing('cart_items', ['id' => $cartItemId]); } - /** @test */ + #[Test] public function cart_can_have_currency() { $cart = Cart::create([ @@ -193,7 +195,7 @@ class CartTest extends TestCase $this->assertEquals('EUR', $cart->currency); } - /** @test */ + #[Test] public function cart_can_have_status() { $cart = Cart::create([ @@ -207,7 +209,7 @@ class CartTest extends TestCase $this->assertEquals(CartStatus::CONVERTED, $cart->fresh()->status); } - /** @test */ + #[Test] public function cart_can_store_metadata() { $cart = Cart::create([ @@ -221,7 +223,7 @@ class CartTest extends TestCase $this->assertEquals('Gift wrapped', $cart->meta->notes); } - /** @test */ + #[Test] public function cart_can_have_session_id() { $sessionId = 'sess_' . str()->random(40); @@ -233,7 +235,7 @@ class CartTest extends TestCase $this->assertEquals($sessionId, $cart->session_id); } - /** @test */ + #[Test] public function checkout_session_link_throws_when_stripe_disabled() { config(['shop.stripe.enabled' => false]); @@ -245,7 +247,7 @@ class CartTest extends TestCase $cart->checkoutSessionLink(); } - /** @test */ + #[Test] public function checkout_session_link_throws_when_cart_empty() { config(['shop.stripe.enabled' => true]); @@ -257,7 +259,7 @@ class CartTest extends TestCase $cart->checkoutSessionLink(); } - /** @test */ + #[Test] public function checkout_session_link_throws_when_cart_empty_even_with_meta() { config(['shop.stripe.enabled' => true]); @@ -271,7 +273,7 @@ class CartTest extends TestCase $cart->checkoutSessionLink(); } - /** @test */ + #[Test] public function checkout_session_link_returns_false_on_stripe_error() { config(['shop.stripe.enabled' => true]); @@ -292,7 +294,7 @@ class CartTest extends TestCase $this->assertNotNull($returnType); } - /** @test */ + #[Test] public function checkout_session_link_returns_null_when_session_not_found() { config(['shop.stripe.enabled' => true]); @@ -307,7 +309,7 @@ class CartTest extends TestCase $this->assertTrue(method_exists($cart, 'checkoutSessionLink')); } - /** @test */ + #[Test] public function checkout_session_link_handles_meta_as_array() { config(['shop.stripe.enabled' => true]); @@ -320,7 +322,7 @@ class CartTest extends TestCase $this->assertEquals('cs_test_123', $cart->meta->stripe_session_id); } - /** @test */ + #[Test] public function checkout_session_link_handles_meta_as_object() { config(['shop.stripe.enabled' => true]); diff --git a/tests/Unit/HtmlDateTimeCastTest.php b/tests/Unit/HtmlDateTimeCastTest.php index b442693..38ab465 100644 --- a/tests/Unit/HtmlDateTimeCastTest.php +++ b/tests/Unit/HtmlDateTimeCastTest.php @@ -3,14 +3,15 @@ namespace Blax\Shop\Tests\Unit; use Blax\Shop\Models\Cart; -use Blax\Shop\Models\CartItem; use Blax\Shop\Models\Product; use Blax\Shop\Tests\TestCase; use Carbon\Carbon; +use PHPUnit\Framework\Attributes\Test; + class HtmlDateTimeCastTest extends TestCase { - /** @test */ + #[Test] public function it_accepts_carbon_instance_and_stores_as_timestamp() { $cart = Cart::factory()->create(); @@ -27,7 +28,7 @@ class HtmlDateTimeCastTest extends TestCase $this->assertEquals('2025-12-25 14:30:00', $cart->from->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_accepts_datetime_interface_and_stores_as_timestamp() { $cart = Cart::factory()->create(); @@ -42,7 +43,7 @@ class HtmlDateTimeCastTest extends TestCase $this->assertEquals('2025-12-25 14:30:00', $cart->from->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_accepts_string_and_stores_as_timestamp() { $cart = Cart::factory()->create(); @@ -57,7 +58,7 @@ class HtmlDateTimeCastTest extends TestCase $this->assertEquals('2025-12-25 14:30:00', $cart->from->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_accepts_html5_datetime_local_format() { $cart = Cart::factory()->create(); @@ -72,7 +73,7 @@ class HtmlDateTimeCastTest extends TestCase $this->assertEquals('2025-12-25 14:30:00', $cart->from->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_can_format_for_html5_input() { $cart = Cart::factory()->create(); @@ -86,7 +87,7 @@ class HtmlDateTimeCastTest extends TestCase $this->assertEquals('2025-12-25T14:30', $htmlFormat); } - /** @test */ + #[Test] public function it_handles_null_values() { $cart = Cart::factory()->create(); @@ -98,7 +99,7 @@ class HtmlDateTimeCastTest extends TestCase $this->assertNull($cart->from); } - /** @test */ + #[Test] public function it_works_with_cart_items() { $product = Product::factory()->create(); @@ -122,7 +123,7 @@ class HtmlDateTimeCastTest extends TestCase $this->assertEquals('2025-12-27T10:00', $item->until->format('Y-m-d\TH:i')); } - /** @test */ + #[Test] public function it_accepts_unix_timestamp() { $cart = Cart::factory()->create(); @@ -137,7 +138,7 @@ class HtmlDateTimeCastTest extends TestCase $this->assertEquals('2025-12-25 14:30:00', $cart->from->format('Y-m-d H:i:s')); } - /** @test */ + #[Test] public function it_maintains_carbon_methods() { $cart = Cart::factory()->create(); diff --git a/tests/Unit/ProductPricingTest.php b/tests/Unit/ProductPricingTest.php index dea31d3..24a24f0 100644 --- a/tests/Unit/ProductPricingTest.php +++ b/tests/Unit/ProductPricingTest.php @@ -5,12 +5,14 @@ namespace Blax\Shop\Tests\Unit; use Blax\Shop\Models\Product; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; + class ProductPricingTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_returns_regular_price_when_not_on_sale() { $product = Product::factory()->withPrices(2, 100)->create(); @@ -21,7 +23,7 @@ class ProductPricingTest extends TestCase $this->assertEquals(100, $product->getCurrentPrice()); } - /** @test */ + #[Test] public function it_returns_sale_price_when_on_sale() { $product = Product::factory() @@ -39,7 +41,7 @@ class ProductPricingTest extends TestCase $this->assertEquals(80, $product->getCurrentPrice()); } - /** @test */ + #[Test] public function it_returns_regular_price_when_sale_has_ended() { $product = Product::factory()->withPrices(1, 100)->create([ @@ -48,7 +50,7 @@ class ProductPricingTest extends TestCase ]); $price = $product->prices()->first(); - $price->sale_unit_amount = 80; + $price->sale_unit_amount = 80; $price->save(); $this->assertEquals(80, $product->getCurrentPrice()); @@ -60,7 +62,7 @@ class ProductPricingTest extends TestCase $this->assertEquals(100, $product->getCurrentPrice()); } - /** @test */ + #[Test] public function it_returns_regular_price_when_sale_hasnt_started() { $product = Product::factory()->withPrices(1, 100)->create([ @@ -69,7 +71,7 @@ class ProductPricingTest extends TestCase ]); $price = $product->prices()->first(); - $price->sale_unit_amount = 80; + $price->sale_unit_amount = 80; $price->save(); $this->assertEquals(100, $product->getCurrentPrice()); diff --git a/tests/Unit/ProductRelationsTest.php b/tests/Unit/ProductRelationsTest.php index 6810da3..f5b49bf 100644 --- a/tests/Unit/ProductRelationsTest.php +++ b/tests/Unit/ProductRelationsTest.php @@ -6,12 +6,13 @@ use Blax\Shop\Enums\ProductRelationType; use Blax\Shop\Models\Product; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class ProductRelationsTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_filters_relations_by_relation_type() { $product = Product::factory()->create(); @@ -41,7 +42,7 @@ class ProductRelationsTest extends TestCase $this->assertSame(1, $product->relatedProducts()->first()->pivot->sort_order); } - /** @test */ + #[Test] public function relations_by_type_accepts_enum_or_string() { $product = Product::factory()->create(); @@ -55,7 +56,7 @@ class ProductRelationsTest extends TestCase $this->assertTrue($product->relationsByType('related')->exists()); } - /** @test */ + #[Test] public function it_can_be_queried_by_specific_relation_types() { $withUpsell = Product::factory()->create(); diff --git a/tests/Unit/StockManagementTest.php b/tests/Unit/StockManagementTest.php index b89637c..c509118 100644 --- a/tests/Unit/StockManagementTest.php +++ b/tests/Unit/StockManagementTest.php @@ -5,12 +5,13 @@ namespace Blax\Shop\Tests\Unit; use Blax\Shop\Models\Product; use Blax\Shop\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class StockManagementTest extends TestCase { use RefreshDatabase; - /** @test */ + #[Test] public function it_detects_low_stock() { $product = Product::factory()->create([ @@ -22,7 +23,7 @@ class StockManagementTest extends TestCase $this->assertTrue($product->isLowStock()); } - /** @test */ + #[Test] public function it_detects_sufficient_stock() { $product = Product::factory()->withStocks(50)->create([ @@ -32,7 +33,7 @@ class StockManagementTest extends TestCase $this->assertFalse($product->isLowStock()); } - /** @test */ + #[Test] public function it_marks_product_as_out_of_stock() { $product = Product::factory()->create([ @@ -46,7 +47,7 @@ class StockManagementTest extends TestCase $this->assertEquals('outofstock', $product->stock_status); } - /** @test */ + #[Test] public function products_without_stock_management_are_always_in_stock() { $product = Product::factory()->create([