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; /// /// 后台Banner管理控制器集成测试 /// public class AdminBannerControllerIntegrationTests : IClassFixture> { private readonly WebApplicationFactory _factory; private readonly IAdminBannerService _mockAdminBannerService; public AdminBannerControllerIntegrationTests(WebApplicationFactory factory) { _mockAdminBannerService = Substitute.For(); _factory = factory.WithWebHostBuilder(builder => { builder.UseEnvironment("Testing"); builder.ConfigureServices(services => { services.RemoveAll(); services.AddSingleton(_mockAdminBannerService); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = AdminTestAuthHandler.AuthenticationScheme; options.DefaultChallengeScheme = AdminTestAuthHandler.AuthenticationScheme; }) .AddScheme( AdminTestAuthHandler.AuthenticationScheme, options => { }); }); }); } /// /// 测试获取Banner列表 - 成功 /// [Fact] public async Task GetBannerList_WithAuth_ReturnsSuccess() { // Arrange var expectedResult = new PagedResult { Items = new List { new AdminBannerDto { Id = 1, Title = "测试Banner", ImageUrl = "https://example.com/banner.jpg", LinkType = 1, LinkTypeName = "内部页面", Status = 1, StatusName = "启用", Sort = 1 } }, Total = 1, PageIndex = 1, PageSize = 10 }; _mockAdminBannerService.GetBannerListAsync(Arg.Any()) .Returns(Task.FromResult(expectedResult)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); // Act var response = await client.GetAsync("/api/admin/banners"); // Assert 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); } /// /// 测试获取Banner详情 - 成功 /// [Fact] public async Task GetBannerDetail_WithAuth_ReturnsSuccess() { // Arrange var expectedResult = new AdminBannerDto { Id = 1, Title = "测试Banner", ImageUrl = "https://example.com/banner.jpg", LinkType = 1, LinkTypeName = "内部页面", Status = 1, StatusName = "启用" }; _mockAdminBannerService.GetBannerByIdAsync(1) .Returns(Task.FromResult(expectedResult)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); // Act var response = await client.GetAsync("/api/admin/banners/1"); // Assert 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); } /// /// 测试创建Banner - 成功 /// [Fact] public async Task CreateBanner_WithAuth_ReturnsSuccess() { // Arrange _mockAdminBannerService.CreateBannerAsync(Arg.Any(), 1) .Returns(Task.FromResult(100L)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var request = new CreateBannerRequest { Title = "新Banner", ImageUrl = "https://example.com/new-banner.jpg", LinkType = 1, Status = 1, Sort = 1 }; // Act var response = await client.PostAsJsonAsync("/api/admin/banners", request); // Assert 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); } /// /// 测试更新Banner - 成功 /// [Fact] public async Task UpdateBanner_WithAuth_ReturnsSuccess() { // Arrange _mockAdminBannerService.UpdateBannerAsync(1, Arg.Any(), 1) .Returns(Task.FromResult(true)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var request = new UpdateBannerRequest { Title = "更新后的Banner", ImageUrl = "https://example.com/updated-banner.jpg", LinkType = 1, Status = 1, Sort = 2 }; // Act var response = await client.PutAsJsonAsync("/api/admin/banners/1", request); // Assert 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); } /// /// 测试删除Banner - 成功 /// [Fact] public async Task DeleteBanner_WithAuth_ReturnsSuccess() { // Arrange _mockAdminBannerService.DeleteBannerAsync(1, 1) .Returns(Task.FromResult(true)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); // Act var response = await client.DeleteAsync("/api/admin/banners/1"); // Assert 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); } /// /// 测试更新Banner状态 - 成功 /// [Fact] public async Task UpdateBannerStatus_WithAuth_ReturnsSuccess() { // Arrange _mockAdminBannerService.UpdateBannerStatusAsync(1, 2, 1) .Returns(Task.FromResult(true)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); // Act var response = await client.PutAsync("/api/admin/banners/1/status/2", null); // Assert 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); } /// /// 测试Banner CRUD流程 - 完整流程测试 /// [Fact] public async Task BannerCRUD_CompleteFlow_Success() { // Arrange var bannerId = 100L; _mockAdminBannerService.CreateBannerAsync(Arg.Any(), 1) .Returns(Task.FromResult(bannerId)); _mockAdminBannerService.GetBannerByIdAsync(bannerId) .Returns(Task.FromResult(new AdminBannerDto { Id = bannerId, Title = "测试Banner", Status = 1 })); _mockAdminBannerService.UpdateBannerAsync(bannerId, Arg.Any(), 1) .Returns(Task.FromResult(true)); _mockAdminBannerService.DeleteBannerAsync(bannerId, 1) .Returns(Task.FromResult(true)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); // Create var createRequest = new CreateBannerRequest { Title = "测试Banner", ImageUrl = "https://example.com/banner.jpg", LinkType = 1, Status = 1 }; var createResponse = await client.PostAsJsonAsync("/api/admin/banners", createRequest); Assert.Equal(HttpStatusCode.OK, createResponse.StatusCode); // Read var readResponse = await client.GetAsync($"/api/admin/banners/{bannerId}"); Assert.Equal(HttpStatusCode.OK, readResponse.StatusCode); // Update var updateRequest = new UpdateBannerRequest { Title = "更新后的Banner", ImageUrl = "https://example.com/banner.jpg", LinkType = 1, Status = 1 }; var updateResponse = await client.PutAsJsonAsync($"/api/admin/banners/{bannerId}", updateRequest); Assert.Equal(HttpStatusCode.OK, updateResponse.StatusCode); // Delete var deleteResponse = await client.DeleteAsync($"/api/admin/banners/{bannerId}"); Assert.Equal(HttpStatusCode.OK, deleteResponse.StatusCode); } }