"""The mapping table must cover the SDK's enum exactly — no silent `other`.""" import pytest from t_tech.invest import OperationType from fintracker.models.ledger import EventKind from fintracker.sources.tinvest.mapper import ( OPERATION_KINDS, UnknownOperationType, kind_for, ) def test_all_operation_types_mapped(): """A new SDK value fails here instead of quietly becoming `other` in the ledger.""" sdk = {m.name for m in OperationType} assert sdk - set(OPERATION_KINDS) == set(), "не замаплены новые типы операций" def test_no_stale_entries(): """And a value dropped by the SDK does not linger in the table.""" sdk = {m.name for m in OperationType} assert set(OPERATION_KINDS) - sdk == set(), "в таблице остались типы, которых нет в SDK" def test_unknown_type_raises(): with pytest.raises(UnknownOperationType): kind_for("OPERATION_TYPE_FROM_THE_FUTURE") @pytest.mark.parametrize( ("op_type", "expected"), [ ("OPERATION_TYPE_BUY", EventKind.buy), ("OPERATION_TYPE_BUY_MARGIN", EventKind.buy), ("OPERATION_TYPE_SELL", EventKind.sell), ("OPERATION_TYPE_INPUT", EventKind.deposit), ("OPERATION_TYPE_OUTPUT", EventKind.withdrawal), ("OPERATION_TYPE_INPUT_SECURITIES", EventKind.transfer_in), ("OPERATION_TYPE_COUPON", EventKind.coupon), ("OPERATION_TYPE_DIVIDEND", EventKind.dividend), ("OPERATION_TYPE_BOND_REPAYMENT", EventKind.amortization), ("OPERATION_TYPE_BOND_REPAYMENT_FULL", EventKind.repayment), ("OPERATION_TYPE_BROKER_FEE", EventKind.commission), ("OPERATION_TYPE_TRACK_MFEE", EventKind.commission), ("OPERATION_TYPE_DIVIDEND_TAX", EventKind.tax), ], ) def test_representative_mappings(op_type, expected): assert kind_for(op_type) == expected def test_tax_correction_follows_the_sign(): """A positive correction is money returned, so it is a refund, not a tax.""" from decimal import Decimal assert kind_for("OPERATION_TYPE_TAX_CORRECTION", Decimal("-10")) == EventKind.tax assert kind_for("OPERATION_TYPE_TAX_CORRECTION", Decimal("10")) == EventKind.tax_refund