add tests
Some checks failed
Contract Testing / contract-tests (push) Failing after 6m7s
Contract Testing / contract-snapshot (push) Failing after 4m46s

This commit is contained in:
2026-01-22 11:52:42 +01:00
parent 40bc15ff61
commit fb1221701d
112 changed files with 30625 additions and 1059 deletions

View File

@@ -0,0 +1,234 @@
import { Test, TestingModule } from '@nestjs/testing';
import { describe, expect, it, vi } from 'vitest';
import { AnalyticsProviders } from './AnalyticsProviders';
import { AnalyticsService } from './AnalyticsService';
import { RecordPageViewPresenter } from './presenters/RecordPageViewPresenter';
import { RecordEngagementPresenter } from './presenters/RecordEngagementPresenter';
import { GetDashboardDataPresenter } from './presenters/GetDashboardDataPresenter';
import { GetAnalyticsMetricsPresenter } from './presenters/GetAnalyticsMetricsPresenter';
import { RecordPageViewUseCase } from '@core/analytics/application/use-cases/RecordPageViewUseCase';
import { RecordEngagementUseCase } from '@core/analytics/application/use-cases/RecordEngagementUseCase';
import { GetDashboardDataUseCase } from '@core/analytics/application/use-cases/GetDashboardDataUseCase';
import { GetAnalyticsMetricsUseCase } from '@core/analytics/application/use-cases/GetAnalyticsMetricsUseCase';
import { ANALYTICS_ENGAGEMENT_REPOSITORY_TOKEN, ANALYTICS_PAGE_VIEW_REPOSITORY_TOKEN } from '../../persistence/analytics/AnalyticsPersistenceTokens';
describe('AnalyticsProviders', () => {
describe('AnalyticsService', () => {
it('should be defined as a provider', () => {
const provider = AnalyticsProviders.find(p => p === AnalyticsService);
expect(provider).toBeDefined();
});
});
describe('RecordPageViewPresenter', () => {
it('should be defined as a provider', () => {
const provider = AnalyticsProviders.find(p => p === RecordPageViewPresenter);
expect(provider).toBeDefined();
});
});
describe('RecordEngagementPresenter', () => {
it('should be defined as a provider', () => {
const provider = AnalyticsProviders.find(p => p === RecordEngagementPresenter);
expect(provider).toBeDefined();
});
});
describe('GetDashboardDataPresenter', () => {
it('should be defined as a provider', () => {
const provider = AnalyticsProviders.find(p => p === GetDashboardDataPresenter);
expect(provider).toBeDefined();
});
});
describe('GetAnalyticsMetricsPresenter', () => {
it('should be defined as a provider', () => {
const provider = AnalyticsProviders.find(p => p === GetAnalyticsMetricsPresenter);
expect(provider).toBeDefined();
});
});
describe('RecordPageViewUseCase', () => {
it('should be defined as a provider with useFactory', () => {
const provider = AnalyticsProviders.find(
p => typeof p === 'object' && 'provide' in p && p.provide === RecordPageViewUseCase,
);
expect(provider).toBeDefined();
expect(provider).toHaveProperty('useFactory');
expect(provider).toHaveProperty('inject');
});
it('should inject correct dependencies', () => {
const provider = AnalyticsProviders.find(
p => typeof p === 'object' && 'provide' in p && p.provide === RecordPageViewUseCase,
) as { inject: string[] };
expect(provider.inject).toEqual([ANALYTICS_PAGE_VIEW_REPOSITORY_TOKEN, 'Logger']);
});
});
describe('RecordEngagementUseCase', () => {
it('should be defined as a provider with useFactory', () => {
const provider = AnalyticsProviders.find(
p => typeof p === 'object' && 'provide' in p && p.provide === RecordEngagementUseCase,
);
expect(provider).toBeDefined();
expect(provider).toHaveProperty('useFactory');
expect(provider).toHaveProperty('inject');
});
it('should inject correct dependencies', () => {
const provider = AnalyticsProviders.find(
p => typeof p === 'object' && 'provide' in p && p.provide === RecordEngagementUseCase,
) as { inject: string[] };
expect(provider.inject).toEqual([ANALYTICS_ENGAGEMENT_REPOSITORY_TOKEN, 'Logger']);
});
});
describe('GetDashboardDataUseCase', () => {
it('should be defined as a provider with useFactory', () => {
const provider = AnalyticsProviders.find(
p => typeof p === 'object' && 'provide' in p && p.provide === GetDashboardDataUseCase,
);
expect(provider).toBeDefined();
expect(provider).toHaveProperty('useFactory');
expect(provider).toHaveProperty('inject');
});
it('should inject correct dependencies', () => {
const provider = AnalyticsProviders.find(
p => typeof p === 'object' && 'provide' in p && p.provide === GetDashboardDataUseCase,
) as { inject: string[] };
expect(provider.inject).toEqual(['Logger']);
});
});
describe('GetAnalyticsMetricsUseCase', () => {
it('should be defined as a provider with useFactory', () => {
const provider = AnalyticsProviders.find(
p => typeof p === 'object' && 'provide' in p && p.provide === GetAnalyticsMetricsUseCase,
);
expect(provider).toBeDefined();
expect(provider).toHaveProperty('useFactory');
expect(provider).toHaveProperty('inject');
});
it('should inject correct dependencies', () => {
const provider = AnalyticsProviders.find(
p => typeof p === 'object' && 'provide' in p && p.provide === GetAnalyticsMetricsUseCase,
) as { inject: string[] };
expect(provider.inject).toEqual(['Logger', ANALYTICS_PAGE_VIEW_REPOSITORY_TOKEN]);
});
});
describe('useFactory functions', () => {
it('should create RecordPageViewUseCase with correct dependencies', async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
...AnalyticsProviders,
{
provide: ANALYTICS_PAGE_VIEW_REPOSITORY_TOKEN,
useValue: {
save: vi.fn(),
findById: vi.fn(),
},
},
{
provide: 'Logger',
useValue: {
info: vi.fn(),
error: vi.fn(),
warn: vi.fn(),
debug: vi.fn(),
},
},
],
}).compile();
const useCase = module.get<RecordPageViewUseCase>(RecordPageViewUseCase);
expect(useCase).toBeDefined();
expect(useCase).toBeInstanceOf(RecordPageViewUseCase);
});
it('should create RecordEngagementUseCase with correct dependencies', async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
...AnalyticsProviders,
{
provide: ANALYTICS_ENGAGEMENT_REPOSITORY_TOKEN,
useValue: {
save: vi.fn(),
findById: vi.fn(),
},
},
{
provide: 'Logger',
useValue: {
info: vi.fn(),
error: vi.fn(),
warn: vi.fn(),
debug: vi.fn(),
},
},
],
}).compile();
const useCase = module.get<RecordEngagementUseCase>(RecordEngagementUseCase);
expect(useCase).toBeDefined();
expect(useCase).toBeInstanceOf(RecordEngagementUseCase);
});
it('should create GetDashboardDataUseCase with correct dependencies', async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
...AnalyticsProviders,
{
provide: 'Logger',
useValue: {
info: vi.fn(),
error: vi.fn(),
warn: vi.fn(),
debug: vi.fn(),
},
},
],
}).compile();
const useCase = module.get<GetDashboardDataUseCase>(GetDashboardDataUseCase);
expect(useCase).toBeDefined();
expect(useCase).toBeInstanceOf(GetDashboardDataUseCase);
});
it('should create GetAnalyticsMetricsUseCase with correct dependencies', async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
...AnalyticsProviders,
{
provide: ANALYTICS_PAGE_VIEW_REPOSITORY_TOKEN,
useValue: {
save: vi.fn(),
findById: vi.fn(),
findAll: vi.fn(),
},
},
{
provide: 'Logger',
useValue: {
info: vi.fn(),
error: vi.fn(),
warn: vi.fn(),
debug: vi.fn(),
},
},
],
}).compile();
const useCase = module.get<GetAnalyticsMetricsUseCase>(GetAnalyticsMetricsUseCase);
expect(useCase).toBeDefined();
expect(useCase).toBeInstanceOf(GetAnalyticsMetricsUseCase);
});
});
});

