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;
///
/// 后台资料审核控制器集成测试
///
public class AdminProfileAuditControllerIntegrationTests : IClassFixture>
{
private readonly WebApplicationFactory _factory;
private readonly IAdminProfileAuditService _mockAdminProfileAuditService;
public AdminProfileAuditControllerIntegrationTests(WebApplicationFactory factory)
{
_mockAdminProfileAuditService = Substitute.For();
_factory = factory.WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Testing");
builder.ConfigureServices(services =>
{
services.RemoveAll();
services.AddSingleton(_mockAdminProfileAuditService);
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = AdminTestAuthHandler.AuthenticationScheme;
options.DefaultChallengeScheme = AdminTestAuthHandler.AuthenticationScheme;
})
.AddScheme(
AdminTestAuthHandler.AuthenticationScheme, options => { });
});
});
}
///
/// 测试获取待审核资料列表 - 未授权返回401
///
[Fact]
public async Task GetPendingProfiles_WithoutAuth_ReturnsUnauthorized()
{
var client = _factory.CreateClient();
var response = await client.GetAsync("/api/admin/profiles/pending");
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
}
///
/// 测试获取待审核资料列表 - 授权后成功
///
[Fact]
public async Task GetPendingProfiles_WithAuth_ReturnsSuccess()
{
var expectedResult = new PagedResult
{
Items = new List
{
new AdminPendingProfileDto
{
ProfileId = 1,
UserId = 100,
XiangQinNo = "123456",
Nickname = "李家长(父亲)",
Relationship = 1,
RelationshipText = "父亲",
Surname = "李",
ChildGender = 1,
ChildGenderText = "男",
Age = 28,
WorkCity = "北京",
AuditStatus = 0,
AuditStatusText = "待审核",
SubmitTime = DateTime.Now.AddHours(-2),
PhotoCount = 3
}
},
Total = 1,
PageIndex = 1,
PageSize = 20
};
_mockAdminProfileAuditService.GetPendingProfilesAsync(Arg.Any())
.Returns(Task.FromResult(expectedResult));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.GetAsync("/api/admin/profiles/pending");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.NotNull(result.Data);
Assert.Single(result.Data.Items);
Assert.Equal("待审核", result.Data.Items[0].AuditStatusText);
}
///
/// 测试获取资料审核详情 - 成功
///
[Fact]
public async Task GetProfileDetail_WithAuth_ReturnsSuccess()
{
var expectedResult = new AdminProfileAuditDetailDto
{
ProfileId = 1,
UserId = 100,
XiangQinNo = "123456",
Nickname = "李家长(父亲)",
Relationship = 1,
RelationshipText = "父亲",
Surname = "李",
ChildGender = 1,
ChildGenderText = "男",
BirthYear = 1996,
Age = 28,
Education = 4,
EducationText = "本科",
WorkProvince = "北京",
WorkCity = "北京",
Occupation = "软件工程师",
MonthlyIncome = 4,
MonthlyIncomeText = "2-3万",
Height = 175,
Weight = 70,
HouseStatus = 1,
HouseStatusText = "有房",
CarStatus = 1,
CarStatusText = "有车",
MarriageStatus = 1,
MarriageStatusText = "未婚",
ExpectMarryTime = 2,
ExpectMarryTimeText = "1-2年内",
Introduction = "这是一段自我介绍",
IsPhotoPublic = true,
WeChatNo = "wx123456",
AuditStatus = 0,
AuditStatusText = "待审核",
Photos = new List
{
new AdminUserPhotoDto { PhotoId = 1, PhotoUrl = "https://example.com/photo1.jpg", Sort = 1 }
}
};
_mockAdminProfileAuditService.GetProfileDetailAsync(1)
.Returns(Task.FromResult(expectedResult));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.GetAsync("/api/admin/profiles/1");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.NotNull(result.Data);
Assert.Equal(expectedResult.ProfileId, result.Data.ProfileId);
Assert.NotNull(result.Data.Photos);
Assert.Single(result.Data.Photos);
}
///
/// 测试审核通过资料 - 成功
///
[Fact]
public async Task ApproveProfile_WithAuth_ReturnsSuccess()
{
_mockAdminProfileAuditService.ApproveProfileAsync(1, 1)
.Returns(Task.FromResult(true));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.PostAsync("/api/admin/profiles/1/approve", null);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
}
///
/// 测试审核拒绝资料 - 成功
///
[Fact]
public async Task RejectProfile_WithAuth_ReturnsSuccess()
{
_mockAdminProfileAuditService.RejectProfileAsync(1, 1, "资料不完整")
.Returns(Task.FromResult(true));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var request = new RejectProfileRequest { RejectReason = "资料不完整" };
var response = await client.PostAsJsonAsync("/api/admin/profiles/1/reject", request);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
}
///
/// 测试审核通过失败 - 返回错误
///
[Fact]
public async Task ApproveProfile_WhenFails_ReturnsError()
{
_mockAdminProfileAuditService.ApproveProfileAsync(1, 1)
.Returns(Task.FromResult(false));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.PostAsync("/api/admin/profiles/1/approve", null);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(40001, result.Code);
}
///
/// 测试资料审核完整流程 - 从待审核到通过
///
[Fact]
public async Task ProfileAuditFlow_FromPendingToApproved_Success()
{
// 设置待审核资料
var pendingProfile = new AdminProfileAuditDetailDto
{
ProfileId = 1,
AuditStatus = 0,
AuditStatusText = "待审核"
};
_mockAdminProfileAuditService.GetProfileDetailAsync(1)
.Returns(Task.FromResult(pendingProfile));
_mockAdminProfileAuditService.ApproveProfileAsync(1, 1)
.Returns(Task.FromResult(true));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
// 获取资料详情
var detailResponse = await client.GetAsync("/api/admin/profiles/1");
Assert.Equal(HttpStatusCode.OK, detailResponse.StatusCode);
// 审核通过
var approveResponse = await client.PostAsync("/api/admin/profiles/1/approve", null);
Assert.Equal(HttpStatusCode.OK, approveResponse.StatusCode);
var content = await approveResponse.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
}
}