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:
2025-12-28 17:19:38 +01:00
parent 622321600d
commit e21630d63a
4 changed files with 1619 additions and 0 deletions

View File

@@ -521,3 +521,208 @@ class TestVendorServiceExceptionDetails:
exception = exc_info.value
assert exception.status_code == 404
assert exception.error_code == "VENDOR_NOT_FOUND"
@pytest.mark.unit
@pytest.mark.vendors
class TestVendorServiceIdentifier:
"""Tests for get_vendor_by_identifier method."""
def setup_method(self):
self.service = VendorService()
def test_get_vendor_by_identifier_with_id(self, db, test_vendor):
"""Test getting vendor by numeric ID string."""
vendor = self.service.get_vendor_by_identifier(db, str(test_vendor.id))
assert vendor is not None
assert vendor.id == test_vendor.id
def test_get_vendor_by_identifier_with_code(self, db, test_vendor):
"""Test getting vendor by vendor_code."""
vendor = self.service.get_vendor_by_identifier(db, test_vendor.vendor_code)
assert vendor is not None
assert vendor.vendor_code == test_vendor.vendor_code
def test_get_vendor_by_identifier_case_insensitive(self, db, test_vendor):
"""Test getting vendor by vendor_code is case insensitive."""
vendor = self.service.get_vendor_by_identifier(
db, test_vendor.vendor_code.lower()
)
assert vendor is not None
assert vendor.id == test_vendor.id
def test_get_vendor_by_identifier_not_found(self, db):
"""Test getting non-existent vendor."""
with pytest.raises(VendorNotFoundException):
self.service.get_vendor_by_identifier(db, "NONEXISTENT_CODE")
@pytest.mark.unit
@pytest.mark.vendors
class TestVendorServicePermissions:
"""Tests for permission checking methods."""
def setup_method(self):
self.service = VendorService()
def test_can_update_vendor_admin(self, db, test_admin, test_vendor):
"""Test admin can always update vendor."""
vendor = db.query(Vendor).filter(Vendor.id == test_vendor.id).first()
assert self.service.can_update_vendor(vendor, test_admin) is True
def test_can_update_vendor_owner(self, db, test_user, test_vendor):
"""Test owner can update vendor."""
vendor = db.query(Vendor).filter(Vendor.id == test_vendor.id).first()
assert self.service.can_update_vendor(vendor, test_user) is True
def test_can_update_vendor_non_owner(self, db, other_company, test_vendor):
"""Test non-owner cannot update vendor."""
from models.database.user import User
vendor = db.query(Vendor).filter(Vendor.id == test_vendor.id).first()
other_user = db.query(User).filter(User.id == other_company.owner_user_id).first()
# Clear any VendorUser relationships
assert self.service.can_update_vendor(vendor, other_user) is False
def test_is_vendor_owner_true(self, db, test_user, test_vendor):
"""Test _is_vendor_owner returns True for owner."""
vendor = db.query(Vendor).filter(Vendor.id == test_vendor.id).first()
assert self.service._is_vendor_owner(vendor, test_user) is True
def test_is_vendor_owner_false(self, db, other_company, test_vendor):
"""Test _is_vendor_owner returns False for non-owner."""
from models.database.user import User
vendor = db.query(Vendor).filter(Vendor.id == test_vendor.id).first()
other_user = db.query(User).filter(User.id == other_company.owner_user_id).first()
assert self.service._is_vendor_owner(vendor, other_user) is False
@pytest.mark.unit
@pytest.mark.vendors
class TestVendorServiceUpdate:
"""Tests for update methods."""
def setup_method(self):
self.service = VendorService()
def test_update_vendor_success(self, db, test_user, test_vendor):
"""Test successfully updating vendor profile."""
from pydantic import BaseModel
class VendorUpdate(BaseModel):
name: str | None = None
description: str | None = None
class Config:
extra = "forbid"
update_data = VendorUpdate(
name="Updated Vendor Name",
description="Updated description",
)
vendor = self.service.update_vendor(
db, test_vendor.id, update_data, test_user
)
db.commit()
assert vendor.name == "Updated Vendor Name"
assert vendor.description == "Updated description"
def test_update_vendor_unauthorized(self, db, other_company, test_vendor):
"""Test update fails for unauthorized user."""
from pydantic import BaseModel
from app.exceptions import InsufficientPermissionsException
from models.database.user import User
class VendorUpdate(BaseModel):
name: str | None = None
class Config:
extra = "forbid"
other_user = db.query(User).filter(User.id == other_company.owner_user_id).first()
update_data = VendorUpdate(name="Unauthorized Update")
with pytest.raises(InsufficientPermissionsException):
self.service.update_vendor(
db, test_vendor.id, update_data, other_user
)
def test_update_vendor_not_found(self, db, test_admin):
"""Test update fails for non-existent vendor."""
from pydantic import BaseModel
class VendorUpdate(BaseModel):
name: str | None = None
class Config:
extra = "forbid"
update_data = VendorUpdate(name="Update")
with pytest.raises(VendorNotFoundException):
self.service.update_vendor(db, 99999, update_data, test_admin)
def test_update_marketplace_settings_success(self, db, test_user, test_vendor):
"""Test successfully updating marketplace settings."""
marketplace_config = {
"letzshop_csv_url_fr": "https://example.com/fr.csv",
"letzshop_csv_url_en": "https://example.com/en.csv",
}
result = self.service.update_marketplace_settings(
db, test_vendor.id, marketplace_config, test_user
)
db.commit()
assert result["message"] == "Marketplace settings updated successfully"
assert result["letzshop_csv_url_fr"] == "https://example.com/fr.csv"
assert result["letzshop_csv_url_en"] == "https://example.com/en.csv"
def test_update_marketplace_settings_unauthorized(
self, db, other_company, test_vendor
):
"""Test marketplace settings update fails for unauthorized user."""
from app.exceptions import InsufficientPermissionsException
from models.database.user import User
other_user = db.query(User).filter(User.id == other_company.owner_user_id).first()
marketplace_config = {"letzshop_csv_url_fr": "https://example.com/fr.csv"}
with pytest.raises(InsufficientPermissionsException):
self.service.update_marketplace_settings(
db, test_vendor.id, marketplace_config, other_user
)
def test_update_marketplace_settings_not_found(self, db, test_admin):
"""Test marketplace settings update fails for non-existent vendor."""
marketplace_config = {"letzshop_csv_url_fr": "https://example.com/fr.csv"}
with pytest.raises(VendorNotFoundException):
self.service.update_marketplace_settings(
db, 99999, marketplace_config, test_admin
)
@pytest.mark.unit
@pytest.mark.vendors
class TestVendorServiceSingleton:
"""Test singleton instance."""
def test_singleton_exists(self):
"""Test vendor_service singleton exists."""
from app.services.vendor_service import vendor_service
assert vendor_service is not None
assert isinstance(vendor_service, VendorService)