nomy-data-models 0.35.6

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

import uuid
from datetime import datetime
from decimal import Decimal

import pytest

from nomy_data_models.models.raw_trade import RawTrade
from nomy_data_models.models.trade_base import MarketType


@pytest.fixture
def raw_trade():
    """Fixture providing a RawTrade instance with predefined values."""
    trade = RawTrade()
    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.extra_data = {"is_twap": True, "other_flag": False}
    return trade


@pytest.fixture
def minimal_raw_trade():
    """Fixture providing a RawTrade instance with minimal required attributes."""
    trade = RawTrade()
    trade.id = uuid.uuid4()
    trade.wallet_address = "0x1234567890123456789012345678901234567890"
    trade.token_symbol_pair = "ETH/USDT"
    trade.is_buy = True
    return trade


class TestRawTrade:
    """Test cases for RawTrade model."""

    def test_raw_trade_creation(self, raw_trade):
        """Test creating a RawTrade instance with all attributes.

        Args:
            raw_trade: Fixture providing a fully populated RawTrade instance
        """
        # Verify the instance was created correctly
        assert raw_trade.id is not None, "ID should be set"
        assert raw_trade.event_at is not None, "Event timestamp should be set"
        assert (
            raw_trade.txn_id
            == "0x1234567890123456789012345678901234567890123456789012345678901234"
        ), "Transaction ID should match"
        assert (
            raw_trade.wallet_address == "0x1234567890123456789012345678901234567890"
        ), "Wallet address should match"
        assert raw_trade.chain_id == 1, "Chain ID should be 1"
        assert raw_trade.exchange == "uniswap", "Exchange should be 'uniswap'"
        assert raw_trade.is_buy is True, "is_buy should be True"
        assert raw_trade.token_price == Decimal(
            "1000.0"
        ), "Token price should be 1000.0"
        assert (
            raw_trade.token_symbol_pair == "ETH/USDT"
        ), "Token symbol pair should be 'ETH/USDT'"
        assert (
            raw_trade.token_address_pair
            == "0x1234567890123456789012345678901234567890/0x0987654321098765432109876543210987654321"
        ), "Token address pair should match"
        assert raw_trade.base_token_symbol == "ETH", "Base token symbol should be 'ETH'"
        assert (
            raw_trade.quote_token_symbol == "USDT"
        ), "Quote token symbol should be 'USDT'"
        assert (
            raw_trade.base_token_address == "0x1234567890123456789012345678901234567890"
        ), "Base token address should match"
        assert (
            raw_trade.quote_token_address
            == "0x0987654321098765432109876543210987654321"
        ), "Quote token address should match"
        assert raw_trade.base_amount == Decimal("1.0"), "Base amount should be 1.0"
        assert raw_trade.quote_amount == Decimal(
            "1000.0"
        ), "Quote amount should be 1000.0"
        assert raw_trade.usd_amount == Decimal("1000.0"), "USD amount should be 1000.0"
        assert raw_trade.market_type == MarketType.SPOT, "Market type should be SPOT"
        assert raw_trade.extra_data == {
            "is_twap": True,
            "other_flag": False,
        }, "Extra data should match"

    def test_raw_trade_repr(self, minimal_raw_trade):
        """Test the string representation of a RawTrade.

        Args:
            minimal_raw_trade: Fixture providing a RawTrade with minimal attributes
        """
        # Verify the string representation
        expected_repr = f"<RawTrade(id={minimal_raw_trade.id}, wallet=0x123456..., pair=ETH/USDT, is_buy=True)"
        assert (
            str(minimal_raw_trade) == expected_repr
        ), "String representation should match expected format"

    def test_raw_trade_db_integration(self, session):
        """Test database integration with the RawTrade model.

        Args:
            session: SQLAlchemy session fixture
        """
        # Create a new RawTrade instance
        trade = RawTrade()
        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.extra_data = {"is_twap": True, "other_flag": False}

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

        # Verify the trade was saved to the database
        retrieved = session.query(RawTrade).filter_by(id=trade.id).first()
        assert retrieved is not None, "Trade should be retrievable from database"
        assert retrieved.id == trade.id, "Retrieved trade 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.extra_data == {
            "is_twap": True,
            "other_flag": False,
        }, "Retrieved extra data should match"

    def test_extra_data_null(self, session):
        """Test that extra_data can be null."""
        trade = RawTrade()
        trade.event_at = datetime.now()
        trade.txn_id = "0x123"
        trade.wallet_address = "0x1234567890123456789012345678901234567890"
        trade.chain_id = 1
        trade.exchange = "test_exchange"
        trade.token_price = Decimal("100.0")
        trade.token_symbol_pair = "BTC/USD"
        trade.base_token_symbol = "BTC"
        trade.quote_token_symbol = "USD"
        trade.base_amount = Decimal("1.0")
        trade.quote_amount = Decimal("100.0")
        trade.market_type = MarketType.SPOT
        trade.extra_data = None

        session.add(trade)
        session.commit()

        retrieved = session.query(RawTrade).filter_by(id=trade.id).first()
        assert retrieved.extra_data is None, "Extra data should be null"

    def test_extra_data_empty(self, session):
        """Test that extra_data can be an empty dict."""
        trade = RawTrade()
        trade.event_at = datetime.now()
        trade.txn_id = "0x123"
        trade.wallet_address = "0x1234567890123456789012345678901234567890"
        trade.chain_id = 1
        trade.exchange = "test_exchange"
        trade.token_price = Decimal("100.0")
        trade.token_symbol_pair = "BTC/USD"
        trade.base_token_symbol = "BTC"
        trade.quote_token_symbol = "USD"
        trade.base_amount = Decimal("1.0")
        trade.quote_amount = Decimal("100.0")
        trade.market_type = MarketType.SPOT
        trade.extra_data = {}

        session.add(trade)
        session.commit()

        retrieved = session.query(RawTrade).filter_by(id=trade.id).first()
        assert retrieved.extra_data == {}, "Extra data should be empty dict"

    def test_extra_data_nested(self, session):
        """Test that extra_data can contain nested structures."""
        nested_data = {
            "is_twap": True,
            "metadata": {
                "source": "api",
                "version": "1.0",
                "flags": {"is_high_priority": True, "requires_verification": False},
            },
        }

        trade = RawTrade()
        trade.event_at = datetime.now()
        trade.txn_id = "0x123"
        trade.wallet_address = "0x1234567890123456789012345678901234567890"
        trade.chain_id = 1
        trade.exchange = "test_exchange"
        trade.token_price = Decimal("100.0")
        trade.token_symbol_pair = "BTC/USD"
        trade.base_token_symbol = "BTC"
        trade.quote_token_symbol = "USD"
        trade.base_amount = Decimal("1.0")
        trade.quote_amount = Decimal("100.0")
        trade.market_type = MarketType.SPOT
        trade.extra_data = nested_data

        session.add(trade)
        session.commit()

        retrieved = session.query(RawTrade).filter_by(id=trade.id).first()
        assert (
            retrieved.extra_data == nested_data
        ), "Extra data should match nested structure"


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