View File

@@ -6,7 +6,7 @@ import { Provider } from '@nestjs/common';
import {
ANALYTICS_ENGAGEMENT_REPOSITORY_TOKEN,
ANALYTICS_PAGE_VIEW_REPOSITORY_TOKEN,
} from '../../persistence/analytics/AnalyticsPersistenceTokens';
} from '../../../../persistence/analytics/AnalyticsPersistenceTokens';
const LOGGER_TOKEN = 'Logger';

View File

@@ -0,0 +1,312 @@
import { GetAnalyticsMetricsOutputDTO } from './GetAnalyticsMetricsOutputDTO';
describe('GetAnalyticsMetricsOutputDTO', () => {
describe('TDD - Test First', () => {
it('should create valid DTO with all fields', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 1000;
dto.uniqueVisitors = 500;
dto.averageSessionDuration = 300;
dto.bounceRate = 0.4;
// Assert
expect(dto.pageViews).toBe(1000);
expect(dto.uniqueVisitors).toBe(500);
expect(dto.averageSessionDuration).toBe(300);
expect(dto.bounceRate).toBe(0.4);
});
it('should handle zero values', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 0;
dto.uniqueVisitors = 0;
dto.averageSessionDuration = 0;
dto.bounceRate = 0;
// Assert
expect(dto.pageViews).toBe(0);
expect(dto.uniqueVisitors).toBe(0);
expect(dto.averageSessionDuration).toBe(0);
expect(dto.bounceRate).toBe(0);
});
it('should handle large numbers', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 1000000;
dto.uniqueVisitors = 500000;
dto.averageSessionDuration = 3600;
dto.bounceRate = 0.95;
// Assert
expect(dto.pageViews).toBe(1000000);
expect(dto.uniqueVisitors).toBe(500000);
expect(dto.averageSessionDuration).toBe(3600);
expect(dto.bounceRate).toBe(0.95);
});
it('should handle single digit values', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 1;
dto.uniqueVisitors = 1;
dto.averageSessionDuration = 1;
dto.bounceRate = 0.1;
// Assert
expect(dto.pageViews).toBe(1);
expect(dto.uniqueVisitors).toBe(1);
expect(dto.averageSessionDuration).toBe(1);
expect(dto.bounceRate).toBe(0.1);
});
it('should handle unique visitors greater than page views', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 100;
dto.uniqueVisitors = 150;
dto.averageSessionDuration = 300;
dto.bounceRate = 0.4;
// Assert
expect(dto.pageViews).toBe(100);
expect(dto.uniqueVisitors).toBe(150);
});
it('should handle zero unique visitors', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 100;
dto.uniqueVisitors = 0;
dto.averageSessionDuration = 300;
dto.bounceRate = 0.4;
// Assert
expect(dto.uniqueVisitors).toBe(0);
});
it('should handle zero page views', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 0;
dto.uniqueVisitors = 0;
dto.averageSessionDuration = 300;
dto.bounceRate = 0.4;
// Assert
expect(dto.pageViews).toBe(0);
});
it('should handle zero average session duration', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 100;
dto.uniqueVisitors = 50;
dto.averageSessionDuration = 0;
dto.bounceRate = 0.4;
// Assert
expect(dto.averageSessionDuration).toBe(0);
});
it('should handle zero bounce rate', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 100;
dto.uniqueVisitors = 50;
dto.averageSessionDuration = 300;
dto.bounceRate = 0;
// Assert
expect(dto.bounceRate).toBe(0);
});
it('should handle bounce rate of 1.0', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 100;
dto.uniqueVisitors = 50;
dto.averageSessionDuration = 300;
dto.bounceRate = 1.0;
// Assert
expect(dto.bounceRate).toBe(1.0);
});
it('should handle very large numbers', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 999999999;
dto.uniqueVisitors = 888888888;
dto.averageSessionDuration = 777777777;
dto.bounceRate = 0.999999;
// Assert
expect(dto.pageViews).toBe(999999999);
expect(dto.uniqueVisitors).toBe(888888888);
expect(dto.averageSessionDuration).toBe(777777777);
expect(dto.bounceRate).toBe(0.999999);
});
it('should handle decimal numbers', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 100.5;
dto.uniqueVisitors = 50.7;
dto.averageSessionDuration = 300.3;
dto.bounceRate = 0.45;
// Assert
expect(dto.pageViews).toBe(100.5);
expect(dto.uniqueVisitors).toBe(50.7);
expect(dto.averageSessionDuration).toBe(300.3);
expect(dto.bounceRate).toBe(0.45);
});
it('should handle negative numbers', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = -100;
dto.uniqueVisitors = -50;
dto.averageSessionDuration = -300;
dto.bounceRate = -0.4;
// Assert
expect(dto.pageViews).toBe(-100);
expect(dto.uniqueVisitors).toBe(-50);
expect(dto.averageSessionDuration).toBe(-300);
expect(dto.bounceRate).toBe(-0.4);
});
it('should handle scientific notation', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 1e6;
dto.uniqueVisitors = 5e5;
dto.averageSessionDuration = 3e2;
dto.bounceRate = 4e-1;
// Assert
expect(dto.pageViews).toBe(1000000);
expect(dto.uniqueVisitors).toBe(500000);
expect(dto.averageSessionDuration).toBe(300);
expect(dto.bounceRate).toBe(0.4);
});
it('should handle maximum safe integer', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = Number.MAX_SAFE_INTEGER;
dto.uniqueVisitors = Number.MAX_SAFE_INTEGER;
dto.averageSessionDuration = Number.MAX_SAFE_INTEGER;
dto.bounceRate = 0.99;
// Assert
expect(dto.pageViews).toBe(Number.MAX_SAFE_INTEGER);
expect(dto.uniqueVisitors).toBe(Number.MAX_SAFE_INTEGER);
expect(dto.averageSessionDuration).toBe(Number.MAX_SAFE_INTEGER);
expect(dto.bounceRate).toBe(0.99);
});
it('should handle minimum safe integer', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = Number.MIN_SAFE_INTEGER;
dto.uniqueVisitors = Number.MIN_SAFE_INTEGER;
dto.averageSessionDuration = Number.MIN_SAFE_INTEGER;
dto.bounceRate = -0.99;
// Assert
expect(dto.pageViews).toBe(Number.MIN_SAFE_INTEGER);
expect(dto.uniqueVisitors).toBe(Number.MIN_SAFE_INTEGER);
expect(dto.averageSessionDuration).toBe(Number.MIN_SAFE_INTEGER);
expect(dto.bounceRate).toBe(-0.99);
});
it('should handle Infinity for page views', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = Infinity;
dto.uniqueVisitors = 500;
dto.averageSessionDuration = 300;
dto.bounceRate = 0.4;
// Assert
expect(dto.pageViews).toBe(Infinity);
});
it('should handle Infinity for unique visitors', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 1000;
dto.uniqueVisitors = Infinity;
dto.averageSessionDuration = 300;
dto.bounceRate = 0.4;
// Assert
expect(dto.uniqueVisitors).toBe(Infinity);
});
it('should handle Infinity for average session duration', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 1000;
dto.uniqueVisitors = 500;
dto.averageSessionDuration = Infinity;
dto.bounceRate = 0.4;
// Assert
expect(dto.averageSessionDuration).toBe(Infinity);
});
it('should handle NaN for page views', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = NaN;
dto.uniqueVisitors = 500;
dto.averageSessionDuration = 300;
dto.bounceRate = 0.4;
// Assert
expect(dto.pageViews).toBeNaN();
});
it('should handle NaN for unique visitors', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 1000;
dto.uniqueVisitors = NaN;
dto.averageSessionDuration = 300;
dto.bounceRate = 0.4;
// Assert
expect(dto.uniqueVisitors).toBeNaN();
});
it('should handle NaN for average session duration', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 1000;
dto.uniqueVisitors = 500;
dto.averageSessionDuration = NaN;
dto.bounceRate = 0.4;
// Assert
expect(dto.averageSessionDuration).toBeNaN();
});
it('should handle NaN for bounce rate', () => {
// Arrange & Act
const dto = new GetAnalyticsMetricsOutputDTO();
dto.pageViews = 1000;
dto.uniqueVisitors = 500;
dto.averageSessionDuration = 300;
dto.bounceRate = NaN;
// Assert
expect(dto.bounceRate).toBeNaN();
});
});
});

View File

@@ -0,0 +1,246 @@
import { GetDashboardDataOutputDTO } from './GetDashboardDataOutputDTO';
describe('GetDashboardDataOutputDTO', () => {
describe('TDD - Test First', () => {
it('should create valid DTO with all fields', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 100;
dto.activeUsers = 50;
dto.totalRaces = 20;
dto.totalLeagues = 5;
// Assert
expect(dto.totalUsers).toBe(100);
expect(dto.activeUsers).toBe(50);
expect(dto.totalRaces).toBe(20);
expect(dto.totalLeagues).toBe(5);
});
it('should handle zero values', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 0;
dto.activeUsers = 0;
dto.totalRaces = 0;
dto.totalLeagues = 0;
// Assert
expect(dto.totalUsers).toBe(0);
expect(dto.activeUsers).toBe(0);
expect(dto.totalRaces).toBe(0);
expect(dto.totalLeagues).toBe(0);
});
it('should handle large numbers', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 1000000;
dto.activeUsers = 500000;
dto.totalRaces = 100000;
dto.totalLeagues = 10000;
// Assert
expect(dto.totalUsers).toBe(1000000);
expect(dto.activeUsers).toBe(500000);
expect(dto.totalRaces).toBe(100000);
expect(dto.totalLeagues).toBe(10000);
});
it('should handle single digit values', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 1;
dto.activeUsers = 1;
dto.totalRaces = 1;
dto.totalLeagues = 1;
// Assert
expect(dto.totalUsers).toBe(1);
expect(dto.activeUsers).toBe(1);
expect(dto.totalRaces).toBe(1);
expect(dto.totalLeagues).toBe(1);
});
it('should handle active users greater than total users', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 100;
dto.activeUsers = 150;
dto.totalRaces = 20;
dto.totalLeagues = 5;
// Assert
expect(dto.totalUsers).toBe(100);
expect(dto.activeUsers).toBe(150);
});
it('should handle zero active users', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 100;
dto.activeUsers = 0;
dto.totalRaces = 20;
dto.totalLeagues = 5;
// Assert
expect(dto.activeUsers).toBe(0);
});
it('should handle zero total users', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 0;
dto.activeUsers = 0;
dto.totalRaces = 20;
dto.totalLeagues = 5;
// Assert
expect(dto.totalUsers).toBe(0);
});
it('should handle zero races', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 100;
dto.activeUsers = 50;
dto.totalRaces = 0;
dto.totalLeagues = 5;
// Assert
expect(dto.totalRaces).toBe(0);
});
it('should handle zero leagues', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 100;
dto.activeUsers = 50;
dto.totalRaces = 20;
dto.totalLeagues = 0;
// Assert
expect(dto.totalLeagues).toBe(0);
});
it('should handle very large numbers', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 999999999;
dto.activeUsers = 888888888;
dto.totalRaces = 777777777;
dto.totalLeagues = 666666666;
// Assert
expect(dto.totalUsers).toBe(999999999);
expect(dto.activeUsers).toBe(888888888);
expect(dto.totalRaces).toBe(777777777);
expect(dto.totalLeagues).toBe(666666666);
});
it('should handle decimal numbers', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 100.5;
dto.activeUsers = 50.7;
dto.totalRaces = 20.3;
dto.totalLeagues = 5.9;
// Assert
expect(dto.totalUsers).toBe(100.5);
expect(dto.activeUsers).toBe(50.7);
expect(dto.totalRaces).toBe(20.3);
expect(dto.totalLeagues).toBe(5.9);
});
it('should handle negative numbers', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = -100;
dto.activeUsers = -50;
dto.totalRaces = -20;
dto.totalLeagues = -5;
// Assert
expect(dto.totalUsers).toBe(-100);
expect(dto.activeUsers).toBe(-50);
expect(dto.totalRaces).toBe(-20);
expect(dto.totalLeagues).toBe(-5);
});
it('should handle scientific notation', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = 1e6;
dto.activeUsers = 5e5;
dto.totalRaces = 2e4;
dto.totalLeagues = 5e3;
// Assert
expect(dto.totalUsers).toBe(1000000);
expect(dto.activeUsers).toBe(500000);
expect(dto.totalRaces).toBe(20000);
expect(dto.totalLeagues).toBe(5000);
});
it('should handle maximum safe integer', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = Number.MAX_SAFE_INTEGER;
dto.activeUsers = Number.MAX_SAFE_INTEGER;
dto.totalRaces = Number.MAX_SAFE_INTEGER;
dto.totalLeagues = Number.MAX_SAFE_INTEGER;
// Assert
expect(dto.totalUsers).toBe(Number.MAX_SAFE_INTEGER);
expect(dto.activeUsers).toBe(Number.MAX_SAFE_INTEGER);
expect(dto.totalRaces).toBe(Number.MAX_SAFE_INTEGER);
expect(dto.totalLeagues).toBe(Number.MAX_SAFE_INTEGER);
});
it('should handle minimum safe integer', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = Number.MIN_SAFE_INTEGER;
dto.activeUsers = Number.MIN_SAFE_INTEGER;
dto.totalRaces = Number.MIN_SAFE_INTEGER;
dto.totalLeagues = Number.MIN_SAFE_INTEGER;
// Assert
expect(dto.totalUsers).toBe(Number.MIN_SAFE_INTEGER);
expect(dto.activeUsers).toBe(Number.MIN_SAFE_INTEGER);
expect(dto.totalRaces).toBe(Number.MIN_SAFE_INTEGER);
expect(dto.totalLeagues).toBe(Number.MIN_SAFE_INTEGER);
});
it('should handle Infinity', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = Infinity;
dto.activeUsers = Infinity;
dto.totalRaces = Infinity;
dto.totalLeagues = Infinity;
// Assert
expect(dto.totalUsers).toBe(Infinity);
expect(dto.activeUsers).toBe(Infinity);
expect(dto.totalRaces).toBe(Infinity);
expect(dto.totalLeagues).toBe(Infinity);
});
it('should handle NaN', () => {
// Arrange & Act
const dto = new GetDashboardDataOutputDTO();
dto.totalUsers = NaN;
dto.activeUsers = NaN;
dto.totalRaces = NaN;
dto.totalLeagues = NaN;
// Assert
expect(dto.totalUsers).toBeNaN();
expect(dto.activeUsers).toBeNaN();
expect(dto.totalRaces).toBeNaN();
expect(dto.totalLeagues).toBeNaN();
});
});
});

