/** * Application Query Tests: GetUserRatingLedgerQuery */ import { describe, it, expect, vi, beforeEach } from 'vitest'; import { GetUserRatingLedgerQueryHandler } from './GetUserRatingLedgerQuery'; import { RatingEventRepository } from '../../domain/repositories/RatingEventRepository'; // Mock repository const createMockRepository = () => ({ save: vi.fn(), findByUserId: vi.fn(), findByIds: vi.fn(), getAllByUserId: vi.fn(), findEventsPaginated: vi.fn(), }); describe('GetUserRatingLedgerQueryHandler', () => { let handler: GetUserRatingLedgerQueryHandler; let mockRepository: ReturnType; beforeEach(() => { mockRepository = createMockRepository(); handler = new GetUserRatingLedgerQueryHandler(mockRepository as unknown as RatingEventRepository); vi.clearAllMocks(); }); it('should query repository with default pagination', async () => { mockRepository.findEventsPaginated.mockResolvedValue({ items: [], total: 0, limit: 20, offset: 0, hasMore: false, }); await handler.execute({ userId: 'user-1' }); expect(mockRepository.findEventsPaginated).toHaveBeenCalledWith('user-1', { limit: 20, offset: 0, }); }); it('should query repository with custom pagination', async () => { mockRepository.findEventsPaginated.mockResolvedValue({ items: [], total: 0, limit: 50, offset: 100, hasMore: false, }); await handler.execute({ userId: 'user-1', limit: 50, offset: 100, }); expect(mockRepository.findEventsPaginated).toHaveBeenCalledWith('user-1', { limit: 50, offset: 100, }); }); it('should query repository with filters', async () => { mockRepository.findEventsPaginated.mockResolvedValue({ items: [], total: 0, limit: 20, offset: 0, hasMore: false, }); const filter: any = { dimensions: ['trust'], sourceTypes: ['vote'], from: '2026-01-01T00:00:00Z', to: '2026-01-31T23:59:59Z', reasonCodes: ['VOTE_POSITIVE'], }; await handler.execute({ userId: 'user-1', filter, }); expect(mockRepository.findEventsPaginated).toHaveBeenCalledWith('user-1', { limit: 20, offset: 0, filter: { dimensions: ['trust'], sourceTypes: ['vote'], from: new Date('2026-01-01T00:00:00Z'), to: new Date('2026-01-31T23:59:59Z'), reasonCodes: ['VOTE_POSITIVE'], }, }); }); it('should map domain entities to DTOs', async () => { const mockEvent = { id: { value: 'event-1' }, userId: 'user-1', dimension: { value: 'trust' }, delta: { value: 5 }, occurredAt: new Date('2026-01-15T12:00:00Z'), createdAt: new Date('2026-01-15T12:00:00Z'), source: 'admin_vote', reason: 'VOTE_POSITIVE', visibility: 'public', weight: 1.0, }; mockRepository.findEventsPaginated.mockResolvedValue({ items: [mockEvent], total: 1, limit: 20, offset: 0, hasMore: false, }); const result = await handler.execute({ userId: 'user-1' }); expect(result.entries).toHaveLength(1); expect(result.entries[0]).toEqual({ id: 'event-1', userId: 'user-1', dimension: 'trust', delta: 5, occurredAt: '2026-01-15T12:00:00.000Z', createdAt: '2026-01-15T12:00:00.000Z', source: 'admin_vote', reason: 'VOTE_POSITIVE', visibility: 'public', weight: 1.0, }); }); it('should handle pagination metadata in result', async () => { mockRepository.findEventsPaginated.mockResolvedValue({ items: [], total: 100, limit: 20, offset: 20, hasMore: true, nextOffset: 40, }); const result = await handler.execute({ userId: 'user-1', limit: 20, offset: 20 }); expect(result.pagination).toEqual({ total: 100, limit: 20, offset: 20, hasMore: true, nextOffset: 40, }); }); });