# Test — Tile Split, Zoom Indicator & YOLO Parser

**Task**: AZ-474_test_tile_split_zoom
**Name**: Tile-split endpoint + YOLO parser + isSplit handling + auto-zoom viewport + zoom indicator + malformed parse
**Description**: Implement the 6 blackbox tests covering the tile-split feature: endpoint contract, YOLO label parser happy path, `DatasetItem.isSplit` honor, auto-zoom viewport matching tile rect, indicator visibility, and the malformed-label error path.
**Complexity**: 3 points
**Dependencies**: AZ-456_test_infrastructure
**Component**: 07_dataset (tile split / zoom) + 06_annotations (parser) (Blackbox Tests)
**Tracker**: AZ-474
**Epic**: AZ-455

## Problem

Tile-split + tile-zoom is the most-numerically-intensive feature in the SPA. A single off-by-one in the YOLO label parser or a stale viewport calc loses every annotation in the tile. The malformed-label path must surface a user-visible error (per AC-39 sad path), not silently produce NaN-rendered boxes.

## Outcome

- 6 scenarios pass.

## Scope

### Included

| Scenario | Profile | Source file |
|----------|---------|-------------|
| FT-P-51 — tile-split endpoint contract | fast + e2e | blackbox-tests.md |
| FT-P-52 — YOLO label parser — happy path | fast | blackbox-tests.md |
| FT-P-53 — `DatasetItem.isSplit` is honored on the dataset list path | fast + e2e | blackbox-tests.md |
| FT-P-54 — tile auto-zoom viewport matches tile rect | fast | blackbox-tests.md |
| FT-P-55 — tile-zoom indicator visible while active | fast | blackbox-tests.md |
| FT-N-10 — malformed YOLO label surfaces a user-visible error (no silent swallow, no NaN render) | fast | blackbox-tests.md |

### Excluded

- Canvas-pixel coordinate math (covered in 16_test_canvas_bbox).
- Annotation save body shape (covered in 05_test_annotations_endpoint).

## Acceptance Criteria

**AC-1: Endpoint contract**
FT-P-51 — outbound URL + body for tile-split match the contract.

**AC-2: YOLO parser happy**
FT-P-52 — input `"3 0.5 0.5 0.2 0.2"` produces the canonical 5-tuple { classId: 3, cx: 0.5, cy: 0.5, w: 0.2, h: 0.2 }.

**AC-3: isSplit honored**
FT-P-53 — dataset items with `isSplit: true` render the split affordance; items with `false` do not.

**AC-4: Auto-zoom**
FT-P-54 — entering a tile sets the viewport to the tile rect (±0.5 px tolerance).

**AC-5: Indicator visibility**
FT-P-55 — while zoomed into a tile, the indicator is visible with the correct ARIA label.

**AC-6: Malformed parser**
FT-N-10 — input `"garbage"` produces a user-visible error (toast or inline) and NO bbox render. Asserted via DOM (error region present) AND `getBoundingClientRect` returning finite values for every rendered box (no NaN).

## System Under Test Boundary

- System under test: `<DatasetPage>` + `<TileViewer>` + the YOLO parser module.
- Allowed stubs: MSW for tile-split endpoint + dataset list.
- Disallowed: stubbing the parser or reading its state — tests pass input via the public surface (typically a paste / load) and assert the rendered result.
- Expected observables per `results_report.md` rows 85-90 (Group 17) + the row for FT-N-10.

## Constraints

- The malformed-label test (FT-N-10) MUST NOT pass by virtue of `alert()` — that's banned by NFT-SEC-07. The error must be in-DOM.

## Risks & Mitigation

**Risk 1 — Viewport rect comparison flakiness**
- *Risk*: `getBoundingClientRect` values depend on layout timing.
- *Mitigation*: wait for `requestAnimationFrame` before measuring; ±0.5 px tolerance.
