Skip to content

feat(domain): unit test infrastructure + expenses logic coverage#4

Merged
sergdort merged 2 commits intomainfrom
feat/domain-unit-tests
Feb 27, 2026
Merged

feat(domain): unit test infrastructure + expenses logic coverage#4
sergdort merged 2 commits intomainfrom
feat/domain-unit-tests

Conversation

@LogenNineFingersIsAlive
Copy link
Collaborator

Summary

Adds unit testing infrastructure to the domain package with coverage reporting in CI.

What changed

New: expenses-logic.ts (pure logic extraction)

Extracted all pure business logic functions from expenses.service.ts into a separate, testable module:

  • normalizeTransferDirection, normalizeExpenseKind, normalizeCounterpartyType
  • assertPositiveAmountMinor, isTransferKind
  • deriveExpenseKind — kind derivation from category + request
  • computeRecoverableMinor — reimbursement recovery calculation
  • deriveReimbursementStatus — state machine (none → expected → partial → settled / written_off)
  • enrichExpensesWithReimbursements — batch enrichment
  • resolveReimbursableDefaults — category mode → row reimbursable resolution
  • validateAndResolveMyShareMinor — share validation with boundary checks

New: 72 unit tests (expenses-logic.test.ts)

Covers all extracted functions with edge cases:

  • normalisation of invalid/null/undefined inputs
  • positive amount validation (0, negative, float rejection)
  • kind derivation across expense/income/transfer categories
  • reimbursement status transitions through all states
  • reimbursable default resolution across all category modes
  • myShare validation boundaries

Coverage reporting

  • expenses-logic.ts: 100% statements, branches, functions, lines
  • Domain package baseline: ~5% overall (repositories + other services untested at unit level — covered by existing integration tests in tests/domain/)

CI changes

  • Added Domain unit tests + coverage step after existing test step
  • Coverage artifact uploaded per run (14-day retention)
  • No hard coverage threshold yet — establishing baseline first

Files

  • packages/domain/src/services/expenses-logic.ts (new)
  • packages/domain/src/services/__tests__/expenses-logic.test.ts (new)
  • packages/domain/src/services/expenses.service.ts (imports from logic module, no behaviour change)
  • packages/domain/package.json (vitest + coverage deps)
  • packages/domain/vitest.config.ts (new)
  • .github/workflows/ci.yml (coverage step + artifact)
  • pnpm-lock.yaml

Notes

  • Existing CLI test accepts monzo sync --override syntax fails locally only due to live Monzo connection in dev DB — passes in CI (clean DB). Pre-existing, not caused by this PR.
  • Existing integration tests in tests/domain/ continue to pass unchanged.

- extract pure business logic from expenses.service into expenses-logic.ts
- add 72 unit tests covering: normalisation, validation, kind derivation,
  reimbursement status state machine, reimbursable defaults, myShare validation
- add vitest + @vitest/coverage-v8 to domain package
- add domain coverage step to CI workflow with artifact upload
- expenses-logic.ts at 100% statement/branch/function/line coverage
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request establishes unit testing infrastructure for the domain package by extracting pure business logic from expenses.service.ts into a separate testable module. This is the first instance of unit tests at the package level, with existing integration tests remaining in the tests/domain/ directory.

Changes:

  • Extracted 8 pure business logic functions from expenses service into expenses-logic.ts for testability
  • Added 72 comprehensive unit tests covering all edge cases including normalization, validation, kind derivation, and reimbursement state transitions
  • Configured Vitest with coverage reporting in CI pipeline (14-day artifact retention)

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/domain/src/services/expenses-logic.ts New module containing pure business logic functions extracted from expenses service - no I/O or database operations
packages/domain/src/services/__tests__/expenses-logic.test.ts Comprehensive test suite with 72 tests achieving 100% coverage of the logic module
packages/domain/src/services/expenses.service.ts Refactored to import functions from expenses-logic module, removing 264 lines of duplicated logic
packages/domain/vitest.config.ts New Vitest configuration for domain package unit tests with v8 coverage provider
packages/domain/package.json Added vitest and @vitest/coverage-v8 dev dependencies with test scripts
.github/workflows/ci.yml Added domain unit test step with coverage artifact upload
pnpm-lock.yaml Locked new testing dependencies including vitest 3.2.4 and coverage tooling
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sergdort sergdort merged commit 24ac847 into main Feb 27, 2026
5 checks passed
@sergdort sergdort deleted the feat/domain-unit-tests branch February 28, 2026 00:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants