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);
}
}