Test Inventory
Bilko — Test Inventory
Status: Active — Tests Implemented
Version: 1.0
Last Updated: 2026-02-25
Author: ALAI Documentation Team
This inventory catalogs all implemented tests in Bilko, organized by package and file.
Summary
| Package |
Test Files |
Test Cases |
Status |
apps/api/tests/ |
9 test files + 1 e2e |
~99 |
Implemented |
packages/core/tests/ |
5 test files |
121 |
Implemented |
| Total |
15 |
~220 |
Active |
packages/core/tests/ — Unit Tests
Pure unit tests for the @bilko/core financial engine. No database, no HTTP. Uses globals: true (no explicit imports of describe/it/expect).
accounting.test.ts — 20 tests
Tests double-entry bookkeeping engine: validateDoubleEntry, createJournalEntry, calculateTrialBalance.
| Test Name |
What It Tests |
Status |
validateDoubleEntry - returns true for balanced entry |
Debit total equals credit total |
Implemented |
validateDoubleEntry - returns false for unbalanced entry |
Debit ≠ credit |
Implemented |
validateDoubleEntry - returns false for fewer than 2 lines |
Minimum 2 lines required |
Implemented |
validateDoubleEntry - returns false for empty lines |
Empty array → false |
Implemented |
validateDoubleEntry - returns false for negative amounts |
Negative amounts invalid |
Implemented |
validateDoubleEntry - returns false for zero amounts |
Zero amounts invalid |
Implemented |
validateDoubleEntry - handles multiple lines that sum to balanced |
Multi-line balanced entry |
Implemented |
validateDoubleEntry - handles decimal amounts with precision |
NUMERIC(19,4) precision |
Implemented |
createJournalEntry - returns entry when valid and balanced |
Happy path |
Implemented |
createJournalEntry - throws for fewer than 2 lines |
Error: "at least 2 lines" |
Implemented |
createJournalEntry - throws for empty lines array |
Error: "at least 2 lines" |
Implemented |
createJournalEntry - throws for missing description |
Error: "must have a description" |
Implemented |
createJournalEntry - throws for whitespace-only description |
Whitespace = missing |
Implemented |
createJournalEntry - throws for missing date |
Error: "must have a date" |
Implemented |
createJournalEntry - throws for unbalanced entry |
Error shows debit vs credit amounts |
Implemented |
createJournalEntry - throws for negative amount lines |
Negative amounts rejected |
Implemented |
calculateTrialBalance - returns balanced from balanced entries |
isBalanced=true, totals correct |
Implemented |
calculateTrialBalance - groups by account number |
Rows aggregated per account |
Implemented |
calculateTrialBalance - returns empty rows for no transactions |
Empty array → zero totals |
Implemented |
calculateTrialBalance - sorts rows by account number |
Rows sorted ascending |
Implemented |
chart-of-accounts.test.ts — 32 tests
Tests chart of accounts operations: account creation, parent-child hierarchy, account type validation.
| Test Area |
Test Count |
Status |
| Account creation (valid + invalid inputs) |
~10 |
Implemented |
| Account hierarchy (parent-child relationships) |
~8 |
Implemented |
| Account type validation (Asset/Liability/Equity/Revenue/Expense) |
~7 |
Implemented |
| Account code format validation (1xxx-5xxx range) |
~7 |
Implemented |
invoicing.test.ts — 22 tests
Tests invoice number generation, total calculations, and line item validation.
| Test Name |
What It Tests |
Status |
generateInvoiceNumber - generates INV-YYYY-NNN format |
Standard format |
Implemented |
generateInvoiceNumber - increments from last number |
Sequential numbering |
Implemented |
generateInvoiceNumber - pads number to 3 digits |
Zero-padding |
Implemented |
generateInvoiceNumber - handles numbers beyond 999 |
No truncation for 1000+ |
Implemented |
generateInvoiceNumber - throws for empty prefix |
Error: "prefix is required" |
Implemented |
generateInvoiceNumber - throws for whitespace-only prefix |
Whitespace = invalid |
Implemented |
generateInvoiceNumber - throws for negative lastNumber |
Error: "non-negative integer" |
Implemented |
generateInvoiceNumber - throws for non-integer lastNumber |
Float rejected |
Implemented |
calculateInvoiceTotals - calculates line item total |
quantity × unitPrice |
Implemented |
calculateInvoiceTotals - calculates subtotal as sum of lines |
Sum of all line totals |
Implemented |
calculateInvoiceTotals - calculates tax per line item |
lineTotal × taxRate / 100 |
Implemented |
calculateInvoiceTotals - calculates total = subtotal + tax |
Final total |
Implemented |
calculateInvoiceTotals - handles items without taxRate |
Missing tax = 0 |
Implemented |
calculateInvoiceTotals - returns zeros for empty items |
Empty array → all zeros |
Implemented |
calculateInvoiceTotals - handles multiple items with different rates |
Mixed 20%/10% tax |
Implemented |
calculateInvoiceTotals - maintains decimal precision |
3 × 33.33 = 99.99 |
Implemented |
validateLineItem - returns true for valid item |
Happy path |
Implemented |
validateLineItem - returns false for zero quantity |
qty=0 invalid |
Implemented |
validateLineItem - returns false for negative quantity |
qty<0 invalid |
Implemented |
validateLineItem - returns false for negative unitPrice |
price<0 invalid |
Implemented |
validateLineItem - returns false for empty description |
Description required |
Implemented |
validateLineItem - returns false for whitespace-only description |
Whitespace = empty |
Implemented |
multi-currency.test.ts — 24 tests
Tests currency conversion, exchange rate locking, and NUMERIC precision handling.
| Test Area |
Test Count |
Status |
| Currency conversion (EUR/RSD/BAM) |
~8 |
Implemented |
| Exchange rate locking at transaction date |
~6 |
Implemented |
| NUMERIC(19,4) precision (no float drift) |
~5 |
Implemented |
| Edge cases (zero rate, missing rate, same currency) |
~5 |
Implemented |
tax.test.ts — 23 tests
Tests VAT calculations for all supported countries and edge cases.
| Test Area |
Test Count |
Status |
| Serbia PDV (20% standard, 10% reduced, 0% exempt) |
~6 |
Implemented |
| BiH PDV (17% standard) |
~4 |
Implemented |
| Croatia PDV (25% standard, 13% reduced, 5% super-reduced) |
~5 |
Implemented |
| Mixed tax rates on single invoice |
~3 |
Implemented |
| Zero-rate exports |
~2 |
Implemented |
| Reverse VAT / gross-to-net |
~3 |
Implemented |
apps/api/tests/ — API Integration Tests
Integration tests for Express API endpoints. Tests use mocked Prisma client — no real database required. Setup in tests/setup.ts.
setup.ts — Test Infrastructure (not a test file)
Provides:
- Prisma client mock via
vi.mock('../src/lib/prisma')
- Environment variable setup (JWT secrets, rate limits)
createTestUser() — factory for test user objects
generateTestAccessToken() — valid JWT for authenticated requests
generateTestRefreshToken() — valid refresh token
- Constants:
TEST_ORG_ID, TEST_USER_ID, TEST_USER_EMAIL
auth.test.ts — 11 tests
| Test Name |
Route |
Status |
returns 201 with user, organization, and tokens |
POST /auth/register |
Implemented |
returns 400 for duplicate email |
POST /auth/register |
Implemented |
returns 200 with tokens for valid credentials |
POST /auth/login |
Implemented |
returns 401 for invalid password |
POST /auth/login |
Implemented |
returns 401 for non-existent email |
POST /auth/login |
Implemented |
returns 200 with new access token for valid refresh token |
POST /auth/refresh |
Implemented |
returns 401 when no refresh token cookie is present |
POST /auth/refresh |
Implemented |
returns 204 and clears cookie |
POST /auth/logout |
Implemented |
returns 200 with current user when authenticated |
GET /auth/me |
Implemented |
returns 401 when no token provided |
GET /auth/me |
Implemented |
returns 401 for invalid token |
GET /auth/me |
Implemented |
invoices.test.ts — 11 tests
| Test Name |
Route |
Status |
returns 200 with paginated list |
GET /invoices |
Implemented |
returns 401 without auth |
GET /invoices |
Implemented |
returns 201 with created invoice |
POST /invoices |
Implemented |
returns 200 with full invoice |
GET /invoices/:id |
Implemented |
returns 404 when invoice not found |
GET /invoices/:id |
Implemented |
returns 200 when updating draft invoice |
PUT /invoices/:id |
Implemented |
returns 400 when updating sent invoice |
PUT /invoices/:id |
Implemented |
returns 200 when sending invoice (draft -> sent) |
PATCH /invoices/:id/status |
Implemented |
returns 200 when marking invoice as paid (sent -> paid) |
PATCH /invoices/:id/status |
Implemented |
returns 204 when deleting draft invoice |
DELETE /invoices/:id |
Implemented |
returns 400 when deleting sent invoice |
DELETE /invoices/:id |
Implemented |
expenses.test.ts — 9 tests
| Test Area |
Route |
Status |
| List expenses (200 + auth) |
GET /expenses |
Implemented |
| Create expense (201) |
POST /expenses |
Implemented |
| Get expense by ID (200 + 404) |
GET /expenses/:id |
Implemented |
| Update expense (200 + 400 for non-pending) |
PUT /expenses/:id |
Implemented |
| Approve expense (200 + role check) |
PATCH /expenses/:id/approve |
Implemented |
| Delete expense (204 + 400 for approved) |
DELETE /expenses/:id |
Implemented |
| Test Area |
Route |
Status |
| List contacts (200 + auth) |
GET /contacts |
Implemented |
| Create contact (201 + validation) |
POST /contacts |
Implemented |
| Get contact (200 + 404) |
GET /contacts/:id |
Implemented |
| Update contact (200) |
PUT /contacts/:id |
Implemented |
| Delete contact (204) |
DELETE /contacts/:id |
Implemented |
accounts.test.ts — 4 tests
| Test Area |
Route |
Status |
| List chart of accounts (200) |
GET /accounts |
Implemented |
| Get account by ID (200 + 404) |
GET /accounts/:id |
Implemented |
| Create account (201) |
POST /accounts |
Implemented |
| Delete account (204) |
DELETE /accounts/:id |
Implemented |
banking.test.ts — 10 tests
| Test Area |
Route |
Status |
| List bank accounts (200) |
GET /banking/accounts |
Implemented |
| Create bank account (201) |
POST /banking/accounts |
Implemented |
| Import bank statement (200 + validation) |
POST /banking/accounts/:id/import |
Implemented |
| List bank transactions (200) |
GET /banking/accounts/:id/transactions |
Implemented |
| Reconcile transaction (200 + 400 for mismatch) |
POST /banking/accounts/:id/reconcile |
Implemented |
reports.test.ts — 9 tests
| Test Area |
Route |
Status |
| Profit & Loss report (200 + date range) |
GET /reports/profit-loss |
Implemented |
| Balance sheet (200) |
GET /reports/balance-sheet |
Implemented |
| VAT report for RS (200 + correct rates) |
GET /reports/vat |
Implemented |
| Trial balance (200) |
GET /reports/trial-balance |
Implemented |
| Auth required on all report endpoints |
All report routes |
Implemented |
transactions.test.ts — 9 tests
| Test Area |
Route |
Status |
| List transactions (200 + pagination) |
GET /transactions |
Implemented |
| Filter by account (200) |
GET /transactions?accountId= |
Implemented |
| Get transaction by ID (200 + 404) |
GET /transactions/:id |
Implemented |
| Auth required |
All transaction routes |
Implemented |
country.test.ts — 27 tests
Tests the country plugin integration — routes that return country-specific tax configuration.
| Test Area |
Route |
Status |
| Serbian PDV rates (20/10/0) for RS org |
GET /country/tax-rates |
Implemented |
| Bosnian PDV rate (17) for BA org |
GET /country/tax-rates |
Implemented |
| Croatian PDV rates (25/13/5/0) for HR org |
GET /country/tax-rates |
Implemented |
| Invoice number format per country |
GET /country/invoice-format |
Implemented |
| Auth required |
All country routes |
Implemented |
| Unknown country code (400) |
GET /country/tax-rates |
Implemented |
e2e/api.test.ts — Full E2E
End-to-end API integration test (no mocks). Exercises the full Express application stack.
Coverage Tracking
| Module |
Current Status |
Target |
@bilko/core accounting engine |
Tests implemented (20 cases) |
>95% |
@bilko/core invoicing |
Tests implemented (22 cases) |
>95% |
@bilko/core tax/VAT |
Tests implemented (23 cases) |
>95% |
@bilko/core multi-currency |
Tests implemented (24 cases) |
>90% |
@bilko/core chart of accounts |
Tests implemented (32 cases) |
>90% |
| Auth API |
Tests implemented (11 cases) |
>85% |
| Invoices API |
Tests implemented (11 cases) |
>80% |
| Expenses API |
Tests implemented (9 cases) |
>80% |
| Banking API |
Tests implemented (10 cases) |
>75% |
| Reports API |
Tests implemented (9 cases) |
>75% |
| Country/Tax-Rates API |
Tests implemented (27 cases) |
>80% |
Test Execution Commands
# All tests (from project root)
npm run test
# Core unit tests only
cd packages/core && npx vitest run
# API integration tests only
cd apps/api && npx vitest run
# Watch mode (re-run on change)
cd packages/core && npx vitest
# Specific file
cd apps/api && npx vitest run tests/auth.test.ts
# With coverage
cd packages/core && npx vitest run --coverage
# Verbose output
npx vitest run --reporter=verbose
Last Updated: 2026-02-25
Status: Active
Total Tests: ~220 across 14 test files