dragon-iso/src/tests/TeamsISO.App.Tests/TeamsISO.App.Tests.csproj

45 lines
1.6 KiB
XML
Raw Normal View History

<Project Sdk="Microsoft.NET.Sdk">
<!--
Test project for the WPF host's pure-logic services (OperatorPresetStore,
OutputNameTemplate, NotesService, OSC parser). Targets net8.0-windows
because TeamsISO.App is net8.0-windows + WinExe — a pure net8.0 test
project can't reference it.
test: ControlSurfaceServer route table smoke coverage Adds end-to-end-ish tests that boot the server on an OS-assigned free port and exercise the route dispatch via HttpClient. Catches regressions in the route table itself (which is the part of the control surface that benefits least from unit tests — its bug surface is the URL → handler mapping, not the handler bodies). * src/tests/TeamsISO.App.Tests/Fakes/StubIsoController.cs — minimal IIsoController stub that lets the App layer instantiate without spinning up the engine + NDI runtime. EnableCalls / DisableCalls / RefreshDiscoveryCalled flags make assertions on side effects easy. * src/tests/TeamsISO.App.Tests/Services/ControlSurfaceServerTests.cs (7 cases): - GET / → 200 with the server-info JSON (product, endpoints). - GET /unknown-path → 200 with body {error:"not found"}. Pinning this odd-but-intentional behavior: the catch-all switch arm returns NotFound() (an object) so response is non-null and the pipeline writes 200 + that body instead of branching to the 404 path. The body is the disambiguator, matching the rest of the surface's "200 + {ok:false,error:…}" convention. - GET /participants → 200 with participants:[] when no view-model. - POST /presets/refresh-discovery → 200 + StubIsoController. RefreshDiscoveryCalled flips true (route → controller round-trip). - POST /presets/{missing}/apply → 200 + ok:false + error:"preset not found" (missing-preset path). - GET /ui → 200 with text/html. - OPTIONS /participants → 204 + Access-Control-Allow-Origin:* (CORS preflight for browser-based controllers). TeamsISO.App.Tests.csproj gains UseWPF=true so the test assembly can transitively compile against the WPF types that ControlSurfaceServer's signature touches (System.Windows.Threading, Application.Current). Implicit-using set narrows under UseWPF, so OscMessageTests gains an explicit `using System.IO` and the new test file gains `using System.Net.Http`. Tests: 56 → 90 in App.Tests; Engine.Tests unchanged at 103. Total green: 193. Build clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 20:52:36 -04:00
Tests cover services that are mostly framework-free, but
ControlSurfaceServer transitively references System.Windows.Threading
(DispatcherTimer) and System.Windows.Application — UseWPF=true pulls
in those types so test code compiles against the App's project
reference without "could not load type" errors at run time.
-->
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
test: ControlSurfaceServer route table smoke coverage Adds end-to-end-ish tests that boot the server on an OS-assigned free port and exercise the route dispatch via HttpClient. Catches regressions in the route table itself (which is the part of the control surface that benefits least from unit tests — its bug surface is the URL → handler mapping, not the handler bodies). * src/tests/TeamsISO.App.Tests/Fakes/StubIsoController.cs — minimal IIsoController stub that lets the App layer instantiate without spinning up the engine + NDI runtime. EnableCalls / DisableCalls / RefreshDiscoveryCalled flags make assertions on side effects easy. * src/tests/TeamsISO.App.Tests/Services/ControlSurfaceServerTests.cs (7 cases): - GET / → 200 with the server-info JSON (product, endpoints). - GET /unknown-path → 200 with body {error:"not found"}. Pinning this odd-but-intentional behavior: the catch-all switch arm returns NotFound() (an object) so response is non-null and the pipeline writes 200 + that body instead of branching to the 404 path. The body is the disambiguator, matching the rest of the surface's "200 + {ok:false,error:…}" convention. - GET /participants → 200 with participants:[] when no view-model. - POST /presets/refresh-discovery → 200 + StubIsoController. RefreshDiscoveryCalled flips true (route → controller round-trip). - POST /presets/{missing}/apply → 200 + ok:false + error:"preset not found" (missing-preset path). - GET /ui → 200 with text/html. - OPTIONS /participants → 204 + Access-Control-Allow-Origin:* (CORS preflight for browser-based controllers). TeamsISO.App.Tests.csproj gains UseWPF=true so the test assembly can transitively compile against the WPF types that ControlSurfaceServer's signature touches (System.Windows.Threading, Application.Current). Implicit-using set narrows under UseWPF, so OscMessageTests gains an explicit `using System.IO` and the new test file gains `using System.Net.Http`. Tests: 56 → 90 in App.Tests; Engine.Tests unchanged at 103. Total green: 193. Build clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 20:52:36 -04:00
<UseWPF>true</UseWPF>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\TeamsISO.App\TeamsISO.App.csproj" />
</ItemGroup>
</Project>