Skip to main content

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

contacts.test.ts — 9 tests

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.

Status
Implemented

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