mirror of
				https://github.com/nsnail/NetAdmin.git
				synced 2025-11-04 21:20:50 +08:00 
			
		
		
		
	@@ -24,7 +24,9 @@ namespace NetAdmin.AdmServer.Host
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///     配置应用程序中间件
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        #pragma warning disable S2325
 | 
			
		||||
        public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifeTime)
 | 
			
		||||
            #pragma warning restore S2325
 | 
			
		||||
        {
 | 
			
		||||
            _ = app                                        //
 | 
			
		||||
                .UseMiddleware<SafetyShopHostMiddleware>() // 安全停机中间件
 | 
			
		||||
@@ -52,7 +54,9 @@ namespace NetAdmin.AdmServer.Host
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///     配置服务容器
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        #pragma warning disable S2325
 | 
			
		||||
        public void ConfigureServices(IServiceCollection services)
 | 
			
		||||
            #pragma warning restore S2325
 | 
			
		||||
        {
 | 
			
		||||
            _ = services.AddConsoleFormatter() // 添加控制台日志模板
 | 
			
		||||
                        .AddAllOptions()       // 添加配置项
 | 
			
		||||
@@ -75,12 +79,18 @@ namespace NetAdmin.AdmServer.Host
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        #pragma warning disable ASA001
 | 
			
		||||
        public Task<int> Execute(CommandContext context, CommandLineArgs settings)
 | 
			
		||||
        public async Task<int> Execute(CommandContext context, CommandLineArgs settings)
 | 
			
		||||
            #pragma warning restore ASA001
 | 
			
		||||
        {
 | 
			
		||||
            Args = settings;
 | 
			
		||||
            _    = Serve.Run(RunOptions.Default.WithArgs(context.Remaining.Raw.ToArray()));
 | 
			
		||||
            return Task.FromResult(0);
 | 
			
		||||
            var webOpt = new WebApplicationOptions //
 | 
			
		||||
                         {
 | 
			
		||||
                             EnvironmentName = Environment.GetEnvironmentVariable("TEST_ENVIRONMENT").NullOrEmpty(null)
 | 
			
		||||
                           , Args            = context.Remaining.Raw.ToArray()
 | 
			
		||||
                         };
 | 
			
		||||
            Serve.BuildApplication(RunOptions.Default.ConfigureOptions(webOpt), null, out var startUrl, out var app);
 | 
			
		||||
            await app.RunAsync(startUrl).ConfigureAwait(false);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -4,6 +4,6 @@
 | 
			
		||||
        <ProjectReference Include="../NetAdmin.AdmServer.Host/NetAdmin.AdmServer.Host.csproj"/>
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
    <ItemGroup>
 | 
			
		||||
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0-release-24373-02"/>
 | 
			
		||||
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0"/>
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
@@ -33,7 +33,7 @@ public abstract class RepositoryService<TEntity, TPrimary, TLogger>(BasicReposit
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     导出实体
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    protected async Task<IActionResult> ExportAsync<TQuery, TExport>( //
 | 
			
		||||
    protected static async Task<IActionResult> ExportAsync<TQuery, TExport>( //
 | 
			
		||||
        Func<QueryReq<TQuery>, ISelectGrouping<TEntity, TEntity>> selector, QueryReq<TQuery> query, string fileName
 | 
			
		||||
      , Expression<Func<ISelectGroupingAggregate<TEntity, TEntity>, object>> listExp = null)
 | 
			
		||||
        where TQuery : DataAbstraction, new()
 | 
			
		||||
@@ -45,7 +45,7 @@ public abstract class RepositoryService<TEntity, TPrimary, TLogger>(BasicReposit
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     导出实体
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    protected async Task<IActionResult> ExportAsync<TQuery, TExport>( //
 | 
			
		||||
    protected static async Task<IActionResult> ExportAsync<TQuery, TExport>( //
 | 
			
		||||
        Func<QueryReq<TQuery>, ISelect<TEntity>> selector, QueryReq<TQuery> query, string fileName
 | 
			
		||||
      , Expression<Func<TEntity, object>>        listExp = null)
 | 
			
		||||
        where TQuery : DataAbstraction, new()
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,21 @@ public abstract record MutableEntity : MutableEntity<long>
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     可变实体
 | 
			
		||||
/// </summary>
 | 
			
		||||
public abstract record MutableEntity<T> : LiteMutableEntity<T>, IFieldModifiedUser
 | 
			
		||||
public abstract record MutableEntity<T> : LiteMutableEntity<T>, IFieldCreatedUser, IFieldModifiedUser
 | 
			
		||||
    where T : IEquatable<T>
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Column(CanUpdate = false, Position = -1)]
 | 
			
		||||
    [CsvIgnore]
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public virtual long? CreatedUserId { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31, CanUpdate = false, Position = -1)]
 | 
			
		||||
    [CsvIgnore]
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public virtual string CreatedUserName { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc cref="EntityBase{T}.Id" />
 | 
			
		||||
    [Column(IsIdentity = false, IsPrimary = true, Position = 1)]
 | 
			
		||||
    [CsvIgnore]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								src/backend/NetAdmin.Domain/Dto/Sys/Cache/DelEntryReq.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/backend/NetAdmin.Domain/Dto/Sys/Cache/DelEntryReq.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
namespace NetAdmin.Domain.Dto.Sys.Cache;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     请求:删除缓存项
 | 
			
		||||
/// </summary>
 | 
			
		||||
public sealed record DelEntryReq : DataAbstraction
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     缓存键
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.缓存键不能为空))]
 | 
			
		||||
    public string Key { get; init; }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/backend/NetAdmin.Domain/Dto/Sys/Tool/ExecuteSqlReq.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/backend/NetAdmin.Domain/Dto/Sys/Tool/ExecuteSqlReq.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
namespace NetAdmin.Domain.Dto.Sys.Tool;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     请求:执行SQL
 | 
			
		||||
/// </summary>
 | 
			
		||||
public record ExecuteSqlReq : DataAbstraction
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     SQL 语句
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string Sql { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     超时时间(秒)
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public int TimeoutSecs { get; init; }
 | 
			
		||||
}
 | 
			
		||||
@@ -10,6 +10,23 @@ namespace NetAdmin.Host.Controllers;
 | 
			
		||||
[ApiDescriptionSettings("Probe")]
 | 
			
		||||
public sealed class ProbeController : ControllerBase<ICache<IDistributedCache, IService>, IService>
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     退出程序
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [AllowAnonymous]
 | 
			
		||||
    [HttpGet]
 | 
			
		||||
    #pragma warning disable CA1822
 | 
			
		||||
    public ActionResult Exit(string token)
 | 
			
		||||
        #pragma warning restore CA1822
 | 
			
		||||
    {
 | 
			
		||||
        if (token != GlobalStatic.SecretKey) {
 | 
			
		||||
            return new UnauthorizedResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Environment.Exit(0);
 | 
			
		||||
        return new OkResult();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     健康检查
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -23,6 +40,46 @@ public sealed class ProbeController : ControllerBase<ICache<IDistributedCache, I
 | 
			
		||||
                       HostName           = Environment.MachineName
 | 
			
		||||
                     , CurrentConnections = SafetyShopHostMiddleware.Connections
 | 
			
		||||
                     , GlobalStatic.ProductVersion
 | 
			
		||||
                     , ThreadCounts = GlobalStatic.CurrentProcess.Threads.Count
 | 
			
		||||
                     , GlobalStatic.LatestLogTime
 | 
			
		||||
                   };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     系统是否已经安全停止
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [AllowAnonymous]
 | 
			
		||||
    [HttpGet]
 | 
			
		||||
    [NonUnify]
 | 
			
		||||
    #pragma warning disable CA1822, S3400
 | 
			
		||||
    public IActionResult IsSystemSafetyStopped(int logTimeoutSeconds = 15)
 | 
			
		||||
        #pragma warning restore S3400, CA1822
 | 
			
		||||
    {
 | 
			
		||||
        return new ContentResult {
 | 
			
		||||
                                     Content = (DateTime.Now - GlobalStatic.LatestLogTime).TotalSeconds >
 | 
			
		||||
                                               logTimeoutSeconds
 | 
			
		||||
                                         ? "1"
 | 
			
		||||
                                         : "0"
 | 
			
		||||
                                 };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     实例下线
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    ///     流量只出不进
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    [AllowAnonymous]
 | 
			
		||||
    [HttpGet]
 | 
			
		||||
    #pragma warning disable CA1822
 | 
			
		||||
    public ActionResult Offline(string token)
 | 
			
		||||
        #pragma warning restore CA1822
 | 
			
		||||
    {
 | 
			
		||||
        if (token != GlobalStatic.SecretKey) {
 | 
			
		||||
            return new UnauthorizedResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SafetyShopHostMiddleware.Stop();
 | 
			
		||||
        return new OkResult();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								src/backend/NetAdmin.Host/Extensions/MethodInfoExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/backend/NetAdmin.Host/Extensions/MethodInfoExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
namespace NetAdmin.Host.Extensions;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     Type 扩展方法
 | 
			
		||||
/// </summary>
 | 
			
		||||
public static class MethodInfoExtensions
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     获取路由路径
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static string GetRoutePath(this MethodInfo me, IServiceProvider serviceProvider)
 | 
			
		||||
    {
 | 
			
		||||
        return serviceProvider.GetService<IActionDescriptorCollectionProvider>()
 | 
			
		||||
                              .ActionDescriptors.Items.FirstOrDefault(x => x.DisplayName!.StartsWith( //
 | 
			
		||||
                                                                          $"{me.DeclaringType}.{me.Name}"
 | 
			
		||||
                                                                        , StringComparison.Ordinal))
 | 
			
		||||
                              ?.AttributeRouteInfo?.Template;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -108,22 +108,20 @@ public static class ServiceCollectionExtensions
 | 
			
		||||
        return me.AddConsoleFormatter(options => {
 | 
			
		||||
            var logLevels = Enum.GetValues<LogLevels>().ToDictionary(x => x, x => x.GetDisplay());
 | 
			
		||||
 | 
			
		||||
            #if DEBUG
 | 
			
		||||
            options.WriteHandler = (message, _, _, _, _) => {
 | 
			
		||||
                #if DEBUG
 | 
			
		||||
                MarkupLine(message.Message.EscapeMarkup(), message, logLevels);
 | 
			
		||||
                if (message.Exception != null) {
 | 
			
		||||
                    MarkupLine(message.Exception.ToString().EscapeMarkup(), message, logLevels);
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            #else
 | 
			
		||||
            options.WriteHandler = (message, _, _, _, _) => {
 | 
			
		||||
                #else
 | 
			
		||||
                var msg = message.Message.ReplaceLineEndings(string.Empty);
 | 
			
		||||
                var (date, logName, logFormat) = ParseMessage(message, false);
 | 
			
		||||
                Console.WriteLine( //
 | 
			
		||||
                    logFormat, date, logLevels[(LogLevels)message.LogLevel].ShortName, logName, message.ThreadId, msg);
 | 
			
		||||
                #endif
 | 
			
		||||
                GlobalStatic.IncrementLogCounter();
 | 
			
		||||
            };
 | 
			
		||||
            #endif
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ public sealed class DefaultApiResultHandler : ApiResultHandler<RestfulInfo<objec
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public IActionResult OnAuthorizeException(DefaultHttpContext context, ExceptionMetadata metadata)
 | 
			
		||||
    {
 | 
			
		||||
        throw new NotImplementedException();
 | 
			
		||||
        LogHelper.Get<DefaultApiResultHandler>().Error(metadata.Exception);
 | 
			
		||||
        throw metadata.Exception;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -9,36 +9,64 @@ namespace NetAdmin.Host.Middlewares;
 | 
			
		||||
public sealed class SafetyShopHostMiddleware(RequestDelegate next)
 | 
			
		||||
{
 | 
			
		||||
    private static long _connections;
 | 
			
		||||
    private static bool _hostStopping;
 | 
			
		||||
    private static bool _trafficOff;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     当前连接数
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static long Connections => Interlocked.Read(ref _connections);
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     是否已停机
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static bool IsShutdown => Volatile.Read(ref _trafficOff);
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     停机处理
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static void OnStopping()
 | 
			
		||||
    {
 | 
			
		||||
        Volatile.Write(ref _hostStopping, true);
 | 
			
		||||
        Stop();
 | 
			
		||||
        while (Interlocked.Read(ref _connections) > 0) {
 | 
			
		||||
            Thread.Sleep(10);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     系统启机
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static void Start()
 | 
			
		||||
    {
 | 
			
		||||
        Volatile.Write(ref _trafficOff, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     系统停机
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static void Stop()
 | 
			
		||||
    {
 | 
			
		||||
        Volatile.Write(ref _trafficOff, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     主函数
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public async Task InvokeAsync(HttpContext context)
 | 
			
		||||
    {
 | 
			
		||||
        if (Volatile.Read(ref _hostStopping)) {
 | 
			
		||||
        if (Volatile.Read(ref _trafficOff) &&
 | 
			
		||||
            !context.Request.Path.StartsWithSegments($"/{Chars.FLG_PATH_API_RPOBE}")) {
 | 
			
		||||
            context.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _ = Interlocked.Increment(ref _connections);
 | 
			
		||||
        await next(context).ConfigureAwait(false);
 | 
			
		||||
        _ = Interlocked.Decrement(ref _connections);
 | 
			
		||||
        // webSocket链接不参与计算
 | 
			
		||||
        if (context.Request.Path.StartsWithSegments($"/{Chars.FLG_PATH_WEBSOCKET_PREFIX}")) {
 | 
			
		||||
            await next(context).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            _ = Interlocked.Increment(ref _connections);
 | 
			
		||||
            await next(context).ConfigureAwait(false);
 | 
			
		||||
            _ = Interlocked.Decrement(ref _connections);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -73,12 +73,15 @@ public static class Chars
 | 
			
		||||
    public const string FLG_HTTP_METHOD_POST                           = "POST";
 | 
			
		||||
    public const string FLG_HTTP_METHOD_PUT                            = "PUT";
 | 
			
		||||
    public const string FLG_HTTP_METHOD_TRACE                          = "TRACE";
 | 
			
		||||
    public const string FLG_PATH_API_SYS_USER_LOGIN_BY_PWD             = "api/sys/user/login.by.pwd";
 | 
			
		||||
    public const string FLG_PATH_PREFIX_HEALTH_CHECK                   = "probe/health.check";
 | 
			
		||||
    public const string FLG_RANDOM_UNAME_PWD                           = "VcXlp7WY";
 | 
			
		||||
    public const string FLG_REDIS_INSTANCE_DATA_CACHE                  = "DataCache";
 | 
			
		||||
    public const string FLG_SNOWFLAKE_WORK_ID                          = "SNOWFLAKE_WORK_ID";
 | 
			
		||||
    public const string FLG_SYSTEM_PREFIX                              = "sc_";
 | 
			
		||||
 | 
			
		||||
    public const string FLG_PATH_API_RPOBE                 = "api/probe";
 | 
			
		||||
    public const string FLG_PATH_API_SYS_USER_LOGIN_BY_PWD = "api/sys/user/login.by.pwd";
 | 
			
		||||
    public const string FLG_PATH_PREFIX_HEALTH_CHECK       = "probe/health.check";
 | 
			
		||||
    public const string FLG_PATH_WEBSOCKET_PREFIX          = "ws";
 | 
			
		||||
    public const string FLG_RANDOM_UNAME_PWD               = "VcXlp7WY";
 | 
			
		||||
    public const string FLG_REDIS_INSTANCE_DATA_CACHE      = "DataCache";
 | 
			
		||||
    public const string FLG_SNOWFLAKE_WORK_ID              = "SNOWFLAKE_WORK_ID";
 | 
			
		||||
    public const string FLG_SYSTEM_PREFIX                  = "sc_";
 | 
			
		||||
 | 
			
		||||
    public const string FLGL_HTTP_HEADER_VALUE_UA_MOBILE
 | 
			
		||||
        = "Mozilla/5.0 (Linux; Android 9; Redmi Note 8 Pro Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.96 Mobile Safari/537.36";
 | 
			
		||||
 
 | 
			
		||||
@@ -7,12 +7,19 @@ namespace NetAdmin.Infrastructure;
 | 
			
		||||
/// </summary>
 | 
			
		||||
public static class GlobalStatic
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     当前进程
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static readonly Process CurrentProcess = Process.GetCurrentProcess();
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     产品版本
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static readonly string ProductVersion
 | 
			
		||||
        = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly()!.Location).ProductVersion;
 | 
			
		||||
 | 
			
		||||
    private static long _latestLogTime;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     调试模式
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -24,10 +31,17 @@ public static class GlobalStatic
 | 
			
		||||
    #endif
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     最后一次日志时间
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static DateTime LatestLogTime => Volatile.Read(ref _latestLogTime).Time();
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     日志记录器忽略的API编号
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static string[] LoggerIgnoreApiIds => [];
 | 
			
		||||
    public static string[] LoggerIgnoreApiIds => [
 | 
			
		||||
        "api/adm/tools/query.es.log", "api/probe/health.check", "api/probe/is.system.safety.stopped"
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     系统内部密钥
 | 
			
		||||
@@ -73,4 +87,12 @@ public static class GlobalStatic
 | 
			
		||||
    ///     Json序列化选项
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static JsonSerializerOptions JsonSerializerOptions { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     增加日志计数器
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static void IncrementLogCounter()
 | 
			
		||||
    {
 | 
			
		||||
        Volatile.Write(ref _latestLogTime, DateTime.Now.TimeUnixUtcMs());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,13 +6,13 @@
 | 
			
		||||
    <Import Project="$(SolutionDir)/build/copy.pkg.xml.comment.files.targets"/>
 | 
			
		||||
    <Import Project="$(SolutionDir)/build/prebuild.targets"/>
 | 
			
		||||
    <ItemGroup>
 | 
			
		||||
        <PackageReference Include="FreeSql.DbContext.NS" Version="3.2.833-preview20260627-ns1"/>
 | 
			
		||||
        <PackageReference Include="FreeSql.Provider.Sqlite.NS" Version="3.2.833-preview20260627-ns1"/>
 | 
			
		||||
        <PackageReference Include="FreeSql.DbContext.NS" Version="3.2.833-ns4"/>
 | 
			
		||||
        <PackageReference Include="FreeSql.Provider.Sqlite.NS" Version="3.2.833-ns4"/>
 | 
			
		||||
        <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.5.2"/>
 | 
			
		||||
        <PackageReference Include="Furion.Extras.ObjectMapper.Mapster.NS" Version="4.9.5.2-ns1"/>
 | 
			
		||||
        <PackageReference Include="Furion.Pure.NS" Version="4.9.5.2-ns1"/>
 | 
			
		||||
        <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.10.0"/>
 | 
			
		||||
        <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0-preview.6.24328.4"/>
 | 
			
		||||
        <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0-preview.7.24406.2"/>
 | 
			
		||||
        <PackageReference Include="Minio" Version="6.0.3"/>
 | 
			
		||||
        <PackageReference Include="NSExt" Version="2.2.0"/>
 | 
			
		||||
        <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.4"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,6 @@ public sealed class FreeSqlBuilder(DatabaseOptions databaseOptions)
 | 
			
		||||
                                                  .UseAutoSyncStructure(
 | 
			
		||||
                                                      initMethods.HasFlag(FreeSqlInitMethods.SyncStructure))
 | 
			
		||||
                                                  .Build();
 | 
			
		||||
 | 
			
		||||
        _ = InitDbAsync(freeSql, initMethods); // 初始化数据库 ,异步
 | 
			
		||||
        return freeSql;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Cache;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
@@ -7,11 +8,21 @@ namespace NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
/// </summary>
 | 
			
		||||
public interface ICacheModule
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     批量删除缓存项
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    Task<int> BulkDeleteEntryAsync(BulkReq<DelEntryReq> req);
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     缓存统计
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    Task<CacheStatisticsRsp> CacheStatisticsAsync();
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     删除缓存项
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    Task<int> DeleteEntryAsync(DelEntryReq req);
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     获取所有缓存项
 | 
			
		||||
    /// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,11 @@ namespace NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
/// </summary>
 | 
			
		||||
public interface IToolsModule
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     执行SQL语句
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    Task<object[][]> ExecuteSqlAsync(ExecuteSqlReq req);
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     获取更新日志
 | 
			
		||||
    /// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using NetAdmin.Application.Services;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Cache;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
 | 
			
		||||
using StackExchange.Redis;
 | 
			
		||||
@@ -21,6 +22,20 @@ public sealed class CacheService(IConnectionMultiplexer connectionMultiplexer) /
 | 
			
		||||
        _redisInstance = redisOptions.Value.Instances.First(x => x.Name == Chars.FLG_REDIS_INSTANCE_DATA_CACHE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public async Task<int> BulkDeleteEntryAsync(BulkReq<DelEntryReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = 0;
 | 
			
		||||
 | 
			
		||||
        // ReSharper disable once LoopCanBeConvertedToQuery
 | 
			
		||||
        foreach (var item in req.Items) {
 | 
			
		||||
            ret += await DeleteEntryAsync(item).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public async Task<CacheStatisticsRsp> CacheStatisticsAsync()
 | 
			
		||||
    {
 | 
			
		||||
@@ -30,6 +45,16 @@ public sealed class CacheService(IConnectionMultiplexer connectionMultiplexer) /
 | 
			
		||||
               };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public async Task<int> DeleteEntryAsync(DelEntryReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        #pragma warning disable VSTHRD103
 | 
			
		||||
        var database   = connectionMultiplexer.GetDatabase(_redisInstance.Database);
 | 
			
		||||
        var delSuccess = await database.KeyDeleteAsync(req.Key).ConfigureAwait(false);
 | 
			
		||||
        return delSuccess ? 1 : 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public async Task<IEnumerable<GetEntryRsp>> GetAllEntriesAsync(GetAllEntriesReq req)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -84,7 +84,9 @@ public sealed class ConfigService(BasicRepository<Sys_Config, long> rpo) //
 | 
			
		||||
    public async Task<QueryConfigRsp> GetAsync(QueryConfigReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryConfigReq> { Filter = req }).ToOneAsync().ConfigureAwait(false);
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryConfigReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryConfigRsp>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -102,7 +102,9 @@ public sealed class DeptService(BasicRepository<Sys_Dept, long> rpo) //
 | 
			
		||||
    public async Task<QueryDeptRsp> GetAsync(QueryDeptReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryDeptReq> { Filter = req }).ToOneAsync().ConfigureAwait(false);
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryDeptReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryDeptRsp>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -89,7 +89,7 @@ public sealed class DicCatalogService(BasicRepository<Sys_DicCatalog, long> rpo)
 | 
			
		||||
    public async Task<QueryDicCatalogRsp> GetAsync(QueryDicCatalogReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryDicCatalogReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryDicCatalogReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryDicCatalogRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -104,7 +104,7 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
 | 
			
		||||
    public async Task<QueryDicContentRsp> GetAsync(QueryDicContentReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryDicContentReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryDicContentReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryDicContentRsp>();
 | 
			
		||||
@@ -145,6 +145,9 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
 | 
			
		||||
    public async Task<List<QueryDicContentRsp>> QueryByCatalogCodeAsync(string catalogCode)
 | 
			
		||||
    {
 | 
			
		||||
        var ret = await Rpo.Orm.Select<Sys_DicContent>()
 | 
			
		||||
                           #if DBTYPE_SQLSERVER
 | 
			
		||||
                           .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
 | 
			
		||||
                           #endif
 | 
			
		||||
                           .Include(a => a.Catalog)
 | 
			
		||||
                           .Where(a => a.Catalog.Code == catalogCode)
 | 
			
		||||
                           .ToListAsync()
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ public sealed class JobRecordService(BasicRepository<Sys_JobRecord, long> rpo) /
 | 
			
		||||
    public async Task<QueryJobRecordRsp> GetAsync(QueryJobRecordReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryJobRecordReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryJobRecordReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryJobRecordRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -112,9 +112,11 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
 | 
			
		||||
                                                                     }
 | 
			
		||||
                                           ]
 | 
			
		||||
                                       };
 | 
			
		||||
        var job = await QueryInternal(new QueryReq<QueryJobReq> { Count = 1, Filter = req, DynamicFilter = df })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false) ?? throw new NetAdminInvalidOperationException(Ln.未获取到待执行任务);
 | 
			
		||||
        var job
 | 
			
		||||
            = await QueryInternal(
 | 
			
		||||
                        new QueryReq<QueryJobReq> { Count = 1, Filter = req, DynamicFilter = df, Order = Orders.None })
 | 
			
		||||
                    .ToOneAsync()
 | 
			
		||||
                    .ConfigureAwait(false) ?? throw new NetAdminInvalidOperationException(Ln.未获取到待执行任务);
 | 
			
		||||
 | 
			
		||||
        var nextExecTime = GetNextExecTime(Chars.FLG_CRON_PER_SECS);
 | 
			
		||||
        try {
 | 
			
		||||
@@ -175,7 +177,9 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
 | 
			
		||||
    public async Task<QueryJobRsp> GetAsync(QueryJobReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryJobReq> { Filter = req }).ToOneAsync().ConfigureAwait(false);
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryJobReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryJobRsp>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -201,13 +205,26 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
 | 
			
		||||
                                                                     }
 | 
			
		||||
                                           ]
 | 
			
		||||
                                       };
 | 
			
		||||
        var job = await QueryInternal(new QueryReq<QueryJobReq> { DynamicFilter = df, Order = Orders.Random })
 | 
			
		||||
                        .Take(1)
 | 
			
		||||
        var job = await QueryInternal(new QueryReq<QueryJobReq> { DynamicFilter = df, Order = Orders.Random }, false)
 | 
			
		||||
                        #if DBTYPE_SQLSERVER
 | 
			
		||||
                        .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
 | 
			
		||||
                        #endif
 | 
			
		||||
                        .Where(a => !Rpo.Orm.Select<Sys_JobRecord>()
 | 
			
		||||
                                        .As("b")
 | 
			
		||||
                                        .Where(b => b.JobId == a.Id && b.TimeId == a.NextTimeId)
 | 
			
		||||
                                        .Any())
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ToOneAsync(a => new {
 | 
			
		||||
                                                 a.RequestUrl
 | 
			
		||||
                                               , a.HttpMethod
 | 
			
		||||
                                               , a.RequestHeader
 | 
			
		||||
                                               , a.RequestBody
 | 
			
		||||
                                               , a.RandomDelayBegin
 | 
			
		||||
                                               , a.RandomDelayEnd
 | 
			
		||||
                                               , a.UserId
 | 
			
		||||
                                               , a.Id
 | 
			
		||||
                                               , a.NextTimeId
 | 
			
		||||
                                               , a.Version
 | 
			
		||||
                                             })
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        if (job == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
@@ -215,15 +232,15 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
 | 
			
		||||
 | 
			
		||||
        #if DBTYPE_SQLSERVER
 | 
			
		||||
        var ret = await UpdateReturnListAsync( //
 | 
			
		||||
                job with { Status = JobStatues.Running, LastExecTime = DateTime.Now }
 | 
			
		||||
              , [nameof(job.Status), nameof(job.LastExecTime)])
 | 
			
		||||
                job.Adapt<Sys_Job>() with { Status = JobStatues.Running, LastExecTime = DateTime.Now }
 | 
			
		||||
              , [nameof(Sys_Job.Status), nameof(Sys_Job.LastExecTime)])
 | 
			
		||||
            .ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
        return ret.FirstOrDefault()?.Adapt<QueryJobRsp>();
 | 
			
		||||
        #else
 | 
			
		||||
        return await UpdateAsync( //
 | 
			
		||||
                job with { Status = JobStatues.Running, LastExecTime = DateTime.Now }
 | 
			
		||||
              , [nameof(job.Status), nameof(job.LastExecTime)])
 | 
			
		||||
                job.Adapt<Sys_Job>() with { Status = JobStatues.Running, LastExecTime = DateTime.Now }
 | 
			
		||||
              , [nameof(Sys_Job.Status), nameof(Sys_Job.LastExecTime)])
 | 
			
		||||
            .ConfigureAwait(false) > 0
 | 
			
		||||
            ? await GetAsync(new QueryJobReq { Id = job.Id }).ConfigureAwait(false)
 | 
			
		||||
            : null;
 | 
			
		||||
@@ -330,12 +347,21 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
 | 
			
		||||
 | 
			
		||||
    private ISelect<Sys_Job> QueryInternal(QueryReq<QueryJobReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var ret = Rpo.Select.Include(a => a.User)
 | 
			
		||||
                     .WhereDynamicFilter(req.DynamicFilter)
 | 
			
		||||
                     .WhereDynamic(req.Filter)
 | 
			
		||||
                     .WhereIf( //
 | 
			
		||||
                         req.Keywords?.Length > 0
 | 
			
		||||
                       , a => a.Id == req.Keywords.Int64Try(0) || a.JobName.Contains(req.Keywords));
 | 
			
		||||
        return QueryInternal(req, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ISelect<Sys_Job> QueryInternal(QueryReq<QueryJobReq> req, bool includeUser)
 | 
			
		||||
    {
 | 
			
		||||
        var ret = Rpo.Select;
 | 
			
		||||
        if (includeUser) {
 | 
			
		||||
            ret = ret.Include(a => a.User);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ret = ret.WhereDynamicFilter(req.DynamicFilter)
 | 
			
		||||
                 .WhereDynamic(req.Filter)
 | 
			
		||||
                 .WhereIf( //
 | 
			
		||||
                     req.Keywords?.Length > 0
 | 
			
		||||
                   , a => a.Id == req.Keywords.Int64Try(0) || a.JobName.Contains(req.Keywords));
 | 
			
		||||
 | 
			
		||||
        // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
 | 
			
		||||
        switch (req.Order) {
 | 
			
		||||
 
 | 
			
		||||
@@ -72,7 +72,7 @@ public sealed class LoginLogService(BasicRepository<Sys_LoginLog, long> rpo) //
 | 
			
		||||
    public async Task<QueryLoginLogRsp> GetAsync(QueryLoginLogReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryLoginLogReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryLoginLogReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryLoginLogRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,9 @@ public sealed class MenuService(BasicRepository<Sys_Menu, long> rpo, IUserServic
 | 
			
		||||
    public async Task<QueryMenuRsp> GetAsync(QueryMenuReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryMenuReq> { Filter = req }).ToOneAsync().ConfigureAwait(false);
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryMenuReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryMenuRsp>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ public sealed class RequestLogDetailService(BasicRepository<Sys_RequestLogDetail
 | 
			
		||||
    public async Task<QueryRequestLogDetailRsp> GetAsync(QueryRequestLogDetailReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryRequestLogDetailReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryRequestLogDetailReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryRequestLogDetailRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -99,7 +99,8 @@ public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo,
 | 
			
		||||
                                                         }.Json()
 | 
			
		||||
                                                          .Object<JsonElement>()
 | 
			
		||||
                                       };
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryRequestLogReq> { Filter = req, DynamicFilter = df })
 | 
			
		||||
        var ret = await QueryInternal(
 | 
			
		||||
                            new QueryReq<QueryRequestLogReq> { Filter = req, DynamicFilter = df, Order = Orders.None })
 | 
			
		||||
                        .Include(a => a.Detail)
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
 
 | 
			
		||||
@@ -96,7 +96,9 @@ public sealed class RoleService(BasicRepository<Sys_Role, long> rpo) //
 | 
			
		||||
    public async Task<QueryRoleRsp> GetAsync(QueryRoleReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryRoleReq> { Filter = req }).ToOneAsync().ConfigureAwait(false);
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryRoleReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryRoleRsp>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ public sealed class SiteMsgDeptService(BasicRepository<Sys_SiteMsgDept, long> rp
 | 
			
		||||
    public async Task<QuerySiteMsgDeptRsp> GetAsync(QuerySiteMsgDeptReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QuerySiteMsgDeptReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QuerySiteMsgDeptReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QuerySiteMsgDeptRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ public sealed class SiteMsgFlagService(BasicRepository<Sys_SiteMsgFlag, long> rp
 | 
			
		||||
    public async Task<QuerySiteMsgFlagRsp> GetAsync(QuerySiteMsgFlagReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QuerySiteMsgFlagReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QuerySiteMsgFlagReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QuerySiteMsgFlagRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ public sealed class SiteMsgRoleService(BasicRepository<Sys_SiteMsgRole, long> rp
 | 
			
		||||
    public async Task<QuerySiteMsgRoleRsp> GetAsync(QuerySiteMsgRoleReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QuerySiteMsgRoleReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QuerySiteMsgRoleReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QuerySiteMsgRoleRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -120,7 +120,7 @@ public sealed class SiteMsgService(
 | 
			
		||||
    public async Task<QuerySiteMsgRsp> GetAsync(QuerySiteMsgReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QuerySiteMsgReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QuerySiteMsgReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .IncludeMany(a => a.Roles)
 | 
			
		||||
                        .IncludeMany(a => a.Users)
 | 
			
		||||
                        .IncludeMany(a => a.Depts)
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ public sealed class SiteMsgUserService(BasicRepository<Sys_SiteMsgUser, long> rp
 | 
			
		||||
    public async Task<QuerySiteMsgUserRsp> GetAsync(QuerySiteMsgUserReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QuerySiteMsgUserReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QuerySiteMsgUserReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QuerySiteMsgUserRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,15 @@ namespace NetAdmin.SysComponent.Application.Services.Sys;
 | 
			
		||||
/// <inheritdoc cref="IToolsService" />
 | 
			
		||||
public sealed class ToolsService : ServiceBase<IToolsService>, IToolsService
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public Task<object[][]> ExecuteSqlAsync(ExecuteSqlReq req)
 | 
			
		||||
    {
 | 
			
		||||
        return App.GetService<IFreeSql>()
 | 
			
		||||
                  .Ado.CommandFluent(req.Sql)
 | 
			
		||||
                  .CommandTimeout(req.TimeoutSecs)
 | 
			
		||||
                  .ExecuteArrayAsync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public async Task<string> GetChangeLogAsync()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -100,7 +100,7 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
 | 
			
		||||
    public async Task<QueryUserProfileRsp> GetAsync(QueryUserProfileReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryUserProfileReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryUserProfileReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryUserProfileRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -172,9 +172,9 @@ public sealed class UserService(
 | 
			
		||||
    public async Task<QueryUserRsp> GetAsync(QueryUserReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await (await QueryInternalAsync(new QueryReq<QueryUserReq> { Filter = req }).ConfigureAwait(false))
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        var ret = await (await QueryInternalAsync(new QueryReq<QueryUserReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                .ConfigureAwait(false)).ToOneAsync()
 | 
			
		||||
                                       .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryUserRsp>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -433,14 +433,51 @@ public sealed class UserService(
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public async Task<UserInfoRsp> UserInfoAsync()
 | 
			
		||||
    {
 | 
			
		||||
        static void OtherIncludes(ISelect<Sys_Role> select)
 | 
			
		||||
        {
 | 
			
		||||
            select.Where(a => a.Enabled)
 | 
			
		||||
                  #if DBTYPE_SQLSERVER
 | 
			
		||||
                  .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
 | 
			
		||||
                  #endif
 | 
			
		||||
                  .IncludeMany( //
 | 
			
		||||
                      a => a.Menus
 | 
			
		||||
                      #if DBTYPE_SQLSERVER
 | 
			
		||||
                      #pragma warning disable SA1115
 | 
			
		||||
                    , then => then.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
 | 
			
		||||
                      #pragma warning restore SA1115
 | 
			
		||||
                      #endif
 | 
			
		||||
                      #pragma warning disable SA1009, SA1111
 | 
			
		||||
                  )
 | 
			
		||||
                  #pragma warning restore SA1111, SA1009
 | 
			
		||||
                  .IncludeMany( //
 | 
			
		||||
                      a => a.Depts
 | 
			
		||||
                      #if DBTYPE_SQLSERVER
 | 
			
		||||
                      #pragma warning disable SA1115
 | 
			
		||||
                    , then => then.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
 | 
			
		||||
                      #pragma warning restore SA1115
 | 
			
		||||
                      #endif
 | 
			
		||||
                      #pragma warning disable SA1009, SA1111
 | 
			
		||||
                  )
 | 
			
		||||
                  #pragma warning restore SA1111, SA1009
 | 
			
		||||
                  .IncludeMany( //
 | 
			
		||||
                      a => a.Apis
 | 
			
		||||
                      #if DBTYPE_SQLSERVER
 | 
			
		||||
                      #pragma warning disable SA1115
 | 
			
		||||
                    , then => then.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
 | 
			
		||||
                      #pragma warning restore SA1115
 | 
			
		||||
                      #endif
 | 
			
		||||
                      #pragma warning disable SA1009, SA1111
 | 
			
		||||
                  )
 | 
			
		||||
                #pragma warning restore SA1111, SA1009
 | 
			
		||||
                ;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var dbUser = await Rpo.Where(a => a.Token == UserToken.Token && a.Enabled)
 | 
			
		||||
                              #if DBTYPE_SQLSERVER
 | 
			
		||||
                              .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
 | 
			
		||||
                              #endif
 | 
			
		||||
                              .Include(a => a.Dept)
 | 
			
		||||
                              .IncludeMany( //
 | 
			
		||||
                                  a => a.Roles
 | 
			
		||||
                                , then => then.Where(a => a.Enabled)
 | 
			
		||||
                                              .IncludeMany(a => a.Menus)
 | 
			
		||||
                                              .IncludeMany(a => a.Depts)
 | 
			
		||||
                                              .IncludeMany(a => a.Apis))
 | 
			
		||||
                              .IncludeMany(a => a.Roles, OtherIncludes)
 | 
			
		||||
                              .ToOneAsync()
 | 
			
		||||
                              .ConfigureAwait(false);
 | 
			
		||||
        return dbUser.Adapt<UserInfoRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
 | 
			
		||||
    public async Task<QueryVerifyCodeRsp> GetAsync(QueryVerifyCodeReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryVerifyCodeReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryVerifyCodeReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryVerifyCodeRsp>();
 | 
			
		||||
@@ -188,11 +188,10 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
 | 
			
		||||
                                                                          , Value    = destDevice
 | 
			
		||||
                                                                        }
 | 
			
		||||
                                                              })
 | 
			
		||||
               #if DBTYPE_SQLSERVER
 | 
			
		||||
            #if DBTYPE_SQLSERVER
 | 
			
		||||
               .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
 | 
			
		||||
               #endif
 | 
			
		||||
               .Take(1)
 | 
			
		||||
               .ToOneAsync();
 | 
			
		||||
            #endif
 | 
			
		||||
            .ToOneAsync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ISelect<Sys_VerifyCode> QueryInternal(QueryReq<QueryVerifyCodeReq> req)
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ public sealed class ExampleService(BasicRepository<Tpl_Example, long> rpo) //
 | 
			
		||||
    public async Task<QueryExampleRsp> GetAsync(QueryExampleReq req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryExampleReq> { Filter = req })
 | 
			
		||||
        var ret = await QueryInternal(new QueryReq<QueryExampleReq> { Filter = req, Order = Orders.None })
 | 
			
		||||
                        .ToOneAsync()
 | 
			
		||||
                        .ConfigureAwait(false);
 | 
			
		||||
        return ret.Adapt<QueryExampleRsp>();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
using NetAdmin.Cache;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Cache;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
 | 
			
		||||
using NetAdmin.SysComponent.Cache.Sys.Dependency;
 | 
			
		||||
@@ -9,6 +10,12 @@ namespace NetAdmin.SysComponent.Cache.Sys;
 | 
			
		||||
public sealed class CacheCache(IDistributedCache cache, ICacheService service) //
 | 
			
		||||
    : DistributedCache<ICacheService>(cache, service), IScoped, ICacheCache
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public Task<int> BulkDeleteEntryAsync(BulkReq<DelEntryReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        return Service.BulkDeleteEntryAsync(req);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public Task<CacheStatisticsRsp> CacheStatisticsAsync()
 | 
			
		||||
    {
 | 
			
		||||
@@ -20,6 +27,12 @@ public sealed class CacheCache(IDistributedCache cache, ICacheService service) /
 | 
			
		||||
        #endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public Task<int> DeleteEntryAsync(DelEntryReq req)
 | 
			
		||||
    {
 | 
			
		||||
        return Service.DeleteEntryAsync(req);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public Task<IEnumerable<GetEntryRsp>> GetAllEntriesAsync(GetAllEntriesReq req)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,12 @@ namespace NetAdmin.SysComponent.Cache.Sys;
 | 
			
		||||
public sealed class ToolsCache(IDistributedCache cache, IToolsService service) //
 | 
			
		||||
    : DistributedCache<IToolsService>(cache, service), IScoped, IToolsCache
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public Task<object[][]> ExecuteSqlAsync(ExecuteSqlReq req)
 | 
			
		||||
    {
 | 
			
		||||
        return Service.ExecuteSqlAsync(req);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public Task<string> GetChangeLogAsync()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Cache;
 | 
			
		||||
using NetAdmin.Host.Controllers;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
@@ -12,6 +13,14 @@ namespace NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
[ApiDescriptionSettings(nameof(Sys), Module = nameof(Sys))]
 | 
			
		||||
public sealed class CacheController(ICacheCache cache) : ControllerBase<ICacheCache, ICacheService>(cache), ICacheModule
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     批量删除缓存项
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public Task<int> BulkDeleteEntryAsync(BulkReq<DelEntryReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        return Cache.BulkDeleteEntryAsync(req);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     缓存统计
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -20,6 +29,14 @@ public sealed class CacheController(ICacheCache cache) : ControllerBase<ICacheCa
 | 
			
		||||
        return Cache.CacheStatisticsAsync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     删除缓存项
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public Task<int> DeleteEntryAsync(DelEntryReq req)
 | 
			
		||||
    {
 | 
			
		||||
        return Cache.DeleteEntryAsync(req);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     获取所有缓存项
 | 
			
		||||
    /// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,14 @@ namespace NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
[ApiDescriptionSettings(nameof(Sys), Module = nameof(Sys))]
 | 
			
		||||
public sealed class ToolsController(IToolsCache cache) : ControllerBase<IToolsCache, IToolsService>(cache), IToolsModule
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     执行SQL语句
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public Task<object[][]> ExecuteSqlAsync(ExecuteSqlReq req)
 | 
			
		||||
    {
 | 
			
		||||
        return Cache.ExecuteSqlAsync(req);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     获取更新日志
 | 
			
		||||
    /// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using Furion.Schedule;
 | 
			
		||||
using NetAdmin.Host.BackgroundRunning;
 | 
			
		||||
using NetAdmin.Host.Middlewares;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Host.Jobs;
 | 
			
		||||
@@ -27,6 +28,11 @@ public sealed class FreeScheduledJob : WorkBase<FreeScheduledJob>, IJob
 | 
			
		||||
    /// <exception cref="NetAdminGetLockerException">加锁失败异常</exception>
 | 
			
		||||
    public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
 | 
			
		||||
    {
 | 
			
		||||
        if (SafetyShopHostMiddleware.IsShutdown) {
 | 
			
		||||
            Console.WriteLine(Ln.此节点已下线);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await WorkflowAsync(true, stoppingToken).ConfigureAwait(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ using NetAdmin.Domain.Dto.Sys.Job;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.JobRecord;
 | 
			
		||||
using NetAdmin.Host.BackgroundRunning;
 | 
			
		||||
using NetAdmin.Host.Extensions;
 | 
			
		||||
using NetAdmin.Host.Middlewares;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Host.Jobs;
 | 
			
		||||
@@ -42,6 +43,11 @@ public sealed class ScheduledJob : WorkBase<ScheduledJob>, IJob
 | 
			
		||||
    /// <exception cref="NetAdminGetLockerException">加锁失败异常</exception>
 | 
			
		||||
    public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
 | 
			
		||||
    {
 | 
			
		||||
        if (SafetyShopHostMiddleware.IsShutdown) {
 | 
			
		||||
            Console.WriteLine(Ln.此节点已下线);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await WorkflowAsync(stoppingToken).ConfigureAwait(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,11 @@
 | 
			
		||||
using NetAdmin.Domain.Events.Sys;
 | 
			
		||||
#if !DEBUG
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.RequestLog;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
 | 
			
		||||
#endif
 | 
			
		||||
using NetAdmin.Domain.Events.Sys;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Host.Subscribers;
 | 
			
		||||
 | 
			
		||||
@@ -8,6 +14,10 @@ namespace NetAdmin.SysComponent.Host.Subscribers;
 | 
			
		||||
/// </summary>
 | 
			
		||||
public sealed class OperationLogger : IEventSubscriber
 | 
			
		||||
{
 | 
			
		||||
    #if !DEBUG
 | 
			
		||||
    private static readonly ConcurrentQueue<CreateRequestLogReq> _requestLogs = new();
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     保存请求日志到数据库
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -18,7 +28,47 @@ public sealed class OperationLogger : IEventSubscriber
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        operationEvent.Data.TruncateStrings();
 | 
			
		||||
        #if DEBUG
 | 
			
		||||
        _ = await App.GetService<IRequestLogService>().CreateAsync(operationEvent.Data).ConfigureAwait(false);
 | 
			
		||||
        #else
 | 
			
		||||
        if (_requestLogs.Count > Numbers.REQUEST_LOG_BUFF_SIZE) {
 | 
			
		||||
            await WriteToDbAsync().ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            _requestLogs.Enqueue(operationEvent.Data);
 | 
			
		||||
        }
 | 
			
		||||
        #endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #if !DEBUG
 | 
			
		||||
    private static async Task WriteToDbAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var inserts = new List<CreateRequestLogReq>(Numbers.REQUEST_LOG_BUFF_SIZE);
 | 
			
		||||
 | 
			
		||||
        // 批量入库
 | 
			
		||||
        for (var i = 0; i != Numbers.REQUEST_LOG_BUFF_SIZE; ++i) {
 | 
			
		||||
            if (!_requestLogs.TryDequeue(out var log)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            inserts.Add(log);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 如果首尾日期不一致,要分别插入不同的日期分表
 | 
			
		||||
        if (inserts[0].CreatedTime.Date != inserts[^1].CreatedTime.Date) {
 | 
			
		||||
            foreach (var dayInserts in inserts.GroupBy(x => x.CreatedTime.Date)) {
 | 
			
		||||
                await App.GetService<IFreeSql>()
 | 
			
		||||
                         .Insert<Sys_RequestLog>(dayInserts.Select(x => x))
 | 
			
		||||
                         .ExecuteSqlBulkCopyAsync(tableName: $"{nameof(Sys_RequestLog)}_{dayInserts.Key:yyyyMMdd}")
 | 
			
		||||
                         .ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            await App.GetService<IFreeSql>()
 | 
			
		||||
                     .Insert<Sys_RequestLog>(inserts)
 | 
			
		||||
                     .ExecuteSqlBulkCopyAsync(tableName: $"{nameof(Sys_RequestLog)}_{inserts[0].CreatedTime:yyyyMMdd}")
 | 
			
		||||
                     .ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #endif
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,8 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
    <ItemGroup>
 | 
			
		||||
        <ProjectReference Include="../NetAdmin.AdmServer.Tests/NetAdmin.AdmServer.Tests.csproj"/>
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
    <ItemGroup>
 | 
			
		||||
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0"/>
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										118
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/ApiTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/ApiTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Api;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     接口测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class ApiTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IApiModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QueryApiReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryApiRsp> CreateAsync(CreateApiReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QueryApiReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QueryApiReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryApiRsp> GetAsync(QueryApiReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryApiRsp>> PagedQueryAsync(PagedQueryReq<QueryApiReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryApiRsp>> QueryAsync(QueryReq<QueryApiReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task SyncAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/CacheTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/CacheTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Cache;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     缓存测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class CacheTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), ICacheModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteEntryAsync(BulkReq<DelEntryReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(CacheController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task<CacheStatisticsRsp> CacheStatisticsAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(CacheController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteEntryAsync(DelEntryReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(CacheController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<GetEntryRsp>> GetAllEntriesAsync(GetAllEntriesReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(CacheController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<GetEntryRsp> GetEntryAsync(GetEntriesReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(CacheController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/CaptchaTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/CaptchaTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Captcha;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     人机验证测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class CaptchaTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), ICaptchaModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task<GetCaptchaRsp> GetCaptchaImageAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(CaptchaController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> VerifyCaptchaAsync(VerifyCaptchaReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(CaptchaController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										139
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/ConfigTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/ConfigTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Config;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     配置测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class ConfigTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IConfigModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QueryConfigReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryConfigRsp> CreateAsync(CreateConfigReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryConfigRsp> EditAsync(EditConfigReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QueryConfigReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QueryConfigReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryConfigRsp> GetAsync(QueryConfigReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task<QueryConfigRsp> GetLatestConfigAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryConfigRsp>> PagedQueryAsync(PagedQueryReq<QueryConfigReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryConfigRsp>> QueryAsync(QueryReq<QueryConfigReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> SetEnabledAsync(SetConfigEnabledReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ConfigController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/ConstantTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/ConstantTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     常量测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1031:Do not use blocking task operations in test method")]
 | 
			
		||||
public class ConstantTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IConstantModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public IDictionary<string, string> GetCharsDic()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = PostJsonAsync(typeof(ConstantController)).GetAwaiter().GetResult();
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public IDictionary<string, Dictionary<string, string[]>> GetEnums()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = PostJsonAsync(typeof(ConstantController)).GetAwaiter().GetResult();
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public IDictionary<string, string> GetLocalizedStrings()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = PostJsonAsync(typeof(ConstantController)).GetAwaiter().GetResult();
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public IDictionary<string, long> GetNumbersDic()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = PostJsonAsync(typeof(ConstantController)).GetAwaiter().GetResult();
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										130
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/DeptTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/DeptTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Dept;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     部门测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class DeptTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IDeptModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QueryDeptReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryDeptRsp> CreateAsync(CreateDeptReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryDeptRsp> EditAsync(EditDeptReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QueryDeptReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QueryDeptReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryDeptRsp> GetAsync(QueryDeptReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryDeptRsp>> PagedQueryAsync(PagedQueryReq<QueryDeptReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryDeptRsp>> QueryAsync(QueryReq<QueryDeptReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> SetEnabledAsync(SetDeptEnabledReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DeptController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/DevTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/DevTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Dev;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     开发测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class DevTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IDevModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task GenerateCsCodeAsync(GenerateCsCodeReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DevController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task GenerateIconCodeAsync(GenerateIconCodeReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DevController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task GenerateJsCodeAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DevController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										181
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/DicTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/DicTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,181 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Dic.Catalog;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Dic.Content;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     字典测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class DicTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IDicModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteCatalogAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteContentAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryDicCatalogRsp> CreateCatalogAsync(CreateDicCatalogReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryDicContentRsp> CreateContentAsync(CreateDicContentReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteCatalogAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteContentAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> EditCatalogAsync(EditDicCatalogReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryDicContentRsp> EditContentAsync(EditDicContentReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportContentAsync(QueryReq<QueryDicContentReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryDicCatalogRsp> GetCatalogAsync(QueryDicCatalogReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryDicContentRsp> GetContentAsync(QueryDicContentReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<string> GetDicValueAsync(GetDicValueReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryDicCatalogRsp>> PagedQueryCatalogAsync(PagedQueryReq<QueryDicCatalogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryDicContentRsp>> PagedQueryContentAsync(PagedQueryReq<QueryDicContentReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryDicCatalogRsp>> QueryCatalogAsync(QueryReq<QueryDicCatalogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryDicContentRsp>> QueryContentAsync(QueryReq<QueryDicContentReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(DicController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/FileTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/FileTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     文件测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class FileTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IFileModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<string> UploadAsync(IFormFile file)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(FileController), file);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										212
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/JobTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/JobTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,212 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Job;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.JobRecord;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     计划作业测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class JobTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IJobModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QueryJobReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountRecordAsync(QueryReq<QueryJobRecordReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryJobRsp> CreateAsync(CreateJobReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryJobRsp> EditAsync(EditJobReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task ExecuteAsync(QueryJobReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QueryJobReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QueryJobReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportRecordAsync(QueryReq<QueryJobRecordReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryJobRsp> GetAsync(QueryJobReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryJobRecordRsp> GetRecordAsync(QueryJobRecordReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<GetBarChartRsp>> GetRecordBarChartAsync(QueryReq<QueryJobRecordReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<GetPieChartRsp>> GetRecordPieChartByHttpStatusCodeAsync(
 | 
			
		||||
        QueryReq<QueryJobRecordReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<GetPieChartRsp>> GetRecordPieChartByNameAsync(QueryReq<QueryJobRecordReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryJobRsp>> PagedQueryAsync(PagedQueryReq<QueryJobReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryJobRecordRsp>> PagedQueryRecordAsync(PagedQueryReq<QueryJobRecordReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryJobRsp>> QueryAsync(QueryReq<QueryJobReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> SetEnabledAsync(SetJobEnabledReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(JobController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										110
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/LoginLogTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/LoginLogTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.LoginLog;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     登录日志测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class LoginLogTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), ILoginLogModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(LoginLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QueryLoginLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(LoginLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryLoginLogRsp> CreateAsync(CreateLoginLogReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(LoginLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(LoginLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QueryLoginLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(LoginLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QueryLoginLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(LoginLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryLoginLogRsp> GetAsync(QueryLoginLogReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(LoginLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryLoginLogRsp>> PagedQueryAsync(PagedQueryReq<QueryLoginLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(LoginLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryLoginLogRsp>> QueryAsync(QueryReq<QueryLoginLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(LoginLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										128
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/MenuTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/MenuTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Menu;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     菜单测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class MenuTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IMenuModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QueryMenuReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryMenuRsp> CreateAsync(CreateMenuReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryMenuRsp> EditAsync(EditMenuReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QueryMenuReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QueryMenuReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryMenuRsp> GetAsync(QueryMenuReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryMenuRsp>> PagedQueryAsync(PagedQueryReq<QueryMenuReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryMenuRsp>> QueryAsync(QueryReq<QueryMenuReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task<IEnumerable<QueryMenuRsp>> UserMenusAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(MenuTests));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										141
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/RequestLogTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/RequestLogTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.RequestLog;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     请求日志测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class RequestLogTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IRequestLogModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QueryRequestLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryRequestLogRsp> CreateAsync(CreateRequestLogReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QueryRequestLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QueryRequestLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryRequestLogRsp> GetAsync(QueryRequestLogReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<GetBarChartRsp>> GetBarChartAsync(QueryReq<QueryRequestLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<GetPieChartRsp>> GetPieChartByApiSummaryAsync(QueryReq<QueryRequestLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<GetPieChartRsp>> GetPieChartByHttpStatusCodeAsync(QueryReq<QueryRequestLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryRequestLogRsp>> PagedQueryAsync(PagedQueryReq<QueryRequestLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryRequestLogRsp>> QueryAsync(QueryReq<QueryRequestLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RequestLogController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										150
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/RoleTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/RoleTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Role;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     角色测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class RoleTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IRoleModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QueryRoleReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryRoleRsp> CreateAsync(CreateRoleReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryRoleRsp> EditAsync(EditRoleReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QueryRoleReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QueryRoleReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryRoleRsp> GetAsync(QueryRoleReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryRoleRsp>> PagedQueryAsync(PagedQueryReq<QueryRoleReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryRoleRsp>> QueryAsync(QueryReq<QueryRoleReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> SetDisplayDashboardAsync(SetDisplayDashboardReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> SetEnabledAsync(SetRoleEnabledReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> SetIgnorePermissionControlAsync(SetIgnorePermissionControlReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(RoleController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										159
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/SiteMsgTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/SiteMsgTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.SiteMsg;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.SiteMsgFlag;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     站内信测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class SiteMsgTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), ISiteMsgModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QuerySiteMsgReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QuerySiteMsgRsp> CreateAsync(CreateSiteMsgReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QuerySiteMsgRsp> EditAsync(EditSiteMsgReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QuerySiteMsgReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QuerySiteMsgReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QuerySiteMsgRsp> GetAsync(QuerySiteMsgReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QuerySiteMsgRsp> GetMineAsync(QuerySiteMsgReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QuerySiteMsgRsp>> PagedQueryAsync(PagedQueryReq<QuerySiteMsgReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QuerySiteMsgRsp>> PagedQueryMineAsync(PagedQueryReq<QuerySiteMsgReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QuerySiteMsgRsp>> QueryAsync(QueryReq<QuerySiteMsgReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task SetSiteMsgStatusAsync(SetUserSiteMsgStatusReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task<long> UnreadCountAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(SiteMsgController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/ToolsTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/ToolsTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.Tool;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     工具测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class ToolsTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IToolsModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<object[][]> ExecuteSqlAsync(ExecuteSqlReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ToolsController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task<string> GetChangeLogAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ToolsController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task<IEnumerable<GetModulesRsp>> GetModulesAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ToolsController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task<DateTime> GetServerUtcTimeAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ToolsController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task<string> GetVersionAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(ToolsController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										309
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/UserTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/UserTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,309 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.User;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.UserProfile;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using NetAdmin.Tests.Attributes;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     用户测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
[TestCaseOrderer("NetAdmin.Tests.PriorityOrderer", "NetAdmin.Tests")]
 | 
			
		||||
public class UserTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IUserModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(100100)]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.Equal(HttpStatusCode.NotFound, rsp.StatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(100200)]
 | 
			
		||||
    public async Task<bool> CheckMobileAvailableAsync(CheckMobileAvailableReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), new CheckMobileAvailableReq { Mobile = "13838381438" });
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(100300)]
 | 
			
		||||
    public async Task<bool> CheckUserNameAvailableAsync(CheckUserNameAvailableReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), new CheckUserNameAvailableReq { UserName = "test" });
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(100400)]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QueryUserReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(100000)]
 | 
			
		||||
    public async Task<QueryUserRsp> CreateAsync(CreateUserReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController)
 | 
			
		||||
                                    , new CreateUserReq {
 | 
			
		||||
                                                            UserName     = "test"
 | 
			
		||||
                                                          , PasswordText = "1234qwer"
 | 
			
		||||
                                                          , RoleIds      = [371729946431493]
 | 
			
		||||
                                                          , DeptId       = 372119301627909
 | 
			
		||||
                                                        });
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(100600)]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(100700)]
 | 
			
		||||
    public async Task<QueryUserRsp> EditAsync(EditUserReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController)
 | 
			
		||||
                                    , new EditUserReq {
 | 
			
		||||
                                                          UserName = "test"
 | 
			
		||||
                                                        , RoleIds  = [371729946431493]
 | 
			
		||||
                                                        , DeptId   = 372119301627909
 | 
			
		||||
                                                      });
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(100800)]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QueryUserReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), new QueryReq<QueryUserReq>());
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(100900)]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QueryUserReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(101000)]
 | 
			
		||||
    public async Task<QueryUserRsp> GetAsync(QueryUserReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    [TestPriority(101100)]
 | 
			
		||||
    public async Task<GetSessionUserAppConfigRsp> GetSessionUserAppConfigAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(101200)]
 | 
			
		||||
    public async Task<LoginRsp> LoginByPwdAsync(LoginByPwdReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController)
 | 
			
		||||
                                    , new LoginByPwdReq { Account = "root", Password = "1234qwer" });
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(101300)]
 | 
			
		||||
    public async Task<LoginRsp> LoginBySmsAsync(LoginBySmsReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController)
 | 
			
		||||
                                    , new LoginBySmsReq { Code = "1234", DestDevice = "13838381438" });
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(101400)]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryUserRsp>> PagedQueryAsync(PagedQueryReq<QueryUserReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(101500)]
 | 
			
		||||
    public async Task<IEnumerable<QueryUserRsp>> QueryAsync(QueryReq<QueryUserReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(101600)]
 | 
			
		||||
    public async Task<IEnumerable<QueryUserProfileRsp>> QueryProfileAsync(QueryReq<QueryUserProfileReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(101700)]
 | 
			
		||||
    public async Task<UserInfoRsp> RegisterAsync(RegisterUserReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(101800)]
 | 
			
		||||
    public async Task<int> ResetPasswordAsync(ResetPasswordReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(101900)]
 | 
			
		||||
    public async Task<UserInfoRsp> SetAvatarAsync(SetAvatarReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(102000)]
 | 
			
		||||
    public async Task<UserInfoRsp> SetEmailAsync(SetEmailReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(102100)]
 | 
			
		||||
    public async Task<int> SetEnabledAsync(SetUserEnabledReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(102200)]
 | 
			
		||||
    public async Task<UserInfoRsp> SetMobileAsync(SetMobileReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(102300)]
 | 
			
		||||
    public async Task<int> SetPasswordAsync(SetPasswordReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [TestPriority(102400)]
 | 
			
		||||
    public async Task<int> SetSessionUserAppConfigAsync(SetSessionUserAppConfigReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Fact]
 | 
			
		||||
    [TestPriority(102500)]
 | 
			
		||||
    public async Task<UserInfoRsp> UserInfoAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(UserController));
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										130
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/VerifyCodeTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/backend/NetAdmin.SysComponent.Tests/Sys/VerifyCodeTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using NetAdmin.AdmServer.Host;
 | 
			
		||||
using NetAdmin.Domain.Dto.Dependency;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.VerifyCode;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Modules.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Host.Controllers.Sys;
 | 
			
		||||
using NetAdmin.Tests;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.SysComponent.Tests.Sys;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     验证码测试
 | 
			
		||||
/// </summary>
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
 | 
			
		||||
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
 | 
			
		||||
public class VerifyCodeTests(WebTestApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : WebApiTestBase<Startup>(factory, testOutputHelper), IVerifyCodeModule
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<long> CountAsync(QueryReq<QueryVerifyCodeReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryVerifyCodeRsp> CreateAsync(CreateVerifyCodeReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<int> DeleteAsync(DelReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> ExistAsync(QueryReq<QueryVerifyCodeReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IActionResult> ExportAsync(QueryReq<QueryVerifyCodeReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<QueryVerifyCodeRsp> GetAsync(QueryVerifyCodeReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryVerifyCodeRsp>> PagedQueryAsync(PagedQueryReq<QueryVerifyCodeReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<IEnumerable<QueryVerifyCodeRsp>> QueryAsync(QueryReq<QueryVerifyCodeReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<SendVerifyCodeRsp> SendVerifyCodeAsync(SendVerifyCodeReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [InlineData(default)]
 | 
			
		||||
    [Theory]
 | 
			
		||||
    public async Task<bool> VerifyAsync(VerifyCodeReq req)
 | 
			
		||||
    {
 | 
			
		||||
        var rsp = await PostJsonAsync(typeof(VerifyCodeController), req);
 | 
			
		||||
        Assert.True(rsp.IsSuccessStatusCode);
 | 
			
		||||
        return default;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
namespace NetAdmin.Tests.Attributes;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     测试用例优先级
 | 
			
		||||
/// </summary>
 | 
			
		||||
[AttributeUsage(AttributeTargets.Method)]
 | 
			
		||||
public class TestPriorityAttribute(int priority) : Attribute
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     优先级
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public int Priority { get; private set; } = priority;
 | 
			
		||||
}
 | 
			
		||||
@@ -3,8 +3,8 @@
 | 
			
		||||
        <ProjectReference Include="../NetAdmin.Host/NetAdmin.Host.csproj"/>
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
    <ItemGroup>
 | 
			
		||||
        <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0-preview.7.24406.2"/>
 | 
			
		||||
        <PackageReference Include="xunit" Version="2.9.0"/>
 | 
			
		||||
        <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0-preview.6.24328.4"/>
 | 
			
		||||
        <PackageReference Include="xunit.runner.visualstudio" Version="3.0.0-pre.24">
 | 
			
		||||
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
 | 
			
		||||
            <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								src/backend/NetAdmin.Tests/PriorityOrderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/backend/NetAdmin.Tests/PriorityOrderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
using NetAdmin.Tests.Attributes;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
using Xunit.Sdk;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.Tests;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     优先级排序
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class PriorityOrderer : ITestCaseOrderer
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     排序测试用例
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public IEnumerable<TTestCase> OrderTestCases<TTestCase>(IEnumerable<TTestCase> testCases)
 | 
			
		||||
        where TTestCase : ITestCase
 | 
			
		||||
    {
 | 
			
		||||
        var sortedMethods = new SortedDictionary<int, List<TTestCase>>();
 | 
			
		||||
 | 
			
		||||
        foreach (var testCase in testCases) {
 | 
			
		||||
            var priority = 0;
 | 
			
		||||
 | 
			
		||||
            foreach (var attr in testCase.TestMethod.Method.GetCustomAttributes(
 | 
			
		||||
                         typeof(TestPriorityAttribute).AssemblyQualifiedName)) {
 | 
			
		||||
                priority = attr.GetNamedArgument<int>("Priority");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            GetOrCreate(sortedMethods, priority).Add(testCase);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach (var list in sortedMethods.Keys.Select(priority => sortedMethods[priority])) {
 | 
			
		||||
            list.Sort((x, y) => StringComparer.OrdinalIgnoreCase.Compare(
 | 
			
		||||
                          x.TestMethod.Method.Name, y.TestMethod.Method.Name));
 | 
			
		||||
            foreach (var testCase in list) {
 | 
			
		||||
                yield return testCase;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static TValue GetOrCreate<TKey, TValue>(SortedDictionary<TKey, TValue> dictionary, TKey key)
 | 
			
		||||
        where TValue : new()
 | 
			
		||||
    {
 | 
			
		||||
        if (dictionary.TryGetValue(key, out var result)) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        result          = new TValue();
 | 
			
		||||
        dictionary[key] = result;
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +1,9 @@
 | 
			
		||||
using System.Net.Http.Headers;
 | 
			
		||||
using System.Net.Http.Json;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.Testing;
 | 
			
		||||
using System.Runtime.CompilerServices;
 | 
			
		||||
using NetAdmin.Domain.Dto;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.User;
 | 
			
		||||
using NetAdmin.Host.Extensions;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
@@ -11,34 +12,68 @@ namespace NetAdmin.Tests;
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     WebApi 测试用例基类
 | 
			
		||||
/// </summary>
 | 
			
		||||
public abstract class WebApiTestBase<T>(WebApplicationFactory<T> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : IClassFixture<WebApplicationFactory<T>>
 | 
			
		||||
public abstract class WebApiTestBase<T>(WebTestApplicationFactory<T> factory, ITestOutputHelper testOutputHelper)
 | 
			
		||||
    : IClassFixture<WebTestApplicationFactory<T>>
 | 
			
		||||
    where T : AppStartup
 | 
			
		||||
{
 | 
			
		||||
    private const string _ACCOUNT  = "root";
 | 
			
		||||
    private const string _PASSWORD = "1234qwer";
 | 
			
		||||
    private       string _accessToken;
 | 
			
		||||
    // ReSharper disable once StaticMemberInGenericType
 | 
			
		||||
    private static string _accessToken;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Post请求
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    protected async Task<HttpResponseMessage> PostAsync(string url, HttpContent content)
 | 
			
		||||
    protected async Task<HttpResponseMessage> PostAsync(Type                      type, HttpContent content
 | 
			
		||||
                                                      , [CallerMemberName] string memberName = null)
 | 
			
		||||
    {
 | 
			
		||||
        var client = factory.CreateClient();
 | 
			
		||||
        await Authorization(client);
 | 
			
		||||
 | 
			
		||||
        var ret = await client.PostAsync(type.GetMethod(memberName!).GetRoutePath(factory.Services), content)
 | 
			
		||||
                              .ConfigureAwait(false);
 | 
			
		||||
        testOutputHelper.WriteLine(await ret.Content.ReadAsStringAsync().ConfigureAwait(false));
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Post请求
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    protected async Task<HttpResponseMessage> PostJsonAsync<TRequest>(Type type, TRequest req = default
 | 
			
		||||
                                                                    , [CallerMemberName] string memberName = null)
 | 
			
		||||
    {
 | 
			
		||||
        return await PostAsync(type, req == null ? JsonContent.Create(new { }) : JsonContent.Create(req), memberName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Post请求
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    protected async Task<HttpResponseMessage> PostJsonAsync(Type type, [CallerMemberName] string memberName = null)
 | 
			
		||||
    {
 | 
			
		||||
        return await PostJsonAsync<object>(type, null, memberName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static async Task Authorization(HttpClient client)
 | 
			
		||||
    {
 | 
			
		||||
        if (_accessToken == null) {
 | 
			
		||||
            var loginRsp = await client.PostAsync(Chars.FLG_PATH_API_SYS_USER_LOGIN_BY_PWD
 | 
			
		||||
                                                , JsonContent.Create(
 | 
			
		||||
                                                      new LoginByPwdReq { Password = _PASSWORD, Account = _ACCOUNT }))
 | 
			
		||||
                                       .ConfigureAwait(false);
 | 
			
		||||
            var loginRspObj = (await loginRsp.Content.ReadAsStringAsync().ConfigureAwait(false))
 | 
			
		||||
            var req = new LoginByPwdReq //
 | 
			
		||||
                      {
 | 
			
		||||
                          Password
 | 
			
		||||
                              = Environment.GetEnvironmentVariable(
 | 
			
		||||
                                    nameof(WebTestApplicationFactory<T>.TEST_PASSWORD)) ??
 | 
			
		||||
                                WebTestApplicationFactory<T>.TEST_PASSWORD
 | 
			
		||||
                        , Account
 | 
			
		||||
                              = Environment.GetEnvironmentVariable(nameof(WebTestApplicationFactory<T>.TEST_ACCOUNT)) ??
 | 
			
		||||
                                WebTestApplicationFactory<T>.TEST_ACCOUNT
 | 
			
		||||
                      };
 | 
			
		||||
            var loginAccount = JsonContent.Create(req);
 | 
			
		||||
            var rspMsg = await client.PostAsync( //
 | 
			
		||||
                                         Chars.FLG_PATH_API_SYS_USER_LOGIN_BY_PWD, loginAccount)
 | 
			
		||||
                                     .ConfigureAwait(false);
 | 
			
		||||
            var rspObj = (await rspMsg.Content.ReadAsStringAsync().ConfigureAwait(false))
 | 
			
		||||
                .ToObject<RestfulInfo<LoginRsp>>();
 | 
			
		||||
            _accessToken = loginRspObj.Data.AccessToken;
 | 
			
		||||
            _accessToken = rspObj.Data.AccessToken;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        client.DefaultRequestHeaders.Authorization
 | 
			
		||||
            = new AuthenticationHeaderValue(Chars.FLG_HTTP_HEADER_VALUE_AUTH_SCHEMA, _accessToken);
 | 
			
		||||
        var ret = await client.PostAsync(url, content).ConfigureAwait(false);
 | 
			
		||||
        testOutputHelper.WriteLine(await ret.Content.ReadAsStringAsync().ConfigureAwait(false));
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								src/backend/NetAdmin.Tests/WebTestApplicationFactory.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/backend/NetAdmin.Tests/WebTestApplicationFactory.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.Testing;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.Tests;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     Web 测试应用程序工厂
 | 
			
		||||
/// </summary>
 | 
			
		||||
/// <typeparam name="T"></typeparam>
 | 
			
		||||
public class WebTestApplicationFactory<T> : WebApplicationFactory<T>
 | 
			
		||||
    where T : class
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     测试用户
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public const string TEST_ACCOUNT = "root";
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     测试密码
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public const string TEST_PASSWORD = "1234qwer";
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user