Test Inventory
Bilko — Test Inventory
Status: NO TESTS EXIST YET — This document tracks planned tests and implementation status.
This inventory catalogs all tests planned for Bilko, organized by category and priority.
Test Coverage Summary
| Category |
Total Planned |
Implemented |
Coverage Target |
| Unit Tests |
45 |
0 |
>80% |
| Integration Tests |
35 |
0 |
>80% |
| E2E Tests |
12 |
0 |
Critical flows |
| TOTAL |
92 |
0 |
— |
graph TD
subgraph COVERAGE["Test Coverage Matrix — 92 Tests Planned"]
subgraph UNIT["Unit Tests — 45"]
FIN["Financial Calculations<br/>12 tests — P0<br/>VAT, invoice totals, precision"]
DE["Double-Entry Validation<br/>6 tests — P0<br/>debit=credit enforcement"]
CUR["Currency Conversion<br/>8 tests — P0<br/>exchange rate locking"]
DATE["Date Utilities<br/>6 tests — P1<br/>due dates, fiscal year"]
FMT["Number Formatting<br/>5 tests — P1<br/>RSD, EUR, BAM display"]
AUTH_U["Authentication Utils<br/>8 tests — P0<br/>bcrypt, JWT, tokens"]
end
subgraph INTEG["Integration Tests — 35"]
AUTH_API["Auth API<br/>10 tests — P0<br/>register/login/refresh/logout"]
INV_API["Invoices API<br/>10 tests — P0<br/>CRUD + status + org-scope"]
EXP_API["Expenses API<br/>8 tests — P1<br/>CRUD + approve/pay"]
REP_API["Reports API<br/>7 tests — P1<br/>P&L / BS / VAT reports"]
end
subgraph E2E_["E2E Tests — 12"]
INV_E2E["Invoice Flow<br/>4 tests — P0<br/>Create → Send → Paid"]
EXP_E2E["Expense Flow<br/>3 tests — P1<br/>Add → Approve → Pay"]
REP_E2E["Report Flow<br/>2 tests — P1<br/>Generate → Export PDF"]
SET_E2E["Settings Flow<br/>2 tests — P2<br/>Org settings + Invite user"]
AUTH_E2E["Auth Flow<br/>1 test — P1<br/>Register → Login → 2FA → Logout"]
end
end
style FIN fill:#dc3545,color:#fff
style DE fill:#dc3545,color:#fff
style CUR fill:#dc3545,color:#fff
style AUTH_U fill:#dc3545,color:#fff
style AUTH_API fill:#dc3545,color:#fff
style INV_API fill:#dc3545,color:#fff
style INV_E2E fill:#dc3545,color:#fff
style DATE fill:#fd7e14,color:#fff
style FMT fill:#fd7e14,color:#fff
style EXP_API fill:#fd7e14,color:#fff
style REP_API fill:#fd7e14,color:#fff
style EXP_E2E fill:#fd7e14,color:#fff
style REP_E2E fill:#fd7e14,color:#fff
style AUTH_E2E fill:#fd7e14,color:#fff
style SET_E2E fill:#6c757d,color:#fff
Priority Legend
- P0 — Critical (MVP blocker, financial logic)
- P1 — High (core features, security)
- P2 — Medium (nice-to-have, edge cases)
- P3 — Low (future enhancements)
Unit Tests (45 total)
Financial Calculations (12 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
vat.test.ts |
calculateVAT - Serbia 20% |
VAT calculation for Serbia |
P0 |
❌ Not implemented |
vat.test.ts |
calculateVAT - BiH 17% |
VAT calculation for BiH |
P0 |
❌ Not implemented |
vat.test.ts |
calculateVAT - Croatia 25% |
VAT calculation for Croatia |
P0 |
❌ Not implemented |
vat.test.ts |
calculateVAT - zero rate |
VAT at 0% (exports) |
P0 |
❌ Not implemented |
vat.test.ts |
calculateVAT - decimal amounts |
VAT on €123.45 |
P0 |
❌ Not implemented |
vat.test.ts |
calculateVAT - rounding |
Rounds to 2 decimal places |
P0 |
❌ Not implemented |
invoice-calc.test.ts |
calculateInvoiceTotal - subtotal |
Sum of line items |
P0 |
❌ Not implemented |
invoice-calc.test.ts |
calculateInvoiceTotal - tax |
Sum of tax amounts |
P0 |
❌ Not implemented |
invoice-calc.test.ts |
calculateInvoiceTotal - discount |
Subtract discount from subtotal |
P0 |
❌ Not implemented |
invoice-calc.test.ts |
calculateInvoiceTotal - total |
Subtotal + tax - discount |
P0 |
❌ Not implemented |
invoice-calc.test.ts |
calculateInvoiceTotal - multi-item |
Multiple line items with different tax rates |
P0 |
❌ Not implemented |
invoice-calc.test.ts |
calculateInvoiceTotal - precision |
NUMERIC(19,4) precision maintained |
P0 |
❌ Not implemented |
Double-Entry Validation (6 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
double-entry.test.ts |
validateTransaction - debit equals credit |
Debit amount = Credit amount |
P0 |
❌ Not implemented |
double-entry.test.ts |
validateTransaction - rejects unbalanced |
Throws error if debit ≠ credit |
P0 |
❌ Not implemented |
double-entry.test.ts |
validateTransaction - requires both accounts |
Throws if missing debit or credit account |
P0 |
❌ Not implemented |
double-entry.test.ts |
validateTransaction - multi-currency |
Validates amounts in base currency |
P0 |
❌ Not implemented |
double-entry.test.ts |
validateTransaction - precision |
NUMERIC precision preserved |
P0 |
❌ Not implemented |
double-entry.test.ts |
validateTransaction - zero amount |
Rejects zero-amount transactions |
P1 |
❌ Not implemented |
Currency Conversion (8 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
currency.test.ts |
convertCurrency - EUR to RSD |
Convert at locked exchange rate |
P0 |
❌ Not implemented |
currency.test.ts |
convertCurrency - RSD to EUR |
Reverse conversion |
P0 |
❌ Not implemented |
currency.test.ts |
convertCurrency - same currency |
Rate = 1.0 when currency matches |
P0 |
❌ Not implemented |
currency.test.ts |
convertCurrency - precision |
NUMERIC(19,4) preserved |
P0 |
❌ Not implemented |
currency.test.ts |
convertCurrency - large amounts |
€999,999,999.9999 |
P0 |
❌ Not implemented |
currency.test.ts |
convertCurrency - rounding |
Rounds to 4 decimal places |
P1 |
❌ Not implemented |
currency.test.ts |
lockExchangeRate - historical rate |
Uses rate from transaction date, not today |
P0 |
❌ Not implemented |
currency.test.ts |
lockExchangeRate - missing rate |
Throws if no rate available for date |
P1 |
❌ Not implemented |
Date Utilities (6 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
date.test.ts |
calculateDueDate - 30 days |
Invoice date + 30 days |
P1 |
❌ Not implemented |
date.test.ts |
calculateDueDate - custom terms |
Invoice date + custom days |
P1 |
❌ Not implemented |
date.test.ts |
isOverdue - past due date |
Returns true if today > due date |
P1 |
❌ Not implemented |
date.test.ts |
isOverdue - not overdue |
Returns false if today <= due date |
P1 |
❌ Not implemented |
date.test.ts |
getFiscalYear - starts Jan 1 |
Fiscal year 2026 = Jan 1 - Dec 31 |
P2 |
❌ Not implemented |
date.test.ts |
getFiscalYear - custom start |
Fiscal year starts on custom date |
P2 |
❌ Not implemented |
| Test File |
Test Name |
What It Tests |
Priority |
Status |
format.test.ts |
formatCurrency - RSD |
"50,000.00 RSD" format |
P1 |
❌ Not implemented |
format.test.ts |
formatCurrency - EUR |
"€50,000.00" format |
P1 |
❌ Not implemented |
format.test.ts |
formatCurrency - BAM |
"50,000.00 BAM" format |
P1 |
❌ Not implemented |
format.test.ts |
formatCurrency - decimal places |
Respects currency decimal places (0-4) |
P1 |
❌ Not implemented |
format.test.ts |
formatCurrency - null |
Returns "-" for null/undefined |
P2 |
❌ Not implemented |
Authentication (8 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
auth.test.ts |
hashPassword - bcrypt 12 rounds |
Password hashed with bcrypt |
P0 |
❌ Not implemented |
auth.test.ts |
hashPassword - unique salt |
Each hash is different |
P0 |
❌ Not implemented |
auth.test.ts |
verifyPassword - correct password |
Returns true for correct password |
P0 |
❌ Not implemented |
auth.test.ts |
verifyPassword - incorrect password |
Returns false for wrong password |
P0 |
❌ Not implemented |
auth.test.ts |
generateJWT - valid payload |
JWT contains user ID, org ID, role |
P0 |
❌ Not implemented |
auth.test.ts |
generateJWT - expiry 15 min |
Access token expires in 15 min |
P0 |
❌ Not implemented |
auth.test.ts |
generateRefreshToken - expiry 7 days |
Refresh token expires in 7 days |
P0 |
❌ Not implemented |
auth.test.ts |
verifyJWT - expired token |
Throws error if token expired |
P1 |
❌ Not implemented |
Integration Tests (35 total)
Auth API (10 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
auth-api.test.ts |
POST /auth/register - success |
Creates user, returns 201 |
P0 |
❌ Not implemented |
auth-api.test.ts |
POST /auth/register - duplicate email |
Returns 400 if email exists |
P0 |
❌ Not implemented |
auth-api.test.ts |
POST /auth/register - weak password |
Returns 400 if password < 8 chars |
P0 |
❌ Not implemented |
auth-api.test.ts |
POST /auth/login - success |
Returns access + refresh tokens |
P0 |
❌ Not implemented |
auth-api.test.ts |
POST /auth/login - wrong password |
Returns 401 |
P0 |
❌ Not implemented |
auth-api.test.ts |
POST /auth/login - non-existent user |
Returns 401 |
P0 |
❌ Not implemented |
auth-api.test.ts |
POST /auth/refresh - success |
Returns new access token |
P0 |
❌ Not implemented |
auth-api.test.ts |
POST /auth/refresh - expired token |
Returns 401 |
P1 |
❌ Not implemented |
auth-api.test.ts |
POST /auth/logout - success |
Deletes refresh token from DB |
P1 |
❌ Not implemented |
auth-api.test.ts |
POST /auth/logout - already logged out |
Returns 204 (idempotent) |
P2 |
❌ Not implemented |
Invoices API (10 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
invoices-api.test.ts |
POST /invoices - success |
Creates invoice, returns 201 |
P0 |
❌ Not implemented |
invoices-api.test.ts |
POST /invoices - validates required fields |
Returns 400 if missing customer |
P0 |
❌ Not implemented |
invoices-api.test.ts |
POST /invoices - validates currency |
Returns 400 if invalid currency code |
P0 |
❌ Not implemented |
invoices-api.test.ts |
POST /invoices - org scoping |
Returns 403 if customer in different org |
P0 |
❌ Not implemented |
invoices-api.test.ts |
GET /invoices - list |
Returns paginated invoices |
P0 |
❌ Not implemented |
invoices-api.test.ts |
GET /invoices - filter by status |
Returns only "paid" invoices |
P1 |
❌ Not implemented |
invoices-api.test.ts |
GET /invoices/:id - success |
Returns invoice by ID |
P0 |
❌ Not implemented |
invoices-api.test.ts |
GET /invoices/:id - not found |
Returns 404 if ID doesn't exist |
P1 |
❌ Not implemented |
invoices-api.test.ts |
PATCH /invoices/:id - update status |
Changes status to "sent" |
P0 |
❌ Not implemented |
invoices-api.test.ts |
DELETE /invoices/:id - soft delete |
Marks as deleted (not hard delete) |
P1 |
❌ Not implemented |
Expenses API (8 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
expenses-api.test.ts |
POST /expenses - success |
Creates expense, returns 201 |
P0 |
❌ Not implemented |
expenses-api.test.ts |
POST /expenses - validates required fields |
Returns 400 if missing amount |
P0 |
❌ Not implemented |
expenses-api.test.ts |
POST /expenses - org scoping |
Returns 403 if vendor in different org |
P0 |
❌ Not implemented |
expenses-api.test.ts |
GET /expenses - list |
Returns paginated expenses |
P0 |
❌ Not implemented |
expenses-api.test.ts |
PATCH /expenses/:id/approve - success |
Changes status to "approved" |
P1 |
❌ Not implemented |
expenses-api.test.ts |
PATCH /expenses/:id/approve - requires admin |
Returns 403 if user is viewer |
P1 |
❌ Not implemented |
expenses-api.test.ts |
PATCH /expenses/:id/reject - success |
Changes status to "rejected" |
P1 |
❌ Not implemented |
expenses-api.test.ts |
DELETE /expenses/:id - soft delete |
Marks as deleted |
P1 |
❌ Not implemented |
Reports API (7 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
reports-api.test.ts |
GET /reports/profit-loss - success |
Returns P&L with revenue, expenses, net |
P1 |
❌ Not implemented |
reports-api.test.ts |
GET /reports/profit-loss - date range |
Filters by start/end date |
P1 |
❌ Not implemented |
reports-api.test.ts |
GET /reports/balance-sheet - success |
Returns assets, liabilities, equity |
P1 |
❌ Not implemented |
reports-api.test.ts |
GET /reports/cash-flow - success |
Returns operating, investing, financing |
P1 |
❌ Not implemented |
reports-api.test.ts |
GET /reports/vat - success |
Returns sales VAT, purchase VAT, net VAT |
P1 |
❌ Not implemented |
reports-api.test.ts |
GET /reports/vat - Serbia 20% |
Calculates Serbian VAT correctly |
P1 |
❌ Not implemented |
reports-api.test.ts |
GET /reports/vat - export PDF |
Returns PDF file |
P2 |
❌ Not implemented |
E2E Tests (12 total)
Invoice Flow (4 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
invoice-flow.spec.ts |
Create invoice via 6-step wizard |
Full invoice creation flow |
P0 |
❌ Not implemented |
invoice-flow.spec.ts |
Preview invoice before sending |
Preview modal shows correct totals |
P0 |
❌ Not implemented |
invoice-flow.spec.ts |
Send invoice to customer |
Email sent, status changed to "sent" |
P0 |
❌ Not implemented |
invoice-flow.spec.ts |
Mark invoice as paid |
Status changed to "paid", paidAt timestamp |
P0 |
❌ Not implemented |
Expense Flow (3 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
expense-flow.spec.ts |
Add expense with receipt upload |
Create expense, upload JPG |
P1 |
❌ Not implemented |
expense-flow.spec.ts |
Approve expense |
Admin approves, status changed |
P1 |
❌ Not implemented |
expense-flow.spec.ts |
Mark expense as paid |
Status changed to "paid" |
P1 |
❌ Not implemented |
Report Flow (2 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
report-flow.spec.ts |
Generate P&L report |
Select date range, view report |
P1 |
❌ Not implemented |
report-flow.spec.ts |
Export P&L to PDF |
Download PDF file |
P1 |
❌ Not implemented |
Settings Flow (2 tests)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
settings-flow.spec.ts |
Update organization settings |
Change org name, tax settings |
P2 |
❌ Not implemented |
settings-flow.spec.ts |
Invite user to organization |
Send invite email, user accepts |
P2 |
❌ Not implemented |
Auth Flow (1 test)
| Test File |
Test Name |
What It Tests |
Priority |
Status |
auth-flow.spec.ts |
Register → Login → 2FA → Logout |
Full auth flow with 2FA |
P1 |
❌ Not implemented |
Critical Path Testing Flow
flowchart TD
START(["Start: No Tests"]) --> P1
subgraph P1["Phase 1 — MVP Critical (25 tests)"]
P1_FIN["Financial Calculations<br/>12 unit tests<br/>VAT RS/BA/HR, invoice totals"]
P1_DE["Double-Entry Validation<br/>6 unit tests<br/>debit=credit, balanced=true"]
P1_AUTH["Auth API<br/>7 integration tests<br/>register, login, refresh"]
P1_FIN --> P1_DE --> P1_AUTH
end
P1 --> P1_GATE{"Coverage<br/>>=50%?"}
P1_GATE -->|Yes| P2
P1_GATE -->|No| P1
subgraph P2["Phase 2 — Core Features (35 tests)"]
P2_CUR["Currency Conversion<br/>8 unit tests"]
P2_INV["Invoices API<br/>10 integration tests"]
P2_E2E["Invoice + Auth + Expense E2E<br/>8 E2E tests"]
P2_REP["Reports API<br/>7 integration tests"]
P2_CUR --> P2_INV --> P2_E2E --> P2_REP
end
P2 --> P2_GATE{"Coverage<br/>>=70%?"}
P2_GATE -->|Yes| P3
P2_GATE -->|No| P2
subgraph P3["Phase 3 — Polish (32 tests)"]
P3_DATE["Date + Formatting<br/>11 unit tests"]
P3_EXP["Expenses API<br/>8 integration tests"]
P3_EDGE["Edge cases<br/>8 tests"]
P3_SET["Settings flow<br/>5 tests"]
P3_DATE --> P3_EXP --> P3_EDGE --> P3_SET
end
P3 --> DONE(["Production Ready<br/>>80% coverage<br/>All critical paths tested"])
style START fill:#6c757d,color:#fff
style DONE fill:#198754,color:#fff
style P1_GATE fill:#ffc107,stroke:#e0a800
style P2_GATE fill:#ffc107,stroke:#e0a800
Test Implementation Roadmap
Phase 1 (MVP Critical) — 25 tests
- ✅ Financial calculations (12 unit tests)
- ✅ Double-entry validation (6 unit tests)
- ✅ Auth API (7 integration tests: register, login, refresh)
Target: Before backend MVP launch
Phase 2 (Core Features) — 35 tests
- ✅ Currency conversion (8 unit tests)
- ✅ Invoices API (10 integration tests)
- ✅ Invoice E2E flow (4 E2E tests)
- ✅ Auth E2E flow (1 E2E test)
- ✅ Expense flow (3 E2E tests)
- ✅ Reports API (7 integration tests)
- ✅ Report E2E flow (2 E2E tests)
Target: 1 month after MVP launch
Phase 3 (Polish) — 32 tests
- ✅ Date utilities (6 unit tests)
- ✅ Number formatting (5 unit tests)
- ✅ Expenses API (8 integration tests)
- ✅ Settings flow (2 E2E tests)
- ✅ Remaining auth tests (3 integration tests)
- ✅ Edge cases (8 tests across categories)
Target: 3 months after MVP launch
Test Execution Commands
Run All Tests
npm run test # All tests (unit + integration + E2E)
Run by Category
npm run test:unit # Unit tests only
npm run test:integration # Integration tests only
npm run test:e2e # E2E tests only
Run Specific Test File
npm run test:unit -- vat.test.ts
npm run test:integration -- invoices-api.test.ts
npm run test:e2e -- invoice-flow.spec.ts
Run with Coverage
npm run test:unit -- --coverage
Watch Mode
npm run test:unit -- --watch
Coverage Tracking
Current Coverage (as of 2026-02-20)
| Category |
Coverage |
Target |
Status |
| Financial Logic |
0% |
>95% |
❌ Not started |
| API Endpoints |
0% |
>80% |
❌ Not started |
| Utilities |
0% |
>90% |
❌ Not started |
| Overall |
0% |
>80% |
❌ Not started |
Next Milestone: 50% coverage (25 critical tests)
Last Updated: 2026-02-20
Status: NO TESTS IMPLEMENTED YET
Total Tests Planned: 92 (45 unit + 35 integration + 12 E2E)
Next Action: Implement Phase 1 financial calculation tests (12 tests)