Files
service-finder/backend/app/test_billing_engine.py
2026-03-22 11:02:05 +00:00

209 lines
7.2 KiB
Python

#!/usr/bin/env python3
"""
Billing Engine tesztelő szkript.
Ellenőrzi, hogy a billing_engine.py fájl helyesen működik-e.
"""
import asyncio
import sys
import os
# Add the parent directory to the path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from app.core.config import settings
from app.services.billing_engine import PricingCalculator, SmartDeduction, AtomicTransactionManager
from app.models.identity import UserRole
async def test_pricing_calculator():
"""Árképzési számoló tesztelése."""
print("=== PricingCalculator teszt ===")
# Mock database session (nem használjuk valódi adatbázist)
class MockSession:
pass
db = MockSession()
# Alap teszt
base_amount = 100.0
# 1. Alapár (HU, user)
final_price = await PricingCalculator.calculate_final_price(
db, base_amount, "HU", UserRole.user
)
print(f"HU, user: {base_amount} -> {final_price} (várt: 100.0)")
assert abs(final_price - 100.0) < 0.01
# 2. UK árszorzó
final_price = await PricingCalculator.calculate_final_price(
db, base_amount, "GB", UserRole.user
)
print(f"GB, user: {base_amount} -> {final_price} (várt: 120.0)")
assert abs(final_price - 120.0) < 0.01
# 3. admin kedvezmény (30%)
final_price = await PricingCalculator.calculate_final_price(
db, base_amount, "HU", UserRole.admin
)
print(f"HU, admin: {base_amount} -> {final_price} (várt: 70.0)")
assert abs(final_price - 70.0) < 0.01
# 4. Kombinált (UK + superadmin - 50%)
final_price = await PricingCalculator.calculate_final_price(
db, base_amount, "GB", UserRole.superadmin
)
print(f"GB, superadmin: {base_amount} -> {final_price} (várt: 60.0)")
assert abs(final_price - 60.0) < 0.01
# 5. Egyedi kedvezmények
discounts = [
{"type": "percentage", "value": 10}, # 10% kedvezmény
{"type": "fixed", "value": 5}, # 5 egység kedvezmény
]
final_price = await PricingCalculator.calculate_final_price(
db, base_amount, "HU", UserRole.user, discounts
)
print(f"HU, user + discounts: {base_amount} -> {final_price} (várt: 85.0)")
assert abs(final_price - 85.0) < 0.01
print("✓ PricingCalculator teszt sikeres!\n")
async def test_smart_deduction_logic():
"""Intelligens levonás logikájának tesztelése (mock adatokkal)."""
print("=== SmartDeduction logika teszt ===")
# Mock wallet objektum
class MockWallet:
def __init__(self):
self.earned_balance = 50.0
self.purchased_balance = 30.0
self.service_coins_balance = 20.0
self.id = 1
# Mock database session
class MockSession:
async def commit(self):
pass
async def execute(self, stmt):
class MockResult:
def scalar_one_or_none(self):
return MockWallet()
return MockResult()
db = MockSession()
print("SmartDeduction osztály metódusai:")
print(f"- calculate_final_price: {'van' if hasattr(PricingCalculator, 'calculate_final_price') else 'nincs'}")
print(f"- deduct_from_wallets: {'van' if hasattr(SmartDeduction, 'deduct_from_wallets') else 'nincs'}")
print(f"- process_voucher_expiration: {'van' if hasattr(SmartDeduction, 'process_voucher_expiration') else 'nincs'}")
print("✓ SmartDeduction struktúra ellenőrizve!\n")
async def test_atomic_transaction_manager():
"""Atomikus tranzakciókezelő struktúrájának ellenőrzése."""
print("=== AtomicTransactionManager struktúra teszt ===")
print("AtomicTransactionManager osztály metódusai:")
print(f"- atomic_billing_transaction: {'van' if hasattr(AtomicTransactionManager, 'atomic_billing_transaction') else 'nincs'}")
print(f"- get_transaction_history: {'van' if hasattr(AtomicTransactionManager, 'get_transaction_history') else 'nincs'}")
# Ellenőrizzük, hogy a szükséges importok megvannak-e
try:
from app.models import LedgerEntryType, WalletType
print(f"- LedgerEntryType importálva: {LedgerEntryType}")
print(f"- WalletType importálva: {WalletType}")
except ImportError as e:
print(f"✗ Import hiba: {e}")
print("✓ AtomicTransactionManager struktúra ellenőrizve!\n")
async def test_file_completeness():
"""Fájl teljességének ellenőrzése."""
print("=== billing_engine.py fájl teljesség teszt ===")
file_path = "backend/app/services/billing_engine.py"
if not os.path.exists(file_path):
print(f"✗ A fájl nem létezik: {file_path}")
return
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Ellenőrizzük a kulcsszavakat
checks = [
("class PricingCalculator", "PricingCalculator osztály"),
("class SmartDeduction", "SmartDeduction osztály"),
("class AtomicTransactionManager", "AtomicTransactionManager osztály"),
("calculate_final_price", "calculate_final_price metódus"),
("deduct_from_wallets", "deduct_from_wallets metódus"),
("atomic_billing_transaction", "atomic_billing_transaction metódus"),
("from app.models.identity import", "identity model import"),
("from app.models import", "audit model import"),
]
all_passed = True
for keyword, description in checks:
if keyword in content:
print(f"{description} megtalálva")
else:
print(f"{description} HIÁNYZIK")
all_passed = False
# Ellenőrizzük a fájl végét
lines = content.strip().split('\n')
last_line = lines[-1].strip() if lines else ""
if last_line and not last_line.startswith('#'):
print(f"✓ Fájl vége rendben: '{last_line[:50]}...'")
else:
print(f"✗ Fájl vége lehet hiányos: '{last_line}'")
print(f"✓ Fájl mérete: {len(content)} karakter, {len(lines)} sor")
if all_passed:
print("✓ billing_engine.py fájl teljesség teszt sikeres!\n")
else:
print("✗ billing_engine.py fájl hiányos!\n")
async def main():
"""Fő tesztfolyamat."""
print("🤖 Billing Engine tesztelés indítása...\n")
try:
await test_file_completeness()
await test_pricing_calculator()
await test_smart_deduction_logic()
await test_atomic_transaction_manager()
print("=" * 50)
print("✅ ÖSSZES TESZT SIKERES!")
print("A Billing Engine implementáció alapvetően működőképes.")
print("\nKövetkező lépések:")
print("1. Valódi adatbázis kapcsolattal tesztelés")
print("2. Voucher kezelés tesztelése")
print("3. Atomikus tranzakciók integrációs tesztje")
print("4. API endpoint integráció")
except Exception as e:
print(f"\n❌ TESZT SIKERTELEN: {e}")
import traceback
traceback.print_exc()
return 1
return 0
if __name__ == "__main__":
exit_code = asyncio.run(main())
sys.exit(exit_code)