using Admin.NET.Plugin.AiDOP.Infrastructure; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Xunit; namespace Admin.NET.Plugin.AiDOP.Tests.S0.Quality; public class AdoS0ApiErrorsTests { [Theory] [InlineData("/api/s0/quality/inspection-plans", true)] [InlineData("/API/S0/QUALITY/inspection-plans", true)] [InlineData("/api/v1/quality/inspection-plans", false)] public void R1_IsS0Request_PathBoundary_IsExpected(string path, bool expected) { Assert.Equal(expected, AdoS0ApiErrors.IsS0Request(path)); } [Fact] public void R2_InvalidRequest_EmptyMessage_UsesDefaultMessage() { var result = AdoS0ApiErrors.InvalidRequest(" "); var body = Assert.IsType(result.Value); Assert.Equal(StatusCodes.Status400BadRequest, result.StatusCode); Assert.Equal(AdoS0ErrorCodes.InvalidRequest, body.Code); Assert.Equal("请求参数非法", body.Message); } [Fact] public void R2_WrapResult_NotFound_UsesUnifiedErrorEnvelope() { var wrapped = AdoS0ApiErrors.WrapResult(new NotFoundResult()); var result = Assert.IsType(wrapped); var body = Assert.IsType(result.Value); Assert.Equal(StatusCodes.Status404NotFound, result.StatusCode); Assert.Equal(AdoS0ErrorCodes.RecordNotFound, body.Code); } [Fact] public void R2_TryMapUnhandledException_DuplicateKeyInKnownPath_MapsToBusinessDuplicateCode() { var ok = AdoS0ApiErrors.TryMapUnhandledException( "/api/s0/supply/suppliers", new InvalidOperationException("Duplicate entry 'S001' for key 'uq_supplier_code'"), out var result); Assert.True(ok); var obj = Assert.IsType(result); var body = Assert.IsType(obj.Value); Assert.Equal(StatusCodes.Status409Conflict, obj.StatusCode); Assert.Equal(AdoS0ErrorCodes.SupplierCodeExists, body.Code); } [Fact] public void R2_TryMapUnhandledException_DuplicateKeyInUnknownPath_UsesGenericDuplicateCode() { var ok = AdoS0ApiErrors.TryMapUnhandledException( "/api/s0/quality/raw-whitelists", new Exception("UNIQUE constraint failed: qms_lymjbmd.gysbm"), out var result); Assert.True(ok); var obj = Assert.IsType(result); var body = Assert.IsType(obj.Value); Assert.Equal(StatusCodes.Status409Conflict, obj.StatusCode); Assert.Equal(AdoS0ErrorCodes.DuplicateCode, body.Code); Assert.Equal("编码已存在", body.Message); } [Fact] public void R2_TryMapUnhandledException_NonDuplicateException_ReturnsInternalServerError() { var ok = AdoS0ApiErrors.TryMapUnhandledException( "/api/s0/quality/inspection-bases", new ApplicationException("db timeout"), out var result); Assert.True(ok); var obj = Assert.IsType(result); var body = Assert.IsType(obj.Value); Assert.Equal(StatusCodes.Status500InternalServerError, obj.StatusCode); Assert.Equal(AdoS0ErrorCodes.InternalServerError, body.Code); Assert.Equal("系统繁忙,请稍后再试", body.Message); } [Fact] public void R2_TryMapUnhandledException_NonS0Path_DoesNotHandle() { var ok = AdoS0ApiErrors.TryMapUnhandledException( "/api/system/users", new Exception("Duplicate entry"), out var result); Assert.False(ok); Assert.Null(result); } }