106 lines
3.2 KiB
TypeScript
106 lines
3.2 KiB
TypeScript
import { NotFoundException } from '@nestjs/common';
|
|
import { Repository } from 'typeorm';
|
|
import { DEMO_CHARACTER_ID } from '../demo/demo-character.constants';
|
|
import { SOUTH_GATE_ID } from '../database/seeds/vertical-slice.constants';
|
|
import { CharacterStatsService } from './character-stats.service';
|
|
import { Character } from './entities/character.entity';
|
|
import { CharactersService } from './characters.service';
|
|
|
|
function fakeCharacterStats(
|
|
overrides: Partial<{ maxHp: number; attack: number }> = {},
|
|
): CharacterStatsService {
|
|
return {
|
|
calculate: jest.fn().mockResolvedValue({
|
|
maxHp: overrides.maxHp ?? 100,
|
|
currentHp: 100,
|
|
attack: overrides.attack ?? 6,
|
|
weaponDamage: 8,
|
|
armor: 0,
|
|
combatPower: 0,
|
|
hpRegenPerSecond: 1,
|
|
hpRegenSince: new Date('2026-08-18T09:00:00.000Z'),
|
|
}),
|
|
} as unknown as CharacterStatsService;
|
|
}
|
|
|
|
describe('CharactersService', () => {
|
|
it('returns the demo character with effective attack/HP and its location summary', async () => {
|
|
const repository = {
|
|
findOne: jest.fn().mockResolvedValue({
|
|
id: DEMO_CHARACTER_ID,
|
|
name: 'Aric Duskwalker',
|
|
level: 1,
|
|
experience: 0,
|
|
silver: 0,
|
|
currentHp: 100,
|
|
baseHp: 100,
|
|
baseAttack: 6,
|
|
currentLocation: {
|
|
id: SOUTH_GATE_ID,
|
|
key: 'south-gate',
|
|
name: 'Südtor von Graufurt',
|
|
},
|
|
}),
|
|
} as unknown as Repository<Character>;
|
|
const characterStats = fakeCharacterStats({ maxHp: 115, attack: 7 });
|
|
const service = new CharactersService(repository, characterStats);
|
|
|
|
await expect(service.getDemoCharacter()).resolves.toEqual({
|
|
id: DEMO_CHARACTER_ID,
|
|
name: 'Aric Duskwalker',
|
|
level: 1,
|
|
experience: 0,
|
|
silver: 0,
|
|
currentHp: 100,
|
|
maxHp: 115,
|
|
attack: 7,
|
|
hpRegenPerSecond: 1,
|
|
hpRegenSince: '2026-08-18T09:00:00.000Z',
|
|
currentLocation: {
|
|
id: SOUTH_GATE_ID,
|
|
key: 'south-gate',
|
|
name: 'Südtor von Graufurt',
|
|
},
|
|
});
|
|
expect(characterStats.calculate).toHaveBeenCalledWith(
|
|
expect.objectContaining({ id: DEMO_CHARACTER_ID }),
|
|
);
|
|
});
|
|
|
|
it('exposes the persisted silver so the HUD never has to guess', async () => {
|
|
const repository = {
|
|
findOne: jest.fn().mockResolvedValue({
|
|
id: DEMO_CHARACTER_ID,
|
|
name: 'Aric Duskwalker',
|
|
level: 1,
|
|
experience: 24,
|
|
silver: 18,
|
|
currentHp: 100,
|
|
baseHp: 100,
|
|
baseAttack: 6,
|
|
currentLocation: {
|
|
id: SOUTH_GATE_ID,
|
|
key: 'south-gate',
|
|
name: 'Südtor von Graufurt',
|
|
},
|
|
}),
|
|
} as unknown as Repository<Character>;
|
|
const service = new CharactersService(repository, fakeCharacterStats());
|
|
|
|
await expect(service.getDemoCharacter()).resolves.toEqual(
|
|
expect.objectContaining({ experience: 24, silver: 18 }),
|
|
);
|
|
});
|
|
|
|
it('reports a missing demo seed as not found', async () => {
|
|
const repository = {
|
|
findOne: jest.fn().mockResolvedValue(null),
|
|
} as unknown as Repository<Character>;
|
|
const service = new CharactersService(repository, fakeCharacterStats());
|
|
|
|
await expect(service.getDemoCharacter()).rejects.toBeInstanceOf(
|
|
NotFoundException,
|
|
);
|
|
});
|
|
});
|