using ScadaLink.CLI; using ScadaLink.CLI.Commands; namespace ScadaLink.CLI.Tests; /// /// Regression tests for CLI-009 — the design doc defines exit code 2 as "authorization /// failure". The previous implementation keyed exit 2 solely off HTTP 403, so an /// authorization failure the server signalled with an error code of /// UNAUTHORIZED/FORBIDDEN but a different HTTP status was misreported as a /// generic error (exit 1). Exit code 2 now keys off either signal. /// [Collection("Console")] public class ExitCodeTests { private static int HandleQuietly(ManagementResponse response) { var errWriter = new StringWriter(); Console.SetError(errWriter); try { return CommandHelpers.HandleResponse(response, "json"); } finally { Console.SetError(new StreamWriter(Console.OpenStandardError()) { AutoFlush = true }); } } [Fact] public void HandleResponse_Http403_ReturnsTwo() { Assert.Equal(2, HandleQuietly(new ManagementResponse(403, null, "Forbidden", "FORBIDDEN"))); } [Theory] [InlineData("UNAUTHORIZED")] [InlineData("FORBIDDEN")] [InlineData("unauthorized")] public void HandleResponse_AuthorizationCode_NonForbiddenStatus_ReturnsTwo(string code) { // The server signalled an authorization failure via the error code but with a // non-403 HTTP status; per the documented exit-code table this is still exit 2. Assert.Equal(2, HandleQuietly(new ManagementResponse(400, null, "Access denied", code))); } [Fact] public void HandleResponse_GenericError_ReturnsOne() { Assert.Equal(1, HandleQuietly(new ManagementResponse(400, null, "Validation failed", "INVALID_ARGUMENT"))); } [Fact] public void HandleResponse_AuthenticationFailure_ReturnsOne() { // Authentication failure (bad credentials) is exit 1, distinct from authorization. Assert.Equal(1, HandleQuietly(new ManagementResponse(401, null, "Invalid credentials", "AUTH_FAILED"))); } }