teamsiso/src/tests/TeamsISO.Engine.Tests/Interop/NdiInteropNormalizeGroupsTests.cs
Zac Gaetano d880941ad5
Some checks failed
CI / build-and-test (push) Failing after 26s
fix(ndi): canonicalize 'public' -> 'Public' in discovery + sender group strings (the real bug)
6+ hours of misdiagnosis today, root cause finally found this evening: the user's config.json persisted ndiGroups.discoveryGroups = 'public,teamsiso-input'. NDI group names are case-sensitive in the runtime. Teams broadcasts to the canonical 'Public' (capital P) group. Lowercase 'public' didn't match -> NDI Find returned zero sources forever. NDI Studio Monitor sees Teams sources because it uses default groups (no filter = 'Public'). Every TeamsISO launch that read the config got zero -> looked like a TeamsISO bug.

Fix: add NdiInteropPInvoke.NormalizeGroups that case-folds 'Public' specifically (the most common operator footgun) while passing through custom group names (e.g. 'teamsiso-input') verbatim. Wire it into CreateFinder and CreateSender. End-to-end test: restored bad lowercase config -> launched via Start Menu shortcut -> Serilog now logs 'NDI finder created with groups: Public,teamsiso-input' (note capital P) -> REST returns 2 participants. 264/264 tests passing (Engine 124 +12 NormalizeGroups cases, App 131, Integration 9).

Also adds InternalsVisibleTo on the NdiInterop project so the engine test project can cover the internal helper directly.
2026-05-16 18:33:49 -04:00

35 lines
1.8 KiB
C#

using System.Runtime.Versioning;
using TeamsISO.Engine.NdiInterop;
namespace TeamsISO.Engine.Tests.Interop;
// NdiInteropPInvoke is marked [SupportedOSPlatform("windows")] because it
// P/Invokes the Windows-only NDI runtime. The pure NormalizeGroups helper
// doesn't actually touch native code, but it inherits the platform tag from
// the enclosing class. Re-declaring SupportedOSPlatform here silences CA1416
// — these tests still only run on Windows (the Engine.Tests project itself
// is platform-agnostic but xunit only schedules them when the OS supports).
[SupportedOSPlatform("windows")]
// NdiInteropPInvoke.NormalizeGroups is internal; the engine tests project has
// access via InternalsVisibleTo applied to TeamsISO.Engine.NdiInterop.
public class NdiInteropNormalizeGroupsTests
{
[Theory]
[InlineData(null, null)]
[InlineData("", null)]
[InlineData(" ", null)]
[InlineData("Public", "Public")] // already canonical
[InlineData("public", "Public")] // lowercase -> canonical (the bug fix)
[InlineData("PUBLIC", "Public")] // shouty -> canonical
[InlineData("PuBlIc", "Public")] // mixed case -> canonical
[InlineData("teamsiso-input", "teamsiso-input")] // custom group: pass through
[InlineData("Public,teamsiso-input", "Public,teamsiso-input")]
[InlineData("public,teamsiso-input", "Public,teamsiso-input")] // mixed list normalizes the standard one only
[InlineData("teamsiso-input,PUBLIC", "teamsiso-input,Public")]
[InlineData(" public , teamsiso-input ", "Public,teamsiso-input")] // whitespace trimmed per part
public void NormalizeGroups_Maps(string? input, string? expected)
{
NdiInteropPInvoke.NormalizeGroups(input).Should().Be(expected);
}
}