chore: audit test suite + retire legacy addTransaction (Issue #11)#14
Merged
Conversation
Inventory gated/legacy tests, retire the legacy hledger-add write path, and make CI actually run the suite with hledger available. - Retire addTransaction: migrate categories.post.ts to appendTransaction (the direct journal writer) and delete the function. One write path now; the friendly control-char guard stays, with validateTransaction as backstop. - Clean tests: delete F1 (engine-behavior assertion), F2 (legacy round-trip), and F4 (a non-skipped test coupled to addTransaction's existence, missed by the original skip/gate sweep). Keep F3 (timeout-kill) + its graceful skip and the two module-invariant tests. Repoint/remove the addTransaction stubs. - CI: add a `test` job (npm ci -> install hledger -> hledger --version gate -> npm run test) so the hledger-gated test runs for real instead of no-op'ing. typecheck job untouched. - Coverage: add a non-default budget-base assign route test (R6.1). - Deliverable: outcome.md records F1-F4 verdicts, a path-coverage map, and follow-ups (hidden-envelopes + journal create/export route coverage). Full suite (40 files) green; nuxi typecheck exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The new CI test job (Issue #11) exposed a latent path-traversal hole that Windows-only local runs could not catch. safeJournalPath used the platform basename to detect separators; on POSIX that is path.posix.basename, which treats `\` as a normal filename char — so `a\x.journal` was rejected on Windows but accepted on Linux. Use win32.basename (treats `/`, `\`, and `C:` drive prefixes as separators) so path-bearing names are rejected identically on every OS. The test's sanity helper had the same platform dependency; switched it to an explicit /[\/]/ check. The load-bearing "must throw" assertion is unchanged. journalFiles.test.ts: 11/11 pass; full suite 40 files green; typecheck exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #11. Relates to #4.
Audits the test suite for tests that aren't protecting us (skipped, env-gated, legacy-path, or asserting hledger's own behavior), retires the legacy
addTransactionwrite path, and makes CI actually run the suite with hledger installed.Spec:
.kiro/specs/audit-test-suite/(design → requirements → tasks → outcome.md = the audit deliverable).What changed
Retire the legacy write path
categories.post.tsnow writes viaappendTransaction(the direct journal writer), notaddTransaction(hledger addover stdin). One write path now.addTransactionfromserver/utils/hledger.ts.fieldHasIllegalChars400 stays;validateTransactioninsideappendTransactionis the backstop, so the injection guard does not regress.Clean the tests
addTransactionexisting in source, missed by the original skip/gate sweep and caught during implementation (recorded in design.md as a tracked correction, with R3.6).HLEDGER_TIMEOUT_MS=1timeout-kill test) and its gracefulif (!hledgerAvailable) returnskip, plus the two module-invariant tests (hledger.ts performs nofswrites / does not importfs).addTransactiontest stubs.CI runs the suite with hledger
testjob to.github/workflows/ci.yml:npm ci→ install hledger →hledger --version(fail-loud gate) →npm run test. Install every run, no cache (ephemeral runners; a stale cache could reintroduce the silent skip).typecheckjob untouched.🔒 Bug the new CI job immediately caught (cross-platform path traversal)
safeJournalPath(server/utils/journalFiles.ts) used the platformbasenameto detect separators. On POSIX that ispath.posix.basename, which treats\as an ordinary filename char — soa\x.journalwas rejected on Windows but accepted on Linux (the likely deployment OS).win32.basename(strict:/,\, andC:drive prefixes) so path-bearing names are rejected identically on every OS. The matching test's sanity helper had the same platform dependency and was switched to an explicit/[\\/]/check; the load-bearing "must throw" assertion is unchanged.Coverage
budget/transferechoes fully-qualified envelope paths and has no base concept, so it's correctly out of scope.Verification
npx vitest run— 40 files, all pass (local; hledger present → F3 ran).npx nuxi typecheck— exit 0, no type errors.any/asadded to production code.Follow-ups (documented in outcome.md, not closed here)
hidden-envelopes.get/post(incl. zero-balance-before-hide).journal/create.postandjournal/export.get.🤖 Generated with Claude Code