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

379 lines
14 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 AdminNotificationControllerIntegrationTests : IClassFixture<WebApplicationFactory<IAdminApiMarker>>
{
private readonly WebApplicationFactory<IAdminApiMarker> _factory;
private readonly IAdminNotificationService _mockAdminNotificationService;
public AdminNotificationControllerIntegrationTests(WebApplicationFactory<IAdminApiMarker> factory)
{
_mockAdminNotificationService = Substitute.For<IAdminNotificationService>();
_factory = factory.WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Testing");
builder.ConfigureServices(services =>
{
services.RemoveAll<IAdminNotificationService>();
services.AddSingleton(_mockAdminNotificationService);
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = AdminTestAuthHandler.AuthenticationScheme;
options.DefaultChallengeScheme = AdminTestAuthHandler.AuthenticationScheme;
})
.AddScheme<AuthenticationSchemeOptions, AdminTestAuthHandler>(
AdminTestAuthHandler.AuthenticationScheme, options => { });
});
});
}
/// <summary>
/// 测试获取系统通知列表 - 未授权返回401
/// </summary>
[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);
}
/// <summary>
/// 测试获取系统通知列表 - 授权后成功
/// </summary>
[Fact]
public async Task GetNotificationList_WithAuth_ReturnsSuccess()
{
var expectedResult = new PagedResult<AdminNotificationDto>
{
Items = new List<AdminNotificationDto>
{
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<AdminNotificationQueryRequest>())
.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<ApiResponse<PagedResult<AdminNotificationDto>>>(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 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<ApiResponse<AdminNotificationDto>>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
Assert.NotNull(result.Data);
Assert.Equal(expectedResult.Id, result.Data.Id);
}
/// <summary>
/// 测试创建系统通知 - 成功
/// </summary>
[Fact]
public async Task CreateNotification_WithAuth_ReturnsSuccess()
{
_mockAdminNotificationService.CreateNotificationAsync(Arg.Any<CreateNotificationRequest>(), 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<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 UpdateNotification_WithAuth_ReturnsSuccess()
{
_mockAdminNotificationService.UpdateNotificationAsync(1, Arg.Any<UpdateNotificationRequest>(), 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<ApiResponse>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
}
/// <summary>
/// 测试删除系统通知 - 成功
/// </summary>
[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<ApiResponse>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
}
/// <summary>
/// 测试发布系统通知 - 成功
/// </summary>
[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<ApiResponse>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
}
/// <summary>
/// 测试撤回系统通知 - 成功
/// </summary>
[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<ApiResponse>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(result);
Assert.Equal(0, result.Code);
}
/// <summary>
/// 测试系统通知完整流程 - 创建、发布、撤回
/// </summary>
[Fact]
public async Task NotificationFlow_CreatePublishWithdraw_Success()
{
var notificationId = 100L;
_mockAdminNotificationService.CreateNotificationAsync(Arg.Any<CreateNotificationRequest>(), 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);
}
/// <summary>
/// 测试通知列表按状态筛选 - 成功
/// </summary>
[Fact]
public async Task GetNotificationList_WithStatusFilter_ReturnsFilteredResults()
{
var expectedResult = new PagedResult<AdminNotificationDto>
{
Items = new List<AdminNotificationDto>
{
new AdminNotificationDto
{
Id = 1,
Title = "草稿通知",
Status = 1,
StatusName = "草稿"
}
},
Total = 1,
PageIndex = 1,
PageSize = 10
};
_mockAdminNotificationService.GetNotificationListAsync(Arg.Is<AdminNotificationQueryRequest>(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<ApiResponse<PagedResult<AdminNotificationDto>>>(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));
}
}