nomy-data-models 0.2.3

Data model definitions for Nomy wallet analysis data processing
Documentation
"""Tests for the enriched_trade module."""

import uuid
from datetime import datetime, timedelta
from decimal import Decimal

import pytest

from nomy_data_models.models.enriched_trade import EnrichedTrade
from nomy_data_models.models.trade_base import MarketType


@pytest.fixture
def enriched_trade():
    """Fixture providing an EnrichedTrade instance with PnL information.

    Returns:
        EnrichedTrade: A fully populated EnrichedTrade instance with PnL
    """
    trade = EnrichedTrade()
    trade.id = uuid.uuid4()
    trade.event_at = datetime.now()
    trade.txn_id = "0x1234567890123456789012345678901234567890123456789012345678901234"
    trade.wallet_address = "0x1234567890123456789012345678901234567890"
    trade.chain_id = 1
    trade.exchange = "uniswap"
    trade.is_buy = True
    trade.token_price = Decimal("1000.0")
    trade.token_symbol_pair = "ETH/USDT"
    trade.token_address_pair = "0x1234567890123456789012345678901234567890/0x0987654321098765432109876543210987654321"
    trade.base_token_symbol = "ETH"
    trade.quote_token_symbol = "USDT"
    trade.base_token_address = "0x1234567890123456789012345678901234567890"
    trade.quote_token_address = "0x0987654321098765432109876543210987654321"
    trade.base_amount = Decimal("1.0")
    trade.quote_amount = Decimal("1000.0")
    trade.usd_amount = Decimal("1000.0")
    trade.market_type = MarketType.SPOT
    trade.pnl_usd = Decimal("100.0")
    trade.pnl = Decimal("0.1")
    trade.roi = Decimal("0.1")
    trade.holding_duration = timedelta(days=7)
    return trade


@pytest.fixture
def enriched_trade_without_pnl():
    """Fixture providing an EnrichedTrade instance without PnL information.

    Returns:
        EnrichedTrade: An EnrichedTrade instance without PnL
    """
    trade = EnrichedTrade()
    trade.id = uuid.uuid4()
    trade.event_at = datetime.now()
    trade.txn_id = "0x1234567890123456789012345678901234567890123456789012345678901234"
    trade.wallet_address = "0x1234567890123456789012345678901234567890"
    trade.chain_id = 1
    trade.exchange = "uniswap"
    trade.is_buy = True
    trade.token_price = Decimal("1000.0")
    trade.token_symbol_pair = "ETH/USDT"
    trade.token_address_pair = "0x1234567890123456789012345678901234567890/0x0987654321098765432109876543210987654321"
    trade.base_token_symbol = "ETH"
    trade.quote_token_symbol = "USDT"
    trade.base_token_address = "0x1234567890123456789012345678901234567890"
    trade.quote_token_address = "0x0987654321098765432109876543210987654321"
    trade.base_amount = Decimal("1.0")
    trade.quote_amount = Decimal("1000.0")
    trade.usd_amount = Decimal("1000.0")
    trade.market_type = MarketType.SPOT
    return trade


