This commit is contained in:
@@ -0,0 +1,76 @@
|
|||||||
|
namespace TaxBaik.Application.Tests;
|
||||||
|
|
||||||
|
using TaxBaik.Application.Services;
|
||||||
|
using TaxBaik.Domain.Entities;
|
||||||
|
using TaxBaik.Domain.Interfaces;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
public class CommonCodeServiceTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task UpsertAsync_TrimsAndRejectsWhitespaceInCodeValue()
|
||||||
|
{
|
||||||
|
var repository = new FakeCommonCodeRepository();
|
||||||
|
var service = new CommonCodeService(repository);
|
||||||
|
|
||||||
|
await Assert.ThrowsAsync<ValidationException>(() => service.UpsertAsync(new CommonCode
|
||||||
|
{
|
||||||
|
CodeGroup = " CLIENT_STATUS ",
|
||||||
|
CodeValue = "active code",
|
||||||
|
CodeName = " 활성 "
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task UpsertAsync_TrimsAndPersistsNormalizedValues()
|
||||||
|
{
|
||||||
|
var repository = new FakeCommonCodeRepository();
|
||||||
|
var service = new CommonCodeService(repository);
|
||||||
|
|
||||||
|
await service.UpsertAsync(new CommonCode
|
||||||
|
{
|
||||||
|
CodeGroup = " CLIENT_STATUS ",
|
||||||
|
CodeValue = "active",
|
||||||
|
CodeName = " 활성 ",
|
||||||
|
SortOrder = 10
|
||||||
|
});
|
||||||
|
|
||||||
|
var saved = Assert.Single(repository.SavedCodes);
|
||||||
|
Assert.Equal("CLIENT_STATUS", saved.CodeGroup);
|
||||||
|
Assert.Equal("active", saved.CodeValue);
|
||||||
|
Assert.Equal("활성", saved.CodeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class FakeCommonCodeRepository : ICommonCodeRepository
|
||||||
|
{
|
||||||
|
public List<CommonCode> SavedCodes { get; } = [];
|
||||||
|
|
||||||
|
public Task<IEnumerable<string>> GetAllGroupsAsync(CancellationToken ct = default) =>
|
||||||
|
Task.FromResult<IEnumerable<string>>([]);
|
||||||
|
|
||||||
|
public Task<IEnumerable<CommonCode>> GetByGroupAsync(string codeGroup, CancellationToken ct = default) =>
|
||||||
|
Task.FromResult<IEnumerable<CommonCode>>([]);
|
||||||
|
|
||||||
|
public Task<IEnumerable<CommonCode>> GetAllActiveAsync(CancellationToken ct = default) =>
|
||||||
|
Task.FromResult<IEnumerable<CommonCode>>([]);
|
||||||
|
|
||||||
|
public Task<CommonCode?> GetAsync(string codeGroup, string codeValue, CancellationToken ct = default) =>
|
||||||
|
Task.FromResult<CommonCode?>(null);
|
||||||
|
|
||||||
|
public Task UpsertAsync(CommonCode code, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
SavedCodes.Add(new CommonCode
|
||||||
|
{
|
||||||
|
CodeGroup = code.CodeGroup,
|
||||||
|
CodeValue = code.CodeValue,
|
||||||
|
CodeName = code.CodeName,
|
||||||
|
SortOrder = code.SortOrder,
|
||||||
|
IsActive = code.IsActive
|
||||||
|
});
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteAsync(string codeGroup, string codeValue, CancellationToken ct = default) =>
|
||||||
|
Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,10 @@ namespace TaxBaik.Application.Services;
|
|||||||
|
|
||||||
public class CommonCodeService(ICommonCodeRepository commonCodeRepository)
|
public class CommonCodeService(ICommonCodeRepository commonCodeRepository)
|
||||||
{
|
{
|
||||||
|
private const int MaxCodeGroupLength = 80;
|
||||||
|
private const int MaxCodeValueLength = 120;
|
||||||
|
private const int MaxCodeNameLength = 200;
|
||||||
|
|
||||||
public async Task<IEnumerable<string>> GetAllGroupsAsync(CancellationToken ct = default)
|
public async Task<IEnumerable<string>> GetAllGroupsAsync(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await commonCodeRepository.GetAllGroupsAsync(ct);
|
return await commonCodeRepository.GetAllGroupsAsync(ct);
|
||||||
@@ -36,13 +40,28 @@ public class CommonCodeService(ICommonCodeRepository commonCodeRepository)
|
|||||||
|
|
||||||
public async Task DeleteAsync(string codeGroup, string codeValue, CancellationToken ct = default)
|
public async Task DeleteAsync(string codeGroup, string codeValue, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await commonCodeRepository.DeleteAsync(codeGroup.Trim(), codeValue.Trim(), ct);
|
await commonCodeRepository.DeleteAsync(NormalizeToken(codeGroup, nameof(codeGroup), MaxCodeGroupLength), NormalizeToken(codeValue, nameof(codeValue), MaxCodeValueLength), ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Normalize(CommonCode code)
|
private static void Normalize(CommonCode code)
|
||||||
{
|
{
|
||||||
code.CodeGroup = code.CodeGroup.Trim();
|
code.CodeGroup = NormalizeToken(code.CodeGroup, nameof(code.CodeGroup), MaxCodeGroupLength);
|
||||||
code.CodeValue = code.CodeValue.Trim();
|
code.CodeValue = NormalizeToken(code.CodeValue, nameof(code.CodeValue), MaxCodeValueLength, disallowWhitespace: true);
|
||||||
code.CodeName = code.CodeName.Trim();
|
code.CodeName = NormalizeToken(code.CodeName, nameof(code.CodeName), MaxCodeNameLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizeToken(string value, string fieldName, int maxLength, bool disallowWhitespace = false)
|
||||||
|
{
|
||||||
|
var normalized = (value ?? string.Empty).Trim();
|
||||||
|
if (string.IsNullOrWhiteSpace(normalized))
|
||||||
|
throw new ValidationException($"{fieldName}은(는) 필수입니다.");
|
||||||
|
|
||||||
|
if (normalized.Length > maxLength)
|
||||||
|
throw new ValidationException($"{fieldName}은(는) 최대 {maxLength}자까지 입력할 수 있습니다.");
|
||||||
|
|
||||||
|
if (disallowWhitespace && normalized.Any(char.IsWhiteSpace))
|
||||||
|
throw new ValidationException($"{fieldName}에는 공백을 사용할 수 없습니다.");
|
||||||
|
|
||||||
|
return normalized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user