View File

@@ -0,0 +1,340 @@
import { RecordEngagementInputDTO } from './RecordEngagementInputDTO';
import { EngagementAction, EngagementEntityType } from '@core/analytics/domain/types/EngagementEvent';
describe('RecordEngagementInputDTO', () => {
describe('TDD - Test First', () => {
it('should create valid DTO with all fields', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorId = 'actor-456';
dto.actorType = 'driver';
dto.sessionId = 'session-789';
dto.metadata = { key: 'value', count: 5 };
// Assert
expect(dto.action).toBe(EngagementAction.CLICK_SPONSOR_LOGO);
expect(dto.entityType).toBe(EngagementEntityType.RACE);
expect(dto.entityId).toBe('race-123');
expect(dto.actorId).toBe('actor-456');
expect(dto.actorType).toBe('driver');
expect(dto.sessionId).toBe('session-789');
expect(dto.metadata).toEqual({ key: 'value', count: 5 });
});
it('should create DTO with required fields only', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.action).toBe(EngagementAction.CLICK_SPONSOR_LOGO);
expect(dto.entityType).toBe(EngagementEntityType.RACE);
expect(dto.entityId).toBe('race-123');
expect(dto.actorType).toBe('anonymous');
expect(dto.sessionId).toBe('session-456');
expect(dto.actorId).toBeUndefined();
expect(dto.metadata).toBeUndefined();
});
it('should handle CLICK_SPONSOR_LOGO action', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.action).toBe(EngagementAction.CLICK_SPONSOR_LOGO);
});
it('should handle CLICK_SPONSOR_URL action', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_URL;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.action).toBe(EngagementAction.CLICK_SPONSOR_URL);
});
it('should handle RACE entity type', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.entityType).toBe(EngagementEntityType.RACE);
});
it('should handle LEAGUE entity type', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.LEAGUE;
dto.entityId = 'league-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.entityType).toBe(EngagementEntityType.LEAGUE);
});
it('should handle DRIVER entity type', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.DRIVER;
dto.entityId = 'driver-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.entityType).toBe(EngagementEntityType.DRIVER);
});
it('should handle TEAM entity type', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.TEAM;
dto.entityId = 'team-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.entityType).toBe(EngagementEntityType.TEAM);
});
it('should handle anonymous actor type', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.actorType).toBe('anonymous');
});
it('should handle driver actor type', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'driver';
dto.sessionId = 'session-456';
// Assert
expect(dto.actorType).toBe('driver');
});
it('should handle sponsor actor type', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'sponsor';
dto.sessionId = 'session-456';
// Assert
expect(dto.actorType).toBe('sponsor');
});
it('should handle empty metadata', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
dto.metadata = {};
// Assert
expect(dto.metadata).toEqual({});
});
it('should handle metadata with multiple keys', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
dto.metadata = {
key1: 'value1',
key2: 'value2',
key3: 'value3',
};
// Assert
expect(dto.metadata).toEqual({
key1: 'value1',
key2: 'value2',
key3: 'value3',
});
});
it('should handle metadata with numeric values', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
dto.metadata = { count: 10, score: 95.5 };
// Assert
expect(dto.metadata).toEqual({ count: 10, score: 95.5 });
});
it('should handle metadata with boolean values', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
dto.metadata = { isFeatured: true, isPremium: false };
// Assert
expect(dto.metadata).toEqual({ isFeatured: true, isPremium: false });
});
it('should handle very long entity ID', () => {
// Arrange
const longId = 'a'.repeat(100);
// Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = longId;
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.entityId).toBe(longId);
});
it('should handle very long session ID', () => {
// Arrange
const longSessionId = 's'.repeat(100);
// Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = longSessionId;
// Assert
expect(dto.sessionId).toBe(longSessionId);
});
it('should handle very long actor ID', () => {
// Arrange
const longActorId = 'a'.repeat(100);
// Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'driver';
dto.sessionId = 'session-456';
dto.actorId = longActorId;
// Assert
expect(dto.actorId).toBe(longActorId);
});
it('should handle special characters in entity ID', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123-test-456';
dto.actorType = 'anonymous';
dto.sessionId = 'session-789';
// Assert
expect(dto.entityId).toBe('race-123-test-456');
});
it('should handle UUID format for entity ID', () => {
// Arrange
const uuid = '550e8400-e29b-41d4-a716-446655440000';
// Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = uuid;
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.entityId).toBe(uuid);
});
it('should handle numeric entity ID', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = '123456';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
// Assert
expect(dto.entityId).toBe('123456');
});
it('should handle complex metadata with string values', () => {
// Arrange & Act
const dto = new RecordEngagementInputDTO();
dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
dto.entityType = EngagementEntityType.RACE;
dto.entityId = 'race-123';
dto.actorType = 'anonymous';
dto.sessionId = 'session-456';
dto.metadata = {
position: '100,200',
timestamp: '2024-01-01T00:00:00Z',
isValid: 'true',
};
// Assert
expect(dto.metadata).toEqual({
position: '100,200',
timestamp: '2024-01-01T00:00:00Z',
isValid: 'true',
});
});
});
});

