113 lines
3.8 KiB
TypeScript
113 lines
3.8 KiB
TypeScript
import { Test, TestingModule } from '@nestjs/testing';
|
|
import { vi } from 'vitest';
|
|
import { AnalyticsController } from './AnalyticsController';
|
|
import { AnalyticsService } from './AnalyticsService';
|
|
import type { Response } from 'express';
|
|
import { EntityType, VisitorType } from '@core/analytics/domain/types/PageView';
|
|
import { EngagementAction, EngagementEntityType } from '@core/analytics/domain/types/EngagementEvent';
|
|
import type { RecordEngagementOutputDTO } from './dtos/RecordEngagementOutputDTO';
|
|
import type { RecordPageViewOutputDTO } from './dtos/RecordPageViewOutputDTO';
|
|
|
|
describe('AnalyticsController', () => {
|
|
let controller: AnalyticsController;
|
|
let service: ReturnType<typeof vi.mocked<AnalyticsService>>;
|
|
|
|
beforeEach(() => {
|
|
service = {
|
|
recordPageView: vi.fn(),
|
|
recordEngagement: vi.fn(),
|
|
getDashboardData: vi.fn(),
|
|
getAnalyticsMetrics: vi.fn(),
|
|
} as any;
|
|
controller = new AnalyticsController(service);
|
|
});
|
|
|
|
describe('recordPageView', () => {
|
|
it('should record a page view and return 201', async () => {
|
|
const input = {
|
|
entityType: EntityType.RACE,
|
|
entityId: 'race-123',
|
|
visitorType: VisitorType.ANONYMOUS,
|
|
sessionId: 'session-456',
|
|
visitorId: 'visitor-789',
|
|
referrer: 'https://example.com',
|
|
userAgent: 'Mozilla/5.0',
|
|
country: 'US',
|
|
};
|
|
const dto: RecordPageViewOutputDTO = { pageViewId: 'pv-123' };
|
|
service.recordPageView.mockResolvedValue(dto);
|
|
|
|
const mockRes: ReturnType<typeof vi.mocked<Response>> = {
|
|
status: vi.fn().mockReturnThis(),
|
|
json: vi.fn(),
|
|
} as unknown as ReturnType<typeof vi.mocked<Response>>;
|
|
|
|
await controller.recordPageView(input, mockRes);
|
|
|
|
expect(service.recordPageView).toHaveBeenCalledWith(input);
|
|
expect(mockRes.status).toHaveBeenCalledWith(201);
|
|
expect(mockRes.json).toHaveBeenCalledWith(dto);
|
|
});
|
|
});
|
|
|
|
describe('recordEngagement', () => {
|
|
it('should record an engagement and return 201', async () => {
|
|
const input = {
|
|
action: EngagementAction.CLICK_SPONSOR_LOGO,
|
|
entityType: EngagementEntityType.RACE,
|
|
entityId: 'race-123',
|
|
actorType: 'driver' as const,
|
|
sessionId: 'session-456',
|
|
actorId: 'actor-789',
|
|
metadata: { key: 'value' },
|
|
};
|
|
const dto: RecordEngagementOutputDTO = { eventId: 'event-123', engagementWeight: 10 };
|
|
service.recordEngagement.mockResolvedValue(dto);
|
|
|
|
const mockRes: ReturnType<typeof vi.mocked<Response>> = {
|
|
status: vi.fn().mockReturnThis(),
|
|
json: vi.fn(),
|
|
} as unknown as ReturnType<typeof vi.mocked<Response>>;
|
|
|
|
await controller.recordEngagement(input, mockRes);
|
|
|
|
expect(service.recordEngagement).toHaveBeenCalledWith(input);
|
|
expect(mockRes.status).toHaveBeenCalledWith(201);
|
|
expect(mockRes.json).toHaveBeenCalledWith(dto);
|
|
});
|
|
});
|
|
|
|
describe('getDashboardData', () => {
|
|
it('should return dashboard data', async () => {
|
|
const dto = {
|
|
totalUsers: 100,
|
|
activeUsers: 50,
|
|
totalRaces: 20,
|
|
totalLeagues: 5,
|
|
};
|
|
service.getDashboardData.mockResolvedValue(dto);
|
|
|
|
const result = await controller.getDashboardData();
|
|
|
|
expect(service.getDashboardData).toHaveBeenCalled();
|
|
expect(result).toEqual(dto);
|
|
});
|
|
});
|
|
|
|
describe('getAnalyticsMetrics', () => {
|
|
it('should return analytics metrics', async () => {
|
|
const dto = {
|
|
pageViews: 1000,
|
|
uniqueVisitors: 500,
|
|
averageSessionDuration: 300,
|
|
bounceRate: 0.4,
|
|
};
|
|
service.getAnalyticsMetrics.mockResolvedValue(dto);
|
|
|
|
const result = await controller.getAnalyticsMetrics();
|
|
|
|
expect(service.getAnalyticsMetrics).toHaveBeenCalled();
|
|
expect(result).toEqual(dto);
|
|
});
|
|
});
|
|
}); |