using FluentAssertions; using PiiRedaction.Core.Detection; using PiiRedaction.Core.Models; namespace PiiRedaction.Core.Tests.Detection; [TestFixture] public sealed class DomainRulePiiDetectorTests { private readonly DomainRulePiiDetector _detector = new(); [Test] public void Detect_PositiveLoanNumber_ReturnsValueOnly() { var entities = _detector.Detect("Loan LN-456789 active."); entities.Should().ContainSingle(entity => entity.Type == PiiEntityType.LoanNumber && entity.Value == "LN-456789" && entity.Source == PiiDetectionSource.Domain); } [Test] public void Detect_PositiveCustomerId_ReturnsEntity() { var entities = _detector.Detect("CustomerId CID-1234 found."); entities.Should().ContainSingle(entity => entity.Type == PiiEntityType.CustomerId && entity.Value == "CID-1234"); } [Test] public void Detect_PositiveAccountNumber_ReturnsEntity() { var entities = _detector.Detect("Account ACC-123456 open."); entities.Should().ContainSingle(entity => entity.Type == PiiEntityType.AccountNumber && entity.Value == "ACC-123456"); } [TestCase("LN-12345")] [TestCase("XLN-456789")] [TestCase("CID-123")] [TestCase("ACC-12345")] public void Detect_InvalidDomainIds_ReturnsEmpty(string text) { _detector.Detect(text).Should().BeEmpty(); } [Test] public void Detect_LoanNumberLabel_PreservesLabelInSurroundingText() { const string text = "LoanNumber LN-456789 end."; var entity = _detector.Detect(text).Single(); entity.Value.Should().Be("LN-456789"); entity.StartIndex.Should().Be("LoanNumber ".Length); } [TestCase(null)] [TestCase("")] [TestCase(" ")] public void Detect_InvalidInput_ThrowsArgumentException(string? text) { var action = () => _detector.Detect(text!); action.Should().Throw(); } }