Move letzshop-related functionality from tenancy to marketplace module: - Move admin letzshop routes to marketplace/routes/api/admin_letzshop.py - Move letzshop schemas to marketplace/schemas/letzshop.py - Remove letzshop code from tenancy module (admin_vendors, vendor_service) - Update model exports and imports Add comprehensive unit tests for vendor services: - test_company_service.py: Company management operations - test_platform_service.py: Platform management operations - test_vendor_domain_service.py: Vendor domain operations - test_vendor_team_service.py: Vendor team management Update module definitions: - billing, messaging, payments: Minor definition updates Add architecture proposals documentation: - Module dependency redesign session notes - Decouple modules implementation plan - Module decoupling proposal Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
298 lines
9.9 KiB
Python
298 lines
9.9 KiB
Python
# tests/unit/services/test_platform_service.py
|
|
"""Unit tests for PlatformService."""
|
|
|
|
import uuid
|
|
|
|
import pytest
|
|
|
|
from app.modules.tenancy.exceptions import PlatformNotFoundException
|
|
from app.modules.tenancy.services.platform_service import platform_service, PlatformStats
|
|
from app.modules.tenancy.models import Platform, VendorPlatform
|
|
from app.modules.cms.models import ContentPage
|
|
|
|
|
|
# =============================================================================
|
|
# FIXTURES
|
|
# =============================================================================
|
|
|
|
|
|
@pytest.fixture
|
|
def inactive_platform(db):
|
|
"""Create an inactive test platform."""
|
|
unique_id = str(uuid.uuid4())[:8]
|
|
platform = Platform(
|
|
code=f"inactive_{unique_id}",
|
|
name=f"Inactive Platform {unique_id}",
|
|
description="An inactive test platform",
|
|
path_prefix=f"inactive{unique_id}",
|
|
is_active=False,
|
|
is_public=False,
|
|
default_language="en",
|
|
supported_languages=["en"],
|
|
)
|
|
db.add(platform)
|
|
db.commit()
|
|
db.refresh(platform)
|
|
return platform
|
|
|
|
|
|
@pytest.fixture
|
|
def platform_with_vendor(db, test_platform, test_vendor):
|
|
"""Create a vendor-platform assignment."""
|
|
vendor_platform = VendorPlatform(
|
|
vendor_id=test_vendor.id,
|
|
platform_id=test_platform.id,
|
|
is_active=True,
|
|
)
|
|
db.add(vendor_platform)
|
|
db.commit()
|
|
return test_platform
|
|
|
|
|
|
@pytest.fixture
|
|
def platform_with_pages(db, test_platform):
|
|
"""Create a platform with content pages."""
|
|
unique_id = str(uuid.uuid4())[:8]
|
|
|
|
# Platform marketing page (published)
|
|
platform_page = ContentPage(
|
|
platform_id=test_platform.id,
|
|
vendor_id=None,
|
|
slug=f"platform-page-{unique_id}",
|
|
page_type="marketing",
|
|
is_platform_page=True,
|
|
is_published=True,
|
|
)
|
|
db.add(platform_page)
|
|
|
|
# Vendor default page (draft)
|
|
default_page = ContentPage(
|
|
platform_id=test_platform.id,
|
|
vendor_id=None,
|
|
slug=f"vendor-default-{unique_id}",
|
|
page_type="about",
|
|
is_platform_page=False,
|
|
is_published=False,
|
|
)
|
|
db.add(default_page)
|
|
|
|
db.commit()
|
|
return test_platform
|
|
|
|
|
|
# =============================================================================
|
|
# GET PLATFORM TESTS
|
|
# =============================================================================
|
|
|
|
|
|
@pytest.mark.unit
|
|
@pytest.mark.tenancy
|
|
class TestPlatformServiceGet:
|
|
"""Test suite for getting platforms."""
|
|
|
|
def test_get_platform_by_code_success(self, db, test_platform):
|
|
"""Test getting a platform by code."""
|
|
platform = platform_service.get_platform_by_code(db, test_platform.code)
|
|
|
|
assert platform is not None
|
|
assert platform.id == test_platform.id
|
|
assert platform.code == test_platform.code
|
|
|
|
def test_get_platform_by_code_not_found(self, db):
|
|
"""Test getting a non-existent platform raises exception."""
|
|
with pytest.raises(PlatformNotFoundException) as exc_info:
|
|
platform_service.get_platform_by_code(db, "nonexistent_platform")
|
|
|
|
assert "nonexistent_platform" in str(exc_info.value)
|
|
|
|
def test_get_platform_by_code_optional_found(self, db, test_platform):
|
|
"""Test optional get returns platform when found."""
|
|
platform = platform_service.get_platform_by_code_optional(db, test_platform.code)
|
|
|
|
assert platform is not None
|
|
assert platform.id == test_platform.id
|
|
|
|
def test_get_platform_by_code_optional_not_found(self, db):
|
|
"""Test optional get returns None when not found."""
|
|
platform = platform_service.get_platform_by_code_optional(db, "nonexistent")
|
|
|
|
assert platform is None
|
|
|
|
def test_get_platform_by_id_success(self, db, test_platform):
|
|
"""Test getting a platform by ID."""
|
|
platform = platform_service.get_platform_by_id(db, test_platform.id)
|
|
|
|
assert platform is not None
|
|
assert platform.code == test_platform.code
|
|
|
|
def test_get_platform_by_id_not_found(self, db):
|
|
"""Test getting a non-existent platform by ID raises exception."""
|
|
with pytest.raises(PlatformNotFoundException):
|
|
platform_service.get_platform_by_id(db, 99999)
|
|
|
|
|
|
# =============================================================================
|
|
# LIST PLATFORMS TESTS
|
|
# =============================================================================
|
|
|
|
|
|
@pytest.mark.unit
|
|
@pytest.mark.tenancy
|
|
class TestPlatformServiceList:
|
|
"""Test suite for listing platforms."""
|
|
|
|
def test_list_platforms_active_only(self, db, test_platform, inactive_platform):
|
|
"""Test listing only active platforms."""
|
|
platforms = platform_service.list_platforms(db, include_inactive=False)
|
|
|
|
platform_ids = [p.id for p in platforms]
|
|
assert test_platform.id in platform_ids
|
|
assert inactive_platform.id not in platform_ids
|
|
|
|
def test_list_platforms_include_inactive(self, db, test_platform, inactive_platform):
|
|
"""Test listing all platforms including inactive."""
|
|
platforms = platform_service.list_platforms(db, include_inactive=True)
|
|
|
|
platform_ids = [p.id for p in platforms]
|
|
assert test_platform.id in platform_ids
|
|
assert inactive_platform.id in platform_ids
|
|
|
|
|
|
# =============================================================================
|
|
# COUNT TESTS
|
|
# =============================================================================
|
|
|
|
|
|
@pytest.mark.unit
|
|
@pytest.mark.tenancy
|
|
class TestPlatformServiceCounts:
|
|
"""Test suite for platform counts."""
|
|
|
|
def test_get_vendor_count_zero(self, db, test_platform):
|
|
"""Test vendor count is zero when no vendors assigned."""
|
|
count = platform_service.get_vendor_count(db, test_platform.id)
|
|
|
|
assert count == 0
|
|
|
|
def test_get_vendor_count_with_vendors(self, db, platform_with_vendor):
|
|
"""Test vendor count with assigned vendors."""
|
|
count = platform_service.get_vendor_count(db, platform_with_vendor.id)
|
|
|
|
assert count >= 1
|
|
|
|
def test_get_platform_pages_count(self, db, platform_with_pages):
|
|
"""Test platform pages count."""
|
|
count = platform_service.get_platform_pages_count(db, platform_with_pages.id)
|
|
|
|
assert count >= 1
|
|
|
|
def test_get_vendor_defaults_count(self, db, platform_with_pages):
|
|
"""Test vendor defaults count."""
|
|
count = platform_service.get_vendor_defaults_count(db, platform_with_pages.id)
|
|
|
|
assert count >= 1
|
|
|
|
def test_get_published_pages_count(self, db, platform_with_pages):
|
|
"""Test published pages count."""
|
|
count = platform_service.get_published_pages_count(db, platform_with_pages.id)
|
|
|
|
assert count >= 1
|
|
|
|
def test_get_draft_pages_count(self, db, platform_with_pages):
|
|
"""Test draft pages count."""
|
|
count = platform_service.get_draft_pages_count(db, platform_with_pages.id)
|
|
|
|
assert count >= 1
|
|
|
|
|
|
# =============================================================================
|
|
# PLATFORM STATS TESTS
|
|
# =============================================================================
|
|
|
|
|
|
@pytest.mark.unit
|
|
@pytest.mark.tenancy
|
|
class TestPlatformServiceStats:
|
|
"""Test suite for platform statistics."""
|
|
|
|
def test_get_platform_stats(self, db, platform_with_pages, test_vendor):
|
|
"""Test getting comprehensive platform statistics."""
|
|
# Add a vendor to the platform
|
|
vendor_platform = VendorPlatform(
|
|
vendor_id=test_vendor.id,
|
|
platform_id=platform_with_pages.id,
|
|
is_active=True,
|
|
)
|
|
db.add(vendor_platform)
|
|
db.commit()
|
|
|
|
stats = platform_service.get_platform_stats(db, platform_with_pages)
|
|
|
|
assert isinstance(stats, PlatformStats)
|
|
assert stats.platform_id == platform_with_pages.id
|
|
assert stats.platform_code == platform_with_pages.code
|
|
assert stats.platform_name == platform_with_pages.name
|
|
assert stats.vendor_count >= 1
|
|
assert stats.platform_pages_count >= 1
|
|
assert stats.vendor_defaults_count >= 1
|
|
|
|
def test_get_platform_stats_empty_platform(self, db, test_platform):
|
|
"""Test stats for a platform with no content."""
|
|
stats = platform_service.get_platform_stats(db, test_platform)
|
|
|
|
assert stats.vendor_count == 0
|
|
assert stats.platform_pages_count == 0
|
|
assert stats.vendor_defaults_count == 0
|
|
|
|
|
|
# =============================================================================
|
|
# UPDATE TESTS
|
|
# =============================================================================
|
|
|
|
|
|
@pytest.mark.unit
|
|
@pytest.mark.tenancy
|
|
class TestPlatformServiceUpdate:
|
|
"""Test suite for updating platforms."""
|
|
|
|
def test_update_platform_name(self, db, test_platform):
|
|
"""Test updating platform name."""
|
|
unique_id = str(uuid.uuid4())[:8]
|
|
new_name = f"Updated Platform {unique_id}"
|
|
|
|
updated = platform_service.update_platform(
|
|
db, test_platform, {"name": new_name}
|
|
)
|
|
db.commit()
|
|
|
|
assert updated.name == new_name
|
|
|
|
def test_update_platform_multiple_fields(self, db, test_platform):
|
|
"""Test updating multiple platform fields."""
|
|
unique_id = str(uuid.uuid4())[:8]
|
|
update_data = {
|
|
"name": f"Multi Update {unique_id}",
|
|
"description": "Updated description",
|
|
"is_public": False,
|
|
}
|
|
|
|
updated = platform_service.update_platform(db, test_platform, update_data)
|
|
db.commit()
|
|
|
|
assert updated.name == f"Multi Update {unique_id}"
|
|
assert updated.description == "Updated description"
|
|
assert updated.is_public is False
|
|
|
|
def test_update_platform_ignores_invalid_fields(self, db, test_platform):
|
|
"""Test that invalid fields are ignored during update."""
|
|
original_name = test_platform.name
|
|
update_data = {
|
|
"nonexistent_field": "value",
|
|
"name": original_name, # Keep same name
|
|
}
|
|
|
|
# Should not raise an error
|
|
updated = platform_service.update_platform(db, test_platform, update_data)
|
|
|
|
assert updated.name == original_name
|