feat(web): add inventory item detail/comparison panel
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
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',
|
||||
requiredLevel: 1,
|
||||
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',
|
||||
requiredLevel: 1,
|
||||
weaponDamage: 11,
|
||||
bonusAttack: 1,
|
||||
bonusHp: 0,
|
||||
bonusArmor: 0,
|
||||
iconPath: '/images/items/bandit-blade.png',
|
||||
},
|
||||
};
|
||||
|
||||
async function setup(overrides: {
|
||||
item?: InventoryItem | null;
|
||||
equippedItemInSlot?: InventoryItem | null;
|
||||
characterLevel?: number;
|
||||
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('characterLevel', overrides.characterLevel ?? 1);
|
||||
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('shows a disabled Benötigt Stufe X button when the level requirement is not met', async () => {
|
||||
const fixture = await setup({ item: { ...banditBlade, item: { ...banditBlade.item, requiredLevel: 5 } }, characterLevel: 1 });
|
||||
const button = (fixture.nativeElement as HTMLElement).querySelector<HTMLButtonElement>('[data-detail-equip]');
|
||||
|
||||
expect(button?.textContent).toContain('Benötigt Stufe 5');
|
||||
expect(button?.disabled).toBe(true);
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user