Repo-wide grep sweep (apps/web/src, apps/api/src) for leftover German content strings missed by Tasks 1-9, mostly in spec fixtures/assertions that mirror already-translated seed content (monster/item names, POI titles and action labels, location names/descriptions) plus a few real source-file gaps: - inventory-detail-panel.component.ts: STAT_LABELS (Waffenschaden, Angriff, Leben, Rüstung) were never translated by Task 6; now match the identical English labels already used in inventory-page.component.html. - app-shell.component.html: aria-label="Spielinhalt" -> "Game content" (this file was outside every prior task's file list). - location-interaction-panel.component.spec.ts: dead NPC-quote fixture translated to match the real wounded-scout POI text. Code comments referencing German source-spec section titles or not-yet-seeded faction names, and inline calculation-documentation comments, are left as-is per the source spec's scope (dev-facing comments may stay German). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ACkMEDYiwtcfchqKkiUJNX
103 lines
3.2 KiB
TypeScript
103 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',
|
|
renown: 1,
|
|
silver: 0,
|
|
currentHp: 100,
|
|
baseHp: 100,
|
|
baseAttack: 6,
|
|
currentLocation: {
|
|
id: SOUTH_GATE_ID,
|
|
key: 'south-gate',
|
|
name: 'Graufurt South Gate',
|
|
},
|
|
}),
|
|
} 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',
|
|
renown: 1,
|
|
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: 'Graufurt South Gate',
|
|
},
|
|
});
|
|
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',
|
|
renown: 5,
|
|
silver: 18,
|
|
currentHp: 100,
|
|
baseHp: 100,
|
|
baseAttack: 6,
|
|
currentLocation: {
|
|
id: SOUTH_GATE_ID,
|
|
key: 'south-gate',
|
|
name: 'Graufurt South Gate',
|
|
},
|
|
}),
|
|
} as unknown as Repository<Character>;
|
|
const service = new CharactersService(repository, fakeCharacterStats());
|
|
|
|
await expect(service.getDemoCharacter()).resolves.toEqual(
|
|
expect.objectContaining({ renown: 5, 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,
|
|
);
|
|
});
|
|
});
|