Wiki reference (diagrams): Development
This document outlines the testing strategy, practices, and guidelines for ShadowCheckStatic.
npm test
npm run test:integrationRequires database connectivity and secrets available via AWS Secrets Manager (or explicit local overrides).
The project uses Jest as the primary testing framework.
# Run all tests
npm test
# Run with coverage
npm run test:cov
# Lint and format check
npm run lint
npm run format:checktests/
├── setup.ts # Test setup and configuration
├── sql-injection-fixes.test.ts
├── wigle-import-auth.test.js
├── api/
│ └── dashboard.test.ts # API endpoint tests
├── helpers/
│ └── integrationEnv.ts # Integration test helpers
├── integration/
│ ├── README.md # Integration test documentation
│ ├── explorer-v2.test.ts
│ ├── like-escaping.test.ts
│ ├── networks-data-integrity.test.ts
│ ├── observability.test.ts
│ ├── route-refactoring-verification.test.ts
│ └── sql-injection-fixes.test.ts
└── unit/
├── escapeSQL.test.ts
├── filterQueryBuilder.test.ts
├── filters-systematic.test.ts
├── health.test.ts
├── observationCountMin-investigation.test.ts
└── requestId.test.ts
Unit tests verify individual functions and modules in isolation.
Location: tests/unit/
Naming Convention: *.test.ts
Examples:
escapeSQL.test.ts- SQL escaping utilitiesfilterQueryBuilder.test.ts- Filter query builderhealth.test.ts- Health check endpointsrequestId.test.ts- Request ID middleware
Best Practices:
- Mock external dependencies (database, file system, network calls)
- Test edge cases and error conditions
- Keep tests fast (< 100ms each)
- Use descriptive test names
Integration tests verify the interaction between multiple components or API endpoints.
Location: tests/integration/
Naming Convention: *.test.ts
Examples:
explorer-v2.test.ts- Explorer v2 functionalitylike-escaping.test.ts- SQL LIKE escapingnetworks-data-integrity.test.ts- Data integrityobservability.test.ts- Observability featuresroute-refactoring-verification.test.ts- Route testssql-injection-fixes.test.ts- SQL injection prevention
See also: integration/README.md
API tests verify REST endpoint behavior.
Location: tests/api/
Examples:
dashboard.test.ts- Dashboard API tests
Utilities for test setup and configuration.
Examples:
integrationEnv.ts- Integration environment setup
See jest.config.js for Jest configuration.
module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/tests'],
testMatch: ['**/*.test.ts', '**/*.test.js'],
collectCoverageFrom: ['server/**/*.ts', '!server/**/*.d.ts'],
coverageDirectory: 'coverage',
// ... more config
};The tests/setup.ts file contains:
- Mock setups- Global test configuration
- Environment variable defaults
- Database connection handling
import { escapeSQL } from '../server/src/utils/escapeSQL';
describe('escapeSQL', () => {
it('should escape single quotes', () => {
const input = "O'Reilly";
const result = escapeSQL(input);
expect(result).toBe("O''Reilly");
});
it('should escape percent and underscore for LIKE', () => {
const input = '100%_match';
const result = escapeSQL(input, true);
expect(result).toBe('100\\%\\_match');
});
});import request from 'supertest';
import { createApp } from '../server/src/utils/appInit';
describe('Explorer API', () => {
let app: Express.Application;
beforeAll(async () => {
app = await createApp();
});
it('should return networks with 200', async () => {
const response = await request(app).get('/api/v1/explorer/networks').expect(200);
expect(response.body).toHaveProperty('data');
expect(Array.isArray(response.body.data)).toBe(true);
});
});Note: The global minimums are enforced in jest.config.js and were recently raised after a major test enhancement drive (April 2026).
| Type | Minimum (Enforced) | Target |
|---|---|---|
| Statements | 60% | 80% |
| Branches | 60% | 70% |
| Functions | 60% | 80% |
| Lines | 60% | 80% |
Run npm run test:cov to generate coverage reports.
Client-side tests are located in:
Example:
Special attention is given to SQL injection prevention:
All user inputs must be properly escaped. See server/src/utils/escapeSQL.ts.
Test cases include:
- Authentication bypass attempts
- Authorization failures
- Input validation failures
- Rate limiting behavior
# Run all tests
npm test
# Run specific test file
npm test -- tests/unit/filterQueryBuilder.test.ts
# Run with coverage
npm run test:cov
# Watch mode
npm test -- --watch
# Run integration tests only (requires live DB at DB_NAME=shadowcheck_test)
RUN_INTEGRATION_TESTS=true DB_NAME=shadowcheck_test npm test
# Focused sibling integration tests
RUN_INTEGRATION_TESTS=true DB_NAME=shadowcheck_test npx jest --testPathPattern="siblingRuleQuality|siblingCoverage" --no-coverage
# Focused sibling unit tests
DB_NAME=shadowcheck_test npx jest tests/unit/siblingDetectionQueries.test.ts tests/unit/adminSiblingService.test.ts --no-coverageTests run automatically on:
- Pull requests
- Merges to main/develop branches
- See
.circleci/config.yml
Test fixtures are managed in:
tests/fixtures/(if exists)- Inline in test files
- Database seeding scripts
Use mocking for:
- Database queries
- External API calls
- File system operations
- Network requests
- ✅ Write tests before fixing bugs (TDD recommended)
- ✅ Use descriptive test names
- ✅ Test edge cases and error conditions
- ✅ Keep tests independent and isolated
- ✅ Use setup/teardown functions appropriately
- ✅ Aim for high coverage on critical paths
- ❌ Commit tests that fail
- ❌ Skip tests without a good reason
- ❌ Test implementation details (test behavior)
- ❌ Make tests dependent on execution order
- ❌ Use hardcoded environment values
-
Timeout errors: Increase timeout for slow operations
it('should handle slow query', async () => { jest.setTimeout(30000); // ... }, 30000);
-
Database connection errors: Ensure test database is running
# Check database connection npm run docker:up -
Memory issues: Run tests sequentially
npm test -- --runInBand
See the CI configuration: