adapter tests
Some checks failed
CI / lint-typecheck (pull_request) Failing after 4m51s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
Some checks failed
CI / lint-typecheck (pull_request) Failing after 4m51s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { TypeOrmAnalyticsSchemaError } from './TypeOrmAnalyticsSchemaError';
|
||||
|
||||
describe('TypeOrmAnalyticsSchemaError', () => {
|
||||
it('contains entity, field, and reason', () => {
|
||||
// Given
|
||||
const params = {
|
||||
entityName: 'AnalyticsSnapshot',
|
||||
fieldName: 'metrics.pageViews',
|
||||
reason: 'not_number' as const,
|
||||
message: 'Custom message',
|
||||
};
|
||||
|
||||
// When
|
||||
const error = new TypeOrmAnalyticsSchemaError(params);
|
||||
|
||||
// Then
|
||||
expect(error.name).toBe('TypeOrmAnalyticsSchemaError');
|
||||
expect(error.entityName).toBe(params.entityName);
|
||||
expect(error.fieldName).toBe(params.fieldName);
|
||||
expect(error.reason).toBe(params.reason);
|
||||
expect(error.message).toBe(params.message);
|
||||
});
|
||||
|
||||
it('works without optional message', () => {
|
||||
// Given
|
||||
const params = {
|
||||
entityName: 'EngagementEvent',
|
||||
fieldName: 'id',
|
||||
reason: 'missing' as const,
|
||||
};
|
||||
|
||||
// When
|
||||
const error = new TypeOrmAnalyticsSchemaError(params);
|
||||
|
||||
// Then
|
||||
expect(error.message).toBe('');
|
||||
expect(error.entityName).toBe(params.entityName);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,90 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { AnalyticsSnapshot } from '@core/analytics/domain/entities/AnalyticsSnapshot';
|
||||
|
||||
import { AnalyticsSnapshotOrmEntity } from '../entities/AnalyticsSnapshotOrmEntity';
|
||||
import { TypeOrmAnalyticsSchemaError } from '../errors/TypeOrmAnalyticsSchemaError';
|
||||
import { AnalyticsSnapshotOrmMapper } from './AnalyticsSnapshotOrmMapper';
|
||||
|
||||
describe('AnalyticsSnapshotOrmMapper', () => {
|
||||
const mapper = new AnalyticsSnapshotOrmMapper();
|
||||
|
||||
it('maps domain -> orm -> domain (round-trip)', () => {
|
||||
// Given
|
||||
const domain = AnalyticsSnapshot.create({
|
||||
id: 'snap_1',
|
||||
entityType: 'league',
|
||||
entityId: 'league-1',
|
||||
period: 'daily',
|
||||
startDate: new Date('2025-01-01T00:00:00.000Z'),
|
||||
endDate: new Date('2025-01-01T23:59:59.999Z'),
|
||||
metrics: {
|
||||
pageViews: 100,
|
||||
uniqueVisitors: 50,
|
||||
avgSessionDuration: 120,
|
||||
bounceRate: 0.4,
|
||||
engagementScore: 75,
|
||||
sponsorClicks: 10,
|
||||
sponsorUrlClicks: 5,
|
||||
socialShares: 2,
|
||||
leagueJoins: 1,
|
||||
raceRegistrations: 3,
|
||||
exposureValue: 150.5,
|
||||
},
|
||||
createdAt: new Date('2025-01-02T00:00:00.000Z'),
|
||||
});
|
||||
|
||||
// When
|
||||
const orm = mapper.toOrmEntity(domain);
|
||||
const rehydrated = mapper.toDomain(orm);
|
||||
|
||||
// Then
|
||||
expect(orm).toBeInstanceOf(AnalyticsSnapshotOrmEntity);
|
||||
expect(orm.id).toBe(domain.id);
|
||||
expect(rehydrated.id).toBe(domain.id);
|
||||
expect(rehydrated.entityType).toBe(domain.entityType);
|
||||
expect(rehydrated.entityId).toBe(domain.entityId);
|
||||
expect(rehydrated.period).toBe(domain.period);
|
||||
expect(rehydrated.startDate.toISOString()).toBe(domain.startDate.toISOString());
|
||||
expect(rehydrated.endDate.toISOString()).toBe(domain.endDate.toISOString());
|
||||
expect(rehydrated.metrics).toEqual(domain.metrics);
|
||||
expect(rehydrated.createdAt.toISOString()).toBe(domain.createdAt.toISOString());
|
||||
});
|
||||
|
||||
it('throws TypeOrmAnalyticsSchemaError for invalid persisted shape', () => {
|
||||
// Given
|
||||
const orm = new AnalyticsSnapshotOrmEntity();
|
||||
orm.id = ''; // Invalid: empty
|
||||
orm.entityType = 'league' as any;
|
||||
orm.entityId = 'league-1';
|
||||
orm.period = 'daily' as any;
|
||||
orm.startDate = new Date();
|
||||
orm.endDate = new Date();
|
||||
orm.metrics = {} as any; // Invalid: missing fields
|
||||
orm.createdAt = new Date();
|
||||
|
||||
// When / Then
|
||||
expect(() => mapper.toDomain(orm)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
|
||||
it('throws TypeOrmAnalyticsSchemaError when metrics are missing required fields', () => {
|
||||
// Given
|
||||
const orm = new AnalyticsSnapshotOrmEntity();
|
||||
orm.id = 'snap_1';
|
||||
orm.entityType = 'league' as any;
|
||||
orm.entityId = 'league-1';
|
||||
orm.period = 'daily' as any;
|
||||
orm.startDate = new Date();
|
||||
orm.endDate = new Date();
|
||||
orm.metrics = { pageViews: 100 } as any; // Missing other metrics
|
||||
orm.createdAt = new Date();
|
||||
|
||||
// When / Then
|
||||
expect(() => mapper.toDomain(orm)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
try {
|
||||
mapper.toDomain(orm);
|
||||
} catch (e: any) {
|
||||
expect(e.fieldName).toContain('metrics.');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,103 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { EngagementEvent } from '@core/analytics/domain/entities/EngagementEvent';
|
||||
|
||||
import { EngagementEventOrmEntity } from '../entities/EngagementEventOrmEntity';
|
||||
import { TypeOrmAnalyticsSchemaError } from '../errors/TypeOrmAnalyticsSchemaError';
|
||||
import { EngagementEventOrmMapper } from './EngagementEventOrmMapper';
|
||||
|
||||
describe('EngagementEventOrmMapper', () => {
|
||||
const mapper = new EngagementEventOrmMapper();
|
||||
|
||||
it('maps domain -> orm -> domain (round-trip)', () => {
|
||||
// Given
|
||||
const domain = EngagementEvent.create({
|
||||
id: 'eng_1',
|
||||
action: 'click_sponsor_logo',
|
||||
entityType: 'sponsor',
|
||||
entityId: 'sponsor-1',
|
||||
actorType: 'driver',
|
||||
actorId: 'driver-1',
|
||||
sessionId: 'sess-1',
|
||||
metadata: { key: 'value', num: 123, bool: true },
|
||||
timestamp: new Date('2025-01-01T10:00:00.000Z'),
|
||||
});
|
||||
|
||||
// When
|
||||
const orm = mapper.toOrmEntity(domain);
|
||||
const rehydrated = mapper.toDomain(orm);
|
||||
|
||||
// Then
|
||||
expect(orm).toBeInstanceOf(EngagementEventOrmEntity);
|
||||
expect(orm.id).toBe(domain.id);
|
||||
expect(rehydrated.id).toBe(domain.id);
|
||||
expect(rehydrated.action).toBe(domain.action);
|
||||
expect(rehydrated.entityType).toBe(domain.entityType);
|
||||
expect(rehydrated.entityId).toBe(domain.entityId);
|
||||
expect(rehydrated.actorType).toBe(domain.actorType);
|
||||
expect(rehydrated.actorId).toBe(domain.actorId);
|
||||
expect(rehydrated.sessionId).toBe(domain.sessionId);
|
||||
expect(rehydrated.metadata).toEqual(domain.metadata);
|
||||
expect(rehydrated.timestamp.toISOString()).toBe(domain.timestamp.toISOString());
|
||||
});
|
||||
|
||||
it('maps domain -> orm -> domain with nulls', () => {
|
||||
// Given
|
||||
const domain = EngagementEvent.create({
|
||||
id: 'eng_2',
|
||||
action: 'view_standings',
|
||||
entityType: 'league',
|
||||
entityId: 'league-1',
|
||||
actorType: 'anonymous',
|
||||
sessionId: 'sess-2',
|
||||
timestamp: new Date('2025-01-01T11:00:00.000Z'),
|
||||
});
|
||||
|
||||
// When
|
||||
const orm = mapper.toOrmEntity(domain);
|
||||
const rehydrated = mapper.toDomain(orm);
|
||||
|
||||
// Then
|
||||
expect(orm.actorId).toBeNull();
|
||||
expect(orm.metadata).toBeNull();
|
||||
expect(rehydrated.actorId).toBeUndefined();
|
||||
expect(rehydrated.metadata).toBeUndefined();
|
||||
});
|
||||
|
||||
it('throws TypeOrmAnalyticsSchemaError for invalid persisted shape', () => {
|
||||
// Given
|
||||
const orm = new EngagementEventOrmEntity();
|
||||
orm.id = ''; // Invalid
|
||||
orm.action = 'invalid_action' as any;
|
||||
orm.entityType = 'league' as any;
|
||||
orm.entityId = 'league-1';
|
||||
orm.actorType = 'anonymous' as any;
|
||||
orm.sessionId = 'sess-1';
|
||||
orm.timestamp = new Date();
|
||||
|
||||
// When / Then
|
||||
expect(() => mapper.toDomain(orm)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
|
||||
it('throws TypeOrmAnalyticsSchemaError for invalid metadata values', () => {
|
||||
// Given
|
||||
const orm = new EngagementEventOrmEntity();
|
||||
orm.id = 'eng_1';
|
||||
orm.action = 'click_sponsor_logo' as any;
|
||||
orm.entityType = 'sponsor' as any;
|
||||
orm.entityId = 'sponsor-1';
|
||||
orm.actorType = 'driver' as any;
|
||||
orm.sessionId = 'sess-1';
|
||||
orm.timestamp = new Date();
|
||||
orm.metadata = { invalid: { nested: 'object' } } as any;
|
||||
|
||||
// When / Then
|
||||
expect(() => mapper.toDomain(orm)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
try {
|
||||
mapper.toDomain(orm);
|
||||
} catch (e: any) {
|
||||
expect(e.reason).toBe('invalid_shape');
|
||||
expect(e.fieldName).toBe('metadata');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,102 @@
|
||||
import type { Repository } from 'typeorm';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { AnalyticsSnapshot } from '@core/analytics/domain/entities/AnalyticsSnapshot';
|
||||
|
||||
import { AnalyticsSnapshotOrmEntity } from '../entities/AnalyticsSnapshotOrmEntity';
|
||||
import { AnalyticsSnapshotOrmMapper } from '../mappers/AnalyticsSnapshotOrmMapper';
|
||||
import { TypeOrmAnalyticsSnapshotRepository } from './TypeOrmAnalyticsSnapshotRepository';
|
||||
|
||||
describe('TypeOrmAnalyticsSnapshotRepository', () => {
|
||||
it('saves mapped entities via injected mapper', async () => {
|
||||
// Given
|
||||
const orm = new AnalyticsSnapshotOrmEntity();
|
||||
orm.id = 'snap_1';
|
||||
|
||||
const mapper: AnalyticsSnapshotOrmMapper = {
|
||||
toOrmEntity: vi.fn().mockReturnValue(orm),
|
||||
toDomain: vi.fn(),
|
||||
} as unknown as AnalyticsSnapshotOrmMapper;
|
||||
|
||||
const repo: Repository<AnalyticsSnapshotOrmEntity> = {
|
||||
save: vi.fn().mockResolvedValue(orm),
|
||||
} as unknown as Repository<AnalyticsSnapshotOrmEntity>;
|
||||
|
||||
const sut = new TypeOrmAnalyticsSnapshotRepository(repo, mapper);
|
||||
|
||||
const domain = AnalyticsSnapshot.create({
|
||||
id: 'snap_1',
|
||||
entityType: 'league',
|
||||
entityId: 'league-1',
|
||||
period: 'daily',
|
||||
startDate: new Date(),
|
||||
endDate: new Date(),
|
||||
metrics: {} as any,
|
||||
createdAt: new Date(),
|
||||
});
|
||||
|
||||
// When
|
||||
await sut.save(domain);
|
||||
|
||||
// Then
|
||||
expect(mapper.toOrmEntity).toHaveBeenCalledWith(domain);
|
||||
expect(repo.save).toHaveBeenCalledWith(orm);
|
||||
});
|
||||
|
||||
it('findById maps entity -> domain', async () => {
|
||||
// Given
|
||||
const orm = new AnalyticsSnapshotOrmEntity();
|
||||
orm.id = 'snap_1';
|
||||
|
||||
const domain = AnalyticsSnapshot.create({
|
||||
id: 'snap_1',
|
||||
entityType: 'league',
|
||||
entityId: 'league-1',
|
||||
period: 'daily',
|
||||
startDate: new Date(),
|
||||
endDate: new Date(),
|
||||
metrics: {} as any,
|
||||
createdAt: new Date(),
|
||||
});
|
||||
|
||||
const mapper: AnalyticsSnapshotOrmMapper = {
|
||||
toOrmEntity: vi.fn(),
|
||||
toDomain: vi.fn().mockReturnValue(domain),
|
||||
} as unknown as AnalyticsSnapshotOrmMapper;
|
||||
|
||||
const repo: Repository<AnalyticsSnapshotOrmEntity> = {
|
||||
findOneBy: vi.fn().mockResolvedValue(orm),
|
||||
} as unknown as Repository<AnalyticsSnapshotOrmEntity>;
|
||||
|
||||
const sut = new TypeOrmAnalyticsSnapshotRepository(repo, mapper);
|
||||
|
||||
// When
|
||||
const result = await sut.findById('snap_1');
|
||||
|
||||
// Then
|
||||
expect(repo.findOneBy).toHaveBeenCalledWith({ id: 'snap_1' });
|
||||
expect(mapper.toDomain).toHaveBeenCalledWith(orm);
|
||||
expect(result?.id).toBe('snap_1');
|
||||
});
|
||||
|
||||
it('findLatest uses correct query options', async () => {
|
||||
// Given
|
||||
const orm = new AnalyticsSnapshotOrmEntity();
|
||||
const mapper: AnalyticsSnapshotOrmMapper = {
|
||||
toDomain: vi.fn().mockReturnValue({ id: 'snap_1' } as any),
|
||||
} as any;
|
||||
const repo: Repository<AnalyticsSnapshotOrmEntity> = {
|
||||
findOne: vi.fn().mockResolvedValue(orm),
|
||||
} as any;
|
||||
const sut = new TypeOrmAnalyticsSnapshotRepository(repo, mapper);
|
||||
|
||||
// When
|
||||
await sut.findLatest('league', 'league-1', 'daily');
|
||||
|
||||
// Then
|
||||
expect(repo.findOne).toHaveBeenCalledWith({
|
||||
where: { entityType: 'league', entityId: 'league-1', period: 'daily' },
|
||||
order: { endDate: 'DESC' },
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,100 @@
|
||||
import type { Repository } from 'typeorm';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { EngagementEvent } from '@core/analytics/domain/entities/EngagementEvent';
|
||||
|
||||
import { EngagementEventOrmEntity } from '../entities/EngagementEventOrmEntity';
|
||||
import { EngagementEventOrmMapper } from '../mappers/EngagementEventOrmMapper';
|
||||
import { TypeOrmEngagementRepository } from './TypeOrmEngagementRepository';
|
||||
|
||||
describe('TypeOrmEngagementRepository', () => {
|
||||
it('saves mapped entities via injected mapper', async () => {
|
||||
// Given
|
||||
const orm = new EngagementEventOrmEntity();
|
||||
orm.id = 'eng_1';
|
||||
|
||||
const mapper: EngagementEventOrmMapper = {
|
||||
toOrmEntity: vi.fn().mockReturnValue(orm),
|
||||
toDomain: vi.fn(),
|
||||
} as unknown as EngagementEventOrmMapper;
|
||||
|
||||
const repo: Repository<EngagementEventOrmEntity> = {
|
||||
save: vi.fn().mockResolvedValue(orm),
|
||||
} as unknown as Repository<EngagementEventOrmEntity>;
|
||||
|
||||
const sut = new TypeOrmEngagementRepository(repo, mapper);
|
||||
|
||||
const domain = EngagementEvent.create({
|
||||
id: 'eng_1',
|
||||
action: 'click_sponsor_logo',
|
||||
entityType: 'sponsor',
|
||||
entityId: 'sponsor-1',
|
||||
actorType: 'anonymous',
|
||||
sessionId: 'sess-1',
|
||||
timestamp: new Date(),
|
||||
});
|
||||
|
||||
// When
|
||||
await sut.save(domain);
|
||||
|
||||
// Then
|
||||
expect(mapper.toOrmEntity).toHaveBeenCalledWith(domain);
|
||||
expect(repo.save).toHaveBeenCalledWith(orm);
|
||||
});
|
||||
|
||||
it('findById maps entity -> domain', async () => {
|
||||
// Given
|
||||
const orm = new EngagementEventOrmEntity();
|
||||
orm.id = 'eng_1';
|
||||
|
||||
const domain = EngagementEvent.create({
|
||||
id: 'eng_1',
|
||||
action: 'click_sponsor_logo',
|
||||
entityType: 'sponsor',
|
||||
entityId: 'sponsor-1',
|
||||
actorType: 'anonymous',
|
||||
sessionId: 'sess-1',
|
||||
timestamp: new Date(),
|
||||
});
|
||||
|
||||
const mapper: EngagementEventOrmMapper = {
|
||||
toOrmEntity: vi.fn(),
|
||||
toDomain: vi.fn().mockReturnValue(domain),
|
||||
} as unknown as EngagementEventOrmMapper;
|
||||
|
||||
const repo: Repository<EngagementEventOrmEntity> = {
|
||||
findOneBy: vi.fn().mockResolvedValue(orm),
|
||||
} as unknown as Repository<EngagementEventOrmEntity>;
|
||||
|
||||
const sut = new TypeOrmEngagementRepository(repo, mapper);
|
||||
|
||||
// When
|
||||
const result = await sut.findById('eng_1');
|
||||
|
||||
// Then
|
||||
expect(repo.findOneBy).toHaveBeenCalledWith({ id: 'eng_1' });
|
||||
expect(mapper.toDomain).toHaveBeenCalledWith(orm);
|
||||
expect(result?.id).toBe('eng_1');
|
||||
});
|
||||
|
||||
it('countByAction uses correct where clause', async () => {
|
||||
// Given
|
||||
const repo: Repository<EngagementEventOrmEntity> = {
|
||||
count: vi.fn().mockResolvedValue(5),
|
||||
} as any;
|
||||
const sut = new TypeOrmEngagementRepository(repo, {} as any);
|
||||
const since = new Date();
|
||||
|
||||
// When
|
||||
await sut.countByAction('click_sponsor_logo', 'sponsor-1', since);
|
||||
|
||||
// Then
|
||||
expect(repo.count).toHaveBeenCalledWith({
|
||||
where: expect.objectContaining({
|
||||
action: 'click_sponsor_logo',
|
||||
entityId: 'sponsor-1',
|
||||
timestamp: expect.anything(),
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,141 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { TypeOrmAnalyticsSchemaError } from '../errors/TypeOrmAnalyticsSchemaError';
|
||||
import {
|
||||
assertBoolean,
|
||||
assertDate,
|
||||
assertEnumValue,
|
||||
assertInteger,
|
||||
assertNonEmptyString,
|
||||
assertNumber,
|
||||
assertOptionalIntegerOrNull,
|
||||
assertOptionalNumberOrNull,
|
||||
assertOptionalStringOrNull,
|
||||
assertRecord,
|
||||
} from './TypeOrmAnalyticsSchemaGuards';
|
||||
|
||||
describe('TypeOrmAnalyticsSchemaGuards', () => {
|
||||
const entity = 'TestEntity';
|
||||
|
||||
describe('assertNonEmptyString', () => {
|
||||
it('accepts valid string', () => {
|
||||
expect(() => assertNonEmptyString(entity, 'field', 'valid')).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects null/undefined', () => {
|
||||
expect(() => assertNonEmptyString(entity, 'field', null)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
expect(() => assertNonEmptyString(entity, 'field', undefined)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
|
||||
it('rejects empty/whitespace string', () => {
|
||||
expect(() => assertNonEmptyString(entity, 'field', '')).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
expect(() => assertNonEmptyString(entity, 'field', ' ')).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
|
||||
it('rejects non-string', () => {
|
||||
expect(() => assertNonEmptyString(entity, 'field', 123)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('assertOptionalStringOrNull', () => {
|
||||
it('accepts valid string, null, or undefined', () => {
|
||||
expect(() => assertOptionalStringOrNull(entity, 'field', 'valid')).not.toThrow();
|
||||
expect(() => assertOptionalStringOrNull(entity, 'field', null)).not.toThrow();
|
||||
expect(() => assertOptionalStringOrNull(entity, 'field', undefined)).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects non-string', () => {
|
||||
expect(() => assertOptionalStringOrNull(entity, 'field', 123)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('assertNumber', () => {
|
||||
it('accepts valid number', () => {
|
||||
expect(() => assertNumber(entity, 'field', 123.45)).not.toThrow();
|
||||
expect(() => assertNumber(entity, 'field', 0)).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects NaN', () => {
|
||||
expect(() => assertNumber(entity, 'field', NaN)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
|
||||
it('rejects non-number', () => {
|
||||
expect(() => assertNumber(entity, 'field', '123')).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('assertOptionalNumberOrNull', () => {
|
||||
it('accepts valid number, null, or undefined', () => {
|
||||
expect(() => assertOptionalNumberOrNull(entity, 'field', 123)).not.toThrow();
|
||||
expect(() => assertOptionalNumberOrNull(entity, 'field', null)).not.toThrow();
|
||||
expect(() => assertOptionalNumberOrNull(entity, 'field', undefined)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('assertInteger', () => {
|
||||
it('accepts valid integer', () => {
|
||||
expect(() => assertInteger(entity, 'field', 123)).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects float', () => {
|
||||
expect(() => assertInteger(entity, 'field', 123.45)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('assertOptionalIntegerOrNull', () => {
|
||||
it('accepts valid integer, null, or undefined', () => {
|
||||
expect(() => assertOptionalIntegerOrNull(entity, 'field', 123)).not.toThrow();
|
||||
expect(() => assertOptionalIntegerOrNull(entity, 'field', null)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('assertBoolean', () => {
|
||||
it('accepts boolean', () => {
|
||||
expect(() => assertBoolean(entity, 'field', true)).not.toThrow();
|
||||
expect(() => assertBoolean(entity, 'field', false)).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects non-boolean', () => {
|
||||
expect(() => assertBoolean(entity, 'field', 'true')).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('assertDate', () => {
|
||||
it('accepts valid Date', () => {
|
||||
expect(() => assertDate(entity, 'field', new Date())).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects invalid Date', () => {
|
||||
expect(() => assertDate(entity, 'field', new Date('invalid'))).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
|
||||
it('rejects non-Date', () => {
|
||||
expect(() => assertDate(entity, 'field', '2025-01-01')).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('assertEnumValue', () => {
|
||||
const allowed = ['a', 'b'] as const;
|
||||
it('accepts allowed value', () => {
|
||||
expect(() => assertEnumValue(entity, 'field', 'a', allowed)).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects disallowed value', () => {
|
||||
expect(() => assertEnumValue(entity, 'field', 'c', allowed)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('assertRecord', () => {
|
||||
it('accepts object', () => {
|
||||
expect(() => assertRecord(entity, 'field', { a: 1 })).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects array', () => {
|
||||
expect(() => assertRecord(entity, 'field', [])).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
|
||||
it('rejects null', () => {
|
||||
expect(() => assertRecord(entity, 'field', null)).toThrow(TypeOrmAnalyticsSchemaError);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user