xiangyixiangqin/server/tests/XiangYi.Api.Tests/AdminApi/AdminSystemControllerIntegrationTests.cs
2026-01-02 18:00:49 +08:00

536 lines
18 KiB
C#

using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using NSubstitute;
using Xunit;
using XiangYi.AdminApi;
using XiangYi.Application.DTOs.Requests;
using XiangYi.Application.DTOs.Responses;
using XiangYi.Application.Interfaces;
namespace XiangYi.Api.Tests.AdminApi;
/// <summary>
/// 后台系统管理控制器集成测试(管理员、角色、权限、菜单、日志)
/// </summary>
public class AdminSystemControllerIntegrationTests : IClassFixture<WebApplicationFactory<IAdminApiMarker>>
{
private readonly WebApplicationFactory<IAdminApiMarker> _factory;
private readonly IAdminAccountService _mockAdminAccountService;
private readonly IAdminRoleService _mockAdminRoleService;
private readonly IAdminMenuService _mockAdminMenuService;
private readonly IAdminLogService _mockAdminLogService;
public AdminSystemControllerIntegrationTests(WebApplicationFactory<IAdminApiMarker> factory)
{
_mockAdminAccountService = Substitute.For<IAdminAccountService>();
_mockAdminRoleService = Substitute.For<IAdminRoleService>();
_mockAdminMenuService = Substitute.For<IAdminMenuService>();
_mockAdminLogService = Substitute.For<IAdminLogService>();
_factory = factory.WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Testing");
builder.ConfigureServices(services =>
{
services.RemoveAll<IAdminAccountService>();
services.RemoveAll<IAdminRoleService>();
services.RemoveAll<IAdminMenuService>();
services.RemoveAll<IAdminLogService>();
services.AddSingleton(_mockAdminAccountService);
services.AddSingleton(_mockAdminRoleService);
services.AddSingleton(_mockAdminMenuService);
services.AddSingleton(_mockAdminLogService);
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = AdminTestAuthHandler.AuthenticationScheme;
options.DefaultChallengeScheme = AdminTestAuthHandler.AuthenticationScheme;
})
.AddScheme<AuthenticationSchemeOptions, AdminTestAuthHandler>(
AdminTestAuthHandler.AuthenticationScheme, options => { });
});
});
}
#region
/// <summary>
/// 测试获取管理员列表- 未授权返回401
/// </summary>
[Fact]
public async Task GetAdminList_WithoutAuth_ReturnsUnauthorized()
{
var client = _factory.CreateClient();
var response = await client.GetAsync("/api/admin/admins");
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
}
/// <summary>
/// 测试获取管理员列表- 授权后成功
/// </summary>
[Fact]
public async Task GetAdminList_WithAuth_ReturnsSuccess()
{
var expectedResult = new PagedResult<AdminAccountListDto>
{
Items = new List<AdminAccountListDto>
{
new AdminAccountListDto
{
AdminId = 1,
Username = "admin",
RealName = "超级管理员",
Status = 1,
StatusText = "正常",
Roles = new List<AdminRoleDto>
{
new AdminRoleDto { RoleId = 1, RoleName = "超级管理员", RoleCode = "admin" }
}
}
},
Total = 1,
PageIndex = 1,
PageSize = 20
};
_mockAdminAccountService.GetAdminListAsync(Arg.Any<AdminAccountQueryRequest>())
.Returns(Task.FromResult(expectedResult));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.GetAsync("/api/admin/admins");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse<PagedResult<AdminAccountListDto>>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.NotNull(result.Data);
Assert.Single(result.Data.Items);
}
/// <summary>
/// 测试创建管理员- 成功
/// </summary>
[Fact]
public async Task CreateAdmin_WithAuth_ReturnsSuccess()
{
_mockAdminAccountService.CreateAdminAsync(Arg.Any<CreateAdminAccountRequest>())
.Returns(Task.FromResult(100L));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var request = new CreateAdminAccountRequest
{
Username = "newadmin",
Password = "password123",
RealName = "新管理员",
Phone = "13800138000",
Status = 1,
RoleIds = new List<long> { 2 }
};
var response = await client.PostAsJsonAsync("/api/admin/admins", request);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse<long>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.Equal(100L, result.Data);
}
/// <summary>
/// 测试删除管理员- 成功
/// </summary>
[Fact]
public async Task DeleteAdmin_WithAuth_ReturnsSuccess()
{
_mockAdminAccountService.DeleteAdminAsync(2, 1)
.Returns(Task.FromResult(true));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.DeleteAsync("/api/admin/admins/2");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
}
#endregion
#region
/// <summary>
/// 测试获取角色列表 - 成功
/// </summary>
[Fact]
public async Task GetRoleList_WithAuth_ReturnsSuccess()
{
var expectedResult = new PagedResult<AdminRoleListDto>
{
Items = new List<AdminRoleListDto>
{
new AdminRoleListDto
{
RoleId = 1,
RoleName = "超级管理员",
RoleCode = "admin",
Status = 1,
StatusText = "正常",
UserCount = 1
}
},
Total = 1,
PageIndex = 1,
PageSize = 20
};
_mockAdminRoleService.GetRoleListAsync(Arg.Any<AdminRoleQueryRequest>())
.Returns(Task.FromResult(expectedResult));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.GetAsync("/api/admin/roles");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse<PagedResult<AdminRoleListDto>>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.NotNull(result.Data);
Assert.Single(result.Data.Items);
}
/// <summary>
/// 测试创建角色 - 成功
/// </summary>
[Fact]
public async Task CreateRole_WithAuth_ReturnsSuccess()
{
_mockAdminRoleService.CreateRoleAsync(Arg.Any<CreateRoleRequest>())
.Returns(Task.FromResult(100L));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var request = new CreateRoleRequest
{
RoleName = "运营管理员",
RoleCode = "operator",
Description = "负责运营相关功能",
Status = 1
};
var response = await client.PostAsJsonAsync("/api/admin/roles", request);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse<long>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.Equal(100L, result.Data);
}
/// <summary>
/// 测试分配角色权限 - 成功
/// </summary>
[Fact]
public async Task AssignRolePermissions_WithAuth_ReturnsSuccess()
{
_mockAdminRoleService.AssignPermissionsAsync(1, Arg.Any<List<long>>())
.Returns(Task.FromResult(true));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var request = new AssignRolePermissionsRequest
{
PermissionIds = new List<long> { 1, 2, 3 }
};
var response = await client.PostAsJsonAsync("/api/admin/roles/1/permissions", request);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
}
#endregion
#region
/// <summary>
/// 测试获取菜单树 - 成功
/// </summary>
[Fact]
public async Task GetMenuTree_WithAuth_ReturnsSuccess()
{
var expectedResult = new List<AdminMenuTreeDto>
{
new AdminMenuTreeDto
{
MenuId = 1,
MenuName = "用户管理",
MenuType = 1,
MenuTypeText = "目录",
Path = "/users",
Children = new List<AdminMenuTreeDto>
{
new AdminMenuTreeDto
{
MenuId = 2,
ParentId = 1,
MenuName = "用户列表",
MenuType = 2,
MenuTypeText = "菜单",
Path = "/users/list"
}
}
}
};
_mockAdminMenuService.GetMenuTreeAsync(Arg.Any<AdminMenuQueryRequest?>())
.Returns(Task.FromResult(expectedResult));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.GetAsync("/api/admin/menus");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse<List<AdminMenuTreeDto>>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.NotNull(result.Data);
Assert.Single(result.Data);
Assert.Single(result.Data[0].Children);
}
/// <summary>
/// 测试创建菜单 - 成功
/// </summary>
[Fact]
public async Task CreateMenu_WithAuth_ReturnsSuccess()
{
_mockAdminMenuService.CreateMenuAsync(Arg.Any<CreateMenuRequest>())
.Returns(Task.FromResult(100L));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var request = new CreateMenuRequest
{
ParentId = 0,
MenuName = "新菜单",
MenuType = 1,
Path = "/new",
Status = 1
};
var response = await client.PostAsJsonAsync("/api/admin/menus", request);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse<long>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.Equal(100L, result.Data);
}
#endregion
#region
/// <summary>
/// 测试获取操作日志列表 - 成功
/// </summary>
[Fact]
public async Task GetLogList_WithAuth_ReturnsSuccess()
{
var expectedResult = new PagedResult<AdminLogListDto>
{
Items = new List<AdminLogListDto>
{
new AdminLogListDto
{
LogId = 1,
AdminUserId = 1,
AdminUsername = "admin",
Module = "用户管理",
Action = "更新状态",
Description = "禁用用户",
RequestUrl = "/api/admin/users/1/status",
RequestMethod = "PUT",
Status = 1,
StatusText = "成功",
CreateTime = DateTime.Now.AddMinutes(-30)
}
},
Total = 1,
PageIndex = 1,
PageSize = 20
};
_mockAdminLogService.GetLogListAsync(Arg.Any<AdminLogQueryRequest>())
.Returns(Task.FromResult(expectedResult));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.GetAsync("/api/admin/logs");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse<PagedResult<AdminLogListDto>>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.NotNull(result.Data);
Assert.Single(result.Data.Items);
}
/// <summary>
/// 测试获取操作日志详情 - 成功
/// </summary>
[Fact]
public async Task GetLogDetail_WithAuth_ReturnsSuccess()
{
var expectedResult = new AdminLogDetailDto
{
LogId = 1,
AdminUserId = 1,
AdminUsername = "admin",
Module = "用户管理",
Action = "更新状态",
Description = "禁用用户",
RequestUrl = "/api/admin/users/1/status",
RequestMethod = "PUT",
RequestParams = "{\"status\":2}",
ResponseResult = "{\"code\":0,\"message\":\"success\"}",
Status = 1,
StatusText = "成功"
};
_mockAdminLogService.GetLogDetailAsync(1)
.Returns(Task.FromResult(expectedResult));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.GetAsync("/api/admin/logs/1");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse<AdminLogDetailDto>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.NotNull(result.Data);
Assert.Equal(expectedResult.LogId, result.Data.LogId);
}
#endregion
#region
/// <summary>
/// 测试获取所有权限- 成功
/// </summary>
[Fact]
public async Task GetAllPermissions_WithAuth_ReturnsSuccess()
{
var expectedResult = new List<AdminPermissionGroupDto>
{
new AdminPermissionGroupDto
{
Module = "用户管理",
Permissions = new List<AdminPermissionDto>
{
new AdminPermissionDto
{
PermissionId = 1,
PermissionName = "用户列表",
PermissionCode = "user:list",
Module = "用户管理"
},
new AdminPermissionDto
{
PermissionId = 2,
PermissionName = "用户详情",
PermissionCode = "user:view",
Module = "用户管理"
}
}
}
};
_mockAdminRoleService.GetAllPermissionsAsync()
.Returns(Task.FromResult(expectedResult));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.GetAsync("/api/admin/permissions");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse<List<AdminPermissionGroupDto>>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.NotNull(result.Data);
Assert.Single(result.Data);
Assert.Equal(2, result.Data[0].Permissions.Count);
}
#endregion
}