Files
proxy/nodejs/test/README.md
T
wmantly 5139fbb79a Documentation cleanup for public release (#123)
Prepares the docs for the public release announcement: removes obsolete/dead
material, fixes drift between the API reference and the actual routes, and
standardizes on the default GitHub Pages URL.

- Remove Vagrant entirely: delete Vagrantfile, docs/dev_setup.md, and stale
  vagrant references in .gitignore/.dockerignore; rewrite openresty/README.md
  to describe the actual (currently unused) directory and point to
  ops/nginx_conf/ for the real OpenResty config.
- Delete docs/Update 4.11.md (personal scratch changelog) and drop both its
  and dev_setup.md's references from docs/README.md's Legacy Documentation
  section.
- Remove checkmark emoji from docs/contributing.md's PR Requirements list.
- Bring the auth model docs up to date with the code: document
  GET /api/auth/oidc/start + /callback, the /api/permission and /api/group
  RBAC routers, the /api/dns/dynamic/* sub-API, and /api/api-token (self
  -service PATs) in both nodejs/api.md and docs/api.md; add the missing
  "Clear Host Cache" section; drop the invite-token/SSH-key endpoints that no
  longer exist in nodejs/routes/user.js; note admin-only routes. Mention
  OIDC/LDAP/RBAC as core features in README.md.
- Keep nodejs/api.md and docs/api.md fully in sync (same body, differing only
  in Jekyll front matter / relative links) instead of letting them drift.
- Fix Node.js version references (20.x -> 22.x) in README.md and
  docs/installation.md to match ops/install.sh and the Dockerfile.
- Note that the manual nginx-conf/systemd install steps in README.md and
  docs/installation.md won't auto-track repo changes the way install.sh's
  symlink approach does, and recommend install.sh.
- Update the stale test/unit file lists in docs/contributing.md and
  nodejs/test/README.md to match the actual directory contents.
- Add npm run test:integration to README.md's Running Tests section.
- Add nodejs/conf/, nodejs/controller/, and nodejs/migrations/ to the project
  structure diagrams in README.md, docs/architecture.md, and
  docs/contributing.md.
- Standardize "CloudFlare" -> "Cloudflare" everywhere to match the actual API
  value in nodejs/models/dns_provider.js.
- Add the missing app_auth__adminGroups row to DEPLOYMENT.md's app_* table.
- Delete docs/CNAME (custom domain) so GitHub Pages serves from the default
  https://theta42.github.io/proxy/, matching docs/README.md.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 23:20:59 -04:00

167 lines
4.7 KiB
Markdown

# Test Suite
This project uses Node.js built-in test runner (requires Node 18+). No external testing dependencies required.
## Running Tests
```bash
# Run all tests
npm test
# Run only unit tests
npm run test:unit
# Run only integration tests
npm run test:integration
# Run tests in watch mode (auto-rerun on file changes)
npm run test:watch
```
## Test Structure
```
test/
├── unit/ # Unit tests for isolated components
│ ├── basicauth.test.js
│ ├── callback_queue.test.js
│ ├── dynamic_record.test.js
│ ├── host_features.test.js
│ ├── host_lookup.test.js
│ ├── hostname_validate.test.js
│ ├── host_sso.test.js
│ ├── oidc.test.js
│ ├── password_policy.test.js
│ ├── roles.test.js
│ ├── safe_redirect.test.js
│ ├── unix_socket.test.js
│ └── wildcard_matchany.test.js
├── integration/ # Integration tests for complex interactions
│ └── dns_provider.test.js
└── helpers/ # Test utilities and contracts
└── dns_provider_contract.js
```
## What We Test
### Unit Tests
**callback_queue.test.js**
- Callback registration and invocation
- Multiple callbacks with arguments
- Error handling
**host_lookup.test.js**
- Host lookup tree algorithm
- Wildcard matching (single and double)
- Exact match priority
- Edge cases (no match, empty input, etc.)
**unix_socket.test.js**
- Unix socket server creation
- JSON message parsing
- Partial data buffering
- Multiple connections
- Error handling
### Integration Tests
**dns_provider.test.js**
- DNS provider contract compliance
- All existing providers (Cloudflare, DigitalOcean, PorkBun)
- Method signatures
- Key mapping
- Type validation
## Adding a New DNS Provider
When you add a new DNS provider, you MUST add tests to ensure it meets the contract:
1. Create your provider class extending `DnsApi` in `models/dns_provider/yourprovider.js`
2. Add a test block in `test/integration/dns_provider.test.js`:
```javascript
describe('YourProvider Provider', () => {
const YourProvider = require('../../models/dns_provider/yourprovider');
test('should meet DNS provider contract', () => {
const mockCredentials = {api_key: 'mock-key'};
const instance = validateDnsProviderContract(YourProvider, mockCredentials);
assert.ok(instance, 'YourProvider should be instantiated');
});
test('should have correct _keyMap structure', () => {
// Test your specific credential requirements
assert.ok(YourProvider._keyMap.api_key);
assert.strictEqual(YourProvider._keyMap.api_key.type, 'string');
assert.strictEqual(YourProvider._keyMap.api_key.isRequired, true);
});
test('should have valid method signatures', () => {
const instance = new YourProvider({api_key: 'mock'});
validateMethodSignatures(instance);
});
test('should validate key mapping', () => {
const instance = new YourProvider({api_key: 'mock'});
validateKeyMapping(instance);
});
test('should validate type checking', () => {
const instance = new YourProvider({api_key: 'mock'});
validateTypeChecking(instance);
});
});
```
3. Run tests to verify compliance:
```bash
npm run test:integration
```
## DNS Provider Contract
All DNS providers must:
1. Extend `DnsApi` base class
2. Define static `_keyMap` with required credentials
3. Define static display properties: `displayName`, `displayIconHtml`, `displayIconUni`
4. Implement required methods:
- `listDomains()` - Returns array of `{domain, zoneId}`
- `getRecords(domain, options)` - Returns array of DNS records
- `createRecord(domain, options)` - Creates a record
- `deleteRecords(domain, options)` - Deletes matching records
5. Define `__apiKeyMap` to translate between class keys and API keys
6. Implement or inherit `__typeCheck()` for record type validation
7. Throw appropriate errors from `this.errors` object
## CI/CD Integration
Tests can be run in GitHub Actions, GitLab CI, or any CI/CD system:
```yaml
# Example GitHub Actions workflow
- name: Run tests
run: npm test
```
## Philosophy
We test **custom logic**, not third-party code:
- YES: Test our host lookup algorithm
- YES: Test our socket buffering logic
- YES: Test DNS provider contracts
- NO: Don't test Express.js routing
- NO: Don't test the Redis ORM
- NO: Don't test external DNS APIs (use mocks)
## Notes
- Tests use Node's built-in `node:test` and `node:assert` modules
- No external testing framework needed
- Tests are fast and run in parallel by default
- Mock external services (Redis, DNS APIs) to avoid network calls
- Focus on testing business logic, not infrastructure