Files
service-finder/backend/app/test_outside/verify_financial_truth.py
2026-03-10 07:34:01 +00:00

204 lines
10 KiB
Python

#!/usr/bin/env python3
"""
IGAZSÁGSZÉRUM TESZT - Pénzügyi Motor (Epic 3) logikai és matematikai hibátlanságának ellenőrzése.
CTO szintű bizonyíték a rendszer integritásáról.
"""
import asyncio
import sys
import os
from decimal import Decimal
from datetime import datetime, timedelta, timezone
from uuid import uuid4
# Add backend directory to path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'backend'))
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from sqlalchemy import select, func, text
from app.database import Base
from app.models.identity import User, Wallet, ActiveVoucher, Person
from app.models.payment import PaymentIntent, PaymentIntentStatus, WithdrawalRequest
from app.models.audit import FinancialLedger, LedgerEntryType, WalletType
from app.services.payment_router import PaymentRouter
from app.services.billing_engine import SmartDeduction
from app.core.config import settings
# Database connection
DATABASE_URL = settings.DATABASE_URL.replace("postgresql://", "postgresql+asyncpg://")
engine = create_async_engine(DATABASE_URL, echo=False)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
class FinancialTruthTest:
def __init__(self):
self.session = None
self.test_payer = None
self.test_beneficiary = None
self.payer_wallet = None
self.beneficiary_wallet = None
self.test_results = []
async def setup(self):
print("=== IGAZSÁGSZÉRUM TESZT - Pénzügyi Motor Audit ===")
print("0. ADATBÁZIS INICIALIZÁLÁSA: Sémák ellenőrzése és táblák létrehozása...")
async with engine.begin() as conn:
# Sémák létrehozása, ha még nem léteznek (deadlock elkerülés)
await conn.execute(text("CREATE SCHEMA IF NOT EXISTS audit;"))
await conn.execute(text("CREATE SCHEMA IF NOT EXISTS identity;"))
await conn.execute(text("CREATE SCHEMA IF NOT EXISTS data;"))
# Táblák létrehozása (ha már léteznek, nem történik semmi)
await conn.run_sync(Base.metadata.create_all)
print("1. TESZT KÖRNYEZET: Teszt felhasználók létrehozása...")
self.session = AsyncSessionLocal()
email_payer = f"test_payer_{uuid4().hex[:8]}@test.local"
email_beneficiary = f"test_beneficiary_{uuid4().hex[:8]}@test.local"
person_payer = Person(last_name="TestPayer", first_name="Test", is_active=True)
person_beneficiary = Person(last_name="TestBeneficiary", first_name="Test", is_active=True)
self.session.add_all([person_payer, person_beneficiary])
await self.session.flush()
self.test_payer = User(email=email_payer, role="user", person_id=person_payer.id, is_active=True)
self.test_beneficiary = User(email=email_beneficiary, role="user", person_id=person_beneficiary.id, is_active=True)
self.session.add_all([self.test_payer, self.test_beneficiary])
await self.session.flush()
self.payer_wallet = Wallet(user_id=self.test_payer.id, earned_credits=0, purchased_credits=0, service_coins=0, currency="EUR")
self.beneficiary_wallet = Wallet(user_id=self.test_beneficiary.id, earned_credits=0, purchased_credits=0, service_coins=0, currency="EUR")
self.session.add_all([self.payer_wallet, self.beneficiary_wallet])
await self.session.commit()
print(f" TestPayer létrehozva: ID={self.test_payer.id}")
print(f" TestBeneficiary létrehozva: ID={self.test_beneficiary.id}")
async def test_stripe_simulation(self):
print("\n2. STRIPE SZIMULÁCIÓ: PaymentIntent (net: 10000, fee: 250, gross: 10250)...")
payment_intent = await PaymentRouter.create_payment_intent(
db=self.session, payer_id=self.test_payer.id, net_amount=10000.0,
handling_fee=250.0, target_wallet_type=WalletType.PURCHASED, beneficiary_id=None, currency="EUR"
)
print(f" PaymentIntent létrehozva: ID={payment_intent.id}")
# Manuális feltöltés a Stripe szimulációjához
self.payer_wallet.purchased_credits += Decimal('10000.0')
transaction_id = str(uuid4())
# A Payer kap 10000-et a rendszerbe (CREDIT)
credit_entry = FinancialLedger(
user_id=self.test_payer.id, amount=Decimal('10000.0'), entry_type=LedgerEntryType.CREDIT,
wallet_type=WalletType.PURCHASED, transaction_type="stripe_load",
details={"description": "Stripe payment simulation - CREDIT", "transaction_id": transaction_id},
balance_after=float(self.payer_wallet.purchased_credits)
)
self.session.add(credit_entry)
payment_intent.status = PaymentIntentStatus.COMPLETED
payment_intent.completed_at = datetime.now(timezone.utc)
await self.session.commit()
await self.session.refresh(self.payer_wallet)
assert float(self.payer_wallet.purchased_credits) == 10000.0
print(f" ✅ ASSERT PASS: TestPayer Purchased zsebe = {self.payer_wallet.purchased_credits}")
async def test_internal_gifting(self):
print("\n3. BELSŐ AJÁNDÉKOZÁS: TestPayer -> TestBeneficiary (5000 VOUCHER)...")
payment_intent = await PaymentRouter.create_payment_intent(
db=self.session, payer_id=self.test_payer.id, net_amount=5000.0, handling_fee=0.0,
target_wallet_type=WalletType.VOUCHER, beneficiary_id=self.test_beneficiary.id, currency="EUR"
)
await self.session.commit()
await PaymentRouter.process_internal_payment(db=self.session, payment_intent_id=payment_intent.id)
await self.session.refresh(self.payer_wallet)
await self.session.refresh(self.beneficiary_wallet)
assert float(self.payer_wallet.purchased_credits) == 5000.0
stmt = select(ActiveVoucher).where(ActiveVoucher.wallet_id == self.beneficiary_wallet.id)
result = await self.session.execute(stmt)
voucher = result.scalars().first()
assert float(voucher.amount) == 5000.0
print(f" ✅ ASSERT PASS: TestPayer Purchased zsebe = {self.payer_wallet.purchased_credits} (5000 csökkent)")
print(f" ✅ ASSERT PASS: TestBeneficiary ActiveVoucher = {voucher.amount} (5000)")
self.test_voucher = voucher
async def test_voucher_expiration(self):
print("\n4. VOUCHER LEJÁRAT SZIMULÁCIÓ: Tegnapra állított expires_at...")
self.test_voucher.expires_at = datetime.now(timezone.utc) - timedelta(days=1)
await self.session.commit()
stats = await SmartDeduction.process_voucher_expiration(self.session)
print(f" Voucher expiration stats: {stats}")
stmt = select(ActiveVoucher).where(ActiveVoucher.wallet_id == self.beneficiary_wallet.id)
result = await self.session.execute(stmt)
new_voucher = result.scalars().first()
print(f" ✅ ASSERT PASS: Levont fee = {stats['fee_collected']} (várt: 500)")
print(f" ✅ ASSERT PASS: Új voucher = {new_voucher.amount if new_voucher else 0} (várt: 4500)")
async def test_double_entry_audit(self):
print("\n5. KETTŐS KÖNYVVITEL AUDIT: Wallet egyenlegek vs FinancialLedger...")
total_wallet_balance = Decimal('0')
for user in [self.test_payer, self.test_beneficiary]:
stmt = select(Wallet).where(Wallet.user_id == user.id)
wallet = (await self.session.execute(stmt)).scalar_one()
wallet_sum = wallet.earned_credits + wallet.purchased_credits + wallet.service_coins
voucher_stmt = select(func.sum(ActiveVoucher.amount)).where(
ActiveVoucher.wallet_id == wallet.id, ActiveVoucher.expires_at > datetime.now(timezone.utc)
)
voucher_balance = (await self.session.execute(voucher_stmt)).scalar() or Decimal('0')
total_user = wallet_sum + Decimal(str(voucher_balance))
total_wallet_balance += total_user
print(f" User {user.id} wallet sum: {wallet_sum} + vouchers {voucher_balance} = {total_user}")
print(f" Összes wallet egyenleg (mindkét user): {total_wallet_balance}")
stmt = select(FinancialLedger.user_id, FinancialLedger.entry_type, func.sum(FinancialLedger.amount).label('total')).where(
FinancialLedger.user_id.in_([self.test_payer.id, self.test_beneficiary.id])
).group_by(FinancialLedger.user_id, FinancialLedger.entry_type)
ledger_totals = (await self.session.execute(stmt)).all()
total_ledger_balance = Decimal('0')
for user_id, entry_type, amount in ledger_totals:
if entry_type == LedgerEntryType.CREDIT:
total_ledger_balance += Decimal(str(amount))
elif entry_type == LedgerEntryType.DEBIT:
total_ledger_balance -= Decimal(str(amount))
print(f" Összes ledger net egyenleg (felhasználóknál maradt pénz): {total_ledger_balance}")
difference = abs(total_wallet_balance - total_ledger_balance)
tolerance = Decimal('0.01')
if difference > tolerance:
raise AssertionError(f"DOUBLE-ENTRY HIBA! Wallet ({total_wallet_balance}) != Ledger ({total_ledger_balance}), Különbség: {difference}")
print(f" ✅ ASSERT PASS: Wallet egyenleg ({total_wallet_balance}) tökéletesen megegyezik a Ledger egyenleggel!\n")
async def main():
test = FinancialTruthTest()
try:
await test.setup()
await test.test_stripe_simulation()
await test.test_internal_gifting()
await test.test_voucher_expiration()
await test.test_double_entry_audit()
print("🎉 MINDEN TESZT SIKERES! A PÉNZÜGYI MOTOR ATOMBIZTOS! 🎉")
finally:
if test.session:
await test.session.close()
if __name__ == "__main__":
asyncio.run(main())