@hazeljs/core 0.2.0-rc.7 → 0.2.0

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.
@@ -163,4 +163,50 @@ describe('Interceptors', () => {
163
163
  expect(result2).toEqual(complexData);
164
164
  });
165
165
  });
166
+ describe('RetryInterceptor', () => {
167
+ it('should call next once when no retry options', async () => {
168
+ const interceptor = new interceptor_1.RetryInterceptor();
169
+ const next = jest.fn().mockResolvedValue({ ok: true });
170
+ const result = await interceptor.intercept(context, next);
171
+ expect(next).toHaveBeenCalledTimes(1);
172
+ expect(result).toEqual({ ok: true });
173
+ });
174
+ it('should call next once when retry count is 0', async () => {
175
+ const interceptor = new interceptor_1.RetryInterceptor();
176
+ context.retryOptions = {
177
+ count: 0,
178
+ };
179
+ const next = jest.fn().mockResolvedValue({ ok: true });
180
+ await interceptor.intercept(context, next);
181
+ expect(next).toHaveBeenCalledTimes(1);
182
+ });
183
+ it('should retry on failure and succeed on second attempt', async () => {
184
+ const interceptor = new interceptor_1.RetryInterceptor();
185
+ context.retryOptions =
186
+ { count: 2, delay: 1 };
187
+ const next = jest
188
+ .fn()
189
+ .mockRejectedValueOnce(new Error('fail'))
190
+ .mockResolvedValueOnce({ ok: true });
191
+ const result = await interceptor.intercept(context, next);
192
+ expect(next).toHaveBeenCalledTimes(2);
193
+ expect(result).toEqual({ ok: true });
194
+ });
195
+ it('should throw after exhausting retries', async () => {
196
+ const interceptor = new interceptor_1.RetryInterceptor();
197
+ context.retryOptions =
198
+ { count: 2, delay: 1 };
199
+ const next = jest.fn().mockRejectedValue(new Error('always fail'));
200
+ await expect(interceptor.intercept(context, next)).rejects.toThrow('always fail');
201
+ expect(next).toHaveBeenCalledTimes(3);
202
+ });
203
+ it('should not retry when retryIf returns false', async () => {
204
+ const interceptor = new interceptor_1.RetryInterceptor();
205
+ context.retryOptions =
206
+ { count: 2, retryIf: () => false };
207
+ const next = jest.fn().mockRejectedValue(new Error('no retry'));
208
+ await expect(interceptor.intercept(context, next)).rejects.toThrow('no retry');
209
+ expect(next).toHaveBeenCalledTimes(1);
210
+ });
211
+ });
166
212
  });
@@ -22,6 +22,7 @@ describe('GlobalMiddlewareManager', () => {
22
22
  mockRes = {
23
23
  setHeader: jest.fn(),
24
24
  status: jest.fn().mockReturnThis(),
25
+ end: jest.fn().mockReturnThis(),
25
26
  json: jest.fn(),
26
27
  };
27
28
  });
@@ -256,4 +257,36 @@ describe('GlobalMiddlewareManager', () => {
256
257
  expect(manager.getMiddleware()).toHaveLength(1);
257
258
  });
258
259
  });
260
+ describe('CorsMiddleware (global-middleware)', () => {
261
+ it('should set CORS headers and call next', () => {
262
+ const middleware = new global_middleware_1.CorsMiddleware();
263
+ const next = jest.fn();
264
+ middleware.use(mockReq, mockRes, next);
265
+ expect(mockRes.setHeader).toHaveBeenCalledWith('Access-Control-Allow-Origin', '*');
266
+ expect(mockRes.setHeader).toHaveBeenCalledWith('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
267
+ expect(next).toHaveBeenCalled();
268
+ });
269
+ it('should set credentials when options.credentials is true', () => {
270
+ const middleware = new global_middleware_1.CorsMiddleware({ credentials: true });
271
+ const next = jest.fn();
272
+ middleware.use(mockReq, mockRes, next);
273
+ expect(mockRes.setHeader).toHaveBeenCalledWith('Access-Control-Allow-Credentials', 'true');
274
+ });
275
+ it('should respond 204 for OPTIONS and not call next', () => {
276
+ const middleware = new global_middleware_1.CorsMiddleware();
277
+ const next = jest.fn();
278
+ mockReq.method = 'OPTIONS';
279
+ middleware.use(mockReq, mockRes, next);
280
+ expect(mockRes.status).toHaveBeenCalledWith(204);
281
+ expect(next).not.toHaveBeenCalled();
282
+ });
283
+ });
284
+ describe('LoggerMiddleware (global-middleware)', () => {
285
+ it('should log request and response and call next', async () => {
286
+ const middleware = new global_middleware_1.LoggerMiddleware();
287
+ const next = jest.fn().mockResolvedValue(undefined);
288
+ await middleware.use(mockReq, mockRes, next);
289
+ expect(next).toHaveBeenCalled();
290
+ });
291
+ });
259
292
  });
@@ -191,6 +191,16 @@ describe('RateLimitMiddleware', () => {
191
191
  expect(true).toBe(true);
192
192
  });
193
193
  });
194
+ describe('MemoryStore coverage', () => {
195
+ it('should run cleanup interval when using default store', async () => {
196
+ const middleware = new rate_limit_middleware_1.RateLimitMiddleware({ max: 5, windowMs: 60 });
197
+ await middleware.use(mockReq, mockRes, nextFn);
198
+ jest.advanceTimersByTime(61000);
199
+ await middleware.use(mockReq, mockRes, nextFn);
200
+ expect(nextFn).toHaveBeenCalled();
201
+ middleware.destroy();
202
+ });
203
+ });
194
204
  describe('edge cases', () => {
195
205
  it('should handle missing socket', async () => {
196
206
  const middleware = new rate_limit_middleware_1.RateLimitMiddleware({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hazeljs/core",
3
- "version": "0.2.0-rc.7",
3
+ "version": "0.2.0",
4
4
  "description": "Core HazelJS framework - Dependency injection, routing, decorators, and base functionality",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -63,5 +63,5 @@
63
63
  "url": "https://github.com/hazeljs/hazel-js/issues"
64
64
  },
65
65
  "homepage": "https://hazeljs.com",
66
- "gitHead": "0a2a8894e755b6cb7a5e3223dfbcd5d245dd2638"
66
+ "gitHead": "6f43ebe685dc190fbfd13f806976d58640197358"
67
67
  }