379 lines
14 KiB
C#
379 lines
14 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 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));
|
||
}
|
||
}
|