Files
ashen-realms/apps/web/src/app/features/inventory/inventory-detail-panel.component.spec.ts
Bastian Wagner c0401d5c60 feat(inventory): remove the requiredLevel equip gate from the detail panel
The API can no longer emit ITEM_LEVEL_REQUIREMENT_NOT_MET (Task 8 removed
the level gate server-side) and InventoryItem.item no longer carries
requiredLevel (Task 12). Drop the characterLevel input, the
meetsLevelRequirement computed, the associated template branch and copy,
and the dead German error-message mapping. Update fixtures across the
inventory specs to the real InventoryItem/CharacterResponse shapes.
2026-08-21 15:06:00 +02:00

104 lines
3.6 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: 'Abgenutztes Kurzschwert',
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: 'Räuberklinge',
rarity: 'COMMON',
equipmentSlot: 'WEAPON',
weaponDamage: 11,
bonusAttack: 1,
bonusHp: 0,
bonusArmor: 0,
iconPath: '/images/items/bandit-blade.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 Ausgerüstet 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('Ausgerüstet');
expect(element.querySelector('[data-detail-equip]')).toBeNull();
});
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('Ausrüsten');
});
it('emits equip with the characterItemId when Ausrüsten 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);
});
});