119 lines
4.3 KiB
TypeScript
119 lines
4.3 KiB
TypeScript
import { Test, TestingModule } from '@nestjs/testing';
|
|
import { GetOnlineCountHandler } from '../../../../src/application/queries/get-online-count/get-online-count.handler';
|
|
import { GetOnlineCountQuery } from '../../../../src/application/queries/get-online-count/get-online-count.query';
|
|
import { PresenceRedisRepository } from '../../../../src/infrastructure/redis/presence-redis.repository';
|
|
import { OnlineDetectionService } from '../../../../src/domain/services/online-detection.service';
|
|
import { TimeWindow } from '../../../../src/domain/value-objects/time-window.vo';
|
|
|
|
describe('GetOnlineCountHandler', () => {
|
|
let handler: GetOnlineCountHandler;
|
|
let presenceRedisRepository: jest.Mocked<PresenceRedisRepository>;
|
|
let onlineDetectionService: OnlineDetectionService;
|
|
|
|
beforeEach(async () => {
|
|
const mockPresenceRedisRepository = {
|
|
updateUserPresence: jest.fn(),
|
|
countOnlineUsers: jest.fn(),
|
|
getOnlineUsers: jest.fn(),
|
|
removeExpiredUsers: jest.fn(),
|
|
};
|
|
|
|
const module: TestingModule = await Test.createTestingModule({
|
|
providers: [
|
|
GetOnlineCountHandler,
|
|
{
|
|
provide: PresenceRedisRepository,
|
|
useValue: mockPresenceRedisRepository,
|
|
},
|
|
OnlineDetectionService,
|
|
],
|
|
}).compile();
|
|
|
|
handler = module.get<GetOnlineCountHandler>(GetOnlineCountHandler);
|
|
presenceRedisRepository = module.get(PresenceRedisRepository);
|
|
onlineDetectionService = module.get(OnlineDetectionService);
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe('execute', () => {
|
|
it('should return online count', async () => {
|
|
presenceRedisRepository.countOnlineUsers.mockResolvedValue(1500);
|
|
|
|
const query = new GetOnlineCountQuery();
|
|
const result = await handler.execute(query);
|
|
|
|
expect(result.count).toBe(1500);
|
|
});
|
|
|
|
it('should return window seconds from OnlineDetectionService', async () => {
|
|
presenceRedisRepository.countOnlineUsers.mockResolvedValue(100);
|
|
|
|
const query = new GetOnlineCountQuery();
|
|
const result = await handler.execute(query);
|
|
|
|
expect(result.windowSeconds).toBe(TimeWindow.DEFAULT_ONLINE_WINDOW_SECONDS);
|
|
});
|
|
|
|
it('should return queriedAt timestamp', async () => {
|
|
presenceRedisRepository.countOnlineUsers.mockResolvedValue(100);
|
|
|
|
const beforeQuery = new Date();
|
|
const query = new GetOnlineCountQuery();
|
|
const result = await handler.execute(query);
|
|
const afterQuery = new Date();
|
|
|
|
expect(result.queriedAt).toBeInstanceOf(Date);
|
|
expect(result.queriedAt.getTime()).toBeGreaterThanOrEqual(beforeQuery.getTime());
|
|
expect(result.queriedAt.getTime()).toBeLessThanOrEqual(afterQuery.getTime());
|
|
});
|
|
|
|
it('should call countOnlineUsers with correct threshold', async () => {
|
|
presenceRedisRepository.countOnlineUsers.mockResolvedValue(500);
|
|
|
|
const query = new GetOnlineCountQuery();
|
|
await handler.execute(query);
|
|
|
|
expect(presenceRedisRepository.countOnlineUsers).toHaveBeenCalledWith(
|
|
expect.any(Number),
|
|
);
|
|
|
|
// Verify threshold is approximately (now - 180 seconds)
|
|
const calledThreshold = presenceRedisRepository.countOnlineUsers.mock.calls[0][0];
|
|
const expectedThreshold = Math.floor(Date.now() / 1000) - 180;
|
|
|
|
expect(Math.abs(calledThreshold - expectedThreshold)).toBeLessThanOrEqual(1);
|
|
});
|
|
|
|
it('should handle zero online users', async () => {
|
|
presenceRedisRepository.countOnlineUsers.mockResolvedValue(0);
|
|
|
|
const query = new GetOnlineCountQuery();
|
|
const result = await handler.execute(query);
|
|
|
|
expect(result.count).toBe(0);
|
|
});
|
|
|
|
it('should handle large number of online users', async () => {
|
|
presenceRedisRepository.countOnlineUsers.mockResolvedValue(1000000);
|
|
|
|
const query = new GetOnlineCountQuery();
|
|
const result = await handler.execute(query);
|
|
|
|
expect(result.count).toBe(1000000);
|
|
});
|
|
|
|
it('should throw error when Redis fails', async () => {
|
|
presenceRedisRepository.countOnlineUsers.mockRejectedValue(
|
|
new Error('Redis connection timeout'),
|
|
);
|
|
|
|
const query = new GetOnlineCountQuery();
|
|
|
|
await expect(handler.execute(query)).rejects.toThrow('Redis connection timeout');
|
|
});
|
|
});
|
|
});
|