using System.Security.Claims; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using ZB.MOM.WW.ScadaBridge.Security; using ZB.MOM.WW.ScadaBridge.Security.Auth; using Xunit; namespace ZB.MOM.WW.ScadaBridge.Security.Tests; public class AutoLoginAuthenticationHandlerTests { /// /// Minimal stub for the scheme options the base /// resolves during InitializeAsync. This /// test project deliberately carries no mocking library, so the seam is hand-rolled. /// private sealed class StubOptionsMonitor : IOptionsMonitor { private readonly AuthenticationSchemeOptions _value = new(); public AuthenticationSchemeOptions CurrentValue => _value; public AuthenticationSchemeOptions Get(string? name) => _value; public IDisposable? OnChange(Action listener) => null; } private static async Task CreateAsync(string user = "multi-role") { var schemeOptions = new StubOptionsMonitor(); var opts = Options.Create(new AuthDisableLoginOptions { DisableLogin = true, User = user }); var handler = new AutoLoginAuthenticationHandler( schemeOptions, NullLoggerFactory.Instance, UrlEncoder.Default, opts, TimeProvider.System); await handler.InitializeAsync( new AuthenticationScheme( CookieAuthenticationDefaults.AuthenticationScheme, null, typeof(AutoLoginAuthenticationHandler)), new DefaultHttpContext()); return handler; } [Fact] public async Task Authenticate_GrantsAllRoles_SystemWide_AsConfiguredUser() { var handler = await CreateAsync("multi-role"); var result = await handler.AuthenticateAsync(); Assert.True(result.Succeeded); var p = result.Principal!; Assert.Equal("multi-role", p.Identity!.Name); foreach (var role in Roles.All) Assert.True(p.IsInRole(role), $"expected role {role}"); Assert.Empty(p.FindAll(JwtTokenService.SiteIdClaimType)); // system-wide => no scope claims } [Fact] public async Task Authenticate_BlankUser_FallsBackToMultiRole() { var handler = await CreateAsync(" "); var result = await handler.AuthenticateAsync(); Assert.Equal("multi-role", result.Principal!.Identity!.Name); } [Fact] public async Task SignInAndSignOut_AreNoOps_DoNotThrow() { var handler = await CreateAsync(); await handler.SignInAsync(new ClaimsPrincipal(), null); await handler.SignOutAsync(null); } }