From 50cb852130986249cacec411e23392a8610e12f1 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sun, 5 Jul 2026 19:17:04 +0200 Subject: feat(budget): tx edit --budget and budget update (v0.5.0) Add two deferred budget follow-ups: - tx edit --budget: re-assign a budget on an existing transaction, mirroring the existing tx add --budget flag (name/id resolved, hard error on miss). Resolves the ISSUES.md backfill wish. - budget update: rename a budget and/or edit its auto-budget fields via PUT /budgets/{id}; only fields passed are sent, empty is a hard error. New command adds to the CLI surface without breaking callers, so this is a MINOR bump (0.4.1 -> 0.5.0). Docs (README, SKILL.md), completion, and TODO synced. The tx add --budget-id item stays open (still YAGNI). Co-Authored-By: Claude Opus 4.8 --- tests/unit/test_commands_transaction.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'tests/unit/test_commands_transaction.py') diff --git a/tests/unit/test_commands_transaction.py b/tests/unit/test_commands_transaction.py index 7366b5c..ec4e54c 100644 --- a/tests/unit/test_commands_transaction.py +++ b/tests/unit/test_commands_transaction.py @@ -274,7 +274,8 @@ class TestTxEdit(unittest.TestCase): ctx, client, resolver = make_ctx() client.request.return_value = {"data": {"id": "9", "attributes": {}}} args = MagicMock(id="9", amount="12.00", date=None, desc="fixed", - source=None, dest=None, category=None, tags=None, type=None) + source=None, dest=None, category=None, tags=None, + budget=None, type=None) rc = tx.cmd_edit(args, ctx) self.assertEqual(rc, 0) method, path = client.request.call_args[0][:2] @@ -291,7 +292,8 @@ class TestTxEdit(unittest.TestCase): }[n] client.request.return_value = {"data": {"id": "9", "attributes": {}}} args = MagicMock(id="9", amount=None, date=None, desc=None, - source="BBVA", dest="Medio", category=None, tags=None, type=None) + source="BBVA", dest="Medio", category=None, tags=None, + budget=None, type=None) tx.cmd_edit(args, ctx) split = client.request.call_args[1]["body"]["transactions"][0] self.assertEqual(split, {"source_id": "3", "destination_id": "4"}) @@ -300,7 +302,8 @@ class TestTxEdit(unittest.TestCase): ctx, client, resolver = make_ctx() client.request.return_value = {"data": {"id": "9", "attributes": {}}} args = MagicMock(id="9", amount=None, date=None, desc=None, source=None, - dest=None, category="Cat", tags="a, b", type="transfer") + dest=None, category="Cat", tags="a, b", budget=None, + type="transfer") tx.cmd_edit(args, ctx) split = client.request.call_args[1]["body"]["transactions"][0] self.assertEqual(split, @@ -311,11 +314,22 @@ class TestTxEdit(unittest.TestCase): from firefly_cli.errors import FireflyError ctx, client, _ = make_ctx() args = MagicMock(id="9", amount=None, date=None, desc=None, source=None, - dest=None, category=None, tags=None, type=None) + dest=None, category=None, tags=None, budget=None, type=None) with self.assertRaises(FireflyError): tx.cmd_edit(args, ctx) client.request.assert_not_called() + def test_edit_budget_ref_sets_budget_id(self): + ctx, client, resolver = make_ctx() + resolver.budget.return_value = {"id": "12", "name": "Groceries"} + client.request.return_value = {"data": {"id": "9", "attributes": {}}} + args = MagicMock(id="9", amount=None, date=None, desc=None, source=None, + dest=None, category=None, tags=None, budget="Groceries", + type=None) + tx.cmd_edit(args, ctx) + split = client.request.call_args[1]["body"]["transactions"][0] + self.assertEqual(split, {"budget_id": "12"}) + class TestTxDelete(unittest.TestCase): def test_delete_requires_yes(self): -- cgit v1.2.3