test: add service unit tests to improve coverage
- Add tests for inventory_service.py (admin methods, helpers) - Add tests for vendor_service.py (identifier, permissions, updates) - Add tests for marketplace_product_service.py (CRUD, admin, CSV export) - Add tests for order_service.py (number generation, customer mgmt) Coverage improved from 67% to 69.6% 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -544,3 +544,243 @@ class TestInventoryService:
|
||||
|
||||
with pytest.raises(InventoryNotFoundException):
|
||||
self.service.delete_inventory(db, other_vendor.id, test_inventory.id)
|
||||
|
||||
# ==================== Admin Method Tests ====================
|
||||
|
||||
def test_get_all_inventory_admin_success(self, db, test_inventory):
|
||||
"""Test get_all_inventory_admin returns all inventory."""
|
||||
result = self.service.get_all_inventory_admin(db)
|
||||
|
||||
assert result.total >= 1
|
||||
assert len(result.inventories) >= 1
|
||||
assert any(inv.id == test_inventory.id for inv in result.inventories)
|
||||
|
||||
def test_get_all_inventory_admin_with_vendor_filter(
|
||||
self, db, test_inventory, test_vendor
|
||||
):
|
||||
"""Test get_all_inventory_admin filters by vendor."""
|
||||
result = self.service.get_all_inventory_admin(
|
||||
db, vendor_id=test_vendor.id
|
||||
)
|
||||
|
||||
for inv in result.inventories:
|
||||
assert inv.vendor_id == test_vendor.id
|
||||
|
||||
def test_get_all_inventory_admin_with_location_filter(
|
||||
self, db, test_inventory
|
||||
):
|
||||
"""Test get_all_inventory_admin filters by location."""
|
||||
location_prefix = test_inventory.location[:5]
|
||||
result = self.service.get_all_inventory_admin(
|
||||
db, location=location_prefix
|
||||
)
|
||||
|
||||
for inv in result.inventories:
|
||||
assert location_prefix.upper() in inv.location.upper()
|
||||
|
||||
def test_get_all_inventory_admin_with_low_stock_filter(self, db):
|
||||
"""Test get_all_inventory_admin filters by low stock."""
|
||||
result = self.service.get_all_inventory_admin(db, low_stock=5)
|
||||
|
||||
for inv in result.inventories:
|
||||
assert inv.quantity <= 5
|
||||
|
||||
def test_get_all_inventory_admin_pagination(self, db):
|
||||
"""Test get_all_inventory_admin pagination."""
|
||||
result = self.service.get_all_inventory_admin(db, skip=0, limit=5)
|
||||
|
||||
assert len(result.inventories) <= 5
|
||||
assert result.skip == 0
|
||||
assert result.limit == 5
|
||||
|
||||
def test_get_inventory_stats_admin(self, db, test_inventory):
|
||||
"""Test get_inventory_stats_admin returns stats."""
|
||||
result = self.service.get_inventory_stats_admin(db)
|
||||
|
||||
assert result.total_entries >= 1
|
||||
assert result.total_quantity >= test_inventory.quantity
|
||||
assert result.total_reserved >= 0
|
||||
assert result.total_available >= 0
|
||||
assert result.low_stock_count >= 0
|
||||
assert result.vendors_with_inventory >= 1
|
||||
assert result.unique_locations >= 1
|
||||
|
||||
def test_get_low_stock_items_admin(self, db, test_product, test_vendor):
|
||||
"""Test get_low_stock_items_admin returns low stock items."""
|
||||
# Create low stock inventory
|
||||
unique_id = str(uuid.uuid4())[:8].upper()
|
||||
low_stock_inv = Inventory(
|
||||
product_id=test_product.id,
|
||||
vendor_id=test_vendor.id,
|
||||
warehouse="strassen",
|
||||
bin_location=f"LOW_{unique_id}",
|
||||
location=f"LOW_{unique_id}",
|
||||
quantity=3,
|
||||
reserved_quantity=0,
|
||||
)
|
||||
db.add(low_stock_inv)
|
||||
db.commit()
|
||||
|
||||
result = self.service.get_low_stock_items_admin(db, threshold=10)
|
||||
|
||||
assert len(result) >= 1
|
||||
for item in result:
|
||||
assert item.quantity <= 10
|
||||
|
||||
def test_get_low_stock_items_admin_with_vendor_filter(
|
||||
self, db, test_inventory, test_vendor
|
||||
):
|
||||
"""Test get_low_stock_items_admin filters by vendor."""
|
||||
result = self.service.get_low_stock_items_admin(
|
||||
db, threshold=1000, vendor_id=test_vendor.id
|
||||
)
|
||||
|
||||
for item in result:
|
||||
assert item.vendor_id == test_vendor.id
|
||||
|
||||
def test_get_vendors_with_inventory_admin(self, db, test_inventory, test_vendor):
|
||||
"""Test get_vendors_with_inventory_admin returns vendors list."""
|
||||
result = self.service.get_vendors_with_inventory_admin(db)
|
||||
|
||||
assert len(result.vendors) >= 1
|
||||
assert any(v.id == test_vendor.id for v in result.vendors)
|
||||
|
||||
def test_get_inventory_locations_admin(self, db, test_inventory):
|
||||
"""Test get_inventory_locations_admin returns locations."""
|
||||
result = self.service.get_inventory_locations_admin(db)
|
||||
|
||||
assert len(result.locations) >= 1
|
||||
assert test_inventory.location in result.locations
|
||||
|
||||
def test_get_inventory_locations_admin_with_vendor_filter(
|
||||
self, db, test_inventory, test_vendor
|
||||
):
|
||||
"""Test get_inventory_locations_admin filters by vendor."""
|
||||
result = self.service.get_inventory_locations_admin(
|
||||
db, vendor_id=test_vendor.id
|
||||
)
|
||||
|
||||
assert len(result.locations) >= 1
|
||||
|
||||
def test_get_vendor_inventory_admin_success(
|
||||
self, db, test_inventory, test_vendor
|
||||
):
|
||||
"""Test get_vendor_inventory_admin returns vendor inventory."""
|
||||
result = self.service.get_vendor_inventory_admin(
|
||||
db, vendor_id=test_vendor.id
|
||||
)
|
||||
|
||||
assert result.total >= 1
|
||||
assert result.vendor_filter == test_vendor.id
|
||||
for inv in result.inventories:
|
||||
assert inv.vendor_id == test_vendor.id
|
||||
|
||||
def test_get_vendor_inventory_admin_vendor_not_found(self, db):
|
||||
"""Test get_vendor_inventory_admin raises for non-existent vendor."""
|
||||
from app.exceptions import VendorNotFoundException
|
||||
|
||||
with pytest.raises(VendorNotFoundException):
|
||||
self.service.get_vendor_inventory_admin(db, vendor_id=99999)
|
||||
|
||||
def test_get_product_inventory_admin(self, db, test_inventory, test_product):
|
||||
"""Test get_product_inventory_admin returns product inventory."""
|
||||
result = self.service.get_product_inventory_admin(db, test_product.id)
|
||||
|
||||
assert result.product_id == test_product.id
|
||||
assert result.total_quantity >= test_inventory.quantity
|
||||
|
||||
def test_get_product_inventory_admin_not_found(self, db):
|
||||
"""Test get_product_inventory_admin raises for non-existent product."""
|
||||
with pytest.raises(ProductNotFoundException):
|
||||
self.service.get_product_inventory_admin(db, 99999)
|
||||
|
||||
def test_verify_vendor_exists_success(self, db, test_vendor):
|
||||
"""Test verify_vendor_exists returns vendor."""
|
||||
result = self.service.verify_vendor_exists(db, test_vendor.id)
|
||||
|
||||
assert result.id == test_vendor.id
|
||||
|
||||
def test_verify_vendor_exists_not_found(self, db):
|
||||
"""Test verify_vendor_exists raises for non-existent vendor."""
|
||||
from app.exceptions import VendorNotFoundException
|
||||
|
||||
with pytest.raises(VendorNotFoundException):
|
||||
self.service.verify_vendor_exists(db, 99999)
|
||||
|
||||
def test_get_inventory_by_id_admin_success(self, db, test_inventory):
|
||||
"""Test get_inventory_by_id_admin returns inventory."""
|
||||
result = self.service.get_inventory_by_id_admin(db, test_inventory.id)
|
||||
|
||||
assert result.id == test_inventory.id
|
||||
|
||||
def test_get_inventory_by_id_admin_not_found(self, db):
|
||||
"""Test get_inventory_by_id_admin raises for non-existent."""
|
||||
with pytest.raises(InventoryNotFoundException):
|
||||
self.service.get_inventory_by_id_admin(db, 99999)
|
||||
|
||||
# ==================== Private Helper Tests ====================
|
||||
|
||||
def test_get_vendor_product_success(self, db, test_product, test_vendor):
|
||||
"""Test _get_vendor_product returns product."""
|
||||
result = self.service._get_vendor_product(
|
||||
db, test_vendor.id, test_product.id
|
||||
)
|
||||
|
||||
assert result.id == test_product.id
|
||||
|
||||
def test_get_vendor_product_not_found(self, db, test_vendor):
|
||||
"""Test _get_vendor_product raises for non-existent product."""
|
||||
with pytest.raises(ProductNotFoundException):
|
||||
self.service._get_vendor_product(db, test_vendor.id, 99999)
|
||||
|
||||
def test_get_vendor_product_wrong_vendor(
|
||||
self, db, test_product, other_company
|
||||
):
|
||||
"""Test _get_vendor_product raises for wrong vendor."""
|
||||
from models.database.vendor import Vendor
|
||||
|
||||
unique_id = str(uuid.uuid4())[:8]
|
||||
other_vendor = Vendor(
|
||||
company_id=other_company.id,
|
||||
vendor_code=f"HELPER_{unique_id.upper()}",
|
||||
subdomain=f"helper{unique_id.lower()}",
|
||||
name=f"Helper Test Vendor {unique_id}",
|
||||
is_active=True,
|
||||
)
|
||||
db.add(other_vendor)
|
||||
db.commit()
|
||||
|
||||
with pytest.raises(ProductNotFoundException):
|
||||
self.service._get_vendor_product(
|
||||
db, other_vendor.id, test_product.id
|
||||
)
|
||||
|
||||
def test_get_inventory_entry_returns_existing(
|
||||
self, db, test_inventory, test_product
|
||||
):
|
||||
"""Test _get_inventory_entry returns existing entry."""
|
||||
result = self.service._get_inventory_entry(
|
||||
db, test_product.id, test_inventory.location
|
||||
)
|
||||
|
||||
assert result is not None
|
||||
assert result.id == test_inventory.id
|
||||
|
||||
def test_get_inventory_entry_returns_none(self, db, test_product):
|
||||
"""Test _get_inventory_entry returns None when not found."""
|
||||
result = self.service._get_inventory_entry(
|
||||
db, test_product.id, "NONEXISTENT_LOCATION"
|
||||
)
|
||||
|
||||
assert result is None
|
||||
|
||||
def test_get_inventory_by_id_returns_existing(self, db, test_inventory):
|
||||
"""Test _get_inventory_by_id returns existing entry."""
|
||||
result = self.service._get_inventory_by_id(db, test_inventory.id)
|
||||
|
||||
assert result.id == test_inventory.id
|
||||
|
||||
def test_get_inventory_by_id_raises_not_found(self, db):
|
||||
"""Test _get_inventory_by_id raises when not found."""
|
||||
with pytest.raises(InventoryNotFoundException):
|
||||
self.service._get_inventory_by_id(db, 99999)
|
||||
|
||||
Reference in New Issue
Block a user