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)); } }