Skip to main content

Test Inventory

Drop Test Inventory

Last updated: 2026-02-13 Source: src/drop-app/tests/ Total test files: 14 (7 unit, 1 integration, 1 performance, 1 regression, 3 E2E, 1 setup)


Directory Structure

tests/
  setup.ts                              # Global setup (sets NODE_ENV=test)
  unit/
    auth.test.ts                        # Password hashing + JWT tokens
    db.test.ts                          # Database schema validation
    feature-flags.test.ts               # Feature flag system
    middleware.test.ts                   # Rate limiting + error responses
    utils.test.ts                       # Utility functions (randomId, maskBankAccount)
    validation.test.ts                  # Input validation functions
    api-routes.test.ts                  # API routes with DB integration
  integration/
    api-endpoints.test.ts               # Full API endpoint integration tests
  performance/
    api-benchmarks.test.ts              # Performance benchmarks
  regression/
    known-bugs.test.ts                  # Regression tests for fixed bugs
  e2e/
    user-flows.spec.ts                  # Basic user journey E2E
    full-flows.spec.ts                  # Complete feature journey E2E
    input-chaos.spec.ts                 # Malicious/edge-case input E2E

Unit Tests (Vitest)

tests/unit/auth.test.ts -- 7 tests

Password Hashing (4 tests):

  • hashPassword produces bcrypt hash (starts with $2)
  • verifyPassword validates correct bcrypt password
  • verifyPassword rejects wrong password
  • verifyPassword does NOT accept SHA-256 hashes (security fix C4)

JWT Token Management (3 tests):

  • signToken and verifyToken round-trip works
  • verifyToken rejects invalid tokens
  • verifyToken rejects tampered tokens

tests/unit/db.test.ts -- 5 tests

  • Creates all 11 expected tables (users, transactions, recipients, merchants, cards, bank_accounts, sessions, notifications, settings, exchange_rates, spending_limits)
  • Users table does NOT have balance column (pass-through model verification)
  • Cards table does NOT have card_number or cvv columns (PCI-DSS fix verification). Has last_four and token_ref instead.
  • Transaction type constraint only allows remittance and qr_payment
  • Foreign key constraints are enforced

tests/unit/feature-flags.test.ts -- 6 tests

  • isEnabled returns default when no env var is set
  • isEnabled reads NEXT_PUBLIC_FF_* env vars
  • featureGate returns 404-like response when disabled
  • featureGate returns null when enabled
  • getAllFlags returns complete flag set (8 flags)
  • topUpViaCard flag does NOT exist (removed feature)

tests/unit/middleware.test.ts -- 7 tests

Rate Limiting (3 tests):

  • Allows requests within limit
  • Blocks after limit exceeded
  • Resets after window expires

jsonError (2 tests):

  • Returns correct JSON format ({error, message, details})
  • Includes details array when provided

getClientIp (2 tests):

  • Extracts from X-Forwarded-For header (first IP)
  • Returns 127.0.0.1 when no header present

tests/unit/utils.test.ts -- 5 tests

randomId (3 tests):

  • Generates prefixed IDs with correct format (prefix_<hex16>)
  • Generates unique IDs on each call
  • Uses the provided prefix

maskBankAccount (2 tests):

  • Masks correctly, showing only last 4 characters
  • Returns short accounts unchanged

tests/unit/validation.test.ts -- 10 tests

Email Validation (2 tests):

  • Accepts valid emails (standard, tag, domain variants)
  • Rejects invalid emails (empty, no @, space, null)

Phone Validation (2 tests):

  • Accepts international format (+47, +381)
  • Rejects invalid numbers (no +, too short, letters, null)

Amount Validation (2 tests):

  • Accepts valid positive amounts (including 0.01)
  • Rejects negative, zero, NaN, and >2 decimal places

IBAN Validation (2 tests):

  • Validates correct IBANs (Norwegian, German)
  • Rejects invalid IBANs (empty, too short, bad checksum, null)

Name Validation (6 tests, grouped):

  • Accepts valid names (Latin, Bosnian chars, apostrophes, hyphens, umlauts)
  • Rejects numbers-only input
  • Accepts names with numbers mixed in (has letters)
  • Rejects empty and null
  • Rejects XSS payloads (<script>, onclick=)
  • Rejects special-chars-only input

PIN Validation (2 tests):

  • Validates 4-digit PINs
  • Rejects invalid PINs (too short, too long, letters, null)

tests/unit/api-routes.test.ts -- 8 test groups

  1. DB + Auth Integration -- User creation with bcrypt, password verification, hash uniqueness
  2. Exchange Rates Seeded -- 6 NOK rates, queryable for API response
  3. Rate Limiting -- Allows within limit, blocks after exceeded, resets after window, cleans expired entries
  4. User Registration Flow -- Insert, unique constraint, default values, KYC/role constraints
  5. Session Tracking -- Create, retrieve, revocation, expiry, index verification
  6. End-to-End User Flow -- Register -> login -> session -> revoke
  7. Foreign Key Constraints -- Cannot create orphan sessions, cannot delete user with sessions
  8. Utility Functions -- randomId format and uniqueness

Integration Tests (Vitest)

tests/integration/api-endpoints.test.ts -- 20+ tests

Tests actual API route handlers with mocked database and auth.

POST /api/auth/register (5 tests):

  • Successfully registers with valid input (201, checks DB)
  • Returns 422 for missing email
  • Returns 422 for short password
  • Returns 422 for missing first name
  • Returns 409 for duplicate email
  • Returns 400 for invalid JSON body

