fix: preserve seeded location identities

This commit is contained in:
Bastian Wagner
2026-08-18 19:40:13 +02:00
parent 067134b684
commit c35859a4de
2 changed files with 159 additions and 57 deletions

View File

@@ -1,4 +1,7 @@
import { DataSource } from 'typeorm';
import { Character } from '../../characters/entities/character.entity';
import { LocationConnection } from '../../world/entities/location-connection.entity';
import { LocationDefinition } from '../../world/entities/location-definition.entity';
import { seedVisibleVerticalSlice } from './vertical-slice.seed';
type Row = Record<string, unknown>;
@@ -39,6 +42,41 @@ class InMemoryRepository {
readonly insert = jest.fn(async (value: Row) => {
this.rows.push({ ...value });
});
readonly update = jest.fn(async (criteria: string | Row, value: Row) => {
const row = this.rows.find((candidate) =>
typeof criteria === 'string'
? candidate.id === criteria
: Object.entries(criteria).every(
([key, expected]) => candidate[key] === expected,
),
);
if (row) {
Object.assign(row, value);
}
});
}
function createDataSource(
locationRepository: InMemoryRepository,
connectionRepository: InMemoryRepository,
characterRepository: InMemoryRepository,
): DataSource {
return {
getRepository: jest.fn((entity: unknown) => {
if (entity === LocationDefinition) {
return locationRepository;
}
if (entity === LocationConnection) {
return connectionRepository;
}
if (entity === Character) {
return characterRepository;
}
throw new Error('Unexpected repository');
}),
} as unknown as DataSource;
}
describe('seedVisibleVerticalSlice', () => {
@@ -46,27 +84,20 @@ describe('seedVisibleVerticalSlice', () => {
const locationRepository = new InMemoryRepository();
const connectionRepository = new InMemoryRepository();
const characterRepository = new InMemoryRepository();
const dataSource = {
getRepository: jest
.fn()
.mockReturnValueOnce(locationRepository)
.mockReturnValueOnce(connectionRepository)
.mockReturnValueOnce(characterRepository)
.mockReturnValueOnce(locationRepository)
.mockReturnValueOnce(connectionRepository)
.mockReturnValueOnce(characterRepository),
} as unknown as DataSource;
await seedVisibleVerticalSlice(dataSource);
await seedVisibleVerticalSlice(dataSource);
expect(locationRepository.upsert).toHaveBeenCalledWith(
expect.arrayContaining([
expect.objectContaining({ id: SOUTH_GATE_ID, key: 'south-gate' }),
expect.objectContaining({ id: BURNED_ROAD_ID, key: 'burned-road' }),
]),
['key'],
const dataSource = createDataSource(
locationRepository,
connectionRepository,
characterRepository,
);
await seedVisibleVerticalSlice(dataSource);
Object.assign(characterRepository.rows[0], {
currentLocationId: BURNED_ROAD_ID,
currentHp: 57,
experience: 39,
});
await seedVisibleVerticalSlice(dataSource);
expect(connectionRepository.upsert).toHaveBeenCalledWith(
expect.arrayContaining([
expect.objectContaining({
@@ -86,5 +117,57 @@ describe('seedVisibleVerticalSlice', () => {
expect(locationRepository.rows).toHaveLength(2);
expect(connectionRepository.rows).toHaveLength(2);
expect(characterRepository.rows).toHaveLength(1);
expect(characterRepository.rows[0]).toEqual(
expect.objectContaining({
currentLocationId: BURNED_ROAD_ID,
currentHp: 57,
experience: 39,
}),
);
});
it('preserves existing location IDs and uses them for the directed connections', async () => {
const locationRepository = new InMemoryRepository();
const connectionRepository = new InMemoryRepository();
const characterRepository = new InMemoryRepository();
const persistedSouthGateId = '30000000-0000-4000-8000-000000000001';
locationRepository.rows.push({
id: persistedSouthGateId,
key: 'south-gate',
name: 'Veraltetes Südtor',
});
const dataSource = createDataSource(
locationRepository,
connectionRepository,
characterRepository,
);
await seedVisibleVerticalSlice(dataSource);
expect(locationRepository.rows).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: persistedSouthGateId,
key: 'south-gate',
name: 'Südtor von Graufurt',
}),
expect.objectContaining({
id: BURNED_ROAD_ID,
key: 'burned-road',
}),
]),
);
expect(connectionRepository.rows).toEqual(
expect.arrayContaining([
expect.objectContaining({
fromLocationId: persistedSouthGateId,
toLocationId: BURNED_ROAD_ID,
}),
expect.objectContaining({
fromLocationId: BURNED_ROAD_ID,
toLocationId: persistedSouthGateId,
}),
]),
);
});
});