You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
haoliang-net/tests/CncService.Tests/AuthServiceTests.cs

199 lines
6.2 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using CncModels.Constants;
using CncModels.Dto.Login;
using CncService;
using CncService.Impl;
using Xunit;
namespace CncService.Tests
{
/// <summary>
/// AuthService 登录认证测试
/// 测试场景:登录成功、密码错误、用户名错误、参数为空、记住密码、构造函数参数校验
/// </summary>
[Collection("Database")]
public class AuthServiceTests : IDisposable
{
private readonly AuthService _service;
public AuthServiceTests()
{
TestDb.TruncateAll();
_service = ServiceFactory.CreateAuthService();
}
public void Dispose()
{
TestDb.TruncateAll();
}
// ======== 构造函数校验 ========
[Fact]
public void _SysConfigRepositorynull_ArgumentNullException()
{
Assert.Throws<ArgumentNullException>(() => new AuthService(null, "secret"));
}
[Fact]
public void _JwtSecretnull_ArgumentNullException()
{
var repo = new CncRepository.Impl.SysConfigRepository(TestDb.ConnectionString);
Assert.Throws<ArgumentNullException>(() => new AuthService(repo, null));
}
// ======== 登录成功 ========
[Fact]
public void Login__Token()
{
// 设置真实BCrypt密码
const string plainPwd = "admin123";
TestDb.SetRealPasswordHash(plainPwd);
var svc = ServiceFactory.CreateAuthService();
var response = svc.Login(new LoginRequest
{
Username = "admin",
Password = plainPwd
});
Assert.NotNull(response);
Assert.False(string.IsNullOrWhiteSpace(response.Token), "Token不应为空");
Assert.Equal(8 * 3600, response.ExpiresIn); // 默认8小时
}
[Fact]
public void Login__24()
{
const string plainPwd = "admin123";
TestDb.SetRealPasswordHash(plainPwd);
var svc = ServiceFactory.CreateAuthService();
var response = svc.Login(new LoginRequest
{
Username = "admin",
Password = plainPwd,
RememberMe = true
});
Assert.Equal(24 * 3600, response.ExpiresIn);
}
// ======== 登录失败 ========
[Fact]
public void Login__BusinessException()
{
const string plainPwd = "admin123";
TestDb.SetRealPasswordHash(plainPwd);
var svc = ServiceFactory.CreateAuthService();
var ex = Assert.Throws<BusinessException>(() => svc.Login(new LoginRequest
{
Username = "admin",
Password = "wrongpassword"
}));
Assert.Equal(ErrorCode.BadRequest, ex.Code);
Assert.Contains("用户名或密码错误", ex.Message);
}
[Fact]
public void Login__BusinessException()
{
const string plainPwd = "admin123";
TestDb.SetRealPasswordHash(plainPwd);
var svc = ServiceFactory.CreateAuthService();
var ex = Assert.Throws<BusinessException>(() => svc.Login(new LoginRequest
{
Username = "wronguser",
Password = plainPwd
}));
Assert.Equal(ErrorCode.BadRequest, ex.Code);
}
[Fact]
public void Login__()
{
const string plainPwd = "admin123";
TestDb.SetRealPasswordHash(plainPwd);
var svc = ServiceFactory.CreateAuthService();
var response = svc.Login(new LoginRequest
{
Username = "ADMIN",
Password = plainPwd
});
Assert.NotNull(response.Token);
}
// ======== 参数校验 ========
[Fact]
public void Login_null_BusinessException()
{
var ex = Assert.Throws<BusinessException>(() => _service.Login(null));
Assert.Equal(ErrorCode.BadRequest, ex.Code);
}
[Fact]
public void Login_null_BCrypt()
{
const string plainPwd = "admin123";
TestDb.SetRealPasswordHash(plainPwd);
var svc = ServiceFactory.CreateAuthService();
// Password为nullBCrypt.Verify("", hash) 应返回false
var ex = Assert.Throws<BusinessException>(() => svc.Login(new LoginRequest
{
Username = "admin",
Password = null
}));
Assert.Equal(ErrorCode.BadRequest, ex.Code);
}
// ======== 边界情况 ========
[Fact]
public void Login__BusinessException()
{
// 清空sys_config表
TestDb.Execute("DELETE FROM cnc_sys_config");
var svc = ServiceFactory.CreateAuthService();
var ex = Assert.Throws<BusinessException>(() => svc.Login(new LoginRequest
{
Username = "admin",
Password = "admin123"
}));
Assert.Equal(ErrorCode.BadRequest, ex.Code);
}
[Fact]
public void Login_Token_Base64Url()
{
const string plainPwd = "admin123";
TestDb.SetRealPasswordHash(plainPwd);
var svc = ServiceFactory.CreateAuthService();
var response = svc.Login(new LoginRequest
{
Username = "admin",
Password = plainPwd
});
// JWT格式header.payload.signature用点分隔为3段
var parts = response.Token.Split('.');
Assert.Equal(3, parts.Length);
Assert.False(string.IsNullOrWhiteSpace(parts[0]), "Header不应为空");
Assert.False(string.IsNullOrWhiteSpace(parts[1]), "Payload不应为空");
Assert.False(string.IsNullOrWhiteSpace(parts[2]), "Signature不应为空");
}
}
}