204 lines
6.8 KiB
C#
204 lines
6.8 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 AuthControllerIntegrationTests : IClassFixture<WebApplicationFactory<IAppApiMarker>>
|
|
{
|
|
private readonly WebApplicationFactory<IAppApiMarker> _factory;
|
|
private readonly IAuthService _mockAuthService;
|
|
|
|
public AuthControllerIntegrationTests(WebApplicationFactory<IAppApiMarker> factory)
|
|
{
|
|
_mockAuthService = Substitute.For<IAuthService>();
|
|
|
|
_factory = factory.WithWebHostBuilder(builder =>
|
|
{
|
|
builder.UseEnvironment("Testing");
|
|
builder.ConfigureServices(services =>
|
|
{
|
|
services.RemoveAll<IAuthService>();
|
|
services.AddSingleton(_mockAuthService);
|
|
|
|
services.AddAuthentication(options =>
|
|
{
|
|
options.DefaultAuthenticateScheme = TestAuthHandler.AuthenticationScheme;
|
|
options.DefaultChallengeScheme = TestAuthHandler.AuthenticationScheme;
|
|
})
|
|
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
|
|
TestAuthHandler.AuthenticationScheme, options => { });
|
|
});
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 测试微信登录 - 成功场景
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task Login_WithValidCode_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var expectedResponse = new LoginResponse
|
|
{
|
|
Token = "jwt-token-123",
|
|
UserId = 1,
|
|
Nickname = "测试用户",
|
|
XiangQinNo = "123456",
|
|
IsProfileCompleted = false,
|
|
IsMember = false,
|
|
MemberLevel = 0,
|
|
IsRealName = false,
|
|
IsNewUser = true
|
|
};
|
|
|
|
_mockAuthService.LoginAsync("valid-code")
|
|
.Returns(Task.FromResult(expectedResponse));
|
|
|
|
var client = _factory.CreateClient();
|
|
var request = new LoginRequest { Code = "valid-code" };
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync("/api/app/auth/login", request);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
var result = JsonSerializer.Deserialize<ApiResponse<LoginResponse>>(content,
|
|
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
|
|
Assert.NotNull(result);
|
|
Assert.Equal(0, result.Code);
|
|
Assert.NotNull(result.Data);
|
|
Assert.Equal(expectedResponse.UserId, result.Data.UserId);
|
|
Assert.Equal(expectedResponse.XiangQinNo, result.Data.XiangQinNo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 测试微信登录 - 空code返回错误
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task Login_WithEmptyCode_ReturnsError()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateClient();
|
|
var request = new LoginRequest { Code = "" };
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync("/api/app/auth/login", request);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
var result = JsonSerializer.Deserialize<ApiResponse<LoginResponse>>(content,
|
|
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
|
|
Assert.NotNull(result);
|
|
Assert.Equal(30003, result.Code); // MissingParameter
|
|
}
|
|
|
|
/// <summary>
|
|
/// 测试绑定手机号 - 未授权返回401
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task BindPhone_WithoutAuth_ReturnsUnauthorized()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateClient();
|
|
var request = new BindPhoneRequest { Code = "phone-code" };
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync("/api/app/auth/bindPhone", request);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 测试绑定手机号 - 授权后成功
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task BindPhone_WithAuth_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var expectedResponse = new BindPhoneResponse { Phone = "138****8888" };
|
|
|
|
_mockAuthService.BindPhoneAsync(1, "phone-code")
|
|
.Returns(Task.FromResult(expectedResponse));
|
|
|
|
var client = _factory.CreateClient();
|
|
client.DefaultRequestHeaders.Add("Authorization", "Bearer test-token-1");
|
|
|
|
var request = new BindPhoneRequest { Code = "phone-code" };
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync("/api/app/auth/bindPhone", request);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
var result = JsonSerializer.Deserialize<ApiResponse<BindPhoneResponse>>(content,
|
|
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
|
|
Assert.NotNull(result);
|
|
Assert.Equal(0, result.Code);
|
|
Assert.NotNull(result.Data);
|
|
Assert.Equal(expectedResponse.Phone, result.Data.Phone);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 测试相亲编号格式 - 6位数字且首位不为0
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task Login_XiangQinNo_ShouldBe6DigitsAndNotStartWithZero()
|
|
{
|
|
// Arrange
|
|
var expectedResponse = new LoginResponse
|
|
{
|
|
Token = "jwt-token-123",
|
|
UserId = 1,
|
|
XiangQinNo = "123456",
|
|
IsNewUser = true
|
|
};
|
|
|
|
_mockAuthService.LoginAsync("test-code")
|
|
.Returns(Task.FromResult(expectedResponse));
|
|
|
|
var client = _factory.CreateClient();
|
|
var request = new LoginRequest { Code = "test-code" };
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync("/api/app/auth/login", request);
|
|
|
|
// Assert
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
var result = JsonSerializer.Deserialize<ApiResponse<LoginResponse>>(content,
|
|
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
|
|
Assert.NotNull(result?.Data?.XiangQinNo);
|
|
var xiangQinNo = result.Data.XiangQinNo;
|
|
|
|
// 验证6位数字
|
|
Assert.Equal(6, xiangQinNo.Length);
|
|
Assert.True(xiangQinNo.All(char.IsDigit), "相亲编号应全为数字");
|
|
Assert.NotEqual('0', xiangQinNo[0]); // 首位不为0
|
|
}
|
|
}
|