class TestEnrichedTrade:
    """Test cases for EnrichedTrade model."""

    def test_enriched_trade_creation(self, enriched_trade):
        """Test creating an EnrichedTrade instance with PnL information.

        Args:
            enriched_trade: Fixture providing an EnrichedTrade instance with PnL
        """
        # Verify the instance was created correctly
        assert enriched_trade.id is not None, "ID should be set"
        assert enriched_trade.event_at is not None, "Event timestamp should be set"
        assert (
            enriched_trade.txn_id
            == "0x1234567890123456789012345678901234567890123456789012345678901234"
        ), "Transaction ID should match"
        assert (
            enriched_trade.wallet_address
            == "0x1234567890123456789012345678901234567890"
        ), "Wallet address should match"
        assert enriched_trade.chain_id == 1, "Chain ID should be 1"
        assert enriched_trade.exchange == "uniswap", "Exchange should be 'uniswap'"
        assert enriched_trade.is_buy is True, "Is buy should be True"
        assert enriched_trade.token_price == Decimal(
            "1000.0"
        ), "Token price should be 1000.0"
        assert (
            enriched_trade.token_symbol_pair == "ETH/USDT"
        ), "Token symbol pair should be 'ETH/USDT'"
        assert (
            enriched_trade.token_address_pair
            == "0x1234567890123456789012345678901234567890/0x0987654321098765432109876543210987654321"
        ), "Token address pair should match"
        assert (
            enriched_trade.base_token_symbol == "ETH"
        ), "Base token symbol should be 'ETH'"
        assert (
            enriched_trade.quote_token_symbol == "USDT"
        ), "Quote token symbol should be 'USDT'"
        assert (
            enriched_trade.base_token_address
            == "0x1234567890123456789012345678901234567890"
        ), "Base token address should match"
        assert (
            enriched_trade.quote_token_address
            == "0x0987654321098765432109876543210987654321"
        ), "Quote token address should match"
        assert enriched_trade.base_amount == Decimal("1.0"), "Base amount should be 1.0"
        assert enriched_trade.quote_amount == Decimal(
            "1000.0"
        ), "Quote amount should be 1000.0"
        assert enriched_trade.usd_amount == Decimal(
            "1000.0"
        ), "USD amount should be 1000.0"
        assert (
            enriched_trade.market_type == MarketType.SPOT
        ), "Market type should be SPOT"
        assert enriched_trade.pnl_usd == Decimal("100.0"), "PnL USD should be 100.0"
        assert enriched_trade.pnl == Decimal("0.1"), "PnL should be 0.1"
        assert enriched_trade.roi == Decimal("0.1"), "ROI should be 0.1"
        assert enriched_trade.holding_duration == timedelta(
            days=7
        ), "Holding duration should be 7 days"

    def test_enriched_trade_repr_with_pnl(self, enriched_trade):
        """Test the string representation of an EnrichedTrade instance with PnL.

        Args:
            enriched_trade: Fixture providing an EnrichedTrade instance with PnL
        """
        # Verify the string representation
        repr_str = str(enriched_trade)
        assert (
            "EnrichedTrade" in repr_str
        ), "String representation should include class name"
        assert "ETH/USDT" in repr_str, "String representation should include token pair"
        assert (
            "pnl_usd=100.0" in repr_str
        ), "String representation should include PnL USD"

    def test_enriched_trade_repr_without_pnl(self, enriched_trade_without_pnl):
        """Test the string representation of an EnrichedTrade instance without PnL.

        Args:
            enriched_trade_without_pnl: Fixture providing an EnrichedTrade instance without PnL
        """
        # Verify the string representation
        repr_str = str(enriched_trade_without_pnl)
        assert (
            "EnrichedTrade" in repr_str
        ), "String representation should include class name"
        assert "ETH/USDT" in repr_str, "String representation should include token pair"
        assert (
            "pnl_usd=None" in repr_str
        ), "String representation should show PnL USD as None"

    def test_enriched_trade_db_integration(self, session):
        """Test database integration with the EnrichedTrade model.

        Args:
            session: SQLAlchemy session fixture
        """
        # Create a new EnrichedTrade instance
        trade = EnrichedTrade()
        trade.id = uuid.uuid4()
        trade.event_at = datetime.now()
        trade.txn_id = (
            "0x1234567890123456789012345678901234567890123456789012345678901234"
        )
        trade.wallet_address = "0x1234567890123456789012345678901234567890"
        trade.chain_id = 1
        trade.exchange = "uniswap"
        trade.is_buy = True
        trade.token_price = Decimal("1000.0")
        trade.token_symbol_pair = "ETH/USDT"
        trade.token_address_pair = "0x1234567890123456789012345678901234567890/0x0987654321098765432109876543210987654321"
        trade.base_token_symbol = "ETH"
        trade.quote_token_symbol = "USDT"
        trade.base_token_address = "0x1234567890123456789012345678901234567890"
        trade.quote_token_address = "0x0987654321098765432109876543210987654321"
        trade.base_amount = Decimal("1.0")
        trade.quote_amount = Decimal("1000.0")
        trade.usd_amount = Decimal("1000.0")
        trade.market_type = MarketType.SPOT
        trade.pnl_usd = Decimal("100.0")
        trade.pnl = Decimal("0.1")
        trade.roi = Decimal("0.1")
        trade.holding_duration = timedelta(days=7)

        # Add to session and commit
        session.add(trade)
        session.commit()

        # Verify the trade was saved to the database
        retrieved = session.query(EnrichedTrade).filter_by(id=trade.id).first()
        assert (
            retrieved is not None
        ), "EnrichedTrade should be retrievable from database"
        assert retrieved.id == trade.id, "Retrieved ID should match"
        assert (
            retrieved.wallet_address == "0x1234567890123456789012345678901234567890"
        ), "Retrieved wallet address should match"
        assert (
            retrieved.token_symbol_pair == "ETH/USDT"
        ), "Retrieved token symbol pair should match"
        assert retrieved.pnl_usd == Decimal("100.0"), "Retrieved PnL USD should match"


if __name__ == "__main__":
    pytest.main(["-v", __file__])