Files
StoreWeb/Tests/Store.Users.Tests/UserServiceValidationTests.cs
2026-10-29 11:34:35 +08:00

78 lines
3.3 KiB
C#

using Store.Users.Contracts.Enums;
using System.ComponentModel.DataAnnotations;
using Store.Users.Contracts.Dtos;
namespace Store.Users.Tests;
/// <summary>确认服务入口执行 DTO 的长度和范围校验,拒绝无效写入。</summary>
public sealed class UserServiceValidationTests
{
[Theory]
[InlineData(0)]
[InlineData(-1)]
public async Task NonPositiveId_IsRejectedByService(int id)
{
using var context = new UserTestContext();
await Assert.ThrowsAsync<ValidationException>(() => context.Users.Delete(id, default));
await Assert.ThrowsAsync<ValidationException>(() => context.Users.Update(new() { Id = id }, false, default));
}
[Theory]
[InlineData("nickname")]
[InlineData("mobile")]
[InlineData("company")]
[InlineData("notes")]
[InlineData("card")]
[InlineData("authority")]
[InlineData("forbidden")]
[InlineData("oem")]
[InlineData("group")]
[InlineData("level")]
[InlineData("monthly")]
[InlineData("postage")]
[InlineData("refund")]
[InlineData("gift")]
[InlineData("logistics")]
public async Task InvalidEdit_IsRejectedBeforePersistence(string field)
{
using var context = new UserTestContext();
var request = new UserUpdateRequest { Id = context.Main.Id };
switch (field)
{
case "nickname": request.NickName = new string('x', 51); break;
case "mobile": request.Mobile = new string('x', 31); break;
case "company": request.CompanyName = new string('x', 101); break;
case "notes": request.Notes = new string('x', 256); break;
case "card": request.CardId = new string('x', 51); break;
case "authority": request.Authority = new string('x', 1001); break;
case "forbidden": request.ForbiddenPage = new string('x', 1001); break;
case "oem": request.OemId = new string('x', 51); break;
case "group": request.GroupId = 0; break;
case "level": request.SaLevel = (UserAdminLevel)2; break;
case "monthly": request.ShopPointsPerMonth = 29; break;
case "postage": request.PostagePerOrder = 2.1m; break;
case "refund": request.RefundPostagePerOrder = 2.4m; break;
case "gift": request.GiftOemAmountPerOrder = -1m; break;
case "logistics": request.SyncLogisticsPerOrder = -1m; break;
}
await Assert.ThrowsAsync<ValidationException>(() => context.Users.Update(request, false, default));
Assert.Empty(context.Sessions.SignedOut);
Assert.Equal("main", (await context.Read("main")).NickName);
}
[Theory]
[InlineData("username")]
[InlineData("password-short")]
[InlineData("password-long")]
public async Task InvalidCreateLength_IsRejectedByService(string field)
{
using var context = new UserTestContext();
var request = new UserCreateRequest { UserName = "created", Password = "password" };
if (field == "username") request.UserName = new string('u', 21);
if (field == "password-short") request.Password = "123";
if (field == "password-long") request.Password = new string('p', 129);
await Assert.ThrowsAsync<ValidationException>(() => context.Users.Create(request, false, default));
Assert.Null(await context.Read(request.UserName));
}
}