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 AdminNotificationControllerIntegrationTests : IClassFixture>
{
private readonly WebApplicationFactory _factory;
private readonly IAdminNotificationService _mockAdminNotificationService;
public AdminNotificationControllerIntegrationTests(WebApplicationFactory factory)
{
_mockAdminNotificationService = Substitute.For();
_factory = factory.WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Testing");
builder.ConfigureServices(services =>
{
services.RemoveAll();
services.AddSingleton(_mockAdminNotificationService);
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = AdminTestAuthHandler.AuthenticationScheme;
options.DefaultChallengeScheme = AdminTestAuthHandler.AuthenticationScheme;
})
.AddScheme(
AdminTestAuthHandler.AuthenticationScheme, options => { });
});
});
}
///
/// 测试获取系统通知列表 - 未授权返回401
///
[Fact]
public async Task GetNotificationList_WithoutAuth_ReturnsUnauthorized()
{
var client = _factory.CreateClient();
var response = await client.GetAsync("/api/admin/notifications");
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
}
///
/// 测试获取系统通知列表 - 授权后成功
///
[Fact]
public async Task GetNotificationList_WithAuth_ReturnsSuccess()
{
var expectedResult = new PagedResult
{
Items = new List
{
new AdminNotificationDto
{
Id = 1,
Title = "系统维护通知",
Content = "系统将于今晚进行维护",
TargetType = 1,
TargetTypeName = "全部用户",
Status = 2,
StatusName = "已发布",
PublishTime = DateTime.Now.AddHours(-1)
}
},
Total = 1,
PageIndex = 1,
PageSize = 10
};
_mockAdminNotificationService.GetNotificationListAsync(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/notifications");
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);
}
///
/// 测试获取系统通知详情 - 成功
///
[Fact]
public async Task GetNotificationDetail_WithAuth_ReturnsSuccess()
{
var expectedResult = new AdminNotificationDto
{
Id = 1,
Title = "系统维护通知",
Content = "系统将于今晚进行维护,预计持续2小时",
TargetType = 1,
TargetTypeName = "全部用户",
Status = 2,
StatusName = "已发布",
PublishTime = DateTime.Now.AddHours(-1)
};
_mockAdminNotificationService.GetNotificationByIdAsync(1)
.Returns(Task.FromResult(expectedResult));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.GetAsync("/api/admin/notifications/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.Id, result.Data.Id);
}
///
/// 测试创建系统通知 - 成功
///
[Fact]
public async Task CreateNotification_WithAuth_ReturnsSuccess()
{
_mockAdminNotificationService.CreateNotificationAsync(Arg.Any(), 1)
.Returns(Task.FromResult(100L));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var request = new CreateNotificationRequest
{
Title = "新系统通知",
Content = "这是一条新的系统通知",
TargetType = 1,
PublishNow = false
};
var response = await client.PostAsJsonAsync("/api/admin/notifications", 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);
Assert.Equal(100L, result.Data);
}
///
/// 测试更新系统通知 - 成功
///
[Fact]
public async Task UpdateNotification_WithAuth_ReturnsSuccess()
{
_mockAdminNotificationService.UpdateNotificationAsync(1, Arg.Any(), 1)
.Returns(Task.FromResult(true));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var request = new UpdateNotificationRequest
{
Title = "更新后的通知",
Content = "这是更新后的通知内容",
TargetType = 1
};
var response = await client.PutAsJsonAsync("/api/admin/notifications/1", 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 DeleteNotification_WithAuth_ReturnsSuccess()
{
_mockAdminNotificationService.DeleteNotificationAsync(1, 1)
.Returns(Task.FromResult(true));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.DeleteAsync("/api/admin/notifications/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);
}
///
/// 测试发布系统通知 - 成功
///
[Fact]
public async Task PublishNotification_WithAuth_ReturnsSuccess()
{
_mockAdminNotificationService.PublishNotificationAsync(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/notifications/1/publish", 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 WithdrawNotification_WithAuth_ReturnsSuccess()
{
_mockAdminNotificationService.WithdrawNotificationAsync(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/notifications/1/withdraw", 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 NotificationFlow_CreatePublishWithdraw_Success()
{
var notificationId = 100L;
_mockAdminNotificationService.CreateNotificationAsync(Arg.Any(), 1)
.Returns(Task.FromResult(notificationId));
_mockAdminNotificationService.GetNotificationByIdAsync(notificationId)
.Returns(Task.FromResult(new AdminNotificationDto
{
Id = notificationId,
Title = "测试通知",
Content = "测试内容",
Status = 1,
StatusName = "草稿"
}));
_mockAdminNotificationService.PublishNotificationAsync(notificationId, 1)
.Returns(Task.FromResult(true));
_mockAdminNotificationService.WithdrawNotificationAsync(notificationId, 1)
.Returns(Task.FromResult(true));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
// Create
var createRequest = new CreateNotificationRequest
{
Title = "测试通知",
Content = "测试内容",
TargetType = 1,
PublishNow = false
};
var createResponse = await client.PostAsJsonAsync("/api/admin/notifications", createRequest);
Assert.Equal(HttpStatusCode.OK, createResponse.StatusCode);
// Read
var readResponse = await client.GetAsync($"/api/admin/notifications/{notificationId}");
Assert.Equal(HttpStatusCode.OK, readResponse.StatusCode);
// Publish
var publishResponse = await client.PostAsync($"/api/admin/notifications/{notificationId}/publish", null);
Assert.Equal(HttpStatusCode.OK, publishResponse.StatusCode);
// Withdraw
var withdrawResponse = await client.PostAsync($"/api/admin/notifications/{notificationId}/withdraw", null);
Assert.Equal(HttpStatusCode.OK, withdrawResponse.StatusCode);
}
///
/// 测试通知列表按状态筛选 - 成功
///
[Fact]
public async Task GetNotificationList_WithStatusFilter_ReturnsFilteredResults()
{
var expectedResult = new PagedResult
{
Items = new List
{
new AdminNotificationDto
{
Id = 1,
Title = "草稿通知",
Status = 1,
StatusName = "草稿"
}
},
Total = 1,
PageIndex = 1,
PageSize = 10
};
_mockAdminNotificationService.GetNotificationListAsync(Arg.Is(r => r.Status == 1))
.Returns(Task.FromResult(expectedResult));
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1");
var response = await client.GetAsync("/api/admin/notifications?status=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.All(result.Data.Items, item => Assert.Equal(1, item.Status));
}
}