75 lines
2.6 KiB
Python
75 lines
2.6 KiB
Python
"""Pengujian jalur independen validate_checkout (V(G) = 7).
|
|
|
|
Satu test per jalur basis. Nomor P1..P7 sama dengan tabel di docs/laporan.md.
|
|
Kebutuhan: FR-ORD-02, FR-ORD-03, FR-ORD-08.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from umkm.catalog import ClothingProduct
|
|
from umkm.checkout import (
|
|
CartItem,
|
|
CheckoutSummary,
|
|
InsufficientStockError,
|
|
InvalidQuantityError,
|
|
MultiShopError,
|
|
ProductNotFoundError,
|
|
validate_checkout,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def products():
|
|
return {
|
|
"p1": ClothingProduct("p1", "shop-A", "Kaos", price=50_000, on_hand=10, size="M"),
|
|
"p2": ClothingProduct("p2", "shop-A", "Kemeja", price=120_000, on_hand=5, size="L"),
|
|
"p3": ClothingProduct("p3", "shop-B", "Jaket", price=200_000, on_hand=5, size="XL"),
|
|
"p4": ClothingProduct("p4", "shop-A", "Topi", price=30_000, on_hand=3, size="S", reserved=3),
|
|
}
|
|
|
|
|
|
def test_p1_keranjang_kosong_total_nol(products):
|
|
"""P1: loop tidak dimasuki."""
|
|
assert validate_checkout([], products) == CheckoutSummary(None, 0)
|
|
|
|
|
|
def test_p2_produk_tidak_ada(products):
|
|
"""P2: product is None -> ProductNotFoundError."""
|
|
with pytest.raises(ProductNotFoundError):
|
|
validate_checkout([CartItem("tidak-ada", 1)], products)
|
|
|
|
|
|
@pytest.mark.parametrize("qty", [0, -1])
|
|
def test_p3_kuantitas_tidak_valid(products, qty):
|
|
"""P3: quantity <= 0 -> InvalidQuantityError (batas 0 dan negatif)."""
|
|
with pytest.raises(InvalidQuantityError):
|
|
validate_checkout([CartItem("p1", qty)], products)
|
|
|
|
|
|
def test_p4_stok_tidak_cukup_pada_item_pertama(products):
|
|
"""P4: available < quantity pada iterasi pertama."""
|
|
with pytest.raises(InsufficientStockError):
|
|
validate_checkout([CartItem("p4", 1)], products)
|
|
|
|
|
|
def test_p5_satu_item_valid(products):
|
|
"""P5: jalur baseline, satu item lolos semua cek."""
|
|
assert validate_checkout([CartItem("p1", 2)], products) == CheckoutSummary("shop-A", 100_000)
|
|
|
|
|
|
def test_p6_dua_item_satu_toko(products):
|
|
"""P6: iterasi kedua, toko sama -> shop_id tidak berubah, total dijumlahkan."""
|
|
result = validate_checkout([CartItem("p1", 2), CartItem("p2", 1)], products)
|
|
assert result == CheckoutSummary("shop-A", 2 * 50_000 + 120_000)
|
|
|
|
|
|
def test_p7_dua_item_beda_toko(products):
|
|
"""P7: iterasi kedua, toko berbeda -> MultiShopError (FR-ORD-08)."""
|
|
with pytest.raises(MultiShopError):
|
|
validate_checkout([CartItem("p1", 1), CartItem("p3", 1)], products)
|
|
|
|
|
|
def test_batas_stok_tepat_sama_lolos(products):
|
|
"""Batas available == quantity harus lolos (cabang stok false)."""
|
|
assert validate_checkout([CartItem("p2", 5)], products).total_amount == 600_000
|