BFI tests
This commit is contained in:
parent
ab1e2468ca
commit
c1f531e659
|
|
@ -22,8 +22,6 @@ class ProductFactory extends Factory
|
||||||
'status' => 'published',
|
'status' => 'published',
|
||||||
'is_visible' => true,
|
'is_visible' => true,
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'price' => $this->faker->randomFloat(2, 10, 1000),
|
|
||||||
'regular_price' => $this->faker->randomFloat(2, 10, 1000),
|
|
||||||
'manage_stock' => true,
|
'manage_stock' => true,
|
||||||
'stock_quantity' => $this->faker->numberBetween(0, 100),
|
'stock_quantity' => $this->faker->numberBetween(0, 100),
|
||||||
'in_stock' => true,
|
'in_stock' => true,
|
||||||
|
|
@ -69,15 +67,15 @@ class ProductFactory extends Factory
|
||||||
return $this->state(['featured' => true]);
|
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()
|
$prices = \Blax\Shop\Models\ProductPrice::factory()
|
||||||
->count($count)
|
->count($count)
|
||||||
->create([
|
->create([
|
||||||
'purchasable_type' => get_class($product),
|
'purchasable_type' => get_class($product),
|
||||||
'purchasable_id' => $product->id,
|
'purchasable_id' => $product->id,
|
||||||
'unit_amount' => $this->faker->randomFloat(2, 10, 1000),
|
'unit_amount' => $unit_amount ?? $this->faker->randomFloat(2, 10, 1000),
|
||||||
'currency' => 'EUR',
|
'currency' => 'EUR',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,6 @@ return new class extends Migration
|
||||||
$table->longText('description')->nullable();
|
$table->longText('description')->nullable();
|
||||||
$table->string('type')->default('simple'); // simple, variable, grouped, external
|
$table->string('type')->default('simple'); // simple, variable, grouped, external
|
||||||
$table->string('stripe_product_id')->nullable();
|
$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_start')->nullable();
|
||||||
$table->timestamp('sale_end')->nullable();
|
$table->timestamp('sale_end')->nullable();
|
||||||
$table->boolean('manage_stock')->default(false);
|
$table->boolean('manage_stock')->default(false);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ interface Purchasable
|
||||||
{
|
{
|
||||||
public function getCurrentPrice(): ?float;
|
public function getCurrentPrice(): ?float;
|
||||||
|
|
||||||
|
public function getPriceAttribute(): ?float;
|
||||||
|
|
||||||
public function isOnSale(): bool;
|
public function isOnSale(): bool;
|
||||||
|
|
||||||
public function decreaseStock(int $quantity = 1): bool;
|
public function decreaseStock(int $quantity = 1): bool;
|
||||||
|
|
@ -13,4 +15,5 @@ interface Purchasable
|
||||||
public function increaseStock(int $quantity = 1): bool;
|
public function increaseStock(int $quantity = 1): bool;
|
||||||
|
|
||||||
public function purchases();
|
public function purchases();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -501,4 +501,9 @@ class Product extends Model implements Purchasable, Cartable
|
||||||
{
|
{
|
||||||
return $this->prices()->where('is_default', true);
|
return $this->prices()->where('is_default', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPriceAttribute(): ?float
|
||||||
|
{
|
||||||
|
return $this->getCurrentPrice();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ trait HasShoppingCapabilities
|
||||||
if ($product->manage_stock) {
|
if ($product->manage_stock) {
|
||||||
$available = $product->getAvailableStock();
|
$available = $product->getAvailableStock();
|
||||||
if ($available < $quantity) {
|
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
|
public function getCartTotal(?string $cartId = null): float
|
||||||
{
|
{
|
||||||
return $this->cartItems()->get()->sum(function ($item) {
|
return $this->cartItems()->get()->sum(function ($item) {
|
||||||
$meta = (array) $item->meta;
|
return $item->purchasable->getCurrentPrice() * $item->quantity;
|
||||||
return $meta['amount'] ?? 0;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -241,7 +240,21 @@ trait HasShoppingCapabilities
|
||||||
|
|
||||||
$purchases = collect();
|
$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;
|
return $purchases;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ class CartManagementTest extends TestCase
|
||||||
public function it_can_update_cart_item_quantity()
|
public function it_can_update_cart_item_quantity()
|
||||||
{
|
{
|
||||||
$cart = Cart::create();
|
$cart = Cart::create();
|
||||||
$product = Product::factory()->create(['price' => 50.00]);
|
$product = Product::factory()->create();
|
||||||
$price = ProductPrice::factory()->create([
|
$price = ProductPrice::factory()->create([
|
||||||
'purchasable_id' => $product->id,
|
'purchasable_id' => $product->id,
|
||||||
'purchasable_type' => get_class($product),
|
'purchasable_type' => get_class($product),
|
||||||
|
|
@ -238,7 +238,7 @@ class CartManagementTest extends TestCase
|
||||||
public function cart_items_have_correct_relationships()
|
public function cart_items_have_correct_relationships()
|
||||||
{
|
{
|
||||||
$cart = Cart::create();
|
$cart = Cart::create();
|
||||||
$product = Product::factory()->create(['price' => 45.00]);
|
$product = Product::factory()->create();
|
||||||
|
|
||||||
$productPrice = ProductPrice::factory()->create([
|
$productPrice = ProductPrice::factory()->create([
|
||||||
'purchasable_id' => $product->id,
|
'purchasable_id' => $product->id,
|
||||||
|
|
@ -256,7 +256,7 @@ class CartManagementTest extends TestCase
|
||||||
public function it_calculates_cart_item_subtotal()
|
public function it_calculates_cart_item_subtotal()
|
||||||
{
|
{
|
||||||
$cart = Cart::create();
|
$cart = Cart::create();
|
||||||
$product = Product::factory()->create(['price' => 25.00]);
|
$product = Product::factory()->create();
|
||||||
|
|
||||||
$productPrice = ProductPrice::factory()->create([
|
$productPrice = ProductPrice::factory()->create([
|
||||||
'purchasable_id' => $product->id,
|
'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()
|
public function it_can_have_multiple_items_of_same_product_with_different_attributes()
|
||||||
{
|
{
|
||||||
$cart = Cart::create();
|
$cart = Cart::create();
|
||||||
$product = Product::factory()->create(['price' => 30.00]);
|
$product = Product::factory()->create();
|
||||||
|
|
||||||
$productPrice = ProductPrice::factory()->create([
|
$productPrice = ProductPrice::factory()->create([
|
||||||
'purchasable_id' => $product->id,
|
'purchasable_id' => $product->id,
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,20 @@ class ProductManagementTest extends TestCase
|
||||||
/** @test */
|
/** @test */
|
||||||
public function it_can_create_a_product()
|
public function it_can_create_a_product()
|
||||||
{
|
{
|
||||||
$product = Product::factory()->create([
|
$product = Product::factory()
|
||||||
'slug' => 'test-product',
|
->withPrices(1, 99.99)
|
||||||
'type' => 'simple',
|
->create([
|
||||||
'price' => 99.99,
|
'slug' => 'test-product',
|
||||||
'regular_price' => 99.99,
|
'type' => 'simple',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertDatabaseHas('products', [
|
$this->assertDatabaseHas('products', [
|
||||||
'id' => $product->id,
|
'id' => $product->id,
|
||||||
'slug' => 'test-product',
|
'slug' => 'test-product',
|
||||||
'price' => 99.99,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->assertCount(1, $product->prices);
|
||||||
|
$this->assertEquals(99.99, $product->prices->first()->unit_amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
|
|
|
||||||
|
|
@ -127,19 +127,19 @@ class PurchaseFlowTest extends TestCase
|
||||||
$purchases = $user->checkout();
|
$purchases = $user->checkout();
|
||||||
|
|
||||||
$this->assertCount(2, $purchases);
|
$this->assertCount(2, $purchases);
|
||||||
$this->assertEquals('completed', $purchases[0]->status);
|
$this->assertEquals('unpaid', $purchases[0]->status);
|
||||||
$this->assertEquals('completed', $purchases[1]->status);
|
$this->assertEquals('unpaid', $purchases[1]->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function user_can_get_cart_total()
|
public function user_can_get_cart_total()
|
||||||
{
|
{
|
||||||
$user = User::factory()->create();
|
$user = User::factory()->create();
|
||||||
$product1 = Product::factory()->create(['price' => 40.00]);
|
$product1 = Product::factory()->withPrices(unit_amount:40)->create();
|
||||||
$product2 = Product::factory()->create(['price' => 60.00]);
|
$product2 = Product::factory()->withPrices(unit_amount:60)->create();
|
||||||
|
|
||||||
$user->addToCart($product1, quantity: 2); // 80.00
|
$user->addToCart($product1, quantity: 2);
|
||||||
$user->addToCart($product2, quantity: 1); // 60.00
|
$user->addToCart($product2, quantity: 1);
|
||||||
|
|
||||||
$total = $user->getCartTotal();
|
$total = $user->getCartTotal();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue