浏览代码

单元测试支持同时切换身份;

qinchaoyue 5 月之前
父节点
当前提交
452926ddd5

+ 3 - 2
src/Hotline.Application.Tests/Application/DefaultCallApplicationTest.cs

@@ -9,13 +9,14 @@ using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.CallCenter;
 using Hotline.Users;
+using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using SqlSugar.Extensions;
 using XF.Domain.Repository;
 
 namespace Hotline.Application.Tests.Application;
-public class DefaultCallApplicationTest
+public class DefaultCallApplicationTest : TestBase
 {
     private readonly XingTangCallApplication _defaultCallApplication;
     private readonly IOrderVisitRepository _orderVisitRepository;
@@ -23,7 +24,7 @@ public class DefaultCallApplicationTest
     public readonly IFixture _fixture;
     private readonly IOrderRepository _orderRepository;
 
-    public DefaultCallApplicationTest(XingTangCallApplication defaultCallApplication, IOrderVisitRepository orderVisitRepository, IRepository<CallNative> callNativeRepository, IOrderRepository orderRepository)
+    public DefaultCallApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, XingTangCallApplication defaultCallApplication, IOrderVisitRepository orderVisitRepository, IRepository<CallNative> callNativeRepository, IOrderRepository orderRepository) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor)
     {
         _fixture = new Fixture();
         _defaultCallApplication = defaultCallApplication;

+ 9 - 3
src/Hotline.Application.Tests/Application/KnowApplicationTest.cs

@@ -1,10 +1,16 @@
-using Hotline.Application.Knowledge;
+using Hotline.Api.Controllers;
+using Hotline.Application.Knowledge;
+using Hotline.Identity.Accounts;
+using Hotline.Identity.Roles;
 using Hotline.KnowledgeBase;
 using Hotline.KnowledgeBase.Notifies;
 using Hotline.Share.Dtos.Knowledge;
 using Hotline.Share.Tools;
+using Hotline.Users;
 using Mapster;
 using MediatR;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using System;
 using System.Collections.Generic;
@@ -15,7 +21,7 @@ using System.Threading.Tasks;
 using XF.Domain.Repository;
 
 namespace Hotline.Application.Tests.Application;
-public class KnowApplicationTest
+public class KnowApplicationTest : TestBase
 {
     private readonly IKnowApplication _knowApplication;
     private readonly IRepository<KnowledgeRelationType> _knowledgeRelationTypeRepository;
@@ -25,7 +31,7 @@ public class KnowApplicationTest
     private readonly IRepository<KnowledgeWord> _knowledgeWordRepository;
     private readonly IRepository<KnowledgeHotWord> _knowledgeHotWordRepository;
 
-    public KnowApplicationTest(IKnowApplication knowApplication, IRepository<KnowledgeRelationType> knowledgeRelationTypeRepository, IMediator mediator, IRepository<KnowledgeBase.Knowledge> knowledgeRepository, IKnowledgeDomainService knowledgeDomainService, IRepository<KnowledgeWord> knowledgeWordRepository, IRepository<KnowledgeHotWord> knowledgeHotWordRepository)
+    public KnowApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IKnowApplication knowApplication, IRepository<KnowledgeRelationType> knowledgeRelationTypeRepository, IMediator mediator, IRepository<KnowledgeBase.Knowledge> knowledgeRepository, IKnowledgeDomainService knowledgeDomainService, IRepository<KnowledgeWord> knowledgeWordRepository, IRepository<KnowledgeHotWord> knowledgeHotWordRepository) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor)
     {
         _knowApplication = knowApplication;
         _knowledgeRelationTypeRepository = knowledgeRelationTypeRepository;

+ 0 - 78
src/Hotline.Application.Tests/Controller/DefaultHttpContextAccessor.cs

@@ -1,78 +0,0 @@
-using Hotline.Application.Tests.Infrastructure;
-using Hotline.Identity.Accounts;
-using Microsoft.AspNetCore.Http;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Authentication;
-using System.Security.Claims;
-using System.Text;
-using System.Threading.Tasks;
-using XF.Domain.Authentications;
-using XF.Domain.Dependency;
-using XF.Domain.Repository;
-
-namespace Hotline.Application.Tests.Controller;
-public class DefaultHttpContextAccessor : ISessionContext, IScopeDependency
-{
-    private HttpContext _content = new DefaultHttpContext();
-
-    private HttpContext GetContext()
-    {
-        var context = new DefaultHttpContext();
-        //var openId = new Claim(AppClaimTypes.OpenId, "测试生成的OpenId");
-        var id = new ClaimsIdentity("身份");
-        //id.AddClaim(openId);
-        context.User = new ClaimsPrincipal(id);
-        //OpenId = context.User.FindFirstValue(AppClaimTypes.OpenId);
-        return context;
-
-    }
-    public HttpContext? HttpContext { get => GetContext(); set => _content = value; }
-
-
-    public string? OpenId { get { return TestSessionConstants.OpenId; } set { } }
-
-    /// <summary>
-    /// Id of current tenant or null for host
-    /// </summary>
-    public string? UserId
-    {
-        get
-        {
-            return TestSessionConstants.UserId;
-        }
-        init { }
-    }
-
-    /// <summary>
-    /// Id of current user or throw Exception for guest
-    /// </summary>
-    /// <exception cref="AuthenticationException"></exception>
-    public string RequiredUserId { get { return TestSessionConstants.UserId; } }
-    public string? UserName { get { return TestSessionConstants.UserName; } init { } }
-    public string? Phone { get; init; }
-
-    /// <summary>
-    /// Roles
-    /// </summary>
-    public string[] Roles { get { return TestSessionConstants.Roles; } init { } }
-    public string? OrgId { get { return TestSessionConstants.OrgId; } init { } }
-    public string RequiredOrgId { get { return TestSessionConstants.OrgId; } }
-    public string? OrgName { get; init; }
-    public int OrgLevel { get; init; }
-    public string? OrgAreaCode { get; init; }
-    public bool OrgIsCenter { get; init; }
-
-    /// <summary>
-    /// 部门行政区划名称
-    /// </summary>
-    public string? OrgAreaName { get; init; }
-    public string? AreaId { get; init; }
-    public string? ClientId { get; init; }
-
-    /// <summary>
-    /// 工号
-    /// </summary>
-    public string? StaffNo { get; init; }
-}

+ 142 - 0
src/Hotline.Application.Tests/Controller/DefaultSessionContext.cs

@@ -0,0 +1,142 @@
+using Hotline.Application.Tests.Infrastructure;
+using Hotline.Identity.Accounts;
+using IdentityModel;
+using Microsoft.AspNetCore.Http;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Authentication;
+using System.Security.Claims;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Authentications;
+using XF.Domain.Dependency;
+using XF.Domain.Repository;
+
+namespace Hotline.Application.Tests.Controller;
+public class DefaultSessionContext : ISessionContext, IScopeDependency
+{
+    private readonly IHttpContextAccessor _contextAccessor;
+    private readonly ClaimsPrincipal User;
+    public DefaultSessionContext(IHttpContextAccessor httpContextAccessor)
+    {
+        _contextAccessor = httpContextAccessor;
+        if (_contextAccessor.HttpContext is null) return;
+
+        User = httpContextAccessor.HttpContext.User;
+        //Roles = user.Claims.Where(d => d.Type == JwtClaimTypes.Role).Select(d => d.Value).ToArray();
+    }
+    private HttpContext _content = new DefaultHttpContext();
+
+    private HttpContext GetContext()
+    {
+        return _contextAccessor.HttpContext;
+        var context = new DefaultHttpContext();
+        //var openId = new Claim(AppClaimTypes.OpenId, "测试生成的OpenId");
+        var id = new ClaimsIdentity("身份");
+        //id.AddClaim(openId);
+        context.User = new ClaimsPrincipal(id);
+        //OpenId = context.User.FindFirstValue(AppClaimTypes.OpenId);
+        return context;
+
+    }
+    public HttpContext? HttpContext { get => GetContext(); set => _content = value; }
+
+
+    public string? OpenId { get; set; }
+
+    /// <summary>
+    /// Id of current tenant or null for host
+    /// </summary>
+    public string? UserId
+    {
+        get { return _contextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier); }
+        init { }
+    }
+
+    /// <summary>
+    /// Id of current user or throw Exception for guest
+    /// </summary>
+    /// <exception cref="AuthenticationException"></exception>
+    public string RequiredUserId => _contextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
+    public string? UserName
+    {
+        get { return _contextAccessor.HttpContext.User.FindFirstValue(AppClaimTypes.UserDisplayName); }
+        init { }
+    }
+
+    public string? Phone
+    {
+        get { return _contextAccessor.HttpContext.User.FindFirstValue(JwtClaimTypes.PhoneNumber); }
+        init { }
+    }
+
+    /// <summary>
+    /// Roles
+    /// </summary>
+    public string[] Roles
+    {
+        get { return _contextAccessor.HttpContext.User.Claims.Where(d => d.Type == ClaimTypes.Role).Select(d => d.Value).ToArray(); }
+        init { }
+    }
+
+    public string? OrgId
+    {
+        get { return _contextAccessor.HttpContext.User.FindFirstValue(AppClaimTypes.DepartmentId); }
+        init { }
+    }
+
+    public string RequiredOrgId => _contextAccessor.HttpContext.User.FindFirstValue(AppClaimTypes.DepartmentId);
+    public string? OrgName
+    {
+        get { return _contextAccessor.HttpContext.User.FindFirstValue(AppClaimTypes.DepartmentName); }
+        init { }
+    }
+
+    public int OrgLevel
+    {
+        get { return _contextAccessor.HttpContext.User.FindIntValue(AppClaimTypes.DepartmentLevel); }
+        init { }
+    }
+
+    public string? OrgAreaCode
+    {
+        get { return _contextAccessor.HttpContext.User.FindFirstValue(AppClaimTypes.DepartmentAreaCode); }
+        init { }
+    }
+
+    public bool OrgIsCenter
+    {
+        get { return _contextAccessor.HttpContext.User.FindBoolValue(AppClaimTypes.DepartmentIsCenter); }
+        init { }
+    }
+
+    /// <summary>
+    /// 部门行政区划名称
+    /// </summary>
+    public string? OrgAreaName
+    {
+        get { return _contextAccessor.HttpContext.User.FindFirstValue(AppClaimTypes.DepartmentAreaName); }
+        init { }
+    }
+
+    public string? AreaId
+    {
+        get { return _contextAccessor.HttpContext.User.FindFirstValue(AppClaimTypes.AreaId); }
+        init { }
+    }
+    public string? ClientId
+    {
+        get { return _contextAccessor.HttpContext.User.FindFirstValue(JwtClaimTypes.ClientId); }
+        init { }
+    }
+
+    /// <summary>
+    /// 工号
+    /// </summary>
+    public string? StaffNo
+    {
+        get { return _contextAccessor.HttpContext.User.FindFirstValue(AppClaimTypes.StaffNo); }
+        init { }
+    }
+}

+ 1 - 1
src/Hotline.Application.Tests/Controller/KnowledgeControllerTest.cs

@@ -27,7 +27,7 @@ public class KnowledgeControllerTest : TestBase
     private readonly KnowledgeController _knowledgeController;
     private readonly IRepository<KnowledgeBase.Knowledge> _knowledgeRepository;
 
-    public KnowledgeControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, KnowledgeServiceMock knowledgeServiceMock, KnowledgeController knowledgeController, IRepository<KnowledgeBase.Knowledge> knowledgeRepository) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository)
+    public KnowledgeControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, KnowledgeServiceMock knowledgeServiceMock, KnowledgeController knowledgeController, IRepository<KnowledgeBase.Knowledge> knowledgeRepository, IHttpContextAccessor httpContextAccessor) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor)
     {
         _knowledgeServiceMock = knowledgeServiceMock;
         _knowledgeController = knowledgeController;

+ 1 - 1
src/Hotline.Application.Tests/Controller/OrderControllerTest.cs

@@ -64,7 +64,7 @@ public class OrderControllerTest : TestBase
     private readonly XingTangCallApplication _defaultCallApplication;
     private readonly ISqlSugarClient _capSqlClient;
 
-    public OrderControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IRepository<Hotspot> hotspotRepository, OrderController orderController, IOrderRepository orderRepository, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, OrderServiceMock orderServiceMock, IRepository<OrderPublish> orderPublishRepository, INotificationHandler<EndWorkflowNotify> orderPublishEndWorkflowHandler, IOrderVisitRepository orderVisitRepository, IRepository<SystemSetting> systemSettingRepository, ISystemSettingCacheManager systemSettingCacheManager, IRepository<CallNative> callNativeRepository, IRepository<CallidRelation> callIdRelationRepository, XingTangCallApplication defaultCallApplication, ISugarUnitOfWork<CapDbContext> capDbContext) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository)
+    public OrderControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IRepository<Hotspot> hotspotRepository, OrderController orderController, IOrderRepository orderRepository, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, OrderServiceMock orderServiceMock, IRepository<OrderPublish> orderPublishRepository, INotificationHandler<EndWorkflowNotify> orderPublishEndWorkflowHandler, IOrderVisitRepository orderVisitRepository, IRepository<SystemSetting> systemSettingRepository, ISystemSettingCacheManager systemSettingCacheManager, IRepository<CallNative> callNativeRepository, IRepository<CallidRelation> callIdRelationRepository, XingTangCallApplication defaultCallApplication, ISugarUnitOfWork<CapDbContext> capDbContext, IHttpContextAccessor httpContextAccessor) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor)
     {
         _hotspotRepository = hotspotRepository;
         _orderController = orderController;

+ 2 - 1
src/Hotline.Application.Tests/Domain/OrderVisitDomainServiceTest.cs

@@ -13,6 +13,7 @@ using Hotline.Share.Enums.Push;
 using Hotline.Share.Tools;
 using Hotline.Users;
 using Mapster;
+using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using XF.Domain.Repository;
@@ -27,7 +28,7 @@ public class OrderVisitDomainServiceTest : TestBase
     private readonly IOrderRepository _orderRepository;
     private readonly OrderServiceMock _orderServiceMock;
 
-    public OrderVisitDomainServiceTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IOrderVisitDomainService orderVisitDomainService, IOrderVisitRepository orderVisitRepository, IRepository<OrderVisitDetail> orderVisitDetailRepository, Publisher publisher, IOrderRepository orderRepository, OrderServiceMock orderServiceMock) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository)
+    public OrderVisitDomainServiceTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IOrderVisitDomainService orderVisitDomainService, IOrderVisitRepository orderVisitRepository, IRepository<OrderVisitDetail> orderVisitDetailRepository, Publisher publisher, IOrderRepository orderRepository, OrderServiceMock orderServiceMock, IHttpContextAccessor httpContextAccessor) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor)
     {
         _orderVisitDomainService = orderVisitDomainService;
         _orderVisitRepository = orderVisitRepository;

+ 3 - 1
src/Hotline.Application.Tests/Startup.cs

@@ -42,6 +42,7 @@ using Hotline.FlowEngine.Notifications;
 using Hotline.Application.Handlers.FlowEngine;
 using Hotline.Application.Jobs;
 using Hotline.Application.Tests.SqlSuger;
+using Microsoft.AspNetCore.Http;
 
 namespace Hotline.Application.Tests;
 public class Startup
@@ -154,7 +155,8 @@ public class Startup
             services.AddScoped<UserController>();
             services.AddScoped<KnowledgeController>();
             services.AddScoped<PushMessageController>();
-            services.AddScoped<ISessionContext, DefaultHttpContextAccessor>();
+            services.AddHttpContextAccessor();
+            services.AddScoped<ISessionContext, Controller.DefaultSessionContext>();
             services.AddScoped<ISessionContextProvider, SessionContextProvider>();
             services.AddScoped<ICallApplication, XingTangCallApplication>();
             services.AddScoped<XingTangCallApplication>();

+ 37 - 6
src/Hotline.Application.Tests/TestBase.cs

@@ -3,13 +3,17 @@ using Hotline.Api.Controllers;
 using Hotline.Application.Tests.Infrastructure;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
+using Hotline.Settings;
 using Hotline.Share.Dtos.Users;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.User;
 using Hotline.Users;
+using IdentityModel;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.DependencyInjection;
+using System.Security.Claims;
+using XF.Domain.Authentications;
 using XF.Domain.Repository;
 
 namespace Hotline.Application.Tests;
@@ -21,9 +25,11 @@ public class TestBase
     public readonly UserController _userController;
     public readonly IFixture _fixture;
     private readonly IServiceScopeFactory _scopeFactory;
+    public readonly IHttpContextAccessor _httpContextAccessor;
 
-    public TestBase(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository)
+    public TestBase(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor)
     {
+
         _fixture = new Fixture();
         _accountRepository = accountRepository;
         _roleRepository = roleRepository;
@@ -34,6 +40,13 @@ public class TestBase
         };
         _scopeFactory = scopeFactory;
         _userRepository = userRepository;
+        _httpContextAccessor = httpContextAccessor;
+
+        if (httpContextAccessor.HttpContext is null)
+        {
+            httpContextAccessor.HttpContext = new DefaultHttpContext();
+            SetZuoXi();
+        }
     }
 
     public void SetPaiDanYuan()
@@ -85,15 +98,33 @@ public class TestBase
                 UserName = userName
             };
             var accountId = _userController.Add(newUser).GetAwaiter().GetResult();
-            TestSessionConstants.UserId = accountId;
+            // TestSessionConstants.UserId = accountId;
             account = _accountRepository.GetExtAsync(
                 d => d.UserName == userName,
                 d => d.Includes(x => x.Roles)).GetAwaiter().GetResult();
         }
         var user = _userRepository.GetAsync(account.Id).GetAwaiter().GetResult();
-        TestSessionConstants.UserId = account.Id;
-        TestSessionConstants.Roles = account.Roles.Select(m => m.Id).ToArray();
-        TestSessionConstants.UserName = account.UserName;
-        TestSessionConstants.OrgId = user.OrgId;
+
+        List<Claim> userClaims = [ 
+            new(JwtClaimTypes.Subject, account.Id),
+            new(JwtClaimTypes.PhoneNumber, account.PhoneNo ?? string.Empty),
+            new(ClaimTypes.NameIdentifier, user.Id),
+            new(AppClaimTypes.UserDisplayName, account.Name),
+            new(AppClaimTypes.DepartmentId, user.OrgId ?? string.Empty), 
+            new(AppClaimTypes.DepartmentIsCenter, user.Organization?.IsCenter.ToString() ?? false.ToString()), 
+            new(AppClaimTypes.DepartmentName, user.Organization?.Name ?? string.Empty), 
+            new(AppClaimTypes.DepartmentAreaCode, user.Organization?.AreaCode ?? string.Empty), 
+            new(AppClaimTypes.DepartmentAreaName, user.Organization?.AreaName ?? string.Empty), 
+            new(AppClaimTypes.DepartmentLevel, user.Organization?.Level.ToString() ?? string.Empty), 
+            new(AppClaimTypes.AreaId, user.OrgId?.GetHigherOrgId() ?? string.Empty),
+        ];
+        ClaimsIdentity identity = new ClaimsIdentity(userClaims);
+        var principal = new ClaimsPrincipal(identity);
+        _httpContextAccessor.HttpContext.User = principal;
+
+        //TestSessionConstants.UserId = account.Id;
+        //TestSessionConstants.Roles = account.Roles.Select(m => m.Id).ToArray();
+        //TestSessionConstants.UserName = account.UserName;
+        //TestSessionConstants.OrgId = user.OrgId;
     }
 }