From 7f4768c20571368b8616f9ead04271776070375d Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Wed, 26 Aug 2026 20:53:42 +0200 Subject: [PATCH] task(B5): seat counting by row and block --- frontend/src/services/seatingService.ts | 14 ++++- frontend/tests/seating.count.test.ts | 84 +++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 frontend/tests/seating.count.test.ts diff --git a/frontend/src/services/seatingService.ts b/frontend/src/services/seatingService.ts index 7519985..13af8d7 100644 --- a/frontend/src/services/seatingService.ts +++ b/frontend/src/services/seatingService.ts @@ -352,8 +352,18 @@ export class SeatingService { return []; } - /** Count seats in a list of elements */ - countSeats(elements: CADElement[]): { total: number; byRow: Record; byBlock: Record } { +/** + * Zählt Sitzplätze gruppiert nach Reihe und Block. + * byRow enthält Reihen aus freien Reihen UND Block-Reihen (seit BUG-1-Fix + * tragen Block-Stühle pro Reihe eine eigene rowId). + */ + countSeats(elements: CADElement[]): { + total: number; + byRow: Record; + byBlock: Record; + /** Platzhalter für künftige Zonen-Gruppierung (aktuell immer leer). */ + byZone?: Record; + } { let total = 0; const byRow: Record = {}; const byBlock: Record = {}; diff --git a/frontend/tests/seating.count.test.ts b/frontend/tests/seating.count.test.ts new file mode 100644 index 0000000..66c4373 --- /dev/null +++ b/frontend/tests/seating.count.test.ts @@ -0,0 +1,84 @@ +/** + * Seating-Tests — countSeats: Zählung nach Reihe/Block/Gesamt. + * Ergänzt Task B5; Grundlage ist der BUG-1-Fix (rowId pro Block-Reihe). + */ +import { describe, it, expect } from 'vitest'; +import { SeatingService } from '../src/services/seatingService'; +import type { CADElement } from '../src/types/cad.types'; + +function makeChair(id: string, props: Record = {}): CADElement { + return { + id, + type: 'chair', + layerId: 'layer-1', + x: 0, + y: 0, + width: 50, + height: 50, + properties: props, + } as unknown as CADElement; +} + +function makeNonChair(id: string): CADElement { + return { + id, + type: 'rect', + layerId: 'layer-1', + x: 0, + y: 0, + width: 10, + height: 10, + properties: {}, + } as unknown as CADElement; +} + +describe('countSeats', () => { + const svc = new SeatingService(); + + it('zählt eine freie Reihe korrekt (5 Stühle, 1 rowId)', () => { + const els = svc.createSeatingRow(0, 0, 'layer-1', { count: 5 }); + const result = svc.countSeats(els); + expect(result.total).toBe(5); + expect(Object.keys(result.byRow).length).toBe(1); + expect(Object.values(result.byRow)[0]).toBe(5); + expect(Object.keys(result.byBlock).length).toBe(0); + }); + + it('zählt einen Block korrekt (3 Reihen × 4 Stühle = 12)', () => { + const els = svc.createSeatingBlock(0, 0, 'layer-1', { rows: 3, cols: 4 }); + const result = svc.countSeats(els); + expect(result.total).toBe(12); + expect(Object.keys(result.byBlock).length).toBe(1); // 1 Block + expect(Object.values(result.byBlock)[0]).toBe(12); + expect(Object.keys(result.byRow).length).toBe(3); // 3 Reihen (BUG-1-Fix!) + for (const count of Object.values(result.byRow)) { + expect(count).toBe(4); // je Reihe 4 Stühle + } + }); + + it('summiert gemischte Zeichnung korrekt (Reihe + Block + Fremdelemente)', () => { + const rows = svc.createSeatingRow(0, 0, 'layer-1', { count: 3 }); + const block = svc.createSeatingBlock(100, 100, 'layer-1', { rows: 2, cols: 2 }); + const others = [makeNonChair('x1'), makeNonChair('x2')]; + const all: CADElement[] = [...rows, ...block, ...others]; + const result = svc.countSeats(all); + expect(result.total).toBe(7); // 3 + 4, Nicht-Stühle ignorieren + expect(Object.keys(result.byRow).length).toBe(3); // 1 freie Reihe + 2 Block-Reihen + expect(Object.keys(result.byBlock).length).toBe(1); + }); + + it('liefert leere Summen bei leerer Eingabe', () => { + const result = svc.countSeats([]); + expect(result.total).toBe(0); + expect(result.byRow).toEqual({}); + expect(result.byBlock).toEqual({}); + }); + + it('zählt handgebaute Stühle ohne rowId nur im Gesamt', () => { + const els = [makeChair('h1'), makeChair('h2'), makeChair('h3', { rowId: 'row_manual' })]; + const result = svc.countSeats(els); + expect(result.total).toBe(3); + expect(result.byRow['row_manual']).toBe(1); + expect(Object.keys(result.byRow).length).toBe(1); + }); +});