The test_state_connected test timed out because _gather_bt_state calls real
bluetoothctl which hangs for 30s when no BT adapter is present. Since these
gathers depend on hardware (nmcli, bluetoothctl) that only exists on the Pi,
mock them in the test fixture so the test suite runs cleanly on any machine.
43/43 tests pass in 2.93s.
- TestAPIRouting: 7 tests covering get/set routing mode and breakpoint
- mock_pipeline now has a real set_routing side_effect that updates properties
- Covers connected/disconnected states, mode toggle, breakpoint change, both
Pipeline:
- process() dispatches to _process_mono() or _process_4cm() based on routing_mode
- _process_4cm() splits chain at routing_breakpoint: pre blocks on ch0, post on ch1
- _process_single_block() extracted for reuse in both mono and 4cm paths
- routing_mode/routing_breakpoint load from preset via load_preset()
- set_routing() for runtime configuration
- Properties: routing_mode (mono|4cm), routing_breakpoint with validation
Web server:
- GET /api/routing — current routing mode and breakpoint
- POST /api/routing — set routing mode/breakpoint, persist to current preset, WS broadcast
- _gather_state() includes routing_mode and routing_breakpoint
Web UI:
- Settings page: 4CM toggle + breakpoint slider with routing description
- Dashboard: routing badge (4CM/Mono) with breakpoint info
- app.js: WebSocket handler, updateRoutingUI(), toggle4cm(), set4cmBreakpoint()
- style.css: .badge, .badge-4cm, .badge-mono, .routing-status, .routing-desc
Tests: mock pipeline fixture updated with routing_mode/routing_breakpoint