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.AppApi; using XiangYi.Application.DTOs.Requests; using XiangYi.Application.DTOs.Responses; using XiangYi.Application.Interfaces; namespace XiangYi.Api.Tests.AppApi; /// /// 聊天控制器集成测试 /// public class ChatControllerIntegrationTests : IClassFixture> { private readonly WebApplicationFactory _factory; private readonly IChatService _mockChatService; public ChatControllerIntegrationTests(WebApplicationFactory factory) { _mockChatService = Substitute.For(); _factory = factory.WithWebHostBuilder(builder => { builder.UseEnvironment("Testing"); builder.ConfigureServices(services => { services.RemoveAll(); services.AddSingleton(_mockChatService); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = TestAuthHandler.AuthenticationScheme; options.DefaultChallengeScheme = TestAuthHandler.AuthenticationScheme; }) .AddScheme( TestAuthHandler.AuthenticationScheme, options => { }); }); }); } /// /// 测试获取会话列表 - 成功 /// [Fact] public async Task GetSessions_WithAuth_ReturnsSuccess() { // Arrange var expectedSessions = new List { new ChatSessionResponse { SessionId = 1, OtherUserId = 2, OtherNickname = "用户2", LastMessageContent = "你好", LastMessageTime = DateTime.Now, UnreadCount = 1 } }; _mockChatService.GetSessionsAsync(1) .Returns(Task.FromResult(expectedSessions)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1"); // Act var response = await client.GetAsync("/api/app/chat/sessions"); // 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); } /// /// 测试获取消息列表 - 成功 /// [Fact] public async Task GetMessages_WithAuth_ReturnsSuccess() { // Arrange var expectedMessages = new PagedResult { Items = new List { new ChatMessageResponse { MessageId = 1, SenderId = 1, Content = "你好", MessageType = 1, CreateTime = DateTime.Now } }, Total = 1, PageIndex = 1, PageSize = 20 }; _mockChatService.CanAccessSessionAsync(1, 100) .Returns(Task.FromResult(true)); _mockChatService.GetMessagesAsync(1, Arg.Any()) .Returns(Task.FromResult(expectedMessages)); _mockChatService.MarkMessagesAsReadAsync(1, 100) .Returns(Task.FromResult(1)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1"); // Act var response = await client.GetAsync("/api/app/chat/messages?sessionId=100&pageIndex=1&pageSize=20"); // 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); } /// /// 测试获取消息列表 - 无权限访问会话 /// [Fact] public async Task GetMessages_NoAccess_ReturnsForbidden() { // Arrange _mockChatService.CanAccessSessionAsync(1, 100) .Returns(Task.FromResult(false)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1"); // Act var response = await client.GetAsync("/api/app/chat/messages?sessionId=100"); // 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.NotEqual(0, result.Code); // 应返回错误码 } /// /// 测试发送消息 - 成功 /// [Fact] public async Task SendMessage_WithAuth_ReturnsSuccess() { // Arrange var expectedResponse = new SendMessageResponse { MessageId = 100, CreateTime = DateTime.Now }; _mockChatService.CanAccessSessionAsync(1, 100) .Returns(Task.FromResult(true)); _mockChatService.SendMessageAsync(1, Arg.Any()) .Returns(Task.FromResult(expectedResponse)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1"); var request = new SendMessageRequest { SessionId = 100, ReceiverId = 2, Content = "你好", MessageType = 1 }; // Act var response = await client.PostAsJsonAsync("/api/app/chat/send", 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.NotNull(result.Data); Assert.Equal(expectedResponse.MessageId, result.Data.MessageId); } /// /// 测试请求交换微信 - 成功 /// [Fact] public async Task ExchangeWeChat_WithAuth_ReturnsSuccess() { // Arrange var expectedResponse = new ExchangeRequestResponse { RequestMessageId = 100, CreateTime = DateTime.Now }; _mockChatService.CanAccessSessionAsync(1, 100) .Returns(Task.FromResult(true)); _mockChatService.ExchangeWeChatAsync(1, Arg.Any()) .Returns(Task.FromResult(expectedResponse)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1"); var request = new ExchangeWeChatRequest { SessionId = 100, ReceiverId = 2 }; // Act var response = await client.PostAsJsonAsync("/api/app/chat/exchangeWeChat", 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.NotNull(result.Data); Assert.Equal(100, result.Data.RequestMessageId); } /// /// 测试响应交换请求 - 同意 /// [Fact] public async Task RespondExchange_Agree_ReturnsSuccess() { // Arrange var expectedResponse = new ExchangeRespondResponse { ResultMessageId = 101, IsAgreed = true, ExchangedData = "wx123456" }; _mockChatService.RespondExchangeAsync(1, Arg.Any()) .Returns(Task.FromResult(expectedResponse)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1"); var request = new RespondExchangeRequest { RequestMessageId = 100, IsAgreed = true }; // Act var response = await client.PostAsJsonAsync("/api/app/chat/respondExchange", 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.NotNull(result.Data); Assert.True(result.Data.IsAgreed); } /// /// 测试获取未读消息数 - 成功 /// [Fact] public async Task GetUnreadCount_WithAuth_ReturnsSuccess() { // Arrange _mockChatService.GetUnreadCountAsync(1) .Returns(Task.FromResult(5)); var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1"); // Act var response = await client.GetAsync("/api/app/chat/unreadCount"); // 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(5, result.Data); } }