import { TimeWindow } from '../../../../src/domain/value-objects/time-window.vo'; describe('TimeWindow Value Object', () => { describe('constants', () => { it('should have default online window of 180 seconds', () => { expect(TimeWindow.DEFAULT_ONLINE_WINDOW_SECONDS).toBe(180); }); it('should have default heartbeat interval of 60 seconds', () => { expect(TimeWindow.DEFAULT_HEARTBEAT_INTERVAL_SECONDS).toBe(60); }); }); describe('default', () => { it('should create default TimeWindow with 180 seconds', () => { const window = TimeWindow.default(); expect(window.windowSeconds).toBe(180); }); }); describe('ofSeconds', () => { it('should create TimeWindow with custom seconds', () => { const window = TimeWindow.ofSeconds(300); expect(window.windowSeconds).toBe(300); }); it('should create TimeWindow with 1 second', () => { const window = TimeWindow.ofSeconds(1); expect(window.windowSeconds).toBe(1); }); it('should throw error for zero seconds', () => { expect(() => TimeWindow.ofSeconds(0)).toThrow('TimeWindow must be positive'); }); it('should throw error for negative seconds', () => { expect(() => TimeWindow.ofSeconds(-1)).toThrow('TimeWindow must be positive'); expect(() => TimeWindow.ofSeconds(-100)).toThrow('TimeWindow must be positive'); }); }); describe('getThresholdTimestamp', () => { it('should calculate threshold timestamp correctly', () => { const window = TimeWindow.ofSeconds(180); const now = new Date('2025-01-01T12:00:00.000Z'); const threshold = window.getThresholdTimestamp(now); // now: 1735732800 (2025-01-01 12:00:00 UTC) // threshold: 1735732800 - 180 = 1735732620 const expectedTimestamp = Math.floor(now.getTime() / 1000) - 180; expect(threshold).toBe(expectedTimestamp); }); it('should use current time if no date provided', () => { const window = TimeWindow.ofSeconds(180); const beforeCall = Math.floor(Date.now() / 1000); const threshold = window.getThresholdTimestamp(); const afterCall = Math.floor(Date.now() / 1000); // threshold should be in range [beforeCall - 180, afterCall - 180] expect(threshold).toBeGreaterThanOrEqual(beforeCall - 180); expect(threshold).toBeLessThanOrEqual(afterCall - 180); }); it('should handle different window sizes', () => { const now = new Date('2025-01-01T12:00:00.000Z'); const nowTimestamp = Math.floor(now.getTime() / 1000); const window60 = TimeWindow.ofSeconds(60); const window300 = TimeWindow.ofSeconds(300); const window3600 = TimeWindow.ofSeconds(3600); expect(window60.getThresholdTimestamp(now)).toBe(nowTimestamp - 60); expect(window300.getThresholdTimestamp(now)).toBe(nowTimestamp - 300); expect(window3600.getThresholdTimestamp(now)).toBe(nowTimestamp - 3600); }); }); describe('windowSeconds getter', () => { it('should return the configured window seconds', () => { const window = TimeWindow.ofSeconds(120); expect(window.windowSeconds).toBe(120); }); }); });