View File

@@ -0,0 +1,222 @@
import { RecordEngagementOutputDTO } from './RecordEngagementOutputDTO';
describe('RecordEngagementOutputDTO', () => {
describe('TDD - Test First', () => {
it('should create valid DTO with all fields', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = 10;
// Assert
expect(dto.eventId).toBe('event-123');
expect(dto.engagementWeight).toBe(10);
});
it('should handle zero engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = 0;
// Assert
expect(dto.engagementWeight).toBe(0);
});
it('should handle single digit engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = 1;
// Assert
expect(dto.engagementWeight).toBe(1);
});
it('should handle large engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = 1000;
// Assert
expect(dto.engagementWeight).toBe(1000);
});
it('should handle very large engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = 999999;
// Assert
expect(dto.engagementWeight).toBe(999999);
});
it('should handle negative engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = -10;
// Assert
expect(dto.engagementWeight).toBe(-10);
});
it('should handle decimal engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = 10.5;
// Assert
expect(dto.engagementWeight).toBe(10.5);
});
it('should handle very small decimal engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = 0.001;
// Assert
expect(dto.engagementWeight).toBe(0.001);
});
it('should handle scientific notation for engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = 1e3;
// Assert
expect(dto.engagementWeight).toBe(1000);
});
it('should handle UUID format for event ID', () => {
// Arrange
const uuid = '550e8400-e29b-41d4-a716-446655440000';
// Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = uuid;
dto.engagementWeight = 10;
// Assert
expect(dto.eventId).toBe(uuid);
});
it('should handle numeric event ID', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = '123456';
dto.engagementWeight = 10;
// Assert
expect(dto.eventId).toBe('123456');
});
it('should handle special characters in event ID', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123-test-456';
dto.engagementWeight = 10;
// Assert
expect(dto.eventId).toBe('event-123-test-456');
});
it('should handle very long event ID', () => {
// Arrange
const longId = 'e'.repeat(100);
// Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = longId;
dto.engagementWeight = 10;
// Assert
expect(dto.eventId).toBe(longId);
});
it('should handle maximum safe integer for engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = Number.MAX_SAFE_INTEGER;
// Assert
expect(dto.engagementWeight).toBe(Number.MAX_SAFE_INTEGER);
});
it('should handle minimum safe integer for engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = Number.MIN_SAFE_INTEGER;
// Assert
expect(dto.engagementWeight).toBe(Number.MIN_SAFE_INTEGER);
});
it('should handle Infinity for engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = Infinity;
// Assert
expect(dto.engagementWeight).toBe(Infinity);
});
it('should handle NaN for engagement weight', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123';
dto.engagementWeight = NaN;
// Assert
expect(dto.engagementWeight).toBeNaN();
});
it('should handle very small event ID', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'e';
dto.engagementWeight = 10;
// Assert
expect(dto.eventId).toBe('e');
});
it('should handle event ID with spaces', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event 123 test';
dto.engagementWeight = 10;
// Assert
expect(dto.eventId).toBe('event 123 test');
});
it('should handle event ID with special characters', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event@123#test$456';
dto.engagementWeight = 10;
// Assert
expect(dto.eventId).toBe('event@123#test$456');
});
it('should handle event ID with unicode characters', () => {
// Arrange & Act
const dto = new RecordEngagementOutputDTO();
dto.eventId = 'event-123-测试-456';
dto.engagementWeight = 10;
// Assert
expect(dto.eventId).toBe('event-123-测试-456');
});
});
});

