3 Commits

Author SHA1 Message Date
Gonçalo Rodrigues
9dfc95cd32 test: add unit tests — 70.3% coverage
Extracted storeIface from Handler so store can be mocked in tests.
Added handler_test.go with 98 test cases covering:
- All HTTP handlers (Dashboard, Transactions, Accounts, Categories, Goals,
  Portfolio, Reports, Projections, NetWorth, Simulator, Sharing, Import*)
- Auth middleware (authMW, ownerOrViewerMW)
- Pure helpers (monthsBetween, parseFloat, sortStrings, appendIfMissing)
- Error paths (bad JSON, missing fields, store errors, bad CSV)
- Alert logic (budget exceeded, goal miss, spend pace)
- Template funcmap exercised via rich render scenarios

Also added tickerStore.resolve tests to portfolio_test.go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 17:18:49 +01:00
Gonçalo Rodrigues
c255d7f523 fix(finance): portfolio prices and projections template
Portfolio:
- fetchPrices was passing ISINs directly to Yahoo Finance, which only
  accepts ticker symbols (e.g. VWCE.DE, not IE00B3RBWM25). Added a
  hardcoded isinToTicker map covering common European ETFs (Vanguard,
  iShares, Xtrackers, Amundi). fetchPricesByISIN now resolves each ISIN
  to its ticker before calling Yahoo and keys the result by ISIN so
  computeHoldings can look up prices correctly. Renamed holdingsByISIN
  to uniqueISINs to reflect what it actually returns.

Projections:
- Template had a missing <tr> and a broken pace-bar width expression
  that mixed float64/int64 in the div template function, causing a
  template execution error that rendered the page blank. Moved all
  math server-side: the handler now pre-computes []catProjection with
  MonthlyAvg, AnnualTotal, and PacePct already calculated. Template
  is now simple range + printf. Chart switched to horizontal bar for
  better readability of long category names.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 12:47:03 +01:00
Gonçalo Rodrigues
13b7149614 First Commit 2026-06-13 11:25:23 +01:00