213 lines
7.1 KiB
C#
213 lines
7.1 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.AppApi;
|
||
using XiangYi.Application.DTOs.Requests;
|
||
using XiangYi.Application.DTOs.Responses;
|
||
using XiangYi.Application.Interfaces;
|
||
|
||
namespace XiangYi.Api.Tests.AppApi;
|
||
|
||
/// <summary>
|
||
/// 资料控制器集成测试
|
||
/// </summary>
|
||
public class ProfileControllerIntegrationTests : IClassFixture<WebApplicationFactory<IAppApiMarker>>
|
||
{
|
||
private readonly WebApplicationFactory<IAppApiMarker> _factory;
|
||
private readonly IProfileService _mockProfileService;
|
||
|
||
public ProfileControllerIntegrationTests(WebApplicationFactory<IAppApiMarker> factory)
|
||
{
|
||
_mockProfileService = Substitute.For<IProfileService>();
|
||
|
||
_factory = factory.WithWebHostBuilder(builder =>
|
||
{
|
||
builder.UseEnvironment("Testing");
|
||
builder.ConfigureServices(services =>
|
||
{
|
||
services.RemoveAll<IProfileService>();
|
||
services.AddSingleton(_mockProfileService);
|
||
|
||
services.AddAuthentication(options =>
|
||
{
|
||
options.DefaultAuthenticateScheme = TestAuthHandler.AuthenticationScheme;
|
||
options.DefaultChallengeScheme = TestAuthHandler.AuthenticationScheme;
|
||
})
|
||
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
|
||
TestAuthHandler.AuthenticationScheme, options => { });
|
||
});
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 测试提交资料 - 未授权返回401
|
||
/// </summary>
|
||
[Fact]
|
||
public async Task CreateOrUpdate_WithoutAuth_ReturnsUnauthorized()
|
||
{
|
||
// Arrange
|
||
var client = _factory.CreateClient();
|
||
var request = new ProfileRequest
|
||
{
|
||
Relationship = 1,
|
||
Surname = "李",
|
||
ChildGender = 1
|
||
};
|
||
|
||
// Act
|
||
var response = await client.PostAsJsonAsync("/api/app/profile", request);
|
||
|
||
// Assert
|
||
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 测试提交资料 - 授权后成功
|
||
/// </summary>
|
||
[Fact]
|
||
public async Task CreateOrUpdate_WithAuth_ReturnsSuccess()
|
||
{
|
||
// Arrange
|
||
_mockProfileService.CreateOrUpdateAsync(1, Arg.Any<ProfileRequest>())
|
||
.Returns(Task.FromResult(100L));
|
||
|
||
var client = _factory.CreateClient();
|
||
client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1");
|
||
|
||
var request = new ProfileRequest
|
||
{
|
||
Relationship = 1,
|
||
Surname = "李",
|
||
ChildGender = 1,
|
||
BirthYear = 1995,
|
||
Education = 4,
|
||
WorkProvince = "广东省",
|
||
WorkCity = "深圳市"
|
||
};
|
||
|
||
// Act
|
||
var response = await client.PostAsJsonAsync("/api/app/profile", request);
|
||
|
||
// Assert
|
||
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 GetMyProfile_WithAuth_ReturnsProfile()
|
||
{
|
||
// Arrange
|
||
var expectedProfile = new ProfileResponse
|
||
{
|
||
UserId = 1,
|
||
Nickname = "李家长(父亲)",
|
||
Relationship = 1,
|
||
Surname = "李",
|
||
ChildGender = 1,
|
||
BirthYear = 1995,
|
||
Education = 4
|
||
};
|
||
|
||
_mockProfileService.GetByUserIdAsync(1)
|
||
.Returns(Task.FromResult<ProfileResponse?>(expectedProfile));
|
||
|
||
var client = _factory.CreateClient();
|
||
client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1");
|
||
|
||
// Act
|
||
var response = await client.GetAsync("/api/app/profile");
|
||
|
||
// Assert
|
||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||
|
||
var content = await response.Content.ReadAsStringAsync();
|
||
var result = JsonSerializer.Deserialize<ApiResponse<ProfileResponse>>(content,
|
||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||
|
||
Assert.NotNull(result);
|
||
Assert.Equal(0, result.Code);
|
||
Assert.NotNull(result.Data);
|
||
Assert.Equal(expectedProfile.Nickname, result.Data.Nickname);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 测试获取我的资料 - 资料不存在
|
||
/// </summary>
|
||
[Fact]
|
||
public async Task GetMyProfile_ProfileNotExists_ReturnsError()
|
||
{
|
||
// Arrange
|
||
_mockProfileService.GetByUserIdAsync(1)
|
||
.Returns(Task.FromResult<ProfileResponse?>(null));
|
||
|
||
var client = _factory.CreateClient();
|
||
client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1");
|
||
|
||
// Act
|
||
var response = await client.GetAsync("/api/app/profile");
|
||
|
||
// Assert
|
||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||
|
||
var content = await response.Content.ReadAsStringAsync();
|
||
var result = JsonSerializer.Deserialize<ApiResponse<ProfileResponse>>(content,
|
||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||
|
||
Assert.NotNull(result);
|
||
Assert.NotEqual(0, result.Code); // 应返回错误码
|
||
}
|
||
|
||
/// <summary>
|
||
/// 测试照片数量限制 - 超过5张返回错误
|
||
/// </summary>
|
||
[Fact]
|
||
public async Task UploadPhotos_ExceedsLimit_ReturnsError()
|
||
{
|
||
// Arrange
|
||
_mockProfileService.CanUploadPhotosAsync(1, 3)
|
||
.Returns(Task.FromResult(false)); // 模拟已有3张,再上传3张超过限制
|
||
|
||
var client = _factory.CreateClient();
|
||
client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1");
|
||
|
||
// 创建多文件上传请求
|
||
using var content = new MultipartFormDataContent();
|
||
for (int i = 0; i < 3; i++)
|
||
{
|
||
var fileContent = new ByteArrayContent(new byte[] { 0x89, 0x50, 0x4E, 0x47 }); // PNG header
|
||
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
|
||
content.Add(fileContent, "files", $"photo{i}.png");
|
||
}
|
||
|
||
// Act
|
||
var response = await client.PostAsync("/api/app/profile/photos", content);
|
||
|
||
// Assert
|
||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||
|
||
var responseContent = await response.Content.ReadAsStringAsync();
|
||
var result = JsonSerializer.Deserialize<ApiResponse<UploadPhotoResponse>>(responseContent,
|
||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||
|
||
Assert.NotNull(result);
|
||
Assert.NotEqual(0, result.Code); // 应返回错误码
|
||
}
|
||
}
|