diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/LoginTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/LoginTests.cs index a0a483a9..e61fdad1 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/LoginTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/LoginTests.cs @@ -74,15 +74,17 @@ public class LoginTests Assert.Equal(200, status); // redirect followed to login page } - /// Verifies that the token endpoint returns a JWT for valid credentials. + /// + /// Verifies that the token endpoint returns a JWT for valid credentials. Skipped when the + /// rig runs with DisableLogin, where /auth/token deliberately answers 404. + /// /// A task that represents the asynchronous operation. - [Fact] + [SkippableFact] public async Task TokenEndpoint_ReturnsJwt() { - var page = await _fixture.NewPageAsync(); - - await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/login"); - await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded); + var page = await OpenLoginPageAsync(); + Skip.If(await TokenEndpointDisabledAsync(page), + "Login is disabled on this rig: POST /auth/token answers 404 by design, so no JWT is issued."); var result = await page.EvaluateAsync(@" async () => { @@ -101,29 +103,50 @@ public class LoginTests Assert.Equal("multi-role", result.GetProperty("username").GetString()); } - /// Verifies that the token endpoint returns HTTP 401 for invalid credentials. + /// + /// Verifies that the token endpoint rejects invalid credentials: HTTP 401 with login + /// enabled, or HTTP 404 under DisableLogin (the exchange is closed entirely, so + /// even bad credentials can never reach a credential check). + /// /// A task that represents the asynchronous operation. [Fact] public async Task TokenEndpoint_InvalidCredentials_Returns401() { - var page = await _fixture.NewPageAsync(); + var page = await OpenLoginPageAsync(); + var disabled = await TokenEndpointDisabledAsync(page); + var status = await PostTokenAsync(page, "baduser", "badpass"); + + Assert.Equal(disabled ? 404 : 401, status); + } + + private async Task OpenLoginPageAsync() + { + var page = await _fixture.NewPageAsync(); await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/login"); await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded); + return page; + } - var status = await page.EvaluateAsync(@" - async () => { + /// + /// Probes whether the rig runs with DisableLogin: the token exchange then answers + /// 404 for any request (AuthEndpoints.HandleTokenAsync), while with login enabled a + /// valid-credential POST is a 200 and never a 404. + /// + private static async Task TokenEndpointDisabledAsync(IPage page) => + await PostTokenAsync(page, PlaywrightFixture.TestUsername, PlaywrightFixture.TestPassword) == 404; + + private static Task PostTokenAsync(IPage page, string username, string password) => + page.EvaluateAsync(@" + async ([u, p]) => { const resp = await fetch('/auth/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - body: 'username=baduser&password=badpass' + body: new URLSearchParams({ username: u, password: p }).toString() }); return resp.status; } - "); - - Assert.Equal(401, status); - } + ", new object[] { username, password }); private static ILocatorAssertions Expect(ILocator locator) => Assertions.Expect(locator);