The Yavsc.Org integration tests were failing 'Internal Server Error' on
the OIDC discovery document when run as part of the full test suite.
Root cause: WebHostFixture bound Kestrel to IPAddress.Loopback on a
dynamically-allocated port and exposed it via IServerAddressesFeature.
But the OIDC issuer URLs (and the issuer claim) come from Site:Authority,
which was left at the production value (mercure.pschneider.fr). So
IdentityServer8's discovery document advertised URLs unreachable from
the test process, and the discovery call returned a 500.
Fix:
- WebServerFixture now overrides Site:Authority and Site:ExternalUrl
in AddInMemoryCollection to 'https://localhost:44300' (the ASP.NET
Core dev HTTPS convention).
- WebHostFixture reads Site:Authority from configuration and binds
Kestrel to that fixed URL. The exposed Addresses list is sourced
from the same configuration value instead of the
IServerAddressesFeature, so the listen URL and the OIDC issuer
URLs always match.
Remoting.cs (Mandatory/Remoting.cs): add 'using
Microsoft.Extensions.DependencyInjection;' so the existing OIDC/DB
diagnostic block (capture raw HTTP response + dump OIDC-related DB
state on discovery failure) compiles. The diagnostic itself is left
in place — it's what surfaced the 500 in the first place.
Yavsc.Blogs.Tests will need a fixture too. Lifting the cross-cutting
plumbing (Kestrel + self-signed cert + address discovery + lazy init)
into a new Yavsc.Tests.Shared project lets the next fixture inherit
from it without copying 200+ lines of setup boilerplate, and keeps
the Org.Tests fixture focused on its IdentityServer + SMTP seed.
* New project src/Yavsc.Tests.Shared with WebHostFixture (abstract)
and TestAuthPolicyProvider (test auth bypass via X-Test-Role).
* WebServerFixture in Org.Tests now inherits from WebHostFixture;
BuildApp + ConfigurePipelineAsync hold only Org-specific work.
* Two shared package versions promoted to the root Directory.Packages.props.
* Tests still 30/30 green.
The EMaillingTests.SendEMailSynchrone smoke test asserts the
recording fake observed this exact call sequence on a successful
send:
Connect, Authenticate, Send, Disconnect
MailSender.SendEmailAsync only calls Authenticate when
smtpSettings.UserName is non-null (src/Yavsc.Server/Services/
MailSender.cs line 89). WebServerFixture built the host without
a Smtp config — so UserName resolved to null, Authenticate was
skipped, and the recording captured only:
Connect, Send, Disconnect
Pre-existing breakage, not introduced by recent work; the
fixture had been loading from .env indirectly (probably never,
or before a refactor that stopped doing so).
Feed the test host a fake SMTP config via the same
AddInMemoryCollection the fixture already uses for
ConnectionStrings:
Smtp:Host = smtp.test.local
Smtp:Port = 465
Smtp:UserName = test-user
Smtp:Password = test-pass
UserName non-null means MailSender now exercises the Authenticate
branch, which the recording captures. Tests in the Yavsc.Org.Tests
suite: 21/21 green (was 20/21 with SendEMailSynchrone failing).
Narrow ISmtpClient to the four operations MailSender actually uses,
behind a Yavsc.Interfaces.ISmtpClientFactory. Production wires
MailKitSmtpClient (SmtpClientFactory); tests wire a recording fake
(RecordingSmtpClientFactory). The fake is pre-registered in
WebServerFixture so SMTP calls are short-circuited; the EMailling
test now asserts the Connect -> Authenticate -> Send -> Disconnect
sequence. Yavsc.Abstract stays free of MailKit/MimeKit.
The partial class ClientController had two constructors declared
across ClientController.cs and ClientController.Collections.cs.
ASP.NET Core DI failed to pick one at request time with:
System.InvalidOperationException: Multiple constructors accepting
all given argument types have been found in type
'Yavsc.Controllers.ClientController'.
Move IHtmlLocalizer<ClientController> into the primary constructor
in ClientController.cs and drop the duplicate one in
ClientController.Collections.cs. The Collections partial now keeps
only its readonly field and action methods; the constructor and
field assignment are unified on the main file.
Also add the missing 'using Microsoft.AspNetCore.Mvc.Localization;'
to ClientController.cs so IHtmlLocalizer resolves.
Move the integration test project from the top-level test/ directory into
src/ alongside the projects it tests. Rename the project (and folder) to
Yavsc.Org.Tests to match .NET conventions and reflect that it tests the
Org runtime primarily.
Path changes:
- test/yavscTests/yavscTests.csproj -> src/Yavsc.Org.Tests/Yavsc.Org.Tests.csproj
- All .cs / .json / .resx files moved to their new location
- PostItViewModelTests moved out to the dedicated src/PostIt.Tests project
(it was unrelated to Org testing)
Build adjustments:
- <ProjectReference> paths shortened (..\..\src\X -> ..\X)
- PostIt project reference removed (covered by its own test project)
- <OutputType>exe added (required by xunit.v3)
- xunit.v3.common and xunit.v3.extensibility.core added to package versions
Solution + sln:
- yavsc.sln Project Name updated to 'Yavsc.Org.Tests' and path updated
- GUID preserved so existing build configs stay valid
Static web assets:
- The CopyStaticWebAssetsManifest target was hard-coding the destination
filename to 'testhost.staticwebassets.endpoints.json', which worked
when the assembly was named 'yavscTests'. Now that the assembly name
is 'Yavsc.Org.Tests', ASP.NET Core's MapStaticAssets() looks for
'Yavsc.Org.Tests.staticwebassets.endpoints.json' (entry-assembly-based
resolution). Use $(MSBuildProjectName) so the copy target stays
correct under any future rename.
2026-06-19 17:52:54 +01:00
Renamed from test/yavscTests/WebServerFixture.cs (Browse further)