@robiki/proxy 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robiki/proxy",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A flexible HTTP/2 proxy server with WebSocket support, configurable routing, CORS, and validation. Use as npm package or Docker container.",
5
5
  "keywords": [
6
6
  "proxy",
@@ -60,7 +60,11 @@
60
60
  "test:docker": "make test-docker-full",
61
61
  "test:docker:config": "make test-docker-config",
62
62
  "test:all": "yarn test && yarn test:docker",
63
- "prepublishOnly": "yarn build"
63
+ "prepublishOnly": "yarn build",
64
+ "publish:npm": "npm publish",
65
+ "publish:docker": "make docker-push-hub",
66
+ "publish:docker:multiarch": "make docker-push-multiarch",
67
+ "publish:all": "yarn publish:npm && yarn publish:docker"
64
68
  },
65
69
  "devDependencies": {
66
70
  "@types/node": "25.0.3",
@@ -83,4 +87,4 @@
83
87
  "publishConfig": {
84
88
  "access": "public"
85
89
  }
86
- }
90
+ }
@@ -0,0 +1,293 @@
1
+ # Robiki Proxy Tests
2
+
3
+ This directory contains comprehensive tests for the Robiki Proxy library.
4
+
5
+ ## Test Structure
6
+
7
+ ```
8
+ tests/
9
+ ├── unit/ # Unit tests for individual components
10
+ │ └── utils/ # Utility function tests
11
+ │ ├── config.test.ts # Configuration management tests
12
+ │ ├── server.test.ts # Server utility tests
13
+ │ ├── files.test.ts # File utility tests
14
+ │ ├── time.test.ts # Time utility tests
15
+ │ └── uuid.test.ts # UUID generation tests
16
+ ├── integration/ # Integration tests
17
+ │ ├── proxy-server.test.ts # ProxyServer class tests
18
+ │ ├── http-proxy.test.ts # HTTP proxy handler tests
19
+ │ ├── full-proxy.test.ts # Full proxy integration tests
20
+ │ └── config-loading.test.ts # Configuration file loading tests
21
+ ├── advanced/ # Advanced feature tests
22
+ │ ├── websocket.test.ts # WebSocket proxying tests
23
+ │ └── http2.test.ts # HTTP/2 specific tests
24
+ ├── docker/ # Docker integration tests
25
+ │ ├── test-docker.sh # Full Docker integration test
26
+ │ ├── test-config-loading.sh # Config loading test
27
+ │ ├── validate.sh # Prerequisites validation
28
+ │ └── README.md # Docker testing documentation
29
+ └── helpers/ # Shared test utilities
30
+ └── test-utils.ts # Reusable test helpers
31
+ ```
32
+
33
+ ## Running Tests
34
+
35
+ ### Run all tests
36
+
37
+ ```bash
38
+ yarn test
39
+ ```
40
+
41
+ ### Run tests in watch mode
42
+
43
+ ```bash
44
+ yarn test:watch
45
+ ```
46
+
47
+ ### Run tests with UI
48
+
49
+ ```bash
50
+ yarn test:ui
51
+ ```
52
+
53
+ ### Run tests with coverage
54
+
55
+ ```bash
56
+ yarn test:coverage
57
+ ```
58
+
59
+ ### Run Docker tests
60
+
61
+ ```bash
62
+ # Full Docker integration test
63
+ yarn test:docker
64
+
65
+ # Config loading test
66
+ yarn test:docker:config
67
+
68
+ # Run all tests (unit + integration + Docker)
69
+ yarn test:all
70
+ ```
71
+
72
+ ### Run specific test file
73
+
74
+ ```bash
75
+ yarn test tests/unit/utils/config.test.ts
76
+ ```
77
+
78
+ ### Run tests matching a pattern
79
+
80
+ ```bash
81
+ yarn test -t "ProxyConfig"
82
+ ```
83
+
84
+ ## Test Categories
85
+
86
+ ### Unit Tests
87
+
88
+ Unit tests focus on testing individual functions and classes in isolation. They are fast and don't require external dependencies.
89
+
90
+ **Coverage includes:**
91
+
92
+ - Configuration loading and management
93
+ - CORS header generation
94
+ - Header conversion (HTTP/1.1 ↔ HTTP/2)
95
+ - Time utilities
96
+ - File type detection
97
+ - UUID generation
98
+
99
+ ### Integration Tests
100
+
101
+ Integration tests verify that different components work together correctly. They may start actual servers and make real HTTP requests.
102
+
103
+ **Coverage includes:**
104
+
105
+ - ProxyServer class functionality
106
+ - HTTP request proxying
107
+ - Route resolution
108
+ - URL remapping
109
+ - Request validation
110
+ - Multi-backend routing
111
+ - Configuration file loading (proxy.config.json)
112
+ - Environment variable configuration
113
+
114
+ ### Advanced Tests
115
+
116
+ Advanced tests cover complex scenarios and protocol-specific features.
117
+
118
+ **Coverage includes:**
119
+
120
+ - WebSocket connection proxying
121
+ - WebSocket message forwarding
122
+ - WebSocket validation
123
+ - HTTP/2 stream handling
124
+ - HTTP/2 multiplexing
125
+ - HTTP/2 header compression concepts
126
+
127
+ ### Docker Tests
128
+
129
+ Docker tests verify the containerized deployment of the proxy server.
130
+
131
+ **Coverage includes:**
132
+
133
+ - Docker image build process
134
+ - Container startup and health
135
+ - Configuration file mounting and loading
136
+ - Port accessibility
137
+ - Environment variable handling
138
+ - Graceful shutdown
139
+ - Docker Compose integration
140
+
141
+ See [tests/docker/README.md](docker/README.md) for detailed Docker testing documentation.
142
+
143
+ ## Writing Tests
144
+
145
+ ### Test Structure
146
+
147
+ Tests follow the Arrange-Act-Assert pattern:
148
+
149
+ ```typescript
150
+ it('should do something', () => {
151
+ // Arrange: Set up test data
152
+ const config = { ... };
153
+
154
+ // Act: Execute the code being tested
155
+ const result = someFunction(config);
156
+
157
+ // Assert: Verify the results
158
+ expect(result).toBe(expectedValue);
159
+ });
160
+ ```
161
+
162
+ ### Async Tests
163
+
164
+ For asynchronous operations, use async/await:
165
+
166
+ ```typescript
167
+ it('should handle async operations', async () => {
168
+ const result = await asyncFunction();
169
+ expect(result).toBeDefined();
170
+ });
171
+ ```
172
+
173
+ ### Test Lifecycle Hooks
174
+
175
+ Use lifecycle hooks to set up and tear down test environments:
176
+
177
+ ```typescript
178
+ describe('Test Suite', () => {
179
+ beforeAll(async () => {
180
+ // Runs once before all tests
181
+ });
182
+
183
+ afterAll(async () => {
184
+ // Runs once after all tests
185
+ });
186
+
187
+ beforeEach(() => {
188
+ // Runs before each test
189
+ });
190
+
191
+ afterEach(() => {
192
+ // Runs after each test
193
+ });
194
+ });
195
+ ```
196
+
197
+ ### Mocking
198
+
199
+ For unit tests, mock external dependencies:
200
+
201
+ ```typescript
202
+ import { vi } from 'vitest';
203
+
204
+ const mockFunction = vi.fn(() => 'mocked value');
205
+ ```
206
+
207
+ ## Test Coverage Goals
208
+
209
+ We aim for the following coverage targets:
210
+
211
+ - **Statements:** > 80%
212
+ - **Branches:** > 75%
213
+ - **Functions:** > 80%
214
+ - **Lines:** > 80%
215
+
216
+ ## Best Practices
217
+
218
+ 1. **Descriptive test names:** Use clear, descriptive names that explain what is being tested
219
+ 2. **One assertion per test:** Focus each test on a single behavior
220
+ 3. **Avoid test interdependence:** Tests should be able to run in any order
221
+ 4. **Clean up resources:** Always close servers, connections, and clean up after tests
222
+ 5. **Use appropriate timeouts:** Set reasonable timeouts for async operations
223
+ 6. **Test edge cases:** Include tests for error conditions and edge cases
224
+ 7. **Keep tests fast:** Unit tests should run in milliseconds, integration tests in seconds
225
+
226
+ ## Debugging Tests
227
+
228
+ ### Run a single test
229
+
230
+ ```bash
231
+ yarn test -t "specific test name"
232
+ ```
233
+
234
+ ### Run with verbose output
235
+
236
+ ```bash
237
+ yarn test --reporter=verbose
238
+ ```
239
+
240
+ ### Debug in VS Code
241
+
242
+ Add a breakpoint and use the "Debug Test" option in VS Code's test explorer.
243
+
244
+ ## Continuous Integration
245
+
246
+ Tests are automatically run in CI/CD pipelines on:
247
+
248
+ - Pull requests
249
+ - Commits to main branch
250
+ - Release builds
251
+
252
+ All tests must pass before code can be merged.
253
+
254
+ ## Contributing
255
+
256
+ When adding new features:
257
+
258
+ 1. Write tests first (TDD approach recommended)
259
+ 2. Ensure all existing tests pass
260
+ 3. Add tests for edge cases
261
+ 4. Update this README if adding new test categories
262
+ 5. Maintain or improve code coverage
263
+
264
+ ## Troubleshooting
265
+
266
+ ### Port conflicts
267
+
268
+ If tests fail due to port conflicts, the test suite uses high port numbers (9876-9894) to avoid conflicts. If you still experience issues, check for processes using these ports:
269
+
270
+ ```bash
271
+ lsof -i :9876-9894
272
+ ```
273
+
274
+ ### Timeout errors
275
+
276
+ If tests timeout, increase the timeout in `vitest.config.ts` or for specific tests:
277
+
278
+ ```typescript
279
+ it('slow test', async () => {
280
+ // test code
281
+ }, 30000); // 30 second timeout
282
+ ```
283
+
284
+ ### WebSocket connection issues
285
+
286
+ WebSocket tests may fail if connections aren't properly closed. Ensure all WebSocket connections are explicitly closed in test cleanup.
287
+
288
+ ## Resources
289
+
290
+ - [Vitest Documentation](https://vitest.dev/)
291
+ - [Testing Best Practices](https://github.com/goldbergyoni/javascript-testing-best-practices)
292
+ - [Node.js HTTP/2 Documentation](https://nodejs.org/api/http2.html)
293
+ - [WebSocket API Documentation](https://github.com/websockets/ws)
@@ -0,0 +1,303 @@
1
+ # Docker Tests
2
+
3
+ This directory contains Docker integration tests for the Robiki Proxy.
4
+
5
+ ## Test Scripts
6
+
7
+ ### 1. `test-docker.sh`
8
+
9
+ Comprehensive Docker build and runtime tests.
10
+
11
+ **What it tests:**
12
+
13
+ - Docker image builds successfully
14
+ - Container starts and stays running
15
+ - Configuration is loaded correctly
16
+ - Ports are accessible
17
+ - Environment variables are set
18
+ - Health checks work
19
+ - Graceful shutdown
20
+
21
+ **Usage:**
22
+
23
+ ```bash
24
+ ./tests/docker/test-docker.sh
25
+ ```
26
+
27
+ Or using Make:
28
+
29
+ ```bash
30
+ make test-docker-full
31
+ ```
32
+
33
+ ### 2. `test-config-loading.sh`
34
+
35
+ Tests specifically for proxy.config.json loading.
36
+
37
+ **What it tests:**
38
+
39
+ - Empty routes configuration
40
+ - Multiple routes configuration
41
+ - CORS configuration
42
+ - Wildcard routes
43
+ - File permissions and readability
44
+ - Configuration priority (file > env > defaults)
45
+
46
+ **Usage:**
47
+
48
+ ```bash
49
+ ./tests/docker/test-config-loading.sh
50
+ ```
51
+
52
+ Or using Make:
53
+
54
+ ```bash
55
+ make test-docker-config
56
+ ```
57
+
58
+ ## Quick Test Commands
59
+
60
+ ### Build Docker Images
61
+
62
+ ```bash
63
+ # Standard build (with dev dependencies for build process)
64
+ make docker-build
65
+
66
+ # Build with dev dependencies (for testing/development)
67
+ make docker-build-dev
68
+
69
+ # Build without dev dependencies (production-optimized)
70
+ make docker-build-prod
71
+ ```
72
+
73
+ ### Build and Basic Test
74
+
75
+ ```bash
76
+ make test-docker
77
+ ```
78
+
79
+ ### Full Integration Test
80
+
81
+ ```bash
82
+ make test-docker-full
83
+ ```
84
+
85
+ ### Config Loading Test
86
+
87
+ ```bash
88
+ make test-docker-config
89
+ ```
90
+
91
+ ### Docker Compose Test
92
+
93
+ ```bash
94
+ make test-docker-compose
95
+ ```
96
+
97
+ ## Build Arguments
98
+
99
+ The Dockerfile supports a build argument to control dependency installation:
100
+
101
+ - `INSTALL_DEV_DEPS=true` (default) - Installs all dependencies including devDependencies. Required for building the application.
102
+ - `INSTALL_DEV_DEPS=false` - Installs only production dependencies. Use this for ultra-minimal production images when you already have pre-built artifacts.
103
+
104
+ **Examples:**
105
+
106
+ ```bash
107
+ # Build with dev dependencies (default, includes build tools)
108
+ docker build --build-arg INSTALL_DEV_DEPS=true -t robiki/proxy:latest .
109
+
110
+ # Build without dev dependencies (smaller image, no build)
111
+ docker build --build-arg INSTALL_DEV_DEPS=false -t robiki/proxy:prod .
112
+ ```
113
+
114
+ **Note:** The default behavior (`INSTALL_DEV_DEPS=true`) is recommended for most use cases as it builds the application from source.
115
+
116
+ ## Manual Testing
117
+
118
+ ### 1. Build the Image
119
+
120
+ ```bash
121
+ docker build -t robiki/proxy:test .
122
+ ```
123
+
124
+ ### 2. Create Test Config
125
+
126
+ ```bash
127
+ cat > proxy.config.test.json <<EOF
128
+ {
129
+ "routes": {
130
+ "test.local": {
131
+ "target": "httpbin.org:80"
132
+ }
133
+ }
134
+ }
135
+ EOF
136
+ ```
137
+
138
+ ### 3. Run Container
139
+
140
+ ```bash
141
+ docker run -d \
142
+ --name test-proxy \
143
+ -p 8080:8080 \
144
+ -v $(pwd)/proxy.config.test.json:/usr/src/proxy.config.json:ro \
145
+ robiki/proxy:test
146
+ ```
147
+
148
+ ### 4. Check Logs
149
+
150
+ ```bash
151
+ docker logs test-proxy
152
+ ```
153
+
154
+ ### 5. Test Connection
155
+
156
+ ```bash
157
+ curl -v http://localhost:8080/get -H "Host: test.local"
158
+ ```
159
+
160
+ ### 6. Cleanup
161
+
162
+ ```bash
163
+ docker stop test-proxy
164
+ docker rm test-proxy
165
+ rm proxy.config.test.json
166
+ ```
167
+
168
+ ## Configuration Examples
169
+
170
+ ### Minimal Config
171
+
172
+ ```json
173
+ {
174
+ "routes": {
175
+ "example.com": {
176
+ "target": "localhost:3000"
177
+ }
178
+ }
179
+ }
180
+ ```
181
+
182
+ ### With CORS
183
+
184
+ ```json
185
+ {
186
+ "routes": {
187
+ "api.example.com": {
188
+ "target": "localhost:3000"
189
+ }
190
+ },
191
+ "cors": {
192
+ "origin": "*",
193
+ "credentials": true
194
+ }
195
+ }
196
+ ```
197
+
198
+ ### With SSL (requires certificates)
199
+
200
+ ```json
201
+ {
202
+ "ssl": {
203
+ "key": "/usr/src/certs/key.pem",
204
+ "cert": "/usr/src/certs/cert.pem",
205
+ "allowHTTP1": true
206
+ },
207
+ "routes": {
208
+ "secure.example.com": {
209
+ "target": "localhost:3000",
210
+ "ssl": true
211
+ }
212
+ }
213
+ }
214
+ ```
215
+
216
+ ### With Wildcard Routes
217
+
218
+ ```json
219
+ {
220
+ "routes": {
221
+ "*.api.example.com": {
222
+ "target": "localhost:4000"
223
+ },
224
+ "example.com": {
225
+ "target": "localhost:3000"
226
+ }
227
+ }
228
+ }
229
+ ```
230
+
231
+ ## Troubleshooting
232
+
233
+ ### Container Won't Start
234
+
235
+ ```bash
236
+ # Check logs
237
+ docker logs <container-name>
238
+
239
+ # Check if config file is mounted
240
+ docker exec <container-name> ls -la /usr/src/proxy.config.json
241
+
242
+ # Check if config is valid JSON
243
+ docker exec <container-name> cat /usr/src/proxy.config.json | node -e "JSON.parse(require('fs').readFileSync(0, 'utf-8'))"
244
+ ```
245
+
246
+ ### Port Already in Use
247
+
248
+ ```bash
249
+ # Find what's using the port
250
+ lsof -i :8080
251
+
252
+ # Use different port mapping
253
+ docker run -p 9000:8080 ...
254
+ ```
255
+
256
+ ### Config Not Loading
257
+
258
+ ```bash
259
+ # Verify environment variable
260
+ docker exec <container-name> env | grep PROXY_CONFIG
261
+
262
+ # Check file permissions
263
+ docker exec <container-name> ls -la /usr/src/proxy.config.json
264
+
265
+ # Test config parsing
266
+ docker exec <container-name> node -e "console.log(require('/usr/src/proxy.config.json'))"
267
+ ```
268
+
269
+ ## CI/CD Integration
270
+
271
+ These tests are designed to run in CI/CD pipelines. See `.github/workflows/test.yml` for GitHub Actions integration.
272
+
273
+ ### Expected Test Results
274
+
275
+ - ✅ All tests should pass on `main` branch
276
+ - ✅ Docker build should complete in < 2 minutes
277
+ - ✅ Container should start in < 10 seconds
278
+ - ✅ All ports should be accessible
279
+ - ✅ Configuration should load without errors
280
+
281
+ ## Performance Benchmarks
282
+
283
+ Expected resource usage:
284
+
285
+ - **Build time**: < 2 minutes
286
+ - **Image size**: ~200-300 MB
287
+ - **Memory usage**: ~50-100 MB
288
+ - **CPU usage**: < 5% idle
289
+ - **Startup time**: < 10 seconds
290
+
291
+ ## Security Notes
292
+
293
+ - Container runs as non-root user (`node`)
294
+ - Uses `dumb-init` for proper signal handling
295
+ - Configuration files should be mounted read-only (`:ro`)
296
+ - Secrets should be passed via environment variables or Docker secrets
297
+ - Health checks are enabled by default
298
+
299
+ ## Further Reading
300
+
301
+ - [Dockerfile](../../Dockerfile)
302
+ - [docker-compose.yml](../../docker-compose.yml)
303
+ - [Main README](../../README.md)