Files
ashen-realms/apps/web/src/app/features/inventory/inventory-detail-panel.component.spec.ts
Bastian Wagner dfa62fd152 fix: translate the last five German fixture strings found by the final review's re-review
Fixes 5 residual findings from the re-review of Playable Slice 0.6.6's
whole-branch review: two twice-hit spec files still carried invented
or seeded German fixture values (reputation-display faction name,
inventory-detail-panel item description and item name), a world store
fixture still used a German location description, and a dev comment
in reputation-content.ts referenced a faction name that no longer
exists in the code. All are literal string substitutions using
already-translated canon English text; no keys, ids, or logic changed.
2026-08-22 09:17:23 +02:00

146 lines
4.8 KiB
TypeScript

import { TestBed } from '@angular/core/testing';
import { vi } from 'vitest';
import type { InventoryItem } from '../../core/api/game-api.models';
import { InventoryDetailPanelComponent } from './inventory-detail-panel.component';
const wornSword: InventoryItem = {
id: 'item-sword',
quantity: 1,
equipped: true,
item: {
key: 'worn-short-sword',
name: 'Worn Shortsword',
description: 'Item description.',
rarity: 'COMMON',
equipmentSlot: 'WEAPON',
weaponDamage: 8,
bonusAttack: 0,
bonusHp: 0,
bonusArmor: 0,
iconPath: '/images/items/worn-short-sword.png',
},
};
const banditBlade: InventoryItem = {
id: 'item-blade',
quantity: 1,
equipped: false,
item: {
key: 'bandit-blade',
name: 'Bandit Blade',
description: 'Item description.',
rarity: 'COMMON',
equipmentSlot: 'WEAPON',
weaponDamage: 11,
bonusAttack: 1,
bonusHp: 0,
bonusArmor: 0,
iconPath: '/images/items/bandit-blade.png',
},
};
const ashPelt: InventoryItem = {
id: 'item-pelt',
quantity: 3,
equipped: false,
item: {
key: 'ash-pelt',
name: 'Ash Pelt',
description: 'Item description.',
rarity: 'COMMON',
equipmentSlot: null,
weaponDamage: 0,
bonusAttack: 0,
bonusHp: 0,
bonusArmor: 0,
iconPath: '/images/items/ash-pelt.png',
},
};
async function setup(overrides: {
item?: InventoryItem | null;
equippedItemInSlot?: InventoryItem | null;
busy?: boolean;
}) {
TestBed.resetTestingModule();
await TestBed.configureTestingModule({ imports: [InventoryDetailPanelComponent] }).compileComponents();
const fixture = TestBed.createComponent(InventoryDetailPanelComponent);
fixture.componentRef.setInput('item', overrides.item ?? null);
fixture.componentRef.setInput('equippedItemInSlot', overrides.equippedItemInSlot ?? null);
fixture.componentRef.setInput('busy', overrides.busy ?? false);
fixture.detectChanges();
return fixture;
}
describe('InventoryDetailPanelComponent', () => {
it('shows a placeholder when nothing is selected', async () => {
const fixture = await setup({ item: null });
expect((fixture.nativeElement as HTMLElement).querySelector('[data-detail-empty]')).not.toBeNull();
});
it('shows Equipped for the currently equipped item, with no equip button', async () => {
const fixture = await setup({ item: wornSword });
const element = fixture.nativeElement as HTMLElement;
expect(element.querySelector('[data-detail-equipped]')?.textContent).toContain('Equipped');
expect(element.querySelector('[data-detail-equip]')).toBeNull();
});
it('refuses to offer an equip button for a non-equippable item', async () => {
const fixture = await setup({ item: ashPelt });
const element = fixture.nativeElement as HTMLElement;
expect(element.textContent).toContain('Not equippable');
expect(element.querySelector('[data-detail-equip]')).toBeNull();
expect(element.querySelector('[data-detail-equipped]')).toBeNull();
});
it('shows the item flavour text from the server', async () => {
const fixture = await setup({
item: {
...banditBlade,
item: { ...banditBlade.item, description: 'A roughly serrated blade, forged for quick raids.' },
},
});
expect((fixture.nativeElement as HTMLElement).textContent).toContain(
'A roughly serrated blade, forged for quick raids.',
);
});
it('shows the stat comparison against the equipped item in the same slot', async () => {
const fixture = await setup({ item: banditBlade, equippedItemInSlot: wornSword });
const text = (fixture.nativeElement as HTMLElement).querySelector('[data-detail-stats]')?.textContent ?? '';
expect(text).toContain('11');
expect(text).toContain('+3');
expect(text).toContain('+1');
});
it('always shows the plain equip button for an owned equippable item', async () => {
const fixture = await setup({ item: banditBlade });
const element = fixture.nativeElement as HTMLElement;
const button = element.querySelector<HTMLButtonElement>('[data-detail-equip]');
expect(button?.disabled).toBe(false);
expect(button?.textContent?.trim()).toBe('Equip');
});
it('emits equip with the characterItemId when Equip is clicked', async () => {
const fixture = await setup({ item: banditBlade });
const emitted: string[] = [];
fixture.componentInstance.equip.subscribe((id: string) => emitted.push(id));
(fixture.nativeElement as HTMLElement).querySelector<HTMLButtonElement>('[data-detail-equip]')?.click();
expect(emitted).toEqual(['item-blade']);
});
it('disables the equip button while busy', async () => {
const fixture = await setup({ item: banditBlade, busy: true });
const button = (fixture.nativeElement as HTMLElement).querySelector<HTMLButtonElement>('[data-detail-equip]');
expect(button?.disabled).toBe(true);
});
});