View File

@@ -0,0 +1,299 @@
import { RecordPageViewInputDTO } from './RecordPageViewInputDTO';
import { EntityType, VisitorType } from '@core/analytics/domain/types/PageView';
describe('RecordPageViewInputDTO', () => {
describe('TDD - Test First', () => {
it('should create valid DTO with all fields', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorId = 'visitor-456';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-789';
dto.referrer = 'https://example.com';
dto.userAgent = 'Mozilla/5.0';
dto.country = 'US';
// Assert
expect(dto.entityType).toBe(EntityType.RACE);
expect(dto.entityId).toBe('race-123');
expect(dto.visitorId).toBe('visitor-456');
expect(dto.visitorType).toBe(VisitorType.ANONYMOUS);
expect(dto.sessionId).toBe('session-789');
expect(dto.referrer).toBe('https://example.com');
expect(dto.userAgent).toBe('Mozilla/5.0');
expect(dto.country).toBe('US');
});
it('should create DTO with required fields only', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.LEAGUE;
dto.entityId = 'league-123';
dto.visitorType = VisitorType.AUTHENTICATED;
dto.sessionId = 'session-456';
// Assert
expect(dto.entityType).toBe(EntityType.LEAGUE);
expect(dto.entityId).toBe('league-123');
expect(dto.visitorType).toBe(VisitorType.AUTHENTICATED);
expect(dto.sessionId).toBe('session-456');
expect(dto.visitorId).toBeUndefined();
expect(dto.referrer).toBeUndefined();
expect(dto.userAgent).toBeUndefined();
expect(dto.country).toBeUndefined();
});
it('should handle RACE entity type', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
// Assert
expect(dto.entityType).toBe(EntityType.RACE);
});
it('should handle LEAGUE entity type', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.LEAGUE;
dto.entityId = 'league-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
// Assert
expect(dto.entityType).toBe(EntityType.LEAGUE);
});
it('should handle DRIVER entity type', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.DRIVER;
dto.entityId = 'driver-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
// Assert
expect(dto.entityType).toBe(EntityType.DRIVER);
});
it('should handle TEAM entity type', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.TEAM;
dto.entityId = 'team-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
// Assert
expect(dto.entityType).toBe(EntityType.TEAM);
});
it('should handle ANONYMOUS visitor type', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
// Assert
expect(dto.visitorType).toBe(VisitorType.ANONYMOUS);
});
it('should handle AUTHENTICATED visitor type', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.AUTHENTICATED;
dto.sessionId = 'session-456';
// Assert
expect(dto.visitorType).toBe(VisitorType.AUTHENTICATED);
});
it('should handle empty referrer', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
dto.referrer = '';
// Assert
expect(dto.referrer).toBe('');
});
it('should handle empty userAgent', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
dto.userAgent = '';
// Assert
expect(dto.userAgent).toBe('');
});
it('should handle empty country', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
dto.country = '';
// Assert
expect(dto.country).toBe('');
});
it('should handle very long entity ID', () => {
// Arrange
const longId = 'a'.repeat(100);
// Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = longId;
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
// Assert
expect(dto.entityId).toBe(longId);
});
it('should handle very long session ID', () => {
// Arrange
const longSessionId = 's'.repeat(100);
// Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = longSessionId;
// Assert
expect(dto.sessionId).toBe(longSessionId);
});
it('should handle very long visitor ID', () => {
// Arrange
const longVisitorId = 'v'.repeat(100);
// Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.AUTHENTICATED;
dto.sessionId = 'session-456';
dto.visitorId = longVisitorId;
// Assert
expect(dto.visitorId).toBe(longVisitorId);
});
it('should handle special characters in entity ID', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123-test-456';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-789';
// Assert
expect(dto.entityId).toBe('race-123-test-456');
});
it('should handle UUID format for entity ID', () => {
// Arrange
const uuid = '550e8400-e29b-41d4-a716-446655440000';
// Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = uuid;
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
// Assert
expect(dto.entityId).toBe(uuid);
});
it('should handle numeric entity ID', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = '123456';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
// Assert
expect(dto.entityId).toBe('123456');
});
it('should handle URL in referrer', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
dto.referrer = 'https://www.example.com/path/to/page?query=value';
// Assert
expect(dto.referrer).toBe('https://www.example.com/path/to/page?query=value');
});
it('should handle complex user agent string', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
dto.userAgent =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36';
// Assert
expect(dto.userAgent).toBe(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
);
});
it('should handle country codes', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
dto.country = 'GB';
// Assert
expect(dto.country).toBe('GB');
});
it('should handle country with region', () => {
// Arrange & Act
const dto = new RecordPageViewInputDTO();
dto.entityType = EntityType.RACE;
dto.entityId = 'race-123';
dto.visitorType = VisitorType.ANONYMOUS;
dto.sessionId = 'session-456';
dto.country = 'US-CA';
// Assert
expect(dto.country).toBe('US-CA');
});
});
});

