66 lines
2.6 KiB
TypeScript
66 lines
2.6 KiB
TypeScript
import 'reflect-metadata';
|
|
import { getMetadataArgsStorage } from 'typeorm';
|
|
import { Combat } from '../../combat/entities/combat.entity';
|
|
import { CombatEvent } from '../../combat/entities/combat-event.entity';
|
|
import { HuntEncounter } from '../../hunting/entities/hunt-encounter.entity';
|
|
|
|
describe('combat system schema', () => {
|
|
it('maps Combat and CombatEvent relations with the documented onDelete behavior', () => {
|
|
const metadata = getMetadataArgsStorage();
|
|
|
|
const relations = metadata.relations.filter(
|
|
(relation) => relation.target === Combat || relation.target === CombatEvent,
|
|
);
|
|
|
|
expect(
|
|
relations.map((relation) => ({
|
|
onDelete: relation.options.onDelete,
|
|
propertyName: relation.propertyName,
|
|
target: relation.target,
|
|
})),
|
|
).toEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({ onDelete: 'RESTRICT', propertyName: 'character', target: Combat }),
|
|
expect.objectContaining({ onDelete: 'RESTRICT', propertyName: 'huntEncounter', target: Combat }),
|
|
expect.objectContaining({ onDelete: 'RESTRICT', propertyName: 'monster', target: Combat }),
|
|
expect.objectContaining({ onDelete: 'CASCADE', propertyName: 'combat', target: CombatEvent }),
|
|
]),
|
|
);
|
|
});
|
|
|
|
it('enforces one combat per hunt encounter via a unique index', () => {
|
|
const metadata = getMetadataArgsStorage();
|
|
const index = metadata.indices.find(
|
|
(candidate) => candidate.target === Combat && candidate.columns?.includes('huntEncounterId'),
|
|
);
|
|
|
|
expect(index).toBeDefined();
|
|
const indexMetadata = index as typeof index & { options?: { unique?: boolean }; unique?: boolean };
|
|
expect(indexMetadata?.options?.unique ?? indexMetadata?.unique).toBe(true);
|
|
});
|
|
|
|
it('enforces ordered, unique event sequencing per combat', () => {
|
|
const metadata = getMetadataArgsStorage();
|
|
const index = metadata.indices.find(
|
|
(candidate) =>
|
|
candidate.target === CombatEvent &&
|
|
candidate.columns?.includes('combatId') &&
|
|
candidate.columns?.includes('sequence'),
|
|
);
|
|
|
|
expect(index).toBeDefined();
|
|
const indexMetadata = index as typeof index & { options?: { unique?: boolean }; unique?: boolean };
|
|
expect(indexMetadata?.options?.unique ?? indexMetadata?.unique).toBe(true);
|
|
});
|
|
|
|
it('adds a nullable consumedAt column to hunt_encounters to prevent reuse', () => {
|
|
const metadata = getMetadataArgsStorage();
|
|
const column = metadata.columns.find(
|
|
(candidate) => candidate.target === HuntEncounter && candidate.propertyName === 'consumedAt',
|
|
);
|
|
|
|
expect(column).toBeDefined();
|
|
expect(column?.options.nullable).toBe(true);
|
|
});
|
|
});
|