feat(hosting,prospecting): add hosting unit tests and fix template bugs
All checks were successful
All checks were successful
- Add 55 unit tests for hosting module (hosted site service, client service service, stats service) with full fixture setup - Fix table_empty_state macro: add x_message param for dynamic Alpine.js expressions rendered via x-text instead of server-side Jinja - Fix hosting templates (sites, clients) using message= with Alpine expressions that rendered as literal text - Fix prospecting templates (leads, scan-jobs, prospects) using nonexistent subtitle= param, migrated to x_message= - Align hosting and prospecting admin templates with shared design system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
186
app/modules/hosting/tests/conftest.py
Normal file
186
app/modules/hosting/tests/conftest.py
Normal file
@@ -0,0 +1,186 @@
|
||||
# app/modules/hosting/tests/conftest.py
|
||||
"""
|
||||
Module-specific fixtures for hosting tests.
|
||||
Core fixtures (db, client, etc.) are inherited from the root conftest.py.
|
||||
"""
|
||||
|
||||
import uuid
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
import pytest
|
||||
|
||||
from app.modules.hosting.models import (
|
||||
ClientService,
|
||||
ClientServiceStatus,
|
||||
HostedSite,
|
||||
HostedSiteStatus,
|
||||
ServiceType,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hosting_platform(db):
|
||||
"""Ensure a 'hosting' platform exists for hosted site creation."""
|
||||
from app.modules.tenancy.models import Platform
|
||||
|
||||
platform = db.query(Platform).filter(Platform.code == "hosting").first()
|
||||
if not platform:
|
||||
platform = Platform(
|
||||
code="hosting",
|
||||
name="Hosting Platform",
|
||||
is_active=True,
|
||||
is_public=False,
|
||||
default_language="fr",
|
||||
supported_languages=["fr", "en", "de"],
|
||||
)
|
||||
db.add(platform)
|
||||
db.commit()
|
||||
db.refresh(platform)
|
||||
return platform
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def system_user(db):
|
||||
"""Create a system user for the HostWizard System merchant."""
|
||||
from app.modules.tenancy.models import User
|
||||
|
||||
user = User(
|
||||
email=f"system-{uuid.uuid4().hex[:8]}@hostwizard.lu",
|
||||
username=f"system_{uuid.uuid4().hex[:8]}",
|
||||
first_name="System",
|
||||
last_name="User",
|
||||
hashed_password="not-a-real-hash", # noqa: SEC001
|
||||
role="super_admin",
|
||||
is_active=True,
|
||||
)
|
||||
db.add(user)
|
||||
db.commit()
|
||||
db.refresh(user)
|
||||
return user
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def system_merchant(db, system_user):
|
||||
"""Ensure the HostWizard System merchant exists."""
|
||||
from app.modules.tenancy.models import Merchant
|
||||
|
||||
merchant = db.query(Merchant).filter(Merchant.name == "HostWizard System").first()
|
||||
if not merchant:
|
||||
merchant = Merchant(
|
||||
name="HostWizard System",
|
||||
contact_email="system@hostwizard.lu",
|
||||
owner_user_id=system_user.id,
|
||||
is_active=True,
|
||||
is_verified=True,
|
||||
)
|
||||
db.add(merchant)
|
||||
db.commit()
|
||||
db.refresh(merchant)
|
||||
return merchant
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hosted_site(db, hosting_platform, system_merchant):
|
||||
"""Create a hosted site in DRAFT status with its backing store."""
|
||||
from app.modules.hosting.services.hosted_site_service import hosted_site_service
|
||||
|
||||
unique = uuid.uuid4().hex[:8]
|
||||
site = hosted_site_service.create(
|
||||
db,
|
||||
{
|
||||
"business_name": f"Test Business {unique}",
|
||||
"contact_name": "John Doe",
|
||||
"contact_email": f"john-{unique}@example.com",
|
||||
"contact_phone": "+352 123 456",
|
||||
"internal_notes": "Test site",
|
||||
},
|
||||
)
|
||||
db.commit()
|
||||
db.refresh(site)
|
||||
return site
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hosted_site_poc_ready(db, hosted_site):
|
||||
"""Create a hosted site in POC_READY status."""
|
||||
from app.modules.hosting.services.hosted_site_service import hosted_site_service
|
||||
|
||||
site = hosted_site_service.mark_poc_ready(db, hosted_site.id)
|
||||
db.commit()
|
||||
db.refresh(site)
|
||||
return site
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hosted_site_proposal_sent(db, hosted_site_poc_ready):
|
||||
"""Create a hosted site in PROPOSAL_SENT status."""
|
||||
from app.modules.hosting.services.hosted_site_service import hosted_site_service
|
||||
|
||||
site = hosted_site_service.send_proposal(
|
||||
db, hosted_site_poc_ready.id, notes="Test proposal"
|
||||
)
|
||||
db.commit()
|
||||
db.refresh(site)
|
||||
return site
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client_service_domain(db, hosted_site):
|
||||
"""Create a domain client service for a hosted site."""
|
||||
service = ClientService(
|
||||
hosted_site_id=hosted_site.id,
|
||||
service_type=ServiceType.DOMAIN,
|
||||
name="test-domain.lu",
|
||||
status=ClientServiceStatus.ACTIVE,
|
||||
billing_period="annual",
|
||||
price_cents=2500,
|
||||
currency="EUR",
|
||||
domain_name="test-domain.lu",
|
||||
registrar="Namecheap",
|
||||
expires_at=datetime.now(UTC) + timedelta(days=365),
|
||||
auto_renew=True,
|
||||
)
|
||||
db.add(service)
|
||||
db.commit()
|
||||
db.refresh(service)
|
||||
return service
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client_service_email(db, hosted_site):
|
||||
"""Create an email client service for a hosted site."""
|
||||
service = ClientService(
|
||||
hosted_site_id=hosted_site.id,
|
||||
service_type=ServiceType.EMAIL,
|
||||
name="Email Hosting",
|
||||
status=ClientServiceStatus.ACTIVE,
|
||||
billing_period="monthly",
|
||||
price_cents=500,
|
||||
currency="EUR",
|
||||
mailbox_count=5,
|
||||
auto_renew=True,
|
||||
)
|
||||
db.add(service)
|
||||
db.commit()
|
||||
db.refresh(service)
|
||||
return service
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client_service_expiring(db, hosted_site):
|
||||
"""Create a client service expiring within 30 days."""
|
||||
service = ClientService(
|
||||
hosted_site_id=hosted_site.id,
|
||||
service_type=ServiceType.SSL,
|
||||
name="SSL Certificate",
|
||||
status=ClientServiceStatus.ACTIVE,
|
||||
billing_period="annual",
|
||||
price_cents=0,
|
||||
currency="EUR",
|
||||
expires_at=datetime.now(UTC) + timedelta(days=15),
|
||||
auto_renew=True,
|
||||
)
|
||||
db.add(service)
|
||||
db.commit()
|
||||
db.refresh(service)
|
||||
return service
|
||||
Reference in New Issue
Block a user