diff options
| author | Danilo M. <danix@danix.xyz> | 2026-07-02 09:21:27 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-07-02 09:21:27 +0200 |
| commit | 71658d023fdbf60be6b4501372519bf8171d6e13 (patch) | |
| tree | bf9adcd6bfd60b56303dad219dfe79b003fe0818 | |
| parent | 166f82d0bfdc598099c088275d68dc42499694f9 (diff) | |
| download | firefly-cli-71658d023fdbf60be6b4501372519bf8171d6e13.tar.gz firefly-cli-71658d023fdbf60be6b4501372519bf8171d6e13.zip | |
v0.3.7 placed the @registry.command decorator above a helper
(_resolve_side) inserted between the decorator and cmd_add, so the
registry bound the helper as the "tx add" handler. Unit tests call
cmd_add directly and missed it; live CLI dispatch failed with
"_resolve_side() missing 2 required positional arguments". Move the
helper above the decorator and add a regression test asserting the
registered handler is cmd_add.
Found by live smoke test against the test instance. Also note in
resolver that Firefly returns 401 (not 404) for an unknown account id.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| -rw-r--r-- | firefly_cli/__init__.py | 2 | ||||
| -rw-r--r-- | firefly_cli/commands/transaction.py | 2 | ||||
| -rw-r--r-- | firefly_cli/resolver.py | 5 | ||||
| -rw-r--r-- | pyproject.toml | 2 | ||||
| -rw-r--r-- | tests/unit/test_commands_transaction.py | 8 |
5 files changed, 15 insertions, 4 deletions
diff --git a/firefly_cli/__init__.py b/firefly_cli/__init__.py index 1ed8352..66300ca 100644 --- a/firefly_cli/__init__.py +++ b/firefly_cli/__init__.py @@ -2,4 +2,4 @@ # Copyright (C) 2026 Danilo M. <danix@danix.xyz> # Licensed under the GNU General Public License v2.0 only. -__version__ = "0.3.7" +__version__ = "0.3.8" diff --git a/firefly_cli/commands/transaction.py b/firefly_cli/commands/transaction.py index 3ce20f3..60af6f4 100644 --- a/firefly_cli/commands/transaction.py +++ b/firefly_cli/commands/transaction.py @@ -39,7 +39,6 @@ def _add_args(p): p.add_argument("--skip-dupes", dest="skip_dupes", action="store_true", help="skip if a tx with same amount+date+source+destination exists") -@registry.command("tx add", help="record a transaction; source/destination resolve to accounts, category/tags auto-create", args=_add_args) def _resolve_side(ctx, name, acc_id, side): # Exactly one of name/id per side (mutually exclusive). id path (ISSUES.md # #2) fetches by id, validating existence; name path resolves as before. @@ -49,6 +48,7 @@ def _resolve_side(ctx, name, acc_id, side): f"(got name={name!r}, id={acc_id!r})") return ctx.resolver.account_by_id(acc_id) if acc_id else ctx.resolver.account(name) +@registry.command("tx add", help="record a transaction; source/destination resolve to accounts, category/tags auto-create", args=_add_args) def cmd_add(args, ctx): src = _resolve_side(ctx, args.source, args.source_id, "from") dst = _resolve_side(ctx, args.dest, args.dest_id, "to") diff --git a/firefly_cli/resolver.py b/firefly_cli/resolver.py index 2a73e79..7296aad 100644 --- a/firefly_cli/resolver.py +++ b/firefly_cli/resolver.py @@ -30,7 +30,10 @@ class Resolver: def account_by_id(self, acc_id): # Escape hatch for same-name accounts (ISSUES.md #2): GET the account - # directly; a bad id 404s and client.request surfaces a FireflyError. + # directly; a bad id errors and client.request surfaces a FireflyError. + # ponytail: Firefly returns 401 (not 404) for an unknown account id, so + # the message reads "Unauthenticated"; the write is still blocked, which + # is what matters. Remap to "account not found" only if it confuses users. item = self.client.request("GET", f"/api/v1/accounts/{acc_id}")["data"] return {"id": item["id"], **item.get("attributes", {})} diff --git a/pyproject.toml b/pyproject.toml index a356bd8..ae35bd7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "firefly-iii-agent" -version = "0.3.7" +version = "0.3.8" description = "CLI tool for agent interaction with Firefly III" readme = "README.md" requires-python = ">=3.11" diff --git a/tests/unit/test_commands_transaction.py b/tests/unit/test_commands_transaction.py index 5f455cb..61a09ab 100644 --- a/tests/unit/test_commands_transaction.py +++ b/tests/unit/test_commands_transaction.py @@ -192,6 +192,14 @@ class TestTxAdd(unittest.TestCase): self.assertEqual(rc, 0) client.request.assert_not_called() # dry-run wins: no search, no write + def test_tx_add_handler_registered_is_cmd_add(self): + # Guard the decorator placement: the @registry.command must wrap cmd_add, + # not a helper defined between the decorator and the def (a misplacement + # unit tests calling cmd_add directly would miss, but CLI dispatch hits). + from firefly_cli import registry + h = next(c.handler for c in registry.all_commands() if c.name == "tx add") + self.assertIs(h, tx.cmd_add) + def test_from_id_resolves_by_id_not_name(self): # --to-id targets an ambiguous account by numeric id (ISSUES.md #2). ctx, client, resolver = make_ctx() |
