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
|
# Copyright (C) 2026 Danilo M. <danix@danix.xyz> GPL-2.0-only
import unittest
from unittest.mock import MagicMock
from types import SimpleNamespace
import firefly_cli.commands.budget as budget
def _ctx(client=None, resolver=None):
return SimpleNamespace(client=client or MagicMock(),
resolver=resolver or MagicMock(), human=False)
class TestBudgetList(unittest.TestCase):
def test_list_defaults_to_current_month(self):
client = MagicMock()
client.request.return_value = {"data": []}
args = SimpleNamespace(start=None, end=None)
rc = budget.cmd_list(args, _ctx(client=client))
self.assertEqual(rc, 0)
_, kwargs = client.request.call_args
params = kwargs["params"]
self.assertTrue(params["start"].endswith("-01"))
self.assertEqual(params["start"][:7], params["end"][:7])
def test_list_explicit_range(self):
client = MagicMock()
client.request.return_value = {"data": []}
args = SimpleNamespace(start="2026-01-01", end="2026-01-31")
budget.cmd_list(args, _ctx(client=client))
_, kwargs = client.request.call_args
self.assertEqual(kwargs["params"],
{"start": "2026-01-01", "end": "2026-01-31"})
class TestBudgetCreate(unittest.TestCase):
def test_create_minimal_active(self):
client = MagicMock()
client.request.return_value = {"data": {"id": "9", "attributes": {"name": "Fun"}}}
args = SimpleNamespace(name="Fun", active=True, currency=None,
auto_budget_amount=None, auto_budget_period=None,
auto_budget_type=None)
rc = budget.cmd_create(args, _ctx(client=client))
self.assertEqual(rc, 0)
method, path = client.request.call_args[0][:2]
body = client.request.call_args[1]["body"]
self.assertEqual((method, path), ("POST", "/api/v1/budgets"))
self.assertEqual(body["name"], "Fun")
self.assertTrue(body["active"])
def test_create_inactive_with_auto_budget(self):
client = MagicMock()
client.request.return_value = {"data": {"id": "9", "attributes": {}}}
args = SimpleNamespace(name="Cap", active=False, currency="EUR",
auto_budget_amount="500", auto_budget_period="monthly",
auto_budget_type="reset")
budget.cmd_create(args, _ctx(client=client))
body = client.request.call_args[1]["body"]
self.assertFalse(body["active"])
self.assertEqual(body["auto_budget_amount"], "500")
self.assertEqual(body["auto_budget_type"], "reset")
self.assertEqual(body["currency_code"], "EUR")
class TestBudgetSpent(unittest.TestCase):
def test_human_mode_replaces_spent_with_scalar(self):
client = MagicMock()
client.request.return_value = {"data": [
{"id": "1", "attributes": {"name": "Food",
"spent": [{"sum": "-12.50"}, {"sum": "-2.50"}]}}]}
ctx = _ctx(client=client)
ctx.human = True
captured = {}
import firefly_cli.output as output
orig = output.emit
def spy(data, human=False, stream=None):
captured["rows"] = data
output.emit = spy
try:
budget.cmd_list(SimpleNamespace(start=None, end=None), ctx)
finally:
output.emit = orig
self.assertEqual(captured["rows"][0]["spent"], "-15.00")
if __name__ == "__main__":
unittest.main()
|