Commit graph

2 commits

Author SHA1 Message Date
fbcc56289e test: ThemeManager + CommandPaletteViewModel.Matches coverage
ThemeManager grows a test seam — its singleton ctor now delegates to
three internal seams (isSystemDark / loadPreference / savePreference)
that the production singleton fills with the real registry +
UIPreferences calls. Tests construct via the internal ctor with
stubs so they never touch HKCU or %LOCALAPPDATA% (which would
otherwise flake on CI or pollute the dev's UI state). Apply() and
the SystemEvents subscription are intentionally NOT exercised
here — both require Application.Current and a real dispatcher.

CommandPaletteViewModel.Matches changes from `private static` to
`internal static` — the predicate is the unit worth pinning, and
building a full CommandPaletteViewModel would require a fake
IIsoController + Dispatcher for one test.

New tests:

* src/tests/TeamsISO.App.Tests/Services/ThemeManagerTests.cs (11 cases):
  - Set Dark → Light round-trips Preference + ResolveTheme and
    persists via the savePreference seam.
  - ResolveTheme follows the system probe when Preference is
    System (true → Dark, false → Light).
  - Toggle from System pins to the opposite of the currently-
    resolved theme (not back to System) — explicit click should
    have visible effect.
  - Toggle from Dark flips Light; Toggle from Light flips Dark.
  - Set rejects invalid preferences (case-sensitive: lowercase
    "dark", "LIGHT", "", "invalid" all throw ArgumentException
    with ParamName=preference).
  - Constructor defaults to System when loadPreference returns
    null (fresh install / missing prefs file) or an invalid value
    (future schema collision).
  - Constructor swallows a load exception so the app doesn't lose
    theming when ui-prefs.json faults on read.

* src/tests/TeamsISO.App.Tests/ViewModels/CommandPaletteMatchesTests.cs
  (16 cases): Theory pinning case-insensitive label / category /
  keyword Contains, plus a full-vocabulary spread test counting
  hits for "theme" (3), "stop" (1), "ndi" (2), "App" (5 — four
  App-category cmds + the Apply transcoder topology substring
  match, called out in the assertion because a future move to a
  stricter algo has to re-decide that affordance deliberately),
  and "xyzzy" (0).

Tests: 56 → 83 in App.Tests; Engine.Tests unchanged at 103.
Total green: 186. Build clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 20:47:25 -04:00
d282e1b0f8 feat(wpf): v2 task 39+40 - studio table redesign + Ctrl+K command palette
Some checks failed
CI / build-and-test (push) Failing after 30s
Task 39: 5-column participants table - state LED, name+codec caption, 5-bar audio meter, mono output name, ISO pill. Row height 52, full-row active-speaker tint (no left stripe). New converter LevelThresholdConverter, OutputName property on ParticipantViewModel.

Task 40: Ctrl+K / Ctrl+P command palette - chromeless centered floating window, fuzzy Contains match across Label/Category/Keywords, arrow nav, Enter invoke, Esc close. Quick/Teams/Network/App categories cover top operator verbs and theme switching.

Also: log startup exceptions to Serilog before the modal MessageBox fires - much better triage signal than user-pasted dialog text.
2026-05-15 11:15:00 -04:00