feat(domain): unit test infrastructure + expenses logic coverage#4
Merged
feat(domain): unit test infrastructure + expenses logic coverage#4
Conversation
- 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
There was a problem hiding this comment.
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.tsfor 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.
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.
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.tsinto a separate, testable module:normalizeTransferDirection,normalizeExpenseKind,normalizeCounterpartyTypeassertPositiveAmountMinor,isTransferKindderiveExpenseKind— kind derivation from category + requestcomputeRecoverableMinor— reimbursement recovery calculationderiveReimbursementStatus— state machine (none → expected → partial → settled / written_off)enrichExpensesWithReimbursements— batch enrichmentresolveReimbursableDefaults— category mode → row reimbursable resolutionvalidateAndResolveMyShareMinor— share validation with boundary checksNew: 72 unit tests (
expenses-logic.test.ts)Covers all extracted functions with edge cases:
Coverage reporting
expenses-logic.ts: 100% statements, branches, functions, linestests/domain/)CI changes
Domain unit tests + coveragestep after existing test stepFiles
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.yamlNotes
accepts monzo sync --override syntaxfails locally only due to live Monzo connection in dev DB — passes in CI (clean DB). Pre-existing, not caused by this PR.tests/domain/continue to pass unchanged.