Files
gridpilot.gg/apps/website/lib/services/analytics/AnalyticsService.test.ts
2026-01-17 22:55:03 +01:00

117 lines
3.9 KiB
TypeScript

import { describe, it, expect, vi, Mocked } from 'vitest';
import { AnalyticsService } from './AnalyticsService';
import { AnalyticsApiClient } from '@/lib/api/analytics/AnalyticsApiClient';
import { RecordPageViewOutputViewModel } from '@/lib/view-models/RecordPageViewOutputViewModel';
import { RecordEngagementOutputViewModel } from '@/lib/view-models/RecordEngagementOutputViewModel';
describe('AnalyticsService', () => {
let mockApiClient: Mocked<AnalyticsApiClient>;
let service: AnalyticsService;
beforeEach(() => {
mockApiClient = {
recordPageView: vi.fn(),
recordEngagement: vi.fn(),
} as Mocked<AnalyticsApiClient>;
service = new AnalyticsService(mockApiClient);
});
describe('recordPageView', () => {
it('should call apiClient.recordPageView with correct input', async () => {
const input = {
path: '/dashboard',
userId: 'user-123',
};
const expectedOutput = { pageViewId: 'pv-123' };
mockApiClient.recordPageView.mockResolvedValue(expectedOutput);
const result = await service.recordPageView(input);
expect(mockApiClient.recordPageView).toHaveBeenCalledWith({
entityType: 'page',
entityId: '/dashboard',
visitorType: 'user',
sessionId: 'temp-session',
path: '/dashboard',
userId: 'user-123',
});
expect(result).toBeInstanceOf(RecordPageViewOutputViewModel);
expect(result.pageViewId).toEqual('pv-123');
});
it('should call apiClient.recordPageView without userId when not provided', async () => {
const input = {
path: '/home',
};
const expectedOutput = { pageViewId: 'pv-456' };
mockApiClient.recordPageView.mockResolvedValue(expectedOutput);
const result = await service.recordPageView(input);
expect(mockApiClient.recordPageView).toHaveBeenCalledWith({
entityType: 'page',
entityId: '/home',
visitorType: 'guest',
sessionId: 'temp-session',
path: '/home',
});
expect(result).toBeInstanceOf(RecordPageViewOutputViewModel);
expect(result.pageViewId).toEqual('pv-456');
});
});
describe('recordEngagement', () => {
it('should call apiClient.recordEngagement with correct input', async () => {
const input = {
eventType: 'button_click',
userId: 'user-123',
metadata: { buttonId: 'submit', page: '/form' },
};
const expectedOutput = { eventId: 'event-123', engagementWeight: 1.5 };
mockApiClient.recordEngagement.mockResolvedValue(expectedOutput);
const result = await service.recordEngagement(input);
expect(mockApiClient.recordEngagement).toHaveBeenCalledWith({
action: 'button_click',
entityType: 'ui_element',
entityId: 'unknown',
actorType: 'user',
sessionId: 'temp-session',
eventType: 'button_click',
userId: 'user-123',
metadata: { buttonId: 'submit', page: '/form' },
});
expect(result).toBeInstanceOf(RecordEngagementOutputViewModel);
expect(result.eventId).toEqual('event-123');
expect(result.engagementWeight).toEqual(1.5);
});
it('should call apiClient.recordEngagement without optional fields', async () => {
const input = {
eventType: 'page_load',
};
const expectedOutput = { eventId: 'event-456', engagementWeight: 0.5 };
mockApiClient.recordEngagement.mockResolvedValue(expectedOutput);
const result = await service.recordEngagement(input);
expect(mockApiClient.recordEngagement).toHaveBeenCalledWith({
action: 'page_load',
entityType: 'ui_element',
entityId: 'unknown',
actorType: 'guest',
sessionId: 'temp-session',
eventType: 'page_load',
});
expect(result).toBeInstanceOf(RecordEngagementOutputViewModel);
expect(result.eventId).toEqual('event-456');
expect(result.engagementWeight).toEqual(0.5);
});
});
});