aboutsummaryrefslogtreecommitdiff
path: root/tests/models/thl/test_ledger.py
blob: 7c48dbdb39e435794e18ba2ee1ec2baeb4c92d36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
from __future__ import annotations

from datetime import UTC, datetime
from uuid import uuid4

import pytest
from pydantic import ValidationError

from generalresearch.models.thl.ledger import (
    AccountType,
    Direction,
    LedgerAccount,
    LedgerEntry,
    LedgerTransaction,
)


class TestLedgerTransaction:

    def test_create(self):
        # Can create with nothing ...
        t = LedgerTransaction()
        assert [] == t.entries
        assert {} == t.metadata
        t = LedgerTransaction(
            created=datetime.now(tz=UTC),
            metadata={"a": "b", "user": "1234"},
            ext_description="foo",
        )

    def test_ledger_entry(self):
        with pytest.raises(expected_exception=ValidationError) as cm:
            LedgerEntry(
                direction=Direction.CREDIT,
                account_uuid="3f3735eaed264c2a9f8a114934afa121",
                amount=0,
            )
        assert "Input should be greater than 0" in str(cm.value)

        with pytest.raises(ValidationError) as cm:
            LedgerEntry(
                direction=Direction.CREDIT,
                account_uuid="3f3735eaed264c2a9f8a114934afa121",
                amount=2**65,
            )
        assert "Input should be less than 9223372036854775807" in str(cm.value)

        with pytest.raises(ValidationError) as cm:
            LedgerEntry(
                direction=Direction.CREDIT,
                account_uuid="3f3735eaed264c2a9f8a114934afa121",
                amount=1.2,
            )
        assert "Input should be a valid integer" in str(cm.value)

    def test_entries(self):
        entries = [
            LedgerEntry(
                direction=Direction.CREDIT,
                account_uuid="3f3735eaed264c2a9f8a114934afa121",
                amount=100,
            ),
            LedgerEntry(
                direction=Direction.DEBIT,
                account_uuid="5927621462814f9893be807db850a31b",
                amount=100,
            ),
        ]
        LedgerTransaction(entries=entries)

    def test_raises_entries(self):
        entries = [
            LedgerEntry(
                direction=Direction.DEBIT,
                account_uuid="3f3735eaed264c2a9f8a114934afa121",
                amount=100,
            ),
            LedgerEntry(
                direction=Direction.DEBIT,
                account_uuid="5927621462814f9893be807db850a31b",
                amount=100,
            ),
        ]
        with pytest.raises(ValidationError) as e:
            LedgerTransaction(entries=entries)
        assert "ledger entries must balance" in str(e.value)

        entries = [
            LedgerEntry(
                direction=Direction.DEBIT,
                account_uuid="3f3735eaed264c2a9f8a114934afa121",
                amount=100,
            ),
            LedgerEntry(
                direction=Direction.CREDIT,
                account_uuid="5927621462814f9893be807db850a31b",
                amount=101,
            ),
        ]
        with pytest.raises(ValidationError) as cm:
            LedgerTransaction(entries=entries)
        assert "ledger entries must balance" in str(cm.value)


class TestLedgerAccount:

    def test_initialization(self):
        u = uuid4().hex
        name = f"test-{u[:8]}"

        with pytest.raises(ValidationError) as cm:
            LedgerAccount(
                display_name=name,
                qualified_name="bad bunny",
                normal_balance=Direction.DEBIT,
                account_type=AccountType.BP_WALLET,
            )
        assert "qualified name should start with" in str(cm.value)

        with pytest.raises(ValidationError) as cm:
            LedgerAccount(
                display_name=name,
                qualified_name="fish sticks:bp_wallet",
                normal_balance=Direction.DEBIT,
                account_type=AccountType.BP_WALLET,
                currency="fish sticks",
            )
        assert "Invalid UUID" in str(cm.value)