POST /api/auth/login (5 tests):

  • Successfully logs in with valid credentials (200)
  • Returns 401 for wrong password
  • Returns 401 for non-existent user
  • Returns 400 for missing email or password
  • Returns 400 for invalid JSON body

GET /api/rates (2 tests):

  • Returns all exchange rates (6 currencies)
  • Returns empty rates when none seeded

GET /api/rates/[currency] (3 tests):

  • Returns rate for valid currency
  • Returns 404 for unsupported currency
  • Handles case-insensitive codes

POST /api/transactions/remittance (7 tests):

  • Successfully creates remittance (201, verifies balance deduction)
  • Returns 401 when not authenticated
  • Returns 403 when KYC not approved
  • Returns 404 when recipient not found
  • Returns 402 when insufficient balance
  • Returns 400 for amount below/above limits
  • Returns 400 for invalid amount (NaN)

POST /api/transactions/qr-payment (8 tests):

  • Successfully creates QR payment (201, verifies balance, fee calc)
  • Returns 401 when not authenticated
  • Returns 404 when merchant not found
  • Returns 402 when insufficient balance
  • Returns 400 for amount below/above limits
  • Returns 400 for missing merchantId
  • Returns 400 for invalid JSON body

Performance Tests (Vitest)

tests/performance/api-benchmarks.test.ts -- 8 tests

Test Threshold
hashPassword (bcrypt rounds=12) < 1000ms
verifyPassword (bcrypt compare) < 1000ms
rateLimit single check < 50ms
DB SELECT query < 10ms
DB INSERT query < 20ms
Exchange rate lookup < 10ms
50 concurrent rateLimit calls < 2000ms total
Transaction INSERT < 50ms

Regression Tests (Vitest)

tests/regression/known-bugs.test.ts -- 4 bug groups

BUG-001: rateLimit() missing await (3 tests):

  • Rate limit actually blocks after exceeded
  • Count increments correctly in database
  • Resets after window expires

BUG-002: Validation errors generic message (3 tests):

  • Register returns details array for validation errors
  • Details contain specific field errors
  • Multiple validation errors all included

BUG-003: Email without @ passed client-side (3 tests):

  • API rejects email without @ symbol
  • API rejects empty string as email
  • API accepts valid email with @

BUG-004: Missing getDb import in auth.ts (5 tests):

  • All auth module exports are functional (signToken, verifyToken, setAuthCookie, clearAuthCookie, getCurrentUser)
  • getCurrentUser returns null when no token
  • All exports are functions

E2E Tests (Playwright)

tests/e2e/user-flows.spec.ts -- 5 test groups

Landing Page (3 tests):

  • Loads homepage with Drop branding
  • Has navigation to login and onboarding
  • Navigates to login page

Login Flow (4 tests):

  • Shows login form with correct fields
  • Shows error with empty credentials (client-side)
  • Shows error with wrong credentials
  • Logs in with demo credentials, redirects to dashboard

Registration Flow (4 tests):

  • Shows form with required fields, disabled button
  • Validates email format client-side
  • Validates password length client-side
  • Full flow: form -> OTP -> PIN -> success

Dashboard (2 tests):

  • Login redirects to dashboard with action buttons
  • Authenticated pages load after login

API Health (4 tests):

  • GET /api/rates returns exchange rates
  • GET /api/rates/RSD returns specific rate
  • GET /api/rates/XXX returns 404
  • POST /api/auth/register validates input

All Pages Load (10 tests):

  • Each page (/, /login, /onboarding, /dashboard, /send, /scan, /history, /accounts, /profile, /cards) returns no server error

tests/e2e/full-flows.spec.ts -- 8 journeys

  1. New User Registration -- form -> OTP -> PIN -> success -> dashboard (skipped)
  2. Send Money -- login -> recipient -> amount -> confirm -> verify in history
  3. QR Payment -- login -> scan -> amount -> pay -> verify in history
  4. Virtual Card -- login -> cards -> order -> verify card appears
  5. Bank Accounts -- login -> accounts -> verify Open Banking info, DNB account
  6. Profile and Logout -- login -> profile -> verify info -> logout -> redirect
  7. Full Navigation -- login -> navigate all 7 pages via direct links
  8. Error Handling -- wrong credentials -> error -> correct -> success (skipped)

tests/e2e/input-chaos.spec.ts -- 7 test groups, 40+ tests

Login Chaos (8 tests):

  • Empty fields, spaces-only email, XSS in email, SQL injection in email, 10K char email, unicode password, special characters, Norwegian characters

Registration Chaos (20+ tests):

  • All fields empty, XSS in firstName, email without @, email with only @, email with spaces, password 7 chars (boundary), password all-numbers, SQL injection in lastName, HTML injection, 10K char name, numbers-only names, special-chars-only, Bosnian chars, emoji, spaces-only, password complexity, underage DOB, duplicate email, far-future DOB, OTP with letters/5 digits/7+ digits, phone with letters

Send Money Chaos (6 tests):

  • Amount 0, negative, extremely large, text in number field, XSS in search, special chars in search

QR Payment Chaos (4 tests):

  • Amount 0, negative, very large, many decimals

API Impossible Inputs (14 tests):

  • Empty JSON, number as email, null values, array/object as email, wrong Content-Type, path traversal, XSS in name, 1MB password, unicode email, numbers-only name, underage DOB, duplicate email, password no letters

Page Resilience (5 tests):

  • Dashboard without auth, send without auth, rapid navigation, double-click submit, browser back from OTP