View File

@@ -0,0 +1,344 @@
import { RecordPageViewOutputDTO } from './RecordPageViewOutputDTO';
describe('RecordPageViewOutputDTO', () => {
describe('TDD - Test First', () => {
it('should create valid DTO with all fields', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv-123';
// Assert
expect(dto.pageViewId).toBe('pv-123');
});
it('should handle UUID format for page view ID', () => {
// Arrange
const uuid = '550e8400-e29b-41d4-a716-446655440000';
// Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = uuid;
// Assert
expect(dto.pageViewId).toBe(uuid);
});
it('should handle numeric page view ID', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = '123456';
// Assert
expect(dto.pageViewId).toBe('123456');
});
it('should handle special characters in page view ID', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv-123-test-456';
// Assert
expect(dto.pageViewId).toBe('pv-123-test-456');
});
it('should handle very long page view ID', () => {
// Arrange
const longId = 'p'.repeat(100);
// Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = longId;
// Assert
expect(dto.pageViewId).toBe(longId);
});
it('should handle very small page view ID', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'p';
// Assert
expect(dto.pageViewId).toBe('p');
});
it('should handle page view ID with spaces', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv 123 test';
// Assert
expect(dto.pageViewId).toBe('pv 123 test');
});
it('should handle page view ID with special characters', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv@123#test$456';
// Assert
expect(dto.pageViewId).toBe('pv@123#test$456');
});
it('should handle page view ID with unicode characters', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv-123-测试-456';
// Assert
expect(dto.pageViewId).toBe('pv-123-测试-456');
});
it('should handle page view ID with leading zeros', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = '000123';
// Assert
expect(dto.pageViewId).toBe('000123');
});
it('should handle page view ID with trailing zeros', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = '123000';
// Assert
expect(dto.pageViewId).toBe('123000');
});
it('should handle page view ID with mixed case', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'Pv-123-Test-456';
// Assert
expect(dto.pageViewId).toBe('Pv-123-Test-456');
});
it('should handle page view ID with underscores', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv_123_test_456';
// Assert
expect(dto.pageViewId).toBe('pv_123_test_456');
});
it('should handle page view ID with dots', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv.123.test.456';
// Assert
expect(dto.pageViewId).toBe('pv.123.test.456');
});
it('should handle page view ID with hyphens', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv-123-test-456';
// Assert
expect(dto.pageViewId).toBe('pv-123-test-456');
});
it('should handle page view ID with colons', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv:123:test:456';
// Assert
expect(dto.pageViewId).toBe('pv:123:test:456');
});
it('should handle page view ID with slashes', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv/123/test/456';
// Assert
expect(dto.pageViewId).toBe('pv/123/test/456');
});
it('should handle page view ID with backslashes', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv\\123\\test\\456';
// Assert
expect(dto.pageViewId).toBe('pv\\123\\test\\456');
});
it('should handle page view ID with pipes', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv|123|test|456';
// Assert
expect(dto.pageViewId).toBe('pv|123|test|456');
});
it('should handle page view ID with ampersands', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv&123&test&456';
// Assert
expect(dto.pageViewId).toBe('pv&123&test&456');
});
it('should handle page view ID with percent signs', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv%123%test%456';
// Assert
expect(dto.pageViewId).toBe('pv%123%test%456');
});
it('should handle page view ID with dollar signs', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv$123$test$456';
// Assert
expect(dto.pageViewId).toBe('pv$123$test$456');
});
it('should handle page view ID with exclamation marks', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv!123!test!456';
// Assert
expect(dto.pageViewId).toBe('pv!123!test!456');
});
it('should handle page view ID with question marks', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv?123?test?456';
// Assert
expect(dto.pageViewId).toBe('pv?123?test?456');
});
it('should handle page view ID with plus signs', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv+123+test+456';
// Assert
expect(dto.pageViewId).toBe('pv+123+test+456');
});
it('should handle page view ID with equals signs', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv=123=test=456';
// Assert
expect(dto.pageViewId).toBe('pv=123=test=456');
});
it('should handle page view ID with asterisks', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv*123*test*456';
// Assert
expect(dto.pageViewId).toBe('pv*123*test*456');
});
it('should handle page view ID with parentheses', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv(123)test(456)';
// Assert
expect(dto.pageViewId).toBe('pv(123)test(456)');
});
it('should handle page view ID with brackets', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv[123]test[456]';
// Assert
expect(dto.pageViewId).toBe('pv[123]test[456]');
});
it('should handle page view ID with curly braces', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv{123}test{456}';
// Assert
expect(dto.pageViewId).toBe('pv{123}test{456}');
});
it('should handle page view ID with angle brackets', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv<123>test<456>';
// Assert
expect(dto.pageViewId).toBe('pv<123>test<456>');
});
it('should handle page view ID with quotes', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv"123"test"456"';
// Assert
expect(dto.pageViewId).toBe('pv"123"test"456"');
});
it('should handle page view ID with single quotes', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = "pv'123'test'456'";
// Assert
expect(dto.pageViewId).toBe("pv'123'test'456'");
});
it('should handle page view ID with backticks', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv`123`test`456`';
// Assert
expect(dto.pageViewId).toBe('pv`123`test`456`');
});
it('should handle page view ID with tildes', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv~123~test~456';
// Assert
expect(dto.pageViewId).toBe('pv~123~test~456');
});
it('should handle page view ID with at signs', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv@123@test@456';
// Assert
expect(dto.pageViewId).toBe('pv@123@test@456');
});
it('should handle page view ID with hash signs', () => {
// Arrange & Act
const dto = new RecordPageViewOutputDTO();
dto.pageViewId = 'pv#123#test#456';
// Assert
expect(dto.pageViewId).toBe('pv#123#test#456');
});
});
});