BFI tests

This commit is contained in:
a6a2f5842 2025-11-24 07:00:07 +01:00
parent ab1e2468ca
commit c1f531e659
8 changed files with 47 additions and 29 deletions

View File

@ -22,8 +22,6 @@ class ProductFactory extends Factory
'status' => 'published',
'is_visible' => true,
'featured' => false,
'price' => $this->faker->randomFloat(2, 10, 1000),
'regular_price' => $this->faker->randomFloat(2, 10, 1000),
'manage_stock' => true,
'stock_quantity' => $this->faker->numberBetween(0, 100),
'in_stock' => true,
@ -69,15 +67,15 @@ class ProductFactory extends Factory
return $this->state(['featured' => true]);
}
public function withPrices(int $count = 1): static
public function withPrices(int $count = 1, null|float $unit_amount = null): static
{
return $this->afterCreating(function (Product $product) use ($count) {
return $this->afterCreating(function (Product $product) use ($count, $unit_amount) {
$prices = \Blax\Shop\Models\ProductPrice::factory()
->count($count)
->create([
'purchasable_type' => get_class($product),
'purchasable_id' => $product->id,
'unit_amount' => $this->faker->randomFloat(2, 10, 1000),
'unit_amount' => $unit_amount ?? $this->faker->randomFloat(2, 10, 1000),
'currency' => 'EUR',
]);

View File

@ -22,9 +22,6 @@ return new class extends Migration
$table->longText('description')->nullable();
$table->string('type')->default('simple'); // simple, variable, grouped, external
$table->string('stripe_product_id')->nullable();
$table->decimal('price', 10, 2)->default(0);
$table->decimal('regular_price', 10, 2)->nullable();
$table->decimal('sale_price', 10, 2)->nullable();
$table->timestamp('sale_start')->nullable();
$table->timestamp('sale_end')->nullable();
$table->boolean('manage_stock')->default(false);

View File

@ -6,6 +6,8 @@ interface Purchasable
{
public function getCurrentPrice(): ?float;
public function getPriceAttribute(): ?float;
public function isOnSale(): bool;
public function decreaseStock(int $quantity = 1): bool;
@ -13,4 +15,5 @@ interface Purchasable
public function increaseStock(int $quantity = 1): bool;
public function purchases();
}

View File

@ -501,4 +501,9 @@ class Product extends Model implements Purchasable, Cartable
{
return $this->prices()->where('is_default', true);
}
public function getPriceAttribute(): ?float
{
return $this->getCurrentPrice();
}
}

View File

@ -82,7 +82,7 @@ trait HasShoppingCapabilities
if ($product->manage_stock) {
$available = $product->getAvailableStock();
if ($available < $quantity) {
throw new \Exception("Insufficient stock. Available: {$available}, Requested: {$quantity}");
throw new NotEnoughStockException("Insufficient stock. Available: {$available}, Requested: {$quantity}");
}
}
@ -205,8 +205,7 @@ trait HasShoppingCapabilities
public function getCartTotal(?string $cartId = null): float
{
return $this->cartItems()->get()->sum(function ($item) {
$meta = (array) $item->meta;
return $meta['amount'] ?? 0;
return $item->purchasable->getCurrentPrice() * $item->quantity;
});
}
@ -241,7 +240,21 @@ trait HasShoppingCapabilities
$purchases = collect();
//
// Create ProductPurchase for each cart item
foreach ($items as $item) {
$product = $item->purchasable;
$quantity = $item->quantity;
$purchase = $this->purchase(
$product->prices()->first(),
$quantity
);
$purchases->push($purchase);
// Remove item from cart
$item->delete();
}
return $purchases;
}

View File

@ -70,7 +70,7 @@ class CartManagementTest extends TestCase
public function it_can_update_cart_item_quantity()
{
$cart = Cart::create();
$product = Product::factory()->create(['price' => 50.00]);
$product = Product::factory()->create();
$price = ProductPrice::factory()->create([
'purchasable_id' => $product->id,
'purchasable_type' => get_class($product),
@ -238,7 +238,7 @@ class CartManagementTest extends TestCase
public function cart_items_have_correct_relationships()
{
$cart = Cart::create();
$product = Product::factory()->create(['price' => 45.00]);
$product = Product::factory()->create();
$productPrice = ProductPrice::factory()->create([
'purchasable_id' => $product->id,
@ -256,7 +256,7 @@ class CartManagementTest extends TestCase
public function it_calculates_cart_item_subtotal()
{
$cart = Cart::create();
$product = Product::factory()->create(['price' => 25.00]);
$product = Product::factory()->create();
$productPrice = ProductPrice::factory()->create([
'purchasable_id' => $product->id,
@ -298,7 +298,7 @@ class CartManagementTest extends TestCase
public function it_can_have_multiple_items_of_same_product_with_different_attributes()
{
$cart = Cart::create();
$product = Product::factory()->create(['price' => 30.00]);
$product = Product::factory()->create();
$productPrice = ProductPrice::factory()->create([
'purchasable_id' => $product->id,

View File

@ -16,18 +16,20 @@ class ProductManagementTest extends TestCase
/** @test */
public function it_can_create_a_product()
{
$product = Product::factory()->create([
'slug' => 'test-product',
'type' => 'simple',
'price' => 99.99,
'regular_price' => 99.99,
]);
$product = Product::factory()
->withPrices(1, 99.99)
->create([
'slug' => 'test-product',
'type' => 'simple',
]);
$this->assertDatabaseHas('products', [
'id' => $product->id,
'slug' => 'test-product',
'price' => 99.99,
]);
$this->assertCount(1, $product->prices);
$this->assertEquals(99.99, $product->prices->first()->unit_amount);
}
/** @test */

View File

@ -127,19 +127,19 @@ class PurchaseFlowTest extends TestCase
$purchases = $user->checkout();
$this->assertCount(2, $purchases);
$this->assertEquals('completed', $purchases[0]->status);
$this->assertEquals('completed', $purchases[1]->status);
$this->assertEquals('unpaid', $purchases[0]->status);
$this->assertEquals('unpaid', $purchases[1]->status);
}
/** @test */
public function user_can_get_cart_total()
{
$user = User::factory()->create();
$product1 = Product::factory()->create(['price' => 40.00]);
$product2 = Product::factory()->create(['price' => 60.00]);
$product1 = Product::factory()->withPrices(unit_amount:40)->create();
$product2 = Product::factory()->withPrices(unit_amount:60)->create();
$user->addToCart($product1, quantity: 2); // 80.00
$user->addToCart($product2, quantity: 1); // 60.00
$user->addToCart($product1, quantity: 2);
$user->addToCart($product2, quantity: 1);
$total = $user->getCartTotal();