feat(web): show quest markers on location hotspots

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Bastian Wagner
2026-08-22 23:28:55 +02:00
parent ff8b7c8b78
commit 3a84fd5371
9 changed files with 253 additions and 6 deletions

View File

@@ -1,5 +1,8 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import type { LocationPointOfInterest } from '../../../core/api/game-api.models';
import type {
LocationPointOfInterest,
NpcMarker,
} from '../../../core/api/game-api.models';
import { LocationPoiComponent } from './location-poi.component';
const wagon: LocationPointOfInterest = {
@@ -16,6 +19,7 @@ const wagon: LocationPointOfInterest = {
async function setup(
poi: LocationPointOfInterest = wagon,
busy = false,
markers: NpcMarker[] = [],
): Promise<{
fixture: ComponentFixture<LocationPoiComponent>;
activated: LocationPointOfInterest[];
@@ -28,6 +32,7 @@ async function setup(
const fixture = TestBed.createComponent(LocationPoiComponent);
fixture.componentRef.setInput('poi', poi);
fixture.componentRef.setInput('busy', busy);
fixture.componentRef.setInput('markers', markers);
const activated: LocationPointOfInterest[] = [];
fixture.componentInstance.activate.subscribe((value) => activated.push(value));
@@ -113,4 +118,48 @@ describe('LocationPoiComponent', () => {
expect(button.getAttribute('aria-label')).toBe('Abandoned Wagon');
});
it('renders no badge without markers', async () => {
const { fixture } = await setup();
expect(fixture.nativeElement.querySelector('[data-poi-badge]')).toBeNull();
});
it('renders a badge for a quest that can be started here', async () => {
const { fixture, button } = await setup(wagon, false, ['QUEST_AVAILABLE']);
expect(
fixture.nativeElement.querySelector('[data-poi-badge]').textContent.trim(),
).toBe('!');
expect(button.getAttribute('aria-label')).toBe(
'Abandoned Wagon: Search, quest available',
);
});
it('renders a badge when the current step waits here', async () => {
const { fixture, button } = await setup(wagon, false, ['QUEST_TURN_IN']);
expect(
fixture.nativeElement.querySelector('[data-poi-badge]').textContent.trim(),
).toBe('?');
expect(button.getAttribute('aria-label')).toContain('quest step ready');
});
it('ignores markers that are not quest markers', async () => {
const { fixture } = await setup(wagon, false, ['MERCHANT', 'EXCHANGE']);
expect(fixture.nativeElement.querySelector('[data-poi-badge]')).toBeNull();
});
it('renders one badge at most, preferring the waiting step', async () => {
const { fixture } = await setup(wagon, false, [
'MERCHANT',
'QUEST_AVAILABLE',
'QUEST_TURN_IN',
]);
const badges = fixture.nativeElement.querySelectorAll('[data-poi-badge]');
expect(badges).toHaveLength(1);
expect(badges[0].textContent.trim()).toBe('?');
});
});