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 AdminPopupControllerIntegrationTests : IClassFixture> { private readonly WebApplicationFactory _factory; private readonly IAdminPopupService _mockAdminPopupService; public AdminPopupControllerIntegrationTests(WebApplicationFactory factory) { _mockAdminPopupService = Substitute.For(); _factory = factory.WithWebHostBuilder(builder => { builder.UseEnvironment("Testing"); builder.ConfigureServices(services => { services.RemoveAll(); services.AddSingleton(_mockAdminPopupService); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = AdminTestAuthHandler.AuthenticationScheme; options.DefaultChallengeScheme = AdminTestAuthHandler.AuthenticationScheme; }) .AddScheme( AdminTestAuthHandler.AuthenticationScheme, options => { }); }); }); } /// /// 测试获取弹窗配置列表 - 未授权返�?01 /// [Fact] public async Task GetPopupList_WithoutAuth_ReturnsUnauthorized() { var client = _factory.CreateClient(); var response = await client.GetAsync("/api/admin/popups"); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); } /// /// 测试获取弹窗配置列表 - 授权后成�? /// [Fact] public async Task GetPopupList_WithAuth_ReturnsSuccess() { var expectedResult = new PagedResult { Items = new List { new AdminPopupDto { Id = 1, PopupType = 1, PopupTypeName = "每日首次", Title = "欢迎弹窗", ImageUrl = "https://example.com/popup.jpg", Status = 1, StatusName = "启用" } }, Total = 1, PageIndex = 1, PageSize = 10 }; _mockAdminPopupService.GetPopupListAsync(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/popups"); 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 GetPopupDetail_WithAuth_ReturnsSuccess() { var expectedResult = new AdminPopupDto { Id = 1, PopupType = 1, PopupTypeName = "每日首次", Title = "欢迎弹窗", ImageUrl = "https://example.com/popup.jpg", LinkUrl = "/pages/member/index", ButtonText = "立即查看", Status = 1, StatusName = "启用" }; _mockAdminPopupService.GetPopupByIdAsync(1) .Returns(Task.FromResult(expectedResult)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.GetAsync("/api/admin/popups/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 GetPopupByType_WithAuth_ReturnsSuccess() { var expectedResult = new AdminPopupDto { Id = 1, PopupType = 1, PopupTypeName = "每日首次", Title = "欢迎弹窗", ImageUrl = "https://example.com/popup.jpg", Status = 1, StatusName = "启用" }; _mockAdminPopupService.GetPopupByTypeAsync(1) .Returns(Task.FromResult(expectedResult)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.GetAsync("/api/admin/popups/type/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(1, result.Data.PopupType); } /// /// 测试更新弹窗配置 - 成功 /// [Fact] public async Task UpdatePopup_WithAuth_ReturnsSuccess() { _mockAdminPopupService.UpdatePopupAsync(1, Arg.Any(), 1) .Returns(Task.FromResult(true)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var request = new UpdatePopupRequest { Title = "更新后的弹窗", ImageUrl = "https://example.com/updated-popup.jpg", LinkUrl = "/pages/member/index", ButtonText = "立即查看", Status = 1 }; var response = await client.PutAsJsonAsync("/api/admin/popups/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 UpdatePopupByType_WithAuth_ReturnsSuccess() { _mockAdminPopupService.UpdatePopupByTypeAsync(1, Arg.Any(), 1) .Returns(Task.FromResult(100L)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var request = new UpdatePopupRequest { Title = "每日首次弹窗", ImageUrl = "https://example.com/popup.jpg", Status = 1 }; var response = await client.PutAsJsonAsync("/api/admin/popups/type/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); Assert.Equal(100L, result.Data); } /// /// 测试更新弹窗状�?- 成功 /// [Fact] public async Task UpdatePopupStatus_WithAuth_ReturnsSuccess() { _mockAdminPopupService.UpdatePopupStatusAsync(1, 2, 1) .Returns(Task.FromResult(true)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); var response = await client.PutAsync("/api/admin/popups/1/status/2", 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 PopupConfiguration_CompleteFlow_Success() { var popupId = 100L; _mockAdminPopupService.UpdatePopupByTypeAsync(1, Arg.Any(), 1) .Returns(Task.FromResult(popupId)); _mockAdminPopupService.GetPopupByIdAsync(popupId) .Returns(Task.FromResult(new AdminPopupDto { Id = popupId, PopupType = 1, PopupTypeName = "每日首次", Title = "测试弹窗", Status = 1 })); _mockAdminPopupService.UpdatePopupStatusAsync(popupId, 2, 1) .Returns(Task.FromResult(true)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer admin-token-1"); // Create/Update by type var createRequest = new UpdatePopupRequest { Title = "测试弹窗", ImageUrl = "https://example.com/popup.jpg", Status = 1 }; var createResponse = await client.PutAsJsonAsync("/api/admin/popups/type/1", createRequest); Assert.Equal(HttpStatusCode.OK, createResponse.StatusCode); // Read var readResponse = await client.GetAsync($"/api/admin/popups/{popupId}"); Assert.Equal(HttpStatusCode.OK, readResponse.StatusCode); // Update status (disable) var statusResponse = await client.PutAsync($"/api/admin/popups/{popupId}/status/2", null); Assert.Equal(HttpStatusCode.OK, statusResponse.StatusCode); } }