feat(reputation): add the reusable Regional Reputation display component

This commit is contained in:
Bastian Wagner
2026-08-21 18:06:37 +02:00
parent 9d1c1a7706
commit 4cb759b628
4 changed files with 200 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
import { TestBed } from '@angular/core/testing';
import type { ReputationEntry } from '../../core/api/game-api.models';
import { ReputationDisplayComponent } from './reputation-display.component';
async function setup(entry: ReputationEntry) {
await TestBed.configureTestingModule({ imports: [ReputationDisplayComponent] }).compileComponents();
const fixture = TestBed.createComponent(ReputationDisplayComponent);
fixture.componentRef.setInput('entry', entry);
fixture.detectChanges();
return fixture;
}
describe('ReputationDisplayComponent', () => {
it('renders the faction name and rank', async () => {
const fixture = await setup({
factionKey: 'border-guard',
factionName: 'Grenzwacht',
reputation: 320,
rank: 'KNOWN',
rankLabel: 'Bekannt',
nextThreshold: 500,
});
const element = fixture.nativeElement as HTMLElement;
expect(element.textContent).toContain('Grenzwacht');
expect(element.textContent).toContain('Bekannt');
});
it('shows current reputation against the next threshold', async () => {
const fixture = await setup({
factionKey: 'border-guard',
factionName: 'Grenzwacht',
reputation: 320,
rank: 'KNOWN',
rankLabel: 'Bekannt',
nextThreshold: 500,
});
const element = fixture.nativeElement as HTMLElement;
expect(element.textContent).toContain('320');
expect(element.textContent).toContain('500');
});
it('renders a progress fraction between 0 and 100', async () => {
const fixture = await setup({
factionKey: 'border-guard',
factionName: 'Grenzwacht',
reputation: 320,
rank: 'KNOWN',
rankLabel: 'Bekannt',
nextThreshold: 500,
});
const element = fixture.nativeElement as HTMLElement;
const fill = element.querySelector<HTMLElement>('[data-reputation-progress-fill]');
const width = parseFloat(fill?.style.inlineSize ?? '0');
expect(width).toBeGreaterThan(0);
expect(width).toBeLessThanOrEqual(100);
});
it('handles the top rank with no next threshold without crashing or showing a bogus progress bar', async () => {
const fixture = await setup({
factionKey: 'border-guard',
factionName: 'Grenzwacht',
reputation: 1500,
rank: 'ESTEEMED',
rankLabel: 'Geachtet',
nextThreshold: null,
});
const element = fixture.nativeElement as HTMLElement;
expect(element.textContent).toContain('Geachtet');
expect(element.querySelector('[data-reputation-max]')).toBeTruthy();
});
it('renders a sensible zero-reputation row for a faction never interacted with', async () => {
const fixture = await setup({
factionKey: 'silent-order',
factionName: 'Der Stille Orden',
reputation: 0,
rank: 'STRANGER',
rankLabel: 'Fremder',
nextThreshold: 100,
});
const element = fixture.nativeElement as HTMLElement;
expect(element.textContent).toContain('Der Stille Orden');
expect(element.textContent).toContain('Fremder');
expect(element.textContent).toContain('0');
const fill = element.querySelector<HTMLElement>('[data-reputation-progress-fill]');
const width = parseFloat(fill?.style.inlineSize ?? '-1');
expect(width).toBe(0);
});
});